MolecularDiffusion.data.component.diffdec_data¶
Dataset / collate / DataModule for DiffDec scaffold-pocket-R-group complexes.
DiffDec carries three node sets per example – a fixed 3D scaffold, a protein
pocket, and the diffused R-group – flat-concatenated into ONE padded node set
with five per-atom masks (scaffold_only_mask, pocket_mask,
scaffold_mask = scaffold+pocket, rgroup_mask, anchors). That is not
the platform’s single-node-set PointCloud batch, so this module brings its own
Dataset and collate_fn and is selected via _target_ from
configs/data/diffdec_dataset.yaml. Direct precedent:
data/component/diffsbdd_data.py, through the same seams
(cli/train.py:597 -> .load() / .train_set / .collate_fn, then
data/lightning_data_module.py’s collate_fn or graph_collate).
Storage is upstream’s own preprocessed ``.pt``, read unchanged. DiffDec
publishes crossdocksingle_{train,test}_full.pt (Zenodo record 10527451) –
a plain list[dict] of exactly the tensors its model consumes. Converting
that into an ASE db and back would be a lossy round-trip for no gain: the five
masks and the anchor flag have no home in the PointCloud db’s node-feature
columns. So the DataModule reads the list directly and
diffdec_collate() below is a port of upstream src/datasets.py
collate (l. 126-166), pocket branch.
Each row carries:
uuid, name -> list attrs, passed through untouched
positions (N, 3) -> float32 coordinates
one_hot (N, 10) -> element one-hot over DIFFDEC_ATOM_VOCAB
charges (N,) -> atomic number (unused by the model, h = one_hot)
anchors (N,) -> 1.0 on the single scaffold attachment atom
scaffold_only_mask (N,) -> scaffold atoms, pocket excluded
pocket_mask (N,) -> pocket atoms
scaffold_mask (N,) -> scaffold_only | pocket (everything NOT noised)
rgroup_mask (N,) -> the diffused R-group slots
num_atoms -> int, list attr
The R-group is padded to a fixed 10 slots with a fake '#' atom
(upstream parse_rgroup, datasets.py l. 84-124), so R-group size is
implicit: the model emits '#' into unused slots and the generator strips
those rows. '#' is therefore a real class of the vocabulary here, never a
padding artefact to be filtered at load time.
Attributes¶
Classes¶
DataModule contract: |
|
One upstream |
Functions¶
|
Port of upstream |
Port of upstream |
|
|
Port of upstream |
Module Contents¶
- class MolecularDiffusion.data.component.diffdec_data.DiffDecDataModule(root: str, train_file: str = 'crossdocksingle_test_full.pt', val_file: str | None = None, test_file: str | None = None, batch_size: int = 4, num_workers: int = 0, limit: int | None = None, atom_vocab: List[str] | None = None, task_type: str = 'diffusion_diffdec', **kwargs: Any)¶
DataModule contract:
load()+train_set/valid_set/test_set.# ponytail: no split logic –
val_file/test_filefall back to the # training file. The published test split is 43 complexes and is what the # smoke test uses; point each at its own.ptfor a real run.- atom_vocab¶
- batch_size = 4¶
- collate_fn¶
- kwargs¶
- limit = None¶
- num_workers = 0¶
- root¶
- task_type = 'diffusion_diffdec'¶
- test_file = 'crossdocksingle_test_full.pt'¶
- test_set: DiffDecDataset | None = None¶
- train_file = 'crossdocksingle_test_full.pt'¶
- train_set: DiffDecDataset | None = None¶
- val_file = 'crossdocksingle_test_full.pt'¶
- valid_set: DiffDecDataset | None = None¶
- class MolecularDiffusion.data.component.diffdec_data.DiffDecDataset(pt_path: str, limit: int | None = None)¶
Bases:
torch.utils.data.DatasetOne upstream
.pt-> one scaffold/pocket/R-group complex per index.No re-centring at load time:
DiffDecTask.forwardremoves the partial centre of mass itself (w.r.t.center_of_mass,anchorsby default), exactly as upstreammodel_single.py:161-169does, and the generator adds that offset back so samples land in the original pocket’s frame.# ponytail: the whole list is read into RAM, like DiffSBDDDataset. The # test split is 43 complexes / 939 KB; the full train split is 1.6 GB, so # switch to a memory-mapped or sharded read if you train on it.
- pt_path¶
- MolecularDiffusion.data.component.diffdec_data.create_template(tensor: torch.Tensor, scaffold_size: int, rgroup_size: int, fill: float = 0.0) torch.Tensor¶
Port of upstream
datasets.py::create_template(l. 216-220).Keeps the first
scaffold_sizerows (scaffold + pocket, which the collate ordering puts first) and replaces the R-group rows with a constant block – zeros for coordinates/features, ones forrgroup_mask.
- MolecularDiffusion.data.component.diffdec_data.create_templates_for_rgroup_generation_single(data: Dict[str, Any], rgroup_sizes: torch.Tensor) Dict[str, Any]¶
Port of upstream
datasets.pyl. 222-244.Blanks the ground-truth R-group out of a real batch, leaving the scaffold and pocket intact, so sampling starts from noise in the R-group slots only.
- MolecularDiffusion.data.component.diffdec_data.diffdec_collate(batch: List[Dict[str, Any]]) Dict[str, Any]¶
Port of upstream
src/datasets.py::collate(l. 126-166).Pocket branch only (
pocket_maskis always present in the single-R-group CrossDocked data):edge_maskis emitted as a flat batch-index vector, not an adjacency mask. The actual graph is a 4 A radius graph rebuilt every forward pass byDynamicsWithPockets.get_dist_edges_4A, which uses this vector only to forbid edges between different samples.
- MolecularDiffusion.data.component.diffdec_data.DATA_ATTRS_TO_ADD_LAST_DIM¶
- MolecularDiffusion.data.component.diffdec_data.DATA_ATTRS_TO_PAD¶
- MolecularDiffusion.data.component.diffdec_data.DATA_LIST_ATTRS¶
- MolecularDiffusion.data.component.diffdec_data.DIFFDEC_ATOM_VOCAB = ['C', 'O', 'N', 'F', 'S', 'Cl', 'Br', 'I', 'P', '#']¶
- MolecularDiffusion.data.component.diffdec_data.DIFFDEC_CHARGES = [6, 8, 7, 9, 16, 17, 35, 53, 15, 0]¶
- MolecularDiffusion.data.component.diffdec_data.FAKE_ATOM_INDEX¶
- MolecularDiffusion.data.component.diffdec_data.logger¶