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