MolecularDiffusion.data.component.pmdm_data¶
Dataset / collate / DataModule for PMDM pocket-ligand complexes.
PMDM carries two node sets per complex – a diffused ligand point cloud and a
fixed full-atom pocket point cloud – flat-concatenated with
torch_scatter-style batch indices. That is not the platform’s padded
single-node-set PointCloud batch, so this module brings its own Dataset and
collate_fn and is selected via _target_ from
configs/data/pmdm_dataset.yaml. Direct precedent:
data/component/diffpharma_data.py, which does the same for a four-node-set
model through the same seams (cli/train.py -> .load() /
.train_set / .collate_fn, then data/lightning_data_module.py’s
collate_fn or graph_collate).
Storage is one ASE db row per complex, written offline by
docs/model_integrations/pmdm/scripts/convert_dataset.py:
Atoms -> ligand only (positions + raw element Z) key_value_pairs -> name, n_lig, n_pocket data -> lig_feat (N_lig, 8) rdkit atom-family flags,
pocket_coords, pocket_element, pocket_aa_type, pocket_is_backbone
Everything in the db is a raw integer, never one-hot. This module owns the
one-hot expansion, so changing a vocabulary does not mean reconverting – and
it keeps PMDM’s PDB/SDF parsing (and its np.bool/np.long calls, all
removed in modern numpy) entirely out of the runtime path.
The collate deliberately emits PMDM’s own attribute names, so the task
adapter is a one-line SimpleNamespace(**batch).
Attributes¶
Classes¶
DataModule contract: |
|
One converted ASE db -> one pocket-ligand complex per index. |
Functions¶
|
Per-molecule fully-connected, self-loop-free edge index with offsets. |
|
Minimal PDB ATOM-line parser for a live pocket file, at generate time. |
|
Concatenate complexes; emit PMDM's own attribute names. |
|
Write a pocket back to a PDB that |
Module Contents¶
- class MolecularDiffusion.data.component.pmdm_data.PMDMDataModule(root: str, train_file: str = 'pmdm_smoke.db', val_file: str | None = None, test_file: str | None = None, batch_size: int = 4, num_workers: int = 0, center: bool = True, limit: int | None = None, atom_vocab: List[str] | None = None, task_type: str = 'diffusion_pmdm', **kwargs: Any)¶
DataModule contract:
load()+train_set/valid_set/test_set.# ponytail: one db, no split –
val_file/test_filedefault to the # training db. The smoke set is 31 complexes; add a real split (and LMDB # streaming) when a full CrossDocked run needs one.- atom_vocab¶
- batch_size = 4¶
- center = True¶
- collate_fn¶
- kwargs¶
- limit = None¶
- num_workers = 0¶
- root¶
- task_type = 'diffusion_pmdm'¶
- test_file = 'pmdm_smoke.db'¶
- test_set: PMDMDataset | None = None¶
- train_file = 'pmdm_smoke.db'¶
- train_set: PMDMDataset | None = None¶
- val_file = 'pmdm_smoke.db'¶
- valid_set: PMDMDataset | None = None¶
- class MolecularDiffusion.data.component.pmdm_data.PMDMDataset(db_path: str, center: bool = True, limit: int | None = None)¶
Bases:
torch.utils.data.DatasetOne converted ASE db -> one pocket-ligand complex per index.
center=Truesubtracts the joint ligand+pocket centroid (upstream’s training-time behaviour,center_pos_plre-centres anyway); generation usescenter=Falseso the sampled ligand lands in the input pocket’s own frame.# ponytail: rows are read eagerly into RAM at construction, like # DiffPharmaDataset. 31 complexes here, fine to ~100k. Stream by row id in # __getitem__ if a full CrossDocked split ever needs it.
- center = True¶
- db_path¶
- MolecularDiffusion.data.component.pmdm_data.fully_connected_edges(sizes: List[int]) torch.Tensor¶
Per-molecule fully-connected, self-loop-free edge index with offsets.
This is what PMDM’s
GetAdj()transform builds (utils/transforms.py:get_adj_matrix(n), bond type constant 2) – the real bonds are thrown away before the model ever sees them.
- MolecularDiffusion.data.component.pmdm_data.parse_pocket_pdb(path: str) Dict[str, numpy.ndarray]¶
Minimal PDB ATOM-line parser for a live pocket file, at generate time.
Relocated from
docs/model_integrations/pmdm/scripts/convert_dataset.py(that script now imports this instead of keeping its own copy) soPMDMConstrainedGeneratorcan read a plainpocket_filePDB directly, the same wayPMDMDatasetreads a converted db row. Returns raw arrays (element Z, amino-acid index, backbone flag) – one-hot expansion is the caller’s job, same convention asPMDMDataset.
- MolecularDiffusion.data.component.pmdm_data.pmdm_collate(batch: List[Dict[str, Any]]) Dict[str, Any]¶
Concatenate complexes; emit PMDM’s own attribute names.
- MolecularDiffusion.data.component.pmdm_data.write_pocket_pdb(pocket: Dict[str, numpy.ndarray], path: str) None¶
Write a pocket back to a PDB that
parse_pocket_pdb()can read.Only what the parser actually checks round-trips exactly: element, amino-acid identity, coordinates, and backbone-set membership (not the specific atom name –
"CA"/"CB"stand in for backbone/sidechain). Used bydocs/model_integrations/pmdm/scripts/extract_smoke_pair.pyto reconstruct a smoke-test pocket from a converted db row (the original raw PDBs were deleted after conversion).
- MolecularDiffusion.data.component.pmdm_data.AA_NAME_NUMBER¶
- MolecularDiffusion.data.component.pmdm_data.BACKBONE_NAMES = ['CA', 'C', 'N', 'O']¶
- MolecularDiffusion.data.component.pmdm_data.MAX_NUM_AA = 20¶
- MolecularDiffusion.data.component.pmdm_data.PMDM_ATOM_VOCAB = ['H', 'C', 'N', 'O', 'F', 'P', 'S', 'Cl', 'Se', 'others']¶
- MolecularDiffusion.data.component.pmdm_data.PMDM_ELEMENTS = [1, 6, 7, 8, 9, 15, 16, 17, 34, 119]¶
- MolecularDiffusion.data.component.pmdm_data.logger¶