diffbio 0.1.0__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.
Files changed (202) hide show
  1. diffbio/__init__.py +39 -0
  2. diffbio/configs.py +75 -0
  3. diffbio/constants.py +204 -0
  4. diffbio/core/__init__.py +127 -0
  5. diffbio/core/base_operators.py +612 -0
  6. diffbio/core/data_types.py +260 -0
  7. diffbio/core/gnn_components.py +629 -0
  8. diffbio/core/graph_utils.py +149 -0
  9. diffbio/core/neural_components.py +270 -0
  10. diffbio/core/optimal_transport.py +133 -0
  11. diffbio/core/soft_ops/__init__.py +216 -0
  12. diffbio/core/soft_ops/_projections_permutahedron.py +1864 -0
  13. diffbio/core/soft_ops/_projections_simplex.py +240 -0
  14. diffbio/core/soft_ops/_projections_transport.py +508 -0
  15. diffbio/core/soft_ops/_sorting_network.py +204 -0
  16. diffbio/core/soft_ops/_types.py +15 -0
  17. diffbio/core/soft_ops/_utils.py +342 -0
  18. diffbio/core/soft_ops/autograd_safe.py +120 -0
  19. diffbio/core/soft_ops/comparison.py +235 -0
  20. diffbio/core/soft_ops/elementwise.py +309 -0
  21. diffbio/core/soft_ops/logical.py +146 -0
  22. diffbio/core/soft_ops/quantile.py +376 -0
  23. diffbio/core/soft_ops/selection.py +236 -0
  24. diffbio/core/soft_ops/sorting.py +926 -0
  25. diffbio/core/soft_ops/straight_through.py +261 -0
  26. diffbio/core/uncertainty.py +279 -0
  27. diffbio/evaluation/__init__.py +42 -0
  28. diffbio/evaluation/adapters.py +409 -0
  29. diffbio/evaluation/graders.py +223 -0
  30. diffbio/evaluation/problem.py +157 -0
  31. diffbio/evaluation/runner.py +277 -0
  32. diffbio/losses/__init__.py +59 -0
  33. diffbio/losses/alignment_losses.py +222 -0
  34. diffbio/losses/biological_regularization.py +288 -0
  35. diffbio/losses/metric_losses.py +139 -0
  36. diffbio/losses/singlecell_losses.py +387 -0
  37. diffbio/losses/statistical_losses.py +345 -0
  38. diffbio/operators/__init__.py +60 -0
  39. diffbio/operators/_count_vae.py +197 -0
  40. diffbio/operators/_loss_balancing.py +65 -0
  41. diffbio/operators/_masked_gene_transformer.py +118 -0
  42. diffbio/operators/_transformer_validation.py +50 -0
  43. diffbio/operators/alignment/__init__.py +51 -0
  44. diffbio/operators/alignment/profile_hmm.py +350 -0
  45. diffbio/operators/alignment/scoring.py +127 -0
  46. diffbio/operators/alignment/smith_waterman.py +261 -0
  47. diffbio/operators/alignment/soft_msa.py +419 -0
  48. diffbio/operators/assembly/__init__.py +27 -0
  49. diffbio/operators/assembly/gnn_assembly.py +252 -0
  50. diffbio/operators/assembly/metagenomic_binning.py +296 -0
  51. diffbio/operators/crispr/__init__.py +17 -0
  52. diffbio/operators/crispr/guide_scoring.py +269 -0
  53. diffbio/operators/drug_discovery/__init__.py +133 -0
  54. diffbio/operators/drug_discovery/_graph_utils.py +142 -0
  55. diffbio/operators/drug_discovery/admet_predictor.py +285 -0
  56. diffbio/operators/drug_discovery/attentive_fp.py +411 -0
  57. diffbio/operators/drug_discovery/dti.py +261 -0
  58. diffbio/operators/drug_discovery/fingerprint.py +490 -0
  59. diffbio/operators/drug_discovery/maccs_keys.py +267 -0
  60. diffbio/operators/drug_discovery/message_passing.py +200 -0
  61. diffbio/operators/drug_discovery/primitives.py +242 -0
  62. diffbio/operators/drug_discovery/property_predictor.py +163 -0
  63. diffbio/operators/drug_discovery/similarity.py +193 -0
  64. diffbio/operators/epigenomics/__init__.py +35 -0
  65. diffbio/operators/epigenomics/chromatin_state.py +491 -0
  66. diffbio/operators/epigenomics/contextual.py +288 -0
  67. diffbio/operators/epigenomics/fno_peak_calling.py +153 -0
  68. diffbio/operators/epigenomics/peak_calling.py +555 -0
  69. diffbio/operators/foundation_models/__init__.py +119 -0
  70. diffbio/operators/foundation_models/adapters.py +114 -0
  71. diffbio/operators/foundation_models/contracts.py +245 -0
  72. diffbio/operators/foundation_models/embedding_probe.py +83 -0
  73. diffbio/operators/foundation_models/experimental.py +128 -0
  74. diffbio/operators/foundation_models/foundation_model.py +332 -0
  75. diffbio/operators/foundation_models/frozen.py +59 -0
  76. diffbio/operators/foundation_models/precomputed.py +270 -0
  77. diffbio/operators/foundation_models/transformer_encoder.py +564 -0
  78. diffbio/operators/mapping/__init__.py +17 -0
  79. diffbio/operators/mapping/neural_mapper.py +493 -0
  80. diffbio/operators/metabolomics/__init__.py +39 -0
  81. diffbio/operators/metabolomics/spectral_similarity.py +315 -0
  82. diffbio/operators/molecular_dynamics/__init__.py +51 -0
  83. diffbio/operators/molecular_dynamics/force_field.py +265 -0
  84. diffbio/operators/molecular_dynamics/integrator.py +304 -0
  85. diffbio/operators/molecular_dynamics/primitives.py +115 -0
  86. diffbio/operators/multiomics/__init__.py +38 -0
  87. diffbio/operators/multiomics/hic_contact.py +377 -0
  88. diffbio/operators/multiomics/multiomics_vae.py +325 -0
  89. diffbio/operators/multiomics/spatial_deconvolution.py +316 -0
  90. diffbio/operators/multiomics/spatial_gene_detection.py +493 -0
  91. diffbio/operators/normalization/__init__.py +42 -0
  92. diffbio/operators/normalization/embedding.py +222 -0
  93. diffbio/operators/normalization/phate.py +400 -0
  94. diffbio/operators/normalization/umap.py +261 -0
  95. diffbio/operators/normalization/vae_normalizer.py +258 -0
  96. diffbio/operators/population/__init__.py +17 -0
  97. diffbio/operators/population/ancestry_estimation.py +274 -0
  98. diffbio/operators/preprocessing/__init__.py +76 -0
  99. diffbio/operators/preprocessing/adapter_removal.py +311 -0
  100. diffbio/operators/preprocessing/duplicate_filter.py +317 -0
  101. diffbio/operators/preprocessing/error_correction.py +287 -0
  102. diffbio/operators/protein/__init__.py +31 -0
  103. diffbio/operators/protein/secondary_structure.py +509 -0
  104. diffbio/operators/quality_filter.py +128 -0
  105. diffbio/operators/rna_structure/__init__.py +35 -0
  106. diffbio/operators/rna_structure/rna_folding.py +509 -0
  107. diffbio/operators/rnaseq/__init__.py +23 -0
  108. diffbio/operators/rnaseq/motif_discovery.py +251 -0
  109. diffbio/operators/rnaseq/splicing_psi.py +216 -0
  110. diffbio/operators/singlecell/__init__.py +193 -0
  111. diffbio/operators/singlecell/ambient_removal.py +333 -0
  112. diffbio/operators/singlecell/archetypes.py +191 -0
  113. diffbio/operators/singlecell/batch_correction.py +288 -0
  114. diffbio/operators/singlecell/cell_annotation.py +519 -0
  115. diffbio/operators/singlecell/communication.py +704 -0
  116. diffbio/operators/singlecell/differential_distribution.py +243 -0
  117. diffbio/operators/singlecell/doublet_detection.py +657 -0
  118. diffbio/operators/singlecell/downsampling.py +166 -0
  119. diffbio/operators/singlecell/enhanced_batch_correction.py +519 -0
  120. diffbio/operators/singlecell/grn_inference.py +336 -0
  121. diffbio/operators/singlecell/imputation.py +429 -0
  122. diffbio/operators/singlecell/knockdown_filter.py +176 -0
  123. diffbio/operators/singlecell/ot_trajectory.py +277 -0
  124. diffbio/operators/singlecell/simulation.py +444 -0
  125. diffbio/operators/singlecell/sindy_grn.py +247 -0
  126. diffbio/operators/singlecell/soft_clustering.py +211 -0
  127. diffbio/operators/singlecell/spatial_domains.py +677 -0
  128. diffbio/operators/singlecell/switch_de.py +184 -0
  129. diffbio/operators/singlecell/trajectory.py +447 -0
  130. diffbio/operators/singlecell/velocity.py +361 -0
  131. diffbio/operators/statistical/__init__.py +35 -0
  132. diffbio/operators/statistical/em_quantification.py +260 -0
  133. diffbio/operators/statistical/hmm.py +234 -0
  134. diffbio/operators/statistical/nb_glm.py +272 -0
  135. diffbio/operators/variant/__init__.py +64 -0
  136. diffbio/operators/variant/classifier.py +333 -0
  137. diffbio/operators/variant/cnn_classifier.py +255 -0
  138. diffbio/operators/variant/cnv_segmentation.py +678 -0
  139. diffbio/operators/variant/deepvariant_pileup.py +426 -0
  140. diffbio/operators/variant/pileup.py +240 -0
  141. diffbio/operators/variant/quality_recalibration.py +274 -0
  142. diffbio/pipelines/__init__.py +65 -0
  143. diffbio/pipelines/differential_expression.py +279 -0
  144. diffbio/pipelines/enhanced_variant_calling.py +326 -0
  145. diffbio/pipelines/perturbation.py +407 -0
  146. diffbio/pipelines/preprocessing.py +267 -0
  147. diffbio/pipelines/single_cell.py +366 -0
  148. diffbio/pipelines/variant_calling.py +490 -0
  149. diffbio/samplers/__init__.py +9 -0
  150. diffbio/samplers/perturbation_sampler.py +142 -0
  151. diffbio/sequences/__init__.py +34 -0
  152. diffbio/sequences/dna.py +239 -0
  153. diffbio/sources/__init__.py +149 -0
  154. diffbio/sources/_anndata_shared.py +89 -0
  155. diffbio/sources/_batch_iteration.py +37 -0
  156. diffbio/sources/_benchmark_source.py +152 -0
  157. diffbio/sources/_indexed_batch_source.py +38 -0
  158. diffbio/sources/_utils.py +45 -0
  159. diffbio/sources/anndata_interop.py +387 -0
  160. diffbio/sources/anndata_source.py +361 -0
  161. diffbio/sources/archive_ii.py +174 -0
  162. diffbio/sources/balifam.py +207 -0
  163. diffbio/sources/bam.py +265 -0
  164. diffbio/sources/bengrn_ground_truth.py +306 -0
  165. diffbio/sources/contextual_epigenomics.py +242 -0
  166. diffbio/sources/dti.py +359 -0
  167. diffbio/sources/embeddings.py +203 -0
  168. diffbio/sources/encode_peaks.py +223 -0
  169. diffbio/sources/fasta.py +226 -0
  170. diffbio/sources/immune_human.py +172 -0
  171. diffbio/sources/indexed_embeddings.py +128 -0
  172. diffbio/sources/indexed_view.py +191 -0
  173. diffbio/sources/molnet.py +493 -0
  174. diffbio/sources/multiomics.py +279 -0
  175. diffbio/sources/pancreas.py +108 -0
  176. diffbio/sources/perturbation/__init__.py +69 -0
  177. diffbio/sources/perturbation/_types.py +51 -0
  178. diffbio/sources/perturbation/_utils.py +125 -0
  179. diffbio/sources/perturbation/concat_source.py +115 -0
  180. diffbio/sources/perturbation/control_mapping.py +215 -0
  181. diffbio/sources/perturbation/experiment_config.py +261 -0
  182. diffbio/sources/perturbation/h5_metadata_cache.py +218 -0
  183. diffbio/sources/perturbation/output_space.py +52 -0
  184. diffbio/sources/perturbation/perturbation_source.py +513 -0
  185. diffbio/sources/seqfish.py +145 -0
  186. diffbio/sources/sequence_foundation.py +68 -0
  187. diffbio/sources/singlecell_foundation.py +68 -0
  188. diffbio/splitters/__init__.py +63 -0
  189. diffbio/splitters/base.py +251 -0
  190. diffbio/splitters/molecular.py +330 -0
  191. diffbio/splitters/perturbation.py +199 -0
  192. diffbio/splitters/random.py +217 -0
  193. diffbio/splitters/sequence.py +201 -0
  194. diffbio/utils/__init__.py +55 -0
  195. diffbio/utils/dependency_runtime.py +115 -0
  196. diffbio/utils/nn_utils.py +157 -0
  197. diffbio/utils/quality.py +45 -0
  198. diffbio/utils/training.py +585 -0
  199. diffbio-0.1.0.dist-info/METADATA +480 -0
  200. diffbio-0.1.0.dist-info/RECORD +202 -0
  201. diffbio-0.1.0.dist-info/WHEEL +4 -0
  202. diffbio-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,261 @@
1
+ """Differentiable drug-target interaction pipeline.
2
+
3
+ The pipeline combines existing DiffBio building blocks:
4
+
5
+ - ``TransformerSequenceEncoder`` for protein sequence embeddings.
6
+ - ``DifferentiableMolecularFingerprint`` for molecular graph fingerprints.
7
+
8
+ This module centralizes DTI input preparation so benchmarks do not maintain
9
+ bespoke protein/drug feature handling.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from dataclasses import dataclass
15
+ from typing import Any
16
+
17
+ import jax.numpy as jnp
18
+ import numpy as np
19
+ from datarax.core.config import OperatorConfig
20
+ from flax import nnx
21
+
22
+ from diffbio.operators.alignment import PROTEIN_ALPHABET
23
+ from diffbio.operators.drug_discovery.fingerprint import (
24
+ DifferentiableMolecularFingerprint,
25
+ MolecularFingerprintConfig,
26
+ )
27
+ from diffbio.operators.drug_discovery.primitives import (
28
+ DEFAULT_ATOM_FEATURES,
29
+ batch_smiles_to_graphs,
30
+ )
31
+ from diffbio.operators.foundation_models.contracts import AdapterMode, FoundationModelKind
32
+ from diffbio.operators.foundation_models.transformer_encoder import (
33
+ TransformerSequenceEncoder,
34
+ TransformerSequenceEncoderConfig,
35
+ )
36
+ from diffbio.sources.dti import validate_dti_dataset
37
+
38
+ PROTEIN_ONE_HOT_PREPROCESSING_VERSION = "protein_one_hot_v1"
39
+ DTI_PIPELINE_INTEGRATION_LAYER = "shared_dti_pipeline_v1"
40
+ _PROTEIN_ALPHABET_INDEX = {residue: index for index, residue in enumerate(PROTEIN_ALPHABET)}
41
+
42
+
43
+ @dataclass(frozen=True)
44
+ class _DTIProteinEncoderConfig:
45
+ """Protein encoder configuration for the DTI pipeline."""
46
+
47
+ protein_hidden_dim: int = 16
48
+ protein_num_layers: int = 1
49
+ protein_num_heads: int = 2
50
+ protein_intermediate_dim: int = 32
51
+ max_protein_length: int = 32
52
+
53
+
54
+ @dataclass(frozen=True)
55
+ class _DTIDrugEncoderConfig:
56
+ """Drug encoder configuration for the DTI pipeline."""
57
+
58
+ drug_fingerprint_dim: int = 16
59
+ drug_hidden_dim: int = 16
60
+ drug_num_layers: int = 2
61
+
62
+
63
+ @dataclass(frozen=True)
64
+ class _DTIPairScorerConfig:
65
+ """Pair scorer and artifact configuration for the DTI pipeline."""
66
+
67
+ pair_hidden_dim: int = 16
68
+ foundation_artifact_id: str = "diffbio.dti_protein_encoder"
69
+ foundation_preprocessing_version: str = PROTEIN_ONE_HOT_PREPROCESSING_VERSION
70
+
71
+
72
+ @dataclass(frozen=True)
73
+ class DTIPipelineConfig(
74
+ _DTIProteinEncoderConfig,
75
+ _DTIDrugEncoderConfig,
76
+ _DTIPairScorerConfig,
77
+ OperatorConfig,
78
+ ):
79
+ """Configuration for the shared differentiable DTI pipeline."""
80
+
81
+ def __post_init__(self) -> None:
82
+ """Validate the pipeline configuration."""
83
+ super().__post_init__()
84
+ positive_fields = {
85
+ "protein_hidden_dim": self.protein_hidden_dim,
86
+ "protein_num_layers": self.protein_num_layers,
87
+ "protein_num_heads": self.protein_num_heads,
88
+ "protein_intermediate_dim": self.protein_intermediate_dim,
89
+ "max_protein_length": self.max_protein_length,
90
+ "drug_fingerprint_dim": self.drug_fingerprint_dim,
91
+ "drug_hidden_dim": self.drug_hidden_dim,
92
+ "drug_num_layers": self.drug_num_layers,
93
+ "pair_hidden_dim": self.pair_hidden_dim,
94
+ }
95
+ for field_name, value in positive_fields.items():
96
+ if value <= 0:
97
+ raise ValueError(f"{field_name} must be positive.")
98
+
99
+
100
+ class DifferentiableDTIPipeline(nnx.Module):
101
+ """ConPLex-style DTI scorer with differentiable drug and protein encoders."""
102
+
103
+ def __init__(
104
+ self,
105
+ config: DTIPipelineConfig,
106
+ *,
107
+ rngs: nnx.Rngs | None = None,
108
+ ) -> None:
109
+ """Initialize protein encoder, drug encoder, and pair scorer."""
110
+ super().__init__()
111
+ if rngs is None:
112
+ rngs = nnx.Rngs(0)
113
+
114
+ self.config = nnx.static(config)
115
+ self.protein_encoder = TransformerSequenceEncoder(
116
+ TransformerSequenceEncoderConfig(
117
+ hidden_dim=config.protein_hidden_dim,
118
+ num_layers=config.protein_num_layers,
119
+ num_heads=config.protein_num_heads,
120
+ intermediate_dim=config.protein_intermediate_dim,
121
+ max_length=config.max_protein_length,
122
+ alphabet_size=len(PROTEIN_ALPHABET),
123
+ dropout_rate=0.0,
124
+ pooling="mean",
125
+ artifact_id=config.foundation_artifact_id,
126
+ preprocessing_version=config.foundation_preprocessing_version,
127
+ adapter_mode=AdapterMode.NATIVE_TRAINABLE,
128
+ ),
129
+ rngs=rngs,
130
+ )
131
+ self.drug_encoder = DifferentiableMolecularFingerprint(
132
+ MolecularFingerprintConfig(
133
+ fingerprint_dim=config.drug_fingerprint_dim,
134
+ hidden_dim=config.drug_hidden_dim,
135
+ num_layers=config.drug_num_layers,
136
+ in_features=DEFAULT_ATOM_FEATURES,
137
+ normalize=True,
138
+ ),
139
+ rngs=rngs,
140
+ )
141
+ self.pair_hidden = nnx.Linear(
142
+ config.protein_hidden_dim + config.drug_fingerprint_dim,
143
+ config.pair_hidden_dim,
144
+ rngs=rngs,
145
+ )
146
+ self.output = nnx.Linear(config.pair_hidden_dim, 1, rngs=rngs)
147
+
148
+ def apply(
149
+ self,
150
+ data: dict[str, Any],
151
+ state: dict[str, Any],
152
+ metadata: dict[str, Any] | None,
153
+ random_params: Any = None,
154
+ stats: dict[str, Any] | None = None,
155
+ ) -> tuple[dict[str, Any], dict[str, Any], dict[str, Any] | None]:
156
+ """Score a prepared paired protein/drug DTI batch."""
157
+ del random_params, stats
158
+
159
+ protein_result, _, _ = self.protein_encoder.apply(
160
+ {
161
+ "sequence": data["protein_one_hot"],
162
+ "attention_mask": data["protein_attention_mask"],
163
+ },
164
+ {},
165
+ None,
166
+ )
167
+ protein_embeddings = jnp.asarray(protein_result["embeddings"], dtype=jnp.float32)
168
+ drug_fingerprints = self._encode_drug_graphs(data["drug_graphs"])
169
+ pair_embeddings = jnp.concatenate([protein_embeddings, drug_fingerprints], axis=-1)
170
+ hidden = nnx.gelu(self.pair_hidden(pair_embeddings))
171
+ scores = self.output(hidden).squeeze(-1)
172
+
173
+ return (
174
+ {
175
+ **data,
176
+ "scores": scores,
177
+ "protein_embeddings": protein_embeddings,
178
+ "drug_fingerprints": drug_fingerprints,
179
+ "pair_embeddings": pair_embeddings,
180
+ "foundation_model": protein_result["foundation_model"],
181
+ "dti_pipeline": self.pipeline_metadata(),
182
+ },
183
+ state,
184
+ metadata,
185
+ )
186
+
187
+ def pipeline_metadata(self) -> dict[str, Any]:
188
+ """Return benchmark-facing metadata for the integrated DTI path."""
189
+ return {
190
+ "integration_layer": DTI_PIPELINE_INTEGRATION_LAYER,
191
+ "pipeline_name": type(self).__name__,
192
+ "protein_encoder": {
193
+ "operator": "TransformerSequenceEncoder",
194
+ "model_family": FoundationModelKind.SEQUENCE_TRANSFORMER.value,
195
+ "adapter_mode": AdapterMode.NATIVE_TRAINABLE.value,
196
+ "preprocessing_version": self.config.foundation_preprocessing_version,
197
+ },
198
+ "drug_encoder": {
199
+ "operator": "DifferentiableMolecularFingerprint",
200
+ "differentiable": True,
201
+ },
202
+ }
203
+
204
+ def _encode_drug_graphs(self, drug_graphs: dict[str, Any]) -> jnp.ndarray:
205
+ """Encode a padded molecular graph batch with the shared fingerprint operator."""
206
+ fingerprints = []
207
+ batch_size = int(drug_graphs["node_features"].shape[0])
208
+ for index in range(batch_size):
209
+ graph = {
210
+ "node_features": drug_graphs["node_features"][index],
211
+ "adjacency": drug_graphs["adjacency"][index],
212
+ "edge_features": drug_graphs["edge_features"][index],
213
+ "node_mask": drug_graphs["node_mask"][index],
214
+ }
215
+ result, _, _ = self.drug_encoder.apply(graph, {}, None)
216
+ fingerprints.append(result["fingerprint"])
217
+ return jnp.stack(fingerprints)
218
+
219
+
220
+ def build_dti_pipeline_inputs(
221
+ data: dict[str, Any],
222
+ *,
223
+ config: DTIPipelineConfig | None = None,
224
+ ) -> dict[str, Any]:
225
+ """Build one encoded protein/graph batch from a validated DTI payload."""
226
+ validate_dti_dataset(data)
227
+ resolved_config = config or DTIPipelineConfig()
228
+ protein_one_hot, protein_attention_mask = encode_protein_sequences(
229
+ data["protein_sequences"],
230
+ max_length=resolved_config.max_protein_length,
231
+ )
232
+ return {
233
+ "protein_one_hot": protein_one_hot,
234
+ "protein_attention_mask": protein_attention_mask,
235
+ "drug_graphs": batch_smiles_to_graphs(list(data["drug_smiles"])),
236
+ "targets": jnp.asarray(data["targets"], dtype=jnp.float32),
237
+ }
238
+
239
+
240
+ def encode_protein_sequences(
241
+ sequences: list[str],
242
+ *,
243
+ max_length: int,
244
+ ) -> tuple[jnp.ndarray, jnp.ndarray]:
245
+ """One-hot encode protein strings using the shared alignment alphabet."""
246
+ if max_length <= 0:
247
+ raise ValueError("max_length must be positive.")
248
+
249
+ encoded = np.zeros((len(sequences), max_length, len(PROTEIN_ALPHABET)), dtype=np.float32)
250
+ attention_mask = np.zeros((len(sequences), max_length), dtype=np.float32)
251
+
252
+ for sequence_index, sequence in enumerate(sequences):
253
+ for residue_index, residue in enumerate(sequence[:max_length]):
254
+ amino_acid_index = _PROTEIN_ALPHABET_INDEX.get(residue.upper())
255
+ if amino_acid_index is None:
256
+ encoded[sequence_index, residue_index, :] = 1.0 / len(PROTEIN_ALPHABET)
257
+ else:
258
+ encoded[sequence_index, residue_index, amino_acid_index] = 1.0
259
+ attention_mask[sequence_index, residue_index] = 1.0
260
+
261
+ return jnp.asarray(encoded), jnp.asarray(attention_mask)