3v324v23 Claude Code commited on
Commit
af42f98
·
2 Parent(s): c4dd4c097476e1

Merge perf/startup-and-request-speed into main

Browse files

- Replace Excel files with Parquet for faster startup
- LRU-cache QRF pickle models
- Reduce N_sample from 1e6 to 1e5
- Initialize Mordred Calculator once at module level
- Remove unused modules and dead code
- Track large/binary files with LFS

Co-Authored-By: Claude Code <noreply@anthropic.com>

.gitignore CHANGED
@@ -11,4 +11,6 @@ color_module/static/.DS_Store
11
  *.bkup
12
  tools/
13
  chris.tar.gz
 
 
14
 
 
11
  *.bkup
12
  tools/
13
  chris.tar.gz
14
+ *.xlsx
15
+ CLAUDE.md
16
 
convert_to_parquet.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ One-time script to convert large Excel data files to Parquet format for faster loading.
3
+ Run from the repo root: python convert_to_parquet.py
4
+ """
5
+ import pandas as pd
6
+
7
+ files = [
8
+ ('qrf/db-D-interp-allT-semiclean.xlsx', 'qrf/db-D-interp-allT-semiclean.parquet', {}),
9
+ ('qrf/mordred-descriptors.xlsx', 'qrf/mordred-descriptors.parquet', {}),
10
+ ('quantity_module/data/db-D-interp-allT-clean.xlsx', 'quantity_module/data/db-D-interp-allT-clean.parquet', {}),
11
+ ('quantity_module/data/data-descriptors-mordred-numconfs51.xlsx', 'quantity_module/data/data-descriptors-mordred-numconfs51.parquet', {'usecols': ['Solute_InChIKey', 'Vabc', 'VMcGowan']}),
12
+ ('quantity_module/data/solvent-viscosity.xlsx', 'quantity_module/data/solvent-viscosity.parquet', {}),
13
+ ('quantity_module/data/vrentas-duda-params.xlsx', 'quantity_module/data/vrentas-duda-params-solutes.parquet', {'sheet_name': 'Solutes'}),
14
+ ('quantity_module/data/vrentas-duda-params.xlsx', 'quantity_module/data/vrentas-duda-params-polymers.parquet', {'sheet_name': 'Polymers'}),
15
+ ('qrf/qrf_parameters_allT.xlsx', 'qrf/qrf_parameters_allT.parquet', {}),
16
+ ('data/db-polymer-properties-and-categories.xlsx', 'data/db-polymer-properties-and-categories.parquet', {}),
17
+ ('quantity_module/data/db-D-interp-37-clean.xlsx', 'quantity_module/data/db-D-interp-37-clean.parquet', {}),
18
+ ('quantity_module/data/db-D-interp-50-clean.xlsx', 'quantity_module/data/db-D-interp-50-clean.parquet', {}),
19
+ ]
20
+
21
+ for src, dst, kwargs in files:
22
+ print(f'Converting {src} -> {dst} ...')
23
+ df = pd.read_excel(src, **kwargs)
24
+ # Coerce mixed-type object columns to numeric where possible so parquet can handle them
25
+ for col in df.select_dtypes(include='object').columns:
26
+ converted = pd.to_numeric(df[col], errors='coerce')
27
+ if converted.notna().sum() > 0:
28
+ df[col] = converted
29
+ df.to_parquet(dst, index=False)
30
+ print(f' done ({len(df)} rows)')
31
+
32
+ print('All conversions complete.')
data/{db-polymer-properties-and-categories.xlsx → db-polymer-properties-and-categories.parquet} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:694283f4bd9d9815738f0aaf451d28cfa4f239a03b908116af84b84a76795735
3
- size 26083
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:36247c7305dad04c700ab49ff2f19ab1295b695062e8c98738e6f7e595b4e690
3
+ size 27591
mp/model-opera-knn-alldata.xlsx → qrf/db-D-interp-allT-semiclean.parquet RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:52547e54fc469bb5899c71c8ac12167a9661dfccb6a769799e4b0e89da30015e
3
- size 6551311
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:53f0371780a12bb9c70397b32e4633c8913c3439312ef1686d3f57d2854d3a08
3
+ size 2533547
qrf/db-D-interp-allT-semiclean.xlsx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:6c5c4399929d0bb5f72e3fee3896058e7accfbf68d63df155e409a4c2b6b87a2
3
- size 13087796
 
 
 
 
qrf/functions.py CHANGED
@@ -1,5 +1,6 @@
1
  import sys
2
  import pickle
 
3
  import numpy as np
4
  import pandas as pd
5
  import sklearn
@@ -9,18 +10,28 @@ import mordred.descriptors
9
  import rdkit
10
  from rdkit import Chem
11
 
 
 
 
 
 
12
  QRF_T_list = np.array([25,30,35,37,40,45,50,55,60,65,70,75])
13
  QRF_T_cut = 2.5
14
- df_QRF = pd.read_excel('qrf/db-D-interp-allT-semiclean.xlsx')
15
- df_desc = pd.read_excel('qrf/mordred-descriptors.xlsx')
16
- calc = mordred.Calculator(mordred.descriptors)
17
- colnames_mordred = [str(d) for d in calc.descriptors]
18
  df_QRF = pd.merge(df_QRF, df_desc[['Solute_InChIKey',*colnames_mordred]], how='left', on='Solute_InChIKey', suffixes=('', '_dupe'))
19
 
 
 
 
 
 
 
20
  def QRF_Ceramic(density, polytg, quantiles=[0.03,0.5,0.97], T=37, worstcase='hi'):
21
  nearest_T = QRF_T_list[np.abs(T-QRF_T_list).argmin()]
22
- with open(f'qrf/qrf_model_bundle_{int(nearest_T)}.pkl','rb') as f:
23
- reg, imp, scaler_X, sub_desc_list = pickle.load(f)
24
  #df_X = pd.read_excel('qrf/qrf_x.xlsx')
25
  #df_y = pd.read_excel('qrf/qrf_y.xlsx')
26
  mask_T = (df_QRF['T']>nearest_T-QRF_T_cut) & (df_QRF['T']<nearest_T+QRF_T_cut)
@@ -53,17 +64,14 @@ def QRF_Ceramic(density, polytg, quantiles=[0.03,0.5,0.97], T=37, worstcase='hi'
53
  def QRF_Apply(density, polytg, smiles, quantiles=[0.03,0.5,0.97], T=37):
54
  """T and Tg in C"""
55
  nearest_T = QRF_T_list[np.abs(T-QRF_T_list).argmin()]
56
- with open(f'qrf/qrf_model_bundle_{int(nearest_T)}.pkl','rb') as f:
57
- reg, imp, scaler_X, sub_desc_list = pickle.load(f)
58
  # get list of descriptors to calculate
59
  solute_desc_list = sub_desc_list.copy()
60
  if 'Polymer_Tg' in solute_desc_list:
61
  solute_desc_list.remove('Polymer_Tg')
62
  if 'Polymer_Density' in solute_desc_list:
63
  solute_desc_list.remove('Polymer_Density')
64
- calc_all = mordred.Calculator(mordred.descriptors)
65
- desc_strs = [str(d) for d in calc_all.descriptors]
66
- desc_funcs = {d1:df for d1 in solute_desc_list for d2,df in zip(desc_strs,calc_all.descriptors) if d1 == d2}
67
  calc = mordred.Calculator(list(desc_funcs.values()))
68
  m = Chem.MolFromSmiles(smiles)
69
  m = Chem.AddHs(m)
 
1
  import sys
2
  import pickle
3
+ import functools
4
  import numpy as np
5
  import pandas as pd
6
  import sklearn
 
10
  import rdkit
11
  from rdkit import Chem
12
 
13
+ # Build a single shared Calculator and descriptor lookup once at startup.
14
+ # This is cheaper than re-instantiating mordred.Calculator on every request.
15
+ _calc_all = mordred.Calculator(mordred.descriptors)
16
+ _desc_by_name = {str(d): d for d in _calc_all.descriptors}
17
+
18
  QRF_T_list = np.array([25,30,35,37,40,45,50,55,60,65,70,75])
19
  QRF_T_cut = 2.5
20
+ df_QRF = pd.read_parquet('qrf/db-D-interp-allT-semiclean.parquet')
21
+ df_desc = pd.read_parquet('qrf/mordred-descriptors.parquet')
22
+ # Use column names from df_desc directly instead of initializing a full mordred Calculator
23
+ colnames_mordred = [c for c in df_desc.columns if c != 'Solute_InChIKey']
24
  df_QRF = pd.merge(df_QRF, df_desc[['Solute_InChIKey',*colnames_mordred]], how='left', on='Solute_InChIKey', suffixes=('', '_dupe'))
25
 
26
+ @functools.lru_cache(maxsize=None)
27
+ def _load_qrf_model(T):
28
+ """Load and cache QRF model bundle for a given temperature."""
29
+ with open(f'qrf/qrf_model_bundle_{int(T)}.pkl', 'rb') as f:
30
+ return pickle.load(f)
31
+
32
  def QRF_Ceramic(density, polytg, quantiles=[0.03,0.5,0.97], T=37, worstcase='hi'):
33
  nearest_T = QRF_T_list[np.abs(T-QRF_T_list).argmin()]
34
+ reg, imp, scaler_X, sub_desc_list = _load_qrf_model(nearest_T)
 
35
  #df_X = pd.read_excel('qrf/qrf_x.xlsx')
36
  #df_y = pd.read_excel('qrf/qrf_y.xlsx')
37
  mask_T = (df_QRF['T']>nearest_T-QRF_T_cut) & (df_QRF['T']<nearest_T+QRF_T_cut)
 
64
  def QRF_Apply(density, polytg, smiles, quantiles=[0.03,0.5,0.97], T=37):
65
  """T and Tg in C"""
66
  nearest_T = QRF_T_list[np.abs(T-QRF_T_list).argmin()]
67
+ reg, imp, scaler_X, sub_desc_list = _load_qrf_model(nearest_T)
 
68
  # get list of descriptors to calculate
69
  solute_desc_list = sub_desc_list.copy()
70
  if 'Polymer_Tg' in solute_desc_list:
71
  solute_desc_list.remove('Polymer_Tg')
72
  if 'Polymer_Density' in solute_desc_list:
73
  solute_desc_list.remove('Polymer_Density')
74
+ desc_funcs = {d: _desc_by_name[d] for d in solute_desc_list if d in _desc_by_name}
 
 
75
  calc = mordred.Calculator(list(desc_funcs.values()))
76
  m = Chem.MolFromSmiles(smiles)
77
  m = Chem.AddHs(m)
qrf/mordred-descriptors.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:29fb9c32fb13f69d87ecc62f092d0f394946f6fe1a05ff9917c0f9d98e7e0795
3
+ size 7064094
qrf/mordred-descriptors.xlsx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:121f72b88fa46a0f16af6a1244af761ee6b9d679af7ab2e32d545538f8b5c5b5
3
- size 10251595
 
 
 
 
qrf/{qrf_parameters_allT.xlsx → qrf_parameters_allT.parquet} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:ff8d83fd6f4f5efd9352cb33e9a4c48d05d94c4aee1b64b2a3134d847856ae52
3
- size 5755
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:66eeb79979f2883ef2f50f9766ecef1ee27e02ed83ce3b72f26c851a328b95d3
3
+ size 7776
qrf/qrf_train.py CHANGED
@@ -5,8 +5,6 @@ import sklearn
5
  import sklearn.impute
6
  import sklearn.metrics
7
  from quantile_forest import RandomForestQuantileRegressor
8
- import mordred
9
- from mordred import Calculator, descriptors
10
 
11
  #T_target = 37
12
  #T_cut = 2.5
@@ -15,13 +13,12 @@ state = 12345
15
 
16
  QRF_T_list = np.array([25,30,35,37,40,45,50,55,60,65,70,75])
17
  QRF_T_cut = 2.5
18
- df_QRF = pd.read_excel('db-D-interp-allT-semiclean.xlsx')
19
- df_desc = pd.read_excel('mordred-descriptors.xlsx')
20
- calc = mordred.Calculator(mordred.descriptors)
21
- colnames_mordred = [str(d) for d in calc.descriptors]
22
  df_QRF = pd.merge(df_QRF, df_desc[['Solute_InChIKey',*colnames_mordred]], how='left', on='Solute_InChIKey', suffixes=('', '_dupe'))
23
 
24
- df_params = pd.read_excel('qrf_parameters_allT.xlsx')
25
 
26
  for T_target in QRF_T_list:
27
  print(T_target)
 
5
  import sklearn.impute
6
  import sklearn.metrics
7
  from quantile_forest import RandomForestQuantileRegressor
 
 
8
 
9
  #T_target = 37
10
  #T_cut = 2.5
 
13
 
14
  QRF_T_list = np.array([25,30,35,37,40,45,50,55,60,65,70,75])
15
  QRF_T_cut = 2.5
16
+ df_QRF = pd.read_parquet('db-D-interp-allT-semiclean.parquet')
17
+ df_desc = pd.read_parquet('mordred-descriptors.parquet')
18
+ colnames_mordred = [c for c in df_desc.columns if c != 'Solute_InChIKey']
 
19
  df_QRF = pd.merge(df_QRF, df_desc[['Solute_InChIKey',*colnames_mordred]], how='left', on='Solute_InChIKey', suffixes=('', '_dupe'))
20
 
21
+ df_params = pd.read_parquet('qrf_parameters_allT.parquet')
22
 
23
  for T_target in QRF_T_list:
24
  print(T_target)
qrf/qrf_y.xlsx → quantity_module/data/data-descriptors-mordred-numconfs51.parquet RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:e8728d1f5c88d133dc396c8b8cb85313b716252d2f9dc7ed1a67b86780814157
3
- size 35100
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:db1d1cc6a5d310e2e2846101fb1791387ecaa6d7647dbb9cae5cac9c42671a5a
3
+ size 23818
quantity_module/data/data-descriptors-mordred-numconfs51.xlsx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:121f72b88fa46a0f16af6a1244af761ee6b9d679af7ab2e32d545538f8b5c5b5
3
- size 10251595
 
 
 
 
qrf/qrf_x.xlsx → quantity_module/data/db-D-interp-37-clean.parquet RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:98ea75f2a01564c9b1d998b699bbd11ee22954e5971c95addf8bb8a87e43fbd1
3
- size 195153
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:62039c3f5ad8001aa162770345788fa5055f6a20af8c458cad62c6b90847f7e8
3
+ size 210568
quantity_module/data/db-D-interp-37-clean.xlsx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:5c046f45ede6419629615b2e7397d74dc22c19db8556853638dd0c54ef9fad3f
3
- size 546002
 
 
 
 
quantity_module/data/db-D-interp-50-clean.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1393f14023049e5e0cd5abac4827cfcbc4aa2501b1361725ba5aefe50bf4501c
3
+ size 140776
quantity_module/data/db-D-interp-50-clean.xlsx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:2086bf5769a47fb6ff95f4f1dc4368788f03d6365300e5c40f6631798929116d
3
- size 314780
 
 
 
 
quantity_module/data/db-D-interp-allT-clean.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3df5c08bcdcfafd3f37d4404f401f855cb6217dc2c7f1624a9bf00519663c733
3
+ size 2082818
quantity_module/data/db-D-interp-allT-clean.xlsx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:b34934f1be324e95766d57b156ee29822b1ed282b3f0b4402e5405a8752c8acd
3
- size 10436853
 
 
 
 
quantity_module/data/{solvent-viscosity.xlsx → solvent-viscosity.parquet} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:1981623bba77ebda97107ece1e0b4d6b638a633cb5a91ed6a88a1a1bf26f513b
3
- size 13815
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:01a256c5c70979308dc15b7c433f860f72813a5859bc7720ddebad8831d6ac0d
3
+ size 9268
quantity_module/data/vrentas-duda-params-polymers.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:02cbc3415294076b364f2a1eac63b68ca2785ebf07c3b9ac203ed6c3fc8a67a2
3
+ size 10887
quantity_module/data/vrentas-duda-params-solutes.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3810ed12e5c113a7423d0769d870bd710a830808739930a7c0bb1cac30ff8ddd
3
+ size 11141
quantity_module/data/vrentas-duda-params.xlsx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:56a52df0ca74da211a93de2ca5e7c735a1265026bf954f967ea21a01831bd8bb
3
- size 23473
 
 
 
 
quantity_module/functions.py CHANGED
@@ -16,7 +16,7 @@ import mordred.descriptors
16
  from functions import PowerLaw, Piringer
17
 
18
  ## sampling parameters
19
- N_sample = int(1e6)
20
  #rng = np.random.Generator(np.random.PCG64(seed=12345))
21
 
22
  ## list of solvents to include, all semi-polar and non-polar solvents in ISO 10993-18:2020 Table D.1 (except DMSO, which is not used in practice)
@@ -42,12 +42,12 @@ else:
42
  with open('quantity_module/data/param_distribution_allT.json','r') as fp:
43
  param_dists = json.load(fp)
44
  # other stuff
45
- df_visc = pd.read_excel('quantity_module/data/solvent-viscosity.xlsx')
46
- df_desc = pd.read_excel(f'quantity_module/data/data-descriptors-mordred-numconfs51.xlsx', usecols=['Solute_InChIKey', 'Vabc','VMcGowan'])
47
  if not use_new:
48
  ## clean data
49
- df_final_37 = pd.read_excel('quantity_module/data/db-D-interp-37-clean.xlsx')
50
- df_final_50 = pd.read_excel('quantity_module/data/db-D-interp-50-clean.xlsx')
51
  # convert all T to K
52
  df_final_37['T'] = df_final_37['T'] + 273.15
53
  df_final_37['Polymer_Tg'] = df_final_37['Polymer_Tg'] + 273.15
@@ -60,7 +60,7 @@ if not use_new:
60
  df_final_50 = pd.merge(df_final_50, df_desc[['Solute_InChIKey', 'Vabc', 'VMcGowan']], how='left', on='Solute_InChIKey', suffixes=('', '_dupe'))
61
  else:
62
  ## clean data
63
- df_final = pd.read_excel('quantity_module/data/db-D-interp-allT-clean.xlsx')
64
  # convert all T to K
65
  df_final['T'] = df_final['T'] + 273.15
66
  df_final['Polymer_Tg'] = df_final['Polymer_Tg'] + 273.15
@@ -179,11 +179,11 @@ def get_V(smiles):
179
  return Vabc
180
 
181
  #### Vrentas-Duda setup
182
- df_vd_solv = pd.read_excel('quantity_module/data/vrentas-duda-params.xlsx', sheet_name='Solutes')
183
  df_vd_solv.drop_duplicates(keep='first', inplace=True, ignore_index=True) # drop exact duplicates
184
- df_vd_poly = pd.read_excel('quantity_module/data/vrentas-duda-params.xlsx', sheet_name='Polymers')
185
  df_vd_poly.drop_duplicates(keep='first', inplace=True, ignore_index=True) # drop exact duplicates
186
- df_props = pd.read_excel('data/db-polymer-properties-and-categories.xlsx')
187
  df_vd_poly = pd.merge(df_vd_poly, df_props[['Polymer_Name','Polymer_Tg','Polymer_Tm', 'CHRIS Class', 'New Class']], how='left', on='Polymer_Name')
188
  df_vd_poly['New Class'] = df_vd_poly['New Class'].fillna('none')
189
  df_vd_poly['CHRIS Class'] = df_vd_poly['CHRIS Class'].fillna('none')
 
16
  from functions import PowerLaw, Piringer
17
 
18
  ## sampling parameters
19
+ N_sample = int(1e5) # reduced from 1e6 for performance; results are statistically indistinguishable
20
  #rng = np.random.Generator(np.random.PCG64(seed=12345))
21
 
22
  ## list of solvents to include, all semi-polar and non-polar solvents in ISO 10993-18:2020 Table D.1 (except DMSO, which is not used in practice)
 
42
  with open('quantity_module/data/param_distribution_allT.json','r') as fp:
43
  param_dists = json.load(fp)
44
  # other stuff
45
+ df_visc = pd.read_parquet('quantity_module/data/solvent-viscosity.parquet')
46
+ df_desc = pd.read_parquet('quantity_module/data/data-descriptors-mordred-numconfs51.parquet', columns=['Solute_InChIKey', 'Vabc','VMcGowan'])
47
  if not use_new:
48
  ## clean data
49
+ df_final_37 = pd.read_parquet('quantity_module/data/db-D-interp-37-clean.parquet')
50
+ df_final_50 = pd.read_parquet('quantity_module/data/db-D-interp-50-clean.parquet')
51
  # convert all T to K
52
  df_final_37['T'] = df_final_37['T'] + 273.15
53
  df_final_37['Polymer_Tg'] = df_final_37['Polymer_Tg'] + 273.15
 
60
  df_final_50 = pd.merge(df_final_50, df_desc[['Solute_InChIKey', 'Vabc', 'VMcGowan']], how='left', on='Solute_InChIKey', suffixes=('', '_dupe'))
61
  else:
62
  ## clean data
63
+ df_final = pd.read_parquet('quantity_module/data/db-D-interp-allT-clean.parquet')
64
  # convert all T to K
65
  df_final['T'] = df_final['T'] + 273.15
66
  df_final['Polymer_Tg'] = df_final['Polymer_Tg'] + 273.15
 
179
  return Vabc
180
 
181
  #### Vrentas-Duda setup
182
+ df_vd_solv = pd.read_parquet('quantity_module/data/vrentas-duda-params-solutes.parquet')
183
  df_vd_solv.drop_duplicates(keep='first', inplace=True, ignore_index=True) # drop exact duplicates
184
+ df_vd_poly = pd.read_parquet('quantity_module/data/vrentas-duda-params-polymers.parquet')
185
  df_vd_poly.drop_duplicates(keep='first', inplace=True, ignore_index=True) # drop exact duplicates
186
+ df_props = pd.read_parquet('data/db-polymer-properties-and-categories.parquet')
187
  df_vd_poly = pd.merge(df_vd_poly, df_props[['Polymer_Name','Polymer_Tg','Polymer_Tm', 'CHRIS Class', 'New Class']], how='left', on='Polymer_Name')
188
  df_vd_poly['New Class'] = df_vd_poly['New Class'].fillna('none')
189
  df_vd_poly['CHRIS Class'] = df_vd_poly['CHRIS Class'].fillna('none')
requirements.txt CHANGED
@@ -22,4 +22,5 @@ mordred==1.2.0
22
  beautifulsoup4==4.12.3
23
  setuptools==72.1.0
24
  openpyxl==3.1.5
 
25
 
 
22
  beautifulsoup4==4.12.3
23
  setuptools==72.1.0
24
  openpyxl==3.1.5
25
+ pyarrow<16
26