/**
   * Returns a list of descriptions corresponding to every item matching the search.
   *
   * @return a list of descriptions
   * @throws SQLException thrown if an SQLException occurs
   * @throws ClassNotFoundException thrown if a ClassNotFoundException occurs
   * @throws IOException thrown if an IOException occurs
   * @throws InterruptedException thrown if an InterruptedException occurs
   */
  public ArrayList<String> getPossibilitiesDescriptions()
      throws SQLException, ClassNotFoundException, IOException, InterruptedException {

    Identification identification = peptideShakerGUI.getIdentification();

    // Some necessary pre-caching
    ArrayList<Type> typeList = types.get(jumpType);
    ArrayList<String> keys = possibilities.get(jumpType),
        proteinKeys = new ArrayList<String>(),
        peptideKeys = new ArrayList<String>();
    for (int i = 0; i < keys.size(); i++) {
      String key = keys.get(i);
      if (typeList.get(i) == Type.PROTEIN) {
        proteinKeys.add(key);
      } else if (typeList.get(i) == Type.PEPTIDE) {
        peptideKeys.add(key);
      }
    }
    if (!proteinKeys.isEmpty()) {
      identification.loadProteinMatches(proteinKeys, null, false);
    }
    if (!peptideKeys.isEmpty()) {
      identification.loadPeptideMatches(peptideKeys, null, false);
    }

    ArrayList<String> descriptions = new ArrayList<String>();
    for (int i = 0; i < keys.size(); i++) {
      String key = keys.get(i);
      Type type = typeList.get(i);
      String description = getItemDescription(key, type);
      descriptions.add(description);
    }
    return descriptions;
  }
 /**
  * Returns the description of an item.
  *
  * @param key the key of the item
  * @param itemType the type of the item
  * @return the description of an item
  * @throws SQLException thrown if an SQLException occurs
  * @throws ClassNotFoundException thrown if a ClassNotFoundException occurs
  * @throws IOException thrown if an IOException occurs
  * @throws InterruptedException thrown if an InterruptedException occurs
  */
 private String getItemDescription(String key, Type itemType)
     throws IllegalArgumentException, SQLException, IOException, ClassNotFoundException,
         InterruptedException {
   Identification identification = peptideShakerGUI.getIdentification();
   switch (itemType) {
     case PROTEIN:
       ProteinMatch proteinMatch = identification.getProteinMatch(key);
       String mainMatch = proteinMatch.getMainMatch();
       String description = sequenceFactory.getHeader(mainMatch).getSimpleProteinDescription();
       String result = mainMatch;
       for (String accession : ProteinMatch.getAccessions(key)) {
         if (!accession.equals(mainMatch)) {
           if (!result.equals(mainMatch)) {
             result += ", ";
           }
           result += accession;
         }
       }
       result += " - " + description;
       return result;
     case PEPTIDE:
       PeptideMatch peptideMatch = identification.getPeptideMatch(key);
       return peptideShakerGUI
           .getDisplayFeaturesGenerator()
           .getTaggedPeptideSequence(peptideMatch, true, true, true);
     case SPECTRUM:
       return Spectrum.getSpectrumTitle(key) + " (" + Spectrum.getSpectrumFile(key) + ")";
     default:
       return "Unknown";
   }
 }
  /**
   * Update the protein table according to the protein inference selection.
   *
   * @param evt
   */
  private void okButtonActionPerformed(
      java.awt.event.ActionEvent evt) { // GEN-FIRST:event_okButtonActionPerformed

    PSParameter psParameter = new PSParameter();

    try {
      psParameter =
          (PSParameter)
              identification.getProteinMatchParameter(inspectedMatch.getKey(), psParameter);
    } catch (Exception e) {
      peptideShakerGUI.catchException(e);
      this.dispose();
      return;
    }
    if (!inspectedMatch.getMainMatch().equals(previousMainMatch)
        || groupClassJComboBox.getSelectedIndex() != psParameter.getGroupClass()) {
      try {
        psParameter.setGroupClass(groupClassJComboBox.getSelectedIndex());
        identification.updateProteinMatchParameter(inspectedMatch.getKey(), psParameter);
        peptideShakerGUI.updateMainMatch(
            inspectedMatch.getMainMatch(), groupClassJComboBox.getSelectedIndex());
      } catch (Exception e) {
        peptideShakerGUI.catchException(e);
      }
      peptideShakerGUI.setDataSaved(false);
    }
    this.dispose();
  } // GEN-LAST:event_okButtonActionPerformed
 @Override
 public boolean isValidated(
     String itemName,
     FilterItemComparator filterItemComparator,
     Object value,
     String spectrumKey,
     Identification identification,
     GeneMaps geneMaps,
     IdentificationFeaturesGenerator identificationFeaturesGenerator,
     IdentificationParameters identificationParameters,
     PeptideSpectrumAnnotator peptideSpectrumAnnotator)
     throws IOException, InterruptedException, ClassNotFoundException, SQLException,
         MzMLUnmarshallerException, MathException {
   SpectrumMatch spectrumMatch = identification.getSpectrumMatch(spectrumKey);
   PeptideAssumption peptideAssumption = spectrumMatch.getBestPeptideAssumption();
   return isValidated(
       itemName,
       filterItemComparator,
       value,
       spectrumKey,
       peptideAssumption,
       identification,
       identificationFeaturesGenerator,
       identificationParameters,
       peptideSpectrumAnnotator);
 }
Example #5
0
 /**
  * Returns the description of an item.
  *
  * @param key the key of the item
  * @param itemType the type of the item
  * @return the description of an item
  * @throws SQLException thrown if an SQLException occurs
  * @throws ClassNotFoundException thrown if a ClassNotFoundException occurs
  * @throws IOException thrown if an IOException occurs
  * @throws InterruptedException thrown if an InterruptedException occurs
  */
 private String getItemDescription(String key, Type itemType)
     throws IllegalArgumentException, SQLException, IOException, ClassNotFoundException,
         InterruptedException {
   Identification identification = reporterGUI.getIdentification();
   switch (itemType) {
     case PROTEIN:
       ProteinMatch proteinMatch = identification.getProteinMatch(key);
       String mainMatch = proteinMatch.getMainMatch();
       String description = sequenceFactory.getHeader(mainMatch).getSimpleProteinDescription();
       String result = mainMatch;
       for (String accession : ProteinMatch.getAccessions(key)) {
         if (!accession.equals(mainMatch)) {
           if (!result.equals(mainMatch)) {
             result += ", ";
           }
           result += accession;
         }
       }
       result += " - " + description;
       return result;
     default:
       return "Unknown";
   }
 }
  /**
   * Sets the main match if the main match column is selected, or opens the protein web link if the
   * accession number column is selected.
   *
   * @param evt
   */
  private void proteinMatchTableMouseReleased(
      java.awt.event.MouseEvent evt) { // GEN-FIRST:event_proteinMatchTableMouseReleased

    int row = proteinMatchTable.rowAtPoint(evt.getPoint());
    int column = proteinMatchTable.columnAtPoint(evt.getPoint());

    if (row != -1) {

      if (column == 1) {
        try {
          inspectedMatch.setMainMatch(accessions.get(row));
          identification.updateProteinMatch(inspectedMatch);
          peptideShakerGUI
              .getIdentificationFeaturesGenerator()
              .updateCoverableAA(inspectedMatch.getKey());
          peptideShakerGUI
              .getIdentificationFeaturesGenerator()
              .updateSequenceCoverage(inspectedMatch.getKey());
          peptideShakerGUI
              .getIdentificationFeaturesGenerator()
              .updateObservableCoverage(inspectedMatch.getKey());
        } catch (Exception e) {
          peptideShakerGUI.catchException(e);
        }
        proteinMatchTable.revalidate();
        proteinMatchTable.repaint();
      } else if (column == 2) {

        // open protein link in web browser
        if (evt.getButton() == MouseEvent.BUTTON1
            && ((String) proteinMatchTable.getValueAt(row, column)).lastIndexOf("<html>") != -1) {

          String link = (String) proteinMatchTable.getValueAt(row, column);
          link = link.substring(link.indexOf("\"") + 1);
          link = link.substring(0, link.indexOf("\""));

          this.setCursor(new java.awt.Cursor(java.awt.Cursor.WAIT_CURSOR));
          BareBonesBrowserLaunch.openURL(link);
          this.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        }
      }
    }
  } // GEN-LAST:event_proteinMatchTableMouseReleased
  /** Clears the database folder. */
  private void clearDatabaseFolder() {

    boolean databaseClosed = true;

    // close the database connection
    if (identification != null) {

      try {
        identification.close();
        identification = null;
      } catch (SQLException e) {
        databaseClosed = false;
        e.printStackTrace();
        JOptionPane.showMessageDialog(
            null, "Failed to close the database.", "Database Error", JOptionPane.WARNING_MESSAGE);
      }
    }

    // empty the matches folder
    if (databaseClosed) {
      File matchFolder = new File(resource, PeptideShaker.SERIALIZATION_DIRECTORY);

      if (matchFolder.exists()) {

        File[] tempFiles = matchFolder.listFiles();

        if (tempFiles != null) {
          for (File currentFile : tempFiles) {
            Util.deleteDir(currentFile);
          }
        }

        if (matchFolder.listFiles() != null && matchFolder.listFiles().length > 0) {
          JOptionPane.showMessageDialog(
              null,
              "Failed to empty the database folder:\n" + matchFolder.getPath() + ".",
              "Database Cleanup Failed",
              JOptionPane.WARNING_MESSAGE);
        }
      }
    }
  }
  /**
   * Returns the modifications found in this project.
   *
   * @return the modifications found in this project
   */
  public ArrayList<String> getFoundModifications() {
    if (identifiedModifications == null) {
      identifiedModifications = new ArrayList<String>();
      for (String peptideKey : identification.getPeptideIdentification()) {

        boolean modified = false;

        for (String modificationName : Peptide.getModificationFamily(peptideKey)) {
          if (!identifiedModifications.contains(modificationName)) {
            identifiedModifications.add(modificationName);
            modified = true;
          }
        }
        if (!modified && !identifiedModifications.contains(PtmPanel.NO_MODIFICATION)) {
          identifiedModifications.add(PtmPanel.NO_MODIFICATION);
        }
      }
    }
    return identifiedModifications;
  }
  /**
   * Creates new form ProteinInferenceDialog.
   *
   * @param peptideShakerGUI
   * @param inspectedMatch
   * @param identification
   */
  public ProteinInferenceDialog(
      PeptideShakerGUI peptideShakerGUI, String inspectedMatch, Identification identification) {
    super(peptideShakerGUI, true);
    this.identification = identification;
    this.peptideShakerGUI = peptideShakerGUI;

    try {
      this.inspectedMatch = identification.getProteinMatch(inspectedMatch);
      previousMainMatch = this.inspectedMatch.getMainMatch();
    } catch (Exception e) {
      peptideShakerGUI.catchException(e);
      this.dispose();
    }

    accessions = new ArrayList(Arrays.asList(ProteinMatch.getAccessions(inspectedMatch)));

    for (String proteinAccession : accessions) {
      if (identification.getProteinIdentification().contains(proteinAccession)) {
        uniqueMatches.add(proteinAccession);
      }
    }

    for (String proteinKey : identification.getProteinIdentification()) {
      if (ProteinMatch.getNProteins(proteinKey) > 1
          && !associatedMatches.contains(proteinKey)
          && !proteinKey.equals(inspectedMatch)) {
        for (String proteinAccession : accessions) {
          if (proteinKey.contains(proteinAccession)) {
            associatedMatches.add(proteinKey);
            break;
          }
        }
      }
    }

    initComponents();

    // make sure that the scroll panes are see-through
    proteinMatchJScrollPane.getViewport().setOpaque(false);
    uniqueHitsJScrollPane.getViewport().setOpaque(false);
    relatedHitsJScrollPane.getViewport().setOpaque(false);

    groupClassJComboBox.setRenderer(new AlignedListCellRenderer(SwingConstants.CENTER));

    PSParameter psParameter = new PSParameter();
    try {
      psParameter =
          (PSParameter) identification.getProteinMatchParameter(inspectedMatch, psParameter);
    } catch (Exception e) {
      peptideShakerGUI.catchException(e);
    }
    matchInfoLbl.setText(
        "[Score: "
            + Util.roundDouble(psParameter.getProteinScore(), 2)
            + ", Confidence: "
            + Util.roundDouble(psParameter.getProteinConfidence(), 2)
            + "]");

    // set up the table column properties
    setColumnProperies();

    // The index should be set in the design according to the PSParameter class static fields!
    groupClassJComboBox.setSelectedIndex(psParameter.getGroupClass());

    setLocationRelativeTo(peptideShakerGUI);
    setVisible(true);
  }
  /**
   * Fills the PSM specific map.
   *
   * @param inputMap The input map
   * @param waitingHandler the handler displaying feedback to the user
   * @param shotgunProtocol information about the protocol
   * @param identificationParameters the identification parameters
   * @throws java.sql.SQLException exception thrown whenever an error occurred while interacting
   *     with the back-end database
   * @throws java.io.IOException exception thrown whenever an error occurred while reading an
   *     external file
   * @throws java.lang.ClassNotFoundException exception thrown whenever an error occurred while
   *     deserializing an object
   * @throws java.lang.InterruptedException exception thrown whenever a threading error occurred
   * @throws uk.ac.ebi.jmzml.xml.io.MzMLUnmarshallerException exception thrown whenever an error
   *     occurred while reading an mzML file
   */
  public void selectBestHitAndFillPsmMap(
      InputMap inputMap,
      WaitingHandler waitingHandler,
      ShotgunProtocol shotgunProtocol,
      IdentificationParameters identificationParameters)
      throws SQLException, IOException, ClassNotFoundException, InterruptedException,
          MzMLUnmarshallerException {

    waitingHandler.setSecondaryProgressCounterIndeterminate(false);
    waitingHandler.setMaxSecondaryProgressCounter(identification.getSpectrumIdentificationSize());

    PeptideSpectrumAnnotator spectrumAnnotator = new PeptideSpectrumAnnotator();
    boolean multiSE = inputMap.isMultipleAlgorithms();

    SequenceMatchingPreferences sequenceMatchingPreferences =
        identificationParameters.getSequenceMatchingPreferences();
    AnnotationSettings annotationPreferences = identificationParameters.getAnnotationPreferences();

    PeptideAssumptionFilter idFilter = identificationParameters.getPeptideAssumptionFilter();

    // Keep a map of the spectrum keys grouped by peptide
    HashMap<String, ArrayList<String>> orderedPsmMap = null;
    if (MemoryConsumptionStatus.memoryUsed() < 0.8) {
      orderedPsmMap =
          new HashMap<String, ArrayList<String>>(
              identification.getSpectrumIdentificationMap().size());
    }

    PSParameter psParameter = new PSParameter();

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

      HashMap<String, ArrayList<String>> keysMap = null;
      if (orderedPsmMap != null) {
        keysMap = new HashMap<String, ArrayList<String>>();
      }

      PsmIterator psmIterator =
          identification.getPsmIterator(spectrumFileName, null, true, waitingHandler);

      while (psmIterator.hasNext()) {

        SpectrumMatch advocateMatch = psmIterator.next();
        String spectrumKey = advocateMatch.getKey();

        // map of the peptide first hits for this spectrum: score -> max protein count -> max search
        // engine votes -> amino acids annotated -> min mass deviation -> peptide sequence
        HashMap<
                Double,
                HashMap<
                    Integer,
                    HashMap<
                        Integer,
                        HashMap<Integer, HashMap<Double, HashMap<String, PeptideAssumption>>>>>>
            peptideAssumptions =
                new HashMap<
                    Double,
                    HashMap<
                        Integer,
                        HashMap<
                            Integer,
                            HashMap<
                                Integer, HashMap<Double, HashMap<String, PeptideAssumption>>>>>>();

        // map of the tag first hits: score -> assumptions
        HashMap<Double, ArrayList<TagAssumption>> tagAssumptions =
            new HashMap<Double, ArrayList<TagAssumption>>();

        ArrayList<String> identifications = new ArrayList<String>();

        HashMap<Integer, HashMap<Double, ArrayList<SpectrumIdentificationAssumption>>> assumptions =
            identification.getAssumptions(spectrumKey);

        for (int searchEngine1 : assumptions.keySet()) {

          HashMap<Double, ArrayList<SpectrumIdentificationAssumption>> advocate1Map =
              assumptions.get(searchEngine1);

          double bestEvalue = Collections.min(advocate1Map.keySet());

          for (SpectrumIdentificationAssumption assumption1 : advocate1Map.get(bestEvalue)) {

            if (assumption1 instanceof PeptideAssumption) {

              PeptideAssumption peptideAssumption1 = (PeptideAssumption) assumption1;
              String id = peptideAssumption1.getPeptide().getKey();

              if (!identifications.contains(id)) {

                psParameter = (PSParameter) peptideAssumption1.getUrParam(psParameter);
                double p;

                if (multiSE && sequenceFactory.concatenatedTargetDecoy()) {
                  p = psParameter.getSearchEngineProbability();
                } else {
                  p = peptideAssumption1.getScore();
                }

                int nSE = 1;
                int proteinMax = 1;
                for (String protein :
                    peptideAssumption1
                        .getPeptide()
                        .getParentProteins(sequenceMatchingPreferences)) {
                  Integer tempCount = proteinCount.get(protein);
                  if (tempCount != null && tempCount > proteinMax) {
                    proteinMax = tempCount;
                  }
                }

                for (int searchEngine2 : assumptions.keySet()) {

                  if (searchEngine1 != searchEngine2) {

                    HashMap<Double, ArrayList<SpectrumIdentificationAssumption>> advocate2Map =
                        assumptions.get(searchEngine2);

                    boolean found = false;
                    ArrayList<Double> eValues2 = new ArrayList<Double>(advocate2Map.keySet());
                    Collections.sort(eValues2);

                    for (double eValue2 : eValues2) {
                      for (SpectrumIdentificationAssumption assumption2 :
                          advocate2Map.get(eValue2)) {

                        if (assumption2 instanceof PeptideAssumption) {

                          PeptideAssumption peptideAssumption2 = (PeptideAssumption) assumption2;

                          if (peptideAssumption1
                              .getPeptide()
                              .isSameSequenceAndModificationStatus(
                                  peptideAssumption2.getPeptide(), sequenceMatchingPreferences)) {
                            PSParameter psParameter2 =
                                (PSParameter) peptideAssumption2.getUrParam(psParameter);
                            p = p * psParameter2.getSearchEngineProbability();
                            nSE++;
                            found = true;
                            break;
                          }
                        }
                      }
                      if (found) {
                        break;
                      }
                    }
                  }
                }

                identifications.add(id);

                HashMap<
                        Integer,
                        HashMap<
                            Integer,
                            HashMap<Integer, HashMap<Double, HashMap<String, PeptideAssumption>>>>>
                    pMap = peptideAssumptions.get(p);
                if (pMap == null) {
                  pMap =
                      new HashMap<
                          Integer,
                          HashMap<
                              Integer,
                              HashMap<
                                  Integer, HashMap<Double, HashMap<String, PeptideAssumption>>>>>(
                          advocate1Map.size());
                  peptideAssumptions.put(p, pMap);
                }

                HashMap<
                        Integer,
                        HashMap<Integer, HashMap<Double, HashMap<String, PeptideAssumption>>>>
                    proteinMaxMap = pMap.get(proteinMax);
                if (proteinMaxMap == null) {
                  proteinMaxMap =
                      new HashMap<
                          Integer,
                          HashMap<Integer, HashMap<Double, HashMap<String, PeptideAssumption>>>>(1);
                  pMap.put(proteinMax, proteinMaxMap);
                }

                HashMap<Integer, HashMap<Double, HashMap<String, PeptideAssumption>>> nSeMap =
                    proteinMaxMap.get(nSE);
                if (nSeMap == null) {
                  nSeMap =
                      new HashMap<Integer, HashMap<Double, HashMap<String, PeptideAssumption>>>(1);
                  proteinMaxMap.put(nSE, nSeMap);
                  HashMap<Double, HashMap<String, PeptideAssumption>> coverageMap =
                      new HashMap<Double, HashMap<String, PeptideAssumption>>(1);
                  nSeMap.put(-1, coverageMap);
                  HashMap<String, PeptideAssumption> assumptionMap =
                      new HashMap<String, PeptideAssumption>(1);
                  coverageMap.put(-1.0, assumptionMap);
                  assumptionMap.put(
                      peptideAssumption1.getPeptide().getSequenceWithLowerCasePtms(),
                      peptideAssumption1);
                } else {
                  MSnSpectrum spectrum = (MSnSpectrum) spectrumFactory.getSpectrum(spectrumKey);

                  HashMap<Double, HashMap<String, PeptideAssumption>> coverageMap = nSeMap.get(-1);
                  if (coverageMap != null) {
                    HashMap<String, PeptideAssumption> assumptionMap = coverageMap.get(-1.0);
                    for (PeptideAssumption tempAssumption :
                        assumptionMap.values()) { // There should be only one
                      Peptide peptide = tempAssumption.getPeptide();
                      SpecificAnnotationSettings specificAnnotationPreferences =
                          annotationPreferences.getSpecificAnnotationPreferences(
                              spectrum.getSpectrumKey(),
                              tempAssumption,
                              identificationParameters.getSequenceMatchingPreferences(),
                              identificationParameters
                                  .getPtmScoringPreferences()
                                  .getSequenceMatchingPreferences());
                      HashMap<Integer, ArrayList<IonMatch>> coveredAminoAcids =
                          spectrumAnnotator.getCoveredAminoAcids(
                              annotationPreferences,
                              specificAnnotationPreferences,
                              (MSnSpectrum) spectrum,
                              peptide);
                      int nIons = coveredAminoAcids.size();
                      nSeMap.put(nIons, coverageMap);
                    }
                    nSeMap.remove(-1);
                  }

                  Peptide peptide = peptideAssumption1.getPeptide();
                  SpecificAnnotationSettings specificAnnotationPreferences =
                      annotationPreferences.getSpecificAnnotationPreferences(
                          spectrum.getSpectrumKey(),
                          peptideAssumption1,
                          identificationParameters.getSequenceMatchingPreferences(),
                          identificationParameters
                              .getPtmScoringPreferences()
                              .getSequenceMatchingPreferences());
                  HashMap<Integer, ArrayList<IonMatch>> coveredAminoAcids =
                      spectrumAnnotator.getCoveredAminoAcids(
                          annotationPreferences,
                          specificAnnotationPreferences,
                          (MSnSpectrum) spectrum,
                          peptide);
                  int nIons = coveredAminoAcids.size();

                  coverageMap = nSeMap.get(nIons);
                  if (coverageMap == null) {
                    coverageMap = new HashMap<Double, HashMap<String, PeptideAssumption>>(1);
                    HashMap<String, PeptideAssumption> assumptionMap =
                        new HashMap<String, PeptideAssumption>(1);
                    assumptionMap.put(
                        peptideAssumption1.getPeptide().getSequenceWithLowerCasePtms(),
                        peptideAssumption1);
                    coverageMap.put(-1.0, assumptionMap);
                    nSeMap.put(nIons, coverageMap);
                  } else {
                    HashMap<String, PeptideAssumption> assumptionMap = coverageMap.get(-1.0);
                    if (assumptionMap != null) {
                      for (PeptideAssumption tempAssumption :
                          assumptionMap.values()) { // There should be only one
                        double massError =
                            Math.abs(
                                tempAssumption.getDeltaMass(
                                    spectrum.getPrecursor().getMz(),
                                    shotgunProtocol.isMs1ResolutionPpm()));
                        coverageMap.put(massError, assumptionMap);
                      }
                      coverageMap.remove(-1.0);
                    }

                    double massError =
                        Math.abs(
                            peptideAssumption1.getDeltaMass(
                                spectrum.getPrecursor().getMz(),
                                shotgunProtocol.isMs1ResolutionPpm()));
                    assumptionMap = coverageMap.get(massError);
                    if (assumptionMap == null) {
                      assumptionMap = new HashMap<String, PeptideAssumption>(1);
                      coverageMap.put(massError, assumptionMap);
                    }
                    assumptionMap.put(
                        peptideAssumption1.getPeptide().getSequenceWithLowerCasePtms(),
                        peptideAssumption1);
                  }
                }
              }
            } else if (assumption1 instanceof TagAssumption) {
              TagAssumption tagAssumption = (TagAssumption) assumption1;
              ArrayList<TagAssumption> assumptionList = tagAssumptions.get(bestEvalue);
              if (assumptionList == null) {
                assumptionList = new ArrayList<TagAssumption>();
                tagAssumptions.put(bestEvalue, assumptionList);
              }
              assumptionList.add(tagAssumption);
            }
          }
        }

        SpectrumMatch spectrumMatch = new SpectrumMatch(spectrumKey);
        if (!peptideAssumptions.isEmpty()) {

          PeptideAssumption bestPeptideAssumption = null;
          ArrayList<Double> ps = new ArrayList<Double>(peptideAssumptions.keySet());
          Collections.sort(ps);
          double retainedP = 0;

          for (double p : ps) {

            retainedP = p;
            HashMap<
                    Integer,
                    HashMap<
                        Integer,
                        HashMap<Integer, HashMap<Double, HashMap<String, PeptideAssumption>>>>>
                pMap = peptideAssumptions.get(p);
            ArrayList<Integer> proteinMaxs = new ArrayList<Integer>(pMap.keySet());
            Collections.sort(proteinMaxs, Collections.reverseOrder());

            for (int proteinMax : proteinMaxs) {

              HashMap<
                      Integer,
                      HashMap<Integer, HashMap<Double, HashMap<String, PeptideAssumption>>>>
                  proteinMaxMap = pMap.get(proteinMax);
              ArrayList<Integer> nSEs = new ArrayList<Integer>(proteinMaxMap.keySet());
              Collections.sort(nSEs, Collections.reverseOrder());

              for (int nSE : nSEs) {

                HashMap<Integer, HashMap<Double, HashMap<String, PeptideAssumption>>> nSeMap =
                    proteinMaxMap.get(nSE);
                ArrayList<Integer> coverages = new ArrayList<Integer>(nSeMap.keySet());
                Collections.sort(coverages, Collections.reverseOrder());

                for (Integer coverage : coverages) {

                  HashMap<Double, HashMap<String, PeptideAssumption>> coverageMap =
                      nSeMap.get(coverage);
                  ArrayList<Double> minErrors = new ArrayList<Double>(coverageMap.keySet());
                  Collections.sort(minErrors);

                  for (double minError : minErrors) {

                    HashMap<String, PeptideAssumption> bestPeptideAssumptions =
                        coverageMap.get(minError);
                    ArrayList<String> sequences =
                        new ArrayList<String>(bestPeptideAssumptions.keySet());
                    Collections.sort(sequences);

                    for (String sequence : sequences) {
                      PeptideAssumption peptideAssumption = bestPeptideAssumptions.get(sequence);
                      if (idFilter.validateProteins(
                          peptideAssumption.getPeptide(), sequenceMatchingPreferences)) {
                        bestPeptideAssumption = peptideAssumption;
                        break;
                      }
                    }
                    if (bestPeptideAssumption != null) {
                      break;
                    }
                  }
                  if (bestPeptideAssumption != null) {
                    break;
                  }
                }
                if (bestPeptideAssumption != null) {
                  break;
                }
              }
              if (bestPeptideAssumption != null) {
                break;
              }
            }
            if (bestPeptideAssumption != null) {
              break;
            }
          }
          if (bestPeptideAssumption != null) {

            if (multiSE) {

              // try to find the most likely modification localization based on the search engine
              // results
              HashMap<PeptideAssumption, ArrayList<Double>> assumptionPEPs =
                  new HashMap<PeptideAssumption, ArrayList<Double>>();
              String bestAssumptionKey =
                  bestPeptideAssumption.getPeptide().getMatchingKey(sequenceMatchingPreferences);

              for (int searchEngine : assumptions.keySet()) {

                boolean found = false;
                HashMap<Double, ArrayList<SpectrumIdentificationAssumption>> advocateMap =
                    assumptions.get(searchEngine);
                ArrayList<Double> eValues = new ArrayList<Double>(advocateMap.keySet());
                Collections.sort(eValues);

                for (double eValue : eValues) {
                  for (SpectrumIdentificationAssumption assumption : advocateMap.get(eValue)) {

                    if (assumption instanceof PeptideAssumption) {

                      PeptideAssumption peptideAssumption = (PeptideAssumption) assumption;

                      if (peptideAssumption
                          .getPeptide()
                          .getMatchingKey(sequenceMatchingPreferences)
                          .equals(bestAssumptionKey)) {

                        found = true;
                        boolean found2 = false;

                        for (PeptideAssumption assumption1 : assumptionPEPs.keySet()) {
                          if (assumption1
                              .getPeptide()
                              .sameModificationsAs(peptideAssumption.getPeptide())) {
                            found2 = true;
                            psParameter = (PSParameter) assumption.getUrParam(psParameter);
                            ArrayList<Double> peps = assumptionPEPs.get(assumption1);
                            peps.add(psParameter.getSearchEngineProbability());
                            break;
                          }
                        }

                        if (!found2) {
                          ArrayList<Double> peps = new ArrayList<Double>(1);
                          assumptionPEPs.put(peptideAssumption, peps);
                          psParameter = (PSParameter) assumption.getUrParam(psParameter);
                          peps.add(psParameter.getSearchEngineProbability());
                        }
                      }
                    }
                  }

                  if (found) {
                    break;
                  }
                }
              }

              Double bestSeP = null;
              int nSe = -1;

              for (PeptideAssumption peptideAssumption : assumptionPEPs.keySet()) {

                ArrayList<Double> peps = assumptionPEPs.get(peptideAssumption);
                Double sep = Collections.min(peps);

                if (bestSeP == null || bestSeP > sep) {
                  bestSeP = sep;
                  nSe = peps.size();
                  bestPeptideAssumption = peptideAssumption;
                } else if (peps.size() > nSe) {
                  if (sep != null && (Math.abs(sep - bestSeP) <= 1e-10)) {
                    nSe = peps.size();
                    bestPeptideAssumption = peptideAssumption;
                  }
                }
              }
            }

            // create a PeptideShaker match based on the best search engine match
            Peptide sePeptide = bestPeptideAssumption.getPeptide();
            ArrayList<String> psProteins =
                new ArrayList<String>(sePeptide.getParentProteins(sequenceMatchingPreferences));
            ArrayList<ModificationMatch> psModificationMatches = null;
            if (sePeptide.isModified()) {
              psModificationMatches =
                  new ArrayList<ModificationMatch>(sePeptide.getNModifications());
              for (ModificationMatch seModMatch : sePeptide.getModificationMatches()) {
                psModificationMatches.add(
                    new ModificationMatch(
                        seModMatch.getTheoreticPtm(),
                        seModMatch.isVariable(),
                        seModMatch.getModificationSite()));
              }
            }

            Peptide psPeptide = new Peptide(sePeptide.getSequence(), psModificationMatches);
            psPeptide.setParentProteins(psProteins);
            PeptideAssumption psAssumption =
                new PeptideAssumption(
                    psPeptide,
                    1,
                    Advocate.peptideShaker.getIndex(),
                    bestPeptideAssumption.getIdentificationCharge(),
                    retainedP);

            spectrumMatch.setBestPeptideAssumption(psAssumption);

            if (orderedPsmMap != null) {
              String peptideKey = psPeptide.getMatchingKey(sequenceMatchingPreferences);
              ArrayList<String> spectrumKeys = keysMap.get(peptideKey);
              if (spectrumKeys == null) {
                spectrumKeys = new ArrayList<String>();
                keysMap.put(peptideKey, spectrumKeys);
              }
              spectrumKeys.add(spectrumKey);
            }

            psParameter = new PSParameter();
            psParameter.setSpectrumProbabilityScore(retainedP);

            PSParameter matchParameter =
                (PSParameter) bestPeptideAssumption.getUrParam(psParameter);
            psParameter.setSearchEngineProbability(matchParameter.getSearchEngineProbability());
            psParameter.setAlgorithmDeltaPEP(matchParameter.getAlgorithmDeltaPEP());
            psParameter.setDeltaPEP(matchParameter.getDeltaPEP());

            matchesValidator
                .getPsmMap()
                .addPoint(
                    psParameter.getPsmProbabilityScore(),
                    spectrumMatch,
                    sequenceMatchingPreferences);
            psParameter.setSpecificMapKey(
                spectrumMatch.getBestPeptideAssumption().getIdentificationCharge().value + "");
            identification.addSpectrumMatchParameter(spectrumKey, psParameter);
            identification.updateSpectrumMatch(spectrumMatch);
          }
        }
        if (!tagAssumptions.isEmpty()) {
          ArrayList<Double> evalues = new ArrayList<Double>(tagAssumptions.keySet());
          Double bestEvalue = Collections.min(evalues);
          TagAssumption bestAssumption = tagAssumptions.get(bestEvalue).get(0);
          spectrumMatch.setBestTagAssumption(bestAssumption);
          identification.updateSpectrumMatch(spectrumMatch);
          if (spectrumMatch.getBestPeptideAssumption() == null) {
            psParameter = new PSParameter();
            if (!multiSE) {
              psParameter.setSpectrumProbabilityScore(bestEvalue);
            }
            PSParameter matchParameter = (PSParameter) bestAssumption.getUrParam(psParameter);
            psParameter.setSearchEngineProbability(matchParameter.getSearchEngineProbability());
            psParameter.setAlgorithmDeltaPEP(matchParameter.getAlgorithmDeltaPEP());
            psParameter.setDeltaPEP(matchParameter.getDeltaPEP());
            psParameter.setSpecificMapKey(
                spectrumMatch.getBestTagAssumption().getIdentificationCharge().value + "");
            identification.addSpectrumMatchParameter(spectrumKey, psParameter);
          }
        }
        waitingHandler.increaseSecondaryProgressCounter();
        if (waitingHandler.isRunCanceled()) {
          return;
        }
      }

      if (orderedPsmMap != null) {
        ArrayList<String> orderedKeys =
            new ArrayList<String>(
                identification.getSpectrumIdentification(spectrumFileName).size());
        for (ArrayList<String> keys : keysMap.values()) {
          orderedKeys.addAll(keys);
        }
        orderedPsmMap.put(spectrumFileName, orderedKeys);

        if (MemoryConsumptionStatus.memoryUsed() > 0.9) {
          orderedPsmMap = null;
        }
      }
    }

    if (orderedPsmMap != null) {
      metrics.setOrderedSpectrumKeys(orderedPsmMap);
    }

    // the protein count map is no longer needed
    proteinCount.clear();

    waitingHandler.setSecondaryProgressCounterIndeterminate(true);
  }
 /**
  * Returns the component of the section corresponding to the given feature.
  *
  * @param identification the identification of the project
  * @param identificationFeaturesGenerator the identification features generator of the project
  * @param identificationParameters the identification parameters
  * @param keys the keys of the protein matches to output
  * @param nSurroundingAA the number of surrounding amino acids to export
  * @param linePrefix the line prefix to use.
  * @param peptideMatch the peptide match
  * @param psParameter the PeptideShaker parameters of the match
  * @param peptideFeature the peptide feature to export
  * @param validatedOnly whether only validated matches should be exported
  * @param decoys whether decoy matches should be exported as well
  * @param waitingHandler the waiting handler
  * @return the component of the section corresponding to the given feature
  * @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
  * @throws uk.ac.ebi.jmzml.xml.io.MzMLUnmarshallerException exception thrown whenever an error
  *     occurred while reading an mzML file
  */
 public static String getfeature(
     Identification identification,
     IdentificationFeaturesGenerator identificationFeaturesGenerator,
     IdentificationParameters identificationParameters,
     ArrayList<String> keys,
     int nSurroundingAA,
     String linePrefix,
     PeptideMatch peptideMatch,
     PSParameter psParameter,
     PsPeptideFeature peptideFeature,
     boolean validatedOnly,
     boolean decoys,
     WaitingHandler waitingHandler)
     throws IOException, IllegalArgumentException, SQLException, ClassNotFoundException,
         InterruptedException, MzMLUnmarshallerException {
   switch (peptideFeature) {
     case accessions:
       StringBuilder proteins = new StringBuilder();
       ArrayList<String> accessions =
           peptideMatch
               .getTheoreticPeptide()
               .getParentProteins(identificationParameters.getSequenceMatchingPreferences());
       Collections.sort(accessions);
       for (String accession : accessions) {
         if (proteins.length() > 0) {
           proteins.append("; ");
         }
         proteins.append(accession);
       }
       return proteins.toString();
     case protein_description:
       SequenceFactory sequenceFactory = SequenceFactory.getInstance();
       StringBuilder descriptions = new StringBuilder();
       accessions =
           peptideMatch
               .getTheoreticPeptide()
               .getParentProteins(identificationParameters.getSequenceMatchingPreferences());
       Collections.sort(accessions);
       for (String accession : accessions) {
         if (descriptions.length() > 0) {
           descriptions.append("; ");
         }
         descriptions.append(sequenceFactory.getHeader(accession).getDescription());
       }
       return descriptions.toString();
     case protein_groups:
       HashSet<String> proteinGroups =
           identification.getProteinMatches(peptideMatch.getTheoreticPeptide());
       proteins = new StringBuilder();
       ArrayList<String> proteinGroupsList = new ArrayList<String>(proteinGroups);
       Collections.sort(proteinGroupsList);
       if (proteinGroupsList.size() > 1) {
         identification.loadProteinMatchParameters(
             proteinGroupsList, psParameter, waitingHandler, false);
       }
       psParameter = new PSParameter();
       for (String proteinGroup : proteinGroupsList) {
         if (identification.getProteinIdentification().contains(proteinGroup)) {
           psParameter =
               (PSParameter) identification.getProteinMatchParameter(proteinGroup, psParameter);
           if (proteins.length() > 0) {
             proteins.append("; ");
           }
           List<String> groupAccessions = Arrays.asList(ProteinMatch.getAccessions(proteinGroup));
           Collections.sort(groupAccessions);
           boolean first = true;
           for (String accession : groupAccessions) {
             if (first) {
               first = false;
             } else {
               proteins.append(", ");
             }
             proteins.append(accession);
           }
           proteins.append(" (");
           proteins.append(psParameter.getMatchValidationLevel().getName());
           proteins.append(")");
         }
       }
       return proteins.toString();
     case best_protein_group_validation:
       MatchValidationLevel bestProteinValidationLevel = MatchValidationLevel.none;
       proteinGroups = identification.getProteinMatches(peptideMatch.getTheoreticPeptide());
       proteinGroupsList = new ArrayList<String>(proteinGroups);
       Collections.sort(proteinGroupsList);
       if (proteinGroupsList.size() > 1) {
         identification.loadProteinMatchParameters(
             proteinGroupsList, psParameter, waitingHandler, false);
       }
       psParameter = new PSParameter();
       for (String proteinGroup : proteinGroupsList) {
         if (identification.getProteinIdentification().contains(proteinGroup)) {
           psParameter =
               (PSParameter) identification.getProteinMatchParameter(proteinGroup, psParameter);
           if (psParameter.getMatchValidationLevel().getIndex()
               > bestProteinValidationLevel.getIndex()) {
             bestProteinValidationLevel = psParameter.getMatchValidationLevel();
           }
         }
       }
       return bestProteinValidationLevel.getName();
     case confidence:
       return psParameter.getPeptideConfidence() + "";
     case decoy:
       if (peptideMatch
           .getTheoreticPeptide()
           .isDecoy(identificationParameters.getSequenceMatchingPreferences())) {
         return "1";
       } else {
         return "0";
       }
     case hidden:
       if (psParameter.isHidden()) {
         return "1";
       } else {
         return "0";
       }
     case localization_confidence:
       return getPeptideModificationLocations(
               peptideMatch, identificationParameters.getSearchParameters().getPtmSettings())
           + "";
     case pi:
       return psParameter.getProteinInferenceClassAsString();
     case position:
       accessions =
           peptideMatch
               .getTheoreticPeptide()
               .getParentProteins(identificationParameters.getSequenceMatchingPreferences());
       Collections.sort(accessions);
       Peptide peptide = peptideMatch.getTheoreticPeptide();
       String start = "";
       for (String proteinAccession : accessions) {
         if (!start.equals("")) {
           start += "; ";
         }
         Protein protein = SequenceFactory.getInstance().getProtein(proteinAccession);
         ArrayList<Integer> starts =
             protein.getPeptideStart(
                 peptide.getSequence(), identificationParameters.getSequenceMatchingPreferences());
         Collections.sort(starts);
         boolean first = true;
         for (int startAa : starts) {
           if (first) {
             first = false;
           } else {
             start += ", ";
           }
           start += startAa;
         }
       }
       return start;
     case psms:
       return peptideMatch.getSpectrumCount() + "";
     case variable_ptms:
       return Peptide.getPeptideModificationsAsString(peptideMatch.getTheoreticPeptide(), true);
     case fixed_ptms:
       return Peptide.getPeptideModificationsAsString(peptideMatch.getTheoreticPeptide(), false);
     case score:
       return psParameter.getPeptideScore() + "";
     case raw_score:
       return psParameter.getPeptideProbabilityScore() + "";
     case sequence:
       return peptideMatch.getTheoreticPeptide().getSequence();
     case missed_cleavages:
       peptide = peptideMatch.getTheoreticPeptide();
       Integer nMissedCleavages =
           peptide.getNMissedCleavages(
               identificationParameters.getSearchParameters().getDigestionPreferences());
       if (nMissedCleavages == null) {
         nMissedCleavages = 0;
       }
       return nMissedCleavages + "";
     case modified_sequence:
       return peptideMatch
           .getTheoreticPeptide()
           .getTaggedModifiedSequence(
               identificationParameters.getSearchParameters().getPtmSettings(),
               false,
               false,
               true);
     case starred:
       if (psParameter.isStarred()) {
         return "1";
       } else {
         return "0";
       }
     case aaBefore:
       peptide = peptideMatch.getTheoreticPeptide();
       accessions =
           peptide.getParentProteins(identificationParameters.getSequenceMatchingPreferences());
       Collections.sort(accessions);
       String subSequence = "";
       for (String proteinAccession : accessions) {
         if (!subSequence.equals("")) {
           subSequence += "; ";
         }
         HashMap<Integer, String[]> surroundingAAs =
             SequenceFactory.getInstance()
                 .getProtein(proteinAccession)
                 .getSurroundingAA(
                     peptide.getSequence(),
                     nSurroundingAA,
                     identificationParameters.getSequenceMatchingPreferences());
         ArrayList<Integer> starts = new ArrayList<Integer>(surroundingAAs.keySet());
         Collections.sort(starts);
         boolean first = true;
         for (int startAa : starts) {
           if (first) {
             first = false;
           } else {
             subSequence += ", ";
           }
           subSequence += surroundingAAs.get(startAa)[0];
         }
       }
       return subSequence;
     case aaAfter:
       peptide = peptideMatch.getTheoreticPeptide();
       accessions =
           peptide.getParentProteins(identificationParameters.getSequenceMatchingPreferences());
       Collections.sort(accessions);
       subSequence = "";
       for (String proteinAccession : accessions) {
         if (!subSequence.equals("")) {
           subSequence += "; ";
         }
         HashMap<Integer, String[]> surroundingAAs =
             SequenceFactory.getInstance()
                 .getProtein(proteinAccession)
                 .getSurroundingAA(
                     peptide.getSequence(),
                     nSurroundingAA,
                     identificationParameters.getSequenceMatchingPreferences());
         ArrayList<Integer> starts = new ArrayList<Integer>(surroundingAAs.keySet());
         Collections.sort(starts);
         boolean first = true;
         for (int startAa : starts) {
           if (first) {
             first = false;
           } else {
             subSequence += ", ";
           }
           subSequence += surroundingAAs.get(startAa)[1];
         }
       }
       return subSequence;
     case nValidatedProteinGroups:
       peptide = peptideMatch.getTheoreticPeptide();
       return identificationFeaturesGenerator.getNValidatedProteinGroups(peptide, waitingHandler)
           + "";
     case unique_database:
       peptide = peptideMatch.getTheoreticPeptide();
       if (identification.isUniqueInDatabase(peptide)) {
         return "1";
       } else {
         return "0";
       }
     case validated:
       return psParameter.getMatchValidationLevel().toString();
     case validated_psms:
       return identificationFeaturesGenerator.getNValidatedSpectraForPeptide(peptideMatch.getKey())
           + "";
     case probabilistic_score:
       PSPtmScores ptmScores = new PSPtmScores();
       ptmScores = (PSPtmScores) peptideMatch.getUrParam(ptmScores);
       if (ptmScores != null) {
         StringBuilder result = new StringBuilder();
         ArrayList<String> modList = new ArrayList<String>(ptmScores.getScoredPTMs());
         Collections.sort(modList);
         for (String mod : modList) {
           PtmScoring ptmScoring = ptmScores.getPtmScoring(mod);
           ArrayList<Integer> sites = new ArrayList<Integer>(ptmScoring.getProbabilisticSites());
           if (!sites.isEmpty()) {
             Collections.sort(sites);
             if (result.length() > 0) {
               result.append(", ");
             }
             result.append(mod).append(" (");
             boolean firstSite = true;
             for (int site : sites) {
               if (firstSite) {
                 firstSite = false;
               } else {
                 result.append(", ");
               }
               result.append(site).append(": ").append(ptmScoring.getProbabilisticScore(site));
             }
             result.append(")");
           }
         }
         return result.toString();
       }
       return "";
     case d_score:
       StringBuilder result = new StringBuilder();
       ptmScores = new PSPtmScores();
       ptmScores = (PSPtmScores) peptideMatch.getUrParam(ptmScores);
       if (ptmScores != null) {
         ArrayList<String> modList = new ArrayList<String>(ptmScores.getScoredPTMs());
         Collections.sort(modList);
         for (String mod : modList) {
           PtmScoring ptmScoring = ptmScores.getPtmScoring(mod);
           ArrayList<Integer> sites = new ArrayList<Integer>(ptmScoring.getDSites());
           if (!sites.isEmpty()) {
             Collections.sort(sites);
             if (result.length() > 0) {
               result.append(", ");
             }
             result.append(mod).append(" (");
             boolean firstSite = true;
             for (int site : sites) {
               if (firstSite) {
                 firstSite = false;
               } else {
                 result.append(", ");
               }
               result.append(site).append(": ").append(ptmScoring.getDeltaScore(site));
             }
             result.append(")");
           }
         }
         return result.toString();
       }
       return "";
     case confident_modification_sites:
       String sequence = peptideMatch.getTheoreticPeptide().getSequence();
       return identificationFeaturesGenerator.getConfidentPtmSites(peptideMatch, sequence);
     case confident_modification_sites_number:
       return identificationFeaturesGenerator.getConfidentPtmSitesNumber(peptideMatch);
     case ambiguous_modification_sites:
       sequence = peptideMatch.getTheoreticPeptide().getSequence();
       return identificationFeaturesGenerator.getAmbiguousPtmSites(peptideMatch, sequence);
     case ambiguous_modification_sites_number:
       return identificationFeaturesGenerator.getAmbiguousPtmSiteNumber(peptideMatch);
     case confident_phosphosites:
       ArrayList<String> modifications = new ArrayList<String>();
       for (String ptm :
           identificationParameters
               .getSearchParameters()
               .getPtmSettings()
               .getAllNotFixedModifications()) {
         if (ptm.contains("Phospho")) {
           modifications.add(ptm);
         }
       }
       return identificationFeaturesGenerator.getConfidentPtmSites(
           peptideMatch, peptideMatch.getTheoreticPeptide().getSequence(), modifications);
     case confident_phosphosites_number:
       modifications = new ArrayList<String>();
       for (String ptm :
           identificationParameters
               .getSearchParameters()
               .getPtmSettings()
               .getAllNotFixedModifications()) {
         if (ptm.contains("Phospho")) {
           modifications.add(ptm);
         }
       }
       return identificationFeaturesGenerator.getConfidentPtmSitesNumber(
           peptideMatch, modifications);
     case ambiguous_phosphosites:
       modifications = new ArrayList<String>();
       for (String ptm :
           identificationParameters
               .getSearchParameters()
               .getPtmSettings()
               .getAllNotFixedModifications()) {
         if (ptm.contains("Phospho")) {
           modifications.add(ptm);
         }
       }
       return identificationFeaturesGenerator.getAmbiguousPtmSites(
           peptideMatch, peptideMatch.getTheoreticPeptide().getSequence(), modifications);
     case ambiguous_phosphosites_number:
       modifications = new ArrayList<String>();
       for (String ptm :
           identificationParameters
               .getSearchParameters()
               .getPtmSettings()
               .getAllNotFixedModifications()) {
         if (ptm.contains("Phospho")) {
           modifications.add(ptm);
         }
       }
       return identificationFeaturesGenerator.getAmbiguousPtmSiteNumber(
           peptideMatch, modifications);
     default:
       return "Not implemented";
   }
 }
  /**
   * Writes the desired section.
   *
   * @param identification the identification of the project
   * @param identificationFeaturesGenerator the identification features generator of the project
   * @param identificationParameters the identification parameters
   * @param keys the keys of the protein matches to output
   * @param nSurroundingAA the number of surrounding amino acids to export
   * @param linePrefix the line prefix to use.
   * @param validatedOnly whether only validated matches should be exported
   * @param decoys whether decoy matches should be exported as well
   * @param waitingHandler the waiting handler
   * @throws IOException exception thrown whenever an error occurred while interacting with a file
   * @throws SQLException thrown whenever an error occurred while interacting with the database
   * @throws ClassNotFoundException thrown whenever an error occurred while deserializing a match
   *     from the database
   * @throws InterruptedException thrown whenever a threading error occurred while interacting with
   *     the database
   * @throws MzMLUnmarshallerException thrown whenever an error occurred while reading an mzML file
   */
  public void writeSection(
      Identification identification,
      IdentificationFeaturesGenerator identificationFeaturesGenerator,
      IdentificationParameters identificationParameters,
      ArrayList<String> keys,
      int nSurroundingAA,
      String linePrefix,
      boolean validatedOnly,
      boolean decoys,
      WaitingHandler waitingHandler)
      throws IOException, SQLException, ClassNotFoundException, InterruptedException,
          MzMLUnmarshallerException {

    if (waitingHandler != null) {
      waitingHandler.setSecondaryProgressCounterIndeterminate(true);
    }

    if (header) {
      writeHeader();
    }

    if (keys == null) {
      keys = new ArrayList<String>(identification.getPeptideIdentification());
    }

    int line = 1;

    if (waitingHandler != null) {
      waitingHandler.setWaitingText("Exporting. Please Wait...");
      waitingHandler.resetSecondaryProgressCounter();
      waitingHandler.setMaxSecondaryProgressCounter(keys.size());
    }

    PSParameter psParameter = new PSParameter();
    ArrayList<UrParameter> parameters = new ArrayList<UrParameter>(1);
    parameters.add(psParameter);

    PeptideMatchesIterator peptideMatchesIterator =
        identification.getPeptideMatchesIterator(
            keys, parameters, psmSection != null, parameters, waitingHandler);

    while (peptideMatchesIterator.hasNext()) {

      if (waitingHandler != null) {
        if (waitingHandler.isRunCanceled()) {
          return;
        }
        waitingHandler.increaseSecondaryProgressCounter();
      }

      PeptideMatch peptideMatch = peptideMatchesIterator.next();
      String peptideKey = peptideMatch.getKey();
      psParameter = (PSParameter) identification.getPeptideMatchParameter(peptideKey, psParameter);

      if (!validatedOnly || psParameter.getMatchValidationLevel().isValidated()) {

        if (decoys
            || !peptideMatch
                .getTheoreticPeptide()
                .isDecoy(identificationParameters.getSequenceMatchingPreferences())) {

          boolean first = true;

          if (indexes) {
            if (linePrefix != null) {
              writer.write(linePrefix);
            }
            writer.write(line + "");
            first = false;
          }

          for (ExportFeature exportFeature : peptideFeatures) {
            if (!first) {
              writer.addSeparator();
            } else {
              first = false;
            }
            PsPeptideFeature peptideFeature = (PsPeptideFeature) exportFeature;
            writer.write(
                getfeature(
                    identification,
                    identificationFeaturesGenerator,
                    identificationParameters,
                    keys,
                    nSurroundingAA,
                    linePrefix,
                    peptideMatch,
                    psParameter,
                    peptideFeature,
                    validatedOnly,
                    decoys,
                    waitingHandler));
          }
          writer.newLine();
          if (psmSection != null) {
            String psmSectionPrefix = "";
            if (linePrefix != null) {
              psmSectionPrefix += linePrefix;
            }
            psmSectionPrefix += line + ".";
            writer.increaseDepth();
            if (waitingHandler != null) {
              waitingHandler.setDisplayProgress(false);
            }
            psmSection.writeSection(
                identification,
                identificationFeaturesGenerator,
                identificationParameters,
                peptideMatch.getSpectrumMatchesKeys(),
                psmSectionPrefix,
                nSurroundingAA,
                validatedOnly,
                decoys,
                waitingHandler);
            if (waitingHandler != null) {
              waitingHandler.setDisplayProgress(true);
            }
            writer.decreseDepth();
          }
          line++;
        }
      }
    }
  }
  @Override
  public boolean isValidated(
      String itemName,
      FilterItemComparator filterItemComparator,
      Object value,
      String matchKey,
      Identification identification,
      IdentificationFeaturesGenerator identificationFeaturesGenerator,
      ShotgunProtocol shotgunProtocol,
      IdentificationParameters identificationParameters,
      PeptideSpectrumAnnotator peptideSpectrumAnnotator)
      throws IOException, InterruptedException, ClassNotFoundException, SQLException,
          MzMLUnmarshallerException, MathException {

    PeptideFilterItem filterItem = PeptideFilterItem.getItem(itemName);
    if (filterItem == null) {
      throw new IllegalArgumentException(
          "Filter item " + itemName + "not recognized as peptide filter item.");
    }
    String input = value.toString();
    switch (filterItem) {
      case proteinAccession:
        PeptideMatch peptideMatch = identification.getPeptideMatch(matchKey);
        return filterItemComparator.passes(
            input,
            peptideMatch
                .getTheoreticPeptide()
                .getParentProteins(identificationParameters.getSequenceMatchingPreferences()));
      case proteinDescription:
        peptideMatch = identification.getPeptideMatch(matchKey);
        ArrayList<String> accessions =
            peptideMatch
                .getTheoreticPeptide()
                .getParentProteins(identificationParameters.getSequenceMatchingPreferences());
        ArrayList<String> descriptions = new ArrayList<String>();
        for (String accession : accessions) {
          Header proteinHeader = SequenceFactory.getInstance().getHeader(accession);
          descriptions.add(proteinHeader.getDescription());
        }
        return filterItemComparator.passes(input, descriptions);
      case sequence:
        return filterItemComparator.passes(input, Peptide.getSequence(matchKey));
      case ptm:
        peptideMatch = identification.getPeptideMatch(matchKey);
        ArrayList<String> ptms;
        PSPtmScores psPtmScores = new PSPtmScores();
        psPtmScores = (PSPtmScores) peptideMatch.getUrParam(psPtmScores);
        if (psPtmScores != null) {
          ptms = psPtmScores.getScoredPTMs();
        } else {
          ptms = new ArrayList<String>(0);
        }
        return filterItemComparator.passes(input, ptms);
      case nPSMs:
        peptideMatch = identification.getPeptideMatch(matchKey);
        Integer nPsms = peptideMatch.getSpectrumCount();
        return filterItemComparator.passes(input, nPsms.toString());
      case nValidatedPSMs:
        nPsms = identificationFeaturesGenerator.getNValidatedSpectraForPeptide(matchKey);
        return filterItemComparator.passes(input, nPsms.toString());
      case nConfidentPSMs:
        nPsms = identificationFeaturesGenerator.getNConfidentSpectraForPeptide(matchKey);
        return filterItemComparator.passes(input, nPsms.toString());
      case confidence:
        PSParameter psParameter = new PSParameter();
        psParameter = (PSParameter) identification.getPeptideMatchParameter(matchKey, psParameter);
        Double confidence = psParameter.getProteinConfidence();
        return filterItemComparator.passes(input, confidence.toString());
      case proteinInference:
        psParameter = new PSParameter();
        psParameter = (PSParameter) identification.getPeptideMatchParameter(matchKey, psParameter);
        Integer pi = psParameter.getProteinInferenceClass();
        return filterItemComparator.passes(input, pi.toString());
      case validationStatus:
        psParameter = new PSParameter();
        psParameter = (PSParameter) identification.getPeptideMatchParameter(matchKey, psParameter);
        Integer validation = psParameter.getMatchValidationLevel().getIndex();
        return filterItemComparator.passes(input, validation.toString());
      case stared:
        psParameter = new PSParameter();
        psParameter = (PSParameter) identification.getPeptideMatchParameter(matchKey, psParameter);
        String starred;
        if (psParameter.isStarred()) {
          starred = FilterItemComparator.trueFalse[0];
        } else {
          starred = FilterItemComparator.trueFalse[1];
        }
        return filterItemComparator.passes(input, starred);
      default:
        throw new IllegalArgumentException(
            "Protein filter not implemented for item " + filterItem.name + ".");
    }
  }
  /**
   * Indicates whether the match designated by the match key validates the given item using the
   * given comparator and value threshold.
   *
   * @param itemName the name of the item to filter on
   * @param filterItemComparator the comparator to use
   * @param value the value to use as a threshold
   * @param spectrumKey the key of the match of interest
   * @param peptideAssumption the assumption to validate
   * @param identification the identification objects where to get identification matches from
   * @param identificationFeaturesGenerator the identification feature generator where to get
   *     identification features
   * @param identificationParameters the identification parameters used
   * @param peptideSpectrumAnnotator the annotator to use to annotate spectra when filtering on PSM
   *     or assumptions
   * @return a boolean indicating whether the match designated by the protein key validates the
   *     given item using the given comparator and value threshold.
   * @throws java.io.IOException exception thrown whenever an exception occurred while reading or
   *     writing a file
   * @throws java.lang.InterruptedException exception thrown whenever a threading issue occurred
   *     while validating that the match passes the filter
   * @throws java.lang.ClassNotFoundException exception thrown whenever an error occurred while
   *     deserilalizing a match
   * @throws java.sql.SQLException exception thrown whenever an error occurred while interacting
   *     with a database
   * @throws uk.ac.ebi.jmzml.xml.io.MzMLUnmarshallerException exception thrown whenever an error
   *     occurred while reading an mzML file
   * @throws org.apache.commons.math.MathException exception thrown whenever an error occurred while
   *     doing statistics on a distribution
   */
  public boolean isValidated(
      String itemName,
      FilterItemComparator filterItemComparator,
      Object value,
      String spectrumKey,
      PeptideAssumption peptideAssumption,
      Identification identification,
      IdentificationFeaturesGenerator identificationFeaturesGenerator,
      IdentificationParameters identificationParameters,
      PeptideSpectrumAnnotator peptideSpectrumAnnotator)
      throws IOException, InterruptedException, ClassNotFoundException, SQLException,
          MzMLUnmarshallerException, MathException {

    AssumptionFilterItem filterItem = AssumptionFilterItem.getItem(itemName);
    if (filterItem == null) {
      throw new IllegalArgumentException(
          "Filter item " + itemName + "not recognized as spectrum assumption filter item.");
    }
    String input = value.toString();
    switch (filterItem) {
      case precrusorMz:
        Precursor precursor = SpectrumFactory.getInstance().getPrecursor(spectrumKey);
        Double mz = precursor.getMz();
        return filterItemComparator.passes(input, mz.toString());
      case precrusorRT:
        precursor = SpectrumFactory.getInstance().getPrecursor(spectrumKey);
        Double rt = precursor.getRt();
        return filterItemComparator.passes(input, rt.toString());
      case precrusorCharge:
        Integer charge = peptideAssumption.getIdentificationCharge().value;
        return filterItemComparator.passes(input, charge.toString());
      case precrusorMzErrorDa:
        precursor = SpectrumFactory.getInstance().getPrecursor(spectrumKey);
        SearchParameters searchParameters = identificationParameters.getSearchParameters();
        Double mzError =
            Math.abs(
                peptideAssumption.getDeltaMass(
                    precursor.getMz(),
                    false,
                    searchParameters.getMinIsotopicCorrection(),
                    searchParameters.getMaxIsotopicCorrection()));
        return filterItemComparator.passes(input, mzError.toString());
      case precrusorMzErrorPpm:
        searchParameters = identificationParameters.getSearchParameters();
        precursor = SpectrumFactory.getInstance().getPrecursor(spectrumKey);
        mzError =
            Math.abs(
                peptideAssumption.getDeltaMass(
                    precursor.getMz(),
                    true,
                    searchParameters.getMinIsotopicCorrection(),
                    searchParameters.getMaxIsotopicCorrection()));
        return filterItemComparator.passes(input, mzError.toString());
      case precrusorMzErrorStat:
        searchParameters = identificationParameters.getSearchParameters();
        precursor = SpectrumFactory.getInstance().getPrecursor(spectrumKey);
        mzError =
            peptideAssumption.getDeltaMass(
                precursor.getMz(),
                identificationParameters.getSearchParameters().isPrecursorAccuracyTypePpm(),
                searchParameters.getMinIsotopicCorrection(),
                searchParameters.getMaxIsotopicCorrection());
        NonSymmetricalNormalDistribution precDeviationDistribution =
            identificationFeaturesGenerator.getMassErrorDistribution(
                Spectrum.getSpectrumFile(spectrumKey));
        Double p;
        if (mzError > precDeviationDistribution.getMean()) {
          p = precDeviationDistribution.getDescendingCumulativeProbabilityAt(mzError);
        } else {
          p = precDeviationDistribution.getCumulativeProbabilityAt(mzError);
        }
        return filterItemComparator.passes(input, p.toString());
      case sequenceCoverage:
        SpectrumFactory spectrumFactory = SpectrumFactory.getInstance();
        MSnSpectrum spectrum = (MSnSpectrum) spectrumFactory.getSpectrum(spectrumKey);
        Peptide peptide = peptideAssumption.getPeptide();
        AnnotationSettings annotationPreferences =
            identificationParameters.getAnnotationPreferences();
        SpecificAnnotationSettings specificAnnotationPreferences =
            annotationPreferences.getSpecificAnnotationPreferences(
                spectrum.getSpectrumKey(),
                peptideAssumption,
                identificationParameters.getSequenceMatchingPreferences(),
                identificationParameters
                    .getPtmScoringPreferences()
                    .getSequenceMatchingPreferences());
        HashMap<Integer, ArrayList<IonMatch>> matches =
            peptideSpectrumAnnotator.getCoveredAminoAcids(
                annotationPreferences,
                specificAnnotationPreferences,
                (MSnSpectrum) spectrum,
                peptide);
        double nCovered = 0;
        int nAA = peptide.getSequence().length();
        for (int i = 0; i <= nAA; i++) {
          ArrayList<IonMatch> matchesAtAa = matches.get(i);
          if (matchesAtAa != null && !matchesAtAa.isEmpty()) {
            nCovered++;
          }
        }
        Double coverage = 100.0 * nCovered / nAA;
        return filterItemComparator.passes(input, coverage.toString());
      case algorithmScore:
        Double score = peptideAssumption.getRawScore();
        if (score == null) {
          score = peptideAssumption.getScore();
        }
        return filterItemComparator.passes(input, score.toString());
      case fileNames:
        return filterItemComparator.passes(input, Spectrum.getSpectrumFile(spectrumKey));
      case confidence:
        PSParameter psParameter = new PSParameter();
        psParameter =
            (PSParameter) identification.getPeptideMatchParameter(spectrumKey, psParameter);
        Double confidence = psParameter.getProteinConfidence();
        return filterItemComparator.passes(input, confidence.toString());
      case validationStatus:
        psParameter = new PSParameter();
        psParameter =
            (PSParameter) identification.getPeptideMatchParameter(spectrumKey, psParameter);
        Integer validation = psParameter.getMatchValidationLevel().getIndex();
        return filterItemComparator.passes(input, validation.toString());
      case stared:
        psParameter = new PSParameter();
        psParameter =
            (PSParameter) identification.getPeptideMatchParameter(spectrumKey, psParameter);
        String starred;
        if (psParameter.isStarred()) {
          starred = FilterItemComparator.trueFalse[0];
        } else {
          starred = FilterItemComparator.trueFalse[1];
        }
        return filterItemComparator.passes(input, starred);
      default:
        throw new IllegalArgumentException(
            "Protein filter not implemented for item " + filterItem.name + ".");
    }
  }