rdworks 0.38.1__py3-none-any.whl → 0.40.1__py3-none-any.whl

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.
rdworks/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = '0.38.1'
1
+ __version__ = '0.40.1'
2
2
 
3
3
  from rdworks.conf import Conf
4
4
  from rdworks.mol import Mol
rdworks/conf.py CHANGED
@@ -19,7 +19,7 @@ from PIL import Image
19
19
  from rdworks.std import clean_2d
20
20
  from rdworks.torsion import get_torsion_atoms, create_torsion_fragment
21
21
  from rdworks.units import ev2kcalpermol, pm2angstrom
22
- from rdworks.utils import recursive_round
22
+ from rdworks.utils import recursive_round, compress_string, decompress_string
23
23
  from rdworks.xtb.wrapper import GFN2xTB
24
24
  from rdworks.display import render_png, render_svg
25
25
 
@@ -39,11 +39,20 @@ class Conf:
39
39
  """
40
40
  assert isinstance(molecule, str | Chem.Mol) or molecule is None
41
41
 
42
- self.rdmol = None # must contain one and only one rdkit conformer
43
42
  self.name = name
43
+ self.rdmol = None # must contain one and only one rdkit conformer
44
44
  self.natoms = 0
45
- self.charge = 0 # molecular charge
46
- self.spin = 1 # molecular spin multiplicity for ASE
45
+ self.charge = 0 # molecular formal charge
46
+ self.spin = 1 # molecular spin multiplicity for ASE
47
+ # Molecular spin multiplicity describes the number of possible orientations of
48
+ # spin angular momentum for a given molecule, essentially indicating the total
49
+ # number of unpaired electrons.
50
+ # Spin Angular Momentum (S): up (+1/2) or down (-1/2)
51
+ # Spin Multiplicity (2S + 1)
52
+ # 0 unpaired electron has S = 0, 2S + 1 = 0, called a singlet.
53
+ # 1 unpaired electron has S = 1/2, 2S + 1 = 2, called a doublet (radical).
54
+ # 2 unpaired electrons has S = 1, 2S + 1 = 3, called a triplet.
55
+
47
56
  self.props = {}
48
57
 
49
58
  if molecule is None:
@@ -63,10 +72,12 @@ class Conf:
63
72
 
64
73
  num_atoms = self.rdmol.GetNumAtoms()
65
74
  tot_atoms = self.rdmol.GetNumAtoms(onlyExplicit=False)
75
+
66
76
  assert num_atoms == tot_atoms, "Conf() Error: missing hydrogens"
77
+
67
78
  self.natoms = num_atoms
68
79
  self.charge = rdmolops.GetFormalCharge(self.rdmol)
69
- self.props.update({'atoms': num_atoms})
80
+ self.props.update({'atoms': self.natoms, 'charge': self.charge})
70
81
 
71
82
  assert self.rdmol.GetConformer().Is3D(), "Conf() Error: not 3D"
72
83
 
@@ -148,7 +159,6 @@ class Conf:
148
159
 
149
160
  return self
150
161
 
151
-
152
162
 
153
163
  def optimize(self,
154
164
  calculator: str | Callable = 'MMFF94',
@@ -402,6 +412,95 @@ class Conf:
402
412
  return {i: d[:4] for i, d in enumerate(get_torsion_atoms(self.rdmol, strict))}
403
413
 
404
414
 
415
+ def torsion_energies_one(self,
416
+ calculator: str | Callable,
417
+ indices: tuple,
418
+ simplify: bool = True,
419
+ fmax: float = 0.05,
420
+ interval: float = 20.0,
421
+ use_converged_only: bool = True,
422
+ **kwargs) -> Self:
423
+ """Calculate potential energy profile for a torsion angle.
424
+
425
+ Args:
426
+ calculator (str | Callable): 'MMFF', 'UFF', or ASE calculator.
427
+ indices (tuple): atom indices (i,j,k,l) for a torsion angle
428
+ simplify (bool, optional): whether to use fragementation. Defaults to True.
429
+ fmax (float, optional): convergence limit for optimize. Defaults to 0.05.
430
+ interval (float, optional): angle intervals. Defaults to 20.0.
431
+ use_converged_only (bool, optional): whether to use only converged data. Defaults to True.
432
+
433
+ Returns:
434
+ Self: modified self.
435
+ """
436
+ ref_conf = self.copy()
437
+
438
+ data = {'indices': indices,
439
+ 'angle': [],
440
+ 'init': [],
441
+ 'last': [],
442
+ 'Converged': [],
443
+ }
444
+
445
+ if simplify:
446
+ frag, frag_ijkl = create_torsion_fragment(ref_conf.rdmol, indices)
447
+ frag_conf = Conf(frag)
448
+ for angle in np.arange(-180.0, 180.0, interval):
449
+ # Iterated numpy.ndarray does not contain the last 180: -180., ..., (180).
450
+ conf = frag_conf.copy()
451
+ conf.set_torsion(*frag_ijkl, angle) # atoms bonded to `l` move.
452
+ conf = conf.optimize(calculator, fmax, **kwargs)
453
+ # conf.optimize() updates coordinates and conf.props:
454
+ # `E_tot_init(kcal/mol)`, `E_tot(kcal/mol)`, `Converged`.
455
+ data['angle'].append(angle)
456
+ data['init'].append(conf.props['E_tot_init(kcal/mol)'])
457
+ data['last'].append(conf.props['E_tot(kcal/mol)'])
458
+ data['Converged'].append(conf.props['Converged'])
459
+ frag_cleaned, _ = clean_2d(frag, reset_isotope=True, remove_H=True)
460
+ # to serialize the molecule
461
+ data['frag'] = Chem.MolToMolBlock(frag_cleaned)
462
+ data['frag_indices'] = frag_ijkl
463
+ else:
464
+ for angle in np.arange(-180.0, 180.0, interval):
465
+ # Iterated numpy.ndarray does not contain the last 180: -180., ..., (180).
466
+ conf = ref_conf.copy()
467
+ conf.set_torsion(*indices, angle) # atoms bonded to `l` move.
468
+ conf = conf.optimize(calculator, fmax, **kwargs)
469
+ # conf.optimize() updates coordinates and conf.props:
470
+ # `E_tot_init(kcal/mol)`, `E_tot(kcal/mol)`, `Converged`.
471
+ data['angle'].append(conf.props['angle'])
472
+ data['init'].append(conf.props['E_tot_init(kcal/mol)'])
473
+ data['last'].append(conf.props['E_tot(kcal/mol)'])
474
+ data['Converged'].append(conf.props['Converged'])
475
+
476
+ # Post-processing
477
+ if use_converged_only:
478
+ data['angle'] = list(itertools.compress(data['angle'], data['Converged']))
479
+ data['init' ] = list(itertools.compress(data['init' ], data['Converged']))
480
+ data['last' ] = list(itertools.compress(data['last' ], data['Converged']))
481
+
482
+ relax = np.array(data['init']) - np.median(data['last'])
483
+ E_rel = relax - np.min(relax)
484
+
485
+ torsion_energy_profile = {
486
+ 'indices' : data['indices'],
487
+ 'angle' : np.round(np.array(data['angle']), 1).tolist(), # np.ndarray -> list for serialization
488
+ 'E_rel(kcal/mol)': np.round(E_rel, 2).tolist(), # np.ndarray -> list for serialization
489
+ }
490
+
491
+ if simplify:
492
+ torsion_energy_profile.update({
493
+ 'frag' : data.get('frag', None),
494
+ 'frag_indices' : data.get('frag_indices', None),
495
+ })
496
+
497
+ self.props['torsion'] = torsion_energy_profile
498
+ self.props['torsion_calculator'] = str(calculator)
499
+
500
+ return self
501
+
502
+
503
+
405
504
  def torsion_energies(self,
406
505
  calculator: str | Callable,
407
506
  torsion_key: int | None = None,
@@ -427,80 +526,23 @@ class Conf:
427
526
  Self: modified self.
428
527
  """
429
528
 
430
- if torsion_key is None:
431
- torsion_atoms_indices = self.torsion_atoms()
432
- # {0: (5, 4, 3, 1)}
433
- else:
434
- torsion_atoms_indices = {torsion_key: self.torsion_atoms()[torsion_key]}
435
-
436
- ref_conf = self.copy()
437
-
438
- data = {}
529
+ torsion_atoms_dict = self.torsion_atoms() # {0: (5, 4, 3, 1)}
530
+ if (torsion_key is not None) and torsion_atoms_dict.get(torsion_key):
531
+ torsion_atoms_dict = {torsion_key: torsion_atoms_dict.get(torsion_key)}
532
+ # single torsion angle atom indices
439
533
 
440
- if simplify:
441
- for tk, indices in torsion_atoms_indices.items():
442
- frag, frag_ijkl = create_torsion_fragment(ref_conf.rdmol, indices)
443
- frag_conf = Conf(frag)
444
- data[tk] = {'indices': indices, 'angle':[], 'init':[], 'last':[], 'Converged':[]}
445
- for angle in np.arange(-180.0, 180.0, interval):
446
- # Iterated numpy.ndarray does not contain the last 180: -180., ..., (180).
447
- conf = frag_conf.copy()
448
- conf.props.update({'torsion_key': tk, 'angle': float(angle)})
449
- conf.set_torsion(*frag_ijkl, angle) # atoms bonded to `l` move.
450
- conf = conf.optimize(calculator, fmax, **kwargs)
451
- # conf.optimize() updates coordinates and conf.props:
452
- # `angle`, `E_tot_init(kcal/mol)`, `E_tot(kcal/mol)`, `Converged`.
453
- tk = conf.props['torsion_key']
454
- data[tk]['angle'].append(conf.props['angle'])
455
- data[tk]['init'].append(conf.props['E_tot_init(kcal/mol)'])
456
- data[tk]['last'].append(conf.props['E_tot(kcal/mol)'])
457
- data[tk]['Converged'].append(conf.props['Converged'])
458
- frag_cleaned, _ = clean_2d(frag, reset_isotope=True, remove_H=True)
459
- # to serialize the molecule
460
- data[tk]['frag'] = Chem.MolToMolBlock(frag_cleaned)
461
- data[tk]['frag_indices'] = frag_ijkl
534
+ conf = self.copy()
462
535
 
463
- else:
464
- # mol.confs will be populated with torsion conformers.
465
- # It is designed for a batch optimization in the future.
466
- torsion_angle_confs = []
467
- for tk, indices in torsion_atoms_indices.items():
468
- data[tk] = {'indices': indices, 'angle':[], 'init':[], 'last':[], 'Converged':[]}
469
- for angle in np.arange(-180.0, 180.0, interval):
470
- # Iterated numpy.ndarray does not contain the last 180: -180., ..., (180).
471
- x = ref_conf.copy()
472
- x.props.update({'torsion_key': tk, 'angle': float(angle)})
473
- x.set_torsion(*indices, angle) # atoms bonded to `l` move.
474
- torsion_angle_confs.append(x)
475
-
476
- # Calculate relaxation energies
477
- for conf in torsion_angle_confs:
478
- conf = conf.optimize(calculator, fmax, **kwargs)
479
- # conf.optimize() updates coordinates and conf.props:
480
- # `angle`, `E_tot_init(kcal/mol)`, `E_tot(kcal/mol)`, `Converged`.
481
- tk = conf.props['torsion_key']
482
- data[tk]['angle'].append(conf.props['angle'])
483
- data[tk]['init'].append(conf.props['E_tot_init(kcal/mol)'])
484
- data[tk]['last'].append(conf.props['E_tot(kcal/mol)'])
485
- data[tk]['Converged'].append(conf.props['Converged'])
486
-
487
- # Post-processing
488
536
  torsion_energy_profiles = {}
489
- for tk, dictdata in data.items():
490
- if use_converged_only:
491
- dictdata['angle'] = list(itertools.compress(dictdata['angle'], dictdata['Converged']))
492
- dictdata['init'] = list(itertools.compress(dictdata['init'], dictdata['Converged']))
493
- dictdata['last'] = list(itertools.compress(dictdata['last'], dictdata['Converged']))
494
- relax = np.array(dictdata['init']) - np.median(dictdata['last'])
495
- E_rel = relax - np.min(relax)
496
- torsion_energy_profiles[tk] = {
497
- 'indices' : dictdata['indices'],
498
- 'angle' : np.round(np.array(dictdata['angle']), 1).tolist(), # np.ndarray -> list for serialization
499
- 'E_rel(kcal/mol)': np.round(E_rel, 2).tolist(), # np.ndarray -> list for serialization
500
- 'frag' : dictdata.get('frag', None),
501
- 'frag_indices' : dictdata.get('frag_indices', None),
502
- }
503
-
537
+ for tk, indices in torsion_atoms_dict.items():
538
+ conf = conf.torsion_energies_one(calculator,
539
+ indices,
540
+ simplify,
541
+ fmax,
542
+ interval,
543
+ use_converged_only)
544
+ torsion_energy_profiles[tk] = conf.props['torsion']
545
+
504
546
  self.props['torsion'] = torsion_energy_profiles
505
547
  self.props['torsion_calculator'] = str(calculator)
506
548
 
@@ -539,7 +581,7 @@ class Conf:
539
581
  return json.dumps(self.props)
540
582
 
541
583
 
542
- def serialize(self, decimals: int = 3) -> str:
584
+ def serialize(self, decimals: int = 3, compressed: bool = False) -> str:
543
585
  """Serialize information necessary to rebuild a Conf object.
544
586
  Args:
545
587
  decimals (int, optional): number of decimal places for float data type. Defaults to 3.
@@ -548,16 +590,21 @@ class Conf:
548
590
  str: serialized string for json.loads()
549
591
  """
550
592
  serialized = json.dumps({
551
- 'name' : self.name,
552
- 'natoms': self.natoms,
593
+ 'name' : self.name,
594
+ 'natoms': self.natoms,
595
+ 'charge': self.charge,
596
+ 'spin': self.spin,
553
597
  'props' : recursive_round(self.props, decimals),
554
598
  'molblock' : self.to_molblock(),
555
599
  })
556
600
 
601
+ if compressed:
602
+ serialized = compress_string(serialized)
603
+
557
604
  return serialized
558
605
 
559
606
 
560
- def deserialize(self, serialized: str) -> Self:
607
+ def deserialize(self, serialized: str, compressed: bool = False) -> Self:
561
608
  """De-serialize information and rebuild a Conf object.
562
609
 
563
610
  Example:
@@ -570,19 +617,27 @@ class Conf:
570
617
  Returns:
571
618
  Self: modified self.
572
619
  """
620
+ if compressed:
621
+ serialized = decompress_string(serialized)
622
+
573
623
  data = json.loads(serialized)
574
624
 
575
625
  self.name = data['name']
576
- self.natoms = data['natoms']
626
+ self.natoms = int(data['natoms'])
627
+ self.charge = int(data['charge'])
628
+ self.spin = int(data['spin'])
577
629
  self.props = data['props']
578
630
  self.rdmol = Chem.MolFromMolBlock(data['molblock'], sanitize=False, removeHs=False)
579
631
 
580
632
  return self
581
633
 
582
634
 
583
- def to_molblock(self) -> str:
635
+ def to_molblock(self, compressed: bool = False) -> str:
584
636
  """Returns MolBlock"""
585
- return Chem.MolToMolBlock(self.rdmol)
637
+ molblock = Chem.MolToMolBlock(self.rdmol)
638
+ if compressed:
639
+ molblock = compress_string(molblock)
640
+ return molblock
586
641
 
587
642
 
588
643
  def to_xyz(self) -> str:
rdworks/mol.py CHANGED
@@ -37,7 +37,7 @@ from rdworks.std import generate_inchi_key, desalt_smiles, standardize, clean_2d
37
37
  from rdworks.xml import list_predefined_xml, get_predefined_xml, parse_xml
38
38
  from rdworks.scaffold import rigid_fragment_indices
39
39
  from rdworks.descriptor import rd_descriptor, rd_descriptor_f
40
- from rdworks.utils import convert_tril_to_symm, QT, recursive_round
40
+ from rdworks.utils import convert_tril_to_symm, QT, recursive_round, compress_string, decompress_string
41
41
  from rdworks.units import ev2kcalpermol
42
42
  from rdworks.autograph import NMRCLUST, DynamicTreeCut, RCKmeans, AutoGraph
43
43
  from rdworks.bitqt import BitQT
@@ -83,17 +83,18 @@ class Mol:
83
83
  """
84
84
  assert isinstance(molecule, str | Chem.Mol | Conf) or molecule is None
85
85
 
86
+ self.name = ''
86
87
  self.rdmol = None # 2D, one and only one Conformer
87
88
  self.smiles = '' # isomeric SMILES
88
89
  self.confs = [] # container for 3D conformers
89
- self.name = ''
90
90
  self.InChIKey = '' # 27 characters (SHA-256 hash of InChI)
91
- self.InChI = ''
92
91
  self.props = {}
93
- self.fp = None
92
+
94
93
  self.max_workers = max_workers
95
94
  self.chunksize = chunksize
96
95
  self.progress = progress
96
+
97
+ self.fp = None
97
98
 
98
99
  if molecule is None:
99
100
  return
@@ -1557,7 +1558,7 @@ class Mol:
1557
1558
  return json.dumps(props)
1558
1559
 
1559
1560
 
1560
- def serialize(self, decimals: int = 2) -> str:
1561
+ def serialize(self, decimals: int = 2, compressed: bool = False) -> str:
1561
1562
  """Serialize information necessary to rebuild a Mol object.
1562
1563
 
1563
1564
  Args:
@@ -1569,14 +1570,18 @@ class Mol:
1569
1570
  serialized = json.dumps({
1570
1571
  'name' : self.name,
1571
1572
  'smiles': self.smiles,
1573
+ 'InChIKey': self.InChIKey,
1572
1574
  'props' : recursive_round(self.props, decimals),
1573
1575
  'confs' : [conf.serialize() for conf in self.confs],
1574
1576
  })
1575
1577
 
1578
+ if compressed:
1579
+ serialized = compress_string(serialized)
1580
+
1576
1581
  return serialized
1577
1582
 
1578
1583
 
1579
- def deserialize(self, serialized: str) -> Self:
1584
+ def deserialize(self, serialized: str, compressed: bool = False) -> Self:
1580
1585
  """De-serialize the information and build a new Mol object.
1581
1586
 
1582
1587
  Example:
@@ -1589,13 +1594,16 @@ class Mol:
1589
1594
  Returns:
1590
1595
  Self: modified self.
1591
1596
  """
1597
+ if compressed:
1598
+ serialized = decompress_string(serialized)
1599
+
1592
1600
  data = json.loads(serialized)
1593
1601
 
1594
1602
  self.name = data['name']
1595
1603
  self.smiles = data['smiles'] # isomeric SMILES, no H
1596
1604
  self.rdmol = Chem.MolFromSmiles(data['smiles']) # for 2D depiction
1597
1605
  self.rdmol.SetProp('_Name', self.name)
1598
- self.InChIKey = generate_inchi_key(self.rdmol)
1606
+ self.InChIKey = data['InChIKey']
1599
1607
  self.props = data['props']
1600
1608
  self.confs = [Conf().deserialize(_) for _ in data['confs']] # for 3D conformers (iterable)
1601
1609
 
rdworks/testdata.py ADDED
@@ -0,0 +1,24 @@
1
+ drugs = {
2
+ 'Acetaminophen': 'CC(=O)Nc1ccc(O)cc1',
3
+ 'Aspirin': 'CC(=O)OC1=CC=CC=C1C(=O)O',
4
+ 'Atorvastatin': 'CC(C)C1=C(C(=C(N1CC[C@H](C[C@H](CC(=O)O)O)O)C2=CC=C(C=C2)F)C3=CC=CC=C3)C(=O)NC4=CC=CC=C4',
5
+ 'Atovaquone': 'C1CC(CCC1C2=CC=C(C=C2)Cl)C3=C(C4=CC=CC=C4C(=O)C3=O)O',
6
+ 'Cefdinir': 'C=CC1=C(N2[C@@H]([C@@H](C2=O)NC(=O)/C(=N\\O)/C3=CSC(=N3)N)SC1)C(=O)O',
7
+ 'Chlorprothixene': 'CN(CC/C=C1C2=CC=CC=C2SC3=C/1C=C(Cl)C=C3)C',
8
+ 'Cimetidine': 'CC1=C(N=CN1)CSCCNC(=NC)NC#N',
9
+ 'Clomipramine': 'CN(C)CCCN1C2=CC=CC=C2CCC3=C1C=C(C=C3)Cl',
10
+ 'Ethopropazine': 'CCN(CC)C(C)CN1C2=CC=CC=C2SC3=CC=CC=C31',
11
+ 'Famotidine': 'C1=C(N=C(S1)N=C(N)N)CSCC/C(=N/S(=O)(=O)N)/N',
12
+ 'Fluconazole': 'C1=CC(=C(C=C1F)F)C(CN2C=NC=N2)(CN3C=NC=N3)O',
13
+ 'Granisetron': 'CN1[C@@H]2CCC[C@H]1CC(C2)NC(=O)C3=NN(C4=CC=CC=C43)C',
14
+ 'Leflunomide': 'CC1=C(C=NO1)C(=O)NC2=CC=C(C=C2)C(F)(F)F',
15
+ 'Linezolid': 'CC(=O)NC[C@H]1CN(C(=O)O1)C2=CC(=C(C=C2)N3CCOCC3)F',
16
+ 'Methixene': 'CN1CCCC(C1)CC2C3=CC=CC=C3SC4=CC=CC=C24',
17
+ 'Molindone': 'CCC1=C(NC2=C1C(=O)C(CC2)CN3CCOCC3)C',
18
+ 'Paroxetine': 'C1CNC[C@H]([C@@H]1C2=CC=C(C=C2)F)COC3=CC4=C(C=C3)OCO4',
19
+ 'Pergolide': 'CCCN1C[C@@H](C[C@H]2[C@H]1CC3=CNC4=CC=CC2=C34)CSC',
20
+ 'Rifampin': 'C[C@H]1/C=C/C=C(\\C(=O)NC2=C(C(=C3C(=C2O)C(=C(C4=C3C(=O)[C@](O4)(O/C=C/[C@@H]([C@H]([C@H]([C@@H]([C@@H]([C@@H]([C@H]1O)C)O)C)OC(=O)C)C)OC)C)C)O)O)/C=N/N5CCN(CC5)C)/C',
21
+ 'Simvastatin': 'O=C(O[C@@H]1[C@H]3C(=C/[C@H](C)C1)\\C=C/[C@@H]([C@@H]3CC[C@H]2OC(=O)C[C@H](O)C2)C)C(C)(C)CC',
22
+ 'Sitagliptin': 'Fc1cc(c(F)cc1F)C[C@@H](N)CC(=O)N3Cc2nnc(n2CC3)C(F)(F)F',
23
+ 'Sofosbuvir': 'C[C@@H](C(OC(C)C)=O)N[P@](OC[C@@H]1[C@H]([C@@](F)([C@@H](O1)N2C=CC(NC2=O)=O)C)O)(OC3=CC=CC=C3)=O',
24
+ }
rdworks/utils.py CHANGED
@@ -1,6 +1,8 @@
1
1
  import numpy as np
2
2
  import math
3
3
  import operator
4
+ import gzip
5
+ import base64
4
6
 
5
7
  from pathlib import Path
6
8
  from types import SimpleNamespace
@@ -14,6 +16,33 @@ from rdkit import Chem
14
16
  from rdworks.autograph.centroid import centroid_medoid
15
17
 
16
18
 
19
+ def compress_string(text: str) -> str:
20
+ """compress string to base64-encoded string.
21
+
22
+ Args:
23
+ text (str): original string.
24
+
25
+ Returns:
26
+ str: base64-encoded compressed string.
27
+ """
28
+ compressed_bytes = gzip.compress(text.encode('utf-8'))
29
+ return base64.b64encode(compressed_bytes).decode('utf-8')
30
+
31
+
32
+ def decompress_string(compressed_text: str) -> str:
33
+ """decompress base64-encoded string to original string.
34
+
35
+ Args:
36
+ compressed_text (str): base64-encoded compressed string.
37
+
38
+ Returns:
39
+ str: original string.
40
+ """
41
+ compressed_bytes = base64.b64decode(compressed_text)
42
+ decompressed_text = gzip.decompress(compressed_bytes).decode('utf-8')
43
+ return decompressed_text
44
+
45
+
17
46
  def compute(fn:Callable, largs: list, **kwargs) -> list:
18
47
  max_workers = kwargs.get('max_workers', 1)
19
48
  chunksize = kwargs.get('chunksize', 10)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rdworks
3
- Version: 0.38.1
3
+ Version: 0.40.1
4
4
  Summary: Frequently used tasks built on RDKit and other tools
5
5
  Author-email: Sung-Hun Bae <sunghun.bae@gmail.com>
6
6
  Maintainer-email: Sung-Hun Bae <sunghun.bae@gmail.com>
@@ -1,10 +1,10 @@
1
- rdworks/__init__.py,sha256=I7VqtqGi1BTUMH2KV5AU3UWjjteuPPjdB3td8SDB4sE,1368
2
- rdworks/conf.py,sha256=5j6KxncNn9eb3F-O3_S631azx-SK_KQ6oDAnf3Cke0A,28782
1
+ rdworks/__init__.py,sha256=u0oNboUCvBT6mkw6z5qRQiMVr-aglMbFITjb7Ut-DEM,1368
2
+ rdworks/conf.py,sha256=vMKVaHKvlPQ87CNfROodzwZ7l9h-tFCs8MGwon6_sJU,30823
3
3
  rdworks/descriptor.py,sha256=34T_dQ6g8v3u-ym8TLKbQtxIIV5TEo-d3pdedq3o-cg,2106
4
4
  rdworks/display.py,sha256=JR0gR26UpH-JCxVOaqXZCUj2MiGZSrx9Me87FncspVI,13469
5
5
  rdworks/ionized.py,sha256=5oIjMRpkX792RIpEEE2Ir96icfFaN_h21mSihhfQPAw,6713
6
6
  rdworks/matchedseries.py,sha256=A3ON4CUpQV159mu9VqgNiJ8uoQ9ePOry9d3ra4NCAgc,10377
7
- rdworks/mol.py,sha256=R6ifd-KIquR9ayl1_HCOE9-tXm89vk9vkHPkQtHsRNU,67787
7
+ rdworks/mol.py,sha256=JC1IHM6mw9uap_uV3i5d6ZAnZqA1kcyOnvwB6lgH4xA,68070
8
8
  rdworks/mollibr.py,sha256=X4UBO6Ga-QmNS7RwUiaDYAx0Q5hnWs71yTkEpH02Qb4,37696
9
9
  rdworks/pka.py,sha256=NVJVfpcNEMlX5QRyLBgUM7GIT7VMjO-llAR4LWc8J2c,1656
10
10
  rdworks/readin.py,sha256=0bnVcZcAmSLqc6zu1mYcv0LdBv2agQfOpKGwpSRL9VE,11742
@@ -13,9 +13,10 @@ rdworks/scaffold.py,sha256=60T5YacyxZsEpDo_J5Qxulm2YNQO4EQR8PcNUwjn1QU,22026
13
13
  rdworks/std.py,sha256=qOVS_lGogueLKh4rsbrsYIMR0c7z_xh6BqLEzD4X9sE,7938
14
14
  rdworks/stereoisomers.py,sha256=g8hhPI-mbYX-MzbF1uAqo5fDZOCNiKYjxI-kLBGdGgg,4980
15
15
  rdworks/tautomers.py,sha256=gtZHZJ-aJbryhBdljHbfjx7xhVW3u_OzdYPtwPail54,610
16
+ rdworks/testdata.py,sha256=TmbNPA-ju6nTBt_Yts4EJUFmL9Cd6DCVXrDF42QLlHw,1732
16
17
  rdworks/torsion.py,sha256=qTRJWsxSktqprL8pUHWEOoV2dKEgoMozh3BB0eGNlZ8,18571
17
18
  rdworks/units.py,sha256=nljKPHcr6IWoAp0CkL7y1gSNDd6a07NeVfxXwSMuHQM,365
18
- rdworks/utils.py,sha256=IxgFniUvjXlJuNJ1Sx9hsJknNNSglP6qzFyz8vdgDcw,13406
19
+ rdworks/utils.py,sha256=d2Sio8WTlGPsmBOHIYDCMWg_7X4rTWjJQAqzd7ywo2A,14191
19
20
  rdworks/xml.py,sha256=aaMhwVRGvt1VzasaKDnkYnZ4kp2cIgvGb1CsmMgwQ_c,10704
20
21
  rdworks/autograph/__init__.py,sha256=0Qfjwo0h4Q0n08zsqHRbuNOZms6MuNXnWErnQpQ6Px0,140
21
22
  rdworks/autograph/autograph.py,sha256=frjsUaCTOD-Z1lYPzOxRoTtqMMiYroWAy6tSwKn3CUA,8769
@@ -65,8 +66,8 @@ rdworks/predefined/misc/reactive-part-3.xml,sha256=LgWHSEbRTVmgBoIO45xbTo1xQJs0X
65
66
  rdworks/predefined/misc/reactive.xml,sha256=syedoQ6VYUfRLnxy99ObuDniJ_a_WhrWAJbTKFfJ6VY,11248
66
67
  rdworks/xtb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
68
  rdworks/xtb/wrapper.py,sha256=I0nW89vlJZ5Za5pCjIpjsEOFbTm7HpeNGiPgssheWn8,11350
68
- rdworks-0.38.1.dist-info/licenses/LICENSE,sha256=UOkJSBqYyQUvtCp7a-vdCANeEcLE2dnTie_eB1By5SY,1074
69
- rdworks-0.38.1.dist-info/METADATA,sha256=_uZpCzy6HddNOJ1adyBo5oM0VX2-bhCBKz8P_7XHKbg,1183
70
- rdworks-0.38.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
71
- rdworks-0.38.1.dist-info/top_level.txt,sha256=05C98HbvBK2axUBogC_hAT_CdpOeQYGnQ6vRAgawr8s,8
72
- rdworks-0.38.1.dist-info/RECORD,,
69
+ rdworks-0.40.1.dist-info/licenses/LICENSE,sha256=UOkJSBqYyQUvtCp7a-vdCANeEcLE2dnTie_eB1By5SY,1074
70
+ rdworks-0.40.1.dist-info/METADATA,sha256=ksYcRcoRSez6WZGRR-0mEMLWk0aO_A3fvK3QVHcHEpw,1183
71
+ rdworks-0.40.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
72
+ rdworks-0.40.1.dist-info/top_level.txt,sha256=05C98HbvBK2axUBogC_hAT_CdpOeQYGnQ6vRAgawr8s,8
73
+ rdworks-0.40.1.dist-info/RECORD,,