Пример #1
0
 /** Set the default preferences. */
 private void setDefaultPreferences() {
   searchParameters = new SearchParameters();
   annotationPreferences.setAnnotationLevel(0.75);
   annotationPreferences.useAutomaticAnnotation(true);
   spectrumCountingPreferences.setSelectedMethod(SpectralCountingMethod.NSAF);
   spectrumCountingPreferences.setValidatedHits(true);
   IonFactory.getInstance().addDefaultNeutralLoss(NeutralLoss.NH3);
   IonFactory.getInstance().addDefaultNeutralLoss(NeutralLoss.H2O);
   processingPreferences = new ProcessingPreferences();
   ptmScoringPreferences = new PTMScoringPreferences();
 }
/**
 * The spectrum annotator annotates peaks in a spectrum.
 *
 * @author Marc Vaudel
 * @author Harald Barsnes
 */
public abstract class SpectrumAnnotator {

  /** Enum of the possibilities for ties resolution when multiple peaks can be annotated. */
  public enum TiesResolution {
    /**
     * The most intense peak is retained. If two peaks have the same intensity, the one with the
     * most accurate m/z is retained.
     */
    mostIntense,
    /**
     * The peak of most accurate m/z is retained. If two peaks have the same error the most intense
     * is retained.
     */
    mostAccurateMz;
  }
  /** The precursor charge as deduced by the search engine. */
  protected int precursorCharge;
  /** The theoretic fragment ions. */
  protected HashMap<Integer, HashMap<Integer, ArrayList<Ion>>> theoreticalFragmentIons;
  /** The Fragment factory which will generate the fragment ions. */
  protected IonFactory fragmentFactory = IonFactory.getInstance();
  /** The key of the currently loaded spectrum. */
  private String spectrumKey = "";
  /** The intensity limit to use. */
  protected double intensityLimit = 0;
  /** Index for the spectrum. */
  private SpectrumIndex spectrumIndex;
  /** The m/z tolerance for peak matching. */
  protected double mzTolerance;
  /** Boolean indicating whether the tolerance is in ppm (true) or in Dalton (false). */
  protected boolean isPpm;
  /** Minimal isotopic correction when matching an ion. */
  protected static final boolean subtractIsotope = false;
  /** The minimal isotope correction. By default only the monoisotopic peak is annotated (min=0). */
  protected static final Integer minIsotopicCorrection = 0;
  /** The maximal isotope correction. By default only the monoisotopic peak is annotated (max=0). */
  protected static final Integer maxIsotopicCorrection = 0;
  /** m/z shift applied to all theoretic peaks. */
  protected double massShift = 0;
  /** N-terminal m/z shift applied to all forward ions. */
  protected double massShiftNTerm = 0;
  /** C-terminal m/z shift applied to all reverse ions. */
  protected double massShiftCTerm = 0;
  /** The methods to use to select the best peak when multiple are possible. */
  protected TiesResolution tiesResolution;
  /**
   * If provided, the annotator will only look for the ions included in the specific annotation
   * settings.
   */
  protected SpecificAnnotationSettings specificAnnotationSettings = null;
  /** The cache to use for the ion match keys. */
  protected IonMatchKeysCache ionMatchKeysCache = new IonMatchKeysCache();

  /**
   * Translates the list of ion matches into a vector of annotations which can be read by the
   * SpectrumPanel.
   *
   * @param ionMatches list of ion matches
   * @return vector of default spectrum annotations
   */
  public static Vector<SpectrumAnnotation> getSpectrumAnnotation(ArrayList<IonMatch> ionMatches) {
    Vector<SpectrumAnnotation> currentAnnotations = new Vector();
    for (IonMatch ionMatch : ionMatches) {
      currentAnnotations.add(
          new DefaultSpectrumAnnotation(
              ionMatch.peak.mz,
              ionMatch.getAbsoluteError(minIsotopicCorrection, maxIsotopicCorrection),
              SpectrumPanel.determineFragmentIonColor(ionMatch.ion, true),
              ionMatch.getPeakAnnotation()));
    }
    return currentAnnotations;
  }

  /**
   * Matches a theoretic ion in the spectrum. Returns an IonMatch containing the ion and the peak.
   * Null if not found.
   *
   * @param theoreticIon the theoretic ion
   * @param inspectedCharge the expected charge
   * @return the IonMatch between the ion and the peak
   */
  protected IonMatch matchInSpectrum(Ion theoreticIon, Integer inspectedCharge) {

    Double fragmentMz = theoreticIon.getTheoreticMz(inspectedCharge);

    // Get the peaks matching the desired m/z
    ArrayList<Peak> matchedPeaks = spectrumIndex.getMatchingPeaks(fragmentMz);

    if (matchedPeaks.isEmpty()) {
      return null;
    }

    // Select the most accurate or most intense according to the annotation settings
    IonMatch ionMatch = new IonMatch(null, theoreticIon, inspectedCharge);
    ionMatch.peak =
        (matchedPeaks.size() == 1) ? matchedPeaks.get(0) : getBestPeak(matchedPeaks, ionMatch);
    return ionMatch;
  }

  /**
   * Returns the peak to retain of the matched peaks according to the ties resolution setting.
   *
   * @param matchedPeaks the peaks matched
   * @param ionMatch an ion match with the ion to be matched
   * @return the peak to retain
   */
  protected Peak getBestPeak(ArrayList<Peak> matchedPeaks, IonMatch ionMatch) {
    Peak bestPeak = null;
    switch (tiesResolution) {
      case mostAccurateMz:
        Double bestPeakError = null;
        for (Peak peak : matchedPeaks) {
          if (bestPeak == null) {
            bestPeak = peak;
            ionMatch.peak = peak;
            bestPeakError = Math.abs(ionMatch.getError(isPpm));
          } else {
            ionMatch.peak = peak;
            double peakError = Math.abs(ionMatch.getError(isPpm));
            if (peakError < bestPeakError) {
              bestPeak = peak;
              bestPeakError = peakError;
            } else if (peakError == bestPeakError && peak.intensity > bestPeak.intensity) {
              bestPeak = peak;
            }
          }
        }
        return bestPeak;
      case mostIntense:
        for (Peak peak : matchedPeaks) {
          if (bestPeak == null || peak.intensity > bestPeak.intensity) {
            bestPeak = peak;
          } else if (peak.intensity == bestPeak.intensity) {
            ionMatch.peak = bestPeak;
            bestPeakError = Math.abs(ionMatch.getError(isPpm));
            ionMatch.peak = peak;
            double peakError = Math.abs(ionMatch.getError(isPpm));
            if (peakError < bestPeakError) {
              bestPeak = peak;
            }
          }
        }
        return bestPeak;
      default:
        throw new UnsupportedOperationException(
            "Ties resolution method " + tiesResolution + " not implemented.");
    }
  }

  /**
   * Sets a new spectrum to annotate.
   *
   * @param spectrum the spectrum to inspect
   * @param intensityLimit the minimal intensity to account for
   */
  protected void setSpectrum(MSnSpectrum spectrum, double intensityLimit) {
    if (spectrumIndex == null
        || !spectrumKey.equals(spectrum.getSpectrumKey())
        || this.intensityLimit != intensityLimit) {

      // Save spectrum number and intensity limit
      spectrumKey = spectrum.getSpectrumKey();
      this.intensityLimit = intensityLimit;

      // See whether the index was previously stored
      spectrumIndex = new SpectrumIndex();
      spectrumIndex = (SpectrumIndex) spectrum.getUrParam(spectrumIndex);

      // Create new index
      spectrumIndex = new SpectrumIndex(spectrum.getPeakMap(), intensityLimit, mzTolerance, isPpm);
      spectrum.addUrParam(spectrumIndex);
    }
  }

  /**
   * Sets a new m/z tolerance for peak matching.
   *
   * @param mzTolerance the new m/z tolerance (in m/z, Th)
   * @param isPpm a boolean indicating whether the mass tolerance is in ppm or in Da
   * @param tiesResolution the method used to resolve ties
   */
  protected void setMassTolerance(
      double mzTolerance, boolean isPpm, TiesResolution tiesResolution) {
    if (mzTolerance != this.mzTolerance || tiesResolution != this.tiesResolution) {

      // Clear previous index
      spectrumIndex = null;

      // Save new values
      this.mzTolerance = mzTolerance;
      this.isPpm = isPpm;
      this.tiesResolution = tiesResolution;
    }
  }

  /**
   * Returns a boolean indicating whether the neutral loss should be accounted for.
   *
   * @param neutralLosses map of expected neutral losses
   * @param neutralLoss the neutral loss of interest
   * @param ion the fragment ion of interest
   * @return boolean indicating whether the neutral loss should be considered
   */
  public boolean isAccounted(NeutralLossesMap neutralLosses, NeutralLoss neutralLoss, Ion ion) {

    if (neutralLosses == null || neutralLosses.isEmpty()) {
      return false;
    }

    for (String neutralLossName : neutralLosses.getAccountedNeutralLosses()) {

      NeutralLoss neutralLossRef = NeutralLoss.getNeutralLoss(neutralLossName);

      if (neutralLoss.isSameAs(neutralLossRef)) {
        switch (ion.getType()) {
          case PEPTIDE_FRAGMENT_ION:
            PeptideFragmentIon peptideFragmentIon = ((PeptideFragmentIon) ion);
            switch (ion.getSubType()) {
              case PeptideFragmentIon.A_ION:
              case PeptideFragmentIon.B_ION:
              case PeptideFragmentIon.C_ION:
                return neutralLosses.getForwardStart(neutralLossName)
                    <= peptideFragmentIon.getNumber();
              case PeptideFragmentIon.X_ION:
              case PeptideFragmentIon.Y_ION:
              case PeptideFragmentIon.Z_ION:
                return neutralLosses.getRewindStart(neutralLossName)
                    <= peptideFragmentIon.getNumber();
              default:
                throw new UnsupportedOperationException(
                    "Fragment ion type "
                        + ion.getSubTypeAsString()
                        + " not implemented in the spectrum annotator.");
            }
          case TAG_FRAGMENT_ION:
            TagFragmentIon tagFragmentIon = ((TagFragmentIon) ion);
            switch (ion.getSubType()) {
              case TagFragmentIon.A_ION:
              case TagFragmentIon.B_ION:
              case TagFragmentIon.C_ION:
                return neutralLosses.getForwardStart(neutralLossName) <= tagFragmentIon.getNumber();
              case TagFragmentIon.X_ION:
              case TagFragmentIon.Y_ION:
              case TagFragmentIon.Z_ION:
                return neutralLosses.getRewindStart(neutralLossName) <= tagFragmentIon.getNumber();
              default:
                throw new UnsupportedOperationException(
                    "Fragment ion type "
                        + ion.getSubTypeAsString()
                        + " not implemented in the spectrum annotator.");
            }
          default:
            return true;
        }
      }
    }
    return false;
  }

  /**
   * Returns a boolean indicating whether the neutral losses of the given fragment ion fit the
   * requirement of the given neutral losses map.
   *
   * @param neutralLosses map of expected neutral losses: neutral loss
   * @param theoreticIon the ion of interest
   * @return a boolean indicating whether the neutral losses of the given fragment ion are fit the
   *     requirement of the given neutral losses map
   */
  public boolean lossesValidated(NeutralLossesMap neutralLosses, Ion theoreticIon) {
    if (theoreticIon.hasNeutralLosses()) {
      for (NeutralLoss neutralLoss : theoreticIon.getNeutralLosses()) {
        if (!isAccounted(neutralLosses, neutralLoss, theoreticIon)) {
          return false;
        }
      }
    }
    return true;
  }

  /**
   * Returns a boolean indicating whether the given charge can be found on the given fragment ion.
   *
   * @param theoreticIon the ion of interest
   * @param charge the candidate charge
   * @param precursorCharge the precursor charge
   * @return a boolean indicating whether the given charge can be found on the given fragment ion
   */
  public boolean chargeValidated(Ion theoreticIon, int charge, int precursorCharge) {
    if (charge == 1) {
      return true;
    }
    switch (theoreticIon.getType()) {
      case IMMONIUM_ION:
      case RELATED_ION: // note: it is possible to implement higher charges but then modify
                        // IonMatch.getPeakAnnotation(boolean html) as well to see the charge
                        // displayed on the spectrum
        return false;
      case REPORTER_ION: // note: it is possible to implement higher charges but then modify
                         // IonMatch.getPeakAnnotation(boolean html) as well to see the charge
                         // displayed on the spectrum
        return false;
      case PEPTIDE_FRAGMENT_ION:
        PeptideFragmentIon peptideFragmentIon = ((PeptideFragmentIon) theoreticIon);
        return charge <= peptideFragmentIon.getNumber() && charge < precursorCharge;
      case TAG_FRAGMENT_ION:
        TagFragmentIon tagFragmentIon = ((TagFragmentIon) theoreticIon);
        return charge <= tagFragmentIon.getNumber() && charge < precursorCharge;
      case PRECURSOR_ION:
        return charge >= precursorCharge;
      default:
        throw new UnsupportedOperationException(
            "Ion type "
                + theoreticIon.getTypeAsString()
                + " not implemented in the spectrum annotator.");
    }
  }

  /**
   * Returns the currently matched ions with the given settings.
   *
   * @param spectrum the spectrum of interest
   * @param annotationSettings the annotation settings
   * @param specificAnnotationSettings the specific annotation settings
   * @return the currently matched ions with the given settings
   */
  public abstract ArrayList<IonMatch> getCurrentAnnotation(
      MSnSpectrum spectrum,
      AnnotationSettings annotationSettings,
      SpecificAnnotationSettings specificAnnotationSettings);

  /**
   * Returns the spectrum currently inspected.
   *
   * @return the spectrum currently inspected
   */
  public String getCurrentlyLoadedSpectrumKey() {
    return spectrumKey;
  }

  /**
   * Returns the m/z shift applied to the fragment ions.
   *
   * @return the m/z shift applied to the fragment ions
   */
  public double getMassShift() {
    return massShift;
  }

  /**
   * Returns the N-terminal m/z shift applied to all forward ions.
   *
   * @return the N-terminal m/z shift applied to all forward ions
   */
  public double getMassShiftNTerm() {
    return massShiftNTerm;
  }

  /**
   * Returns the C-terminal m/z shift applied to all reverse ions.
   *
   * @return the C-terminal m/z shift applied to all reverse ions
   */
  public double getMassShiftCTerm() {
    return massShiftNTerm;
  }

  /**
   * Sets an m/z shift on all ions. The previous mass main shift will be removed.
   *
   * @param aMassShift the m/z shift to apply
   */
  public void setMassShift(double aMassShift) {
    this.massShift = aMassShift;
    updateMassShifts();
  }

  /**
   * Sets the m/z shifts. The previous mass shifts will be removed.
   *
   * @param aMassShift the m/z shift to apply
   * @param aMassShiftNTerm the n-terminal mass shift to apply to all forward ions
   * @param aMassShiftCTerm the c-terminal mass shift to apply to all reverse ions
   */
  public void setMassShifts(double aMassShift, double aMassShiftNTerm, double aMassShiftCTerm) {
    this.massShift = aMassShift;
    this.massShiftNTerm = aMassShiftNTerm;
    this.massShiftCTerm = aMassShiftCTerm;
    updateMassShifts();
  }

  /**
   * Sets the terminal m/z shifts.
   *
   * @param aMassShiftNTerm the n-terminal mass shift to apply to all forward ions
   * @param aMassShiftCTerm the c-terminal mass shift to apply to all reverse ions
   */
  public void setTerminalMassShifts(double aMassShiftNTerm, double aMassShiftCTerm) {
    this.massShiftNTerm = aMassShiftNTerm;
    this.massShiftCTerm = aMassShiftCTerm;
    updateMassShifts();
  }

  /** Updates the mass shifts. */
  protected void updateMassShifts() {
    if (theoreticalFragmentIons != null) {
      HashMap<Integer, ArrayList<Ion>> peptideFragmentIons =
          theoreticalFragmentIons.get(IonType.PEPTIDE_FRAGMENT_ION.index);
      ArrayList<Ion> ions = peptideFragmentIons.get(PeptideFragmentIon.A_ION);
      if (ions != null) {
        for (Ion ion : ions) {
          ion.setTheoreticMass(ion.getTheoreticMass() + massShift + massShiftNTerm);
        }
      }
      ions = peptideFragmentIons.get(PeptideFragmentIon.B_ION);
      if (ions != null) {
        for (Ion ion : ions) {
          ion.setTheoreticMass(ion.getTheoreticMass() + massShift + massShiftNTerm);
        }
      }
      ions = peptideFragmentIons.get(PeptideFragmentIon.C_ION);
      if (ions != null) {
        for (Ion ion : ions) {
          ion.setTheoreticMass(ion.getTheoreticMass() + massShift + massShiftNTerm);
        }
      }
      ions = peptideFragmentIons.get(PeptideFragmentIon.X_ION);
      if (ions != null) {
        for (Ion ion : ions) {
          ion.setTheoreticMass(ion.getTheoreticMass() + massShift + massShiftCTerm);
        }
      }
      ions = peptideFragmentIons.get(PeptideFragmentIon.Y_ION);
      if (ions != null) {
        for (Ion ion : ions) {
          ion.setTheoreticMass(ion.getTheoreticMass() + massShift + massShiftCTerm);
        }
      }
      ions = peptideFragmentIons.get(PeptideFragmentIon.Z_ION);
      if (ions != null) {
        for (Ion ion : ions) {
          ion.setTheoreticMass(ion.getTheoreticMass() + massShift + massShiftCTerm);
        }
      }

      HashMap<Integer, ArrayList<Ion>> tagFragmentIons =
          theoreticalFragmentIons.get(IonType.TAG_FRAGMENT_ION.index);
      ions = tagFragmentIons.get(TagFragmentIon.A_ION);
      if (ions != null) {
        for (Ion ion : ions) {
          ion.setTheoreticMass(ion.getTheoreticMass() + massShift + massShiftNTerm);
        }
      }
      ions = tagFragmentIons.get(TagFragmentIon.B_ION);
      if (ions != null) {
        for (Ion ion : ions) {
          ion.setTheoreticMass(ion.getTheoreticMass() + massShift + massShiftNTerm);
        }
      }
      ions = tagFragmentIons.get(TagFragmentIon.C_ION);
      if (ions != null) {
        for (Ion ion : ions) {
          ion.setTheoreticMass(ion.getTheoreticMass() + massShift + massShiftNTerm);
        }
      }
      ions = tagFragmentIons.get(TagFragmentIon.X_ION);
      if (ions != null) {
        for (Ion ion : ions) {
          ion.setTheoreticMass(ion.getTheoreticMass() + massShift + massShiftCTerm);
        }
      }
      ions = tagFragmentIons.get(TagFragmentIon.Y_ION);
      if (ions != null) {
        for (Ion ion : ions) {
          ion.setTheoreticMass(ion.getTheoreticMass() + massShift + massShiftCTerm);
        }
      }
      ions = tagFragmentIons.get(TagFragmentIon.Z_ION);
      if (ions != null) {
        for (Ion ion : ions) {
          ion.setTheoreticMass(ion.getTheoreticMass() + massShift + massShiftCTerm);
        }
      }
    }
  }

  /**
   * Returns the possible neutral losses expected by default for a given peptide. /!\ this method
   * will work only if the PTM found in the peptide are in the PTMFactory.
   *
   * @param spectrumIdentificationAssumption the spectrumIdentificationAssumption of interest
   * @param sequenceMatchingPreferences the sequence matching settings for peptide to protein
   *     mapping
   * @param ptmSequenceMatchingPreferences the sequence matching settings for PTM to peptide mapping
   * @return the expected possible neutral losses
   * @throws IOException exception thrown whenever an error occurred while interacting with a file
   *     while mapping potential modification sites
   * @throws InterruptedException exception thrown whenever a threading issue occurred while mapping
   *     potential modification sites
   * @throws ClassNotFoundException exception thrown whenever an error occurred while deserializing
   *     an object from the ProteinTree
   * @throws SQLException exception thrown whenever an error occurred while interacting with the
   *     ProteinTree
   */
  public static NeutralLossesMap getDefaultLosses(
      SpectrumIdentificationAssumption spectrumIdentificationAssumption,
      SequenceMatchingPreferences sequenceMatchingPreferences,
      SequenceMatchingPreferences ptmSequenceMatchingPreferences)
      throws IOException, InterruptedException, ClassNotFoundException, SQLException {
    if (spectrumIdentificationAssumption instanceof PeptideAssumption) {
      PeptideAssumption peptideAssumption = (PeptideAssumption) spectrumIdentificationAssumption;
      return PeptideSpectrumAnnotator.getDefaultLosses(
          peptideAssumption.getPeptide(),
          sequenceMatchingPreferences,
          ptmSequenceMatchingPreferences);
    } else if (spectrumIdentificationAssumption instanceof TagAssumption) {
      TagAssumption tagAssumption = (TagAssumption) spectrumIdentificationAssumption;
      return TagSpectrumAnnotator.getDefaultLosses(
          tagAssumption.getTag(), ptmSequenceMatchingPreferences);
    } else {
      throw new IllegalArgumentException(
          "Default neutral loss map not implemented for SpectrumIdentificationAssumption "
              + spectrumIdentificationAssumption.getClass()
              + ".");
    }
  }

  /**
   * This method matches the potential fragment ions of a given peptide with a given peak. Note:
   * fragment ions need to be initiated by the SpectrumAnnotator extending class.
   *
   * @param specificAnnotationSettings the specific annotation settings
   * @param peak The peak to match
   * @return A list of potential ion matches
   */
  protected ArrayList<IonMatch> matchPeak(
      SpecificAnnotationSettings specificAnnotationSettings, Peak peak) {

    ArrayList<IonMatch> result = new ArrayList<IonMatch>();

    HashMap<Ion.IonType, HashSet<Integer>> ionTypes = specificAnnotationSettings.getIonTypes();
    for (Ion.IonType ionType : ionTypes.keySet()) {
      HashMap<Integer, ArrayList<Ion>> ionMap = theoreticalFragmentIons.get(ionType.index);
      if (ionMap != null) {
        HashSet<Integer> subtypes = ionTypes.get(ionType);
        for (int subType : subtypes) {
          ArrayList<Ion> ions = ionMap.get(subType);
          if (ions != null) {
            for (Ion ion : ions) {
              for (int charge : specificAnnotationSettings.getSelectedCharges()) {
                if (chargeValidated(ion, charge, specificAnnotationSettings.getPrecursorCharge())
                    && lossesValidated(specificAnnotationSettings.getNeutralLossesMap(), ion)) {
                  IonMatch ionMatch = new IonMatch(peak, ion, charge);
                  if (Math.abs(
                          ionMatch.getError(
                              specificAnnotationSettings.isFragmentIonPpm(),
                              minIsotopicCorrection,
                              maxIsotopicCorrection))
                      <= specificAnnotationSettings.getFragmentIonAccuracy()) {
                    result.add(ionMatch);
                  }
                }
              }
            }
          }
        }
      }
    }

    return result;
  }

  /**
   * Returns the expected ions in a map indexed by the possible charges.
   *
   * <p>Note that, except for +1 precursors, fragments ions will be expected to have a charge
   * strictly smaller than the precursor ion charge.
   *
   * <p>Note: fragment ions need to be initiated by the SpectrumAnnotator extending class.
   *
   * @param specificAnnotationSettings the specific annotation settings
   * @return an ArrayList of IonMatch containing the ion matches with the given settings
   */
  protected HashMap<Integer, ArrayList<Ion>> getExpectedIons(
      SpecificAnnotationSettings specificAnnotationSettings) {

    HashMap<Integer, ArrayList<Ion>> result = new HashMap<Integer, ArrayList<Ion>>();

    HashMap<Ion.IonType, HashSet<Integer>> ionTypes = specificAnnotationSettings.getIonTypes();
    for (Ion.IonType ionType : ionTypes.keySet()) {
      HashMap<Integer, ArrayList<Ion>> ionMap = theoreticalFragmentIons.get(ionType.index);
      if (ionMap != null) {
        HashSet<Integer> subtypes = ionTypes.get(ionType);
        for (int subType : subtypes) {
          ArrayList<Ion> ions = ionMap.get(subType);
          if (ions != null) {
            for (Ion ion : ions) {
              if (lossesValidated(specificAnnotationSettings.getNeutralLossesMap(), ion)) {
                for (int charge : specificAnnotationSettings.getSelectedCharges()) {
                  if (chargeValidated(ion, charge, precursorCharge)) {
                    ArrayList<Ion> resultsAtCharge = result.get(charge);
                    if (resultsAtCharge == null) {
                      resultsAtCharge = new ArrayList<Ion>();
                      result.put(charge, resultsAtCharge);
                    }
                    resultsAtCharge.add(ion);
                  }
                }
              }
            }
          }
        }
      }
    }

    return result;
  }

  /**
   * Convenience method to match a reporter ion in a spectrum. The charge is assumed to be 1.
   *
   * @param theoreticIon the theoretic ion to look for
   * @param charge the charge of the ion
   * @param spectrum the spectrum
   * @param massTolerance the mass tolerance to use
   * @return a list of all the ion matches
   * @throws java.lang.InterruptedException exception thrown if the thread is interrupted
   */
  public static ArrayList<IonMatch> matchReporterIon(
      Ion theoreticIon, int charge, Spectrum spectrum, double massTolerance)
      throws InterruptedException {
    ArrayList<IonMatch> result = new ArrayList<IonMatch>(1);
    double targetMass = theoreticIon.getTheoreticMz(charge);
    for (double mz : spectrum.getOrderedMzValues()) {
      if (Math.abs(mz - targetMass) <= massTolerance) {
        result.add(new IonMatch(spectrum.getPeakMap().get(mz), theoreticIon, charge));
      }
      if (mz > targetMass + massTolerance) {
        break;
      }
    }
    return result;
  }
}
Пример #3
0
  public void importPeptideShakerFile(File aPsFile, final String resource) {

    this.resource = resource;
    this.currentPSFile = aPsFile;
    loadGeneMapping();
    loadEnzymes();
    resetPtmFactory();
    // setDefaultPreferences(); // @TODO: i tried re-adding this but then we get a null pointer, but
    // the two below have to be added or the default neutral losses won't appear
    IonFactory.getInstance().addDefaultNeutralLoss(NeutralLoss.H2O);
    IonFactory.getInstance().addDefaultNeutralLoss(NeutralLoss.NH3);

    // exceptionHandler = new ExceptionHandler(this);

    new Thread("ProgressThread") {
      @Override
      public void run() {
        jprog.setValue(10);
      }
    }.start();

    Thread importThread =
        new Thread("ImportThread") {
          @Override
          public void run() {
            try {
              // reset enzymes, ptms and preferences
              loadEnzymes();
              resetPtmFactory();
              setDefaultPreferences();
              try {
                // close any open connection to an identification database
                if (identification != null) {
                  identification.close();
                }
              } catch (Exception e) {
                e.printStackTrace();
              }
              File experimentFile =
                  new File(
                      PeptideShaker.SERIALIZATION_DIRECTORY, PeptideShaker.experimentObjectName);
              File matchFolder = new File(PeptideShaker.SERIALIZATION_DIRECTORY);
              // empty the existing files in the matches folder
              if (matchFolder.exists()) {
                for (File file : matchFolder.listFiles()) {
                  if (file.isDirectory()) {
                    boolean deleted = Util.deleteDir(file);

                    if (!deleted) {
                      System.out.println("Failed to delete folder: " + file.getPath());
                    }
                  } else {
                    boolean deleted = file.delete();

                    if (!deleted) {
                      System.out.println("Failed to delete file: " + file.getPath());
                    }
                  }
                }
              }
              final int BUFFER = 2048;
              byte data[] = new byte[BUFFER];
              FileInputStream fi = new FileInputStream(currentPSFile);
              BufferedInputStream bis = new BufferedInputStream(fi, BUFFER);
              try {
                ArchiveInputStream tarInput =
                    new ArchiveStreamFactory().createArchiveInputStream(bis);
                ArchiveEntry archiveEntry;

                while ((archiveEntry = tarInput.getNextEntry()) != null) {
                  File destinationFile = new File(archiveEntry.getName());
                  File destinationFolder = destinationFile.getParentFile();
                  boolean destFolderExists = true;
                  if (!destinationFolder.exists()) {
                    destFolderExists = destinationFolder.mkdirs();
                  }
                  if (destFolderExists) {
                    FileOutputStream fos = new FileOutputStream(destinationFile);
                    BufferedOutputStream bos = new BufferedOutputStream(fos);
                    int count;
                    while ((count = tarInput.read(data, 0, BUFFER)) != -1
                        && !progressDialog.isRunCanceled()) {
                      bos.write(data, 0, count);
                    }

                    bos.close();
                    fos.close();

                    //	                                int progress = (int) (100 *
                    // tarInput.getBytesRead() / fileLength);
                    //	                               progressDialog.setValue(progress);
                  } else {
                    System.out.println(
                        "Folder does not exist: \'"
                            + destinationFolder.getAbsolutePath()
                            + "\'. User preferences not saved.");
                  }
                }
                tarInput.close();
              } catch (ArchiveException e) {
                // Most likely an old project
                experimentFile = currentPSFile;
                e.printStackTrace();
              }
              fi.close();
              bis.close();
              fi.close();

              MsExperiment tempExperiment = ExperimentIO.loadExperiment(experimentFile);
              Sample tempSample = null;
              PeptideShakerSettings experimentSettings = new PeptideShakerSettings();
              if (tempExperiment.getUrParam(experimentSettings) instanceof PSSettings) {
                // convert old settings files using utilities version 3.10.68 or older
                // convert the old ProcessingPreferences object
                PSSettings tempSettings =
                    (PSSettings) tempExperiment.getUrParam(experimentSettings);
                ProcessingPreferences tempProcessingPreferences = new ProcessingPreferences();
                tempProcessingPreferences.setProteinFDR(
                    tempSettings.getProcessingPreferences().getProteinFDR());
                tempProcessingPreferences.setPeptideFDR(
                    tempSettings.getProcessingPreferences().getPeptideFDR());
                tempProcessingPreferences.setPsmFDR(
                    tempSettings.getProcessingPreferences().getPsmFDR());
                // convert the old PTMScoringPreferences object
                PTMScoringPreferences tempPTMScoringPreferences = new PTMScoringPreferences();
                tempPTMScoringPreferences.setaScoreCalculation(
                    tempSettings.getPTMScoringPreferences().aScoreCalculation());
                tempPTMScoringPreferences.setaScoreNeutralLosses(
                    tempSettings.getPTMScoringPreferences().isaScoreNeutralLosses());
                tempPTMScoringPreferences.setFlrThreshold(
                    tempSettings.getPTMScoringPreferences().getFlrThreshold());
                // missing gene refrences
                GenePreferences genePreferences = getGenePreferences();
                //     String selectedSpecies = genePreferences.getCurrentSpecies();
                //    String speciesDatabase =
                // genePreferences.getEnsemblDatabaseName(selectedSpecies);

                experimentSettings =
                    new PeptideShakerSettings(
                        tempSettings.getSearchParameters(),
                        tempSettings.getAnnotationPreferences(),
                        tempSettings.getSpectrumCountingPreferences(),
                        tempSettings.getProjectDetails(),
                        tempSettings.getFilterPreferences(),
                        tempSettings.getDisplayPreferences(),
                        tempSettings.getMetrics(),
                        tempProcessingPreferences,
                        tempSettings.getIdentificationFeaturesCache(),
                        tempPTMScoringPreferences,
                        genePreferences,
                        new IdFilter());
                ;
              } else {
                experimentSettings =
                    (PeptideShakerSettings) tempExperiment.getUrParam(experimentSettings);
              }

              idFilter = experimentSettings.getIdFilter();
              setAnnotationPreferences(experimentSettings.getAnnotationPreferences());
              setSpectrumCountingPreferences(experimentSettings.getSpectrumCountingPreferences());
              setPtmScoringPreferences(experimentSettings.getPTMScoringPreferences());
              setProjectDetails(experimentSettings.getProjectDetails());
              setSearchParameters(experimentSettings.getSearchParameters());
              setProcessingPreferences(experimentSettings.getProcessingPreferences());
              setMetrics(experimentSettings.getMetrics());
              setDisplayPreferences(experimentSettings.getDisplayPreferences());

              if (experimentSettings.getFilterPreferences() != null) {
                setFilterPreferences(experimentSettings.getFilterPreferences());
              } else {
                setFilterPreferences(new FilterPreferences());
              }
              if (experimentSettings.getDisplayPreferences() != null) {
                setDisplayPreferences(experimentSettings.getDisplayPreferences());
                displayPreferences.compatibilityCheck(searchParameters.getModificationProfile());
              } else {
                setDisplayPreferences(new DisplayPreferences());
                displayPreferences.setDefaultSelection(searchParameters.getModificationProfile());
              }
              ArrayList<Sample> samples = new ArrayList(tempExperiment.getSamples().values());

              if (samples.size() == 1) {
                tempSample = samples.get(0);
              } else {
                tempSample = samples.get(0);
                String[] sampleNames = new String[samples.size()];
                for (int cpt = 0; cpt < sampleNames.length; cpt++) {
                  sampleNames[cpt] = samples.get(cpt).getReference();
                  System.out.println(sampleNames[cpt]);
                }
                SampleSelection sampleSelection =
                    new SampleSelection(null, true, sampleNames, "sample");
                sampleSelection.setVisible(false);
                String choice = sampleSelection.getChoice();
                for (Sample sampleTemp : samples) {
                  if (sampleTemp.getReference().equals(choice)) {
                    tempSample = sampleTemp;
                    break;
                  }
                }
              }

              ArrayList<Integer> replicates =
                  new ArrayList(tempExperiment.getAnalysisSet(tempSample).getReplicateNumberList());

              System.out.println(replicates);
              int tempReplicate;

              if (replicates.size() == 1) {
                tempReplicate = replicates.get(0);
              } else {
                String[] replicateNames = new String[replicates.size()];
                for (int cpt = 0; cpt < replicateNames.length; cpt++) {
                  replicateNames[cpt] = samples.get(cpt).getReference();
                }
                SampleSelection sampleSelection =
                    new SampleSelection(null, true, replicateNames, "replicate");
                sampleSelection.setVisible(false);
                Integer choice = new Integer(sampleSelection.getChoice());
                tempReplicate = 0;
              }

              setProject(tempExperiment, tempSample, tempReplicate);

              identificationFeaturesGenerator =
                  new IdentificationFeaturesGenerator(
                      identification,
                      searchParameters,
                      idFilter,
                      metrics,
                      spectrumCountingPreferences);
              if (experimentSettings.getIdentificationFeaturesCache() != null) {
                identificationFeaturesGenerator.setIdentificationFeaturesCache(
                    experimentSettings.getIdentificationFeaturesCache());
              }

              //	                    mainProgressDialog.setTitle("Loading FASTA File. Please
              // Wait...");

              try {
                File providedFastaLocation =
                    experimentSettings.getSearchParameters().getFastaFile();
                String fileName = providedFastaLocation.getName();
                File projectFolder = currentPSFile.getParentFile();
                File dataFolder = new File(projectFolder, "data");

                // try to locate the FASTA file
                if (providedFastaLocation.exists()) {
                  SequenceFactory.getInstance().loadFastaFile(providedFastaLocation);
                } else if (new File(projectFolder, fileName).exists()) {
                  SequenceFactory.getInstance().loadFastaFile(new File(projectFolder, fileName));
                  experimentSettings
                      .getSearchParameters()
                      .setFastaFile(new File(projectFolder, fileName));
                } else if (new File(dataFolder, fileName).exists()) {
                  SequenceFactory.getInstance().loadFastaFile(new File(dataFolder, fileName));
                  experimentSettings
                      .getSearchParameters()
                      .setFastaFile(new File(dataFolder, fileName));
                } else {
                  // return error

                  System.out.println("fastafile is missing");
                }
              } catch (Exception e) {
                e.printStackTrace();
                System.out.println("fastafile is missing");
              }

              //	                 mainProgressDialog.setTitle("Locating Spectrum Files. Please
              // Wait...");

              for (String spectrumFileName : identification.getSpectrumFiles()) {

                try {
                  File providedSpectrumLocation = projectDetails.getSpectrumFile(spectrumFileName);
                  // try to locate the spectrum file
                  if (providedSpectrumLocation == null || !providedSpectrumLocation.exists()) {
                    File projectFolder = currentPSFile.getParentFile();
                    File fileInProjectFolder = new File(projectFolder, spectrumFileName);
                    File dataFolder = new File(projectFolder, "data");
                    File fileInDataFolder = new File(dataFolder, spectrumFileName);
                    File fileInLastSelectedFolder =
                        new File(getLastSelectedFolder(), spectrumFileName);
                    if (fileInProjectFolder.exists()) {
                      projectDetails.addSpectrumFile(fileInProjectFolder);
                    } else if (fileInDataFolder.exists()) {
                      projectDetails.addSpectrumFile(fileInDataFolder);
                    } else if (fileInLastSelectedFolder.exists()) {
                      projectDetails.addSpectrumFile(fileInLastSelectedFolder);
                    } else {

                      System.out.println("error no file");
                    }
                  }
                } catch (Exception e) {
                  clearData(true);
                  // clearPreferences();
                  e.printStackTrace();
                  System.out.println("error no file");
                  return;
                }
              }

              objectsCache = new ObjectsCache();
              objectsCache.setAutomatedMemoryManagement(true);

              if (identification.isDB()) {
                try {
                  String dbFolder =
                      new File(resource, PeptideShaker.SERIALIZATION_DIRECTORY).getAbsolutePath();
                  identification.establishConnection(dbFolder, false, objectsCache);
                } catch (Exception e) {
                  e.printStackTrace();
                }
              } else {
                updateAnnotationPreferencesFromSearchSettings();
                annotationPreferences.useAutomaticAnnotation(true);
              }

              int cpt = 1, nfiles = identification.getSpectrumFiles().size();
              for (String fileName : identification.getSpectrumFiles()) {

                //                             mainProgressDialog.setTitle("Importing Spectrum
                // Files. Please Wait...");
                try {
                  File mgfFile = projectDetails.getSpectrumFile(fileName);
                  spectrumFactory.addSpectra(mgfFile, progressDialog);
                } catch (Exception e) {
                  clearData(true);
                  e.printStackTrace();
                  return;
                }
              }
              boolean compatibilityIssue =
                  getSearchParameters().getIonSearched1() == null
                      || getSearchParameters().getIonSearched2() == null;

              if (compatibilityIssue) {
                JOptionPane.showMessageDialog(
                    null,
                    "The annotation preferences for this project may have changed.\n\n"
                        + "Note that PeptideShaker has substancially improved, we strongly\n"
                        + "recommend reprocessing your identification files.",
                    "Annotation Preferences",
                    JOptionPane.INFORMATION_MESSAGE);
                updateAnnotationPreferencesFromSearchSettings();
              }

              if (identification.getSpectrumIdentificationMap() == null) {
                // 0.18 version, needs update of the spectrum mapping
                identification.updateSpectrumMapping();
              }
            } catch (OutOfMemoryError error) {
              System.out.println(
                  "Ran out of memory! (runtime.maxMemory(): "
                      + Runtime.getRuntime().maxMemory()
                      + ")");
              Runtime.getRuntime().gc();
              JOptionPane.showMessageDialog(
                  null,
                  "The task used up all the available memory and had to be stopped.\n"
                      + "Memory boundaries are set in ../resources/conf/JavaOptions.txt.",
                  "Out Of Memory Error",
                  JOptionPane.ERROR_MESSAGE);
              error.printStackTrace();
            } catch (Exception exp) {
              exp.printStackTrace();
            }
          }
        };
    importThread.setPriority(Thread.MAX_PRIORITY);
    //        importThread.start();
    //        while (importThread.isAlive()) {
    //            try {
    //                Thread.currentThread().sleep(100);
    //
    //            } catch (Exception e) {
    //                e.printStackTrace();
    //            }
    //        }
    ExecutorService es = Executors.newCachedThreadPool();
    es.execute(importThread);
    es.shutdown();
    try {
      boolean finshed = es.awaitTermination(1, TimeUnit.DAYS);
      System.gc();
      return;

      //        t.start();
    } catch (InterruptedException ex) {
      System.err.println(ex.getMessage());
      // Logger.getLogger(UpdatedOutputGenerator.class.getName()).log(Level.SEVERE, null, ex);
    }
    System.gc();
    //        return;

  }