public @Nonnull Range getDataRTRange(int msLevel) {
    // check if we have this value already cached
    Range rtRange = dataRTRange.get(msLevel);
    if (rtRange != null) return rtRange;

    // find the value
    for (Scan scan : scans.values()) {

      // ignore scans of other ms levels
      if ((msLevel != 0) && (scan.getMSLevel() != msLevel)) continue;

      if (rtRange == null) rtRange = new Range(scan.getRetentionTime());
      else rtRange.extendRange(scan.getRetentionTime());
    }

    // cache the value
    if (rtRange != null) dataRTRange.put(msLevel, rtRange);
    else rtRange = new Range(0);

    return rtRange;
  }
  public @Nonnull Range getDataMZRange(int msLevel) {
    // check if we have this value already cached
    Range mzRange = dataMZRange.get(msLevel);
    if (mzRange != null) return mzRange;

    // find the value
    for (Scan scan : scans.values()) {

      // ignore scans of other ms levels
      if ((msLevel != 0) && (scan.getMSLevel() != msLevel)) continue;

      if (mzRange == null) mzRange = scan.getMZRange();
      else mzRange.extendRange(scan.getMZRange());
    }

    // cache the value, if we found any
    if (mzRange != null) dataMZRange.put(msLevel, mzRange);
    else mzRange = new Range(0);

    return mzRange;
  }
  /** @see net.sf.mzmine.datamodel.RawDataFile#getScanNumbers(int, double, double) */
  public @Nonnull int[] getScanNumbers(int msLevel, @Nonnull Range rtRange) {
    assert rtRange != null;

    ArrayList<Integer> eligibleScanNumbers = new ArrayList<Integer>();

    Enumeration<StorableScan> scansEnum = scans.elements();
    while (scansEnum.hasMoreElements()) {
      Scan scan = scansEnum.nextElement();

      if ((scan.getMSLevel() == msLevel) && (rtRange.contains(scan.getRetentionTime())))
        eligibleScanNumbers.add(scan.getScanNumber());
    }

    int[] numbersArray = CollectionUtils.toIntArray(eligibleScanNumbers);
    Arrays.sort(numbersArray);

    return numbersArray;
  }
  /** @see Runnable#run() */
  public void run() {

    if ((mzWeight == 0) && (rtWeight == 0)) {
      setStatus(TaskStatus.ERROR);
      errorMessage = "Cannot run alignment, all the weight parameters are zero";
      return;
    }

    setStatus(TaskStatus.PROCESSING);
    logger.info("Running join aligner");

    // Remember how many rows we need to process. Each row will be processed
    // twice, first for score calculation, second for actual alignment.
    for (int i = 0; i < peakLists.length; i++) {
      totalRows += peakLists[i].getNumberOfRows() * 2;
    }

    // Collect all data files
    Vector<RawDataFile> allDataFiles = new Vector<RawDataFile>();
    for (PeakList peakList : peakLists) {

      for (RawDataFile dataFile : peakList.getRawDataFiles()) {

        // Each data file can only have one column in aligned peak list
        if (allDataFiles.contains(dataFile)) {
          setStatus(TaskStatus.ERROR);
          errorMessage =
              "Cannot run alignment, because file "
                  + dataFile
                  + " is present in multiple peak lists";
          return;
        }

        allDataFiles.add(dataFile);
      }
    }

    // Create a new aligned peak list
    alignedPeakList = new SimplePeakList(peakListName, allDataFiles.toArray(new RawDataFile[0]));

    // Iterate source peak lists
    for (PeakList peakList : peakLists) {

      // Create a sorted set of scores matching
      TreeSet<RowVsRowScore> scoreSet = new TreeSet<RowVsRowScore>();

      PeakListRow allRows[] = peakList.getRows();

      // Calculate scores for all possible alignments of this row
      for (PeakListRow row : allRows) {

        if (isCanceled()) return;

        // Calculate limits for a row with which the row can be aligned
        Range mzRange = mzTolerance.getToleranceRange(row.getAverageMZ());
        Range rtRange = rtTolerance.getToleranceRange(row.getAverageRT());

        // Get all rows of the aligned peaklist within parameter limits
        PeakListRow candidateRows[] = alignedPeakList.getRowsInsideScanAndMZRange(rtRange, mzRange);

        // Calculate scores and store them
        for (PeakListRow candidate : candidateRows) {

          if (sameChargeRequired) {
            if (!PeakUtils.compareChargeState(row, candidate)) continue;
          }

          if (sameIDRequired) {
            if (!PeakUtils.compareIdentities(row, candidate)) continue;
          }

          if (compareIsotopePattern) {
            IsotopePattern ip1 = row.getBestIsotopePattern();
            IsotopePattern ip2 = candidate.getBestIsotopePattern();

            if ((ip1 != null) && (ip2 != null)) {
              ParameterSet isotopeParams =
                  parameters
                      .getParameter(JoinAlignerParameters.compareIsotopePattern)
                      .getEmbeddedParameters();

              if (!IsotopePatternScoreCalculator.checkMatch(ip1, ip2, isotopeParams)) {
                continue;
              }
            }
          }

          RowVsRowScore score =
              new RowVsRowScore(
                  row, candidate, mzRange.getSize() / 2, mzWeight, rtRange.getSize() / 2, rtWeight);

          scoreSet.add(score);
        }

        processedRows++;
      }

      // Create a table of mappings for best scores
      Hashtable<PeakListRow, PeakListRow> alignmentMapping =
          new Hashtable<PeakListRow, PeakListRow>();

      // Iterate scores by descending order
      Iterator<RowVsRowScore> scoreIterator = scoreSet.iterator();
      while (scoreIterator.hasNext()) {

        RowVsRowScore score = scoreIterator.next();

        // Check if the row is already mapped
        if (alignmentMapping.containsKey(score.getPeakListRow())) continue;

        // Check if the aligned row is already filled
        if (alignmentMapping.containsValue(score.getAlignedRow())) continue;

        alignmentMapping.put(score.getPeakListRow(), score.getAlignedRow());
      }

      // Align all rows using mapping
      for (PeakListRow row : allRows) {

        PeakListRow targetRow = alignmentMapping.get(row);

        // If we have no mapping for this row, add a new one
        if (targetRow == null) {
          targetRow = new SimplePeakListRow(newRowID);
          newRowID++;
          alignedPeakList.addRow(targetRow);
        }

        // Add all peaks from the original row to the aligned row
        for (RawDataFile file : row.getRawDataFiles()) {
          targetRow.addPeak(file, row.getPeak(file));
        }

        // Add all non-existing identities from the original row to the
        // aligned row
        PeakUtils.copyPeakListRowProperties(row, targetRow);

        processedRows++;
      }
    } // Next peak list

    // Add new aligned peak list to the project
    MZmineProject currentProject = MZmineCore.getCurrentProject();
    currentProject.addPeakList(alignedPeakList);

    // Add task description to peakList
    alignedPeakList.addDescriptionOfAppliedTask(
        new SimplePeakListAppliedMethod("Join aligner", parameters));

    logger.info("Finished join aligner");
    setStatus(TaskStatus.FINISHED);
  }
 public void setValue(Range value) {
   minTxtField.setText(format.format(value.getMin()));
   maxTxtField.setText(format.format(value.getMax()));
 }
  /**
   * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String,
   *     java.lang.String)
   */
  public void endElement(String namespaceURI, String sName, String qName) throws SAXException {

    if (canceled) throw new SAXException("Parsing canceled");

    // <NAME>
    if (qName.equals(PeakListElementName_2_3.PEAKLIST_NAME.getElementName())) {
      name = getTextOfElement();
      logger.info("Loading peak list: " + name);
      peakListName = name;
    }

    // <PEAKLIST_DATE>
    if (qName.equals(PeakListElementName_2_3.PEAKLIST_DATE.getElementName())) {
      dateCreated = getTextOfElement();
    }

    // <QUANTITY>
    if (qName.equals(PeakListElementName_2_3.QUANTITY.getElementName())) {
      String text = getTextOfElement();
      totalRows = Integer.parseInt(text);
    }

    // <RAW_FILE>
    if (qName.equals(PeakListElementName_2_3.RAWFILE.getElementName())) {
      rawDataFileID = getTextOfElement();
      RawDataFile dataFile = dataFilesIDMap.get(rawDataFileID);
      if (dataFile == null) {
        throw new SAXException(
            "Cannot open peak list, because raw data file " + rawDataFileID + " is missing.");
      }
      currentPeakListDataFiles.add(dataFile);
    }

    // <SCAN_ID>
    if (qName.equals(PeakListElementName_2_3.SCAN_ID.getElementName())) {

      byte[] bytes = Base64.decodeToBytes(getTextOfElement());
      // make a data input stream
      DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(bytes));
      scanNumbers = new int[numOfMZpeaks];
      for (int i = 0; i < numOfMZpeaks; i++) {
        try {
          scanNumbers[i] = dataInputStream.readInt();
        } catch (IOException ex) {
          throw new SAXException(ex);
        }
      }
    }

    // <REPRESENTATIVE_SCAN>
    if (qName.equals(PeakListElementName_2_3.REPRESENTATIVE_SCAN.getElementName())) {
      representativeScan = Integer.valueOf(getTextOfElement());
    }

    // <FRAGMENT_SCAN>

    if (qName.equals(PeakListElementName_2_3.FRAGMENT_SCAN.getElementName())) {
      fragmentScan = Integer.valueOf(getTextOfElement());
    }

    // <MASS>
    if (qName.equals(PeakListElementName_2_3.MZ.getElementName())) {

      byte[] bytes = Base64.decodeToBytes(getTextOfElement());
      // make a data input stream
      DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(bytes));
      masses = new double[numOfMZpeaks];
      for (int i = 0; i < numOfMZpeaks; i++) {
        try {
          masses[i] = (double) dataInputStream.readFloat();
        } catch (IOException ex) {
          throw new SAXException(ex);
        }
      }
    }

    // <HEIGHT>
    if (qName.equals(PeakListElementName_2_3.HEIGHT.getElementName())) {

      byte[] bytes = Base64.decodeToBytes(getTextOfElement());
      // make a data input stream
      DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(bytes));
      intensities = new double[numOfMZpeaks];
      for (int i = 0; i < numOfMZpeaks; i++) {
        try {
          intensities[i] = (double) dataInputStream.readFloat();
        } catch (IOException ex) {
          throw new SAXException(ex);
        }
      }
    }

    // <PEAK>
    if (qName.equals(PeakListElementName_2_3.PEAK.getElementName())) {

      DataPoint[] mzPeaks = new DataPoint[numOfMZpeaks];
      Range peakRTRange = null, peakMZRange = null, peakIntensityRange = null;
      RawDataFile dataFile = dataFilesIDMap.get(peakColumnID);

      if (dataFile == null)
        throw new SAXException("Error in project: data file " + peakColumnID + " not found");

      for (int i = 0; i < numOfMZpeaks; i++) {

        Scan sc = dataFile.getScan(scanNumbers[i]);
        double retentionTime = sc.getRetentionTime();

        double mz = masses[i];
        double intensity = intensities[i];

        if ((peakRTRange == null) || (peakIntensityRange == null)) {
          peakRTRange = new Range(retentionTime);
          peakIntensityRange = new Range(intensity);
        } else {
          peakRTRange.extendRange(retentionTime);
          peakIntensityRange.extendRange(intensity);
        }
        if (mz > 0.0) {
          mzPeaks[i] = new SimpleDataPoint(mz, intensity);
          if (peakMZRange == null) peakMZRange = new Range(mz);
          else peakMZRange.extendRange(mz);
        }
      }

      FeatureStatus status = FeatureStatus.valueOf(peakStatus);

      SimpleFeature peak =
          new SimpleFeature(
              dataFile,
              mass,
              rt,
              height,
              area,
              scanNumbers,
              mzPeaks,
              status,
              representativeScan,
              fragmentScan,
              peakRTRange,
              peakMZRange,
              peakIntensityRange);

      peak.setCharge(currentPeakCharge);

      if (currentIsotopes.size() > 0) {
        SimpleIsotopePattern newPattern =
            new SimpleIsotopePattern(
                currentIsotopes.toArray(new DataPoint[0]),
                currentIsotopePatternStatus,
                currentIsotopePatternDescription);
        peak.setIsotopePattern(newPattern);
        currentIsotopes.clear();
      }

      buildingRow.addPeak(dataFile, peak);
    }

    // <IDENTITY_PROPERTY>
    if (qName.equals(PeakListElementName_2_3.IDPROPERTY.getElementName())) {
      identityProperties.put(identityPropertyName, getTextOfElement());
    }

    // <PEAK_IDENTITY>
    if (qName.equals(PeakListElementName_2_3.PEAK_IDENTITY.getElementName())) {
      SimplePeakIdentity identity = new SimplePeakIdentity(identityProperties);
      buildingRow.addPeakIdentity(identity, preferred);
    }

    // <ROW>
    if (qName.equals(PeakListElementName_2_3.ROW.getElementName())) {
      buildingPeakList.addRow(buildingRow);
      buildingRow = null;
      parsedRows++;
    }

    // <ISOTOPE>
    if (qName.equals(PeakListElementName_2_3.ISOTOPE.getElementName())) {
      String text = getTextOfElement();
      String items[] = text.split(":");
      double mz = Double.valueOf(items[0]);
      double intensity = Double.valueOf(items[1]);
      DataPoint isotope = new SimpleDataPoint(mz, intensity);
      currentIsotopes.add(isotope);
    }

    if (qName.equals(PeakListElementName_2_3.METHOD_NAME.getElementName())) {
      String appliedMethod = getTextOfElement();
      appliedMethods.add(appliedMethod);
    }

    if (qName.equals(PeakListElementName_2_3.METHOD_PARAMETERS.getElementName())) {
      String appliedMethodParam = getTextOfElement();
      appliedMethodParameters.add(appliedMethodParam);
    }
  }