Skip to content

Commit

Permalink
Added support for MtriX in mmCIF #64
Browse files Browse the repository at this point in the history
  • Loading branch information
douweschulte committed Jul 20, 2022
1 parent bdf2b5a commit a1ac5cb
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ As the main goal of this library is to allow access to the atomical data many me
| ANISOU | ✔️ | ✔️ | atom_site |
| SCALE | ✔️ | ✔️ | _atom_sites.Cartn_transf |
| ORIGX | ✔️ | ✔️ | _database_PDB_matrix.origx |
| MATRIX | ✔️ | | ? |
| MATRIX | ✔️ | ✔️ | struct_ncs_oper |
| CRYSTAL | ✔️ | ✔️ | cell + symmetry |
| MODEL | ✔️ | ✔️ | atom_site |
| MASTER | 〰️ || _pdbx_database_PDB_master |
Expand Down
54 changes: 54 additions & 0 deletions src/read/mmcif/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ fn parse_mmcif(
let mut pdb = PDB::default();
let mut errors: Vec<PDBError> = Vec::new();
let mut unit_cell = UnitCell::default();
let mut mtrix_id = None;

pdb.identifier = Some(input.name.clone());

Expand Down Expand Up @@ -140,6 +141,59 @@ fn parse_mmcif(
#[allow(clippy::unwrap_used)]
parse_matrix(s, get_f64(&single.content, &context),pdb.origx.as_mut().unwrap(), &context)
}
s if s.starts_with("structs_ncs_oper.") => {
if s.ends_with("id") {
match get_usize(&single.content, &context) {
Err(e) => Some(e),
Ok(Some(id)) => {
mtrix_id = Some(id);
pdb.add_mtrix(MtriX::new(id, TransformationMatrix::identity(), true));
None
}
Ok(None) => Some(PDBError::new(
ErrorLevel::InvalidatingError,
"MtriX with missing ID",
"If a MtriX id is given it should be a number not a missing value.",
context.clone(),
))
}
} else {
#[allow(clippy::unwrap_used)]
match mtrix_id {
Some(id) => {
let mut mtrix = pdb.mtrix_mut().find(|m| m.serial_number == id).unwrap();
if s.ends_with("code") {
match get_text(&single.content, &context) {
Ok(Some(t)) if t == "given" => {mtrix.contained = true; None},
Ok(Some(t)) if t == "generate" => {mtrix.contained = false; None},
Ok(Some(_)) => Some(PDBError::new(
ErrorLevel::InvalidatingError,
"MtriX code invalid",
"Only the values 'generate' and 'given' are valid for `_struct_ncs_oper.code`.",
context.clone(),
)),
_ => Some(PDBError::new(
ErrorLevel::InvalidatingError,
"MtriX code invalid",
"The value for `_struct_ncs_oper.code` should be a textual value.",
context.clone(),
)),
}
} else if s.ends_with("details") {
None // Ignore the details, it will not be saved somewhere
} else {
parse_matrix(s, get_f64(&single.content, &context),&mut mtrix.transformation, &context)
}
},
None => Some(PDBError::new(
ErrorLevel::InvalidatingError,
"MtriX matrix given without ID",
"The MtriX ID (`_struct_ncs_oper.id`) should be given before any matrix information is given.",
context.clone(),
))
}
}
}
_ => None,
}
.map(|e| vec![e])
Expand Down
46 changes: 44 additions & 2 deletions src/save/mmcif.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ _cell.Z_PDB {}",
if let Some(scale) = &pdb.scale {
let ma = scale.matrix();
write!(
"_atom_sites.entry_id '{}'
"# Scale definition
_atom_sites.entry_id '{}'
_atom_sites.Cartn_transf_matrix[1][1] {}
_atom_sites.Cartn_transf_matrix[1][2] {}
_atom_sites.Cartn_transf_matrix[1][3] {}
Expand Down Expand Up @@ -137,7 +138,8 @@ _atom_sites.Cartn_transf_vector[3] {}",
if let Some(origx) = &pdb.origx {
let ma = origx.matrix();
write!(
"_database_PDB_matrix.entry_id '{}'
"# OrigX definition
_database_PDB_matrix.entry_id '{}'
_database_PDB_matrix.origx[1][1] {}
_database_PDB_matrix.origx[1][2] {}
_database_PDB_matrix.origx[1][3] {}
Expand Down Expand Up @@ -166,6 +168,46 @@ _database_PDB_matrix.origx_vector[3] {}",
);
}

// MtriX
for mtrix in pdb.mtrix() {
let ma = mtrix.transformation.matrix();
write!(
r#"# OrigX definition
_struct_ncs_oper.id '{}'
_struct_ncs_oper.code {}
_struct_ncs_oper.matrix[1][1] {}
_struct_ncs_oper.matrix[1][2] {}
_struct_ncs_oper.matrix[1][3] {}
_struct_ncs_oper.matrix[2][1] {}
_struct_ncs_oper.matrix[2][2] {}
_struct_ncs_oper.matrix[2][3] {}
_struct_ncs_oper.matrix[3][1] {}
_struct_ncs_oper.matrix[3][2] {}
_struct_ncs_oper.matrix[3][3] {}
_struct_ncs_oper.vector[1] {}
_struct_ncs_oper.vector[2] {}
_struct_ncs_oper.vector[3] {}"#,
mtrix.serial_number,
if mtrix.contained {
"given"
} else {
"generated"
},
ma[0][0],
ma[0][1],
ma[0][2],
ma[1][0],
ma[1][1],
ma[1][2],
ma[2][0],
ma[2][1],
ma[2][2],
ma[0][3],
ma[1][3],
ma[2][3],
);
}

if let Some(symmetry) = &pdb.symmetry {
write!(
"# Space group definition
Expand Down

0 comments on commit a1ac5cb

Please sign in to comment.