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         * Return the z, i.e. the multiplicity of the space group times the number of chains in asymmetric unit
149         * @return 0
150         * @deprecated As of 4.0, use {@link SpaceGroup#getMultiplicity()} and {@link Structure#size()}
151         */
152        @Deprecated
153        public int getZ() {
154                return 0;
155        }
156
157        /**
158         * Gets all symmetry transformation operators corresponding to this structure's space group
159         * (including the identity, at index 0) expressed in the orthonormal basis. Using PDB axes
160         * convention (NCODE=1).
161         * @return an array of size {@link SpaceGroup#getNumOperators()}
162         */
163        public Matrix4d[] getTransformationsOrthonormal() {
164                Matrix4d[] transfs = new Matrix4d[this.getSpaceGroup().getNumOperators()];
165                transfs[0] = new Matrix4d(this.getSpaceGroup().getTransformation(0)); // no need to transform the identity
166                for (int i=1;i<this.getSpaceGroup().getNumOperators();i++) {
167                        transfs[i] = this.cell.transfToOrthonormal(this.getSpaceGroup().getTransformation(i));
168                }
169                return transfs;
170        }
171
172        /**
173         * Get the NCS operators.
174         * Some PDB files contain NCS operators necessary to create the full AU.
175         * Usually this happens for viral proteins.
176         * See http://www.wwpdb.org/documentation/format33/sect8.html#MTRIXn .
177         * Note that the "given" operators
178         * (iGiven field =1 in PDB format, "given" string in _struct_ncs_oper.code in mmCIF format)
179         * are not stored.
180         * @return the operators or null if no operators present
181         */
182        public Matrix4d[] getNcsOperators() {
183                return ncsOperators;
184        }
185
186        /**
187         * Set the NCS operators.
188         * Some PDB files contain NCS operators necessary to create the full AU.
189         * Usually this happens for viral proteins.
190         * See http://www.wwpdb.org/documentation/format33/sect8.html#MTRIXn .
191         * Note that the "given" operators
192         * (iGiven field =1 in PDB format, "given" string in _struct_ncs_oper.code in mmCIF format)
193         * are not stored.
194         * @param ncsOperators
195         */
196        public void setNcsOperators(Matrix4d[] ncsOperators) {
197                this.ncsOperators = ncsOperators;
198        }
199        
200        /**
201         * Whether this structure has a non-standard space group not supported 
202         * by Biojava. If this is true {@link #getSpaceGroup()} will be null.
203         * @since 4.2.5
204         */
205        public boolean isNonStandardSg() {
206                return nonStandardSg;
207        }
208        
209        /**
210         * Set the non-standard space group field
211         * @param nonStandardSg
212         * @since 4.2.5
213         */
214        public void setNonStandardSg(boolean nonStandardSg) {
215                this.nonStandardSg = nonStandardSg;
216        }
217        
218        /**
219         * Whether this structure is non-standard coordinate frame convention, for which our scale matrix 
220         * calculation and thus the crystal reconstruction will be incorrect.
221         * There's ~ 200 old structures in the PDB affected by the non-standard frame problem, hopefully they will
222         * be remediated in the future.
223         * For more info see: https://github.com/eppic-team/owl/issues/4
224         * @since 4.2.5
225         */
226        public boolean isNonStandardCoordFrameConvention() {
227                return nonStandardCoordFrameConvention;
228        }
229        
230        /**
231         * Set the non-standard coordinate frame convention field
232         * @param nonStandardCoordFrameConvention
233         * @since 4.2.5
234         */
235        public void setNonStandardCoordFrameConvention(boolean nonStandardCoordFrameConvention) {
236                this.nonStandardCoordFrameConvention = nonStandardCoordFrameConvention;
237        }
238
239
240        @Override
241        public String toString() {
242                return "["+
243                                (sg==null?"no SG":sg.getShortSymbol())+" - "+
244
245                                (cell==null?"no Cell":
246                                String.format("%.2f %.2f %.2f, %.2f %.2f %.2f",
247                                                cell.getA(),cell.getB(),cell.getC(),cell.getAlpha(),cell.getBeta(),cell.getGamma()) )+
248                                (ncsOperators==null? "" : String.format(" - %d NCS operators",ncsOperators.length) )+
249                                "]";
250        }
251
252
253}