diff --git a/news/morph_inputs.rst b/news/morph_inputs.rst new file mode 100644 index 0000000..470ad37 --- /dev/null +++ b/news/morph_inputs.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* All morph inputs are now outputted for multiple morphs/targets. + +**Security:** + +* diff --git a/src/diffpy/morph/morph_io.py b/src/diffpy/morph/morph_io.py index 84d5c15..b788fcf 100644 --- a/src/diffpy/morph/morph_io.py +++ b/src/diffpy/morph/morph_io.py @@ -34,6 +34,96 @@ def custom_formatwarning(msg, *args, **kwargs): warnings.formatwarning = custom_formatwarning +def build_morph_inputs_container( + scale, + stretch, + smear_pdf, + smear, + hshift, + vshift, + squeeze, +): + """Helper function to extract input morphing parameters for CLI + morphs. Python morphs are handled separately. + + Parameters + ---------- + scale + opts.scale + stretch + opts.stretch + smear_pdf + opts.smear_pdf + smear + opts.smear + hshift + opts.hshift + vshift + opts.vshift + squeeze + opts.squeeze + + Returns + ------- + dict + The dictionary of input morphing parameters. + Only one of smear and smear_pdf is included + (takes smear_pdf over smear when both exist). + Does not include hshift if a degree zero + or above squeeze is used. + Does not include stretch if a degree one + or above squeeze is used. + """ + squeeze_poly_deg = -1 + squeeze_in = None + if squeeze is not None: + squeeze_in = {} + # handle list/tuple input + if len(squeeze) > 1 and squeeze[0] == "[" and squeeze[-1] == "]": + squeeze = squeeze[1:-1] + elif len(squeeze) > 1 and squeeze[0] == "(" and squeeze[-1] == ")": + squeeze = squeeze[1:-1] + squeeze_coeffs = squeeze.strip().split(",") + idx = 0 + for _, coeff in enumerate(squeeze_coeffs): + if coeff.strip() != "": + try: + squeeze_in.update({f"a{idx}": float(coeff)}) + idx += 1 + except ValueError: + # user has already been warned + pass + squeeze_poly_deg = len(squeeze_in.keys()) + + scale_in = scale + if squeeze_poly_deg < 1: + stretch_in = stretch + else: + stretch_in = None + if smear_pdf is None: + smear_in = smear + else: + smear_in = smear_pdf + morph_inputs = { + "scale": scale_in, + "stretch": stretch_in, + "smear": smear_in, + } + + if squeeze_poly_deg < 0: + hshift_in = hshift + else: + hshift_in = None + vshift_in = vshift + morph_inputs.update({"hshift": hshift_in, "vshift": vshift_in}) + + if squeeze_in is not None: + for idx, _ in enumerate(squeeze_in): + morph_inputs.update({f"squeeze a{idx}": squeeze_in[f"a{idx}"]}) + + return morph_inputs + + def single_morph_output( morph_inputs, morph_results, diff --git a/src/diffpy/morph/morphapp.py b/src/diffpy/morph/morphapp.py index 327ed2d..a5c67d9 100755 --- a/src/diffpy/morph/morphapp.py +++ b/src/diffpy/morph/morphapp.py @@ -725,17 +725,16 @@ def single_morph( # if you think there requires special handling # Input morph parameters - morph_inputs = { - "scale": scale_in, - "stretch": stretch_in, - "smear": smear_in, - } - morph_inputs.update({"hshift": hshift_in, "vshift": vshift_in}) - # More complex input morph parameters are only displayed conditionally - if opts.squeeze is not None: - squeeze_dict = squeeze_dict_in.copy() - for idx, _ in enumerate(squeeze_dict): - morph_inputs.update({f"squeeze a{idx}": squeeze_dict[f"a{idx}"]}) + morph_inputs = io.build_morph_inputs_container( + opts.scale, + opts.stretch, + opts.smear_pdf, + opts.smear, + opts.hshift, + opts.vshift, + opts.squeeze, + ) + # Special python morph inputs (for single morph only) if pymorphs is not None: if "funcxy" in pymorphs: for funcxy_param in pymorphs["funcxy"][1].keys(): @@ -953,12 +952,15 @@ def multiple_targets(parser, opts, pargs, stdout_flag=True, python_wrap=False): for key in morph_results.keys(): target_file_names.append(key) - morph_inputs = { - "scale": opts.scale, - "stretch": opts.stretch, - "smear": opts.smear_pdf, - } - morph_inputs.update({"hshift": opts.hshift, "vshift": opts.vshift}) + morph_inputs = io.build_morph_inputs_container( + opts.scale, + opts.stretch, + opts.smear_pdf, + opts.smear, + opts.hshift, + opts.vshift, + opts.squeeze, + ) try: # Print summary of morphs to terminal and to file (if requested) @@ -1136,12 +1138,15 @@ def multiple_morphs(parser, opts, pargs, stdout_flag=True, python_wrap=False): for key in morph_results.keys(): morph_file_names.append(key) - morph_inputs = { - "scale": opts.scale, - "stretch": opts.stretch, - "smear": opts.smear_pdf, - } - morph_inputs.update({"hshift": opts.hshift, "vshift": opts.vshift}) + morph_inputs = io.build_morph_inputs_container( + opts.scale, + opts.stretch, + opts.smear_pdf, + opts.smear, + opts.hshift, + opts.vshift, + opts.squeeze, + ) try: # Print summary of morphs to terminal and to file (if requested)