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 22.01.2007
021 *
022 */
023package org.biojava.nbio.structure;
024
025
026import org.biojava.nbio.structure.io.FileParsingParameters;
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029
030import java.io.Serializable;
031import java.util.*;
032
033/**
034 * An object to contain the info from the PDB header for a Molecule.
035 * In mmCIF dictionary, it is called an Entity. In the case of polymers it
036 * is defined as each group of sequence identical NCS-related chains
037 *
038 * Now PDB file format 3.2 aware - contains the new TAX_ID fields for the
039 * organism studied and the expression system.
040 *
041 * @author Jules Jacobsen
042 * @author Jose Duarte
043 * @author Anthony Bradley
044 * @since 1.5
045 */
046public class EntityInfo implements Serializable {
047
048        private final static Logger logger = LoggerFactory.getLogger(EntityInfo.class);
049
050
051        // TODO We could drop a lot of the stuff here that is PDB-file related (actually many PDB files don't contain many of these fields) - JD 2016-03-25
052        //     The only really essential part of a EntityInfo is the member chains and the entity_id/mol_id
053        // See also issue https://github.com/biojava/biojava/issues/219
054
055        private static final long serialVersionUID = 2991897825657586356L;
056
057        /**
058         * The list of chains that are described by this EntityInfo
059         */
060        private List<Chain> chains;
061
062        /**
063         * The Molecule identifier, called entity_id in mmCIF dictionary
064         */
065        private int molId;
066
067        /**
068         * A map to cache residue number mapping, between ResidueNumbers and index (1-based) in aligned sequences (SEQRES).
069         * Initialised lazily upon call to {@link #getAlignedResIndex(Group, Chain)}
070         * Keys are asym_ids of chains, values maps of residue numbers to indices.
071         */
072        private Map<String, Map<ResidueNumber,Integer>> chains2pdbResNums2ResSerials;
073
074        private String refChainId;
075        private String description = null;
076        private String title = null;
077        /**
078         * The type of entity (polymer, non-polymer, water)
079         */
080        private EntityType type = null;
081        private List<String> synonyms = null;
082        private List<String> ecNums = null;
083        private String engineered = null;
084        private String mutation = null;
085        private String biologicalUnit = null;
086        private String details = null;
087        private String numRes = null;
088        private String resNames = null;
089        private String headerVars = null;
090        private String synthetic = null;
091        private String fragment = null;
092        private String organismScientific = null;
093        private String organismTaxId = null;
094        private String organismCommon = null;
095        private String strain = null;
096        private String variant = null;
097        private String cellLine = null;
098        private String atcc = null;
099        private String organ = null;
100        private String tissue = null;
101        private String cell = null;
102        private String organelle = null;
103        private String secretion = null;
104        private String gene = null;
105        private String cellularLocation = null;
106        private String expressionSystem = null;
107        private String expressionSystemTaxId = null;
108        private String expressionSystemStrain = null;
109        private String expressionSystemVariant = null;
110        private String expressionSystemCellLine = null;
111        private String expressionSystemAtccNumber = null;
112        private String expressionSystemOrgan = null;
113        private String expressionSystemTissue = null;
114        private String expressionSystemCell = null;
115        private String expressionSystemOrganelle = null;
116        private String expressionSystemCellularLocation = null;
117        private String expressionSystemVectorType = null;
118        private String expressionSystemVector = null;
119        private String expressionSystemPlasmid = null;
120        private String expressionSystemGene = null;
121        private String expressionSystemOtherDetails = null;
122
123        private Long id;
124
125        public EntityInfo () {
126                chains = new ArrayList<Chain>();
127                chains2pdbResNums2ResSerials = new HashMap<String, Map<ResidueNumber,Integer>>();
128                molId = -1;
129        }
130
131        /**
132         * Constructs a new EntityInfo copying all data from the given one
133         * but not setting the Chains
134         * @param c
135         */
136        public EntityInfo (EntityInfo c) {
137
138                this.chains = new ArrayList<Chain>();
139
140                this.chains2pdbResNums2ResSerials = new HashMap<String, Map<ResidueNumber,Integer>>();
141
142                this.molId = c.molId;
143
144                this.type = c.type;
145
146                this.refChainId = c.refChainId;
147
148                this.description = c.description;
149                this.title = c.title;
150
151                if (c.synonyms!=null) {
152                        this.synonyms = new ArrayList<String>();
153                        synonyms.addAll(c.synonyms);
154                }
155                if (c.ecNums!=null) {
156                        this.ecNums = new ArrayList<String>();
157                        ecNums.addAll(c.ecNums);
158                }
159
160                this.engineered = c.engineered;
161                this.mutation = c.mutation;
162                this.biologicalUnit = c.biologicalUnit;
163                this.details = c.details;
164
165                this.numRes = c.numRes;
166                this.resNames = c.resNames;
167
168                this.headerVars = c.headerVars;
169
170                this.synthetic = c.synthetic;
171                this.fragment = c.fragment;
172                this.organismScientific = c.organismScientific;
173                this.organismTaxId = c.organismTaxId;
174                this.organismCommon = c.organismCommon;
175                this.strain = c.strain;
176                this.variant = c.variant;
177                this.cellLine = c.cellLine;
178                this.atcc = c.atcc;
179                this.organ = c.organ;
180                this.tissue = c.tissue;
181                this.cell = c.cell;
182                this.organelle = c.organelle;
183                this.secretion = c.secretion;
184                this.gene = c.gene;
185                this.cellularLocation = c.cellularLocation;
186                this.expressionSystem = c.expressionSystem;
187                this.expressionSystemTaxId = c.expressionSystemTaxId;
188                this.expressionSystemStrain = c.expressionSystemStrain;
189                this.expressionSystemVariant = c.expressionSystemVariant;
190                this.expressionSystemCellLine = c.expressionSystemCellLine;
191                this.expressionSystemAtccNumber = c.expressionSystemAtccNumber;
192                this.expressionSystemOrgan = c.expressionSystemOrgan;
193                this.expressionSystemTissue = c.expressionSystemTissue;
194                this.expressionSystemCell = c.expressionSystemCell;
195                this.expressionSystemOrganelle = c.expressionSystemOrganelle;
196                this.expressionSystemCellularLocation = c.expressionSystemCellularLocation;
197                this.expressionSystemVectorType = c.expressionSystemVectorType;
198                this.expressionSystemVector = c.expressionSystemVector;
199                this.expressionSystemPlasmid = c.expressionSystemPlasmid;
200                this.expressionSystemGene = c.expressionSystemGene;
201                this.expressionSystemOtherDetails = c.expressionSystemOtherDetails;
202
203
204        }
205
206        @Override
207        public String toString(){
208                StringBuilder buf = new StringBuilder();
209                buf.append("EntityInfo: ").append(molId).append(" ");
210                buf.append(description==null?"(no name)":"("+description+")");
211                buf.append(" asymIds: ");
212                if (chains!=null) {
213                        for (int i=0;i<chains.size();i++) {
214                                buf.append(chains.get(i).getId());
215                                if (i!=chains.size()-1) buf.append(",");
216                        }
217                } else {
218                        buf.append("no chains");
219                }
220                return buf.toString();
221        }
222
223        /**
224         * Get the representative Chain for this EntityInfo.
225         * We choose the Chain with the first asym_id chain identifier after
226         * lexicographical sorting (case insensitive),
227         * e.g. chain A if EntityInfo is composed of chains A,B,C,D,E
228         * @return
229         */
230        public Chain getRepresentative() {
231
232                List<String> chainIds = new ArrayList<String>();
233                for (Chain chain:chains) {
234                        chainIds.add(chain.getId());
235                }
236
237                Collections.sort(chainIds, String.CASE_INSENSITIVE_ORDER);
238
239                for (Chain chain:chains) {
240                        if (chain.getId().equals(chainIds.get(0))) {
241                                return chain;
242                        }
243                }
244
245                logger.error("Could not find a representative chain for EntityInfo '{}'", this.toString());
246
247                return null;
248        }
249
250        /** get the ID used by Hibernate
251         *
252         * @return the ID used by Hibernate
253         */
254        public Long getId() {
255                return id;
256        }
257
258        /** set the ID used by Hibernate
259         *
260         * @param id
261         */
262        public void setId(Long id) {
263                this.id = id;
264        }
265
266        /**
267         * Return the list of member chain ids (asym ids) that are described by this EntityInfo,
268         * only unique chain IDs are contained in the list.
269         * Note that in the case of multimodel structures this will return just the unique
270         * chain identifiers whilst {@link #getChains()} will return a corresponding chain
271         * per model.
272         * @return the list of unique ChainIDs that are described by this EnityInfo
273         * @see #setChains(List)
274         * @see #getChains()
275         */
276        public List<String> getChainIds() {
277
278                Set<String> uniqChainIds = new TreeSet<String>();
279                for (int i=0;i<getChains().size();i++) {
280                        uniqChainIds.add(getChains().get(i).getId());
281                }
282
283                return new ArrayList<String>(uniqChainIds);
284        }
285
286        /**
287         * Given a Group g of Chain c (member of this EnityInfo) return the corresponding position in the
288         * alignment of all member sequences (1-based numbering), i.e. the index (1-based) in the SEQRES sequence.
289         * This allows for comparisons of residues belonging to different chains of the same EnityInfo (entity).
290         * <p>
291         * If {@link FileParsingParameters#setAlignSeqRes(boolean)} is not used or SEQRES not present, a mapping
292         * will not be available and this method will return {@link ResidueNumber#getSeqNum()} for all residues, which
293         * in some cases will be correctly aligned indices (when no insertion codes are
294         * used and when all chains within the entity are numbered in the same way), but
295         * in general they will be neither unique (because of insertion codes) nor aligned.
296         * </p>
297         * @param g
298         * @param c
299         * @return the aligned residue index (1 to n), if no SEQRES groups are available at all then {@link ResidueNumber#getSeqNum()}
300         * is returned as a fall-back, if the group is not found in the SEQRES groups then -1 is returned
301         * for the given group and chain
302         * @throws IllegalArgumentException if the given Chain is not a member of this EnityInfo
303         * @see {@link Chain#getSeqResGroup(int)}
304         */
305        public int getAlignedResIndex(Group g, Chain c) {
306
307                boolean contained = false;
308                for (Chain member:getChains()) {
309                        if (c.getId().equals(member.getId())) {
310                                contained = true;
311                                break;
312                        }
313                }
314                if (!contained)
315                        throw new IllegalArgumentException("Given chain with asym_id "+c.getId()+" is not a member of this entity: "+getChainIds().toString());
316
317                if (!chains2pdbResNums2ResSerials.containsKey(c.getId())) {
318                        // we do lazy initialisation of the map
319                        initResSerialsMap(c);
320                }
321                // if no seqres groups are available at all the map will be null
322                Map<ResidueNumber,Integer> map = chains2pdbResNums2ResSerials.get(c.getId());
323                int serial;
324                if (map!=null) {
325
326                        ResidueNumber resNum = g.getResidueNumber();
327                        // the resNum will be null for groups that are SEQRES only and not in ATOM,
328                        // still it can happen that a group is in ATOM in one chain but not in other of the same entity.
329                        // This is what we try to find out here (analogously to what we do in initResSerialsMap() ):
330                        if (resNum==null && c.getSeqResGroups()!=null && !c.getSeqResGroups().isEmpty()) {
331
332                                int index = c.getSeqResGroups().indexOf(g);
333
334                                resNum = findResNumInOtherChains(index, c);
335
336                        }
337
338                        if (resNum == null) {
339                                // still null, we really can't map
340                                serial = -1;
341                        }
342                        else {
343
344                                Integer alignedSerial = map.get(resNum);
345
346                                if (alignedSerial==null) {
347                                        // the map doesn't contain this group, something's wrong: return -1
348                                        serial = -1;
349                                } else {
350                                        serial = alignedSerial;
351                                }
352                        }
353
354                } else {
355                        // no seqres groups available we resort to using the pdb residue numbers are given
356                        serial = g.getResidueNumber().getSeqNum();
357                }
358                return serial;
359        }
360
361        private void initResSerialsMap(Chain c) {
362                if (c.getSeqResGroups()==null || c.getSeqResGroups().isEmpty()) {
363                        logger.warn("No SEQRES groups found in chain with asym_id {}, will use residue numbers as given (no insertion codes, not necessarily aligned). "
364                                        + "Make sure your structure has SEQRES records and that you use FileParsingParameters.setAlignSeqRes(true)",
365                                        c.getId());
366                        // we add a explicit null to the map so that we flag it as unavailable for this chain
367                        chains2pdbResNums2ResSerials.put(c.getId(), null);
368                        return;
369                }
370
371                Map<ResidueNumber,Integer> resNums2ResSerials = new HashMap<ResidueNumber, Integer>();
372                chains2pdbResNums2ResSerials.put(c.getId(), resNums2ResSerials);
373
374                for (int i=0;i<c.getSeqResGroups().size();i++) {
375
376                        // The seqres group will have a null residue number whenever its corresponding atom group doesn't exist
377                        // because it is missing in the electron density.
378                        // However, it can be observed in the density in other chains of the same entity,
379                        // to be complete we go and look for the residue number in other chains, so that we have a
380                        // seqres to atom mapping as complete as possible (with all known atom groups of any chain of this entity)
381
382                        ResidueNumber resNum = c.getSeqResGroup(i).getResidueNumber();
383
384                        if (resNum==null) {
385                                resNum = findResNumInOtherChains(i,c);
386                        }
387
388                        // NOTE that resNum will still be null here for cases where the residue
389                        // is missing in atom groups (not observed in density) in all chains
390                        // Thus the mapping will not be possible for residues that are only in SEQRES groups
391                        resNums2ResSerials.put(resNum, i+1);
392                }
393        }
394
395        private ResidueNumber findResNumInOtherChains(int i, Chain chain) {
396
397                // note that getChains contains all chains from all models, we'll just use first model found and skip the others
398                for (Chain c: getFirstModelChains()) {
399
400                        if (c == chain) continue;
401
402                        Group seqResGroup = c.getSeqResGroup(i);
403
404                        if (seqResGroup==null) {
405                                logger.warn("The SEQRES group is null for index {} in chain with asym_id {}, whilst it wasn't null in chain with asym_id {}",
406                                                 i, c.getId(), chain.getId());
407                                continue;
408                        }
409
410                        if (seqResGroup.getResidueNumber()!=null) return seqResGroup.getResidueNumber();
411
412                }
413
414                return null;
415        }
416
417        /**
418         * Return the ref chain id value.
419         * @return the RefChainID
420         * @see #setRefChainId(String)
421         */
422        public String getRefChainId() {
423                return refChainId;
424        }
425
426        /**
427         * Return the ref chain id value.
428         * @param refChainId the RefChainID
429         * @see #getRefChainId()
430         */
431        public void setRefChainId(String refChainId) {
432                this.refChainId = refChainId;
433        }
434
435        /**
436         * Return the molecule identifier, called entity_id in mmCIF dictionary.
437         * @return the molecule id
438         * @see #setMolId(int)
439         */
440        public int getMolId() {
441                return molId;
442        }
443
444        /**
445         * Set the molecule identifier, called entity_id in mmCIF dictionary.
446         * @param molId the molecule id
447         * @see #getMolId()
448         */
449        public void setMolId(int molId) {
450                this.molId = molId;
451        }
452
453        public String getDescription() {
454                return description;
455        }
456
457        public void setDescription(String molName) {
458                this.description = molName;
459        }
460
461        public String getTitle() {
462                return title;
463        }
464
465        public void setTitle(String title) {
466                this.title = title;
467        }
468
469        public List<String> getSynonyms() {
470                return synonyms;
471        }
472
473        public void setSynonyms(List<String> synonyms) {
474                this.synonyms = synonyms;
475        }
476
477        public List<String> getEcNums() {
478                return ecNums;
479        }
480
481        public void setEcNums(List<String> ecNums) {
482                this.ecNums = ecNums;
483        }
484
485        public String getEngineered() {
486                return engineered;
487        }
488
489        public void setEngineered(String engineered) {
490                this.engineered = engineered;
491        }
492
493        public String getMutation() {
494                return mutation;
495        }
496
497        public void setMutation(String mutation) {
498                this.mutation = mutation;
499        }
500
501        public String getBiologicalUnit() {
502                return biologicalUnit;
503        }
504
505        public void setBiologicalUnit(String biologicalUnit) {
506                this.biologicalUnit = biologicalUnit;
507        }
508
509        public String getDetails() {
510                return details;
511        }
512
513        public void setDetails(String details) {
514                this.details = details;
515        }
516
517        public String getNumRes() {
518                return numRes;
519        }
520
521        public void setNumRes(String numRes) {
522                this.numRes = numRes;
523        }
524
525        public String getResNames() {
526                return resNames;
527        }
528
529        public void setResNames(String resNames) {
530                this.resNames = resNames;
531        }
532
533        public String getHeaderVars() {
534                return headerVars;
535        }
536
537        public void setHeaderVars(String headerVars) {
538                this.headerVars = headerVars;
539        }
540
541        public String getSynthetic() {
542                return synthetic;
543        }
544
545        public void setSynthetic(String synthetic) {
546                this.synthetic = synthetic;
547        }
548
549        public String getFragment() {
550                return fragment;
551        }
552
553        public void setFragment(String fragment) {
554                this.fragment = fragment;
555        }
556
557        public String getOrganismScientific() {
558                return organismScientific;
559        }
560
561        public void setOrganismScientific(String organismScientific) {
562                this.organismScientific = organismScientific;
563        }
564
565        public String getOrganismTaxId() {
566                return organismTaxId;
567        }
568
569        public void setOrganismTaxId(String organismTaxId) {
570                this.organismTaxId = organismTaxId;
571        }
572
573        public String getOrganismCommon() {
574                return organismCommon;
575        }
576
577        public void setOrganismCommon(String organismCommon) {
578                this.organismCommon = organismCommon;
579        }
580
581        public String getStrain() {
582                return strain;
583        }
584
585        public void setStrain(String strain) {
586                this.strain = strain;
587        }
588
589        public String getVariant() {
590                return variant;
591        }
592
593        public void setVariant(String variant) {
594                this.variant = variant;
595        }
596
597        public String getCellLine() {
598                return cellLine;
599        }
600
601        public void setCellLine(String cellLine) {
602                this.cellLine = cellLine;
603        }
604
605        public String getAtcc() {
606                return atcc;
607        }
608
609        public void setAtcc(String atcc) {
610                this.atcc = atcc;
611        }
612
613        public String getOrgan() {
614                return organ;
615        }
616
617        public void setOrgan(String organ) {
618                this.organ = organ;
619        }
620
621        public String getTissue() {
622                return tissue;
623        }
624
625        public void setTissue(String tissue) {
626                this.tissue = tissue;
627        }
628
629        public String getCell() {
630                return cell;
631        }
632
633        public void setCell(String cell) {
634                this.cell = cell;
635        }
636
637        public String getOrganelle() {
638                return organelle;
639        }
640
641        public void setOrganelle(String organelle) {
642                this.organelle = organelle;
643        }
644
645        public String getSecretion() {
646                return secretion;
647        }
648
649        public void setSecretion(String secretion) {
650                this.secretion = secretion;
651        }
652
653        public String getGene() {
654                return gene;
655        }
656
657        public void setGene(String gene) {
658                this.gene = gene;
659        }
660
661        public String getCellularLocation() {
662                return cellularLocation;
663        }
664
665        public void setCellularLocation(String cellularLocation) {
666                this.cellularLocation = cellularLocation;
667        }
668
669        public String getExpressionSystem() {
670                return expressionSystem;
671        }
672
673        public String getExpressionSystemTaxId() {
674                return expressionSystemTaxId;
675        }
676
677        public void setExpressionSystemTaxId(String expressionSystemTaxId) {
678                this.expressionSystemTaxId = expressionSystemTaxId;
679        }
680
681        public void setExpressionSystem(String expressionSystem) {
682                this.expressionSystem = expressionSystem;
683        }
684
685        public String getExpressionSystemStrain() {
686                return expressionSystemStrain;
687        }
688
689        public void setExpressionSystemStrain(String expressionSystemStrain) {
690                this.expressionSystemStrain = expressionSystemStrain;
691        }
692
693        public String getExpressionSystemVariant() {
694                return expressionSystemVariant;
695        }
696
697        public void setExpressionSystemVariant(String expressionSystemVariant) {
698                this.expressionSystemVariant = expressionSystemVariant;
699        }
700
701        public String getExpressionSystemCellLine() {
702                return expressionSystemCellLine;
703        }
704
705        public void setExpressionSystemCellLine(String expressionSystemCellLine) {
706                this.expressionSystemCellLine = expressionSystemCellLine;
707        }
708
709        public String getExpressionSystemAtccNumber() {
710                return expressionSystemAtccNumber;
711        }
712
713        public void setExpressionSystemAtccNumber(String expressionSystemAtccNumber) {
714                this.expressionSystemAtccNumber = expressionSystemAtccNumber;
715        }
716
717        public String getExpressionSystemOrgan() {
718                return expressionSystemOrgan;
719        }
720
721        public void setExpressionSystemOrgan(String expressionSystemOrgan) {
722                this.expressionSystemOrgan = expressionSystemOrgan;
723        }
724
725        public String getExpressionSystemTissue() {
726                return expressionSystemTissue;
727        }
728
729        public void setExpressionSystemTissue(String expressionSystemTissue) {
730                this.expressionSystemTissue = expressionSystemTissue;
731        }
732
733        public String getExpressionSystemCell() {
734                return expressionSystemCell;
735        }
736
737        public void setExpressionSystemCell(String expressionSystemCell) {
738                this.expressionSystemCell = expressionSystemCell;
739        }
740
741        public String getExpressionSystemOrganelle() {
742                return expressionSystemOrganelle;
743        }
744
745        public void setExpressionSystemOrganelle(String expressionSystemOrganelle) {
746                this.expressionSystemOrganelle = expressionSystemOrganelle;
747        }
748
749        public String getExpressionSystemCellularLocation() {
750                return expressionSystemCellularLocation;
751        }
752
753        public void setExpressionSystemCellularLocation(String expressionSystemCellularLocation) {
754                this.expressionSystemCellularLocation = expressionSystemCellularLocation;
755        }
756
757        public String getExpressionSystemVectorType() {
758                return expressionSystemVectorType;
759        }
760
761        public void setExpressionSystemVectorType(String expressionSystemVectorType) {
762                this.expressionSystemVectorType = expressionSystemVectorType;
763        }
764
765        public String getExpressionSystemVector() {
766                return expressionSystemVector;
767        }
768
769        public void setExpressionSystemVector(String expressionSystemVector) {
770                this.expressionSystemVector = expressionSystemVector;
771        }
772
773        public String getExpressionSystemPlasmid() {
774                return expressionSystemPlasmid;
775        }
776
777        public void setExpressionSystemPlasmid(String expressionSystemPlasmid) {
778                this.expressionSystemPlasmid = expressionSystemPlasmid;
779        }
780
781        public String getExpressionSystemGene() {
782                return expressionSystemGene;
783        }
784
785        public void setExpressionSystemGene(String expressionSystemGene) {
786                this.expressionSystemGene = expressionSystemGene;
787        }
788
789        public String getExpressionSystemOtherDetails() {
790                return expressionSystemOtherDetails;
791        }
792
793        public void setExpressionSystemOtherDetails(String expressionSystemOtherDetails) {
794                this.expressionSystemOtherDetails = expressionSystemOtherDetails;
795        }
796
797        /**
798         * Get the list of chains that are part of this EntityInfo. Note that for multi-model
799         * structures chains from all models are returned.
800         *
801         * @return a List of Chain objects
802         */
803        public List<Chain> getChains(){
804                return this.chains;
805        }
806
807        private List<Chain> getFirstModelChains() {
808
809                Map<String, Chain> firstModelChains = new LinkedHashMap<>();
810                Set<String> lookupChainIds = new HashSet<>(getChainIds());
811
812                for (Chain chain : chains) {
813                        if (lookupChainIds.contains(chain.getId())) {
814                                if (!firstModelChains.containsKey(chain.getId())) {
815                                        firstModelChains.put(chain.getId(), chain);
816                                }
817                        }
818                }
819
820                return new ArrayList<>(firstModelChains.values());
821        }
822
823         /**
824          * Add new Chain to this EntityInfo
825          * @param chain
826          */
827        public void addChain(Chain chain){
828                this.chains.add(chain);
829        }
830
831        /**
832         * Set the chains for this EntityInfo
833         * @param chains
834         */
835        public void setChains(List<Chain> chains){
836                this.chains = chains;
837        }
838
839        /**
840         * Get the type of entity this EntityInfo describes.
841         * Options are polymer, non-polymer or water.
842         * @return a string describing the type of entity. (polymer, non-polymer or water).
843         */
844        public EntityType getType() {
845                return this.type;
846        }
847
848        /**
849         * Set the type of entity this EntityInfo describes.
850         * Options are polymer, non-polymer or water.
851         * @param type a string describing the type of entity. (polymer, non-polymer or water).
852         */
853        public void setType(EntityType type) {
854                this.type = type;
855        }
856}