//If the two lengths added is greater than the length of the probe,
//the longest of the two (or 3' if equal) is reduced to the maximum possible
//value (or 0) and an alert is added.
int probeLength = p.length();
if (min5Length + min3Length > probeLength) {
ProbeMakerPropertyUtils.addMessage(p,new Message(
"Templating not properly calculated because minimum lengths are too great", //$NON-NLS-1$
PROBE_IS_SELF_TEMPLATE, Message.ALERT));
while (min5Length + min3Length > probeLength) {
if (min5Length > min3Length) {
min5Length = probeLength - min3Length > 0 ?
probeLength - min3Length : 1;
}
else {
min3Length = probeLength - min5Length > 0 ?
probeLength - min5Length : 1;
}
}
}
/**** Searches are performed as string searches, and thus use string index system. ******/
//For a sequence to be a template for a padlock probe, it is
//necessary for the sequence to be similar to the intended template, and
//in particular, the sequence near the probes ends must be identical
try {
NucleotideSequence tss5 = p.getTSSPair().getSequence(TSSPair.KEY_FIVE_PRIME);
NucleotideSequence tss3 = p.getTSSPair().getSequence(TSSPair.KEY_THREE_PRIME);
// The sequence of the probe arms (full arms)
String tssSeq = tss3.seqString() + tss5.seqString();
NucleotideSequence fullTSS = new SimpleNucleotideSequence("TSS",tssSeq,p.getType()); //$NON-NLS-1$
//Get the sequence to search for in other probes
String threeseq = p.subsequence(p.length() - min3Length + 1, p.length());
String fiveseq = p.subsequence(1, min5Length);
String query = NucleotideSequenceHandler.getRevComp(threeseq + fiveseq, p.getType(),s.getType());
//Length of 5' TSS
int TSSlen5 = tss5.length();
//Length of 3' TSS
int TSSlen3 = tss3.length();
//Get the string to search in, extend it if it is to be interpreted as circular,
//and change any Us to Ts to allow correct interpretation
String sequence = s.seqString().replace('U', 'T');
if (circular) {
sequence += sequence.substring(0, min3Length + min5Length - 1);
}
//To store the results in
Stack<Integer> results = new Stack<Integer>();
//Search for occurrences of the query in the sequence
int index = -1;
while ((index = sequence.indexOf(query, index + 1)) > -1) {
//If stipulated, check Tm to be above limit
if (doTm) {
float maxTm = -Float.MAX_VALUE;
//Extract a template to check the whole TSS pair against
int start = Math.max(0,index+min5Length-TSSlen5);
int end = Math.min(index+min5Length+TSSlen3,sequence.length());
//Get the template to compare to
String template = sequence.substring(start,end);
//Get all possible sequences to match the probe to
String[] sequences = NucleotideSequenceHandler.getPossibleSequences(template,s.getType());
for (int sc = 0;sc<sequences.length;sc++) {
NucleotideSequence s2 = new SimpleNucleotideSequence("S2",sequences[sc],s.getType()); //$NON-NLS-1$
NAHybridStructure hs = ((FractionalMeltingPointCalculator) fmpc).calculateHybridStructure(fullTSS,s2);
if (hs != null) {
float Tm;
try {
Tm = fmpc.getMeltingPoint(fullTSS,s2,hs);
}
catch (UnsupportedHybridStructureException e) {
Tm = -MeltingPointCalculator.T0;
}
if (Tm > maxTm) {
maxTm = Tm;
}
}
}
if (maxTm >= limit) {
results.push(new Integer(index + min5Length));
}
}
else {
results.push(new Integer(index + min5Length));
}
}
//Read results stack and transform to array
if (results.isEmpty()) {
return null;
}
int[] res = new int[results.size()];
for (int i = 0; i < res.length; i++) {
//Add one to convert from string to sequence index system
res[i] = ( results.pop()).intValue() + 1;
}
return res;
}
catch (ClusterException e1) {
ProbeMakerPropertyUtils.addMessage(p.getTSSPair(),new Message("Padlock ligation analysis could not be performed: " + e1.toString(), //$NON-NLS-1$
NO_ANALYSIS,Message.ALERT));
return new int[0];
}
}