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