*/
private void processPCI() {
// Product a list of candidates for each individual FAME peak
List<List<CorrectedSpectrum>> candidates = new ArrayList<List<CorrectedSpectrum>>();
CorrectedSpectrum bestMatch = null, highestMatch = null;
double bestIntensity = 0, highestIntensity = 0;
int bestLibraryMatch = -1, highestLibraryMatch = -1;
for (int i = 0; i < FameData.N_FAMES; i++) {
int mass = FameData.FAME_MASSES[i] + 1;
String name = FameData.FAME_NAMES[i];
// Search for [M + H]+ ion for each FAME marker
List<CorrectedSpectrum> matches = new ArrayList<CorrectedSpectrum>();
double maxBasePeakIntensity = 0;
for (CorrectedSpectrum spectrum : spectra) {
// Canceled?
if (isCanceled())
return;
DataPoint basePeak = spectrum.getBasePeak();
if (basePeak != null && (int) basePeak.getMZ() == mass) {
matches.add(spectrum);
// Compute maximum base peak intensity of these FAME markers
if (basePeak.getIntensity() > maxBasePeakIntensity)
maxBasePeakIntensity = basePeak.getIntensity();
// Find highest intensity FAME marker
if (basePeak.getIntensity() > highestIntensity) {
highestMatch = spectrum;
highestIntensity = basePeak.getIntensity();
highestLibraryMatch = i;
}
}
}
// Find initial standard match
CorrectedSpectrum bestCandidate = null;
int count = 0;
for (CorrectedSpectrum s : matches) {
if (s.getBasePeak().getIntensity() > 0.5 * maxBasePeakIntensity) {
bestCandidate = s;
count++;
}
}
if (count == 1 && bestCandidate != null && i > 1
&& i < FameData.N_FAMES - 2) {
if (bestMatch == null) {
bestMatch = bestCandidate;
bestIntensity = bestCandidate.getBasePeak().getIntensity();
bestLibraryMatch = i;
logger.info("Best Match: " + name + " "
+ bestMatch.getScanNumber() + " "
+ bestMatch.getRetentionTime() + " "
+ bestIntensity);
}
}
candidates.add(matches);
}
if (bestMatch == null) {
bestMatch = highestMatch;
bestIntensity = highestIntensity;
bestLibraryMatch = highestLibraryMatch;
}
// Return an error if no initial match is found
if (bestMatch == null) {
MZmineCore.getDesktop().displayErrorMessage(
"Unable to find initial standard match in "
+ dataFile.getName());
setStatus(TaskStatus.ERROR);
cancel();
return;
}
List<Double> fameTimes = new ArrayList<Double>();
List<Double> fameIndices = new ArrayList<Double>();
List<String> fameNames = new ArrayList<String>();
// Search for each FAME marker individually
for (int i = 0; i < FameData.N_FAMES; i++) {
List<CorrectedSpectrum> matches = candidates.get(i);
if (matches.size() > 0) {
double shift = FameData.FAME_RETENTION_TIMES[bestLibraryMatch]
- FameData.FAME_RETENTION_TIMES[i];
double expectedRt = bestMatch.getRetentionTime() - shift;
for (Iterator<CorrectedSpectrum> it = matches.iterator(); it
.hasNext();) {
CorrectedSpectrum s = it.next();
// Filter those peaks outside of expected range
if (Math.abs(s.getRetentionTime() - expectedRt) > timeWindow)
it.remove();
}
highestMatch = null;
highestIntensity = 0;
for (CorrectedSpectrum s : matches) {
if (s.getBasePeak().getIntensity() > highestIntensity) {
highestMatch = s;
highestIntensity = s.getBasePeak().getIntensity();
}
}
if (highestMatch != null) {
fameTimes.add(highestMatch.getRetentionTime());
fameIndices
.add((double) FameData.FAME_RETENTION_INDICES[i]);
fameNames.add(FameData.FAME_NAMES[i]);
}
}
}
// Store retention correction results
results = new TreeMap<String, FameCorrection>();
for (int i = 0; i < fameTimes.size(); i++)
results.put(fameNames.get(i), new FameCorrection(correctedDataFile,
fameTimes.get(i), (int) fameIndices.get(i).doubleValue()));
// Log results
logger.info(dataFile + "");
logger.info(fameTimes + "");
logger.info(fameNames + "");
// Apply linear/polynomial fit
CombinedRegression fit = new CombinedRegression(5);
fit.setData(Doubles.toArray(fameTimes), Doubles.toArray(fameIndices));
// Add calculated retention index to each mass spectrum
for (int scanNumber : correctedDataFile.getScanNumbers(1)) {
CorrectedSpectrum s = (CorrectedSpectrum) correctedDataFile
.getScan(scanNumber);
s.setRetentionIndex((int) fit.getY(s.getRetentionTime()));
s.setRetentionCorrection(fit, results);
}
}