From 9d8db9efd4aa8992bc8df3d156ed6c6cad725c7e Mon Sep 17 00:00:00 2001 From: Valerij Talagayev <82884038+talagayev@users.noreply.github.com> Date: Tue, 7 Apr 2026 01:19:24 +0200 Subject: [PATCH 1/2] Update openmmdlanalysis.py --- .../openmmdl_analysis/openmmdlanalysis.py | 47 ++++++++++++++----- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/openmmdl/openmmdl_analysis/openmmdlanalysis.py b/openmmdl/openmmdl_analysis/openmmdlanalysis.py index b40723d5..2a0c98a0 100644 --- a/openmmdl/openmmdl_analysis/openmmdlanalysis.py +++ b/openmmdl/openmmdl_analysis/openmmdlanalysis.py @@ -65,6 +65,24 @@ def pushd(path: str): _FLOAT_RE = re.compile(r"[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?") +_TRUE_BOOL_VALUES = {"1", "true", "t", "yes", "y", "on"} +_FALSE_BOOL_VALUES = {"0", "false", "f", "no", "n", "off"} + + +def parse_bool_flag(value): + """Parse flexible CLI boolean values like true/false, yes/no, y/n, 1/0.""" + if isinstance(value, bool): + return value + + normalized_value = str(value).strip().lower() + if normalized_value in _TRUE_BOOL_VALUES: + return True + if normalized_value in _FALSE_BOOL_VALUES: + return False + + raise argparse.ArgumentTypeError( + "Boolean value expected. Use one of: true/false, yes/no, y/n, 1/0, on/off." + ) def parse_xyz(val): """ @@ -148,20 +166,23 @@ def main(): parser.add_argument( "-p", dest="generate_pml", - help="Generate .pml files for pharmacophore visualization", + help="Generate .pml files for pharmacophore visualization (accepts true/false, yes/no, y/n)", default=False, + type=parse_bool_flag, ) parser.add_argument( "-r", dest="frame_rmsd", - help='RMSD Difference between frames calculation type "True" to use it default is False,', - default="No", + help="Calculate RMSD differences between frames (accepts true/false, yes/no, y/n)", + default=False, + type=parse_bool_flag, ) parser.add_argument( "-nuc", dest="receptor_nucleic", - help="Treat nucleic acids as receptor", + help="Treat nucleic acids as receptor (accepts true/false, yes/no, y/n)", default=False, + type=parse_bool_flag, ) parser.add_argument( "-s", @@ -184,14 +205,16 @@ def main(): parser.add_argument( "-w", dest="stable_water_analysis", - help="Should stable water analysis be performed? True or False", + help="Should stable water analysis be performed? (accepts true/false, yes/no, y/n)", default=False, + type=parse_bool_flag, ) parser.add_argument( "-rep", dest="representative_frame", - help="Calculate the representative frame for each binding mode. Defaults to False", + help="Calculate the representative frame for each binding mode (accepts true/false, yes/no, y/n)", default=False, + type=parse_bool_flag, ) parser.add_argument( "--watereps", @@ -270,7 +293,7 @@ def main(): W.write(u.atoms) pdb_md = mda.Universe(topology, trajectory) water_eps = float(args.water_eps) - stable_water_analysis = bool(args.stable_water_analysis) + stable_water_analysis = args.stable_water_analysis if stable_water_analysis: stable_water_analyser = StableWaters(trajectory, topology, water_eps) @@ -290,8 +313,8 @@ def main(): dataframe = args.dataframe min_transition = int(args.min_transition) cpu_count = int(args.cpu_count) - generate_pml = bool(args.generate_pml) - receptor_nucleic = bool(args.receptor_nucleic) + generate_pml = args.generate_pml + receptor_nucleic = args.receptor_nucleic special_ligand = args.special_ligand reference = args.reference peptide = args.peptide @@ -380,7 +403,7 @@ def main(): selection1="nucleicbackbone", selection2=["nucleic", f"resname {ligand}"], ) - if frame_rmsd != "No": + if frame_rmsd: pairwise_rmsd_prot, pairwise_rmsd_lig = rmsd_analyzer.rmsd_dist_frames( fig_type, lig=f"{ligand}", nucleic=True ) @@ -391,7 +414,7 @@ def main(): selection1="backbone", selection2=["protein", f"chainID {peptide}"], ) - if frame_rmsd != "No": + if frame_rmsd: pairwise_rmsd_prot, pairwise_rmsd_lig = rmsd_analyzer.rmsd_dist_frames(fig_type, lig=f"chainID {peptide}") logger.info("\033[1mRMSD calculated\033[0m") else: @@ -400,7 +423,7 @@ def main(): selection1="backbone", selection2=["protein", f"resname {ligand}"], ) - if frame_rmsd != "No": + if frame_rmsd: pairwise_rmsd_prot, pairwise_rmsd_lig = rmsd_analyzer.rmsd_dist_frames(fig_type, lig=f"{ligand}") logger.info("\033[1mRMSD calculated\033[0m") From a6a42a394ee4c083d4265755e53055fa4ec3065d Mon Sep 17 00:00:00 2001 From: Valerij Talagayev <82884038+talagayev@users.noreply.github.com> Date: Wed, 8 Apr 2026 01:28:30 +0200 Subject: [PATCH 2/2] Update openmmdlsetup.py --- openmmdl/openmmdl_setup/openmmdlsetup.py | 44 ++++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/openmmdl/openmmdl_setup/openmmdlsetup.py b/openmmdl/openmmdl_setup/openmmdlsetup.py index 86844d2d..27af8c2d 100644 --- a/openmmdl/openmmdl_setup/openmmdlsetup.py +++ b/openmmdl/openmmdl_setup/openmmdlsetup.py @@ -423,7 +423,7 @@ def createAmberBashScript(): ) elif nmLigFile[-4:] == ".pdb": a_script.append( - "obabel ${nmLigFile}.pdb -O ${nmLigFile}.sdf -p # convert to sdf file for openmmdl_analysis, -p: add hydrogens appropriate for pH7.4" + "obabel ${nmLigFile}.pdb -O ${nmLigFile}.sdf -p # convert to sdf file for openmmdl analysis, -p: add hydrogens appropriate for pH7.4" ) a_script.append( @@ -691,7 +691,7 @@ def createAmberBashScript(): def extractLigName(lig_file_name): """ Extract the ligand name from the pdb file as a string, which is the fourth column of the first line in the pdb file. - This string can be used for openmmdl_analysis in later function `createScript`. + This string can be used for openmmdl analysis in later function `createScript`. Params: ------- @@ -1873,11 +1873,11 @@ def _xml_script_segment(to_serialize, target_file): if fileType == "pdb": if has_pdb_ligands: script.append( - f"analysis_jobs.append(('Final_Output/All_Atoms', f'openmmdl_analysis -t centered_top{top_ext} -d centered_traj{traj_ext} -l {{ligands[0]}} -n {{ligand_names[0]}}{{analysis_special_flags}} -b {session['binding_mode']} -m {session['min_transition']} -r {session['rmsd_diff']} -p {session['pml_generation']} -w {session['stable_water']} --watereps {session['wc_distance']}'))" + f"analysis_jobs.append(('Final_Output/All_Atoms', f'openmmdl analysis -t centered_top{top_ext} -d centered_traj{traj_ext} -l {{ligands[0]}} -n {{ligand_names[0]}}{{analysis_special_flags}} -b {session['binding_mode']} -m {session['min_transition']} -r {session['rmsd_diff']} -p {session['pml_generation']} -w {session['stable_water']} --watereps {session['wc_distance']}'))" ) elif not has_pdb_ligands: script.append( - "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl_analysis -t centered_top%s -d centered_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl analysis -t centered_top%s -d centered_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -1892,7 +1892,7 @@ def _xml_script_segment(to_serialize, target_file): elif fileType == "amber": if not session["nmLig"] and not session["spLig"]: script.append( - "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl_analysis -t centered_top%s -d centered_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl analysis -t centered_top%s -d centered_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -1906,7 +1906,7 @@ def _xml_script_segment(to_serialize, target_file): ) elif session["nmLig"] and not session["spLig"]: script.append( - "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl_analysis -t centered_top%s -d centered_traj%s -n %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl analysis -t centered_top%s -d centered_traj%s -n %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -1921,7 +1921,7 @@ def _xml_script_segment(to_serialize, target_file): ) elif session["nmLig"] and session["spLig"]: script.append( - "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl_analysis -t centered_top%s -d centered_traj%s -n %s -s %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl analysis -t centered_top%s -d centered_traj%s -n %s -s %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -1940,11 +1940,11 @@ def _xml_script_segment(to_serialize, target_file): if fileType == "pdb": if has_pdb_ligands: script.append( - f"analysis_jobs.append(('Final_Output/Prot_Lig', f'openmmdl_analysis -t prot_lig_top{top_ext} -d prot_lig_traj{traj_ext} -l {{ligands[0]}} -n {{ligand_names[0]}}{{analysis_special_flags}} -b {session['binding_mode']} -m {session['min_transition']} -r {session['rmsd_diff']} -p {session['pml_generation']} -w {session['stable_water']} --watereps {session['wc_distance']}'))" + f"analysis_jobs.append(('Final_Output/Prot_Lig', f'openmmdl analysis -t prot_lig_top{top_ext} -d prot_lig_traj{traj_ext} -l {{ligands[0]}} -n {{ligand_names[0]}}{{analysis_special_flags}} -b {session['binding_mode']} -m {session['min_transition']} -r {session['rmsd_diff']} -p {session['pml_generation']} -w {session['stable_water']} --watereps {session['wc_distance']}'))" ) elif not has_pdb_ligands: script.append( - "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl_analysis -t prot_lig_top%s -d prot_lig_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl analysis -t prot_lig_top%s -d prot_lig_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -1959,7 +1959,7 @@ def _xml_script_segment(to_serialize, target_file): elif fileType == "amber": if not session["nmLig"] and not session["spLig"]: script.append( - "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl_analysis -t prot_lig_top%s -d prot_lig_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl analysis -t prot_lig_top%s -d prot_lig_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -1973,7 +1973,7 @@ def _xml_script_segment(to_serialize, target_file): ) elif session["nmLig"] and not session["spLig"]: script.append( - "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl_analysis -t prot_lig_top%s -d prot_lig_traj%s -n %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl analysis -t prot_lig_top%s -d prot_lig_traj%s -n %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -1988,7 +1988,7 @@ def _xml_script_segment(to_serialize, target_file): ) elif session["nmLig"] and session["spLig"]: script.append( - "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl_analysis -t prot_lig_top%s -d prot_lig_traj%s -n %s -s %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl analysis -t prot_lig_top%s -d prot_lig_traj%s -n %s -s %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -2007,14 +2007,14 @@ def _xml_script_segment(to_serialize, target_file): if fileType == "pdb": if has_pdb_ligands: script.append( - f"analysis_jobs.append(('Final_Output/All_Atoms', f'openmmdl_analysis -t centered_top{top_ext} -d centered_traj{traj_ext} -l {{ligands[0]}} -n {{ligand_names[0]}}{{analysis_special_flags}} -b {session['binding_mode']} -m {session['min_transition']} -r {session['rmsd_diff']} -p {session['pml_generation']} -w {session['stable_water']} --watereps {session['wc_distance']}'))" + f"analysis_jobs.append(('Final_Output/All_Atoms', f'openmmdl analysis -t centered_top{top_ext} -d centered_traj{traj_ext} -l {{ligands[0]}} -n {{ligand_names[0]}}{{analysis_special_flags}} -b {session['binding_mode']} -m {session['min_transition']} -r {session['rmsd_diff']} -p {session['pml_generation']} -w {session['stable_water']} --watereps {session['wc_distance']}'))" ) script.append( - f"analysis_jobs.append(('Final_Output/Prot_Lig', f'openmmdl_analysis -t prot_lig_top{top_ext} -d prot_lig_traj{traj_ext} -l {{ligands[0]}} -n {{ligand_names[0]}}{{analysis_special_flags}} -b {session['binding_mode']} -m {session['min_transition']} -r {session['rmsd_diff']} -p {session['pml_generation']} -w {session['stable_water']} --watereps {session['wc_distance']}'))" + f"analysis_jobs.append(('Final_Output/Prot_Lig', f'openmmdl analysis -t prot_lig_top{top_ext} -d prot_lig_traj{traj_ext} -l {{ligands[0]}} -n {{ligand_names[0]}}{{analysis_special_flags}} -b {session['binding_mode']} -m {session['min_transition']} -r {session['rmsd_diff']} -p {session['pml_generation']} -w {session['stable_water']} --watereps {session['wc_distance']}'))" ) elif not has_pdb_ligands: script.append( - "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl_analysis -t centered_top%s -d centered_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl analysis -t centered_top%s -d centered_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -2027,7 +2027,7 @@ def _xml_script_segment(to_serialize, target_file): ) ) script.append( - "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl_analysis -t prot_lig_top%s -d prot_lig_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl analysis -t prot_lig_top%s -d prot_lig_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -2042,7 +2042,7 @@ def _xml_script_segment(to_serialize, target_file): elif fileType == "amber": if not session["nmLig"] and not session["spLig"]: script.append( - "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl_analysis -t centered_top%s -d centered_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl analysis -t centered_top%s -d centered_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -2055,7 +2055,7 @@ def _xml_script_segment(to_serialize, target_file): ) ) script.append( - "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl_analysis -t prot_lig_top%s -d prot_lig_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl analysis -t prot_lig_top%s -d prot_lig_traj%s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -2069,7 +2069,7 @@ def _xml_script_segment(to_serialize, target_file): ) elif session["nmLig"] and not session["spLig"]: script.append( - "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl_analysis -t centered_top%s -d centered_traj%s -n %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl analysis -t centered_top%s -d centered_traj%s -n %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -2083,7 +2083,7 @@ def _xml_script_segment(to_serialize, target_file): ) ) script.append( - "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl_analysis -t prot_lig_top%s -d prot_lig_traj%s -n %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl analysis -t prot_lig_top%s -d prot_lig_traj%s -n %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -2098,7 +2098,7 @@ def _xml_script_segment(to_serialize, target_file): ) elif session["nmLig"] and session["spLig"]: script.append( - "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl_analysis -t centered_top%s -d centered_traj%s -n %s -s %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/All_Atoms', 'openmmdl analysis -t centered_top%s -d centered_traj%s -n %s -s %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext, @@ -2113,7 +2113,7 @@ def _xml_script_segment(to_serialize, target_file): ) ) script.append( - "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl_analysis -t prot_lig_top%s -d prot_lig_traj%s -n %s -s %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" + "analysis_jobs.append(('Final_Output/Prot_Lig', 'openmmdl analysis -t prot_lig_top%s -d prot_lig_traj%s -n %s -s %s -b %s -m %s -r %s -p %s -w %s --watereps %s'))" % ( top_ext, traj_ext,