Пример #1
0
  /** Loads the modifications from the modification file. */
  public void resetPtmFactory() {
    // reset ptm factory
    ptmFactory.reloadFactory();
    ptmFactory = PTMFactory.getInstance();
    try {
      ptmFactory.importModifications(new File(resource, PeptideShaker.MODIFICATIONS_FILE), false);
    } catch (Exception e) {
      e.printStackTrace();
    }

    try {
      ptmFactory.importModifications(
          new File(resource, PeptideShaker.USER_MODIFICATIONS_FILE), true);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /**
   * Get the terminal modifications as a string in the Tide format.
   *
   * @param modifications the modifications to check
   * @param fixed if the modifications are to to be added as fixed or variable
   * @param nTerm true if the modifications are n-terminal, false if c-terminal
   * @return the terminal modifications as a string in the Tide format
   */
  private String getTerminalModifications(
      ArrayList<String> modifications, boolean fixed, boolean nTerm) {

    String terminalModifications = "";

    for (String ptmName : modifications) {

      PTM ptm = ptmFactory.getPTM(ptmName);

      if ((ptm.isNTerm() && nTerm) || (ptm.isCTerm() && !nTerm)) {

        if (!terminalModifications.isEmpty()) {
          terminalModifications += ",";
        }

        // add the number of allowed ptms per peptide
        if (!fixed) {
          terminalModifications += "1";
        }

        // add the residues affected
        AminoAcidPattern ptmPattern = ptm.getPattern();
        String tempPtmPattern = "";
        if (ptmPattern != null && ptmPattern.length() > 0) {
          for (Character aminoAcid : ptmPattern.getAminoAcidsAtTarget()) {
            tempPtmPattern += aminoAcid;
          }
        }

        if (tempPtmPattern.length() == 0) {
          tempPtmPattern = "X";
        }

        terminalModifications += tempPtmPattern;

        // add the ptm mass
        if (ptm.getRoundedMass() > 0) {
          terminalModifications += "+";
        }
        terminalModifications += ptm.getRoundedMass();
      }
    }

    return terminalModifications;
  }
  /**
   * Creates the Andromeda PTM file and saves the PTM indexes in the search parameters.
   *
   * @param andromedaFolder the Andromeda installation folder
   * @param identificationParameters the identification parameters
   * @param identificationParametersFile the file where to save the search parameters
   * @throws IOException exception thrown whenever an error occurs while writing to the file.
   * @throws java.lang.ClassNotFoundException exception thrown whenever an error occurred while
   *     saving the search parameters
   */
  public static void createPtmFile(
      File andromedaFolder,
      IdentificationParameters identificationParameters,
      File identificationParametersFile)
      throws IOException, ClassNotFoundException {

    File file = new File(andromedaFolder, "conf");
    file = new File(file, "modifications.xml");
    BufferedWriter bw = new BufferedWriter(new FileWriter(file));
    int index = 0;
    String date = "0001-01-01T00:00:00";

    PTMFactory ptmFactory = PTMFactory.getInstance();
    SearchParameters searchParameters = identificationParameters.getSearchParameters();
    AndromedaParameters andromedaParameters =
        (AndromedaParameters)
            searchParameters.getIdentificationAlgorithmParameter(Advocate.andromeda.getIndex());

    try {
      bw.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
      bw.newLine();
      bw.write(
          "<modifications xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
      bw.newLine();

      // add the default ptms
      for (String ptmName : ptmFactory.getDefaultModifications()) {
        PTM ptm = ptmFactory.getPTM(ptmName);
        writePtm(bw, date, ptm, index);
        andromedaParameters.setPtmIndex(ptmName, index);
        index++;
      }

      // add the user ptms
      for (String ptmName : ptmFactory.getUserModifications()) {
        PTM ptm = ptmFactory.getPTM(ptmName);
        writePtm(bw, date, ptm, index);
        andromedaParameters.setPtmIndex(ptmName, index);
        index++;
      }

      bw.write("</modifications>");
      bw.newLine();
    } finally {
      bw.close();
    }

    IdentificationParameters.saveIdentificationParameters(
        identificationParameters, identificationParametersFile);
  }
  /**
   * Get the non-terminal modifications as a string in the Tide format.
   *
   * @param modifications the modifications to check
   * @param fixed if the modifications are to to be added as fixed or variable
   * @return the non-terminal modifications as a string in the Tide forma
   */
  private String getNonTerminalModifications(ArrayList<String> modifications, boolean fixed) {

    // tide ptm pattern: [max_per_peptide]residues[+/-]mass_change
    String nonTerminalModifications = "";

    for (String ptmName : modifications) {

      PTM ptm = ptmFactory.getPTM(ptmName);

      if (!ptm.isNTerm() && !ptm.isCTerm()) {

        if (!nonTerminalModifications.isEmpty()) {
          nonTerminalModifications += ",";
        }

        // add the number of allowed ptms per peptide
        if (!fixed) {
          nonTerminalModifications +=
              tideParameters
                  .getMaxVariablePtmsPerTypePerPeptide(); // @TODO: make this modification specific?
        }

        // add the residues affected
        AminoAcidPattern ptmPattern = ptm.getPattern();
        if (ptmPattern != null && ptmPattern.length() > 0) {
          for (Character aminoAcid : ptmPattern.getAminoAcidsAtTarget()) {
            nonTerminalModifications += aminoAcid;
          }
        }

        // add the ptm mass
        if (ptm.getRoundedMass() > 0) {
          nonTerminalModifications += "+";
        }
        nonTerminalModifications += ptm.getRoundedMass();
      }
    }

    return nonTerminalModifications;
  }
Пример #5
0
  /**
   * Calling this method will run the configured PeptideShaker process.
   *
   * @return returns 1 if the process was canceled
   */
  public Object call() {

    PathSettingsCLIInputBean pathSettingsCLIInputBean =
        followUpCLIInputBean.getPathSettingsCLIInputBean();

    if (pathSettingsCLIInputBean.getLogFolder() != null) {
      redirectErrorStream(pathSettingsCLIInputBean.getLogFolder());
    }

    if (pathSettingsCLIInputBean.hasInput()) {
      PathSettingsCLI pathSettingsCLI = new PathSettingsCLI(pathSettingsCLIInputBean);
      pathSettingsCLI.setPathSettings();
    } else {
      try {
        setPathConfiguration();
      } catch (Exception e) {
        System.out.println(
            "An error occurred when the setting path configurations. Default paths will be used.");
        e.printStackTrace();
      }
    }

    setDbFolder(PeptideShaker.getMatchesFolder());

    try {
      ArrayList<PathKey> errorKeys = PeptideShakerPathPreferences.getErrorKeys();
      if (!errorKeys.isEmpty()) {
        System.out.println(
            "Unable to write in the following configuration folders. Please use a temporary folder, "
                + "the path configuration command line, or edit the configuration paths from the graphical interface.");
        for (PathKey pathKey : errorKeys) {
          System.out.println(pathKey.getId() + ": " + pathKey.getDescription());
        }
      }
    } catch (Exception e) {
      System.out.println("Unable to load the path configurations. Default paths will be used.");
      e.printStackTrace();
    }

    // Load user preferences
    utilitiesUserPreferences = UtilitiesUserPreferences.loadUserPreferences();

    // Instantiate factories
    PeptideShaker.instantiateFacories(utilitiesUserPreferences);
    ptmFactory = PTMFactory.getInstance();
    enzymeFactory = EnzymeFactory.getInstance();

    // Load resources files
    loadSpecies();

    waitingHandler = new WaitingHandlerCLIImpl();

    String inputFilePath = null;

    try {
      if (followUpCLIInputBean.getZipFile() != null) {
        inputFilePath = followUpCLIInputBean.getZipFile().getAbsolutePath();
        loadCpsFromZipFile(
            followUpCLIInputBean.getZipFile(), PeptideShaker.getMatchesFolder(), waitingHandler);
      } else if (followUpCLIInputBean.getCpsFile() != null) {
        inputFilePath = followUpCLIInputBean.getCpsFile().getAbsolutePath();
        cpsFile = followUpCLIInputBean.getCpsFile();
        loadCpsFile(PeptideShaker.getMatchesFolder(), waitingHandler);
      } else {
        waitingHandler.appendReport("PeptideShaker project input missing.", true, true);
        return 1;
      }
    } catch (SQLException e) {
      waitingHandler.appendReport(
          "An error occurred while reading: "
              + inputFilePath
              + ". "
              + "It looks like another instance of PeptideShaker is still connected to the file. "
              + "Please close all instances of PeptideShaker and try again.",
          true,
          true);
      e.printStackTrace();
    } catch (Exception e) {
      waitingHandler.appendReport(
          "An error occurred while reading: " + inputFilePath + ".", true, true);
      e.printStackTrace();
      try {
        PeptideShakerCLI.closePeptideShaker(identification);
      } catch (Exception e2) {
        waitingHandler.appendReport("An error occurred while closing PeptideShaker.", true, true);
        e2.printStackTrace();
      }
      return 1;
    }

    // load fasta file
    try {
      if (!loadFastaFile(waitingHandler)) {
        waitingHandler.appendReport(
            "The FASTA file was not found. Please provide its location in the command line parameters.",
            true,
            true);
        try {
          PeptideShakerCLI.closePeptideShaker(identification);
        } catch (Exception e2) {
          waitingHandler.appendReport("An error occurred while closing PeptideShaker.", true, true);
          e2.printStackTrace();
        }
        return 1;
      }
      waitingHandler.appendReport(
          "Protein database "
              + identificationParameters
                  .getProteinInferencePreferences()
                  .getProteinSequenceDatabase()
                  .getName()
              + ".",
          true,
          true);
    } catch (Exception e) {
      waitingHandler.appendReport("An error occurred while loading the fasta file.", true, true);
      e.printStackTrace();
      try {
        PeptideShakerCLI.closePeptideShaker(identification);
      } catch (Exception e2) {
        waitingHandler.appendReport("An error occurred while closing PeptideShaker.", true, true);
        e2.printStackTrace();
      }
      return 1;
    }

    // load the spectrum files
    try {
      if (!loadSpectrumFiles(waitingHandler)) {
        if (identification.getSpectrumFiles().size() > 1) {
          waitingHandler.appendReport(
              "The spectrum files were not found. Please provide their location in the command line parameters.",
              true,
              true);
        } else {
          waitingHandler.appendReport(
              "The spectrum file was not found. Please provide its location in the command line parameters",
              true,
              true);
        }
        try {
          PeptideShakerCLI.closePeptideShaker(identification);
        } catch (Exception e2) {
          waitingHandler.appendReport("An error occurred while closing PeptideShaker.", true, true);
          e2.printStackTrace();
        }
        return 1;
      }
    } catch (Exception e) {
      waitingHandler.appendReport(
          "An error occurred while loading the spectrum file(s).", true, true);
      e.printStackTrace();
      try {
        PeptideShakerCLI.closePeptideShaker(identification);
      } catch (Exception e2) {
        waitingHandler.appendReport("An error occurred while closing PeptideShaker.", true, true);
        e2.printStackTrace();
      }
      return 1;
    }

    // Load project specific PTMs
    String error =
        PeptideShaker.loadModifications(getIdentificationParameters().getSearchParameters());
    if (error != null) {
      System.out.println(error);
    }

    // recalibrate spectra
    if (followUpCLIInputBean.recalibrationNeeded()) {
      try {
        CLIExportMethods.recalibrateSpectra(
            followUpCLIInputBean, identification, identificationParameters, waitingHandler);
        waitingHandler.appendReport("Recalibration process completed.", true, true);
      } catch (Exception e) {
        waitingHandler.appendReport(
            "An error occurred while recalibrating the spectra.", true, true);
        e.printStackTrace();
        waitingHandler.setRunCanceled();
      }
    }

    // export spectra
    if (followUpCLIInputBean.spectrumExportNeeded()) {
      try {
        CLIExportMethods.exportSpectra(
            followUpCLIInputBean,
            identification,
            waitingHandler,
            identificationParameters.getSequenceMatchingPreferences());
        waitingHandler.appendReport("Spectrum export completed.", true, true);
      } catch (Exception e) {
        waitingHandler.appendReport("An error occurred while exporting the spectra.", true, true);
        e.printStackTrace();
        waitingHandler.setRunCanceled();
      }
    }

    // export protein accessions
    if (followUpCLIInputBean.accessionExportNeeded()) {
      try {
        CLIExportMethods.exportAccessions(
            followUpCLIInputBean,
            identification,
            identificationFeaturesGenerator,
            waitingHandler,
            filterPreferences);
        waitingHandler.appendReport("Protein accessions export completed.", true, true);
      } catch (Exception e) {
        waitingHandler.appendReport(
            "An error occurred while exporting the protein accessions.", true, true);
        e.printStackTrace();
        waitingHandler.setRunCanceled();
      }
    }

    // export protein details
    if (followUpCLIInputBean.fastaExportNeeded()) {
      try {
        CLIExportMethods.exportFasta(
            followUpCLIInputBean,
            identification,
            identificationFeaturesGenerator,
            waitingHandler,
            filterPreferences);
        waitingHandler.appendReport("Protein details export completed.", true, true);
      } catch (Exception e) {
        waitingHandler.appendReport(
            "An error occurred while exporting the protein details.", true, true);
        e.printStackTrace();
        waitingHandler.setRunCanceled();
      }
    }

    // progenesis export
    if (followUpCLIInputBean.progenesisExportNeeded()) {
      try {
        CLIExportMethods.exportProgenesis(
            followUpCLIInputBean,
            identification,
            waitingHandler,
            identificationParameters.getSequenceMatchingPreferences());
        waitingHandler.appendReport("Progenesis export completed.", true, true);
      } catch (Exception e) {
        waitingHandler.appendReport(
            "An error occurred while exporting the Progenesis file.", true, true);
        e.printStackTrace();
        waitingHandler.setRunCanceled();
      }
    }

    // PepNovo training export
    if (followUpCLIInputBean.pepnovoTrainingExportNeeded()) {
      try {
        CLIExportMethods.exportPepnovoTrainingFiles(
            followUpCLIInputBean, identification, identificationParameters, waitingHandler);
        waitingHandler.appendReport("PepNovo training export completed.", true, true);
      } catch (Exception e) {
        waitingHandler.appendReport(
            "An error occurred while exporting the PepNovo training file.", true, true);
        e.printStackTrace();
        waitingHandler.setRunCanceled();
      }
    }

    // inclusion list export
    if (followUpCLIInputBean.inclusionListNeeded()) {
      try {
        CLIExportMethods.exportInclusionList(
            followUpCLIInputBean,
            identification,
            identificationFeaturesGenerator,
            identificationParameters.getSearchParameters(),
            waitingHandler,
            filterPreferences);
      } catch (Exception e) {
        waitingHandler.appendReport(
            "An error occurred while generating the inclusion list.", true, true);
        e.printStackTrace();
        waitingHandler.setRunCanceled();
      }
    }

    try {
      PeptideShakerCLI.closePeptideShaker(identification);
    } catch (Exception e2) {
      waitingHandler.appendReport("An error occurred while closing PeptideShaker.", true, true);
      e2.printStackTrace();
      waitingHandler.setRunCanceled();
    }

    if (!waitingHandler.isRunCanceled()) {
      waitingHandler.appendReport("Follow-up export completed.", true, true);
      System.exit(
          0); // @TODO: Find other ways of cancelling the process? If not cancelled searchgui will
              // not stop.
      // Note that if a different solution is found, the DummyFrame has to be closed similar to the
      // setVisible method in the WelcomeDialog!!
      return 0;
    } else {
      System.exit(
          1); // @TODO: Find other ways of cancelling the process? If not cancelled searchgui will
              // not stop.
      // Note that if a different solution is found, the DummyFrame has to be closed similar to the
      // setVisible method in the WelcomeDialog!!
      return 1;
    }
  }
Пример #6
0
public class PSFileImporter {

  private File currentPSFile;
  private EnzymeFactory enzymeFactory = EnzymeFactory.getInstance();
  private String resource;
  /** The spectrum annotator. */
  private SpectrumAnnotator spectrumAnnotator = new SpectrumAnnotator();
  /** The project details. */
  private ProjectDetails projectDetails = null;
  /** The spectrum factory. */
  private SpectrumFactory spectrumFactory = SpectrumFactory.getInstance(100);
  /** The identification to display. */
  private Identification identification;
  /** The compomics PTM factory. */
  private PTMFactory ptmFactory = PTMFactory.getInstance();
  /** The parameters of the search. */
  private SearchParameters searchParameters = new SearchParameters();
  /** The initial processing preferences */
  private ProcessingPreferences processingPreferences = new ProcessingPreferences();
  /** The annotation preferences. */
  private AnnotationPreferences annotationPreferences = new AnnotationPreferences();
  /** The spectrum counting preferences. */
  private SpectrumCountingPreferences spectrumCountingPreferences =
      new SpectrumCountingPreferences();
  /** The PTM scoring preferences */
  private PTMScoringPreferences ptmScoringPreferences = new PTMScoringPreferences();
  /** The identification filter used for this project. */
  private IdFilter idFilter = new IdFilter();

  /** The actually identified modifications. */
  /**
   * 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;
  }

  private ArrayList<String> identifiedModifications = null;
  /** Metrics picked-up while loading the files. */
  private Metrics metrics;
  /** The display preferences. */
  private DisplayPreferences displayPreferences = new DisplayPreferences();
  /** The sequence factory. */
  private SequenceFactory sequenceFactory = SequenceFactory.getInstance(30000);
  /** The filter preferences. */
  private FilterPreferences filterPreferences = new FilterPreferences();
  /** The compomics experiment. */
  private MsExperiment experiment = null;
  /** The investigated sample. */
  private Sample sample;
  /** The replicate number. */
  private int replicateNumber;
  /** The class used to provide sexy features out of the identification. */
  private IdentificationFeaturesGenerator identificationFeaturesGenerator;
  /** The last folder opened by the user. Defaults to user.home. */
  private String lastSelectedFolder = "user.home";
  /** The object cache used for the identification database. */
  private ObjectsCache objectsCache;

  private com.compomics.util.experiment.ProteomicAnalysis proteomicAnalysis;
  private ProgressDialogX progressDialog;
  private javax.swing.JProgressBar jprog;

  public PSFileImporter(javax.swing.JProgressBar jprog) {
    this.progressDialog = new ProgressDialogX(false);
    this.jprog = jprog;
  }

  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;

  }

  /** Loads the enzymes from the enzyme file into the enzyme factory. */
  private void loadEnzymes() {
    try {
      enzymeFactory.importEnzymes(new File(resource, PeptideShaker.ENZYME_FILE));
    } catch (Exception e) {
      System.out.println("Not able to load the enzyme file." + "Wrong enzyme file.");
      e.printStackTrace();
    }
  }

  /** Loads the modifications from the modification file. */
  public void resetPtmFactory() {
    // reset ptm factory
    ptmFactory.reloadFactory();
    ptmFactory = PTMFactory.getInstance();
    try {
      ptmFactory.importModifications(new File(resource, PeptideShaker.MODIFICATIONS_FILE), false);
    } catch (Exception e) {
      e.printStackTrace();
    }

    try {
      ptmFactory.importModifications(
          new File(resource, PeptideShaker.USER_MODIFICATIONS_FILE), true);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /** 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();
  }

  /** Imports the gene mapping. */
  private void loadGeneMapping() {
    try {
      geneFactory.initialize(new File(resource, GENE_MAPPING_PATH), null);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /** The path to the gene mapping file. */
  private final String GENE_MAPPING_PATH = "/resources/conf/gene_ontology/gene_details_human";
  /** The gene factory. */
  private GeneFactory geneFactory = GeneFactory.getInstance();

  /**
   * Updates the new annotation preferences.
   *
   * @param annotationPreferences the new annotation preferences
   */
  public void setAnnotationPreferences(AnnotationPreferences annotationPreferences) {
    this.annotationPreferences = annotationPreferences;
  }

  /**
   * Sets new spectrum counting preferences.
   *
   * @param spectrumCountingPreferences new spectrum counting preferences
   */
  public void setSpectrumCountingPreferences(
      SpectrumCountingPreferences spectrumCountingPreferences) {
    this.spectrumCountingPreferences = spectrumCountingPreferences;
  }

  /**
   * Sets the PTM scoring preferences
   *
   * @param ptmScoringPreferences the PTM scoring preferences
   */
  public void setPtmScoringPreferences(PTMScoringPreferences ptmScoringPreferences) {
    this.ptmScoringPreferences = ptmScoringPreferences;
  }

  /**
   * Sets the project details.
   *
   * @param projectDetails the project details
   */
  public void setProjectDetails(ProjectDetails projectDetails) {
    this.projectDetails = projectDetails;
  }

  /**
   * Updates the search parameters.
   *
   * @param searchParameters the new search parameters
   */
  public void setSearchParameters(SearchParameters searchParameters) {
    this.searchParameters = searchParameters;
    PeptideShaker.loadModifications(searchParameters);
  }

  /**
   * Sets the initial processing preferences.
   *
   * @param processingPreferences the initial processing preferences
   */
  public void setProcessingPreferences(ProcessingPreferences processingPreferences) {
    this.processingPreferences = processingPreferences;
  }

  /**
   * Sets the metrics saved while loading the files.
   *
   * @param metrics the metrics saved while loading the files
   */
  public void setMetrics(Metrics metrics) {
    this.metrics = metrics;
  }

  /**
   * Sets the display preferences to use.
   *
   * @param displayPreferences the display preferences to use
   */
  public void setDisplayPreferences(DisplayPreferences displayPreferences) {
    this.displayPreferences = displayPreferences;
  }
  /**
   * Sets the gui filter preferences to use. .\
   *
   * @param filterPreferences the gui filter preferences to use
   */
  public void setFilterPreferences(FilterPreferences filterPreferences) {
    this.filterPreferences = filterPreferences;
  }
  /**
   * This method sets the information of the project when opened.
   *
   * @param experiment the experiment conducted
   * @param sample The sample analyzed
   * @param replicateNumber The replicate number
   */
  public void setProject(MsExperiment experiment, Sample sample, int replicateNumber) {
    this.experiment = experiment;
    this.sample = sample;
    this.replicateNumber = replicateNumber;
    ProteomicAnalysis proteomic_Analysis =
        experiment.getAnalysisSet(sample).getProteomicAnalysis(replicateNumber);
    identification = proteomic_Analysis.getIdentification(IdentificationMethod.MS2_IDENTIFICATION);
  }

  /**
   * Returns the last selected folder.
   *
   * @return the last selected folder
   */
  public String getLastSelectedFolder() {
    return lastSelectedFolder;
  }

  /**
   * Set the last selected folder.
   *
   * @param lastSelectedFolder the folder to set
   */
  public void setLastSelectedFolder(String lastSelectedFolder) {
    this.lastSelectedFolder = lastSelectedFolder;
  }

  /**
   * Returns the identification displayed.
   *
   * @return the identification displayed
   */
  public com.compomics.util.experiment.identification.Identification getIdentification() {
    return identification;
  }

  /**
   * Returns the identification features generator.
   *
   * @return the identification features generator
   */
  public IdentificationFeaturesGenerator getIdentificationFeaturesGenerator() {
    return identificationFeaturesGenerator;
  }

  /**
   * Returns the search parameters.
   *
   * @return the search parameters
   */
  public SearchParameters getSearchParameters() {
    return searchParameters;
  }

  /**
   * Return the display preferences to use.
   *
   * @return the display preferences to use
   */
  public DisplayPreferences getDisplayPreferences() {
    return displayPreferences;
  }

  public ArrayList<IonMatch> getIonsCurrentlyMatched() throws MzMLUnmarshallerException {
    return spectrumAnnotator.getCurrentAnnotation(
        annotationPreferences.getIonTypes(),
        annotationPreferences.getNeutralLosses(),
        annotationPreferences.getValidatedCharges());
  }

  public SpectrumAnnotator getSpectrumAnnorator() {
    return spectrumAnnotator;
  }

  public void clearData(boolean clearDatabaseFolder) {
    projectDetails = null;
    spectrumAnnotator = new SpectrumAnnotator();
    try {
      spectrumFactory.closeFiles();
    } catch (Exception e) {
      e.printStackTrace();
    }
    try {
      sequenceFactory.closeFile();
    } catch (Exception e) {
      e.printStackTrace();
    }
    try {
      GOFactory.getInstance().closeFiles();
    } catch (Exception e) {
      e.printStackTrace();
    }

    try {
      spectrumFactory.clearFactory();
    } catch (Exception e) {
      e.printStackTrace();
    }

    try {
      sequenceFactory.clearFactory();
    } catch (Exception e) {
      e.printStackTrace();
    }

    try {
      GOFactory.getInstance().clearFactory();
    } catch (Exception e) {
      e.printStackTrace();
    }

    identifiedModifications = null;

    if (clearDatabaseFolder) {
      clearDatabaseFolder();
    }

    resetFeatureGenerator();

    // set up the tabs/panels

    currentPSFile = null;
  }

  /** Resets the feature generator. */
  public void resetFeatureGenerator() {
    identificationFeaturesGenerator =
        new IdentificationFeaturesGenerator(
            identification, searchParameters, idFilter, metrics, spectrumCountingPreferences);
  }

  /** 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);
        }
      }
    }
  }

  /** Updates the ions used for fragment annotation. */
  public void updateAnnotationPreferencesFromSearchSettings() {
    annotationPreferences.setPreferencesFromSearchParamaers(searchParameters);
  }

  /**
   * Returns the gene preferences.
   *
   * @return the gene preferences
   */
  public GenePreferences getGenePreferences() {
    return genePreferences;
  }

  private GenePreferences genePreferences = new GenePreferences();

  /**
   * Returns the experiment.
   *
   * @return the experiment
   */
  public MsExperiment getExperiment() {
    return experiment;
  }

  /*
   * Returns the sample.
   * @return the sample
   */
  public Sample getSample() {
    return sample;
  }
  /**
   * Returns the replicate number.
   *
   * @return the replicateNumber
   */
  public int getReplicateNumber() {
    return this.replicateNumber;
  }

  /**
   * Returns the desired spectrum.
   *
   * @param spectrumKey the key of the spectrum
   * @return the desired spectrum
   */
  public MSnSpectrum getSpectrum(String spectrumKey) {
    String spectrumFile = Spectrum.getSpectrumFile(spectrumKey);
    String spectrumTitle = Spectrum.getSpectrumTitle(spectrumKey);
    try {
      return (MSnSpectrum) spectrumFactory.getSpectrum(spectrumFile, spectrumTitle);
    } catch (Exception e) {
      System.out.println(e.getMessage());
      return null;
    }
  }
}
  /**
   * Writes the lines corresponding to the given PTM name.
   *
   * @param writer the writer used to write
   * @param mod the name of the modifications of interest
   * @param variable a string (see static fields) indicating whether the modification is fixed or
   *     variable
   * @throws IOException
   */
  private static void writePtmLine(BufferedWriter writer, String mod, String variable)
      throws IOException {

    // Get the PTMFactory
    PTMFactory ptmFactory = PTMFactory.getInstance();
    PTM ptm = ptmFactory.getPTM(mod);
    double ptmMass = ptm.getRoundedMass();

    if (ptmMass > maxMassOffsetValue) {

      String connector = "";
      if (ptmMass > 0) {
        connector = "+";
      }

      // Write a line for each residue
      if (ptm.getPattern() == null || ptm.getPattern().getAminoAcidsAtTarget().isEmpty()) {

        if (variable.equalsIgnoreCase(FIXED_PTM)) {
          variable = VARIABLE_PTM; // PepNovo+ does not support fixed PTMs at the terminals...
        }

        if (ptmFactory.getPTM(mod).getType() == PTM.MODN
            || ptmFactory.getPTM(mod).getType() == PTM.MODNAA
            || ptmFactory.getPTM(mod).getType() == PTM.MODNP
            || ptmFactory.getPTM(mod).getType() == PTM.MODNPAA) {
          writer.append("N_TERM" + SEP);
          writer.append(ptmMass + SPACE);
          writer.append(variable + SPACE);
          writer.append("N_TERM" + SPACE);
          writer.append("^" + connector + Long.toString(Math.round(ptmMass)) + SPACE);
          modIdMap.put(ptm.getName(), "^" + connector + Long.toString(Math.round(ptmMass)));
          writer.append(ptm.getName().toUpperCase());
          writer.newLine();
        } else if (ptmFactory.getPTM(mod).getType() == PTM.MODC
            || ptmFactory.getPTM(mod).getType() == PTM.MODCAA
            || ptmFactory.getPTM(mod).getType() == PTM.MODCP
            || ptmFactory.getPTM(mod).getType() == PTM.MODCPAA) {
          writer.append("C_TERM" + SEP);
          writer.append(ptmMass + SPACE);
          writer.append(variable + SPACE);
          writer.append("C_TERM" + SPACE);
          writer.append("$" + connector + Long.toString(Math.round(ptmMass)) + SPACE);
          modIdMap.put(ptm.getName(), "$" + connector + Long.toString(Math.round(ptmMass)));
          writer.append(ptm.getName().toUpperCase());
          writer.newLine();
        }
      } else {

        for (Character residue : ptm.getPattern().getAminoAcidsAtTarget()) {

          if (ptmFactory.getPTM(mod).getType() == PTM.MODN
              || ptmFactory.getPTM(mod).getType() == PTM.MODNAA
              || ptmFactory.getPTM(mod).getType() == PTM.MODNP
              || ptmFactory.getPTM(mod).getType() == PTM.MODNPAA) {
            writer.append(residue + SEP);
            writer.append(ptmMass + SPACE);
            writer.append(variable + SPACE);
            writer.append("+1" + SPACE);
            writer.append(residue + connector + Long.toString(Math.round(ptmMass)) + SPACE);
            modIdMap.put(ptm.getName(), residue + connector + Long.toString(Math.round(ptmMass)));
          } else if (ptmFactory.getPTM(mod).getType() == PTM.MODC
              || ptmFactory.getPTM(mod).getType() == PTM.MODCAA
              || ptmFactory.getPTM(mod).getType() == PTM.MODCP
              || ptmFactory.getPTM(mod).getType() == PTM.MODCPAA) {
            writer.append(residue + SEP);
            writer.append(ptmMass + SPACE);
            writer.append(variable + SPACE);
            writer.append("-1" + SPACE);
            writer.append(residue + connector + Long.toString(Math.round(ptmMass)) + SPACE);
            modIdMap.put(ptm.getName(), residue + connector + Long.toString(Math.round(ptmMass)));
          } else {
            writer.append(residue + SEP);
            writer.append(ptmMass + SPACE);
            writer.append(variable + SPACE);
            writer.append(ALL_LOCATIONS + SPACE);
            writer.append(residue + connector + Long.toString(Math.round(ptmMass)) + SPACE);
            modIdMap.put(ptm.getName(), residue + connector + Long.toString(Math.round(ptmMass)));
          }

          writer.append(ptm.getName().toUpperCase());
          writer.newLine();
        }
      }
    }
  }
  /** Fill the modification ID map. */
  private static void fillModIdMap() {

    // @TODO: is this method really needed anymore?
    modIdMap = new HashMap<String, String>();
    PTMFactory ptmFactory = PTMFactory.getInstance();
    List<String> mods = new ArrayList<String>();
    mods.addAll(ptmFactory.getDefaultModifications());
    mods.addAll(ptmFactory.getUserModifications());
    // Connector string: plus for positive modifications, minus for negative ones
    String connector;

    // Write the modifications
    for (String mod : mods) {
      PTM ptm = ptmFactory.getPTM(mod);
      double ptmMass = ptm.getRoundedMass();

      if (ptmMass > 0) {
        connector = "+";
      } else {
        connector = "";
      }

      if (ptm.getPattern() == null || ptm.getPattern().getAminoAcidsAtTarget().isEmpty()) {
        if (ptmFactory.getPTM(mod).getType() == PTM.MODN
            || ptmFactory.getPTM(mod).getType() == PTM.MODNAA
            || ptmFactory.getPTM(mod).getType() == PTM.MODNP
            || ptmFactory.getPTM(mod).getType() == PTM.MODNPAA) {
          modIdMap.put(ptm.getName(), "^" + connector + Long.toString(Math.round(ptmMass)));
        } else if (ptmFactory.getPTM(mod).getType() == PTM.MODC
            || ptmFactory.getPTM(mod).getType() == PTM.MODCAA
            || ptmFactory.getPTM(mod).getType() == PTM.MODCP
            || ptmFactory.getPTM(mod).getType() == PTM.MODCPAA) {
          modIdMap.put(ptm.getName(), "$" + connector + Long.toString(Math.round(ptmMass)));
        }
      } else {
        for (Character residue : ptmFactory.getPTM(mod).getPattern().getAminoAcidsAtTarget()) {
          if (ptmFactory.getPTM(mod).getType() == PTM.MODN
              || ptmFactory.getPTM(mod).getType() == PTM.MODNAA
              || ptmFactory.getPTM(mod).getType() == PTM.MODNP
              || ptmFactory.getPTM(mod).getType() == PTM.MODNPAA) {
            modIdMap.put(ptm.getName(), residue + connector + Long.toString(Math.round(ptmMass)));
          } else if (ptmFactory.getPTM(mod).getType() == PTM.MODC
              || ptmFactory.getPTM(mod).getType() == PTM.MODCAA
              || ptmFactory.getPTM(mod).getType() == PTM.MODCP
              || ptmFactory.getPTM(mod).getType() == PTM.MODCPAA) {
            modIdMap.put(ptm.getName(), residue + connector + Long.toString(Math.round(ptmMass)));
          } else {
            modIdMap.put(ptm.getName(), residue + connector + Long.toString(Math.round(ptmMass)));
          }
        }
      }
    }
  }
/**
 * ProcessBuilder for the Tide index generation.
 *
 * @author Harald Barsnes
 */
public class TideIndexProcessBuilder extends SearchGUIProcessBuilder {

  /** The name of the Tide executable. */
  public static final String EXECUTABLE_FILE_NAME = "crux";
  /** The FASTA file. */
  private File fastaFile;
  /** The search parameters. */
  private SearchParameters searchParameters;
  /** The advanced Tide parameters. */
  private TideParameters tideParameters;
  /** The compomics PTM factory. */
  private PTMFactory ptmFactory = PTMFactory.getInstance();

  /**
   * Constructor.
   *
   * @param tideFolder the Tide folder
   * @param searchParameters the search parameters
   * @param waitingHandler the waiting handler
   * @throws IOException thrown of there are problems creating the Tide parameter file
   */
  public TideIndexProcessBuilder(
      File tideFolder, SearchParameters searchParameters, WaitingHandler waitingHandler)
      throws IOException {

    this.waitingHandler = waitingHandler;
    this.searchParameters = searchParameters;
    tideParameters =
        (TideParameters)
            searchParameters.getIdentificationAlgorithmParameter(Advocate.tide.getIndex());
    this.fastaFile = searchParameters.getFastaFile();

    // make sure that the tide file is executable
    File tide = new File(tideFolder.getAbsolutePath() + File.separator + EXECUTABLE_FILE_NAME);
    tide.setExecutable(true);

    // full path to executable
    process_name_array.add(tide.getAbsolutePath());
    process_name_array.add("tide-index");

    // add the fasta file
    process_name_array.add(searchParameters.getFastaFile().getAbsolutePath());

    // the name of the index file
    process_name_array.add(
        tideParameters.getFastIndexFolderName()); // @TODO: put in the user temp folder instead?

    // overwrite existing files
    process_name_array.add("--overwrite");
    process_name_array.add("T");

    // add the modifications
    String nonTerminalMods = getNonTerminalModifications();
    if (!nonTerminalMods.isEmpty()) {
      process_name_array.add("--mods-spec");
      process_name_array.add(getNonTerminalModifications());
    }
    String nTermMods = getTerminalModifications(true);
    if (!nTermMods.isEmpty()) {
      process_name_array.add("--nterm-peptide-mods-spec");
      process_name_array.add(nTermMods);
    }
    String cTermMods = getTerminalModifications(false);
    if (!cTermMods.isEmpty()) {
      process_name_array.add("--cterm-peptide-mods-spec");
      process_name_array.add(cTermMods);
    }

    // the max number of modifications per peptide
    if (tideParameters.getMaxVariablePtmsPerPeptide() != null) {
      process_name_array.add("--max-mods");
      process_name_array.add(tideParameters.getMaxVariablePtmsPerPeptide().toString());
    }

    // the decoy format
    process_name_array.add("--decoy-format");
    process_name_array.add(tideParameters.getDecoyFormat());
    if (!tideParameters.getDecoyFormat().equalsIgnoreCase("none")) {
      process_name_array.add("--keep-terminal-aminos");
      process_name_array.add(tideParameters.getKeepTerminalAminoAcids());
      process_name_array.add("--seed");
      process_name_array.add(tideParameters.getDecoySeed().toString());
    }

    // missed cleavages
    process_name_array.add("--missed-cleavages");
    process_name_array.add("" + searchParameters.getnMissedCleavages());

    // set the output directory
    process_name_array.add("--output-dir");
    process_name_array.add(tideParameters.getOutputFolderName());

    // create peptide list
    process_name_array.add("--peptide-list");
    if (tideParameters.getPrintPeptides()) {
      process_name_array.add("T");
    } else {
      process_name_array.add("F");
    }

    // use parameter file
    // process_name_array.add("--parameter-file");
    // process_name_array.add("a file"); // @TODO: implement?
    //
    // output verbosity
    process_name_array.add("--verbosity");
    process_name_array.add("" + tideParameters.getVerbosity());

    // peptide lengths
    process_name_array.add("--min-length");
    process_name_array.add(tideParameters.getMinPeptideLength().toString());
    process_name_array.add("--max-length");
    process_name_array.add(tideParameters.getMaxPeptideLength().toString());

    // peptide masses
    process_name_array.add("--min-mass");
    process_name_array.add(tideParameters.getMinPrecursorMass().toString());
    process_name_array.add("--max-mass");
    process_name_array.add(tideParameters.getMaxPrecursorMass().toString());

    // monoisotopic precursor mass
    process_name_array.add("--monoisotopic-precursor");
    if (tideParameters.getMonoisotopicPrecursor()) {
      process_name_array.add("T");
    } else {
      process_name_array.add("F");
    }

    // include starting peptide both with and without the initial m
    process_name_array.add("--clip-nterm-methionine");
    if (tideParameters.getClipNtermMethionine()) {
      process_name_array.add("T");
    } else {
      process_name_array.add("F");
    }

    // enzyme
    //      note: Tide enzymes not supported:
    //          elastase ([ALIV]|{P}), clostripain ([R]|[]), iodosobenzoate ([W]|[]),
    // proline-endopeptidase ([P]|[]),
    //          staph-protease ([E]|[]), pepsin-a ([FL]|{P}), elastase-trypsin-chymotrypsin
    // ([ALIVKRWFY]|{P})
    if (searchParameters.getEnzyme().getName().equals("Trypsin")) {
      process_name_array.add("--enzyme");
      process_name_array.add("trypsin");
    } else if (searchParameters.getEnzyme().getName().equals("Trypsin, no P rule")) {
      process_name_array.add("--enzyme");
      process_name_array.add("trypsin/p");
    } else if (searchParameters.getEnzyme().getName().equals("Chymotrypsin (FYWL)")) {
      process_name_array.add("--enzyme");
      process_name_array.add("chymotrypsin");
    } else if (searchParameters.getEnzyme().getName().equals("CNBr")) {
      process_name_array.add("--enzyme");
      process_name_array.add("cyanogen-bromide");
    } else if (searchParameters.getEnzyme().getName().equals("Asp-N")) {
      process_name_array.add("--enzyme");
      process_name_array.add("asp-n");
    } else if (searchParameters.getEnzyme().getName().equals("Lys-C")) {
      process_name_array.add("--enzyme");
      process_name_array.add("lys-c");
    } else if (searchParameters.getEnzyme().getName().equals("Lys-N (K)")) {
      process_name_array.add("--enzyme");
      process_name_array.add("lys-n");
    } else if (searchParameters.getEnzyme().getName().equals("Arg-C")) {
      process_name_array.add("--enzyme");
      process_name_array.add("arg-c");
    } else if (searchParameters.getEnzyme().getName().equals("Glu-C (DE)")) {
      process_name_array.add("--enzyme");
      process_name_array.add("glu-c");
    } else if (searchParameters.getEnzyme().getName().equals("Unspecific")) {
      process_name_array.add("--enzyme");
      process_name_array.add("no-enzyme");
    } else {
      process_name_array.add("--custom-enzyme");
      process_name_array.add(searchParameters.getEnzyme().getXTandemFormat());
    }

    // full or partial enzyme digestion
    process_name_array.add("--digestion");
    process_name_array.add(tideParameters.getDigestionType());

    process_name_array.trimToSize();

    // print the command to the log file
    System.out.println(
        System.getProperty("line.separator")
            + System.getProperty("line.separator")
            + "tide index command: ");

    for (Object currentElement : process_name_array) {
      System.out.print(currentElement + " ");
    }

    System.out.println(System.getProperty("line.separator"));

    pb = new ProcessBuilder(process_name_array);
    pb.directory(tideFolder);

    // set error out and std out to same stream
    pb.redirectErrorStream(true);
  }

  /**
   * Returns a string with the non-terminal modifications as a string in the Tide format.
   *
   * @return the non-terminal modifications as a string in the Tide format.
   */
  private String getNonTerminalModifications() {

    String tempFixedNonTerminalModifications =
        getNonTerminalModifications(
            searchParameters.getPtmSettings().getFixedModifications(), true);
    String tempVariableNonTerminalModifications =
        getNonTerminalModifications(
            searchParameters.getPtmSettings().getVariableModifications(), false);

    if (!tempFixedNonTerminalModifications.isEmpty()
        && !tempVariableNonTerminalModifications.isEmpty()) {
      tempFixedNonTerminalModifications += "," + tempVariableNonTerminalModifications;
    } else if (!tempVariableNonTerminalModifications.isEmpty()) {
      return tempVariableNonTerminalModifications;
    }

    return tempFixedNonTerminalModifications;
  }

  /**
   * Get the non-terminal modifications as a string in the Tide format.
   *
   * @param modifications the modifications to check
   * @param fixed if the modifications are to to be added as fixed or variable
   * @return the non-terminal modifications as a string in the Tide forma
   */
  private String getNonTerminalModifications(ArrayList<String> modifications, boolean fixed) {

    // tide ptm pattern: [max_per_peptide]residues[+/-]mass_change
    String nonTerminalModifications = "";

    for (String ptmName : modifications) {

      PTM ptm = ptmFactory.getPTM(ptmName);

      if (!ptm.isNTerm() && !ptm.isCTerm()) {

        if (!nonTerminalModifications.isEmpty()) {
          nonTerminalModifications += ",";
        }

        // add the number of allowed ptms per peptide
        if (!fixed) {
          nonTerminalModifications +=
              tideParameters
                  .getMaxVariablePtmsPerTypePerPeptide(); // @TODO: make this modification specific?
        }

        // add the residues affected
        AminoAcidPattern ptmPattern = ptm.getPattern();
        if (ptmPattern != null && ptmPattern.length() > 0) {
          for (Character aminoAcid : ptmPattern.getAminoAcidsAtTarget()) {
            nonTerminalModifications += aminoAcid;
          }
        }

        // add the ptm mass
        if (ptm.getRoundedMass() > 0) {
          nonTerminalModifications += "+";
        }
        nonTerminalModifications += ptm.getRoundedMass();
      }
    }

    return nonTerminalModifications;
  }

  /**
   * Returns a string with the terminal modifications as a string in the Tide format.
   *
   * @param nTerm true if the modifications are n-terminal, false if c-terminal
   * @return the terminal modifications as a string in the Tide format.
   */
  private String getTerminalModifications(boolean nTerm) {

    String tempNTermModifications =
        getTerminalModifications(
            searchParameters.getPtmSettings().getFixedModifications(), true, nTerm);
    String tempCTermModifications =
        getTerminalModifications(
            searchParameters.getPtmSettings().getVariableModifications(), false, nTerm);

    if (!tempNTermModifications.isEmpty() && !tempCTermModifications.isEmpty()) {
      tempNTermModifications += "," + tempCTermModifications;
    } else if (!tempCTermModifications.isEmpty()) {
      return tempCTermModifications;
    }

    return tempNTermModifications;
  }

  /**
   * Get the terminal modifications as a string in the Tide format.
   *
   * @param modifications the modifications to check
   * @param fixed if the modifications are to to be added as fixed or variable
   * @param nTerm true if the modifications are n-terminal, false if c-terminal
   * @return the terminal modifications as a string in the Tide format
   */
  private String getTerminalModifications(
      ArrayList<String> modifications, boolean fixed, boolean nTerm) {

    String terminalModifications = "";

    for (String ptmName : modifications) {

      PTM ptm = ptmFactory.getPTM(ptmName);

      if ((ptm.isNTerm() && nTerm) || (ptm.isCTerm() && !nTerm)) {

        if (!terminalModifications.isEmpty()) {
          terminalModifications += ",";
        }

        // add the number of allowed ptms per peptide
        if (!fixed) {
          terminalModifications += "1";
        }

        // add the residues affected
        AminoAcidPattern ptmPattern = ptm.getPattern();
        String tempPtmPattern = "";
        if (ptmPattern != null && ptmPattern.length() > 0) {
          for (Character aminoAcid : ptmPattern.getAminoAcidsAtTarget()) {
            tempPtmPattern += aminoAcid;
          }
        }

        if (tempPtmPattern.length() == 0) {
          tempPtmPattern = "X";
        }

        terminalModifications += tempPtmPattern;

        // add the ptm mass
        if (ptm.getRoundedMass() > 0) {
          terminalModifications += "+";
        }
        terminalModifications += ptm.getRoundedMass();
      }
    }

    return terminalModifications;
  }

  @Override
  public String getType() {
    return "Tide Indexing Process";
  }

  @Override
  public String getCurrentlyProcessedFileName() {
    return fastaFile.getName();
  }
}