DataPoint secondaryBasePeak = s.getSecondaryBasePeak();
if (fameBasePeaks.contains((int) s.getBasePeak().getMZ())
|| (secondaryBasePeak != null && (secondaryBasePeak
.getMZ() == 74 || secondaryBasePeak.getMZ() == 87))) {
allCandidates.add(new SimpleScan(s));
totalScans += 2 * FameData.N_FAMES;
}
}
processedScans++;
}
// Perform C13 Isotope filtering on candidates
for (SimpleScan s : allCandidates)
applyC13IsotopeFilter(s);
// Find spectrum with the highest similarity to a library spectrum
double maxSimilarity = 0;
int libraryMatch = -1;
SimpleScan highestMatch = null;
for (SimpleScan s : allCandidates) {
DataPoint basePeak = s.getBasePeak();
double bestSimilarity = 0;
int matchesCount = 0;
for (int i = 0; i < FameData.N_FAMES; i++) {
String name = FameData.FAME_NAMES[i];
// Check for ion qualifier
int qualifier = FameData.QUALIFIER_IONS[i];
DataPoint[] p = s.getDataPointsByMass(new Range(qualifier,
qualifier));
// Confirm that the qualifier ion exists
if (p.length != 1)
continue;
// Check for similarity
int minSimilarity = FameData.MIN_SIMILARITY[i];
double similarity = FameData.computeSimilarity(name, s);
if (similarity > bestSimilarity) {
bestSimilarity = similarity;
matchesCount++;
}
if (bestSimilarity > maxSimilarity) {
logger.info("Best Match: " + dataFile + " " + name + " "
+ similarity + " " + s.getScanNumber() + " "
+ s.getRetentionTime() + " " + matchesCount);
maxSimilarity = bestSimilarity;
highestMatch = s;
libraryMatch = i;
}
processedScans++;
}
}
// Return an error if no initial match is found
if (highestMatch == null) {
MZmineCore.getDesktop().displayErrorMessage(
"Unable to find initial standard match in "
+ dataFile.getName());
setStatus(TaskStatus.ERROR);
return;
}
// Product a list of candidates for each individual FAME peak
List<List<SimpleScan>> candidates = new ArrayList<List<SimpleScan>>();
for (int i = 0; i < FameData.N_FAMES; i++) {
List<SimpleScan> matches = new ArrayList<SimpleScan>();
if (i == libraryMatch)
matches.add(highestMatch);
else {
double expectedRT = highestMatch.getRetentionTime()
- (FameData.FAME_RETENTION_TIMES[libraryMatch] - FameData.FAME_RETENTION_TIMES[i]);
for (SimpleScan s : allCandidates) {
if (s.getBasePeak() != null
&& s.getBasePeak().getIntensity() > 0
&& Math.abs(s.getRetentionTime() - expectedRT) < timeWindow)
matches.add(s);
processedScans++;
}
}
candidates.add(matches);
}
// Apply spectral similarity to choose the best match for each FAME peak
List<Double> fameTimes = new ArrayList<Double>();
List<Double> fameIndices = new ArrayList<Double>();
List<String> fameNames = new ArrayList<String>();
for (int i = 0; i < FameData.N_FAMES; i++) {
String libraryName = FameData.FAME_NAMES[i];
List<SimpleScan> matches = candidates.get(i);
SimpleScan bestMatch = null;
double maxBasePeakIntensity = 0;
maxSimilarity = 0;
for (SimpleScan s : matches) {
if (bestMatch == null) {
bestMatch = s;
maxBasePeakIntensity = s.getBasePeak().getIntensity();
} else {
double similarity = FameData.computeSimilarity(libraryName,
s);
// || (similarity < maxSimilarity &&
// s.getBasePeak().getIntensity() / maxBasePeakIntensity >
// similarity / maxSimilarity)
if ((similarity > maxSimilarity && s.getBasePeak()
.getIntensity() > maxBasePeakIntensity)) {
bestMatch = s;
maxBasePeakIntensity = s.getBasePeak().getIntensity();
maxSimilarity = similarity;
}
}
}
if (bestMatch != null) {
fameTimes.add(bestMatch.getRetentionTime());
fameIndices.add((double) FameData.FAME_RETENTION_INDICES[i]);
fameNames.add(FameData.FAME_NAMES[i]);
}
}