/* * Eoulsan development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public License version 2.1 or * later and CeCILL-C. This should be distributed with the code. * If you do not have a copy, see: * * http://www.gnu.org/licenses/lgpl-2.1.txt * http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt * * Copyright for this code is held jointly by the Genomic platform * of the Institut de Biologie de l'École normale supérieure and * the individual authors. These should be listed in @author doc * comments. * * For more information on the Eoulsan project and its aims, * or to join the Eoulsan Google group, visit the home page * at: * * http://outils.genomique.biologie.ens.fr/eoulsan * */ package fr.ens.biologie.genomique.eoulsan.modules.expression; import static fr.ens.biologie.genomique.eoulsan.core.ParallelizationMode.OWN_PARALLELIZATION; import static fr.ens.biologie.genomique.eoulsan.core.ParallelizationMode.STANDARD; import static fr.ens.biologie.genomique.eoulsan.data.DataFormats.ADDITIONAL_ANNOTATION_TSV; import static fr.ens.biologie.genomique.eoulsan.data.DataFormats.ANNOTATED_EXPRESSION_RESULTS_ODS; import static fr.ens.biologie.genomique.eoulsan.data.DataFormats.ANNOTATED_EXPRESSION_RESULTS_TSV; import static fr.ens.biologie.genomique.eoulsan.data.DataFormats.ANNOTATED_EXPRESSION_RESULTS_XLSX; import static fr.ens.biologie.genomique.eoulsan.data.DataFormats.EXPRESSION_RESULTS_TSV; import static fr.ens.biologie.genomique.eoulsan.translators.TranslatorUtils.loadTranslator; import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; import com.google.common.base.Splitter; import fr.ens.biologie.genomique.eoulsan.AbstractEoulsanRuntime.EoulsanExecMode; import fr.ens.biologie.genomique.eoulsan.EoulsanException; import fr.ens.biologie.genomique.eoulsan.EoulsanRuntime; import fr.ens.biologie.genomique.eoulsan.Globals; import fr.ens.biologie.genomique.eoulsan.annotations.HadoopCompatible; import fr.ens.biologie.genomique.eoulsan.core.InputPorts; import fr.ens.biologie.genomique.eoulsan.core.InputPortsBuilder; import fr.ens.biologie.genomique.eoulsan.core.Modules; import fr.ens.biologie.genomique.eoulsan.core.OutputPorts; import fr.ens.biologie.genomique.eoulsan.core.OutputPortsBuilder; import fr.ens.biologie.genomique.eoulsan.core.ParallelizationMode; import fr.ens.biologie.genomique.eoulsan.core.Parameter; import fr.ens.biologie.genomique.eoulsan.core.StepConfigurationContext; import fr.ens.biologie.genomique.eoulsan.core.TaskContext; import fr.ens.biologie.genomique.eoulsan.core.TaskResult; import fr.ens.biologie.genomique.eoulsan.core.TaskStatus; import fr.ens.biologie.genomique.eoulsan.core.Version; import fr.ens.biologie.genomique.eoulsan.data.Data; import fr.ens.biologie.genomique.eoulsan.data.DataFile; import fr.ens.biologie.genomique.eoulsan.data.DataFormat; import fr.ens.biologie.genomique.eoulsan.modules.AbstractModule; import fr.ens.biologie.genomique.eoulsan.translators.Translator; import fr.ens.biologie.genomique.eoulsan.translators.TranslatorUtils; import fr.ens.biologie.genomique.eoulsan.translators.io.ODSTranslatorOutputFormat; import fr.ens.biologie.genomique.eoulsan.translators.io.TSVTranslatorOutputFormat; import fr.ens.biologie.genomique.eoulsan.translators.io.TranslatorOutputFormat; import fr.ens.biologie.genomique.eoulsan.translators.io.XLSXTranslatorOutputFormat; /** * This class define a module that create annotated expression files in TSV, ODS * or XLSX format. * @since 2.0 * @author Laurent Jourdren */ @HadoopCompatible public class ExpressionResultsAnnotationModule extends AbstractModule { public static final String MODULE_NAME = "expressionresultsannotation"; public static final String COUNTER_GROUP = "expressionresultsannotation"; private static final DataFormat DEFAULT_FORMAT = ANNOTATED_EXPRESSION_RESULTS_TSV; private final Map<String, DataFormat> outputFormats = new HashMap<>(); private boolean useAdditionalAnnotationFile = true; // // Module methods // @Override public String getName() { return MODULE_NAME; } @Override public String getDescription() { return "This module add annotation to expression files"; } @Override public Version getVersion() { return Globals.APP_VERSION; } @Override public InputPorts getInputPorts() { final InputPortsBuilder builder = new InputPortsBuilder(); // Add the port for the expression file builder.addPort("expressionfile", EXPRESSION_RESULTS_TSV, true); // Add the port for the additional annotation if (this.useAdditionalAnnotationFile) { builder.addPort("additionalannotation", ADDITIONAL_ANNOTATION_TSV, true); } return builder.create(); } @Override public OutputPorts getOutputPorts() { final OutputPortsBuilder builder = new OutputPortsBuilder(); // Set the output ports for (Map.Entry<String, DataFormat> e : this.outputFormats.entrySet()) { builder.addPort(e.getKey() + "output", e.getValue()); } return builder.create(); } @Override public ParallelizationMode getParallelizationMode() { final Collection<DataFormat> formats = this.outputFormats.values(); // XLSX and ODS file creation require lot of memory so multithreading is // disable in local mode to avoid out of memory when several files are // processing at the same time if (EoulsanRuntime.getRuntime().getMode() == EoulsanExecMode.LOCAL && (formats.contains(ANNOTATED_EXPRESSION_RESULTS_ODS) || formats.contains(ANNOTATED_EXPRESSION_RESULTS_XLSX))) { return OWN_PARALLELIZATION; } // TSV creation can be multithreaded return STANDARD; } @Override public void configure(final StepConfigurationContext context, final Set<Parameter> stepParameters) throws EoulsanException { for (final Parameter p : stepParameters) { switch (p.getName()) { case "annotationfile": Modules.removedParameter(context, p); break; case "use.additional.annotation.file": this.useAdditionalAnnotationFile = p.getBooleanValue(); break; case "outputformat": Modules.renamedParameter(context, p, "output.format"); case "output.format": // Set output format for (String format : Splitter.on(',').trimResults().omitEmptyStrings() .split(p.getValue())) { switch (format) { case "tsv": this.outputFormats.put(format, ANNOTATED_EXPRESSION_RESULTS_TSV); break; case "ods": this.outputFormats.put(format, ANNOTATED_EXPRESSION_RESULTS_ODS); break; case "xlsx": this.outputFormats.put(format, ANNOTATED_EXPRESSION_RESULTS_XLSX); break; default: throw new EoulsanException("Unknown output format: " + format); } } break; default: // Unknown option Modules.unknownParameter(context, p); } } // Set the default format if (this.outputFormats.isEmpty()) { this.outputFormats.put(DEFAULT_FORMAT.getDefaultExtension().substring(1), DEFAULT_FORMAT); } } @Override public TaskResult execute(final TaskContext context, final TaskStatus status) { // Get hypertext links file final DataFile linksFile = TranslatorUtils.getLinksFileFromSettings(context.getSettings()); // Load translator final Translator translator; try { if (this.useAdditionalAnnotationFile) { // If no annotation file parameter set final Data additionalAnnotationData = context.getInputData(ADDITIONAL_ANNOTATION_TSV); // Create translator with additional annotation file translator = loadTranslator(additionalAnnotationData.getDataFile(), linksFile); } else { // Create translator without additional annotation file translator = TranslatorUtils.loadTranslator(linksFile); } } catch (IOException e) { return status.createTaskResult(e); } // Define Result StringBuilder resultString = new StringBuilder(); // Convert to TSV try { final Data inData = context.getInputData(EXPRESSION_RESULTS_TSV); final DataFile inFile = inData.getDataFile(); // For each formats for (Map.Entry<String, DataFormat> e : this.outputFormats.entrySet()) { // Get format final DataFormat format = e.getValue(); final Data outData = context.getOutputData(format, inData); final DataFile outFile = outData.getDataFile(); final TranslatorOutputFormat of; if (format == ANNOTATED_EXPRESSION_RESULTS_XLSX) { of = new XLSXTranslatorOutputFormat(outFile.create()); } else if (format == ANNOTATED_EXPRESSION_RESULTS_ODS) { of = new ODSTranslatorOutputFormat(outFile.create()); } else { of = new TSVTranslatorOutputFormat(outFile.create()); } TranslatorUtils.addTranslatorFields(inFile.open(), 0, translator, of); resultString.append("Convert "); resultString.append(inFile); resultString.append(" to "); resultString.append(outFile); resultString.append('\n'); } } catch (IOException e) { return status.createTaskResult(e); } // Set the description of the context status.setDescription(resultString.toString()); // Return the result return status.createTaskResult(); } }