001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 * Created on 26.04.2004
021 * @author Andreas Prlic
022 *
023 */
024package org.biojava.nbio.structure;
025
026import org.biojava.nbio.structure.io.FileConvert;
027import org.biojava.nbio.structure.io.PDBFileReader;
028
029import java.util.List;
030import java.util.Map;
031
032
033/**
034 *
035 * Interface for a structure object. Provides access to the data of a PDB file.
036 *
037 * A structure object allows to access the PDB header information as well
038 * as to the data from the ATOM records. The header information is
039 * currently available through the following objects:
040 * <ul>
041 * <li>{@link PDBHeader}</li>
042 * <li>{@link DBRef}</li>
043 * <li>{@link Compound}</li>
044 * </ul>
045 *
046 * The structure object provides access to the data from the ATOM records through
047 * a hierarchy of sub-object:
048 * <pre>
049 * Structure
050 *         |
051 *         {@link Chain}
052 *             |
053 *             {@link Group}
054 *                 |
055 *                 {@link Atom}
056 * </pre>
057 *
058 * For more documentation on how to work with the Structure API please
059 * see <a href="http://biojava.org/wiki/BioJava:CookBook#Protein_Structure" target="_top">
060 * http://biojava.org/wiki/BioJava:CookBook#Protein_Structure</a>
061 *
062 * <p>
063 *  The tutorial for the BioJava structure modules can be found at <a href="https://github.com/biojava/biojava3-tutorial/tree/master/structure">github</a>.
064 * </p>
065 *
066 *
067 * <hr/>
068 * </hr>
069 * <p>
070 * Q: How can I get a Structure object from a PDB file?
071 * </p>
072 * <p>
073 * A:
074 * </p>
075 * <pre>
076 * public {@link Structure} loadStructure(String pathToPDBFile){
077 *              {@link PDBFileReader} pdbreader = new {@link PDBFileReader}();
078 *
079 *              {@link Structure} structure = null;
080 *              try{
081 *                      structure = pdbreader.getStructure(pathToPDBFile);
082 *                      System.out.println(structure);
083 *              } catch (IOException e) {
084 *                      e.printStackTrace();
085 *              }
086 *              return structure;
087 *      }
088 *  </pre>
089 *
090 * <hr>
091 * </hr>
092 * <p>
093 * Q: How can I calculate Phi and Psi angles of AminoAcids?
094 * </p>
095 * <p>
096 * A:
097 * </p>
098 * <pre>
099 * public void calcPhiPsi({@link Structure} structure){
100 *
101 *
102 *              // get the first chain from the structure
103 *
104 *              {@link Chain} chain  = structure.getChain(0);
105 *
106 *              // A protein chain consists of a number of groups. These can be either
107 *              // {@link AminoAcid}, {@link HetatomImpl Hetatom} or {@link NucleotideImpl Nucleotide} groups.
108 *              //
109 *              // Note: BioJava provides access to both the ATOM and SEQRES data in a PDB file.
110 *              // since we are interested in doing calculations here, we only request the groups
111 *              // from the ATOM records
112 *
113 *              //  get the Groups of the chain that are AminoAcids.
114 *              List<Group> groups = chain.getAtomGroups(GroupType.AMINOACID);
115 *
116 *              {@link AminoAcid} a;
117 *              {@link AminoAcid} b;
118 *              {@link AminoAcid} c ;
119 *
120 *              for ( int i=0; i < groups.size(); i++){
121 *
122 *                      // since we requested only groups of type AMINOACID they will always be amino acids
123 *                      // Nucleotide and Hetatom groups will not be present in the groups list.
124 *
125 *                      b = ({@link AminoAcid})groups.get(i);
126 *
127 *                      double phi =360.0;
128 *                      double psi =360.0;
129 *
130 *                      if ( i > 0) {
131 *                              a = ({@link AminoAcid})groups.get(i-1) ;
132 *                              try {
133 *
134 *                                      // the Calc class provides utility methods for various calculations on
135 *                                      // structures, groups and atoms
136 *
137 *                                      phi = {@link Calc}.getPhi(a,b);
138 *                              } catch ({@link StructureException} e){
139 *                                      e.printStackTrace();
140 *                                      phi = 360.0 ;
141 *                              }
142 *                      }
143 *                      if ( i < groups.size()-1) {
144 *                              c = ({@link AminoAcid})groups.get(i+1) ;
145 *                              try {
146 *                                      psi = {@link Calc}.getPsi(b,c);
147 *                              }catch ({@link StructureException} e){
148 *                                      e.printStackTrace();
149 *                                      psi = 360.0 ;
150 *                              }
151 *                      }
152 *
153 *                      System.out.print(b.getPDBCode() + " " + b.getPDBName() + ":"  );
154 *
155 *                      System.out.println(String.format("\tphi: %+7.2f psi: %+7.2f", phi, psi));
156 *
157 *              }
158 * </pre>
159 * <hr>
160 * </hr>
161 *
162 *
163 *
164 *
165 * @author Andreas Prlic
166 * @since 1.4
167 * @version %I% %G%
168 */
169public interface Structure extends Cloneable {
170
171
172        /**
173         * Return an identical copy of this Structure object
174         *
175         * @return identical copy of this Structure object
176         */
177        public Structure clone();
178
179        /**
180         * String representation of object.
181         */
182        @Override
183        public String toString();
184
185        /**
186         * Set PDB code of structure .
187         *
188         * @param pdb_id  a String specifying the PDBCode
189         * @see #getPDBCode
190         */
191        public void setPDBCode (String pdb_id) ;
192
193        /**
194         * Get PDB code of structure.
195         *
196         * @return a String representing the PDBCode value
197         * @see #setPDBCode
198         */
199        public String  getPDBCode () ;
200
201        /**
202         * Set biological name of Structure .
203         *
204         * @param name  a String specifying the biological name of the Structure
205         * @see #getName
206         */
207        public void setName(String name);
208
209        /**
210         * Get biological name of Structure.
211         *
212         * @return a String representing the biological name of the Structure
213         * @see #setName
214         */
215        public String getName();
216        /**
217         * Get an identifier corresponding to this structure
218         * @return The StructureIdentifier used to create this structure
219         */
220        public StructureIdentifier getStructureIdentifier();
221        /**
222         * Set the identifier corresponding to this structure
223         * @param structureIdentifier the structureIdentifier corresponding to this structure
224         */
225        public void setStructureIdentifier(StructureIdentifier structureIdentifier);
226
227        /**
228           sets/gets an List of  Maps which corresponds to the CONECT lines in the PDB file:
229
230           <pre>
231           COLUMNS         DATA TYPE        FIELD           DEFINITION
232           ---------------------------------------------------------------------------------
233                1 -  6         Record name      "CONECT"
234                7 - 11         Integer          serial          Atom serial number
235           12 - 16         Integer          serial          Serial number of bonded atom
236           17 - 21         Integer          serial          Serial number of bonded atom
237           22 - 26         Integer          serial          Serial number of bonded atom
238           27 - 31         Integer          serial          Serial number of bonded atom
239           32 - 36         Integer          serial          Serial number of hydrogen bonded
240           atom
241           37 - 41         Integer          serial          Serial number of hydrogen bonded
242           atom
243           42 - 46         Integer          serial          Serial number of salt bridged
244           atom
245           47 - 51         Integer          serial          Serial number of hydrogen bonded
246           atom
247           52 - 56         Integer          serial          Serial number of hydrogen bonded
248           atom
249           57 - 61         Integer          serial          Serial number of salt bridged
250           atom
251           </pre>
252
253           the HashMap for a single CONECT line contains the following fields:
254
255           <li> atomserial (mandatory) : Atom serial number</li>
256           <li> bond1 .. bond4 (optional): Serial number of bonded atom</li>
257           <li> hydrogen1 .. hydrogen4 (optional):Serial number of hydrogen bonded atom</li>
258           <li> salt1 .. salt2 (optional): Serial number of salt bridged atom</li>
259
260           *
261           * @param connections  a List object specifying the connections
262           * @see #getConnections
263           * @deprecated use {@link Atom#addBond(Bond)} instead
264        */
265        @Deprecated
266        public void setConnections(List<Map<String,Integer>> connections);
267
268        /**
269         * Return the connections value.
270         * @return a List object representing the connections value
271         * @see #setConnections
272         * @deprecated use {@link Atom#getBonds()} instead
273         */
274        @Deprecated
275        public List<Map<String,Integer>> getConnections();
276
277        /**
278         * Return number of Chains in this Structure.
279         * @return an int representing the number of Chains in this Structure
280         */
281        public int size() ;
282
283        /**
284         * Return number of chains of model.
285         *
286         * @param modelnr  an int specifying the number of the Model that should be used
287         * @return an int representing the number of Chains in this Model
288         */
289        public int size(int modelnr);
290
291        /**
292         * Return the number of models .
293         * In this implementation also XRAY structures have "1 model", since
294         * model is the container for the chains.
295         * to test if a Structure is an NMR structure use {@link #isNmr()}.
296         *
297         * @return an int representing the number of models in this Structure
298         * @see #isNmr()
299         */
300        public int nrModels() ;
301
302        /**
303         * Test if this structure is an NMR structure.
304         *
305         * @return true if this Structure has been solved by NMR
306         * @see #nrModels()
307         */
308        public boolean isNmr() ;
309
310        /**
311         * Test if this structure is a crystallographic structure, i.e. it is an asymmetric unit
312         * from which it is possible to reconstruct the crystal lattice given cell parameters and
313         * space group.
314         *
315         * @return true if crystallographic, false otherwise
316         */
317        public boolean isCrystallographic();
318
319        /** set NMR flag.
320         *
321         * @param nmr  true to declare that this Structure has been solved by NMR.
322         */
323        @Deprecated
324        public void setNmr(boolean nmr);
325
326
327        /**
328         * Add a new model.
329         *
330         * @param model  a List object containing the Chains of the new Model
331         */
332        public void addModel(List<Chain> model);
333
334
335        /**
336         * A convenience function if one wants to edit and replace the
337         * models in a structure. Allows to set (replace) the model at position
338         * with the new List of Chains.
339         * @param position starting at 0
340         * @param model
341         */
342        public void setModel(int position, List<Chain> model);
343
344        /**
345         * Retrieve all Chains belonging to a model .
346         * @see #getChains(int modelnr)
347         *
348         * @param modelnr  an int
349         * @return a List object containing the Chains of Model nr. modelnr
350
351         */
352        public List<Chain> getModel(int modelnr);
353
354        /**
355         * Retrieve all chains - if it is a NMR structure will return the chains of the first model.
356         * This is the same as getChains(0);
357         * @see #getModel(int modelnr)
358         * @see #getChains(int modelnr)
359         *
360         * @return a List object containing the Chains of Model nr. modelnr
361         */
362        public List<Chain> getChains();
363
364
365        /**
366         * Set the chains of a structure, if this is a NMR structure,
367         * this will only set model 0.
368         *
369         * @see #setChains(int, List)
370         *
371         * @param chains the list of chains for this structure.
372         */
373        public void setChains(List<Chain> chains);
374
375        /**
376         * Retrieve all chains of a model.
377         * @see #getModel
378         *
379         * @param modelnr  an int
380         * @return a List object containing the Chains of Model nr. modelnr
381         */
382        public List<Chain> getChains(int modelnr);
383
384        /**
385         * Set the chains for a model
386         * @param chains
387         * @param modelnr
388         */
389        public void setChains( int modelnr, List<Chain> chains);
390
391        /**
392         * Add a new chain.
393         *
394         * @param chain  a Chain object
395         */
396        public void addChain(Chain chain);
397
398        /**
399         * Add a new chain, if several models are available.
400         *
401         * @param chain    a Chain object
402         * @param modelnr  an int specifying to which model the Chain should be added
403         */
404        public void addChain(Chain chain, int modelnr);
405
406        /**
407         * Retrieve a chain by its position within the Structure .
408         *
409         * @param pos  an int for the position in the List of Chains.
410         * @return a Chain object
411        */
412        public Chain getChain(int pos);
413
414        /**
415         * Retrieve a chain by its position within the Structure and model number.
416         *
417         * @param pos      an int
418         * @param modelnr  an int
419         * @return a Chain object
420        */
421        public Chain getChain( int modelnr, int pos);
422
423
424
425        /**
426         * Request a particular chain from a structure.
427         * by default considers only the first model.
428         * @param chainId the ID of a chain that should be returned
429         * @return Chain the requested chain
430         * @throws StructureException
431         */
432        public Chain findChain(String chainId)
433        throws StructureException;
434
435
436        /**
437         * Check if a chain with the id chainId is contained in this structure.
438         *
439         * @param chainId the name of the chain
440         * @return true if a chain with the id (name) chainId is found
441         */
442        public boolean hasChain(String chainId);
443
444        /**
445         * Request a particular chain from a particular model
446         * @param modelnr the number of the model to use
447         * @param chainId the ID of a chain that should be returned
448         * @return Chain the requested chain
449         * @throws StructureException
450         */
451        public Chain findChain(String chainId, int modelnr)
452        throws StructureException;
453
454        /**
455         * Request a particular group from a structure.
456         * by default considers only the first model in the structure.
457         * @param chainId the ID of the chain to use
458         * @param pdbResnum the PDB residue number of the requested group
459         * @return Group the requested Group
460         * @throws StructureException
461         */
462        public  Group findGroup(String chainId, String pdbResnum)
463                        throws StructureException;
464
465        /**
466         * Request a particular group from a structure.
467         * considers only model nr X. count starts with 0.
468         * @param chainId the ID of the chain to use
469         * @param pdbResnum the PDB residue number of the requested group
470         * @param modelnr the number of the model to use
471         * @return Group the requested Group
472         * @throws StructureException
473         */
474         public  Group findGroup(String chainId, String pdbResnum, int modelnr)
475         throws StructureException;
476
477
478         /**
479          * Request a chain by its PDB code
480          * by default takes only the first model
481          *
482          * @param chainId the chain identifier
483          * @return the Chain that matches the chainID
484          * @throws StructureException
485          */
486         public Chain getChainByPDB(String chainId)
487                 throws StructureException;
488
489         /**
490          * Request a chain by its PDB code
491          * by default takes only the first model
492          *
493          * @param chainId the chain identifier
494          * @param modelnr request a particular model;
495          * @return the Chain that matches the chainID in the model
496          * @throws StructureException
497          */
498         public Chain getChainByPDB(String chainId, int modelnr)
499                 throws StructureException;
500
501
502        /**
503         * Create a String that contains this Structure's contents in PDB file format.
504         *
505         * @return a String that looks like a PDB file
506         * @see FileConvert
507         */
508        public String toPDB();
509
510        /**
511         * Create a String that contains this Structure's contents in MMCIF file format.
512         * @return
513         */
514        public String toMMCIF();
515
516        /**
517         * Set the Compounds
518         *
519         * @param molList
520         */
521        public void setCompounds(List<Compound> molList);
522
523        /**
524         * Get all the Compounds for this Structure.
525         * Compounds are called Entities in mmCIF dictionary.
526         *
527         * @return a list of Compounds
528         */
529        public List<Compound> getCompounds();
530
531        /**
532         * Add a Compound to this Structure
533         */
534        public void addCompound(Compound compound);
535
536        /**
537         * Set the list of database references for this structure
538         * @param dbrefs list of DBRef objects
539         *
540         */
541        public void setDBRefs(List<DBRef> dbrefs);
542
543        /**
544         * Get the list of database references
545         *
546         * @return list of DBRef objects
547         */
548        public List<DBRef> getDBRefs();
549
550        /**
551         * Request a particular compound by its molId (entity_id in mmCIF dictionary)
552         *
553         * @param molId
554         * @return a compound
555         */
556        public Compound getCompoundById(int molId);
557
558
559        /**
560         * Return the header information for this PDB file
561         *
562         * @return the PDBHeader object
563         */
564        public PDBHeader getPDBHeader();
565
566        /**
567         * Return whether or not the entry has an associated journal article
568         * or publication. The JRNL section is not mandatory and thus may not be
569         * present.
570         * @return flag if a JournalArticle has been found.
571         */
572        public boolean hasJournalArticle();
573
574        /**
575         * Get the associated publication as defined by the JRNL records in a PDB
576         * file.
577         * @return a JournalArticle
578         */
579        public JournalArticle getJournalArticle();
580
581        /**
582         * Set the associated publication as defined by the JRNL records in a PDB
583         * file.
584         * @param journalArticle
585         */
586        public void setJournalArticle(JournalArticle journalArticle);
587
588        /**
589         * Get the list of disulfide Bonds as they have been defined in the PDB files
590         *
591         * @return a list of Bonds
592         */
593        public List<Bond> getSSBonds();
594
595        /**
596         * Set the list of SSBonds for this structure
597         *
598         * @param ssbonds
599         */
600        public void setSSBonds(List<Bond> ssbonds);
601
602        /**
603         * Add a single disulfide Bond to this structure
604         *
605         * @param ssbond
606         */
607        public void addSSBond(Bond ssbond);
608
609        /**
610         * Set the the header information for this PDB file
611         *
612         * @param header the PDBHeader object
613         */
614        public void setPDBHeader(PDBHeader header);
615
616        /**
617         * Get the ID used by Hibernate
618         *
619         * @return the ID used by Hibernate
620         */
621        public Long getId() ;
622
623        /** set the ID used by Hibernate
624         *
625         * @param id
626         */
627        public void setId(Long id) ;
628
629        /**
630         * @param sites the sites to set in the structure
631         */
632        public void setSites(List<Site> sites);
633
634        /**
635         * @return the sites contained in this structure
636         */
637        public List<Site> getSites();
638
639        public List<Group> getHetGroups();
640
641        /**
642         * Set a flag to indicate if this structure is a biological assembly
643         * @param biologicalAssembly true if biological assembly, otherwise false
644         * @since 3.2
645         */
646        public void setBiologicalAssembly(boolean biologicalAssembly);
647
648        /**
649         * Get flag that indicates if this structure is a biological assembly
650         * @return  true if biological assembly, otherwise false
651         * @since 3.2
652         */
653        public boolean isBiologicalAssembly();
654
655        /**
656         * Set crystallographic information for this structure
657         * @param PDBCrystallographicInfo crystallographic information
658         * @since 3.2
659         */
660
661        public void setCrystallographicInfo(PDBCrystallographicInfo crystallographicInfo);
662
663        /**
664         * Get crystallographic information for this structure
665         * @return PDBCrystallographicInfo crystallographic information
666         * @since 3.2
667         */
668        public PDBCrystallographicInfo getCrystallographicInfo();
669
670        /**
671         * Resets all models of this Structure
672         * @since 4.0.1
673         */
674        public void resetModels();
675
676        /**
677         * Returns the PDB identifier associated with this StructureIdentifier.
678         * @deprecated From BioJava 4.2, use {@link #getPDBCode()} or
679         *  <code>getStructureIdentifier().toCanonical().getPdbId()</code>
680         */
681        @Deprecated
682        String getPdbId();
683
684        /**
685         * Returns the list of {@link ResidueRange ResidueRanges} that this StructureIdentifier defines.
686         * This is a unique representation.
687         * @deprecated From BioJava 4.2, use
688         *  <code>getStructureIdentifier().toCanonical().getResidueRanges()</code>
689         */
690        @Deprecated
691        List<? extends ResidueRange> getResidueRanges();
692
693        /**
694         * Returns a list of residue ranges. For example:
695         * <pre>
696         * getRanges().get(0): 'A'
697         * getRanges().get(1): 'B_5-100'
698         * </pre>
699         * This is a unique representation.
700         * @deprecated From BioJava 4.2, use
701         *  <code>getStructureIdentifier().toCanonical().getRanges()</code>
702         */
703        @Deprecated
704        List<String> getRanges();
705
706        /**
707         * Get a string representing this structure's contents. The following places
708         * are searched for a non-null value, with the first being returned:
709         * <ol>
710         * <li>{@link #getStructureIdentifier()}.getIdentifier(), which should give
711         *     the string originally used to create the structure
712         * <li>{@link #getName()}
713         * <li>A combination of {@link #getPDBCode()} with a heuristic description
714         *     of the residue ranges, in {@link SubstructureIdentifier} format.
715         * </ol>
716         * @return A {@link SubstructureIdentifier}-format string describing the residue ranges in this structure
717         * @since The behavior of this method changed in BioJava 4.2. Previously it
718         *  returned the same value as {@link #getPDBCode()}
719         */
720        String getIdentifier();
721}