Skip to content

Commit fe7396c

Browse files
committed
Basic implementation of mmcif writing
1 parent 24c7f6b commit fe7396c

File tree

5 files changed

+383
-12
lines changed

5 files changed

+383
-12
lines changed

biojava-structure/src/main/java/org/biojava/nbio/structure/ResidueRangeAndLength.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import java.util.ArrayList;
2424
import java.util.Iterator;
2525
import java.util.List;
26-
import java.util.NavigableMap;
2726

2827
import org.slf4j.Logger;
2928
import org.slf4j.LoggerFactory;

biojava-structure/src/main/java/org/biojava/nbio/structure/io/FileConvert.java

Lines changed: 220 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
package org.biojava.nbio.structure.io;
2323

2424
import org.biojava.nbio.structure.*;
25+
import org.biojava.nbio.structure.io.mmcif.model.AtomSite;
2526
import org.biojava.nbio.core.util.XMLWriter;
2627

2728
import java.io.IOException;
@@ -34,8 +35,8 @@
3435
import java.util.Locale;
3536
import java.util.Map;
3637

37-
//import org.slf4j.Logger;
38-
//import org.slf4j.LoggerFactory;
38+
import org.slf4j.Logger;
39+
import org.slf4j.LoggerFactory;
3940

4041

4142
/** Methods to convert a structure object into different file formats.
@@ -44,7 +45,12 @@
4445
*/
4546
public class FileConvert {
4647

47-
//private static final Logger logger = LoggerFactory.getLogger(FileConvert.class);
48+
private static final Logger logger = LoggerFactory.getLogger(FileConvert.class);
49+
50+
/**
51+
* The character to be printed out in cases where a value is not assigned in mmCIF files
52+
*/
53+
public static final String MMCIF_MISSING_VALUE = "?";
4854

4955
private Structure structure ;
5056

@@ -336,7 +342,8 @@ public static String toPDB(Atom a, String chainId) {
336342
}
337343

338344

339-
/** Convert a Chain object to PDB representation
345+
/**
346+
* Convert a Chain object to PDB representation
340347
*
341348
* @param chain
342349
* @return
@@ -358,7 +365,8 @@ public static String toPDB(Chain chain){
358365
return w.toString();
359366
}
360367

361-
/** Convert a Group object to PDB representation
368+
/**
369+
* Convert a Group object to PDB representation
362370
*
363371
* @param g
364372
* @return
@@ -370,7 +378,7 @@ public static String toPDB(Group g){
370378
}
371379

372380
/**
373-
* print ATOM record in the following syntax
381+
* Print ATOM record in the following syntax
374382
<pre>
375383
ATOM 1 N ASP A 15 110.964 24.941 59.191 1.00 83.44 N
376384
*
@@ -489,7 +497,8 @@ private static boolean hasInsertionCode(String pdbserial) {
489497
}
490498

491499

492-
/** convert a protein Structure to a DAS Structure XML response .
500+
/**
501+
* Convert a protein Structure to a DAS Structure XML response .
493502
* @param xw a XMLWriter object
494503
* @throws IOException ...
495504
*
@@ -676,4 +685,208 @@ else if (name.length()==1)
676685

677686
return fullName;
678687
}
688+
689+
690+
public String toMmCif() {
691+
StringBuilder str = new StringBuilder();
692+
693+
try {
694+
String header = MMCIFFileTools.toLoopMmCifHeaderString("_atom_site", AtomSite.class.getName());
695+
str.append(header);
696+
} catch (ClassNotFoundException e) {
697+
logger.error("Class not found, will not have a header for this MMCIF category: "+e.getMessage());
698+
}
699+
700+
701+
702+
int nrModels = structure.nrModels();
703+
704+
for (int m = 0 ; m < nrModels ; m++) {
705+
List<Chain> model = structure.getModel(m);
706+
707+
708+
int nrChains = model.size();
709+
for ( int c =0; c<nrChains;c++) {
710+
Chain chain = model.get(c);
711+
712+
if (chain.getCompound()==null) {
713+
logger.warn("No Compound (entity) found for chain {}: entity_id will be set to 0, label_seq_id will be the same as auth_seq_id", chain.getChainID());
714+
}
715+
716+
int nrGroups = chain.getAtomLength();
717+
718+
for ( int h=0; h<nrGroups;h++){
719+
720+
Group g= chain.getAtomGroup(h);
721+
722+
toMmCif(g,str,m+1);
723+
724+
}
725+
726+
}
727+
728+
729+
}
730+
731+
return str.toString();
732+
}
733+
734+
public static String toMmCif(Chain chain, String chainId, String internalChainId) {
735+
StringBuilder str = new StringBuilder();
736+
737+
try {
738+
String header = MMCIFFileTools.toLoopMmCifHeaderString("_atom_site", AtomSite.class.getName());
739+
str.append(header);
740+
} catch (ClassNotFoundException e) {
741+
logger.error("Class not found, will not have a header for this MMCIF category: "+e.getMessage());
742+
}
743+
744+
if (chain.getCompound()==null) {
745+
logger.warn("No Compound (entity) found for chain {}: entity_id will be set to 0, label_seq_id will be the same as auth_seq_id", chain.getChainID());
746+
}
747+
748+
749+
int nrGroups = chain.getAtomLength();
750+
751+
for ( int h=0; h<nrGroups;h++){
752+
753+
Group g= chain.getAtomGroup(h);
754+
755+
toMmCif(g,str, 1, chainId, internalChainId);
756+
757+
}
758+
759+
return str.toString();
760+
}
761+
762+
public static String toMmCif(Chain chain) {
763+
StringBuilder str = new StringBuilder();
764+
765+
try {
766+
String header = MMCIFFileTools.toLoopMmCifHeaderString("_atom_site", AtomSite.class.getName());
767+
str.append(header);
768+
} catch (ClassNotFoundException e) {
769+
logger.error("Class not found, will not have a header for this MMCIF category: "+e.getMessage());
770+
}
771+
772+
int nrGroups = chain.getAtomLength();
773+
774+
for ( int h=0; h<nrGroups;h++){
775+
776+
Group g= chain.getAtomGroup(h);
777+
778+
toMmCif(g, str, 1);
779+
780+
}
781+
782+
return str.toString();
783+
}
784+
785+
public static void toMmCif(Group g, StringBuilder str, int model) {
786+
toMmCif(g, str, model, g.getChainId(), g.getChain().getInternalChainID());
787+
}
788+
789+
public static void toMmCif(Group g, StringBuilder str, int model, String chainId, String internalChainId) {
790+
int groupsize = g.size();
791+
792+
for ( int atompos = 0 ; atompos < groupsize; atompos++) {
793+
Atom a = null ;
794+
795+
a = g.getAtom(atompos);
796+
if ( a == null)
797+
continue ;
798+
799+
toMmCif(a, str, model, chainId, internalChainId);
800+
801+
}
802+
if ( g.hasAltLoc()){
803+
for (Group alt : g.getAltLocs() ) {
804+
toMmCif(alt,str,model,chainId,internalChainId);
805+
}
806+
}
807+
}
808+
809+
/**
810+
* Write the atom as a mmCIF atom_site record.
811+
* @param a
812+
* @param str
813+
* @param chainId
814+
* @param internalChainId
815+
*/
816+
private static void toMmCif(Atom a, StringBuilder str, int model, String chainId, String internalChainId) {
817+
818+
/*
819+
ATOM 7 C CD . GLU A 1 24 ? -10.109 15.374 38.853 1.00 50.05 ? ? ? ? ? ? 24 GLU A CD 1
820+
ATOM 8 O OE1 . GLU A 1 24 ? -9.659 14.764 37.849 1.00 49.80 ? ? ? ? ? ? 24 GLU A OE1 1
821+
ATOM 9 O OE2 . GLU A 1 24 ? -11.259 15.171 39.310 1.00 50.51 ? ? ? ? ? ? 24 GLU A OE2 1
822+
ATOM 10 N N . LEU A 1 25 ? -5.907 18.743 37.412 1.00 41.55 ? ? ? ? ? ? 25 LEU A N 1
823+
ATOM 11 C CA . LEU A 1 25 ? -5.168 19.939 37.026 1.00 37.55 ? ? ? ? ? ? 25 LEU A CA 1
824+
*/
825+
826+
Group g = a.getGroup();
827+
828+
String record ;
829+
if ( g.getType().equals(GroupType.HETATM) ) {
830+
record = "HETATM";
831+
} else {
832+
record = "ATOM";
833+
}
834+
835+
String entityId = "0";
836+
String labelSeqId = Integer.toString(g.getResidueNumber().getSeqNum());
837+
if (g.getChain()!=null && g.getChain().getCompound()!=null) {
838+
entityId = Integer.toString(g.getChain().getCompound().getMolId());
839+
labelSeqId = Integer.toString(g.getChain().getCompound().getAlignedResIndex(g, g.getChain()));
840+
}
841+
842+
Character altLoc = a.getAltLoc() ;
843+
String altLocStr = altLoc.toString();
844+
if (altLoc==null || altLoc == ' ') {
845+
altLocStr = ".";
846+
}
847+
848+
Element e = a.getElement();
849+
String eString = e.toString().toUpperCase();
850+
if ( e.equals(Element.R)) {
851+
eString = "X";
852+
}
853+
854+
String insCode = MMCIF_MISSING_VALUE;
855+
if (g.getResidueNumber().getInsCode()!=null ) {
856+
insCode = Integer.toString(g.getResidueNumber().getInsCode());
857+
}
858+
859+
AtomSite atomSite = new AtomSite();
860+
atomSite.setGroup_PDB(record);
861+
atomSite.setId(Integer.toString(a.getPDBserial()));
862+
atomSite.setType_symbol(eString);
863+
atomSite.setLabel_atom_id(a.getName());
864+
atomSite.setLabel_alt_id(altLocStr);
865+
atomSite.setLabel_comp_id(g.getPDBName());
866+
atomSite.setLabel_asym_id(internalChainId);
867+
atomSite.setLabel_entity_id(entityId);
868+
atomSite.setLabel_seq_id(labelSeqId);
869+
atomSite.setPdbx_PDB_ins_code(insCode);
870+
atomSite.setCartn_x(d3.format(a.getX()));
871+
atomSite.setCartn_y(d3.format(a.getY()));
872+
atomSite.setCartn_z(d3.format(a.getZ()));
873+
atomSite.setOccupancy(d2.format(a.getOccupancy()));
874+
atomSite.setB_iso_or_equiv(d2.format(a.getTempFactor()));
875+
atomSite.setCartn_x_esd(MMCIF_MISSING_VALUE);
876+
atomSite.setCartn_y_esd(MMCIF_MISSING_VALUE);
877+
atomSite.setCartn_z_esd(MMCIF_MISSING_VALUE);
878+
atomSite.setOccupancy_esd(MMCIF_MISSING_VALUE);
879+
atomSite.setB_iso_or_equiv_esd(MMCIF_MISSING_VALUE);
880+
atomSite.setPdbx_formal_charge(MMCIF_MISSING_VALUE);
881+
atomSite.setAuth_seq_id(Integer.toString(g.getResidueNumber().getSeqNum()));
882+
atomSite.setAuth_comp_id(g.getPDBName());
883+
atomSite.setAuth_asym_id(chainId);
884+
atomSite.setAuth_atom_id(a.getName());
885+
atomSite.setPdbx_PDB_model_num(Integer.toString(model));
886+
887+
str.append(MMCIFFileTools.toSingleLineMmCifString(atomSite));
888+
889+
}
890+
891+
679892
}

0 commit comments

Comments
 (0)