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