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.symmetry.internal;
022
023import java.util.List;
024import java.util.Random;
025
026import org.biojava.nbio.structure.align.ce.CeParameters;
027
028/**
029 * Provides parameters to {@link CeSymm}.
030 *
031 * @author Spencer Bliven
032 * @author Aleix Lafita
033 * @since 4.1.1
034 *
035 */
036public class CESymmParameters extends CeParameters {
037
038        private int maxSymmOrder;
039        private int userOrder;
040        private SymmetryType symmType;
041        private OrderDetectorMethod orderDetectorMethod;
042        private RefineMethod refineMethod;
043        private boolean optimization;
044        private int rndSeed;
045        private int symmLevels;
046        private double unrefinedScoreThreshold;
047        private double refinedScoreThreshold;
048        private int sseThreshold;
049        private int minCoreLength;
050        private double distanceCutoff;
051        private boolean gaps;
052        private int optimizationSteps;
053
054        public static enum OrderDetectorMethod {
055                SEQUENCE_FUNCTION, GRAPH_COMPONENT, ANGLE, USER_INPUT;
056                public static final OrderDetectorMethod DEFAULT = SEQUENCE_FUNCTION;
057        }
058
059        public static enum RefineMethod {
060                NOT_REFINED, SEQUENCE_FUNCTION, GRAPH_COMPONENT;
061                public static final RefineMethod DEFAULT = SEQUENCE_FUNCTION;
062        }
063
064        public static final double DEFAULT_SYMMETRY_THRESHOLD = 0.4;
065
066        /**
067         * The internal symmetry detection can be divided into two types: CLOSE:
068         * includes the circular and dihedral symmetries, and OPEN: includes the
069         * helical and protein repeats symmetries.
070         * <p>
071         * All internal symmetry cases share one property: all the repeats have the
072         * same 3D transformation.
073         * <p>
074         * AUTO option automatically identifies the type. The criterion for
075         * classification is that the CLOSE symmetry generates CeSymm alignments
076         * with circular permutations (2 blocks in AFPChain), whereas the OPEN
077         * symmetry generates alignments without a CP (only one block in AFPChain).
078         */
079        public enum SymmetryType {
080                CLOSED, OPEN, AUTO;
081                public static final SymmetryType DEFAULT = AUTO;
082        }
083
084        public CESymmParameters() {
085                reset();
086        }
087
088        @Override
089        public CESymmParameters clone() {
090
091                CESymmParameters p = new CESymmParameters();
092
093                p.maxSymmOrder = maxSymmOrder;
094                p.symmType = symmType;
095                p.orderDetectorMethod = orderDetectorMethod;
096                p.userOrder = userOrder;
097                p.refineMethod = refineMethod;
098                p.optimization = optimization;
099                p.rndSeed = rndSeed;
100                p.symmLevels = symmLevels;
101                p.unrefinedScoreThreshold = unrefinedScoreThreshold;
102                p.refinedScoreThreshold = refinedScoreThreshold;
103                p.sseThreshold = sseThreshold;
104                p.minCoreLength = minCoreLength;
105                p.distanceCutoff = distanceCutoff;
106                p.gaps = gaps;
107                p.optimizationSteps = optimizationSteps;
108
109                p.winSize = winSize;
110                p.rmsdThr = rmsdThr;
111                p.rmsdThrJoin = rmsdThrJoin;
112                p.scoringStrategy = scoringStrategy;
113                p.maxGapSize = maxGapSize;
114                p.showAFPRanges = showAFPRanges;
115                p.maxOptRMSD = maxOptRMSD;
116                p.gapOpen = gapOpen;
117                p.gapExtension = gapExtension;
118                p.distanceIncrement = distanceIncrement;
119                p.oRmsdThr = oRmsdThr;
120                p.maxNrIterationsForOptimization = maxNrIterationsForOptimization;
121                p.seqWeight = seqWeight;
122
123                return p;
124        }
125
126        @Override
127        public void reset() {
128                super.reset();
129                maxSymmOrder = 8;
130                symmType = SymmetryType.DEFAULT;
131                orderDetectorMethod = OrderDetectorMethod.DEFAULT;
132                userOrder = 0;
133                refineMethod = RefineMethod.DEFAULT;
134                optimization = true;
135                rndSeed = new Random().nextInt(10000);
136                symmLevels = 0;
137                unrefinedScoreThreshold = DEFAULT_SYMMETRY_THRESHOLD;
138                refinedScoreThreshold = DEFAULT_SYMMETRY_THRESHOLD * 0.9;
139                sseThreshold = 0;
140                minCoreLength = 15;
141                distanceCutoff = 7.0;
142                gaps = true;
143                optimizationSteps = 0;
144        }
145
146        @Override
147        public List<String> getUserConfigHelp() {
148                List<String> params = super.getUserConfigHelp();
149
150                // maxSymmOrder help explanation
151                params.add("Sets the maximum order of symmetry of the protein.");
152
153                // userOrder help explanation
154                params.add("Order of symmetry determined by the user. "
155                                + "Use it with the USER_INPUT order option. Imposes an order"
156                                + " of symmetry to the alignment. If 0 the order is set "
157                                + "automatically.");
158
159                StringBuilder symmTypes = new StringBuilder("Type of Symmetry: ");
160                SymmetryType[] vals = SymmetryType.values();
161                if (vals.length == 1) {
162                        symmTypes.append(vals[0].name());
163                } else if (vals.length > 1) {
164                        for (int i = 0; i < vals.length - 1; i++) {
165                                symmTypes.append(vals[i].name());
166                                symmTypes.append(", ");
167                        }
168                        symmTypes.append("or ");
169                        symmTypes.append(vals[vals.length - 1].name());
170                }
171                params.add(symmTypes.toString());
172
173                StringBuilder orderTypes = new StringBuilder("Order Detection Method: ");
174                OrderDetectorMethod[] vals2 = OrderDetectorMethod.values();
175                if (vals2.length == 1) {
176                        orderTypes.append(vals2[0].name());
177                } else if (vals2.length > 1) {
178                        for (int i = 0; i < vals2.length - 1; i++) {
179                                orderTypes.append(vals2[i].name());
180                                orderTypes.append(", ");
181                        }
182                        orderTypes.append("or ");
183                        orderTypes.append(vals[vals.length - 1].name());
184                }
185                params.add(orderTypes.toString());
186
187                StringBuilder refineTypes = new StringBuilder("Refinement Method: ");
188                RefineMethod[] values = RefineMethod.values();
189                if (values.length == 1) {
190                        refineTypes.append(values[0].name());
191                } else if (values.length > 1) {
192                        for (int i = 0; i < values.length - 1; i++) {
193                                refineTypes.append(values[i].name());
194                                refineTypes.append(", ");
195                        }
196                        refineTypes.append("or ");
197                        refineTypes.append(values[values.length - 1].name());
198                }
199                params.add(refineTypes.toString());
200
201                // optimization help explanation
202                params.add("Optimize the refined alignment if true.");
203                // seed help explanation
204                params.add("Random seed for the Monte Carlo optimization, "
205                                + "for reproducibility of results.");
206                // symmetry levels
207                params.add("Specify the maximum number of symmetry levels to explore "
208                                + "recursively. If equal to 1, only C and H symmetries can be "
209                                + "found. If equal to 2, D and two-level hierarchical C and H "
210                                + "can be found, etc. If equal to 0, the number of recursive "
211                                + "iterations is unbounded (until thresholds reached).");
212                // unrefined score threshold
213                params.add("Unrefined score threshold: TM-score values for the optimal"
214                                + " self-alignment, before refinement, below the "
215                                + "threshold will be considered asymmetric.");
216                // refined score threshold
217                params.add("Refined score threshold: TM-score values for the refined "
218                                + "multiple alignment of repeats below the "
219                                + "threshold will be considered asymmetric.");
220                // SSE threshold
221                params.add("SSE threshold: The minimum number of secondary structure "
222                                + "elements (strands or helices) in each symmetrical repeat. "
223                                + "If the repeats do not have enough SSE, the structure will "
224                                + "be considered asymmetric. 0 means no restriction.");
225                // min core repeat length
226                params.add("Minimum core length: the minimum number of non-gapped "
227                                + "residues in every symmetric repeat.");
228                // distance cutoff
229                params.add("Distance Cutoff: the maximum allowed distance (in A) "
230                                + "between two aligned residues.");
231
232                // gaps
233                params.add("Internal Gaps: allow up to 50% of repeats to have gaps in "
234                                + "the multiple alignment if true, "
235                                + "otherwise all repeats must be aligned at each position.");
236
237                // optimization steps
238                params.add("Optimization Steps: maximum number of optimization steps:"
239                                + " 0 means calculated automatically with the alignment length.");
240
241                return params;
242        }
243
244        @Override
245        public List<String> getUserConfigParameters() {
246                List<String> params = super.getUserConfigParameters();
247                params.add("MaxSymmOrder");
248                params.add("UserOrder");
249                params.add("SymmType");
250                params.add("OrderDetectorMethod");
251                params.add("RefineMethod");
252                params.add("Optimization");
253                params.add("RndSeed");
254                params.add("SymmLevels");
255                params.add("UnrefinedScoreThreshold");
256                params.add("RefinedScoreThreshold");
257                params.add("SSEThreshold");
258                params.add("MinCoreLength");
259                params.add("DistanceCutoff");
260                params.add("Gaps");
261                params.add("OptimizationSteps");
262                return params;
263        }
264
265        @Override
266        public List<String> getUserConfigParameterNames() {
267                List<String> params = super.getUserConfigParameterNames();
268                params.add("Maximum Order of Symmetry");
269                params.add("User Input Order");
270                params.add("Type of Symmetry");
271                params.add("Order Detection Method");
272                params.add("Refinement Method");
273                params.add("Optimization");
274                params.add("Random Seed");
275                params.add("Symmetry Levels");
276                params.add("Unrefined Score Threshold");
277                params.add("Refined Score Threshold");
278                params.add("SSE Threshold");
279                params.add("Minimum Core Length");
280                params.add("Distance Cutoff");
281                params.add("Internal Gaps");
282                params.add("Optimization Steps");
283                return params;
284        }
285
286        @Override
287        @SuppressWarnings("rawtypes")
288        public List<Class> getUserConfigTypes() {
289                List<Class> params = super.getUserConfigTypes();
290                params.add(Integer.class);
291                params.add(Integer.class);
292                params.add(SymmetryType.class);
293                params.add(OrderDetectorMethod.class);
294                params.add(RefineMethod.class);
295                params.add(Boolean.class);
296                params.add(Integer.class);
297                params.add(Integer.class);
298                params.add(Double.class);
299                params.add(Double.class);
300                params.add(Integer.class);
301                params.add(Integer.class);
302                params.add(Double.class);
303                params.add(Boolean.class);
304                params.add(Integer.class);
305                return params;
306        }
307
308        public RefineMethod getRefineMethod() {
309                return refineMethod;
310        }
311
312        public void setRefineMethod(RefineMethod refineMethod) {
313                this.refineMethod = refineMethod;
314        }
315
316        @Deprecated
317        public void setRefineResult(boolean doRefine) {
318                if (!doRefine) {
319                        refineMethod = RefineMethod.NOT_REFINED;
320                } else {
321                        refineMethod = RefineMethod.DEFAULT;
322                }
323        }
324
325        public OrderDetectorMethod getOrderDetectorMethod() {
326                return orderDetectorMethod;
327        }
328
329        public void setOrderDetectorMethod(OrderDetectorMethod orderDetectorMethod) {
330                this.orderDetectorMethod = orderDetectorMethod;
331        }
332
333        public void setUserOrder(Integer userOrder) {
334                this.userOrder = userOrder;
335        }
336
337        public int getUserOrder() {
338                return userOrder;
339        }
340
341        public void setMaxSymmOrder(Integer maxSymmOrder) {
342                this.maxSymmOrder = maxSymmOrder;
343        }
344
345        public int getMaxSymmOrder() {
346                return maxSymmOrder;
347        }
348
349        public SymmetryType getSymmType() {
350                return symmType;
351        }
352
353        public void setSymmType(SymmetryType type) {
354                this.symmType = type;
355        }
356
357        public boolean getOptimization() {
358                return optimization;
359        }
360
361        public void setOptimization(Boolean optimization) {
362                this.optimization = optimization;
363        }
364
365        public int getRndSeed() {
366                return rndSeed;
367        }
368
369        public void setRndSeed(Integer seed) {
370                this.rndSeed = seed;
371        }
372
373        public int getSymmLevels() {
374                return symmLevels;
375        }
376
377        public void setSymmLevels(Integer symmLevels) {
378                this.symmLevels = symmLevels;
379        }
380
381        public double getUnrefinedScoreThreshold() {
382                return unrefinedScoreThreshold;
383        }
384
385        public void setUnrefinedScoreThreshold(Double unrefinedScoreThreshold) {
386                this.unrefinedScoreThreshold = unrefinedScoreThreshold;
387        }
388        
389        public double getRefinedScoreThreshold() {
390                return refinedScoreThreshold;
391        }
392
393        public void setRefinedScoreThreshold(Double refinedScoreThreshold) {
394                this.refinedScoreThreshold = refinedScoreThreshold;
395        }
396
397        public int getSSEThreshold() {
398                return sseThreshold;
399        }
400
401        public void setSSEThreshold(Integer sseThreshold) {
402                this.sseThreshold = sseThreshold;
403        }
404
405        public int getMinCoreLength() {
406                return minCoreLength;
407        }
408
409        public void setMinCoreLength(Integer minCoreLength) {
410                this.minCoreLength = minCoreLength;
411        }
412
413        public double getDistanceCutoff() {
414                return distanceCutoff;
415        }
416
417        public void setDistanceCutoff(Double distanceCutoff) {
418                this.distanceCutoff = distanceCutoff;
419        }
420
421        public boolean isGaps() {
422                return gaps;
423        }
424
425        public void setGaps(Boolean gaps) {
426                this.gaps = gaps;
427        }
428
429        public int getOptimizationSteps() {
430                return optimizationSteps;
431        }
432
433        public void setOptimizationSteps(Integer optimizationSteps) {
434                this.optimizationSteps = optimizationSteps;
435        }
436
437        @Override
438        public String toString() {
439                return "CESymmParameters [maxSymmOrder=" + maxSymmOrder
440                                + ", userOrder=" + userOrder + ", symmType=" + symmType
441                                + ", orderDetectorMethod=" + orderDetectorMethod
442                                + ", refineMethod=" + refineMethod + ", optimization="
443                                + optimization + ", rndSeed=" + rndSeed + ", symmLevels="
444                                + symmLevels + ", unrefinedScoreThreshold="
445                                + unrefinedScoreThreshold + ", refinedScoreThreshold="
446                                + refinedScoreThreshold + ", sseThreshold=" + sseThreshold
447                                + ", minCoreLength=" + minCoreLength + ", distanceCutoff="
448                                + distanceCutoff + ", gaps=" + gaps + ", optimizationSteps="
449                                + optimizationSteps + "]";
450        }
451
452}