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.io.Serializable;
030import java.util.List;
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 EntityInfo}</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 *  {@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 *  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, Serializable {
170
171
172        /**
173         * Return an identical copy of this Structure object
174         *
175         * @return identical copy of this Structure object
176         */
177        Structure clone();
178
179        /**
180         * String representation of object.
181         */
182        @Override
183        String toString();
184
185        /**
186         * Set biological name of Structure .
187         *
188         * @param name  a String specifying the biological name of the Structure
189         * @see #getName
190         */
191        void setName(String name);
192
193        /**
194         * Get biological name of Structure.
195         *
196         * @return a String representing the biological name of the Structure
197         * @see #setName
198         */
199        String getName();
200
201        /**
202         * Get an identifier corresponding to this structure
203         * @return The StructureIdentifier used to create this structure
204         */
205        StructureIdentifier getStructureIdentifier();
206
207        /**
208         * Set the identifier corresponding to this structure
209         * @param structureIdentifier the structureIdentifier corresponding to this structure
210         */
211        void setStructureIdentifier(StructureIdentifier structureIdentifier);
212
213        /**
214         * Return number of polymer Chains in this Structure for first model.
215         * @return the number of polymer Chains in this Structure
216         */
217        int size() ;
218
219        /**
220         * Return number of chains of model.
221         *
222         * @param modelnr  an int specifying the number of the Model that should be used
223         * @return an int representing the number of Chains in this Model
224         */
225        int size(int modelnr);
226
227        /**
228         * Return the number of models .
229         * In this implementation also XRAY structures have "1 model", since
230         * model is the container for the chains.
231         * to test if a Structure is an NMR structure use {@link #isNmr()}.
232         *
233         * @return an int representing the number of models in this Structure
234         * @see #isNmr()
235         */
236        int nrModels() ;
237
238        /**
239         * Test if this structure is an NMR structure.
240         *
241         * @return true if this Structure has been solved by NMR
242         * @see #nrModels()
243         */
244        boolean isNmr() ;
245
246        /**
247         * Test if this structure is a crystallographic structure, i.e. it is an asymmetric unit
248         * from which it is possible to reconstruct the crystal lattice given cell parameters and
249         * space group.
250         *
251         * @return true if crystallographic, false otherwise
252         */
253        boolean isCrystallographic();
254
255        /**
256         * Add a new model.
257         *
258         * @param model  a List object containing the Chains of the new Model
259         */
260        void addModel(List<Chain> model);
261
262
263        /**
264         * A convenience function if one wants to edit and replace the
265         * models in a structure. Allows to set (replace) the model at position
266         * with the new List of Chains.
267         * @param position starting at 0
268         * @param model list of chains representing a model
269         */
270        void setModel(int position, List<Chain> model);
271
272        /**
273         * Retrieve all Chains belonging to a model .
274         * @see #getChains(int modelnr)
275         *
276         * @param modelnr  an int
277         * @return a List object containing the Chains of Model nr. modelnr
278         */
279        List<Chain> getModel(int modelnr);
280
281        /**
282         * Retrieve all chains for the first model.
283         * This is the same as getChains(0);
284         * @see #getModel(int modelnr)
285         * @see #getChains(int modelnr)
286         *
287         * @return a List object containing the Chains of Model nr. modelnr
288         */
289        List<Chain> getChains();
290
291        /**
292         * Set the chains of a structure, if this is a NMR structure,
293         * this will only set model 0.
294         *
295         * @see #setChains(int, List)
296         *
297         * @param chains the list of chains for this structure.
298         */
299        void setChains(List<Chain> chains);
300
301        /**
302         * Retrieve all chains of a model.
303         * @see #getModel
304         *
305         * @param modelnr  an int
306         * @return a List object containing the Chains of Model nr. modelnr
307         */
308        List<Chain> getChains(int modelnr);
309
310        /**
311         * Set the chains for a model
312         * @param chains the chains for a model
313         * @param modelnr the number of the model
314         */
315        void setChains( int modelnr, List<Chain> chains);
316
317        /**
318         * Return all polymeric chains for the first model
319         *
320         * @return all polymeric chains.
321         * @since 5.0
322         */
323        List<Chain> getPolyChains();
324
325        /**
326         * Return all polymeric chains for the given model index.
327         * @param modelIdx the model index
328         * @return all polymeric chains.
329         * @since 5.0
330         */
331        List<Chain> getPolyChains(int modelIdx);
332
333        /**
334         * Return all non-polymeric chains for the first model
335         *
336         * @return all non-polymeric chains.
337         * @since 5.0
338         */
339        List<Chain> getNonPolyChains();
340
341        /**
342         * Return all non-polymeric chains for the given model index.
343         *
344         * @param modelIdx the model index
345         * @return all non-polymeric chains.
346         * @since 5.0
347         */
348        List<Chain> getNonPolyChains(int modelIdx);
349
350        /**
351         * Return all water chains for the first model
352         * @return
353         * @since 5.0
354         */
355        List<Chain> getWaterChains();
356
357        /**
358         * Return all water chains for the given model index
359         * @param modelIdx
360         * @return
361         * @since 5.0
362         */
363        List<Chain> getWaterChains(int modelIdx);
364
365        /**
366         * Add a new chain to the first model
367         *
368         * @param chain  a Chain object
369         */
370        void addChain(Chain chain);
371
372        /**
373         * Add a new chain to the model specified by the given index
374         *
375         * @param chain    a Chain object
376         * @param modelnr  an int specifying to which model the Chain should be added
377         */
378        void addChain(Chain chain, int modelnr);
379
380        /**
381         * Retrieve a chain by its index within the Structure .
382         *
383         * @param chainIndex the index of the desired chain in the structure
384         * @return a Chain object
385         */
386        Chain getChainByIndex(int chainIndex);
387
388        /**
389         * Retrieve a chain by its indices within the Structure and model.
390         *
391         * @param chainIndex the index of the desired chain in the structure
392         * @param modelnr the model the desired chain is in
393         * @return a Chain object
394         */
395        Chain getChainByIndex(int modelnr, int chainIndex);
396
397        /**
398         * Check if a chain with the chainId aymId is contained in this structure.
399         *
400         * @param asymId the Id of the chain
401         * @return true if a chain with the id asymId is found
402         */
403        boolean hasChain(String asymId);
404
405        /**
406         * Check if a non polymeric chain with chainId asymId is contained in the structure.
407         *
408         * @param asymId the id of the chain
409         * @return true if a nonpolymeric chain with the asymId is found
410         * @since 5.0
411         */
412        boolean hasNonPolyChain(String asymId);
413
414
415        /**
416         * Check if a chain  with chain name authId is contained in the structure
417         *
418         * @param authId the chain name
419         * @return true if a chain with the name authId is found
420         */
421        boolean hasPdbChain(String authId) ;
422
423        /**
424         * Request a particular group from a structure.
425         * by default considers only the first model in the structure.
426         * @param authId the name of the chain to use
427         * @param pdbResnum the PDB residue number of the requested group
428         * @return Group the requested Group
429         * @throws StructureException
430         */
431        Group findGroup(String authId, String pdbResnum) throws StructureException;
432
433        /**
434         * Request a particular group from a structure.
435         * considers only model nr X. count starts with 0.
436         * @param authId the chain name of the chain to use
437         * @param pdbResnum the PDB residue number of the requested group
438         * @param modelnr the number of the model to use
439         * @return Group the requested Group
440         * @throws StructureException
441         */
442        Group findGroup(String authId, String pdbResnum, int modelnr) throws StructureException;
443
444        /**
445         * Retrieve a Chain (polymeric, non-polymeric or water) based on
446         * the 'internal' chain id (asymId) for the first model
447         * @param asymId the asymId (chainId)
448         * @return
449         * @see #getPolyChain(String)
450         * @see #getNonPolyChain(String)
451         * @see #getWaterChain(String)
452         */
453        Chain getChain(String asymId);
454
455        /**
456         * Retrieve a Chain (polymeric, non-polymeric or water) based on
457         * the 'internal' chain id (asymId) for the given model index
458         * @param asymId the asymId (chainId)
459         * @param modelIdx the index of the required model (0-based)
460         * @return
461         * @see #getPolyChain(String, int)
462         * @see #getNonPolyChain(String, int)
463         * @see #getWaterChain(String, int)
464         */
465        Chain getChain(String asymId, int modelIdx);
466
467        /**
468         * Retrieve a polymeric Chain based on the 'internal' chain
469         * id (asymId) for the first model
470         *
471         * <p>See {@link #getPolyChainByPDB(String)} for a similar
472         * method using the chain name (authId).
473         * @param asymId the asymId (chainId)
474         * @return a polymeric Chain or null if it can't be found
475         * @since 5.0
476         */
477        Chain getPolyChain(String asymId);
478
479        /**
480         * Retrieve a polymeric Chain based on the 'internal' chain
481         * id (asymId) for the given model index
482         *
483         * <p>See {@link #getPolyChainByPDB(String, int)} for a similar
484         * method using the chain name (authId).
485         * @param asymId the asymId (chainId)
486         * @param modelIdx the index of the required model (0-based)
487         * @return a polymeric Chain or null if it can't be found
488         * @since 5.0
489         */
490        Chain getPolyChain(String asymId, int modelIdx);
491
492        /**
493         * Retrieve a polymeric Chain based on the 'public' chain
494         * name (authId) for the first model
495         *
496         * <p>See {@link #getPolyChain(String)} for a similar
497         * method using the chain id (asymId).
498         * @param authId the author id (chainName, public chain id)
499         * @return a polymeric Chain or null if it can't be found
500         * @since 5.0
501         */
502        Chain getPolyChainByPDB(String authId);
503
504        /**
505         * Retrieve a polymeric Chain based on the 'public' chain
506         * name (authId) for the given model index.
507         *
508         * <p>See {@link #getPolyChain(String, int)} for a similar
509         * method using the chain id (asymId).
510         * @param authId the author id (chainName, public chain id)
511         * @param modelIdx the index of the required model (0-based)
512         * @return a polymeric Chain or null if it can't be found
513         * @since 5.0
514         *
515         */
516        Chain getPolyChainByPDB(String authId, int modelIdx);
517
518
519        /**
520         * Retrieve a non-polymeric Chain based on the 'internal' chain
521         * id (asymId) for the first model
522         * @param asymId the asymId (chainId)
523         * @return a non-polymeric chain or null if it can't be found
524         * @since 5.0
525         */
526        Chain getNonPolyChain(String asymId);
527
528        /**
529         * Retrieve a non-polymeric Chain based on the 'internal' chain
530         * id (asymId) for the given model index
531         * @param asymId the asymId (chainId)
532         * @param modelIdx the index of the required model (0-based)
533         * @return a non-polymeric Chain or null if it can't be found
534         * @since 5.0
535         */
536        Chain getNonPolyChain(String asymId, int modelIdx);
537
538        /**
539         * Retrieve all non-polymeric Chains corresponding to the given 'public' chain
540         * name (authId) for the first model.
541         * @param authId the author id (chainName, public chain id)
542         * @return a list of non-polymeric Chains, if none found the list will be empty
543         * @since 5.0
544         */
545        List<Chain> getNonPolyChainsByPDB(String authId);
546
547        /**
548         * Retrieve all non-polymeric Chains corresponding to the 'public' chain
549         * name (authId) and the given model index.
550         * @param authId the author id (chainName, public chain id)
551         * @param modelIdx the index of the required model (0-based)
552         * @return a list of non-polymeric Chains, if none found the list will be empty
553         * @since 5.0
554         */
555        List<Chain> getNonPolyChainsByPDB(String authId, int modelIdx);
556
557        /**
558         * Retrieve a water Chain based on the 'internal' chain id (asymId)
559         * for the first model
560         * @param asymId the asymId (chainId)
561         * @return a water Chain or null if it can't be found
562         * @since 5.0
563         */
564        Chain getWaterChain(String asymId);
565
566        /**
567         * Retrieve a water chain based on the 'internal' chain id (asymId)
568         * for the given model index
569         * @param asymId the asymId (chainId)
570         * @param modelIdx the index of the required model (0-based)
571         * @return
572         * @since 5.0
573         */
574        Chain getWaterChain(String asymId, int modelIdx);
575
576        /**
577         * Retrieve a water Chain based on the 'public' chain name (authId)
578         * for the first model
579         * @param authId the author id (chainName, public chain id)
580         * @return
581         * @since 5.0
582         */
583        Chain getWaterChainByPDB(String authId);
584
585        /**
586         * Retrieve a water Chain based on the 'public' chain name (authId)
587         * for the given model index
588         * @param authId the author id (chainName, public chain id)
589         * @param modelIdx the index of the required model (0-based)
590         * @return
591         * @since 5.0
592         */
593        Chain getWaterChainByPDB(String authId, int modelIdx);
594
595
596        /**
597         * Create a String that contains this Structure's contents in PDB file format.
598         *
599         * @return a String that looks like a PDB file
600         * @see FileConvert
601         */
602        String toPDB();
603
604        /**
605         * Create a String that contains this Structure's contents in MMCIF file format.
606         * @return a String representation of the Structure object in mmCIF.
607         */
608        String toMMCIF();
609
610        /**
611         * Set the EntityInfo
612         *
613         * @param molList list of entityinfo objects
614         */
615        void setEntityInfos(List<EntityInfo> molList);
616
617        /**
618         * Get all the EntityInfo for this Structure.
619         *
620         * @return a list of EntityInfos
621         */
622        List<EntityInfo> getEntityInfos();
623
624        /**
625         * Add an EntityInfo to this Structure
626         */
627        void addEntityInfo(EntityInfo entityInfo);
628
629        /**
630         * Set the list of database references for this structure
631         * @param dbrefs list of DBRef objects
632         *
633         */
634        void setDBRefs(List<DBRef> dbrefs);
635
636        /**
637         * Get the list of database references
638         *
639         * @return list of DBRef objects
640         */
641        List<DBRef> getDBRefs();
642
643        /**
644         * Request a particular entity by its entity id (mol id in legacy PDB format)
645         *
646         * @param entityId the number of the entity
647         * @return an entity, or null if the molId was not found
648         */
649        EntityInfo getEntityById(int entityId);
650
651        /**
652         * Return the header information for this PDB file.
653         * <b>N.B.</b> Take care when you blindly use the returned object from this method,
654         * because it might be null in some cases.
655         *
656         * @return the PDBHeader object
657         */
658        PDBHeader getPDBHeader();
659
660        /**
661         * Return whether or not the entry has an associated journal article
662         * or ation. The JRNL section is not mandatory and thus may not be
663         * present.
664         * @return flag if a JournalArticle has been found.
665         */
666        boolean hasJournalArticle();
667
668        /**
669         * Get the associated publication as defined by the JRNL records in a PDB
670         * file.
671         * @return a JournalArticle
672         */
673        JournalArticle getJournalArticle();
674
675        /**
676         * Set the associated publication as defined by the JRNL records in a PDB
677         * file.
678         * @param journalArticle a JournalArticle object
679         */
680        void setJournalArticle(JournalArticle journalArticle);
681
682        /**
683         * Get the list of disulfide Bonds as they have been defined in the PDB files
684         *
685         * @return a list of Bonds
686         */
687        List<Bond> getSSBonds();
688
689        /**
690         * Set the list of SSBonds for this structure
691         *
692         * @param ssbonds
693         */
694        void setSSBonds(List<Bond> ssbonds);
695
696        /**
697         * Add a single disulfide Bond to this structure
698         *
699         * @param ssbond a disulfide bond
700         */
701        void addSSBond(Bond ssbond);
702
703        /**
704         * Set the the header information for this PDB file
705         *
706         * @param header the PDBHeader object
707         */
708        void setPDBHeader(PDBHeader header);
709
710        /**
711         * @param sites the sites to set in the structure
712         */
713        void setSites(List<Site> sites);
714
715        /**
716         * @return the sites contained in this structure
717         */
718        List<Site> getSites();
719
720        /**
721         * Set a flag to indicate if this structure is a biological assembly
722         * @param biologicalAssembly true if biological assembly, otherwise false
723         * @since 3.2
724         */
725        void setBiologicalAssembly(boolean biologicalAssembly);
726
727        /**
728         * Get flag that indicates if this structure is a biological assembly
729         * @return  true if biological assembly, otherwise false
730         * @since 3.2
731         */
732        boolean isBiologicalAssembly();
733
734        /**
735         * Set crystallographic information for this structure
736         * @param crystallographicInfo crystallographic information
737         * @since 3.2
738         */
739        void setCrystallographicInfo(PDBCrystallographicInfo crystallographicInfo);
740
741        /**
742         * Get crystallographic information for this structure
743         * @return PDBCrystallographicInfo crystallographic information
744         * @since 3.2
745         */
746        PDBCrystallographicInfo getCrystallographicInfo();
747
748        /**
749         * Resets all models of this Structure
750         * @since 4.0.1
751         */
752        void resetModels();
753
754        /**
755         * Get a string representing this structure's contents. The following places
756         * are searched for a non-null value, with the first being returned:
757         * <ol>
758         * <li>{@link #getStructureIdentifier()}.getIdentifier(), which should give
759         *     the string originally used to create the structure
760         * <li>{@link #getName()}
761         * <li>A combination of {@link #getPDBCode()} with a heuristic description
762         *     of the residue ranges, in {@link SubstructureIdentifier} format.
763         * </ol>
764         * @return A {@link SubstructureIdentifier}-format string describing the residue ranges in this structure
765         * @since The behavior of this method changed in BioJava 4.2. Previously it
766         *  returned the same value as {@link #getPDBCode()}
767         */
768        String getIdentifier();
769
770        /**
771         * Get PDB code of structure.
772         *
773         * @return a String representing the PDBCode value
774         * @see #setPDBCode
775         * @deprecated use {@link #getPdbId()} to get a {@link PdbId} object or getPdbId().getId() to get a {@link String}
776         */
777        @Deprecated
778        String getPDBCode () ;
779
780        /**
781         * Set PDB code of structure .
782         *
783         * @param pdb_id  a String specifying the PDBCode
784         * @see #getPDBCode
785         * @deprecated use {@link #setPDBCode(PdbId)}
786         */
787        @Deprecated
788        void setPDBCode (String pdb_id);
789
790
791
792        /**
793         * Returns the PDB identifier associated with this StructureIdentifier.
794         * @return the {@link PdbId} object
795         * @since 6.0.0
796         */
797        PdbId getPdbId();
798        
799        
800        /**Sets the {@link PdbId} identifier associated with this structure.
801         * @param pdbId the {@link PdbId} identifier object to set
802         * @since 6.0.0
803         */
804        void setPdbId(PdbId pdbId);
805
806}