int minlength, double preftemp,
byte acidType, byte fixedEnd) {
//Create a new TSS.
PropertyAcceptorNucleotideSequence pa = ProbeMakerSequenceFactory.createTSS(new SimpleNucleotideSequence(armDesc,"",acidType),temp == null ? "" : DesignUtils.getTargetID(temp)); //$NON-NLS-1$ //$NON-NLS-2$
ChangeableNucleotideSequence cns = (ChangeableNucleotideSequence) pa;
if (temp == null) return pa;
//Set the probe arm sequence to the reverse complement of the template
try {
cns.setSequence(NucleotideSequenceHandler.getRevComp(temp,acidType));
}
catch (SequenceFormatException e) {
throw new UnsupportedOperationException("Invalid sequence"); //$NON-NLS-1$
}
//If template is polymorphic
if (NucleotideSequenceHandler.countPolys(temp) > 0) {
ProbeMakerPropertyUtils.addMessage(pa,new Message("Could not calculate Tm because of polymorphisms",messagetype,Message.ALERT)); //$NON-NLS-1$
}
else {
//If both ends are fixed, this is the probe arm, so just skip the design
if (fixedEnd != TemplateHandler.BOTH) {
//Now cut off one base at a time until we reach either minimum length, or
//preferred temperature.
boolean done = false; //are we done yet?
String oldseq = pa.seqString(); //store old seq here
float oldTm = 0.0f;
float Tm = 0.0f; //melting temp
while (!done) {
if (pa.length() == 0) {
ProbeMakerPropertyUtils.addMessage(pa,new Message("Could not calculate Tm because of zero length",messagetype,Message.ALERT)); //$NON-NLS-1$
return pa;
}
//Set up the structure for the MPC
int secstart = fixedEnd == TemplateHandler.THREEPRIME ? 1 :
temp.length() - pa.length() + 1;
int secend = fixedEnd == TemplateHandler.THREEPRIME ? pa.length() :
temp.length();
NAHybridStructure st = new DefaultNAHybridStructure(pa, 1, pa.length(),
temp, secstart,
secend);
//calculate the Tm of the probe Arm to the template
oldTm = Tm;
Tm = Analyzer.calculateTm(pa,temp,st,defaultMpc,backupMpc);
//Tm = defaultMpc.getMeltingPoint(pa);
//If minimum length reached, stop and check if further away than last length
if (pa.length() <= minlength) {
done = true;
//if further from temp than last, restore the old seq.
if (oldTm > 0 && Math.abs(Tm - preftemp) > Math.abs(oldTm - preftemp)) {
try {
cns.setSequence(oldseq);
}
catch (SequenceFormatException e) {
throw new UnsupportedOperationException("Invalid sequence"); //$NON-NLS-1$
}
}
break;
}
//If below temp limit, back up one step
if (Tm <= preftemp) {
done = true;
if (oldTm > 0 && Math.abs(Tm - preftemp) > Math.abs(oldTm - preftemp)) {
try {
cns.setSequence(oldseq);
}
catch (SequenceFormatException e) {
throw new UnsupportedOperationException("Invalid sequence"); //$NON-NLS-1$
}
}
break;
}
//Here we cut of the sequence at the appropriate end and do all again
oldseq = pa.seqString(); //but first store the old sequence
//remove nucleotides form the non-fixed end of the arm
switch (fixedEnd) {
case TemplateHandler.THREEPRIME:
try {
cns.edit(new SimpleSequenceEdit(1, 1, "")); //$NON-NLS-1$
}
catch (SequenceFormatException e) {
throw new UnsupportedOperationException("Invalid sequence"); //$NON-NLS-1$
}
break;
case TemplateHandler.FIVEPRIME:
try {
cns.edit(new SimpleSequenceEdit(pa.length(), 1, "")); //$NON-NLS-1$
}
catch (SequenceFormatException e) {
throw new UnsupportedOperationException("Invalid sequence"); //$NON-NLS-1$
}