001 package org.jaga.reproduction.proteinLocation;
002
003 import org.jaga.reproduction.Mutation;
004 import org.jaga.individualRepresentation.proteinLocation.*;
005 import java.util.ArrayList;
006 import org.jaga.definitions.*;
007
008 /**
009 * TODO: Complete these comments.
010 *
011 * <p><u>Project:</u> JAGA - Java API for Genetic Algorithms.</p>
012 *
013 * <p><u>Company:</u> University College London and JAGA.Org
014 * (<a href="http://www.jaga.org" target="_blank">http://www.jaga.org</a>).
015 * </p>
016 *
017 * <p><u>Copyright:</u> (c) 2004 by G. Paperin.<br/>
018 * This program is free software; you can redistribute it and/or modify
019 * it under the terms of the GNU General Public License as published by
020 * the Free Software Foundation, ONLY if you include a note of the original
021 * author(s) in any redistributed/modified copy.<br/>
022 * This program is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
025 * GNU General Public License for more details.<br/>
026 * You should have received a copy of the GNU General Public License
027 * along with this program; if not, write to the Free Software
028 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
029 * or see http://www.gnu.org/licenses/gpl.html</p>
030 *
031 * @author Greg Paperin (greg@jaga.org)
032 *
033 * @version JAGA public release 1.0 beta
034 */
035
036 public class PolypeptidePatternMutation extends Mutation {
037
038 private SubstitutionScoringMatrix scoringMatrix = new Blosum62();
039
040 private int aminoAcid_deleteChance = 2;
041 private int aminoAcid_cloneChance = 2;
042 private int aminoAcid_mutateChance = 5;
043 private int aminoAcid_generaliseToPropertyChance = 3;
044 private int aminoAcid_generaliseToGroupChance = 2;
045
046 private int group_substractChance = 5;
047 private int group_addChance = 5;
048 private int group_swapChance = 9;
049 private int group_deleteChance = 2;
050 private int group_cloneChance = 2;
051 private int group_onEmptyDeleteChance = 1;
052 private int group_onEmptyReplaceChance = 1;
053 private double group_onSingleReplaceProb = 0.75;
054 private double group_onPropertyTriggerPercent = 0.7;
055 private double group_onPropertyReplaceProb = 0.5;
056 private int group_onLargeTriggerLength = 12;
057 private int group_onLargeSplitChance = 2;
058 private int group_onLargeReplaceChance = 3;
059 private int group_onLargeDontActChance = 5;
060
061 private int property_deleteChance = 2;
062 private int property_cloneChance = 5;
063 private int property_mutateChance = 5;
064 private int property_expandChance = 5;//3
065 private int property_expandGroupSize = 6;
066 private int property_expandSamePropCount = 5;
067
068 private int singleGap_deleteChance = 3;
069 private int singleGap_cloneChance = 5;
070 private int singleGap_mutateChance = 5;
071 private int singleGap_expandChance = 2;
072 private int singleGap_expandGroupSize = 20;
073
074
075 public PolypeptidePatternMutation() {
076 super();
077 }
078
079 public PolypeptidePatternMutation(double mutProb) {
080 super(mutProb);
081 }
082
083 public Class getApplicableClass() {
084 return ProteinLocationClassifier.class;
085 }
086
087 private PolypeptidePatternItem [] mutateItem(AminoAcid aAcid, GAParameterSet params) {
088 int sum = aminoAcid_cloneChance + aminoAcid_deleteChance + aminoAcid_mutateChance
089 + aminoAcid_generaliseToPropertyChance + aminoAcid_generaliseToGroupChance;
090 int dice = params.getRandomGenerator().nextInt(0, sum);
091
092 // clone:
093 if (0 <= dice && dice < aminoAcid_cloneChance) {
094 return new PolypeptidePatternItem [] {aAcid, aAcid};
095
096 // delete:
097 } else if (aminoAcid_cloneChance <= dice && dice < aminoAcid_cloneChance + aminoAcid_deleteChance) {
098 return new PolypeptidePatternItem[0];
099
100 // mutate:
101 } else if (aminoAcid_cloneChance + aminoAcid_deleteChance <= dice
102 && dice < aminoAcid_cloneChance + aminoAcid_deleteChance + aminoAcid_mutateChance) {
103 /*
104 AminoAcid substitute = scoringMatrix.chooseProbabalisticMutation(aAcid, params);
105 if (null == substitute)
106 return new PolypeptidePatternItem[] {SingleGap.getInstance()};
107 else
108 return new PolypeptidePatternItem[] {substitute};
109 */
110 return new PolypeptidePatternItem[] {AminoAcidFactory.getRandomResidue(params)};
111
112 // generalise to a property group:
113 } else if (aminoAcid_cloneChance + aminoAcid_deleteChance + aminoAcid_mutateChance <= dice
114 && dice < aminoAcid_cloneChance + aminoAcid_deleteChance
115 + aminoAcid_mutateChance
116 + aminoAcid_generaliseToPropertyChance) {
117 ArrayList props = new ArrayList();
118 if (aAcid.isSmall()) props.add(AminoAcidPropertyFactory.Small);
119 if (aAcid.isHydrophobic()) props.add(AminoAcidPropertyFactory.Hydrophobic);
120 if (aAcid.isPolar()) props.add(AminoAcidPropertyFactory.Polar);
121 if (aAcid.isPositive()) props.add(AminoAcidPropertyFactory.Positive);
122 if (aAcid.isNegative()) props.add(AminoAcidPropertyFactory.Negative);
123 if (aAcid.isTiny()) props.add(AminoAcidPropertyFactory.Tiny);
124 if (aAcid.isAliphatic()) props.add(AminoAcidPropertyFactory.Aliphatic);
125 if (aAcid.isAromatic()) props.add(AminoAcidPropertyFactory.Aromatic);
126 Object p = props.get(params.getRandomGenerator().nextInt(0, props.size()));
127 return new PolypeptidePatternItem [] {(AminoAcidProperty) p};
128
129 // must be generalise to list group:
130 } else {
131 AminoAcidGroup group = new AminoAcidGroup();
132 group.addResidue(aAcid);
133 return new PolypeptidePatternItem [] {group};
134
135 }
136 }
137
138 private PolypeptidePatternItem [] mutateItem(AminoAcidGroup group, GAParameterSet params) {
139 /*
140 - delete an item from the group
141 - add an item to the group
142 - swap an item in the group
143 - delete the whole group
144 - clone the group
145 then check in this order:
146 - if group becomes empty, it wont be able to match anything, so:
147 - delete it or
148 - replace by a gap
149 - if group has only one residue - consider replacing group by that acid
150 - if more then X percent in group have same property - consider replacing by property group
151 - if group becomes too large, consider:
152 - splitting in two groups
153 - replacing by a gap
154 */
155 RandomGenerator rnd = params.getRandomGenerator();
156 int sum = group_substractChance + group_addChance + group_swapChance
157 + group_deleteChance + group_cloneChance;
158 int dice = rnd.nextInt(0, sum);
159
160 // clone:
161 if (0 <= dice && dice < group_cloneChance) {
162 return new PolypeptidePatternItem[] {group, group};
163
164 // delete:
165 } else if (group_cloneChance <= dice && dice < group_cloneChance + group_deleteChance) {
166 return new PolypeptidePatternItem[0];
167
168 // substract a residue:
169 } else if (group_cloneChance + group_deleteChance <= dice
170 && dice < group_cloneChance + group_deleteChance + group_substractChance) {
171 int ind = rnd.nextInt(0, group.size());
172 group.removeResidue(ind);
173
174 // add a residue:
175 } else if (group_cloneChance + group_deleteChance + group_substractChance <= dice
176 && dice < group_cloneChance + group_deleteChance + group_substractChance + group_addChance) {
177 group.addResidue(AminoAcidFactory.getRandomResidue(params));
178
179 // must be swap a residue:
180 } else {
181 int ind = rnd.nextInt(0, group.size());
182 group.swapResidue(ind, AminoAcidFactory.getRandomResidue(params));
183
184 }
185
186 // Now the checks:
187
188 if (group.size() == 0) {
189 dice = rnd.nextInt(0, group_onEmptyDeleteChance + group_onEmptyReplaceChance);
190 if (dice < group_onEmptyDeleteChance)
191 return new PolypeptidePatternItem[0];
192 else
193 return new PolypeptidePatternItem [] {SingleGap.getInstance()};
194 }
195 if (group.size() == 1) {
196 if (rnd.nextDouble() < group_onSingleReplaceProb)
197 return new PolypeptidePatternItem [] {group.getResidue(0)};
198 }
199 int frequentProp = group.getMaxRepresentedProperty();
200 if (0 != frequentProp) {
201 if (group.getPropertyProportion(frequentProp) >= group_onPropertyTriggerPercent)
202 if (rnd.nextDouble() < group_onPropertyReplaceProb)
203 return new PolypeptidePatternItem [] {AminoAcidPropertyFactory.getPropertyByCode(frequentProp)};
204 }
205 if (group.size() >= group_onLargeTriggerLength) {
206 dice = rnd.nextInt(0, group_onLargeSplitChance
207 + group_onLargeReplaceChance + group_onLargeDontActChance);
208 if (dice < group_onLargeSplitChance) {
209 AminoAcidGroup group2 = new AminoAcidGroup();
210 int half = group.size() / 2;
211 for (int i = 0; i < half; i++) {
212 int ind = rnd.nextInt(0, group.size());
213 AminoAcid aa = group.removeResidue(ind);
214 group2.addResidue(aa);
215 }
216 return new PolypeptidePatternItem [] {group, group2};
217
218 } else if (dice < group_onLargeSplitChance + group_onLargeReplaceChance) {
219 return new PolypeptidePatternItem [] {SingleGap.getInstance()};
220
221 } else ; // Don't act = do nothing.
222 }
223
224 return new PolypeptidePatternItem [] {group};
225 }
226
227 private PolypeptidePatternItem [] mutateItem(AminoAcidProperty property, GAParameterSet params) {
228 /*
229 - delete the hole group
230 - duplicate the group
231 - mutate to some other property
232 - mutate to aa group consisting of at least X% of acids with this property
233 */
234 int sum = property_deleteChance + property_cloneChance
235 + property_mutateChance + property_expandChance;
236 int dice = params.getRandomGenerator().nextInt(0, sum);
237
238 // clone:
239 if (0 <= dice && dice < property_cloneChance) {
240 return new PolypeptidePatternItem [] {property, property};
241
242 // delete:
243 } else if (property_cloneChance <= dice && dice < property_cloneChance + property_deleteChance) {
244 return new PolypeptidePatternItem[0];
245
246 // mutate:
247 } else if (property_cloneChance + property_deleteChance <= dice
248 && dice < property_cloneChance + property_deleteChance + property_mutateChance) {
249 return new PolypeptidePatternItem[] {AminoAcidPropertyFactory.getRandomProperty(params)};
250
251 // must be expand:
252 } else {
253 AminoAcidGroup group = new AminoAcidGroup();
254 for (int i = 0; i < property_expandGroupSize; i++) {
255 AminoAcid aa;
256 if (i < property_expandSamePropCount)
257 aa = AminoAcidFactory.getRandomResidueByProperty(property.getProperty(), params);
258 else
259 aa = AminoAcidFactory.getRandomResidue(params);
260 group.addResidue(aa);
261 }
262 return new PolypeptidePatternItem [] {group};
263
264 }
265 }
266
267 private PolypeptidePatternItem [] mutateItem(SingleGap gap, GAParameterSet params) {
268 int sum = singleGap_cloneChance + singleGap_deleteChance
269 + singleGap_mutateChance + singleGap_expandChance;
270 int dice = params.getRandomGenerator().nextInt(0, sum);
271
272 // clone:
273 if (0 <= dice && dice < singleGap_cloneChance) {
274 return new PolypeptidePatternItem [] {gap, gap};
275
276 // delete:
277 } else if (singleGap_cloneChance <= dice && dice < singleGap_cloneChance + singleGap_deleteChance) {
278 return new PolypeptidePatternItem[0];
279
280 // mutate:
281 } else if (singleGap_cloneChance + singleGap_deleteChance <= dice
282 && dice < singleGap_cloneChance + singleGap_deleteChance + singleGap_mutateChance) {
283 AminoAcid substitute = scoringMatrix.chooseProbabalisticMutation((AminoAcid) null, params);
284 if (null == substitute)
285 return new PolypeptidePatternItem[] {SingleGap.getInstance()};
286 else
287 return new PolypeptidePatternItem[] {substitute};
288
289 // must be expand:
290 } else {
291 AminoAcidGroup group = new AminoAcidGroup();
292 for (int i = 0; i < singleGap_expandGroupSize; i++) {
293 AminoAcid aa = AminoAcidFactory.getRandomResidue(params);
294 group.addResidue(aa);
295 }
296 return new PolypeptidePatternItem [] {group};
297
298 }
299 }
300
301 private PolypeptidePatternItem [] mutatePatternItem(PolypeptidePatternItem item, GAParameterSet params) {
302
303 if (item instanceof AminoAcid)
304 return mutateItem((AminoAcid) item, params);
305 if (item instanceof AminoAcidGroup)
306 return mutateItem((AminoAcidGroup) item, params);
307 if (item instanceof AminoAcidProperty)
308 return mutateItem((AminoAcidProperty) item, params);
309 if (item instanceof SingleGap)
310 return mutateItem((SingleGap) item, params);
311 throw new IllegalArgumentException("Cannot mutate a PolypeptidePatternItem"
312 + " of an unexpected type ("
313 + item.getClass().getName() + ")");
314 }
315
316 public Individual reproduce(Individual parent, GAParameterSet params) {
317 ProteinLocationClassifierFactory factory = (ProteinLocationClassifierFactory) params.getIndividualsFactory();
318 ProteinLocationClassifier kid = (ProteinLocationClassifier)
319 factory.createSpecificIndividual(parent, params);
320 PolypeptidePattern pattern = kid.getPattern();
321 RandomGenerator rnd = params.getRandomGenerator();
322 double mutProb = getMutationProbability();
323 int i = 0;
324 while(i < pattern.getLength()) {
325 if (rnd.nextDouble() > mutProb) {
326 i++;
327 continue;
328 }
329 PolypeptidePatternItem item = kid.getPattern().getItem(i);
330 PolypeptidePatternItem [] res = mutatePatternItem(item, params);
331 if (0 == res.length) {
332 pattern.removeItem(i);
333 i++;
334 } else if (1 == res.length) {
335
336 //if (null == res[0]) System.out.println("\n**********" + item.getClass().getName());
337
338 pattern.replaceItem(i, res[0]);
339 i++;
340 } else { /* must be 1 < res.length */
341 pattern.replaceItem(i, res[0]);
342 i++;
343 for (int j = 1; j < res.length; i++, j++) {
344 if (pattern.getLength() >= factory.getMaxPatternLength())
345 break;
346 pattern.insertItem(i, res[j]);
347 }
348 }
349 }
350 return kid;
351 }
352
353 public Individual[] reproduce(Individual[] parents, GAParameterSet params) {
354 Individual [] kids = new Individual[parents.length];
355 for (int i = 0; i < parents.length; i++) {
356 kids[i] = reproduce(parents[i], params);
357 }
358 return kids;
359 }
360
361 public int getAminoAcid_cloneChance() {
362 return aminoAcid_cloneChance;
363 }
364
365 public void setAminoAcid_cloneChance(int aminoAcid_cloneChance) {
366 this.aminoAcid_cloneChance = aminoAcid_cloneChance;
367 }
368
369 public int getAminoAcid_deleteChance() {
370 return aminoAcid_deleteChance;
371 }
372
373 public void setAminoAcid_deleteChance(int aminoAcid_deleteChance) {
374 this.aminoAcid_deleteChance = aminoAcid_deleteChance;
375 }
376
377 public int getAminoAcid_generaliseToGroupChance() {
378 return aminoAcid_generaliseToGroupChance;
379 }
380
381 public void setAminoAcid_generaliseToGroupChance(int
382 aminoAcid_generaliseToGroupChance) {
383 this.aminoAcid_generaliseToGroupChance =
384 aminoAcid_generaliseToGroupChance;
385 }
386
387 public int getAminoAcid_generaliseToPropertyChance() {
388 return aminoAcid_generaliseToPropertyChance;
389 }
390
391 public void setAminoAcid_generaliseToPropertyChance(int
392 aminoAcid_generaliseToPropertyChance) {
393 this.aminoAcid_generaliseToPropertyChance =
394 aminoAcid_generaliseToPropertyChance;
395 }
396
397 public int getAminoAcid_mutateChance() {
398 return aminoAcid_mutateChance;
399 }
400
401 public void setAminoAcid_mutateChance(int aminoAcid_mutateChance) {
402 this.aminoAcid_mutateChance = aminoAcid_mutateChance;
403 }
404
405 public int getGroup_addChance() {
406 return group_addChance;
407 }
408
409 public void setGroup_addChance(int group_addChance) {
410 this.group_addChance = group_addChance;
411 }
412
413 public int getGroup_cloneChance() {
414 return group_cloneChance;
415 }
416
417 public void setGroup_cloneChance(int group_cloneChance) {
418 this.group_cloneChance = group_cloneChance;
419 }
420
421 public int getGroup_deleteChance() {
422 return group_deleteChance;
423 }
424
425 public void setGroup_deleteChance(int group_deleteChance) {
426 this.group_deleteChance = group_deleteChance;
427 }
428
429 public int getGroup_onEmptyDeleteChance() {
430 return group_onEmptyDeleteChance;
431 }
432
433 public void setGroup_onEmptyDeleteChance(int group_onEmptyDeleteChance) {
434 this.group_onEmptyDeleteChance = group_onEmptyDeleteChance;
435 }
436
437 public int getGroup_onEmptyReplaceChance() {
438 return group_onEmptyReplaceChance;
439 }
440
441 public void setGroup_onEmptyReplaceChance(int group_onEmptyReplaceChance) {
442 this.group_onEmptyReplaceChance = group_onEmptyReplaceChance;
443 }
444
445 public int getGroup_onLargeDontActChance() {
446 return group_onLargeDontActChance;
447 }
448
449 public void setGroup_onLargeDontActChance(int group_onLargeDontActChance) {
450 this.group_onLargeDontActChance = group_onLargeDontActChance;
451 }
452
453 public int getGroup_onLargeReplaceChance() {
454 return group_onLargeReplaceChance;
455 }
456
457 public void setGroup_onLargeReplaceChance(int group_onLargeReplaceChance) {
458 this.group_onLargeReplaceChance = group_onLargeReplaceChance;
459 }
460
461 public int getGroup_onLargeSplitChance() {
462 return group_onLargeSplitChance;
463 }
464
465 public void setGroup_onLargeSplitChance(int group_onLargeSplitChance) {
466 this.group_onLargeSplitChance = group_onLargeSplitChance;
467 }
468
469 public int getGroup_onLargeTriggerLength() {
470 return group_onLargeTriggerLength;
471 }
472
473 public void setGroup_onLargeTriggerLength(int group_onLargeTriggerLength) {
474 this.group_onLargeTriggerLength = group_onLargeTriggerLength;
475 }
476
477 public double getGroup_onPropertyReplaceProb() {
478 return group_onPropertyReplaceProb;
479 }
480
481 public void setGroup_onPropertyReplaceProb(double
482 group_onPropertyReplaceProb) {
483 this.group_onPropertyReplaceProb = group_onPropertyReplaceProb;
484 }
485
486 public double getGroup_onPropertyTriggerPercent() {
487 return group_onPropertyTriggerPercent;
488 }
489
490 public void setGroup_onPropertyTriggerPercent(double
491 group_onPropertyTriggerPercent) {
492 this.group_onPropertyTriggerPercent = group_onPropertyTriggerPercent;
493 }
494
495 public double getGroup_onSingleReplaceProb() {
496 return group_onSingleReplaceProb;
497 }
498
499 public void setGroup_onSingleReplaceProb(double group_onSingleReplaceProb) {
500 this.group_onSingleReplaceProb = group_onSingleReplaceProb;
501 }
502
503 public int getGroup_substractChance() {
504 return group_substractChance;
505 }
506
507 public void setGroup_substractChance(int group_substractChance) {
508 this.group_substractChance = group_substractChance;
509 }
510
511 public int getGroup_swapChance() {
512 return group_swapChance;
513 }
514
515 public void setGroup_swapChance(int group_swapChance) {
516 this.group_swapChance = group_swapChance;
517 }
518
519 public int getProperty_cloneChance() {
520 return property_cloneChance;
521 }
522
523 public void setProperty_cloneChance(int property_cloneChance) {
524 this.property_cloneChance = property_cloneChance;
525 }
526
527 public int getProperty_deleteChance() {
528 return property_deleteChance;
529 }
530
531 public void setProperty_deleteChance(int property_deleteChance) {
532 this.property_deleteChance = property_deleteChance;
533 }
534
535 public int getProperty_expandChance() {
536 return property_expandChance;
537 }
538
539 public void setProperty_expandChance(int property_expandChance) {
540 this.property_expandChance = property_expandChance;
541 }
542
543 public int getProperty_expandGroupSize() {
544 return property_expandGroupSize;
545 }
546
547 public void setProperty_expandGroupSize(int property_expandGroupSize) {
548 this.property_expandGroupSize = property_expandGroupSize;
549 }
550
551 public int getProperty_expandSamePropCount() {
552 return property_expandSamePropCount;
553 }
554
555 public void setProperty_expandSamePropCount(int
556 property_expandSamePropCount) {
557 this.property_expandSamePropCount = property_expandSamePropCount;
558 }
559
560 public int getProperty_mutateChance() {
561 return property_mutateChance;
562 }
563
564 public void setProperty_mutateChance(int property_mutateChance) {
565 this.property_mutateChance = property_mutateChance;
566 }
567
568 public SubstitutionScoringMatrix getScoringMatrix() {
569 return scoringMatrix;
570 }
571
572 public void setScoringMatrix(SubstitutionScoringMatrix scoringMatrix) {
573 this.scoringMatrix = scoringMatrix;
574 }
575
576 public int getSingleGap_cloneChance() {
577 return singleGap_cloneChance;
578 }
579
580 public void setSingleGap_cloneChance(int singleGap_cloneChance) {
581 this.singleGap_cloneChance = singleGap_cloneChance;
582 }
583
584 public int getSingleGap_deleteChance() {
585 return singleGap_deleteChance;
586 }
587
588 public void setSingleGap_deleteChance(int singleGap_deleteChance) {
589 this.singleGap_deleteChance = singleGap_deleteChance;
590 }
591
592 public int getSingleGap_expandChance() {
593 return singleGap_expandChance;
594 }
595
596 public void setSingleGap_expandChance(int singleGap_expandChance) {
597 this.singleGap_expandChance = singleGap_expandChance;
598 }
599
600 public int getSingleGap_expandGroupSize() {
601 return singleGap_expandGroupSize;
602 }
603
604 public void setSingleGap_expandGroupSize(int singleGap_expandGroupSize) {
605 this.singleGap_expandGroupSize = singleGap_expandGroupSize;
606 }
607
608 public int getSingleGap_mutateChance() {
609 return singleGap_mutateChance;
610 }
611
612 public void setSingleGap_mutateChance(int singleGap_mutateChance) {
613 this.singleGap_mutateChance = singleGap_mutateChance;
614 }
615
616 }