package eu.isas.peptideshaker.cmd;
import com.compomics.util.Util;
import com.compomics.util.db.DerbyUtil;
import com.compomics.util.experiment.biology.EnzymeFactory;
import com.compomics.util.experiment.biology.PTMFactory;
import com.compomics.util.experiment.identification.SequenceFactory;
import com.compomics.util.experiment.massspectrometry.SpectrumFactory;
import com.compomics.util.waiting.WaitingHandler;
import com.compomics.util.gui.waiting.waitinghandlers.WaitingHandlerCLIImpl;
import eu.isas.peptideshaker.PeptideShaker;
import eu.isas.peptideshaker.preferences.PeptideShakerPathPreferences;
import eu.isas.peptideshaker.utils.CpsParent;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
/**
* Command line interface to run follow-up analysis on cps files.
*
* @author Marc Vaudel
*/
public class FollowUpCLI extends CpsParent {
/**
* The follow up options.
*/
private FollowUpCLIInputBean followUpCLIInputBean = null;
/**
* The Progress messaging handler reports the status throughout all
* PeptideShaker processes.
*/
private WaitingHandler waitingHandler;
/**
* The compomics PTM factory.
*/
private PTMFactory ptmFactory = PTMFactory.getInstance();
/**
* The enzyme factory.
*/
private EnzymeFactory enzymeFactory = EnzymeFactory.getInstance();
/**
* Construct a new FollowUpCLI runnable from a FollowUpCLI Bean. When
* initialization is successful, calling "run" will open the PeptideShaker
* project and write the desired output files.
*
* @param followUpCLIInputBean the follow-up options
*/
public FollowUpCLI(FollowUpCLIInputBean followUpCLIInputBean) {
this.followUpCLIInputBean = followUpCLIInputBean;
loadEnzymes();
loadPtms();
}
/**
* 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.hasInput()) {
PathSettingsCLI pathSettingsCLI = new PathSettingsCLI(pathSettingsCLIInputBean);
pathSettingsCLI.setPathSettings();
} else {
try {
setPathConfiguration();
} catch (Exception e) {
System.out.println("An error occurred when setting path configuration. Default will be used.");
e.printStackTrace();
}
}
waitingHandler = new WaitingHandlerCLIImpl();
cpsFile = followUpCLIInputBean.getCpsFile();
try {
loadCpsFile(PeptideShaker.getJarFilePath(), waitingHandler);
} catch (SQLException e) {
waitingHandler.appendReport("An error occurred while reading: " + cpsFile.getAbsolutePath() + ". "
+ "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();
waitingHandler.appendReport(cpsFile.getAbsolutePath() + " successfuly loaded.", true, true);
} catch (Exception e) {
waitingHandler.appendReport("An error occurred while reading: " + cpsFile.getAbsolutePath() + ".", true, true);
e.printStackTrace();
return 1;
}
// Load fasta file
try {
if (!loadFastaFile(waitingHandler)) {
waitingHandler.appendReport("The fasta file was not found, please locate it using the GUI.", true, true);
return 1;
}
waitingHandler.appendReport("Protein database " + searchParameters.getFastaFile().getName() + ".", true, true);
} catch (Exception e) {
waitingHandler.appendReport("An error occurred while loading the fasta file.", true, true);
e.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 locate them using the GUI.", true, true);
} else {
waitingHandler.appendReport("The spectrum file was not found, please locate it using the GUI.", true, true);
}
return 1;
}
waitingHandler.appendReport("Spectrum file(s) successfully loaded.", true, true);
} catch (Exception e) {
waitingHandler.appendReport("An error occurred while loading the spectrum file(s).", true, true);
e.printStackTrace();
return 1;
}
loadGeneMappings(PeptideShaker.getJarFilePath(), waitingHandler);
// recalibrate spectra
if (followUpCLIInputBean.recalibrationNeeded()) {
try {
CLIMethods.recalibrateSpectra(followUpCLIInputBean, identification, annotationPreferences, waitingHandler);
waitingHandler.appendReport("Recalibration process completed.", true, true);
} catch (Exception e) {
waitingHandler.appendReport("An error occurred while recalibrating the spectra.", true, true);
e.printStackTrace();
}
}
// export spectra
if (followUpCLIInputBean.spectrumExportNeeded()) {
try {
CLIMethods.exportSpectra(followUpCLIInputBean, identification, waitingHandler, sequenceMatchingPreferences);
waitingHandler.appendReport("Spectrum export completed.", true, true);
} catch (Exception e) {
waitingHandler.appendReport("An error occurred while exporting the spectra.", true, true);
e.printStackTrace();
}
}
// export protein accessions
if (followUpCLIInputBean.accessionExportNeeded()) {
try {
CLIMethods.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();
}
}
// export protein details
if (followUpCLIInputBean.fastaExportNeeded()) {
try {
CLIMethods.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();
}
}
// progenesis export
if (followUpCLIInputBean.progenesisExportNeeded()) {
try {
CLIMethods.exportProgenesis(followUpCLIInputBean, identification, waitingHandler, sequenceMatchingPreferences);
waitingHandler.appendReport("Progenesis export completed.", true, true);
} catch (Exception e) {
waitingHandler.appendReport("An error occurred while exporting the Progenesis file.", true, true);
e.printStackTrace();
}
}
// Pepnovo training export
if (followUpCLIInputBean.pepnovoTrainingExportNeeded()) {
try {
CLIMethods.exportPepnovoTrainingFiles(followUpCLIInputBean, identification, annotationPreferences, 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();
}
}
// Inclusion list export
if (followUpCLIInputBean.inclusionListNeeded()) {
try {
CLIMethods.exportInclusionList(followUpCLIInputBean, identification, identificationFeaturesGenerator, searchParameters, waitingHandler, filterPreferences);
} catch (Exception e) {
waitingHandler.appendReport("An error occurred while generating the inclusion list.", true, true);
e.printStackTrace();
}
}
try {
closePeptideShaker();
} catch (Exception e) {
waitingHandler.appendReport("An error occurred while closing PeptideShaker.", true, true);
e.printStackTrace();
}
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 null;
}
/**
* Sets the path configuration.
*/
private void setPathConfiguration() throws IOException {
File pathConfigurationFile = new File(PeptideShaker.getJarFilePath(), PeptideShakerPathPreferences.configurationFileName);
if (pathConfigurationFile.exists()) {
PeptideShakerPathPreferences.loadPathPreferencesFromFile(pathConfigurationFile);
}
}
/**
* Close the PeptideShaker instance by clearing up factories and cache.
*
* @throws IOException thrown of IOException occurs
* @throws SQLException thrown if SQLException occurs
*/
public void closePeptideShaker() throws IOException, SQLException {
SpectrumFactory.getInstance().closeFiles();
SequenceFactory.getInstance().closeFile();
identification.close();
DerbyUtil.closeConnection();
File matchFolder = PeptideShaker.getSerializationDirectory(PeptideShaker.getJarFilePath());
File[] tempFiles = matchFolder.listFiles();
if (tempFiles != null) {
for (File currentFile : tempFiles) {
Util.deleteDir(currentFile);
}
}
}
/**
* PeptideShaker follow-up CLI header message when printing the usage.
*/
private static String getHeader() {
return System.getProperty("line.separator")
+ "The PeptideShaker follow-up command line takes a cps file and generates various types of output files." + System.getProperty("line.separator")
+ System.getProperty("line.separator")
+ "For further help see http://peptide-shaker.googlecode.com and http://code.google.com/p/peptide-shaker/wiki/PeptideShakerCLI." + System.getProperty("line.separator")
+ System.getProperty("line.separator")
+ "Or contact the developers at https://groups.google.com/group/peptide-shaker." + System.getProperty("line.separator")
+ System.getProperty("line.separator")
+ "----------------------"
+ System.getProperty("line.separator")
+ "OPTIONS"
+ System.getProperty("line.separator")
+ "----------------------" + System.getProperty("line.separator")
+ System.getProperty("line.separator");
}
/**
* Verifies the command line start parameters.
*
* @return true if the startup was valid
*/
private static boolean isValidStartup(CommandLine aLine) throws IOException {
if (aLine.getOptions().length == 0) {
return false;
}
if (!aLine.hasOption(FollowUpCLIParams.CPS_FILE.id) || ((String) aLine.getOptionValue(FollowUpCLIParams.CPS_FILE.id)).equals("")) {
System.out.println("\n" + FollowUpCLIParams.CPS_FILE.description + " not specified.\n");
return false;
} else {
String fileTxt = aLine.getOptionValue(FollowUpCLIParams.CPS_FILE.id);
File testFile = new File(fileTxt.trim());
if (!testFile.exists()) {
System.out.println("\n" + FollowUpCLIParams.CPS_FILE.description + " \'" + testFile.getAbsolutePath() + "\' not found.\n");
return false;
}
}
return true;
}
/**
* Loads the enzymes from the enzyme file into the enzyme factory.
*/
private void loadEnzymes() {
try {
File lEnzymeFile = new File(PeptideShaker.getJarFilePath() + File.separator + PeptideShaker.ENZYME_FILE);
enzymeFactory.importEnzymes(lEnzymeFile);
} catch (Exception e) {
System.err.println("Not able to load the enzyme file.");
e.printStackTrace();
}
}
/**
* Loads the modifications from the modification file.
*/
public void loadPtms() {
// reset ptm factory
ptmFactory = PTMFactory.getInstance();
try {
ptmFactory.importModifications(new File(PeptideShaker.getJarFilePath(), PeptideShaker.MODIFICATIONS_FILE), false);
} catch (Exception e) {
e.printStackTrace();
}
try {
ptmFactory.importModifications(new File(PeptideShaker.getJarFilePath(), PeptideShaker.USER_MODIFICATIONS_FILE), true);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Starts the launcher by calling the launch method. Use this as the main
* class in the jar file.
*
* @param args the command line arguments
*/
public static void main(String[] args) {
try {
Options lOptions = new Options();
FollowUpCLIParams.createOptionsCLI(lOptions);
BasicParser parser = new BasicParser();
CommandLine line = parser.parse(lOptions, args);
if (!isValidStartup(line)) {
PrintWriter lPrintWriter = new PrintWriter(System.out);
lPrintWriter.print(System.getProperty("line.separator") + "========================================" + System.getProperty("line.separator"));
lPrintWriter.print("PeptideShaker Follow Up - Command Line" + System.getProperty("line.separator"));
lPrintWriter.print("========================================" + System.getProperty("line.separator"));
lPrintWriter.print(getHeader());
lPrintWriter.print(FollowUpCLIParams.getOptionsAsString());
lPrintWriter.flush();
lPrintWriter.close();
System.exit(0);
} else {
FollowUpCLIInputBean lCLIBean = new FollowUpCLIInputBean(line);
FollowUpCLI followUpCLI = new FollowUpCLI(lCLIBean);
followUpCLI.call();
}
} catch (OutOfMemoryError e) {
System.out.println("<CompomicsError>PeptideShaker used up all the memory and had to be stopped. See the PeptideShaker log for details.</CompomicsError>");
System.err.println("Ran out of memory!");
System.err.println("Memory given to the Java virtual machine: " + Runtime.getRuntime().maxMemory() + ".");
System.err.println("Memory used by the Java virtual machine: " + Runtime.getRuntime().totalMemory() + ".");
System.err.println("Free memory in the Java virtual machine: " + Runtime.getRuntime().freeMemory() + ".");
e.printStackTrace();
} catch (Exception e) {
System.out.print("<CompomicsError>PeptideShaker processing failed. See the PeptideShaker log for details.</CompomicsError>");
e.printStackTrace();
}
}
@Override
public String toString() {
return "FollowUpCLI{"
+ ", cliInputBean=" + followUpCLIInputBean
+ '}';
}
}