robert 2.0.0__tar.gz → 2.0.2__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 (77) hide show
  1. {robert-2.0.0 → robert-2.0.2}/PKG-INFO +8 -2
  2. {robert-2.0.0 → robert-2.0.2}/README.md +11 -7
  3. {robert-2.0.0 → robert-2.0.2}/robert/aqme.py +1 -1
  4. {robert-2.0.0 → robert-2.0.2}/robert/curate.py +2 -2
  5. {robert-2.0.0 → robert-2.0.2}/robert/generate.py +11 -3
  6. robert-2.0.2/robert/icons/Robert_icon.png +0 -0
  7. robert-2.0.2/robert/icons/Robert_logo_transparent.png +0 -0
  8. robert-2.0.2/robert/icons/info_icon.png +0 -0
  9. robert-2.0.2/robert/icons/pdf_icon.png +0 -0
  10. robert-2.0.2/robert/icons/play_icon.png +0 -0
  11. robert-2.0.2/robert/icons/stop_icon.png +0 -0
  12. {robert-2.0.0 → robert-2.0.2}/robert/predict_utils.py +9 -8
  13. robert-2.0.2/robert/report/Robert_logo.jpg +0 -0
  14. {robert-2.0.0 → robert-2.0.2}/robert/report.py +6 -14
  15. {robert-2.0.0 → robert-2.0.2}/robert/report_utils.py +240 -105
  16. {robert-2.0.0 → robert-2.0.2}/robert/robert.py +1 -7
  17. {robert-2.0.0 → robert-2.0.2}/robert/utils.py +114 -41
  18. {robert-2.0.0 → robert-2.0.2}/robert.egg-info/PKG-INFO +8 -2
  19. {robert-2.0.0 → robert-2.0.2}/robert.egg-info/SOURCES.txt +7 -0
  20. {robert-2.0.0 → robert-2.0.2}/robert.egg-info/requires.txt +4 -0
  21. {robert-2.0.0 → robert-2.0.2}/setup.py +9 -3
  22. {robert-2.0.0 → robert-2.0.2}/tests/test_2generate.py +19 -29
  23. {robert-2.0.0 → robert-2.0.2}/tests/test_3verify.py +12 -11
  24. {robert-2.0.0 → robert-2.0.2}/tests/test_4predict.py +9 -5
  25. {robert-2.0.0 → robert-2.0.2}/tests/test_5aqme_n_full.py +117 -71
  26. {robert-2.0.0 → robert-2.0.2}/LICENSE +0 -0
  27. {robert-2.0.0 → robert-2.0.2}/robert/__init__.py +0 -0
  28. {robert-2.0.0 → robert-2.0.2}/robert/__main__.py +0 -0
  29. {robert-2.0.0 → robert-2.0.2}/robert/argument_parser.py +0 -0
  30. {robert-2.0.0 → robert-2.0.2}/robert/evaluate.py +0 -0
  31. {robert-2.0.0 → robert-2.0.2}/robert/generate_utils.py +0 -0
  32. {robert-2.0.0/robert/report → robert-2.0.2/robert/icons}/Robert_logo.jpg +0 -0
  33. {robert-2.0.0 → robert-2.0.2}/robert/model_params/ADAB_params.yaml +0 -0
  34. {robert-2.0.0 → robert-2.0.2}/robert/model_params/GB_params.yaml +0 -0
  35. {robert-2.0.0 → robert-2.0.2}/robert/model_params/GP_params.yaml +0 -0
  36. {robert-2.0.0 → robert-2.0.2}/robert/model_params/MVL_params.yaml +0 -0
  37. {robert-2.0.0 → robert-2.0.2}/robert/model_params/NN_params.yaml +0 -0
  38. {robert-2.0.0 → robert-2.0.2}/robert/model_params/RF_params.yaml +0 -0
  39. {robert-2.0.0 → robert-2.0.2}/robert/model_params/VR_params.yaml +0 -0
  40. {robert-2.0.0 → robert-2.0.2}/robert/predict.py +0 -0
  41. {robert-2.0.0 → robert-2.0.2}/robert/report/Robert_icon.ico +0 -0
  42. {robert-2.0.0 → robert-2.0.2}/robert/report/Robert_logo1.jpg +0 -0
  43. {robert-2.0.0 → robert-2.0.2}/robert/report/abbrev.png +0 -0
  44. {robert-2.0.0 → robert-2.0.2}/robert/report/adv_anal.png +0 -0
  45. {robert-2.0.0 → robert-2.0.2}/robert/report/features.png +0 -0
  46. {robert-2.0.0 → robert-2.0.2}/robert/report/generate.png +0 -0
  47. {robert-2.0.0 → robert-2.0.2}/robert/report/outliers.png +0 -0
  48. {robert-2.0.0 → robert-2.0.2}/robert/report/pred.png +0 -0
  49. {robert-2.0.0 → robert-2.0.2}/robert/report/repro.png +0 -0
  50. {robert-2.0.0 → robert-2.0.2}/robert/report/score.png +0 -0
  51. {robert-2.0.0 → robert-2.0.2}/robert/report/score_0.jpg +0 -0
  52. {robert-2.0.0 → robert-2.0.2}/robert/report/score_1.jpg +0 -0
  53. {robert-2.0.0 → robert-2.0.2}/robert/report/score_10.jpg +0 -0
  54. {robert-2.0.0 → robert-2.0.2}/robert/report/score_2.jpg +0 -0
  55. {robert-2.0.0 → robert-2.0.2}/robert/report/score_3.jpg +0 -0
  56. {robert-2.0.0 → robert-2.0.2}/robert/report/score_4.jpg +0 -0
  57. {robert-2.0.0 → robert-2.0.2}/robert/report/score_5.jpg +0 -0
  58. {robert-2.0.0 → robert-2.0.2}/robert/report/score_6.jpg +0 -0
  59. {robert-2.0.0 → robert-2.0.2}/robert/report/score_7.jpg +0 -0
  60. {robert-2.0.0 → robert-2.0.2}/robert/report/score_8.jpg +0 -0
  61. {robert-2.0.0 → robert-2.0.2}/robert/report/score_9.jpg +0 -0
  62. {robert-2.0.0 → robert-2.0.2}/robert/report/score_w_1_0.jpg +0 -0
  63. {robert-2.0.0 → robert-2.0.2}/robert/report/score_w_1_1.jpg +0 -0
  64. {robert-2.0.0 → robert-2.0.2}/robert/report/score_w_2_0.jpg +0 -0
  65. {robert-2.0.0 → robert-2.0.2}/robert/report/score_w_2_1.jpg +0 -0
  66. {robert-2.0.0 → robert-2.0.2}/robert/report/score_w_2_2.jpg +0 -0
  67. {robert-2.0.0 → robert-2.0.2}/robert/report/score_w_3_0.jpg +0 -0
  68. {robert-2.0.0 → robert-2.0.2}/robert/report/score_w_3_1.jpg +0 -0
  69. {robert-2.0.0 → robert-2.0.2}/robert/report/score_w_3_2.jpg +0 -0
  70. {robert-2.0.0 → robert-2.0.2}/robert/report/score_w_3_3.jpg +0 -0
  71. {robert-2.0.0 → robert-2.0.2}/robert/report/transpa.png +0 -0
  72. {robert-2.0.0 → robert-2.0.2}/robert/report/y_distrib.png +0 -0
  73. {robert-2.0.0 → robert-2.0.2}/robert/verify.py +0 -0
  74. {robert-2.0.0 → robert-2.0.2}/robert.egg-info/dependency_links.txt +0 -0
  75. {robert-2.0.0 → robert-2.0.2}/robert.egg-info/top_level.txt +0 -0
  76. {robert-2.0.0 → robert-2.0.2}/setup.cfg +0 -0
  77. {robert-2.0.0 → robert-2.0.2}/tests/test_1curate.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: robert
3
- Version: 2.0.0
3
+ Version: 2.0.2
4
4
  Summary: Refiner and Optimizer of a Bunch of Existing Regression Tools
5
5
  Home-page: https://github.com/jvalegre/robert
6
- Download-URL: https://github.com/jvalegre/robert/archive/refs/tags/2.0.0.tar.gz
6
+ Download-URL: https://github.com/jvalegre/robert/archive/refs/tags/2.0.2.tar.gz
7
7
  Author: Juan V. Alegre Requena, David Dalmau
8
8
  Author-email: jv.alegre@csic.es
9
9
  License: MIT
@@ -16,6 +16,8 @@ Classifier: Programming Language :: Python :: 3.7
16
16
  Classifier: Programming Language :: Python :: 3.8
17
17
  Classifier: Programming Language :: Python :: 3.9
18
18
  Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
19
21
  Requires-Python: >=3.10
20
22
  Description-Content-Type: text/markdown
21
23
  License-File: LICENSE
@@ -31,5 +33,9 @@ Requires-Dist: bayesian-optimization==3.0.0b1
31
33
  Requires-Dist: numba==0.60.0
32
34
  Requires-Dist: shap==0.46.0
33
35
  Requires-Dist: weasyprint==63.1
36
+ Requires-Dist: PySide6
37
+ Requires-Dist: PyMuPDF
38
+ Requires-Dist: ansi2html
39
+ Requires-Dist: rdkit==2024.3.3
34
40
 
35
41
  Documentation in Read The Docs: https://robert.readthedocs.io
@@ -17,17 +17,20 @@ Don't miss out the latest hands-on tutorials from our [YouTube channel](https://
17
17
  ## Recommended installation
18
18
  1. (Only once) Create new conda environment: `conda create -n robert python=3.10`
19
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`
20
+ 3. Install ROBERT using pip: `pip install robert`
21
+ 4. Install RDKit (only if you plan to use easyROB): `pip install rdkit`
22
+ 5. Install libraries for the PDF report `conda install -y -c conda-forge glib gtk3 pango mscorefonts`
23
+ 6. (Only for compatible devices) Install Intelex accelerator: `pip install scikit-learn-intelex==2025.2.0`
23
24
  * Inexperienced users should visit the *Users with no Python experience* section in [Read the Docs](https://robert.readthedocs.io).
24
25
  ## Update the program
25
- 1. Update to the latest version: `pip install robert --upgrade`
26
+ 1. Update to the latest version: `pip install robert --upgrade`
26
27
 
27
28
  ## Developers and help desk
28
29
  List of main developers and contact emails:
29
30
  - [ ] [Juan V. Alegre-Requena](https://orcid.org/0000-0002-0769-7168). Contact: [jv.alegre@csic.es](mailto:jv.alegre@csic.es)
30
- - [ ] [David Dalmau Ginesta](https://orcid.org/0000-0002-2506-6546). Contact: [ddalmau@unizar.es](mailto:ddalmau@unizar.es)
31
+ - [ ] [David Dalmau Ginesta](https://orcid.org/0000-0002-2506-6546). Contact: [ddalmau@unizar.es](mailto:ddalmau@unizar.es)
32
+ - [ ] [Miguel Martinez Fernandez](https://orcid.org/0009-0002-8538-7250). Contact [miguel.martinez@csic.es](mailto:miguel.martinez@csic.es)
33
+ - [ ] [Luis Giner Tendero](https://github.com/LlGinerT/). Contact [lginertendero@gmail.com](mailto:lginertendero@gmail.com)
31
34
 
32
35
  For suggestions and improvements of the code (greatly appreciated!), please reach out through the issues and pull requests options of Github.
33
36
 
@@ -58,6 +61,7 @@ If you use any of the ROBERT modules, please include this citation:
58
61
  If you use the AQME module, please include this citation:
59
62
  * Alegre-Requena et al., AQME: Automated Quantum Mechanical Environments for Researchers and Educators. *Wiley Interdiscip. Rev. Comput. Mol. Sci.* **2023**, *13*, e1663.
60
63
 
61
- Additionally, please include the corresponding reference for Scikit-learn and SHAP:
64
+ Additionally, please include the corresponding reference for Scikit-learn, SHAP and BayesianOptimization:
62
65
  * 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.
66
+ * Lundberg et al., From local explanations to global understanding with explainable AI for trees. *Nat. Mach. Intell.* **2020**, *2*, 56–67.
67
+ * Fernando Nogueira, {Bayesian Optimization}: Open source constrained global optimization tool for {Python}, **2014**, https://github.com/bayesian-optimization/BayesianOptimization
@@ -125,7 +125,7 @@ class aqme:
125
125
  aqme_indv_name = f'AQME_indiv_{smi_suffix}'
126
126
 
127
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']
128
+ cmd_qdescp = ['python','-u', '-m', 'aqme', '--qdescp', '--input', f'{aqme_indv_name}.csv', '--program', 'xtb', '--csv_name', f'{aqme_indv_name}.csv', '--nprocs', f'{self.args.nprocs}', '--robert']
129
129
  _ = self.run_aqme(cmd_qdescp, self.args.qdescp_keywords)
130
130
 
131
131
  if smi_suffix is not None:
@@ -8,10 +8,10 @@ Parameters
8
8
  Name of the column containing the response variable in the input CSV file (i.e. 'solubility').
9
9
  discard : list, default=[]
10
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']).
11
+ in the curated CSV file (i.e. "['name','SMILES']").
12
12
  ignore : list, default=[]
13
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
14
+ (i.e. "['name','SMILES']"). The descriptors will be included in the curated CSV file. The y value
15
15
  is automatically ignored.
16
16
  names : str, default=''
17
17
  Column of the names for each datapoint. Names are used to print outliers.
@@ -63,15 +63,23 @@ Parameters
63
63
  Number of features to keep after the PFI filter. If pfi_max is 0, all the features that pass the PFI
64
64
  filter are used.
65
65
  auto_test : bool, default=True
66
- Raises % of test points to 10% if test_set is lower than that.
67
- test_set : float, default=0.1
68
- Amount of datapoints to separate as external test set (0.1 = 10%). These points will not be used during the
66
+ Raises % of test points to 20% if test_set is lower than that.
67
+ test_set : float, default=0.2
68
+ Amount of datapoints to separate as external test set (0.2 = 20%). These points will not be used during the
69
69
  hyperoptimization, and PREDICT will use the points as test set during ROBERT workflows. Select
70
70
  --test_set 0 to use only training and validation.
71
71
  kfold : int, default=5
72
72
  Number of random data splits for the cross-validation of the models.
73
73
  repeat_kfolds : int, default=10
74
74
  Number of repetitions for the k-fold cross-validation of the models.
75
+ split : str, default='even'
76
+ Specifies how the data is split into training and test sets. Options:
77
+ 1. 'even': splits the data evenly into training and test sets.
78
+ 2. 'RND': randomly splits the data.
79
+ 3. 'stratified': splits the data while preserving the distribution of the target variable.
80
+ 4. 'KN': uses a k-means approach to select representative samples.
81
+ 5. 'EXTRA_Q1': selects the 10% lowest values.
82
+ 6. 'EXTRA_Q5': selects the 10% highest values.
75
83
 
76
84
  """
77
85
  #####################################################.
Binary file
Binary file
Binary file
Binary file
@@ -61,14 +61,15 @@ def plot_predictions(self, params_dict, Xy_data, path_n_suffix):
61
61
  # Plot CV average ± SD graph of validation or test set
62
62
  _ = graph_reg(self,Xy_data,params_dict,set_types,path_n_suffix,graph_style,sd_graph=True)
63
63
  if 'y_external' in Xy_data and not Xy_data['y_external'].isnull().values.any() and len(Xy_data['y_external']) > 0:
64
- # Plot CV average ± SD graph of validation or test set
65
- _ = graph_reg(self,Xy_data,params_dict,set_types,path_n_suffix,graph_style,csv_test=True,sd_graph=True)
64
+ # Plot CV average ± SD graph of external set
65
+ set_type = 'external'
66
+ _ = graph_reg(self,Xy_data,params_dict,set_type,path_n_suffix,graph_style,csv_test=True,sd_graph=True)
66
67
 
67
68
  elif params_dict['type'].lower() == 'clas':
68
69
  for set_type in set_types:
69
70
  _ = graph_clas(self,Xy_data,params_dict,set_type,path_n_suffix)
70
- if 'y_pred_csv_test' in Xy_data and not Xy_data['y_csv_test'].isnull().values.any() and len(Xy_data['y_csv_test']) > 0:
71
- set_type = 'csv_test'
71
+ if 'y_external' in Xy_data and not Xy_data['y_external'].isnull().values.any() and len(Xy_data['y_external']) > 0:
72
+ set_type = 'external'
72
73
  _ = graph_clas(self,Xy_data,params_dict,set_type,path_n_suffix,csv_test=True)
73
74
 
74
75
  return graph_style
@@ -182,11 +183,11 @@ def print_predict(self,Xy_data,model_data,suffix_title):
182
183
  print_results += f"\n - External test : R2 = {Xy_data['r2_external']:.2}, MAE = {Xy_data['mae_external']:.2}, RMSE = {Xy_data['rmse_external']:.2}"
183
184
 
184
185
  elif model_data['type'].lower() == 'clas':
185
- print_results += f"\n - {CV_type} : Accuracy = {Xy_data['acc_train']:.2}, F1 score = {Xy_data['f1_train']:.2}, MCC = {Xy_data['mcc_train']:.2}"
186
+ print_results += f"\n - {CV_type} : Accur. = {Xy_data['acc_train']:.2}, F1 score = {Xy_data['f1_train']:.2}, MCC = {Xy_data['mcc_train']:.2}"
186
187
  if 'y_pred_test' in Xy_data and not Xy_data['y_test'].isnull().values.any() and len(Xy_data['y_test']) > 0:
187
- print_results += f"\n - Test : Accuracy = {Xy_data['acc_test']:.2}, F1 score = {Xy_data['f1_test']:.2}, MCC = {Xy_data['mcc_test']:.2}"
188
- if 'y_pred_csv_test' in Xy_data and not Xy_data['y_csv_test'].isnull().values.any() and len(Xy_data['y_csv_test']) > 0:
189
- print_results += f"\n - csv_test : Accur. = {Xy_data['acc_csv_test']:.2}, F1 score = {Xy_data['f1_csv_test']:.2}, MCC = {Xy_data['mcc_csv_test']:.2}"
188
+ print_results += f"\n - Test : Accur. = {Xy_data['acc_test']:.2}, F1 score = {Xy_data['f1_test']:.2}, MCC = {Xy_data['mcc_test']:.2}"
189
+ if 'y_external' in Xy_data and not Xy_data['y_external'].isnull().values.any() and len(Xy_data['y_external']) > 0:
190
+ print_results += f"\n - External test : Accur. = {Xy_data['acc_external']:.2}, F1 score = {Xy_data['f1_external']:.2}, MCC = {Xy_data['mcc_external']:.2}"
190
191
 
191
192
  self.args.log.write(print_results)
192
193
 
@@ -342,7 +342,7 @@ class report:
342
342
  if data_score[f'cv_sd_score_{suffix}'] == 0:
343
343
  warnings_dict[f'moderate_warnings_{suffix}'].append('Imprecise predictions (Section B.3b)')
344
344
  elif pred_type == 'clas':
345
- if data_score[f'r2_diff_score_{suffix}'] == 0:
345
+ if data_score[f'diff_mcc_score_{suffix}'] == 0:
346
346
  warnings_dict[f'moderate_warnings_{suffix}'].append('Imprecise predictions (Section B.3b)')
347
347
 
348
348
  # y distribution
@@ -528,11 +528,11 @@ class report:
528
528
 
529
529
  elif section == 'adv_sorted_cv':
530
530
  # advanced score analysis 3d, descriptor proportion
531
- columns_score.append(adv_sorted_cv(self,suffix,data_score,spacing*2))
531
+ columns_score.append(adv_sorted_cv(self,suffix,data_score,spacing*2,pred_type))
532
532
 
533
533
  elif section == 'adv_cv_diff' and pred_type == 'clas':
534
534
  # advanced score analysis 3b, difference of MCC in model and CV
535
- columns_score.append(adv_cv_diff(self,suffix,data_score,spacing*2))
535
+ columns_score.append(adv_cv_diff(self,suffix,data_score,spacing*2,pred_type))
536
536
 
537
537
  # Combine both columns
538
538
  adv_score_dat += combine_cols(columns_score)
@@ -889,9 +889,9 @@ class report:
889
889
  if aqme_workflow:
890
890
  if not find_aqme:
891
891
  repro_dat += f"""{reduced_line}{space}- AQME is required, but no version was found:</p>"""
892
- repro_dat += f"""{reduced_line}{space}- Install AQME and its dependencies: conda install -y -c conda-forge aqme</p>"""
892
+ repro_dat += f"""{reduced_line}{space}- Install AQME and its dependencies: pip install aqme==VERSION_USED</p>"""
893
893
  if find_aqme:
894
- repro_dat += f"""{reduced_line}{space}- Adjust AQME version: pip install aqme=={aqme_version}</p>"""
894
+ repro_dat += f"""{reduced_line}{space}- Install or adjust AQME version: pip install aqme=={aqme_version}</p>"""
895
895
 
896
896
  try:
897
897
  path_xtb = Path(f'{os.getcwd()}/AQME/QDESCP')
@@ -1163,15 +1163,7 @@ class report:
1163
1163
  if pred_type.lower() == 'reg':
1164
1164
  results_images = [str(file_path) for file_path in module_path.rglob(f'{file_name}_*.png')]
1165
1165
  elif pred_type.lower() == 'clas':
1166
- results_images = []
1167
- all_images = [str(file_path) for file_path in module_path.rglob('*.png')]
1168
- for img in all_images:
1169
- if 'test' in set_types:
1170
- if file_name in img and '_test.png' in img:
1171
- results_images.append(img)
1172
- else:
1173
- if file_name in img and '_valid.png' in img:
1174
- results_images.append(img)
1166
+ results_images = [str(file_path) for file_path in module_path.rglob(f'{file_name}_*.png')]
1175
1167
  # images with no suffixes in the names
1176
1168
  else:
1177
1169
  results_images = [str(file_path) for file_path in module_path.rglob(f'{file_name}_*.png')]