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 */
021package org.biojava.nbio.structure.io.mmcif.model;
022
023import org.biojava.nbio.structure.io.mmcif.chem.ChemCompTools;
024import org.biojava.nbio.structure.io.mmcif.chem.PolymerType;
025import org.biojava.nbio.structure.io.mmcif.chem.ResidueType;
026
027import java.io.Serializable;
028import java.util.ArrayList;
029import java.util.List;
030
031/** A definition for a Chemical Component, as maintained by the wwPDB. For access to all definitions,
032 * please download the components.cif.gz file from the wwPDB website.
033 *
034 * @author Andreas Prlic
035 *
036 */
037public class ChemComp implements Serializable, Comparable<ChemComp>{
038        /**
039         *
040         */
041        private static final long serialVersionUID = -4736341142030215915L;
042
043        private String id ;
044        private String name;
045        private String type;
046        private String pdbx_type;
047        private String formula;
048        private String mon_nstd_parent_comp_id;
049        private String pdbx_synonyms;
050        private String pdbx_formal_charge;
051        private String pdbx_initial_date ;
052        private String pdbx_modified_date;
053        private String pdbx_ambiguous_flag;
054        private String pdbx_release_status ;
055        private String pdbx_replaced_by;
056        private String pdbx_replaces;
057        private String formula_weight;
058        private String one_letter_code;
059        private String three_letter_code;
060        private String pdbx_model_coordinates_details;
061        private String pdbx_model_coordinates_missing_flag;
062        private String pdbx_ideal_coordinates_details;
063        private String pdbx_ideal_coordinates_missing_flag;
064        private String pdbx_model_coordinates_db_code;
065        private String pdbx_subcomponent_list;
066        private String pdbx_processing_site;
067        private String mon_nstd_flag;
068
069        @IgnoreField
070        private List<ChemCompDescriptor> descriptors = new ArrayList<ChemCompDescriptor>();
071        @IgnoreField
072        private List<ChemCompBond> bonds = new ArrayList<ChemCompBond>();
073        @IgnoreField
074        private List<ChemCompAtom> atoms = new ArrayList<ChemCompAtom>();
075
076        // and some derived data for easier processing...
077        @IgnoreField
078        private ResidueType residueType;
079        @IgnoreField
080        private PolymerType polymerType;
081        @IgnoreField
082        private boolean standard;
083
084        @Override
085        public String toString(){
086                StringBuffer buf = new StringBuffer("ChemComp ");
087                buf.append(id);
088                buf.append(" ");
089                buf.append(one_letter_code);
090                buf.append(" ");
091                buf.append(three_letter_code);
092                buf.append(" poly:");
093                buf.append(getPolymerType());
094                buf.append(" resi:");
095                buf.append(getResidueType());
096                if (isStandard())
097                        buf.append(" standard");
098                else
099                        buf.append(" modified");
100                buf.append(" ");
101
102                buf.append(name);
103                buf.append(" ");
104                buf.append(pdbx_type);
105                buf.append(" ");
106                buf.append(formula);
107                buf.append(" parent:");
108                buf.append(mon_nstd_parent_comp_id);
109                return buf.toString();
110        }
111
112        public boolean hasParent(){
113                String pid = mon_nstd_parent_comp_id;
114                if ((pid != null ) && (! pid.equals("?"))){
115                        return true;
116                }
117                return false;
118        }
119
120        public boolean isStandard(){
121                return standard;
122        }
123
124        private void setStandardFlag(){
125                standard = ChemCompTools.isStandardChemComp(this);
126        }
127
128
129
130        public String getId() {
131                return id;
132        }
133        public void setId(String id) {
134                this.id = id;
135        }
136        public String getName() {
137                return name;
138        }
139        public void setName(String name) {
140                this.name = name;
141        }
142        public String getType() {
143                return type;
144        }
145
146        public void setType(String type) {
147                this.type = type;
148
149                residueType = ResidueType.getResidueTypeFromString(type);
150                if ( residueType != null){
151                        polymerType = residueType.polymerType;
152                }
153
154        }
155
156
157        public ResidueType getResidueType() {
158                return residueType;
159        }
160
161        public void setResidueType(ResidueType residueType) {
162                this.residueType = residueType;
163        }
164
165        public PolymerType getPolymerType() {
166                return polymerType;
167        }
168
169        public void setPolymerType(PolymerType polymerType) {
170                this.polymerType = polymerType;
171        }
172
173        public String getPdbx_type() {
174                return pdbx_type;
175        }
176        public void setPdbx_type(String pdbx_type) {
177                this.pdbx_type = pdbx_type;
178        }
179        public String getFormula() {
180                return formula;
181        }
182        public void setFormula(String formula) {
183                this.formula = formula;
184        }
185        public String getMon_nstd_parent_comp_id() {
186                return mon_nstd_parent_comp_id;
187        }
188        public void setMon_nstd_parent_comp_id(String mon_nstd_parent_comp_id) {
189                this.mon_nstd_parent_comp_id = mon_nstd_parent_comp_id;
190                setStandardFlag();
191        }
192        public String getPdbx_synonyms() {
193                return pdbx_synonyms;
194        }
195        public void setPdbx_synonyms(String pdbx_synonyms) {
196                this.pdbx_synonyms = pdbx_synonyms;
197        }
198        public String getPdbx_formal_charge() {
199                return pdbx_formal_charge;
200        }
201        public void setPdbx_formal_charge(String pdbx_formal_charge) {
202                this.pdbx_formal_charge = pdbx_formal_charge;
203        }
204        public String getPdbx_initial_date() {
205                return pdbx_initial_date;
206        }
207        public void setPdbx_initial_date(String pdbx_initial_date) {
208                this.pdbx_initial_date = pdbx_initial_date;
209        }
210        public String getPdbx_modified_date() {
211                return pdbx_modified_date;
212        }
213        public void setPdbx_modified_date(String pdbx_modified_date) {
214                this.pdbx_modified_date = pdbx_modified_date;
215        }
216        public String getPdbx_ambiguous_flag() {
217                return pdbx_ambiguous_flag;
218        }
219        public void setPdbx_ambiguous_flag(String pdbx_ambiguous_flag) {
220                this.pdbx_ambiguous_flag = pdbx_ambiguous_flag;
221        }
222        public String getPdbx_release_status() {
223                return pdbx_release_status;
224        }
225        public void setPdbx_release_status(String pdbx_release_status) {
226                this.pdbx_release_status = pdbx_release_status;
227        }
228        public String getPdbx_replaced_by() {
229                return pdbx_replaced_by;
230        }
231        public void setPdbx_replaced_by(String pdbx_replaced_by) {
232                this.pdbx_replaced_by = pdbx_replaced_by;
233        }
234        public String getPdbx_replaces() {
235                return pdbx_replaces;
236        }
237        public void setPdbx_replaces(String pdbx_replaces) {
238                this.pdbx_replaces = pdbx_replaces;
239        }
240        public String getFormula_weight() {
241                return formula_weight;
242        }
243        public void setFormula_weight(String formula_weight) {
244                this.formula_weight = formula_weight;
245        }
246        public String getOne_letter_code() {
247                return one_letter_code;
248        }
249        public void setOne_letter_code(String one_letter_code) {
250                this.one_letter_code = one_letter_code;
251                setStandardFlag();
252        }
253        public String getThree_letter_code() {
254                return three_letter_code;
255        }
256        public void setThree_letter_code(String three_letter_code) {
257                this.three_letter_code = three_letter_code;
258        }
259        public String getPdbx_model_coordinates_details() {
260                return pdbx_model_coordinates_details;
261        }
262        public void setPdbx_model_coordinates_details(
263                        String pdbx_model_coordinates_details) {
264                this.pdbx_model_coordinates_details = pdbx_model_coordinates_details;
265        }
266        public String getPdbx_model_coordinates_missing_flag() {
267                return pdbx_model_coordinates_missing_flag;
268        }
269        public void setPdbx_model_coordinates_missing_flag(
270                        String pdbx_model_coordinates_missing_flag) {
271                this.pdbx_model_coordinates_missing_flag = pdbx_model_coordinates_missing_flag;
272        }
273        public String getPdbx_ideal_coordinates_details() {
274                return pdbx_ideal_coordinates_details;
275        }
276        public void setPdbx_ideal_coordinates_details(
277                        String pdbx_ideal_coordinates_details) {
278                this.pdbx_ideal_coordinates_details = pdbx_ideal_coordinates_details;
279        }
280        public String getPdbx_ideal_coordinates_missing_flag() {
281                return pdbx_ideal_coordinates_missing_flag;
282        }
283        public void setPdbx_ideal_coordinates_missing_flag(
284                        String pdbx_ideal_coordinates_missing_flag) {
285                this.pdbx_ideal_coordinates_missing_flag = pdbx_ideal_coordinates_missing_flag;
286        }
287        public String getPdbx_model_coordinates_db_code() {
288                return pdbx_model_coordinates_db_code;
289        }
290        public void setPdbx_model_coordinates_db_code(
291                        String pdbx_model_coordinates_db_code) {
292                this.pdbx_model_coordinates_db_code = pdbx_model_coordinates_db_code;
293        }
294        public String getPdbx_subcomponent_list() {
295                return pdbx_subcomponent_list;
296        }
297        public void setPdbx_subcomponent_list(String pdbx_subcomponent_list) {
298                this.pdbx_subcomponent_list = pdbx_subcomponent_list;
299        }
300        public String getPdbx_processing_site() {
301                return pdbx_processing_site;
302        }
303        public void setPdbx_processing_site(String pdbx_processing_site) {
304                this.pdbx_processing_site = pdbx_processing_site;
305        }
306
307        public void setStandard(boolean standard) {
308                this.standard = standard;
309        }
310
311        public String getMon_nstd_flag()
312        {
313                return mon_nstd_flag;
314        }
315
316        public void setMon_nstd_flag(String mon_nstd_flag)
317        {
318                this.mon_nstd_flag = mon_nstd_flag;
319        }
320
321        public List<ChemCompDescriptor> getDescriptors() {
322                return descriptors;
323        }
324
325        public void setDescriptors(List<ChemCompDescriptor> descriptors) {
326                this.descriptors = descriptors;
327        }
328
329        public List<ChemCompBond> getBonds() {
330                return bonds;
331        }
332
333        public void setBonds(List<ChemCompBond> bonds) {
334                this.bonds = bonds;
335        }
336
337        public List<ChemCompAtom> getAtoms() {
338                return atoms;
339        }
340
341        public void setAtoms(List<ChemCompAtom> atoms) {
342                this.atoms = atoms;
343        }
344
345        @Override
346        public int compareTo(ChemComp arg0) {
347                if ( this.equals(arg0))
348                        return 0;
349                return this.getId().compareTo(arg0.getId());
350        }
351
352        @Override
353        public int hashCode() {
354                final int prime = 31;
355                int result = 1;
356                result = prime * result
357                                + ((descriptors == null) ? 0 : descriptors.hashCode());
358                result = prime * result + ((formula == null) ? 0 : formula.hashCode());
359                result = prime * result
360                                + ((formula_weight == null) ? 0 : formula_weight.hashCode());
361                result = prime * result + ((id == null) ? 0 : id.hashCode());
362                result = prime * result
363                                + ((mon_nstd_flag == null) ? 0 : mon_nstd_flag.hashCode());
364                result = prime
365                                * result
366                                + ((mon_nstd_parent_comp_id == null) ? 0
367                                                : mon_nstd_parent_comp_id.hashCode());
368                result = prime * result + ((name == null) ? 0 : name.hashCode());
369                result = prime * result
370                                + ((one_letter_code == null) ? 0 : one_letter_code.hashCode());
371                result = prime
372                                * result
373                                + ((pdbx_ambiguous_flag == null) ? 0 : pdbx_ambiguous_flag
374                                                .hashCode());
375                result = prime
376                                * result
377                                + ((pdbx_formal_charge == null) ? 0 : pdbx_formal_charge
378                                                .hashCode());
379                result = prime
380                                * result
381                                + ((pdbx_ideal_coordinates_details == null) ? 0
382                                                : pdbx_ideal_coordinates_details.hashCode());
383                result = prime
384                                * result
385                                + ((pdbx_ideal_coordinates_missing_flag == null) ? 0
386                                                : pdbx_ideal_coordinates_missing_flag.hashCode());
387                result = prime
388                                * result
389                                + ((pdbx_initial_date == null) ? 0 : pdbx_initial_date
390                                                .hashCode());
391                result = prime
392                                * result
393                                + ((pdbx_model_coordinates_db_code == null) ? 0
394                                                : pdbx_model_coordinates_db_code.hashCode());
395                result = prime
396                                * result
397                                + ((pdbx_model_coordinates_details == null) ? 0
398                                                : pdbx_model_coordinates_details.hashCode());
399                result = prime
400                                * result
401                                + ((pdbx_model_coordinates_missing_flag == null) ? 0
402                                                : pdbx_model_coordinates_missing_flag.hashCode());
403                result = prime
404                                * result
405                                + ((pdbx_modified_date == null) ? 0 : pdbx_modified_date
406                                                .hashCode());
407                result = prime
408                                * result
409                                + ((pdbx_processing_site == null) ? 0 : pdbx_processing_site
410                                                .hashCode());
411                result = prime
412                                * result
413                                + ((pdbx_release_status == null) ? 0 : pdbx_release_status
414                                                .hashCode());
415                result = prime
416                                * result
417                                + ((pdbx_replaced_by == null) ? 0 : pdbx_replaced_by.hashCode());
418                result = prime * result
419                                + ((pdbx_replaces == null) ? 0 : pdbx_replaces.hashCode());
420                result = prime
421                                * result
422                                + ((pdbx_subcomponent_list == null) ? 0
423                                                : pdbx_subcomponent_list.hashCode());
424                result = prime * result
425                                + ((pdbx_synonyms == null) ? 0 : pdbx_synonyms.hashCode());
426                result = prime * result
427                                + ((pdbx_type == null) ? 0 : pdbx_type.hashCode());
428                result = prime * result
429                                + ((polymerType == null) ? 0 : polymerType.hashCode());
430                result = prime * result
431                                + ((residueType == null) ? 0 : residueType.hashCode());
432                result = prime * result + (standard ? 1231 : 1237);
433                result = prime
434                                * result
435                                + ((three_letter_code == null) ? 0 : three_letter_code
436                                                .hashCode());
437                result = prime * result + ((type == null) ? 0 : type.hashCode());
438                return result;
439        }
440
441        @Override
442        public boolean equals(Object obj) {
443                if (this == obj)
444                        return true;
445                if (obj == null)
446                        return false;
447                if (getClass() != obj.getClass())
448                        return false;
449                ChemComp other = (ChemComp) obj;
450                if (descriptors == null) {
451                        if (other.descriptors != null)
452                                return false;
453                } else if (!descriptors.equals(other.descriptors))
454                        return false;
455                if (formula == null) {
456                        if (other.formula != null)
457                                return false;
458                } else if (!formula.equals(other.formula))
459                        return false;
460                if (formula_weight == null) {
461                        if (other.formula_weight != null)
462                                return false;
463                } else if (!formula_weight.equals(other.formula_weight))
464                        return false;
465                if (id == null) {
466                        if (other.id != null)
467                                return false;
468                } else if (!id.equals(other.id))
469                        return false;
470                if (mon_nstd_flag == null) {
471                        if (other.mon_nstd_flag != null)
472                                return false;
473                } else if (!mon_nstd_flag.equals(other.mon_nstd_flag))
474                        return false;
475                if (mon_nstd_parent_comp_id == null) {
476                        if (other.mon_nstd_parent_comp_id != null)
477                                return false;
478                } else if (!mon_nstd_parent_comp_id
479                                .equals(other.mon_nstd_parent_comp_id))
480                        return false;
481                if (name == null) {
482                        if (other.name != null)
483                                return false;
484                } else if (!name.equals(other.name))
485                        return false;
486                if (one_letter_code == null) {
487                        if (other.one_letter_code != null)
488                                return false;
489                } else if (!one_letter_code.equals(other.one_letter_code))
490                        return false;
491                if (pdbx_ambiguous_flag == null) {
492                        if (other.pdbx_ambiguous_flag != null)
493                                return false;
494                } else if (!pdbx_ambiguous_flag.equals(other.pdbx_ambiguous_flag))
495                        return false;
496                if (pdbx_formal_charge == null) {
497                        if (other.pdbx_formal_charge != null)
498                                return false;
499                } else if (!pdbx_formal_charge.equals(other.pdbx_formal_charge))
500                        return false;
501                if (pdbx_ideal_coordinates_details == null) {
502                        if (other.pdbx_ideal_coordinates_details != null)
503                                return false;
504                } else if (!pdbx_ideal_coordinates_details
505                                .equals(other.pdbx_ideal_coordinates_details))
506                        return false;
507                if (pdbx_ideal_coordinates_missing_flag == null) {
508                        if (other.pdbx_ideal_coordinates_missing_flag != null)
509                                return false;
510                } else if (!pdbx_ideal_coordinates_missing_flag
511                                .equals(other.pdbx_ideal_coordinates_missing_flag))
512                        return false;
513                if (pdbx_initial_date == null) {
514                        if (other.pdbx_initial_date != null)
515                                return false;
516                } else if (!pdbx_initial_date.equals(other.pdbx_initial_date))
517                        return false;
518                if (pdbx_model_coordinates_db_code == null) {
519                        if (other.pdbx_model_coordinates_db_code != null)
520                                return false;
521                } else if (!pdbx_model_coordinates_db_code
522                                .equals(other.pdbx_model_coordinates_db_code))
523                        return false;
524                if (pdbx_model_coordinates_details == null) {
525                        if (other.pdbx_model_coordinates_details != null)
526                                return false;
527                } else if (!pdbx_model_coordinates_details
528                                .equals(other.pdbx_model_coordinates_details))
529                        return false;
530                if (pdbx_model_coordinates_missing_flag == null) {
531                        if (other.pdbx_model_coordinates_missing_flag != null)
532                                return false;
533                } else if (!pdbx_model_coordinates_missing_flag
534                                .equals(other.pdbx_model_coordinates_missing_flag))
535                        return false;
536                if (pdbx_modified_date == null) {
537                        if (other.pdbx_modified_date != null)
538                                return false;
539                } else if (!pdbx_modified_date.equals(other.pdbx_modified_date))
540                        return false;
541                if (pdbx_processing_site == null) {
542                        if (other.pdbx_processing_site != null)
543                                return false;
544                } else if (!pdbx_processing_site.equals(other.pdbx_processing_site))
545                        return false;
546                if (pdbx_release_status == null) {
547                        if (other.pdbx_release_status != null)
548                                return false;
549                } else if (!pdbx_release_status.equals(other.pdbx_release_status))
550                        return false;
551                if (pdbx_replaced_by == null) {
552                        if (other.pdbx_replaced_by != null)
553                                return false;
554                } else if (!pdbx_replaced_by.equals(other.pdbx_replaced_by))
555                        return false;
556                if (pdbx_replaces == null) {
557                        if (other.pdbx_replaces != null)
558                                return false;
559                } else if (!pdbx_replaces.equals(other.pdbx_replaces))
560                        return false;
561                if (pdbx_subcomponent_list == null) {
562                        if (other.pdbx_subcomponent_list != null)
563                                return false;
564                } else if (!pdbx_subcomponent_list.equals(other.pdbx_subcomponent_list))
565                        return false;
566                if (pdbx_synonyms == null) {
567                        if (other.pdbx_synonyms != null)
568                                return false;
569                } else if (!pdbx_synonyms.equals(other.pdbx_synonyms))
570                        return false;
571                if (pdbx_type == null) {
572                        if (other.pdbx_type != null)
573                                return false;
574                } else if (!pdbx_type.equals(other.pdbx_type))
575                        return false;
576                if (polymerType != other.polymerType)
577                        return false;
578                if (residueType != other.residueType)
579                        return false;
580                if (standard != other.standard)
581                        return false;
582                if (three_letter_code == null) {
583                        if (other.three_letter_code != null)
584                                return false;
585                } else if (!three_letter_code.equals(other.three_letter_code))
586                        return false;
587                if (type == null) {
588                        if (other.type != null)
589                                return false;
590                } else if (!type.equals(other.type))
591                        return false;
592                return true;
593        }
594
595        /**
596         * Creates a new instance of the dummy empty ChemComp.
597         * @return
598         */
599        public static ChemComp getEmptyChemComp(){
600                ChemComp comp = new ChemComp();
601
602                comp.setOne_letter_code("?");
603                comp.setThree_letter_code("???"); // Main signal for isEmpty()
604                comp.setPolymerType(PolymerType.unknown);
605                comp.setResidueType(ResidueType.atomn);
606                return comp;
607        }
608
609        /**
610         * Indicates whether this compound was created with
611         * @return
612         */
613        public boolean isEmpty() {
614                // Is this the best flag for it being empty?
615                return id == null || getThree_letter_code() == null || getThree_letter_code().equals("???");
616        }
617
618}