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;
022
023import org.biojava.nbio.structure.xtal.CrystalCell;
024import org.biojava.nbio.structure.xtal.SpaceGroup;
025
026import javax.vecmath.Matrix4d;
027import java.io.Serializable;
028import java.util.Locale;
029
030/**
031 * A class to hold crystallographic information about a PDB structure.
032 *
033 * @author Peter Rose
034 * @author duarte_j
035 */
036public class PDBCrystallographicInfo implements Serializable {
037
038        private static final long serialVersionUID = -7949886749566087669L;
039
040        private CrystalCell cell;
041        private SpaceGroup sg;
042
043        /**
044         * Some PDB files contain NCS operators necessary to create the full AU.
045         * Usually this happens for viral proteins.
046         * See http://www.wwpdb.org/documentation/format33/sect8.html#MTRIXn .
047         * Note that the "given" operators
048         * (iGiven field =1 in PDB format, "given" string in _struct_ncs_oper.code in mmCIF format)
049         * are not stored.
050         */
051        private Matrix4d[] ncsOperators;
052
053        /**
054         * Whether this structure has a non-standard space group not supported
055         * by Biojava. If this is true the sg member will be null.
056         * @since 4.2.5
057         */
058        private boolean nonStandardSg;
059
060        /**
061         * Whether this structure is non-standard coordinate frame convention, for which our scale matrix
062         * calculation and thus the crystal reconstruction will be incorrect.
063         * There's ~ 200 old structures in the PDB affected by the non-standard frame problem, hopefully they will
064         * be remediated in the future.
065         * For more info see: https://github.com/eppic-team/owl/issues/4
066         * @since 4.2.5
067         */
068        private boolean nonStandardCoordFrameConvention;
069
070        public PDBCrystallographicInfo() {
071
072        }
073
074        /**
075         * @return the unit cell parameter a
076         */
077        public float getA() {
078                return (float)cell.getA();
079        }
080
081        /**
082         * @return the unit cell parameter b
083         */
084        public float getB() {
085                return (float)cell.getB();
086        }
087
088        /**
089         * @return the unit cell parameter c
090         */
091        public float getC() {
092                return (float)cell.getC();
093        }
094
095        /**
096         * @return the unit cell parameter alpha (degrees)
097         */
098        public float getAlpha() {
099                return (float)cell.getAlpha();
100        }
101
102        /**
103         * @return the unit cell parameter beta (degrees)
104         */
105        public float getBeta() {
106                return (float)cell.getBeta();
107        }
108
109        /**
110         * @return the unit cell parameter gamma (degrees)
111         */
112        public float getGamma() {
113                return (float)cell.getGamma();
114        }
115
116        /**
117         * Return the crystal cell
118         * @return
119         */
120        public CrystalCell getCrystalCell() {
121                return cell;
122        }
123
124        /**
125         * Set the crystal cell
126         * @param cell
127         */
128        public void setCrystalCell(CrystalCell cell) {
129                this.cell = cell;
130        }
131
132        /**
133         * Get the SpaceGroup
134         * @return the spaceGroup
135         */
136        public SpaceGroup getSpaceGroup() {
137                return sg;
138        }
139
140        /**
141         * Set the SpaceGroup
142         * @param spaceGroup
143         */
144        public void setSpaceGroup(SpaceGroup spaceGroup) {
145                this.sg = spaceGroup;
146        }
147
148        /**
149         * Gets all symmetry transformation operators corresponding to this structure's space group
150         * (including the identity, at index 0) expressed in the orthonormal basis. Using PDB axes
151         * convention (NCODE=1).
152         * @return an array of size {@link SpaceGroup#getNumOperators()}
153         */
154        public Matrix4d[] getTransformationsOrthonormal() {
155                Matrix4d[] transfs = new Matrix4d[this.getSpaceGroup().getNumOperators()];
156                transfs[0] = new Matrix4d(this.getSpaceGroup().getTransformation(0)); // no need to transform the identity
157                for (int i=1;i<this.getSpaceGroup().getNumOperators();i++) {
158                        transfs[i] = this.cell.transfToOrthonormal(this.getSpaceGroup().getTransformation(i));
159                }
160                return transfs;
161        }
162
163        /**
164         * Get the NCS operators.
165         * Some PDB files contain NCS operators necessary to create the full AU.
166         * Usually this happens for viral proteins.
167         * See http://www.wwpdb.org/documentation/format33/sect8.html#MTRIXn .
168         * Note that the "given" operators
169         * (iGiven field =1 in PDB format, "given" string in _struct_ncs_oper.code in mmCIF format)
170         * are not stored.
171         * @return the operators or null if no operators present
172         */
173        public Matrix4d[] getNcsOperators() {
174                return ncsOperators;
175        }
176
177        /**
178         * Set the NCS operators.
179         * Some PDB files contain NCS operators necessary to create the full AU.
180         * Usually this happens for viral proteins.
181         * See http://www.wwpdb.org/documentation/format33/sect8.html#MTRIXn .
182         * Note that the "given" operators
183         * (iGiven field =1 in PDB format, "given" string in _struct_ncs_oper.code in mmCIF format)
184         * are not stored.
185         * @param ncsOperators
186         */
187        public void setNcsOperators(Matrix4d[] ncsOperators) {
188                this.ncsOperators = ncsOperators;
189        }
190
191        /**
192         * Whether this structure has a non-standard space group not supported
193         * by Biojava. If this is true {@link #getSpaceGroup()} will be null.
194         * @since 4.2.5
195         */
196        public boolean isNonStandardSg() {
197                return nonStandardSg;
198        }
199
200        /**
201         * Set the non-standard space group field
202         * @param nonStandardSg
203         * @since 4.2.5
204         */
205        public void setNonStandardSg(boolean nonStandardSg) {
206                this.nonStandardSg = nonStandardSg;
207        }
208
209        /**
210         * Whether this structure is non-standard coordinate frame convention, for which our scale matrix
211         * calculation and thus the crystal reconstruction will be incorrect.
212         * There's ~ 200 old structures in the PDB affected by the non-standard frame problem, hopefully they will
213         * be remediated in the future.
214         * For more info see: https://github.com/eppic-team/owl/issues/4
215         * @since 4.2.5
216         */
217        public boolean isNonStandardCoordFrameConvention() {
218                return nonStandardCoordFrameConvention;
219        }
220
221        /**
222         * Set the non-standard coordinate frame convention field
223         * @param nonStandardCoordFrameConvention
224         * @since 4.2.5
225         */
226        public void setNonStandardCoordFrameConvention(boolean nonStandardCoordFrameConvention) {
227                this.nonStandardCoordFrameConvention = nonStandardCoordFrameConvention;
228        }
229
230
231        @Override
232        public String toString() {
233                return "["+
234                                (sg==null?"no SG":sg.getShortSymbol())+" - "+
235
236                                (cell==null?"no Cell":
237                                String.format(Locale.US, "%.2f %.2f %.2f, %.2f %.2f %.2f",
238                                                cell.getA(),cell.getB(),cell.getC(),cell.getAlpha(),cell.getBeta(),cell.getGamma()) )+
239                                (ncsOperators==null? "" : String.format(" - %d NCS operators",ncsOperators.length) )+
240                                "]";
241        }
242
243
244}