robert 1.2.0__tar.gz → 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. {robert-1.2.0 → robert-2.0.0}/LICENSE +0 -0
  2. {robert-1.2.0 → robert-2.0.0}/PKG-INFO +35 -36
  3. {robert-1.2.0 → robert-2.0.0}/README.md +18 -9
  4. {robert-1.2.0 → robert-2.0.0}/robert/__init__.py +0 -0
  5. {robert-1.2.0 → robert-2.0.0}/robert/__main__.py +1 -1
  6. {robert-1.2.0 → robert-2.0.0}/robert/aqme.py +23 -29
  7. {robert-1.2.0 → robert-2.0.0}/robert/argument_parser.py +15 -14
  8. robert-2.0.0/robert/curate.py +160 -0
  9. {robert-1.2.0 → robert-2.0.0}/robert/evaluate.py +12 -10
  10. robert-2.0.0/robert/generate.py +176 -0
  11. robert-2.0.0/robert/generate_utils.py +223 -0
  12. {robert-1.2.0 → robert-2.0.0}/robert/model_params/ADAB_params.yaml +1 -4
  13. {robert-1.2.0 → robert-2.0.0}/robert/model_params/GB_params.yaml +10 -10
  14. robert-2.0.0/robert/model_params/GP_params.yaml +2 -0
  15. robert-2.0.0/robert/model_params/MVL_params.yaml +2 -0
  16. robert-2.0.0/robert/model_params/NN_params.yaml +11 -0
  17. {robert-1.2.0 → robert-2.0.0}/robert/model_params/RF_params.yaml +8 -8
  18. robert-2.0.0/robert/model_params/VR_params.yaml +28 -0
  19. {robert-1.2.0 → robert-2.0.0}/robert/predict.py +20 -30
  20. robert-2.0.0/robert/predict_utils.py +226 -0
  21. {robert-1.2.0 → robert-2.0.0}/robert/report/Robert_icon.ico +0 -0
  22. {robert-1.2.0 → robert-2.0.0}/robert/report/Robert_logo.jpg +0 -0
  23. {robert-1.2.0 → robert-2.0.0}/robert/report/Robert_logo1.jpg +0 -0
  24. {robert-1.2.0 → robert-2.0.0}/robert/report/abbrev.png +0 -0
  25. {robert-1.2.0 → robert-2.0.0}/robert/report/adv_anal.png +0 -0
  26. {robert-1.2.0 → robert-2.0.0}/robert/report/features.png +0 -0
  27. robert-1.2.0/robert/report/GENERATE.png → robert-2.0.0/robert/report/generate.png +0 -0
  28. {robert-1.2.0 → robert-2.0.0}/robert/report/outliers.png +0 -0
  29. {robert-1.2.0 → robert-2.0.0}/robert/report/pred.png +0 -0
  30. {robert-1.2.0 → robert-2.0.0}/robert/report/repro.png +0 -0
  31. {robert-1.2.0 → robert-2.0.0}/robert/report/score.png +0 -0
  32. {robert-1.2.0 → robert-2.0.0}/robert/report/score_0.jpg +0 -0
  33. {robert-1.2.0 → robert-2.0.0}/robert/report/score_1.jpg +0 -0
  34. {robert-1.2.0 → robert-2.0.0}/robert/report/score_10.jpg +0 -0
  35. {robert-1.2.0 → robert-2.0.0}/robert/report/score_2.jpg +0 -0
  36. {robert-1.2.0 → robert-2.0.0}/robert/report/score_3.jpg +0 -0
  37. {robert-1.2.0 → robert-2.0.0}/robert/report/score_4.jpg +0 -0
  38. {robert-1.2.0 → robert-2.0.0}/robert/report/score_5.jpg +0 -0
  39. {robert-1.2.0 → robert-2.0.0}/robert/report/score_6.jpg +0 -0
  40. {robert-1.2.0 → robert-2.0.0}/robert/report/score_7.jpg +0 -0
  41. {robert-1.2.0 → robert-2.0.0}/robert/report/score_8.jpg +0 -0
  42. {robert-1.2.0 → robert-2.0.0}/robert/report/score_9.jpg +0 -0
  43. {robert-1.2.0 → robert-2.0.0}/robert/report/score_w_1_0.jpg +0 -0
  44. {robert-1.2.0 → robert-2.0.0}/robert/report/score_w_1_1.jpg +0 -0
  45. {robert-1.2.0 → robert-2.0.0}/robert/report/score_w_2_0.jpg +0 -0
  46. {robert-1.2.0 → robert-2.0.0}/robert/report/score_w_2_1.jpg +0 -0
  47. {robert-1.2.0 → robert-2.0.0}/robert/report/score_w_2_2.jpg +0 -0
  48. {robert-1.2.0 → robert-2.0.0}/robert/report/score_w_3_0.jpg +0 -0
  49. {robert-1.2.0 → robert-2.0.0}/robert/report/score_w_3_1.jpg +0 -0
  50. {robert-1.2.0 → robert-2.0.0}/robert/report/score_w_3_2.jpg +0 -0
  51. {robert-1.2.0 → robert-2.0.0}/robert/report/score_w_3_3.jpg +0 -0
  52. {robert-1.2.0 → robert-2.0.0}/robert/report/transpa.png +0 -0
  53. {robert-1.2.0 → robert-2.0.0}/robert/report/y_distrib.png +0 -0
  54. {robert-1.2.0 → robert-2.0.0}/robert/report.py +67 -46
  55. {robert-1.2.0 → robert-2.0.0}/robert/report_utils.py +229 -203
  56. {robert-1.2.0 → robert-2.0.0}/robert/robert.py +12 -2
  57. robert-2.0.0/robert/utils.py +2835 -0
  58. robert-2.0.0/robert/verify.py +271 -0
  59. {robert-1.2.0 → robert-2.0.0}/robert.egg-info/PKG-INFO +35 -36
  60. {robert-1.2.0 → robert-2.0.0}/robert.egg-info/SOURCES.txt +2 -2
  61. {robert-1.2.0 → robert-2.0.0}/robert.egg-info/dependency_links.txt +0 -0
  62. robert-2.0.0/robert.egg-info/requires.txt +12 -0
  63. {robert-1.2.0 → robert-2.0.0}/robert.egg-info/top_level.txt +0 -0
  64. {robert-1.2.0 → robert-2.0.0}/setup.cfg +10 -10
  65. {robert-1.2.0 → robert-2.0.0}/setup.py +9 -10
  66. {robert-1.2.0 → robert-2.0.0}/tests/test_1curate.py +54 -13
  67. {robert-1.2.0 → robert-2.0.0}/tests/test_2generate.py +108 -93
  68. {robert-1.2.0 → robert-2.0.0}/tests/test_3verify.py +24 -23
  69. {robert-1.2.0 → robert-2.0.0}/tests/test_4predict.py +21 -14
  70. {robert-1.2.0 → robert-2.0.0}/tests/test_5aqme_n_full.py +88 -94
  71. robert-1.2.0/robert/curate.py +0 -311
  72. robert-1.2.0/robert/generate.py +0 -327
  73. robert-1.2.0/robert/generate_utils.py +0 -759
  74. robert-1.2.0/robert/model_params/GP_params.yaml +0 -2
  75. robert-1.2.0/robert/model_params/MVL_params.yaml +0 -2
  76. robert-1.2.0/robert/model_params/NN_params.yaml +0 -35
  77. robert-1.2.0/robert/model_params/VR_params.yaml +0 -28
  78. robert-1.2.0/robert/predict_utils.py +0 -1048
  79. robert-1.2.0/robert/utils.py +0 -1376
  80. robert-1.2.0/robert/verify.py +0 -467
  81. robert-1.2.0/robert.egg-info/requires.txt +0 -13
  82. robert-1.2.0/tests/test_6evaluate.py +0 -276
File without changes
@@ -1,36 +1,35 @@
1
- Metadata-Version: 2.1
2
- Name: robert
3
- Version: 1.2.0
4
- Summary: Refiner and Optimizer of a Bunch of Existing Regression Tools
5
- Home-page: https://github.com/jvalegre/robert
6
- Download-URL: https://github.com/jvalegre/robert/archive/refs/tags/1.2.0.tar.gz
7
- Author: Juan V. Alegre Requena, David Dalmau
8
- Author-email: jv.alegre@csic.es
9
- License: MIT
10
- Keywords: workflows,machine learning,cheminformatics,data curation,prediction,automated
11
- Classifier: Development Status :: 5 - Production/Stable
12
- Classifier: Intended Audience :: Developers
13
- Classifier: Topic :: Software Development :: Build Tools
14
- Classifier: License :: OSI Approved :: MIT License
15
- Classifier: Programming Language :: Python :: 3.7
16
- Classifier: Programming Language :: Python :: 3.8
17
- Classifier: Programming Language :: Python :: 3.9
18
- Classifier: Programming Language :: Python :: 3.10
19
- Requires-Python: >=3.10
20
- Description-Content-Type: text/markdown
21
- License-File: LICENSE
22
- Requires-Dist: PyYAML==6.0.1
23
- Requires-Dist: matplotlib==3.9.2
24
- Requires-Dist: pandas==2.2.2
25
- Requires-Dist: numpy==1.26.4
26
- Requires-Dist: progress==1.6
27
- Requires-Dist: seaborn==0.13.2
28
- Requires-Dist: scipy==1.14.0
29
- Requires-Dist: scikit-learn==1.5.1
30
- Requires-Dist: hyperopt==0.2.7
31
- Requires-Dist: numba==0.60.0
32
- Requires-Dist: shap==0.45.1
33
- Requires-Dist: mapie==0.8.6
34
- Requires-Dist: weasyprint==62.3
35
-
36
- Documentation in Read The Docs: https://robert.readthedocs.io
1
+ Metadata-Version: 2.1
2
+ Name: robert
3
+ Version: 2.0.0
4
+ Summary: Refiner and Optimizer of a Bunch of Existing Regression Tools
5
+ Home-page: https://github.com/jvalegre/robert
6
+ Download-URL: https://github.com/jvalegre/robert/archive/refs/tags/2.0.0.tar.gz
7
+ Author: Juan V. Alegre Requena, David Dalmau
8
+ Author-email: jv.alegre@csic.es
9
+ License: MIT
10
+ Keywords: workflows,machine learning,cheminformatics,data curation,prediction,automated
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Build Tools
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.7
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: PyYAML==6.0.2
23
+ Requires-Dist: matplotlib==3.10.0
24
+ Requires-Dist: pandas==2.2.3
25
+ Requires-Dist: numpy==1.26.4
26
+ Requires-Dist: progress==1.6
27
+ Requires-Dist: seaborn==0.13.2
28
+ Requires-Dist: scipy==1.15.0
29
+ Requires-Dist: scikit-learn==1.6.0
30
+ Requires-Dist: bayesian-optimization==3.0.0b1
31
+ Requires-Dist: numba==0.60.0
32
+ Requires-Dist: shap==0.46.0
33
+ Requires-Dist: weasyprint==63.1
34
+
35
+ Documentation in Read The Docs: https://robert.readthedocs.io
@@ -7,15 +7,22 @@
7
7
  [![Codecov](https://img.shields.io/codecov/c/github/jvalegre/robert?label=Codecov&logo=codecov)](https://codecov.io/gh/jvalegre/robert)
8
8
  [![Downloads](https://img.shields.io/pepy/dt/robert?label=Downloads&logo=pypi)](https://www.pepy.tech/projects/robert)
9
9
  [![Read the Docs](https://img.shields.io/readthedocs/robert?label=Read%20the%20Docs&logo=readthedocs)](https://robert.readthedocs.io/)
10
-
11
- ROBERT is an ensemble of automated machine learning protocols that can be run sequentially
12
- through a single command line or a graphical user interface. The program works for **regression and classification problems**.
13
- Comprehensive workflows have been designed to meet state-of-the-art standards for cheminformatics studies, including:
10
+ [![PyPI](https://img.shields.io/pypi/v/robert)](https://pypi.org/project/robert/)
14
11
 
15
12
  ## Documentation
16
13
  Full documentation with installation instructions, technical details and examples can be found in [Read the Docs](https://robert.readthedocs.io).
17
14
 
18
- Don't miss out the latest hands-on tutorials from our [YouTube channel](https://www.youtube.com/channel/UCHRqI8N61bYxWV9BjbUI4Xw)!
15
+ Don't miss out the latest hands-on tutorials from our [YouTube channel](https://www.youtube.com/channel/UCHRqI8N61bYxWV9BjbUI4Xw)!
16
+
17
+ ## Recommended installation
18
+ 1. (Only once) Create new conda environment: `conda create -n robert python=3.10`
19
+ 2. Activate conda environment: `conda activate robert`
20
+ 3. Install ROBERT using pip: `pip install robert`
21
+ 4. Install libraries for the PDF report `conda install -y -c conda-forge glib gtk3 pango mscorefonts`
22
+ 5. (Only for compatible devices) Install Intelex accelerator: `pip install scikit-learn-intelex==2025.0.1`
23
+ * Inexperienced users should visit the *Users with no Python experience* section in [Read the Docs](https://robert.readthedocs.io).
24
+ ## Update the program
25
+ 1. Update to the latest version: `pip install robert --upgrade`
19
26
 
20
27
  ## Developers and help desk
21
28
  List of main developers and contact emails:
@@ -32,6 +39,8 @@ J.V.A.R. - The acronym ROBERT is dedicated to **ROBERT Paton**, who was a mentor
32
39
 
33
40
  D.D.G. - The style of the ROBERT_report.pdf file was created with the help of **Oliver Lee** (2023, Zysman-Colman group at University of St Andrews).
34
41
 
42
+ J.V.A.R. and D.D.G. - The improvements from v1.0 to v1.2 are largely the result of insightful discussions with **Matthew Sigman** and his students, **Jamie Cadge** and **Simone Gallarati** (2024, University of Utah).
43
+
35
44
  We really THANK all the testers for their feedback and for participating in the reproducibility tests, including:
36
45
 
37
46
  * **David Valiente** (2022-2023, Universidad Miguel Hernández)
@@ -44,11 +53,11 @@ We really THANK all the testers for their feedback and for participating in the
44
53
 
45
54
  ## How to cite ROBERT
46
55
  If you use any of the ROBERT modules, please include this citation:
47
- * Dalmau, D.; Alegre Requena, J. V. ChemRxiv, 2023, DOI: 10.26434/chemrxiv-2023-k994h.
56
+ * Dalmau, D.; Alegre Requena, J. V. ROBERT: Bridging the Gap between Machine Learning and Chemistry. *Wiley Interdiscip. Rev. Comput. Mol. Sci.* **2024**, *14*, e1733.
48
57
 
49
58
  If you use the AQME module, please include this citation:
50
- * Alegre-Requena et al., AQME: Automated Quantum Mechanical Environments for Researchers and Educators. Wiley Interdiscip. Rev. Comput. Mol. Sci. 2023, 13, e1663.
59
+ * Alegre-Requena et al., AQME: Automated Quantum Mechanical Environments for Researchers and Educators. *Wiley Interdiscip. Rev. Comput. Mol. Sci.* **2023**, *13*, e1663.
51
60
 
52
61
  Additionally, please include the corresponding reference for Scikit-learn and SHAP:
53
- * Pedregosa et al., Scikit-learn: Machine Learning in Python, J. Mach. Learn. Res. 2011, 12, 2825-2830.
54
- * Lundberg et al., From local explanations to global understanding with explainable AI for trees, Nat. Mach. Intell. 2020, 2, 56–67.
62
+ * Pedregosa et al., Scikit-learn: Machine Learning in Python. *J. Mach. Learn. Res.* **2011**, *12*, 2825-2830.
63
+ * Lundberg et al., From local explanations to global understanding with explainable AI for trees. *Nat. Mach. Intell.* **2020**, *2*, 56–67.
File without changes
@@ -13,7 +13,7 @@ from robert import robert
13
13
  # This allows the usage python pip-*.whl/pip install pip-*.whl
14
14
 
15
15
  if __package__ != 'robert':
16
- print('ROBERT is not installed! Use: pip install robert or conda install -c conda-forge robert.')
16
+ print('ROBERT is not installed! Use: pip install robert or conda install -y -c conda-forge robert.')
17
17
 
18
18
  if __name__ == '__main__':
19
19
  robert.main()
@@ -12,9 +12,8 @@ Parameters
12
12
  Name of the column containing the response variable in the input CSV file (i.e. 'solubility').
13
13
  qdescp_keywords : str, default=''
14
14
  Add extra keywords to the AQME-QDESCP run (i.e. qdescp_keywords="--qdescp_atoms ['Ir']")
15
- csearch_keywords : str, default='--sample 50'
16
- Add extra keywords to the AQME-CSEARCH run (i.e. csearch_keywords='--sample 10'). CREST can be
17
- used instead of RDKit by adding "--program crest".
15
+ descp_lvl : str, default='interpret'
16
+ Type of descriptor to be used in the AQME-ROBERT workflow. Options are 'interpret', 'denovo' or 'full'.
18
17
 
19
18
  """
20
19
  #####################################################.
@@ -95,8 +94,15 @@ class aqme:
95
94
  os.remove(new_sdf)
96
95
  shutil.move(sdf_file, new_sdf)
97
96
 
98
- #Load database
99
- csv_df = load_database(self,csv_target,job_type)
97
+ # Load database
98
+ csv_df,_,_ = load_database(self,csv_target,job_type,print_info=False)
99
+
100
+ # avoid running calcs with special signs (i.e. *)
101
+ for name_csv_indiv in csv_df['code_name']:
102
+ if '*' in f'{name_csv_indiv}':
103
+ self.args.log.write(f"\nx WARNING! The names provided in the CSV contain * (i.e. {name_csv_indiv}). Please, remove all the * characters.")
104
+ self.args.log.finalize()
105
+ sys.exit()
100
106
 
101
107
  # find if there is more than one SMILES column in the CSV file
102
108
  for column in csv_df.columns:
@@ -118,48 +124,36 @@ class aqme:
118
124
  csv_temp.to_csv(f'AQME_indiv_{smi_suffix}.csv', index=False)
119
125
  aqme_indv_name = f'AQME_indiv_{smi_suffix}'
120
126
 
121
- # run the initial AQME-CSEARCH conformational search with RDKit (default) or CREST
122
- if '--program crest' not in self.args.csearch_keywords.lower():
123
- cmd_csearch = ['python', '-m', 'aqme', '--csearch', '--program', 'rdkit', '--input', f'{aqme_indv_name}.csv', '--nprocs', f'{self.args.nprocs}']
124
- else:
125
- self.args.log.write(f"\no CREST detected in the csearch_keywords option, it will be used for conformer sampling")
126
- cmd_csearch = ['python', '-m', 'aqme', '--csearch', '--input', f'{aqme_indv_name}.csv', '--nprocs', f'{self.args.nprocs}']
127
- _ = self.run_aqme(cmd_csearch, self.args.csearch_keywords)
128
-
129
- sdf_files = 'CSEARCH/*.sdf'
130
- if smi_suffix is not None:
131
- sdf_files = f'CSEARCH/*_{smi_suffix}_*.sdf'
132
-
133
- # run QDESCP to generate descriptors
134
- cmd_qdescp = ['python', '-m', 'aqme', '--qdescp', '--files', sdf_files, '--program', 'xtb', '--csv_name', f'{aqme_indv_name}.csv', '--nprocs', f'{self.args.nprocs}', '--robert']
127
+ # run AQME-QDESCP to generate descriptors
128
+ cmd_qdescp = ['python', '-m', 'aqme', '--qdescp', '--input', f'{aqme_indv_name}.csv', '--program', 'xtb', '--csv_name', f'{aqme_indv_name}.csv', '--nprocs', f'{self.args.nprocs}', '--robert']
135
129
  _ = self.run_aqme(cmd_qdescp, self.args.qdescp_keywords)
136
130
 
137
131
  if smi_suffix is not None:
138
132
  # Change column names by adding suffix
139
133
  try:
140
- df_temp = pd.read_csv(f'AQME-ROBERT_{aqme_indv_name}.csv', encoding='utf-8')
134
+ df_temp = pd.read_csv(f'AQME-ROBERT_{self.args.descp_lvl}_{aqme_indv_name}.csv', encoding='utf-8')
141
135
  except FileNotFoundError:
142
136
  self.args.log.write("x WARNING! ROBERT stopped due to a problem with the AQME job. Please, check the previous AQME warnings.")
143
137
  sys.exit()
144
138
  df_temp.columns = [f'{col}_{smi_suffix}' if col not in ['code_name','SMILES'] and col not in aqme_args else col for col in df_temp.columns]
145
- df_temp.to_csv(f'AQME-ROBERT_{aqme_indv_name}.csv', index=False)
139
+ df_temp.to_csv(f'AQME-ROBERT_{self.args.descp_lvl}_{aqme_indv_name}.csv', index=False)
146
140
 
147
141
  # Check if there are missing rows in the AQME-ROBERT_{aqme_indv_name}.csv
148
142
  if len(df_temp) < len(csv_temp):
149
143
  missing_rows = csv_temp.loc[~csv_temp['code_name'].isin(df_temp['code_name'])]
150
- missing_rows[['code_name', 'SMILES']].to_csv(f'AQME-ROBERT_{aqme_indv_name}.csv', mode='a', header=False, index=False)
144
+ missing_rows[['code_name', 'SMILES']].to_csv(f'AQME-ROBERT_{self.args.descp_lvl}_{aqme_indv_name}.csv', mode='a', header=False, index=False)
151
145
 
152
146
  # Get the order of code_name in aqme_indv_name
153
147
  order = csv_temp['code_name'].tolist()
154
148
 
155
149
  # Sort the rows in 'AQME-ROBERT_{aqme_indv_name}.csv' based on the order
156
- df_temp = pd.read_csv(f'AQME-ROBERT_{aqme_indv_name}.csv', encoding='utf-8')
150
+ df_temp = pd.read_csv(f'AQME-ROBERT_{self.args.descp_lvl}_{aqme_indv_name}.csv', encoding='utf-8')
157
151
  df_temp = df_temp.sort_values(by='code_name', key=lambda x: x.map({v: i for i, v in enumerate(order)}))
158
152
 
159
153
  # Fill missing values with corresponding SMILES row
160
154
  df_temp = df_temp.fillna(df_temp.groupby('SMILES').transform('first'))
161
155
 
162
- df_temp.to_csv(f'AQME-ROBERT_{aqme_indv_name}.csv', index=False)
156
+ df_temp.to_csv(f'AQME-ROBERT_{self.args.descp_lvl}_{aqme_indv_name}.csv', index=False)
163
157
 
164
158
  # return SDF files after csv_test
165
159
  if aqme_test:
@@ -169,23 +163,23 @@ class aqme:
169
163
  shutil.rmtree(path_sdf)
170
164
 
171
165
  # if AQME-ROBERT_AQME_indiv_n.csv >0 in folder:
172
- if len(glob.glob('AQME-ROBERT_AQME_indiv*.csv')) > 0:
166
+ if len(glob.glob(f'AQME-ROBERT_{self.args.descp_lvl}_AQME_indiv*.csv')) > 0:
173
167
 
174
168
  df_concat = pd.DataFrame()
175
169
 
176
170
  # Read and concatenate CSV files
177
- for file in sorted(glob.glob('AQME-ROBERT_AQME_indiv*.csv'), key=os.path.getmtime,reverse=True):
171
+ for file in sorted(glob.glob(f'AQME-ROBERT_{self.args.descp_lvl}_AQME_indiv*.csv'), key=os.path.getmtime,reverse=True):
178
172
  columns_to_drop = ['code_name', 'SMILES'] + aqme_args
179
173
  df_temp = pd.read_csv(file, encoding='utf-8')
180
174
  columns_to_drop = [col for col in columns_to_drop if col in df_temp.columns]
181
175
  df_temp = df_temp.drop(columns=columns_to_drop)
182
176
  df_concat = pd.concat([df_temp, df_concat], axis=1)
183
177
  df_concat = pd.concat([csv_df, df_concat], axis=1)
184
- df_concat.to_csv(f'AQME-ROBERT_{csv_target}', index=False)
178
+ df_concat.to_csv(f'AQME-ROBERT_{self.args.descp_lvl}_{csv_target}', index=False)
185
179
 
186
180
 
187
181
  # if no qdesc_atom is set, only keep molecular properties and discard atomic properties
188
- aqme_db = f'AQME-ROBERT_{csv_target}'
182
+ aqme_db = f'AQME-ROBERT_{self.args.descp_lvl}_{csv_target}'
189
183
 
190
184
  # ensure that the AQME database was successfully created
191
185
  if not os.path.exists(aqme_db):
@@ -226,7 +220,7 @@ class aqme:
226
220
  try:
227
221
  from aqme.qprep import qprep
228
222
  except ModuleNotFoundError:
229
- self.args.log.write("x AQME is not installed (required for the --aqme option)! You can install the program with 'conda install -c conda-forge aqme'")
223
+ self.args.log.write("x AQME is not installed (required for the --aqme option)! The program is typically installed within 2-5 minutes (https://aqme.readthedocs.io, see the Installation section)")
230
224
  sys.exit()
231
225
 
232
226
 
@@ -16,8 +16,7 @@ var_dict = {
16
16
  "report": False,
17
17
  "cheers": False,
18
18
  "evaluate": False,
19
- "seed": [],
20
- "generate_acc": 'mid',
19
+ "seed": 0,
21
20
  "destination": None,
22
21
  "csv_name" : '',
23
22
  "csv_train": '',
@@ -27,29 +26,31 @@ var_dict = {
27
26
  "discard" : [],
28
27
  "ignore" : [],
29
28
  "categorical" : "onehot",
30
- "corr_filter" : True,
29
+ "corr_filter_x" : True,
30
+ "corr_filter_y" : False,
31
+ "std" : True,
31
32
  "desc_thres" : 25,
32
33
  "thres_y" : 0.001,
33
- "thres_x" : 0.9,
34
- "test_set" : 0.1,
34
+ "thres_x" : 0.7,
35
+ "test_set" : 0.2,
35
36
  "auto_test" : True,
36
- "train" : [60,70,80,90],
37
- "auto_kn" : True,
38
37
  "auto_type": True,
39
- "filter_train" : True,
40
- "split" : "RND",
41
38
  "model" : ['RF','GB','NN','MVL'],
42
39
  "eval_model" : 'MVL',
43
40
  "custom_params" : None,
44
41
  "type" : "reg",
45
- "epochs" : 0,
42
+ "split" : "even",
46
43
  "nprocs": 8,
47
44
  "error_type" : "rmse",
48
45
  "pfi_epochs" : 5,
49
- "pfi_threshold" : 0.04,
46
+ "pfi_threshold" : 0.2,
50
47
  "pfi_filter" : True,
51
48
  "pfi_max" : 0,
52
- "kfold" : 'auto',
49
+ "init_points" : 10,
50
+ "n_iter" : 10,
51
+ "expect_improv" : 0.05,
52
+ "kfold" : 5,
53
+ "repeat_kfolds" : 10,
53
54
  "alpha" : 0.05,
54
55
  "params_dir" : '',
55
56
  "csv_test" : '',
@@ -58,7 +59,7 @@ var_dict = {
58
59
  "pfi_show" : 10,
59
60
  "names" : '',
60
61
  "qdescp_keywords" : '',
61
- "csearch_keywords": '--sample 10',
62
+ "descp_lvl": "interpret",
62
63
  "report_modules" : ['AQME','CURATE','GENERATE','VERIFY','PREDICT'],
63
64
  "debug_report": False
64
65
  }
@@ -83,5 +84,5 @@ def set_options(kwargs):
83
84
  else:
84
85
  print("Warning! Option: [", key,":",kwargs[key],"] provided but no option exists, try the online documentation to see available options for each module.",)
85
86
  sys.exit()
86
-
87
+
87
88
  return options
@@ -0,0 +1,160 @@
1
+ """
2
+ Parameters
3
+ ----------
4
+
5
+ csv_name : str, default=''
6
+ Name of the CSV file containing the database. A path can be provided (i.e. 'C:/Users/FOLDER/FILE.csv').
7
+ y : str, default=''
8
+ Name of the column containing the response variable in the input CSV file (i.e. 'solubility').
9
+ discard : list, default=[]
10
+ List containing the columns of the input CSV file that will not be included as descriptors
11
+ in the curated CSV file (i.e. ['name','SMILES']).
12
+ ignore : list, default=[]
13
+ List containing the columns of the input CSV file that will be ignored during the curation process
14
+ (i.e. ['name','SMILES']). The descriptors will be included in the curated CSV file. The y value
15
+ is automatically ignored.
16
+ names : str, default=''
17
+ Column of the names for each datapoint. Names are used to print outliers.
18
+ destination : str, default=None,
19
+ Directory to create the output file(s).
20
+ varfile : str, default=None
21
+ Option to parse the variables using a yaml file (specify the filename, i.e. varfile=FILE.yaml).
22
+ categorical : str, default='onehot'
23
+ Mode to convert data from columns with categorical variables. As an example, a variable containing 4
24
+ types of C atoms (i.e. primary, secondary, tertiary, quaternary) will be converted into categorical
25
+ variables. Options:
26
+ 1. 'onehot' (for one-hot encoding, ROBERT will create a descriptor for each type of
27
+ C atom using 0s and 1s to indicate whether the C type is present)
28
+ 2. 'numbers' (to describe the C atoms with numbers: 1, 2, 3, 4).
29
+ corr_filter_x : bool, default=True
30
+ Activate the correlation filters of descriptors, based on the correlation
31
+ of the descriptors with other descriptors (x filter).
32
+ corr_filter_y : bool, default=False
33
+ Activate the correlation filters of descriptors, based on the correlation
34
+ of the descriptors with the y values (y filter, for noise). This filter is only
35
+ suggested for MVL.
36
+ desc_thres : float, default=25
37
+ Threshold for the descriptor-to-datapoints ratio to loose the correlation filter. By default,
38
+ the correlation filter is loosen if there are 25 times more datapoints than descriptors.
39
+ thres_x : float, default=0.7
40
+ Thresolhold to discard descriptors based on high R**2 correlation with other descriptors (i.e.
41
+ if thres_x=0.7, variables that show R**2 > 0.7 will be discarded).
42
+ thres_y : float, default=0.001
43
+ Thresolhold to discard descriptors with poor correlation with the y values based on R**2 (i.e.
44
+ if thres_y=0.001, variables that show R**2 < 0.001 will be discarded).
45
+ seed : int, default=0
46
+ Random seed used in RFECV feature selector and other protocols.
47
+ kfold : int, default=5
48
+ Number of random data splits for the cross-validation of the RFECV feature selector.
49
+ repeat_kfolds : int, default=10
50
+ Number of repetitions for the k-fold cross-validation of the RFECV feature selector.
51
+ auto_type : bool, default=True
52
+ If there are only two y values, the program automatically changes the type of problem to classification.
53
+
54
+
55
+ """
56
+ #####################################################.
57
+ # This file stores the CURATE class #
58
+ # used in data curation #
59
+ #####################################################.
60
+
61
+ import time
62
+ import os
63
+ import pandas as pd
64
+ from robert.utils import (load_variables, finish_print, load_database, pearson_map,
65
+ check_clas_problem, categorical_transform, correlation_filter)
66
+
67
+
68
+ class curate:
69
+ """
70
+ Class containing all the functions from the CURATE module.
71
+
72
+ Parameters
73
+ ----------
74
+ kwargs : argument class
75
+ Specify any arguments from the CURATE module (for a complete list of variables, visit the ROBERT documentation)
76
+ """
77
+
78
+ def __init__(self, **kwargs):
79
+
80
+ start_time = time.time()
81
+
82
+ # load default and user-specified variables
83
+ self.args = load_variables(kwargs, "curate")
84
+
85
+ # load database, discard user-defined descriptors and perform data checks
86
+ csv_df,_,_ = load_database(self,self.args.csv_name,"curate")
87
+
88
+ # adjust options of classification problems and detects whether the right type of problem was used
89
+ self = check_clas_problem(self,csv_df)
90
+
91
+ if not self.args.evaluate:
92
+ # transform categorical descriptors
93
+ csv_df = categorical_transform(self,csv_df,'curate')
94
+
95
+ # apply duplicate filters (i.e., duplication of datapoints or descriptors)
96
+ csv_df = self.dup_filter(csv_df)
97
+
98
+ # apply the correlation filters and returns the database without correlated descriptors
99
+ if self.args.corr_filter_x or self.args.corr_filter_y:
100
+ csv_df = correlation_filter(self,csv_df)
101
+
102
+ # save the curated CSV
103
+ _ = self.save_curate(csv_df)
104
+
105
+ # create Pearson heatmap
106
+ _ = pearson_map(self,csv_df,'curate')
107
+
108
+ # finish the printing of the CURATE info file
109
+ _ = finish_print(self,start_time,'CURATE')
110
+
111
+
112
+ def dup_filter(self,csv_df_dup):
113
+ '''
114
+ Removes duplicated datapoints and descriptors
115
+ '''
116
+
117
+ txt_dup = f'\no Duplication filters activated'
118
+ txt_dup += f'\n Excluded datapoints:'
119
+
120
+ # remove duplicated entries
121
+ datapoint_drop = []
122
+ for i,datapoint in enumerate(csv_df_dup.duplicated()):
123
+ if datapoint:
124
+ datapoint_drop.append(i)
125
+ for datapoint in datapoint_drop:
126
+ txt_dup += f'\n - Datapoint number {datapoint}'
127
+
128
+ if len(datapoint_drop) == 0:
129
+ txt_dup += f'\n - No datapoints were removed'
130
+
131
+ csv_df_dup = csv_df_dup.drop(datapoint_drop, axis=0)
132
+
133
+ csv_df_dup.reset_index(drop=True)
134
+ self.args.log.write(txt_dup)
135
+
136
+ return csv_df_dup
137
+
138
+
139
+ def save_curate(self,csv_df):
140
+ '''
141
+ Saves the curated database and options used in CURATE
142
+ '''
143
+
144
+ # saves curated database
145
+ csv_basename = os.path.basename(f'{self.args.csv_name}').split('.')[0]
146
+ csv_curate_name = f'{csv_basename}_CURATE.csv'
147
+ csv_curate_name = self.args.destination.joinpath(csv_curate_name)
148
+ _ = csv_df.to_csv(f'{csv_curate_name}', index = None, header=True)
149
+ path_reduced = '/'.join(f'{csv_curate_name}'.replace('\\','/').split('/')[-2:])
150
+ self.args.log.write(f'\no The curated database was stored in {path_reduced}.')
151
+
152
+ # saves important options used in CURATE
153
+ options_name = f'CURATE_options.csv'
154
+ options_name = self.args.destination.joinpath(options_name)
155
+ options_df = pd.DataFrame()
156
+ options_df['y'] = [self.args.y]
157
+ options_df['ignore'] = [self.args.ignore]
158
+ options_df['names'] = [self.args.names]
159
+ options_df['csv_name'] = [csv_curate_name]
160
+ _ = options_df.to_csv(f'{options_name}', index = None, header=True)
@@ -22,6 +22,8 @@ GENERAL
22
22
  Type of the pedictions. Options:
23
23
  1. 'reg' (Regressor)
24
24
  2. 'clas' (Classifier)
25
+ seed : int, default=0
26
+ Random seed used in the ML predictor models and other protocols.
25
27
  destination : str, default=None,
26
28
  Directory to create the output file(s).
27
29
 
@@ -58,9 +60,10 @@ Affect PREDICT
58
60
  Affect VERIFY and PREDICT
59
61
  +++++++++++++++++++++++++
60
62
 
61
- kfold : int, default='auto',
62
- Number of folds for the k-fold cross-validation. If 'auto', the program does
63
- a LOOCV for databases with less than 50 points, and 5-fold CV for larger databases
63
+ kfold : int, default=5
64
+ Number of random data splits for the cross-validation of the models.
65
+ repeat_kfolds : int, default=10
66
+ Number of repetitions for the k-fold cross-validation of the models.
64
67
 
65
68
  """
66
69
  #####################################################.
@@ -109,12 +112,12 @@ class evaluate:
109
112
  Load databases, merge them and save CSV (tracking the test types using the Set column)
110
113
  '''
111
114
 
112
- csv_df_train = load_database(self,self.args.csv_train,"evaluate")
115
+ csv_df_train,_,_ = load_database(self,self.args.csv_train,"evaluate",print_info=False)
113
116
  csv_df_train['Set'] = ['Training'] * len(csv_df_train[self.args.y])
114
- csv_df_valid = load_database(self,self.args.csv_valid,"evaluate")
117
+ csv_df_valid,_,_ = load_database(self,self.args.csv_valid,"evaluate",print_info=False)
115
118
  csv_df_valid['Set'] = ['Validation'] * len(csv_df_valid[self.args.y])
116
119
  if self.args.csv_test != '':
117
- csv_df_test = load_database(self,self.args.csv_test,"evaluate")
120
+ csv_df_test,_,_ = load_database(self,self.args.csv_test,"evaluate",print_info=False)
118
121
  csv_df_test['Set'] = ['Test'] * len(csv_df_test[self.args.y])
119
122
 
120
123
  self.args.ignore.append('Set')
@@ -163,12 +166,11 @@ class evaluate:
163
166
  train_points = len(csv_df_train[self.args.y])
164
167
  valid_points = len(csv_df_valid[self.args.y])
165
168
  df_params['train'] = [train_proportion]
166
- df_params['split'] = ['user-defined']
169
+ df_params['kfold'] = [self.args.kfold]
170
+ df_params['repeat_kfolds'] = [self.args.repeat_kfolds]
167
171
  df_params['model'] = [self.args.eval_model]
168
172
  df_params['type'] = [self.args.type]
169
- if self.args.seed == []:
170
- self.args.seed = [0]
171
- df_params['seed'] = [self.args.seed[0]]
173
+ df_params['seed'] = [self.args.seed]
172
174
  df_params['y'] = [self.args.y]
173
175
  df_params['names'] = [self.args.names]
174
176
  df_params['error_type'] = [self.args.error_type]