diff --git a/.gitignore b/.gitignore index e5a62def77a249acb7ca38254e86e1f8424d8a7d..c121512a94caf98ad9f4e0b7501aa9313bd375f0 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,4 @@ met4j-core/src/main/java/fr/inra/toulouse/metexplore/met4j_core/Test\.java dependency-reduced-pom.xml -/met4j.sif +*.sif diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ced3b4053e6beffd52dd18dcfff2ac771c6fe651..0e08809cc517d48f24ef649dd8f617c935cae9da 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,6 +3,7 @@ stages: - build - test + - package - deploy - build-containers @@ -11,10 +12,34 @@ stages: image: docker:latest services: - docker:dind + script: + - if [ "$CI_COMMIT_BRANCH" = "master" ]; then docker build -t "$DOCKER_IMAGE:latest" .; fi + - if [ "$CI_COMMIT_BRANCH" = "master" ]; then docker push "$DOCKER_IMAGE:latest"; fi + - if [ "$CI_COMMIT_BRANCH" = "develop" -o "$CI_COMMIT_BRANCH" = "master" ]; then docker build -t "$DOCKER_IMAGE:$VERSION" .; fi + # version in lower case + - if [ "$CI_COMMIT_BRANCH" = "develop" -o "$CI_COMMIT_BRANCH" = "master" -a "$VERSION" != "$LOWER_CASE_VERSION" ]; then docker build -t "$DOCKER_IMAGE:$LOWER_CASE_VERSION" .; fi + - if [ "$CI_COMMIT_BRANCH" = "develop" -o "$CI_COMMIT_BRANCH" = "master" -a "$VERSION" != "$LOWER_CASE_VERSION" ]; then docker push "$DOCKER_IMAGE:$LOWER_CASE_VERSION"; fi + - docker build -t "$DOCKER_IMAGE:$CI_COMMIT_BRANCH" . + - docker push "$DOCKER_IMAGE:$CI_COMMIT_BRANCH" + # branch in lower case + - docker build -t "$DOCKER_IMAGE:$LOWER_CASE_COMMIT_BRANCH" . + - docker push "$DOCKER_IMAGE:$LOWER_CASE_COMMIT_BRANCH" + rules: + - if: $CI_COMMIT_BRANCH == "master" + when: always + - if: $CI_COMMIT_BRANCH == "develop" + when: always + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + when: never + - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH + when: manual + needs: + - build + - package variables: MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" - MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" + MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository" cache: paths: @@ -24,15 +49,45 @@ build: image: maven:3.6-adoptopenjdk-14 stage: build script: - - mvn compile + - mvn $MAVEN_OPTS compile + - TRUEVERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) + - VERSION=$TRUEVERSION + - if [ "$CI_COMMIT_BRANCH" = "master" ]; then VERSION=${VERSION%"-SNAPSHOT"}; fi + - LOWER_CASE_VERSION=${VERSION,,} + - LOWER_CASE_COMMIT_BRANCH=${CI_COMMIT_BRANCH,,} + - echo "VERSION=$VERSION" >> build.env + - echo "TRUEVERSION=$TRUEVERSION" >> build.env + - echo "LOWER_CASE_VERSION=$LOWER_CASE_VERSION" >> build.env + - echo "LOWER_CASE_COMMIT_BRANCH=$LOWER_CASE_COMMIT_BRANCH" >> build.env + artifacts: + expire_in: 60 min + paths: + - target/ + - "*/target" + reports: + dotenv: build.env test: image: maven:3.6-adoptopenjdk-14 stage: test script: - - mvn clean test + - find . -name "*.class" -exec touch {} \+ + - mvn $MAVEN_OPTS clean test - cat coverage/target/site/jacoco-aggregate/index.html | grep -o '<tfoot>.*</tfoot>' +package: + image: maven:3.6-adoptopenjdk-14 + stage: package + script: + - mvn $MAVEN_OPTS clean install -DskipTests=true + - cd met4j-toolbox + - mvn $MAVEN_OPTS package -DskipTests=true + - cd .. + artifacts: + expire_in: 60 min + paths: + - "met4j-toolbox/target/met4j-toolbox-$TRUEVERSION.jar" + deploySnapshot: image: maven:3.6-adoptopenjdk-14 stage: deploy @@ -71,39 +126,35 @@ buildSingularity: entrypoint: [ "" ] script: - singularity build met4j-toolbox.sif met4j.singularity - - singularity push --docker-username "${CI_REGISTRY_USER}" --docker-password "${CI_REGISTRY_PASSWORD}" met4j-toolbox.sif oras://"$CI_REGISTRY_IMAGE"/met4j-singularity:"$CI_COMMIT_TAG" + - if [ "$CI_COMMIT_BRANCH" = "master" ]; then singularity push --docker-username "${CI_REGISTRY_USER}" --docker-password "${CI_REGISTRY_PASSWORD}" met4j-toolbox.sif oras://"$CI_REGISTRY_IMAGE"/met4j-singularity:"latest"; fi + - if [ "$CI_COMMIT_BRANCH" = "develop" -o "$CI_COMMIT_BRANCH" = "master" ]; then singularity push --docker-username "${CI_REGISTRY_USER}" --docker-password "${CI_REGISTRY_PASSWORD}" met4j-toolbox.sif oras://"$CI_REGISTRY_IMAGE"/met4j-singularity:"$VERSION"; fi + # version in lower case + - if [ "$CI_COMMIT_BRANCH" = "develop" -o "$CI_COMMIT_BRANCH" = "master" -a "$VERSION" != "$LOWER_CASE_VERSION"]; then singularity push --docker-username "${CI_REGISTRY_USER}" --docker-password "${CI_REGISTRY_PASSWORD}" met4j-toolbox.sif oras://"$CI_REGISTRY_IMAGE"/met4j-singularity:"$LOWER_CASE_VERSION"; fi + - singularity push --docker-username "${CI_REGISTRY_USER}" --docker-password "${CI_REGISTRY_PASSWORD}" met4j-toolbox.sif oras://"$CI_REGISTRY_IMAGE"/met4j-singularity:"$CI_COMMIT_BRANCH" + # branch in lower case + - singularity push --docker-username "${CI_REGISTRY_USER}" --docker-password "${CI_REGISTRY_PASSWORD}" met4j-toolbox.sif oras://"$CI_REGISTRY_IMAGE"/met4j-singularity:"$LOWER_CASE_COMMIT_BRANCH" rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - when: manual + - if: $CI_COMMIT_BRANCH == "master" + when: always + - if: $CI_COMMIT_BRANCH == "develop" + when: always + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + when: never - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH when: manual + needs: + - build + - package buildDockerProdGitlab: extends: .template_docker before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - script: - - docker build -t "$CI_REGISTRY/metexplore/met4j/met4j-docker:latest" . - - docker push "$CI_REGISTRY/metexplore/met4j/met4j-docker:latest" - rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - when: manual - - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH - when: manual + - DOCKER_IMAGE="$CI_REGISTRY/metexplore/met4j/met4j-docker" + buildDockerProdDockerhub: extends: .template_docker before_script: - docker login -u "$DOCKERHUB_USER" -p "$DOCKERHUB_PASSWORD" $DOCKERHUB_REGISTRY - script: - - docker build --pull -t "$DOCKERHUB_IMAGE:latest" . - - docker push "$DOCKERHUB_IMAGE:latest" - rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - when: manual - - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH - when: manual - - - - + - DOCKER_IMAGE=$DOCKERHUB_IMAGE \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 50f8cf1aa955c0581d989de041f56600cb9845c1..b66d8971e046c69e55c11f820cee41d36f9d4368 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,25 +4,16 @@ RUN export DEBIAN_FRONTEND=noninteractive RUN apt-get update \ && apt-get upgrade -y \ -&& apt-get install -y openjdk-11-jre git maven \ +&& apt-get install -y openjdk-11-jre maven \ && apt-get clean \ && apt-get purge -RUN mkdir -p /opt && cd /opt \ -&& git clone https://forgemia.inra.fr/metexplore/met4j.git \ -&& cd met4j \ -&& mvn install \ -&& cd met4j-toolbox \ -&& mvn package - -RUN mkdir -p /opt/bin \ -&& cd /opt/met4j/met4j-toolbox \ -&& cp target/met4j*.jar /opt/bin/met4j.jar \ -&& cd /opt \ -&& rm -rf met4j ~/.m2 \ -&& apt-get remove -y git && apt-get autoremove -y +RUN mkdir -p /opt/bin COPY ./docker_files/met4j.sh /opt/bin +COPY ./met4j-toolbox/target/met4j*.jar /opt/bin/met4j.jar + +RUN chmod a+x /opt/bin/met4j.sh -ENTRYPOINT ["/opt/bin/met4j.sh"] +RUN cd /usr/bin && ln -s /opt/bin/met4j.sh diff --git a/README.md b/README.md index 743e1f957268abb913724f8d56054a8d59052050..d6b0a92b47fec307da994445a396b4a716c8b00f 100644 --- a/README.md +++ b/README.md @@ -10,17 +10,14 @@ **Met4J is an open-source Java library dedicated to the structural analysis of metabolic networks. It also came with a toolbox gathering CLI for several analyses relevant to metabolism-related research.** -Met4j is composed by several modules: +Met4j is composed by three main modules: - [met4j-core](met4j-core/README.md): it's the key module which contains all the core classes for handling metabolic networks - [met4j-io](met4j-io/README.md): for importing/exporting metabolic networks in several formats (SBML, MetExploreXml, KEGG) - [met4j-graph](met4j-graph/README.md): for performing graph-based topological analysis of metabolic networks. -The other modules contains utilities to serve the main modules listed here. - -The full list of implemented metabolic network analysis can be found in the [met4j-toolbox](met4j-toolbox/README.md) - +The package [met4j-toolbox](met4j-toolbox/README.md) contains high-level apps that can be run in command line by using either jar file or Singularity or Docker containers. ## Installation @@ -52,41 +49,22 @@ git clone https://forgemia.inra.fr/metexplore/met4j.git; cd met4j; mvn clean install ``` -to build the executable toolbox jar: -``` -cd met4j-toolbox -mvn clean compile assembly:single -mv ./target/*-jar-with-dependencies.jar ../../../ -``` ## Usage Documentation for the library modules can be found in each module's own README. -Detailed code examples can be found at [here](https://forgemia.inra.fr/metexplore/tutorialmet4j). - -The toolbox can be launched using -``` -java -jar met4j-toolbox-0.8.0-jar-with-dependencies.jar -``` -which will list all the contained applications that can be called using - -``` -java -cp met4j-toolbox-0.8.0-jar-with-dependencies.jar <App full name> -h -``` - -### With singularity - -You need at least [singularity](https://sylabs.io/guides/3.5/user-guide/quick_start.html) v3.5. - -```console -singularity pull met4j-toolbox.sif oras://registry.forgemia.inra.fr/metexplore/met4j/met4j-singularity:latest -``` +Detailed code examples can be found at [here](https://forgemia.inra.fr/metexplore/tutorialmet4j). ## Contributing + Pull requests are welcome **on the gitlab repo** ([https://forgemia.inra.fr/metexplore/met4j](https://forgemia.inra.fr/metexplore/met4j)). For major changes, please open an issue first to discuss what you would like to change. Please make sure to update tests as appropriate. +## Issues + +Issues or suggestions can be posted [here](https://forgemia.inra.fr/metexplore/met4j/-/issues). + ## License Met4J is distributed under the open license [CeCILL-2.1](https://cecill.info/licences/Licence_CeCILL_V2.1-en.html) (compatible GNU-GPL). diff --git a/docker_files/met4j.sh b/docker_files/met4j.sh index 23a5411e00c290f04b40c2eed72811425731644e..6369824abdd9ee81ae331b7b65106cbc627d2800 100644 --- a/docker_files/met4j.sh +++ b/docker_files/met4j.sh @@ -44,6 +44,6 @@ if [ $# -lt 1 ] echo "display Help" exec java -jar $path_jar else - echo "Lauch met4j-toolbox" + echo "Launch met4j-toolbox" exec java -Dlog4j.configuration= -cp $path_jar fr.inrae.toulouse.metexplore.met4j_toolbox."$@" fi \ No newline at end of file diff --git a/met4j-core/src/main/java/fr/inrae/toulouse/metexplore/met4j_core/biodata/BioEntity.java b/met4j-core/src/main/java/fr/inrae/toulouse/metexplore/met4j_core/biodata/BioEntity.java index 3d4fa6a1e4ffaee7e8ecd8224f0b8809075e12dd..98afdd160fb43ef0f12c5a498be9cb4dcd7047da 100755 --- a/met4j-core/src/main/java/fr/inrae/toulouse/metexplore/met4j_core/biodata/BioEntity.java +++ b/met4j-core/src/main/java/fr/inrae/toulouse/metexplore/met4j_core/biodata/BioEntity.java @@ -81,7 +81,7 @@ public abstract class BioEntity { */ public BioEntity(String id, String name) { if (StringUtils.isVoid(id)) { - String newId = UUID.randomUUID().toString().replaceAll("-", "_"); + String newId = "_"+UUID.randomUUID().toString().replaceAll("-", "_"); this.id = newId; } else { this.id = id; diff --git a/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/reader/plugin/AnnotationParser.java b/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/reader/plugin/AnnotationParser.java index e13041383418bd857ba2e71af13c1e6c45203bee..11dc21dc78a675895e00355a12fc2f0cc7340350 100644 --- a/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/reader/plugin/AnnotationParser.java +++ b/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/reader/plugin/AnnotationParser.java @@ -64,234 +64,225 @@ import static fr.inrae.toulouse.metexplore.met4j_core.utils.StringUtils.*; * because they do not extend the {@link fr.inrae.toulouse.metexplore.met4j_core.biodata.BioPhysicalEntity} class * * @author Benjamin - * @since 3.0 * @version $Id: $Id + * @since 3.0 */ public class AnnotationParser implements PackageParser, AdditionalDataTag, ReaderSBML1Compatible, ReaderSBML2Compatible, - ReaderSBML3Compatible { - - /** Constant <code>ORIGIN="SBML"</code> */ - public static final String ORIGIN = "SBML"; - - /** - * The Jsbml Model - */ - public Model model; - /** - * The BioNetwork - */ - public BioNetwork bionetwork; - - /** - * The user defined annotation pattern used in the regular expression of - * this class - */ - public String annotationPattern; - - /** - * The default annotation pattern: - * <ul> - * <li>http://identifiers.org/([^/]+)/(.*) - * </ul> - * The first parenthesis group is - */ - public static final String defaultAnnotationPattern = "https?://identifiers.org/([^/]+)/(.*)"; - - /** - * Constructor - * - * @param useDefault - * true to use the {@link #defaultAnnotationPattern} - */ - public AnnotationParser(boolean useDefault) { - if (useDefault) - this.setAnnotationPattern(defaultAnnotationPattern); - } - - /** - * Constructor - * - * @param pattern - * the user defined pattern - */ - public AnnotationParser(String pattern) { - this.annotationPattern = pattern; - } - - /** - * <p>getAssociatedPackageName.</p> - * - * @return a {@link java.lang.String} object. - */ - public String getAssociatedPackageName() { - return "annot"; - } - - /** {@inheritDoc} */ - public boolean isPackageUseableOnModel(Model model) { - return true; - } - - /** - * {@inheritDoc} - * - * Parse all model entities to retrieve their annotations and extract the - * desired information - */ - public void parseModel(Model model, BioNetwork bionetwork) { - System.err.println("Starting " + this.getAssociatedPackageName() + " plugin..."); - - this.setBionetwork(bionetwork); - this.setModel(model); - - this.parseAnnotation(bionetwork,model.getAnnotation()); - - this.parseSbmlAnnotations(bionetwork.getReactionsView()); - this.parseSbmlAnnotations(bionetwork.getMetabolitesView()); - this.parseSbmlAnnotations(bionetwork.getGenesView()); - this.parseSbmlAnnotations(bionetwork.getCompartmentsView()); - } - - /** - * - * One of the different lists present in the {@link BioNetwork} - * class - */ - private void parseSbmlAnnotations(BioCollection<?> collection) { - - for (BioEntity entry : collection) { - - String id = entry.getId(); - - if(entry.getAttribute("oldId") != null) - { - id = (String) entry.getAttribute("oldId"); - } - - UniqueNamedSBase sbase = this.getModel().findUniqueNamedSBase(id); - - if (sbase != null && !sbase.getAnnotation().isEmpty() && sbase.hasValidAnnotation()) { - - this.parseAnnotation(entry, sbase.getAnnotation()); - - } - } - } - - /** - * Parse entity's annotation to extract external identifiers - * - * @param annot - * the SBML annotation element - */ - private void parseAnnotation(BioEntity ent, Annotation annot) { - - Matcher m; - for (CVTerm cv : annot.getListOfCVTerms()) { - - String qual; - - if(cv.isBiologicalQualifier()) { - - qual = cv.getBiologicalQualifierType().getElementNameEquivalent(); - } - else { - qual = cv.getModelQualifierType().getElementNameEquivalent(); - } - - for (String ress : cv.getResources()) { - if (this.getAnnotationPattern() != null - && (m = Pattern.compile(this.getAnnotationPattern()).matcher(ress)).matches()) { - - if (m.group(1).equalsIgnoreCase("ec-code") && ent instanceof BioReaction) { - String oldEc = ((BioReaction) ent).getEcNumber(); - if(isVoid(oldEc)) - { - ((BioReaction) ent).setEcNumber(m.group(2)); - } - else { - ((BioReaction) ent).setEcNumber(oldEc+";"+m.group(2)); - } - } - ent.addRef(m.group(1), m.group(2), 1, qual, ORIGIN); - } - } - } - - String nonrdfAnnot = annot.getNonRDFannotationAsString(); - if (ent instanceof BioMetabolite && nonrdfAnnot != null && !nonrdfAnnot.isEmpty()) { - - String specialInchiPattern = "<in:inchi xmlns:in=\"([^\"]+)\">InChI=([^<]+)</in:inchi>"; - - m = Pattern.compile(specialInchiPattern, Pattern.DOTALL).matcher(nonrdfAnnot); - - while (m.find()) { - - if (m.group(1).equalsIgnoreCase("http://biomodels.net/inchi")) { - String inchi = m.group(2); - if (!ent.hasRef("inchi", inchi)) { - ent.addRef("inchi", inchi, 1, "is", ORIGIN); - } - } - } - } - } - - /** - * <p>Getter for the field <code>model</code>.</p> - * - * @return the model - */ - public Model getModel() { - return model; - } - - /** - * <p>Setter for the field <code>model</code>.</p> - * - * @param model - * the model to set - */ - public void setModel(Model model) { - this.model = model; - } - - /** - * <p>Getter for the field <code>bionetwork</code>.</p> - * - * @return the bionetwork - */ - public BioNetwork getBionetwork() { - return bionetwork; - } - - /** - * <p>Setter for the field <code>bionetwork</code>.</p> - * - * @param bionetwork - * the bionetwork to set - */ - public void setBionetwork(BioNetwork bionetwork) { - this.bionetwork = bionetwork; - } - - /** - * <p>Getter for the field <code>annotationPattern</code>.</p> - * - * @return the annotationPattern - */ - public String getAnnotationPattern() { - return annotationPattern; - } - - /** - * <p>Setter for the field <code>annotationPattern</code>.</p> - * - * @param annotationPattern - * the annotationPattern to set - */ - public void setAnnotationPattern(String annotationPattern) { - this.annotationPattern = annotationPattern; - } + ReaderSBML3Compatible { + + /** + * Constant <code>ORIGIN="SBML"</code> + */ + public static final String ORIGIN = "SBML"; + + /** + * The Jsbml Model + */ + public Model model; + /** + * The BioNetwork + */ + public BioNetwork bionetwork; + + /** + * The user defined annotation pattern used in the regular expression of + * this class + */ + public String annotationPattern; + + /** + * The default annotation pattern: + * <ul> + * <li>http://identifiers.org/([^/]+)/(.*) + * </ul> + * The first parenthesis group is + */ + public static final String defaultAnnotationPattern = "https?://identifiers.org/([^/]+)/(.*)"; + + /** + * Constructor + * + * @param useDefault true to use the {@link #defaultAnnotationPattern} + */ + public AnnotationParser(boolean useDefault) { + if (useDefault) + this.setAnnotationPattern(defaultAnnotationPattern); + } + + /** + * Constructor + * + * @param pattern the user defined pattern + */ + public AnnotationParser(String pattern) { + this.annotationPattern = pattern; + } + + /** + * <p>getAssociatedPackageName.</p> + * + * @return a {@link java.lang.String} object. + */ + public String getAssociatedPackageName() { + return "annot"; + } + + /** + * {@inheritDoc} + */ + public boolean isPackageUseableOnModel(Model model) { + return true; + } + + /** + * {@inheritDoc} + * <p> + * Parse all model entities to retrieve their annotations and extract the + * desired information + */ + public void parseModel(Model model, BioNetwork bionetwork) { + System.err.println("Starting " + this.getAssociatedPackageName() + " plugin..."); + + this.setBionetwork(bionetwork); + this.setModel(model); + + this.parseAnnotation(bionetwork, model.getAnnotation()); + + this.parseSbmlAnnotations(bionetwork.getReactionsView()); + this.parseSbmlAnnotations(bionetwork.getMetabolitesView()); + this.parseSbmlAnnotations(bionetwork.getGenesView()); + this.parseSbmlAnnotations(bionetwork.getCompartmentsView()); + } + + /** + * One of the different lists present in the {@link BioNetwork} + * class + */ + private void parseSbmlAnnotations(BioCollection<?> collection) { + + for (BioEntity entry : collection) { + + String id = entry.getId(); + + if (entry.getAttribute("oldId") != null) { + id = (String) entry.getAttribute("oldId"); + } + + UniqueNamedSBase sbase = this.getModel().findUniqueNamedSBase(id); + + if (sbase != null && !sbase.getAnnotation().isEmpty() && sbase.hasValidAnnotation()) { + + this.parseAnnotation(entry, sbase.getAnnotation()); + + } + } + } + + /** + * Parse entity's annotation to extract external identifiers + * + * @param annot the SBML annotation element + */ + private void parseAnnotation(BioEntity ent, Annotation annot) { + + Matcher m; + for (CVTerm cv : annot.getListOfCVTerms()) { + + String qual; + + if (cv.isBiologicalQualifier()) { + + qual = cv.getBiologicalQualifierType().getElementNameEquivalent(); + } else { + qual = cv.getModelQualifierType().getElementNameEquivalent(); + } + + for (String ress : cv.getResources()) { + if (this.getAnnotationPattern() != null + && (m = Pattern.compile(this.getAnnotationPattern()).matcher(ress)).matches()) { + + if (m.group(1).equalsIgnoreCase("ec-code") && ent instanceof BioReaction) { + String oldEc = ((BioReaction) ent).getEcNumber(); + if (isVoid(oldEc)) { + ((BioReaction) ent).setEcNumber(m.group(2)); + } else { + ((BioReaction) ent).setEcNumber(oldEc + ";" + m.group(2)); + } + } + ent.addRef(m.group(1), m.group(2), 1, qual, ORIGIN); + } + } + } + + String nonrdfAnnot = annot.getNonRDFannotationAsString(); + if (ent instanceof BioMetabolite && nonrdfAnnot != null && !nonrdfAnnot.isEmpty()) { + + String specialInchiPattern = "InChI=([^<]+)"; + + m = Pattern.compile(specialInchiPattern, Pattern.DOTALL).matcher(nonrdfAnnot); + + while (m.find()) { + String inchi = m.group(1); + if (!ent.hasRef("inchi", inchi)) { + ent.addRef("inchi", inchi, 1, "is", ORIGIN); + ((BioMetabolite) ent).setInchi(inchi); + } + } + } + } + + /** + * <p>Getter for the field <code>model</code>.</p> + * + * @return the model + */ + public Model getModel() { + return model; + } + + /** + * <p>Setter for the field <code>model</code>.</p> + * + * @param model the model to set + */ + public void setModel(Model model) { + this.model = model; + } + + /** + * <p>Getter for the field <code>bionetwork</code>.</p> + * + * @return the bionetwork + */ + public BioNetwork getBionetwork() { + return bionetwork; + } + + /** + * <p>Setter for the field <code>bionetwork</code>.</p> + * + * @param bionetwork the bionetwork to set + */ + public void setBionetwork(BioNetwork bionetwork) { + this.bionetwork = bionetwork; + } + + /** + * <p>Getter for the field <code>annotationPattern</code>.</p> + * + * @return the annotationPattern + */ + public String getAnnotationPattern() { + return annotationPattern; + } + + /** + * <p>Setter for the field <code>annotationPattern</code>.</p> + * + * @param annotationPattern the annotationPattern to set + */ + public void setAnnotationPattern(String annotationPattern) { + this.annotationPattern = annotationPattern; + } } diff --git a/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/writer/plugin/AnnotationWriter.java b/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/writer/plugin/AnnotationWriter.java index 1e971c1c1e04461ca3c24f3ad2fa1b49960f79b5..e7eac52933305318af95583099b022d2c191cbf1 100644 --- a/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/writer/plugin/AnnotationWriter.java +++ b/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/writer/plugin/AnnotationWriter.java @@ -247,7 +247,7 @@ public class AnnotationWriter implements PackageWriter, AdditionalDataTag { addingLoop: for (BioRef r : refs) { - if (IdentifiersOrg.validIdentifiers.contains(r.getDbName().toLowerCase())){ + if (IdentifiersOrg.validIdentifiers.contains(r.getDbName().toLowerCase()) && ! r.getDbName().equalsIgnoreCase("inchi")){ Qualifier qual; diff --git a/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/tabulated/attributes/SetEcsFromFile.java b/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/tabulated/attributes/SetEcsFromFile.java index dc26b9d9ca3ca8739253d386912c3020ed6e8a5a..b727d3c71175cbbe9ac8656ed2aecddf61f45043 100644 --- a/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/tabulated/attributes/SetEcsFromFile.java +++ b/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/tabulated/attributes/SetEcsFromFile.java @@ -86,8 +86,6 @@ public class SetEcsFromFile extends AbstractSetAttributesFromFile { String[] ecs = ec.split(";"); - System.err.println("ec : "+ec+" l :"+ecs.length); - return Arrays.stream(ecs).allMatch(e -> { Matcher m = patternEC.matcher(e); return m.matches(); diff --git a/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/tabulated/attributes/SetRefsFromFile.java b/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/tabulated/attributes/SetRefsFromFile.java index ceecebf70fbe48138d1eed1d07162d12da547440..b692e5bf810c583610e1a17591cecb3bdf225410 100644 --- a/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/tabulated/attributes/SetRefsFromFile.java +++ b/met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/tabulated/attributes/SetRefsFromFile.java @@ -101,7 +101,7 @@ public class SetRefsFromFile extends AbstractSetAttributesFromFile { int n = 0; - if(! IdentifiersOrg.validIdentifiers.contains(ref)) { + if(! IdentifiersOrg.validIdentifiers.contains(ref.toLowerCase())) { System.err.println("Warning : the identifier "+ref+" is not a valid id in identifiers.org"); } diff --git a/met4j-io/src/test/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/reader/plugin/AnnotationParserTest.java b/met4j-io/src/test/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/reader/plugin/AnnotationParserTest.java index 16ef8c774d8a302a69feb85387df81c51c13ffa1..b947050b6ea81401dc3c9a60baa50a1417e890cc 100644 --- a/met4j-io/src/test/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/reader/plugin/AnnotationParserTest.java +++ b/met4j-io/src/test/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/reader/plugin/AnnotationParserTest.java @@ -260,6 +260,9 @@ public class AnnotationParserTest { assertEquals(refInchis, s1.getRefs()); + System.err.println(s1.getInchi()); + + assertEquals("truc", s1.getInchi()); } } diff --git a/met4j-toolbox/README.md b/met4j-toolbox/README.md index 4d51cca3d779ce910a5697cc48955b44b5a7406e..1fecda21c4612405214a20809c00d56146ba9ad6 100644 --- a/met4j-toolbox/README.md +++ b/met4j-toolbox/README.md @@ -1,8 +1,13 @@ # met4j-toolbox **Met4j command-line toolbox for metabolic networks** -## Installation +## Installation from source + ``` +git clone https://forgemia.inra.fr/metexplore/met4j.git; +cd met4j; +mvn clean install + cd met4j-toolbox mvn clean package ``` @@ -10,12 +15,120 @@ mvn clean package ## Usage The toolbox can be launched using ``` -java -jar met4j-toolbox-<version>.jar +java -jar target/met4j-toolbox-<version>.jar ``` which will list all the contained applications that can be called using ``` -java -cp met4j-toolbox-<version>.jar <Package>.<App name> -h +java -cp target/met4j-toolbox-<version>.jar <Package>.<App name> -h +``` + + +## From singularity + +You need at least [singularity](https://sylabs.io/guides/3.5/user-guide/quick_start.html) v3.5. + +```console +singularity pull met4j-toolbox.sif oras://registry.forgemia.inra.fr/metexplore/met4j/met4j-singularity:latest +``` + +If you want a specific version: + +```console +singularity pull met4j-toolbox.sif oras://registry.forgemia.inra.fr/metexplore/met4j/met4j-singularity:x.y.z +``` + +If you want the last develop version: + +```console +singularity pull met4j-toolbox.sif oras://registry.forgemia.inra.fr/metexplore/met4j/met4j-singularity:develop +``` + +If you want to build by yourself the singularity image: + +```console +cd met4j-toolbox +mvn package +cd ../ +singularity build met4j-toolbox.sif met4j.singularity +``` + + +This will download a singularity container met4j-toolbox.sif that you can directly launch. + +To list all the apps. +```console +met4j-toolbox.sif +``` + +To launch a specific app, prefix its name with the last component of its package name. For instance: + +```console +met4j-toolbox.sif convert.Tab2Sbml -h -in fic.tsv -sbml fic.sbml +``` + +By default, singularity does not see the directories that are not descendants of your home directory. To get the directories outside your home directory, you have to specify the SINGULARITY_BIND environment variable. +At least, to get the data in the default reference directory, you have to specify: +In bash: +```console +export SINGULARITY_BIND=/db +``` +In csh or in tcsh +```console +setenv SINGULARITY_BIND /db +``` + +## From docker + +First install [Docker](https://www.docker.com/). + +Pull the latest met4j image: + +```console +sudo docker pull metexplore/met4j:latest +``` + +If you want a specific version: + +```console +sudo docker pull metexplore/met4j:x.y.z +``` + +If you want the develop version: +```console +sudo docker pull metexplore/met4j:develop +``` + +If you want to build by yourself the docker image: + +```console +cd met4j-toolbox +mvn package +cd ../ +sudo docker build -t metexplore/met4j:myversion . +``` + + +To list all the apps: +```console +sudo docker run metexplore/met4j:latest met4j.sh +``` + +Don't forget to map volumes when you want to process local files. +Example: + +```console +sudo docker run -v /home/lcottret/work:/work \ + metexplore/met4j:latest met4j.sh convert.Sbml2Tab \ + -in /work/toy_model.xml -out /work/toy_model.tsv +``` + +If you change the working directory, you have to specify "sh /usr/bin/met4j.sh": + +```console +sudo docker run -w /work -v /home/lcottret/work:/work \ + metexplore/met4j:latest sh /usr/bin/met4j.sh convert.Sbml2Tab \ + -in toy_model.xml -out toy_model.tsv ``` ## Features diff --git a/met4j-toolbox/pom.xml b/met4j-toolbox/pom.xml index 1dbc1e80e9ad13788f0c897fdc5f136f03e95022..b122cd649af9d27fd4e17d81c396f2b16b7631fa 100644 --- a/met4j-toolbox/pom.xml +++ b/met4j-toolbox/pom.xml @@ -66,6 +66,11 @@ <artifactId>json-simple</artifactId> <version>1.1.1</version> </dependency> + <dependency> + <groupId>org.hibernate.validator</groupId> + <artifactId>hibernate-validator</artifactId> + <version>6.0.17.Final</version> + </dependency> </dependencies> <description>Bundle of all met4j modules and api</description> @@ -100,6 +105,7 @@ </mainClass> <manifestEntries> <Multi-Release>true</Multi-Release> + <Implementation-Version>${project.version}</Implementation-Version> </manifestEntries> </transformer> <transformer diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/GenerateGalaxyFiles.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/GenerateGalaxyFiles.java new file mode 100644 index 0000000000000000000000000000000000000000..ecc44d2ed1e14127a3d55d18bb590a812612ac77 --- /dev/null +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/GenerateGalaxyFiles.java @@ -0,0 +1,226 @@ +/* + * Copyright INRAE (2022) + * + * contact-metexplore@inrae.fr + * + * This software is a computer program whose purpose is to [describe + * functionalities and technical features of your software]. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "https://cecill.info/licences/Licence_CeCILL_V2.1-en.html". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * + */ +package fr.inrae.toulouse.metexplore.met4j_toolbox; + +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.utils.ResourceURLFilter; +import fr.inrae.toulouse.metexplore.met4j_toolbox.utils.Resources; +import org.apache.commons.lang3.ClassUtils; +import org.kohsuke.args4j.Option; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class GenerateGalaxyFiles extends AbstractMet4jApplication { + + + @Option(name = "-o", usage = "output directory where the galaxy wrappers and the tool_conf.xml will be written", required = true) + public String outputDirectory; + + @Option(name = "-p", usage = "Package type", required = false) + public GalaxyPackageType packageType = GalaxyPackageType.Singularity; + + @Option(name = "-v", usage = "Met4j version", required = false) + public String version = "latest"; + + public static void main(String[] args) { + + GenerateGalaxyFiles app = new GenerateGalaxyFiles(); + app.parseArguments(args); + app.run(); + } + + private void run() { + + try { + + DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance(); + + DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder(); + + Document toolConf = documentBuilder.newDocument(); + + Element root = toolConf.createElement("toolbox"); + + root.setAttribute("monitor", "true"); + toolConf.appendChild(root); + + Element section = toolConf.createElement("section"); + section.setAttribute("id", "met4j"); + section.setAttribute("name", "met4j apps"); + + root.appendChild(section); + + ResourceURLFilter filter = u -> { + + String path = GenerateGalaxyFiles.class.getPackage().getName() + .replace(".", "/"); + + String s = u.getFile(); + return s.endsWith(".class") && !s.contains("$") + && s.contains(path); + }; + + + File rep = new File(this.outputDirectory); + + if (rep.exists() && !rep.isDirectory()) { + System.err.println(this.outputDirectory + " already exists and it's a file not a directory..."); + System.exit(1); + } + + if (!rep.exists()) { + if (!rep.mkdir()) { + System.err.println("Impossible to create the directory " + this.outputDirectory); + System.exit(1); + } + } + + String path = GenerateGalaxyFiles.class.getPackage().getName() + .replace(".", "/"); + + int n = 0; + + List<URL> sortedUrls = Resources.getResourceURLs(Resources.class, filter).stream().sorted(Comparator.comparing(URL::getPath)).collect(Collectors.toList()); + + String toolPackage = ""; + + for (URL u : sortedUrls){ + + String entry = u.getFile(); + int idx = entry.indexOf(path); + + entry = entry.substring(idx, entry.length() - ".class".length()); + + Class<?> myClass = Class.forName(entry.replace('/', '.')); + + List<Class<?>> allSuperclasses = ClassUtils.getAllSuperclasses(myClass); + + if (myClass != this.getClass() + && allSuperclasses.contains(AbstractMet4jApplication.class)) { + + Constructor<?> ctor = myClass.getConstructor(); + + try { + Object obj = ctor.newInstance(); + + Class methodArgs[] = new Class[3]; + methodArgs[0] = String.class; + methodArgs[1] = GalaxyPackageType.class; + methodArgs[2] = String.class; + + System.err.println(obj.getClass().getName()); + + Method method = obj.getClass().getMethod("xmlGalaxyWrapper", methodArgs); + method.invoke(obj, this.outputDirectory, this.packageType, this.version); + + Element tool = toolConf.createElement("tool"); + + Method getPackageName = obj.getClass().getMethod("getSimplePackageName"); + String packageName = (String) getPackageName.invoke(obj); + + if(! packageName.equals(toolPackage)) { + Element label = toolConf.createElement("label"); + label.setAttribute("id", packageName); + label.setAttribute("text", "met4j "+packageName); + label.setAttribute("version", ""); + section.appendChild(label); + toolPackage = packageName; + } + + String className = obj.getClass().getSimpleName(); + + tool.setAttribute("file", "met4j/" + packageName + "/" + className + "/" + className + ".xml"); + + section.appendChild(tool); + + n++; + } catch (InstantiationException e) { + // It's not a class that can be instantiated + } + + } + } + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); + DOMSource domSource = new DOMSource(toolConf); + StreamResult streamResult = new StreamResult(new File(outputDirectory + "/tool_conf.xml")); + + transformer.transform(domSource, streamResult); + + } catch (Exception e) { + e.printStackTrace(); + System.err.println("Problem while creating galaxy file tree"); + System.exit(1); + } + + + } + + @Override + public String getLabel() { + return this.getClass().getSimpleName(); + } + + @Override + public String getLongDescription() { + return this.getShortDescription() + "\n" + + "Creates a directory for each app with inside the galaxy xml wrapper."; + } + + @Override + public String getShortDescription() { + return "Create the galaxy file tree containing met4j-toolbox app wrappers"; + } +} \ No newline at end of file diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/GenerateJson.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/GenerateJson.java new file mode 100644 index 0000000000000000000000000000000000000000..6d679244e2d59de422fea4de2fea4ca13e5bfb98 --- /dev/null +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/GenerateJson.java @@ -0,0 +1,117 @@ +/* + * Copyright INRAE (2022) + * + * contact-metexplore@inrae.fr + * + * This software is a computer program whose purpose is to [describe + * functionalities and technical features of your software]. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "https://cecill.info/licences/Licence_CeCILL_V2.1-en.html". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * + */ +package fr.inrae.toulouse.metexplore.met4j_toolbox; + +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.utils.ResourceURLFilter; +import fr.inrae.toulouse.metexplore.met4j_toolbox.utils.Resources; +import org.apache.commons.lang3.ClassUtils; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.List; + +public class GenerateJson { + + + public static void main(String[] args) { + try { + + + ResourceURLFilter filter = new ResourceURLFilter() { + + public @Override + boolean accept(URL u) { + + String path = GenerateJson.class.getPackage().getName() + .replace(".", "/"); + + String s = u.getFile(); + return s.endsWith(".class") && !s.contains("$") + && s.contains(path); + } + }; + + String jsonStr = "{\"status\":\"true\",\"apps\":["; + + String path = GenerateJson.class.getPackage().getName() + .replace(".", "/"); + + + int n = 0; + + for (URL u : Resources.getResourceURLs(Resources.class, filter)) { + + String entry = u.getFile(); + int idx = entry.indexOf(path); + + entry = entry.substring(idx, entry.length() - ".class".length()); + + Class<?> myClass = Class.forName(entry.replace('/', '.')); + + List<Class<?>> allSuperclasses = ClassUtils.getAllSuperclasses(myClass); + + if (allSuperclasses.contains(AbstractMet4jApplication.class)) { + + Constructor<?> ctor = myClass.getConstructor(); + + try { + Object obj = ctor.newInstance(); + + Method method = obj.getClass().getMethod("json"); + if (n > 0) { + jsonStr += ","; + } + jsonStr += method.invoke(obj); + n++; + } catch (InstantiationException e) { + // It's not a class that can be instantiated + } + + } + } + + jsonStr += "]}"; + + System.out.println(jsonStr); + + } catch (Exception e) { + System.out.println("{\"status\":\"false\"}"); + e.printStackTrace(); + } + } +} diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSet.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSet.java index 96b8c9b8b85d4face093f5fe8385e7ff8dc3245d..c21aa34a263b9f8e7a700579b613661b94745805 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSet.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSet.java @@ -41,10 +41,14 @@ import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.writer.JsbmlWriter; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.*; import org.kohsuke.args4j.Option; import java.io.IOException; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.*; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.*; + /** * <p>Abstract AbstractSbmlSet class.</p> * @@ -54,19 +58,26 @@ import java.io.IOException; public abstract class AbstractSbmlSet extends AbstractMet4jApplication { @Option(name="-n", usage="[0] Number of lines to skip at the beginning of the tabulated file") - protected int nSkip = 0; + public int nSkip = 0; + @Format(name= Sbml) + @ParameterType(name = OutputFile) @Option(name="-out", usage="[out.sbml] Out sbml file") - protected String out = "out.sbml"; + public String out = "out.sbml"; + @Format(name= Sbml) + @ParameterType(name = InputFile) @Option(name="-sbml", usage="Original sbml file", required=true) - protected String sbml; + public String sbml; + @ParameterType(name = InputFile) + @Format(name= Tsv) @Option(name="-tab", usage="Tabulated file") - protected String tab; + public String tab; + @ParameterType(name= EnumParameterTypes.Text) @Option(name="-c", usage="[#] Comment String in the tabulated file. The lines beginning by this string won't be read") - protected String c="#"; + public String c="#"; /** * <p>Constructor for AbstractSbmlSet.</p> @@ -86,7 +97,7 @@ public abstract class AbstractSbmlSet extends AbstractMet4jApplication { } catch (IOException e) { e.printStackTrace(); System.err.println("Unable to read the sbml file "+this.sbml); - System.exit(0); + System.exit(1); } BioNetwork bn = null; @@ -95,7 +106,7 @@ public abstract class AbstractSbmlSet extends AbstractMet4jApplication { } catch (Met4jSbmlReaderException e) { e.printStackTrace(); System.err.println("Problem while reading the sbml file "+this.sbml); - System.exit(0); + System.exit(1); } return bn; @@ -115,7 +126,7 @@ public abstract class AbstractSbmlSet extends AbstractMet4jApplication { } catch (Exception e) { e.printStackTrace(); System.err.println("Error in writing the sbml file"); - System.exit(0); + System.exit(1); } } diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSetAny.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSetAny.java index c62e3ce2abc4d29dd7b6bb21380201e1d9a68e56..a6938318760ad1d9e38752a9c5af93ea9afd7b93 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSetAny.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSetAny.java @@ -37,8 +37,12 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.attributes; import fr.inrae.toulouse.metexplore.met4j_io.tabulated.attributes.EntityType; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.*; + /** * <p>Abstract AbstractSbmlSetAny class.</p> * @@ -50,17 +54,19 @@ public abstract class AbstractSbmlSetAny extends AbstractSbmlSet { public final String setDescription = "The ids must correspond between the tabulated file and the SBML file.\n" + "If prefix or suffix is different in the SBML file, use the -p or the -s options."; + @ParameterType(name=Text) @Option(name="-ci", usage="[1] number of the column where are the object ids") - protected int colid=1; + public int colid=1; @Option(name="-p", usage="[deactivated] To match the objects in the sbml file, adds the prefix R_ to reactions and M_ to metabolites") - protected Boolean p=false; + public Boolean p=false; @Option(name="-s", usage="[deactivated] To match the objects in the sbml file, adds the suffix _comparmentID to metabolites") - protected Boolean s=false; + public Boolean s=false; - @Option(name="-o", usage="[REACTION] Object type in the column id : REACTION;METABOLITE;PROTEIN;GENE;PATHWAY") - protected EntityType o= EntityType.REACTION; + @ParameterType(name=Text) + @Option(name="-o", usage="[REACTION] Object type in the column id : REACTION;METABOLITE;GENE;PATHWAY") + public EntityType o= EntityType.REACTION; /** * <p>Constructor for AbstractSbmlSetAny.</p> diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSetMetabolite.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSetMetabolite.java index 3592da3add2912339ce2b15b128fdef69199644e..9e30fdadea58fe33dd79d2de088e7ad59d0cd3aa 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSetMetabolite.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSetMetabolite.java @@ -50,13 +50,13 @@ public abstract class AbstractSbmlSetMetabolite extends AbstractSbmlSet{ "If prefix or suffix is different in the SBML file, use the -p or the -s options."; @Option(name="-ci", usage="[1] number of the column where are the metabolite ids") - protected int colid=1; + public Integer colid=1; @Option(name="-p", usage="[deactivated] To match the objects in the sbml file, adds the prefix M_ to metabolite ids") - protected Boolean p=false; + public Boolean p=false; @Option(name="-s", usage="[deactivated] To match the objects in the sbml file, adds the suffix _comparmentID to metabolites") - protected Boolean s=false; + public Boolean s=false; /** * <p>Constructor for AbstractSbmlSetMetabolite.</p> diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSetReaction.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSetReaction.java index ae63e70cc632aaf2c5001b7e47e0b41a08747125..db092f4530f52df9f7609d8529ee8b772ae7b0b7 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSetReaction.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/AbstractSbmlSetReaction.java @@ -36,6 +36,8 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.attributes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; /** @@ -49,11 +51,12 @@ public abstract class AbstractSbmlSetReaction extends AbstractSbmlSet { public final String setDescription = "The ids must correspond between the tabulated file and the SBML file.\n" + "If prefix R_ is present in the ids in the SBML file and not in the tabulated file, use the -p option."; + @ParameterType(name= EnumParameterTypes.Integer) @Option(name="-ci", usage="[1] number of the column where are the reaction ids") - protected int colid=1; + public int colid=1; @Option(name="-p", usage="[deactivated] To match the objects in the sbml file, adds the prefix R_ to reactions") - protected Boolean p=false; + public Boolean p=false; /** * <p>Constructor for AbstractSbmlSetReaction.</p> diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/ExtractPathways.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/ExtractPathways.java index fdac9589509d4e8b93c263aed3c0e0b96269673d..a15279db567c2b7003d04602fc982a30a3649f7f 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/ExtractPathways.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/ExtractPathways.java @@ -7,15 +7,23 @@ import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderExcepti import fr.inrae.toulouse.metexplore.met4j_io.jsbml.writer.JsbmlWriter; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.writer.Met4jSbmlWriterException; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; import java.io.IOException; public class ExtractPathways extends AbstractMet4jApplication { + @Format(name= EnumFormats.Sbml) + @ParameterType(name= EnumParameterTypes.InputFile) @Option(name = "-i", usage = "input SBML file", required = true) public String inputPath = null; + @Format(name= EnumFormats.Sbml) + @ParameterType(name= EnumParameterTypes.OutputFile) @Option(name = "-o", usage = "output SBML file", required = true) public String outputPath = null; diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/ExtractSbmlAnnot.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/ExtractSbmlAnnot.java index 34a659f176949b4e6c7d7a10784dc0cf425e443f..af1f01fa7e9d6259ec106e32b4486280e463cb2b 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/ExtractSbmlAnnot.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/ExtractSbmlAnnot.java @@ -7,6 +7,10 @@ import fr.inrae.toulouse.metexplore.met4j_core.biodata.collection.BioCollection; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; import java.io.FileWriter; @@ -15,16 +19,20 @@ import java.util.*; public class ExtractSbmlAnnot extends AbstractMet4jApplication { + @Format(name= EnumFormats.Sbml) + @ParameterType(name= EnumParameterTypes.InputFile) @Option(name = "-i", usage = "input SBML file", required = true) public String inputPath = null; + @Format(name= EnumFormats.Tsv) + @ParameterType(name= EnumParameterTypes.OutputFile) @Option(name = "-o", usage = "output file path", required = true) public String outputPath = null; enum entity { METABOLITE,REACTION,GENE} @Option(name="-export", usage = "the type of entity to extract annotation, either metabolite, reaction, or gene", required = true) - public entity export; + public entity export = entity.METABOLITE; @Option(name="-db", usage = "name of the referenced database to export annotations from, as listed in notes or identifiers.org base uri", required = true) public String db; diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetChargesFromFile.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetChargesFromFile.java index 078b0d6cbb958177e60caf8390e209421de59333..b149a5bdfddaedf0ced1965409a132656bf940eb 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetChargesFromFile.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetChargesFromFile.java @@ -38,6 +38,8 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.attributes; import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork; import fr.inrae.toulouse.metexplore.met4j_io.tabulated.attributes.SetChargesFromFile; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; /** @@ -48,8 +50,9 @@ import org.kohsuke.args4j.Option; */ public class SbmlSetChargesFromFile extends AbstractSbmlSetMetabolite { + @ParameterType(name= EnumParameterTypes.Integer) @Option(name="-cc", usage="[2] number of the column where are the charges") - private int colcharge=2; + public int colcharge=2; /** {@inheritDoc} */ @Override @@ -63,7 +66,7 @@ public class SbmlSetChargesFromFile extends AbstractSbmlSetMetabolite { return this.getShortDescription()+"\n"+ "The charge must be a number. "+ this.setDescription+"\n" + "The charge will be written in the SBML file in two locations:+\n" + - "- in the reaction notes (e.g. <p>charge: -1</p>\n" + + "- in the reaction notes (e.g. <p>charge: -1</p>)\n" + "- as fbc attribute (e.g. fbc:charge=\"1\")"; } @@ -107,12 +110,12 @@ public class SbmlSetChargesFromFile extends AbstractSbmlSetMetabolite { if(!flag) { System.err.println("Error in "+this.getLabel()); - System.exit(0); + System.exit(1); } this.writeSbml(bn); - System.exit(1); + System.exit(0); } } diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetEcsFromFile.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetEcsFromFile.java index c4c3616665e387115745e829c3c37668ce4da592..bd483f3de626c4fdf59b42044eed8599cbd58930 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetEcsFromFile.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetEcsFromFile.java @@ -38,6 +38,8 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.attributes; import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork; import fr.inrae.toulouse.metexplore.met4j_io.tabulated.attributes.SetEcsFromFile; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; /** @@ -48,9 +50,9 @@ import org.kohsuke.args4j.Option; */ public class SbmlSetEcsFromFile extends AbstractSbmlSetReaction { - + @ParameterType(name= EnumParameterTypes.Integer) @Option(name="-cec", usage="[2] number of the column where are the ecs") - private int colec=2; + public int colec=2; /** {@inheritDoc} */ @@ -64,7 +66,7 @@ public class SbmlSetEcsFromFile extends AbstractSbmlSetReaction { public String getLongDescription() { return this.getShortDescription()+"\n"+this.setDescription+"\n" + "The EC will be written in the SBML file in two locations:+\n" + - "- in the reaction notes (e.g. <p>EC_NUMBER: 2.4.2.14</p>\n" + + "- in the reaction notes (e.g. <p>EC_NUMBER: 2.4.2.14</p>)\n" + "- as a reaction annotation (e.g. <rdf:li rdf:resource=\"http://identifiers.org/ec-code/2.4.2.14\"/>)"; } @@ -102,7 +104,7 @@ public class SbmlSetEcsFromFile extends AbstractSbmlSetReaction { if(!flag) { System.err.println("Error in setting ECs"); - System.exit(0); + System.exit(1); } this.writeSbml(bn); diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetFormulasFromFile.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetFormulasFromFile.java index 9095c1f550a5adc2f25a5d0494f43e88e3562007..c7f3d665eed8b5ee6bc8ac55a3e985af1c4f797e 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetFormulasFromFile.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetFormulasFromFile.java @@ -38,6 +38,8 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.attributes; import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork; import fr.inrae.toulouse.metexplore.met4j_io.tabulated.attributes.SetFormulasFromFile; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; /** @@ -48,8 +50,9 @@ import org.kohsuke.args4j.Option; */ public class SbmlSetFormulasFromFile extends AbstractSbmlSetMetabolite { + @ParameterType(name= EnumParameterTypes.Integer) @Option(name="-cf", usage="[2] number of the column where are the formulas") - private int colformula=2; + public int colformula=2; /** {@inheritDoc} */ @Override @@ -105,12 +108,12 @@ public class SbmlSetFormulasFromFile extends AbstractSbmlSetMetabolite { if(!flag) { System.err.println("Error in SbmlSetFormula"); - System.exit(0); + System.exit(1); } this.writeSbml(bn); - System.exit(1); + System.exit(0); } diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetGprsFromFile.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetGprsFromFile.java index f6a20b2f234fac5e562f307027544d69c1596554..37d47fe826fdbe8cd5526d5db30bd0b386b86a66 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetGprsFromFile.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetGprsFromFile.java @@ -38,6 +38,8 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.attributes; import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork; import fr.inrae.toulouse.metexplore.met4j_io.tabulated.attributes.SetGprsFromFile; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; import java.io.IOException; @@ -50,9 +52,9 @@ import java.io.IOException; */ public class SbmlSetGprsFromFile extends AbstractSbmlSetReaction { - + @ParameterType(name= EnumParameterTypes.Integer) @Option(name="-cgpr", usage="[2] number of the column where are the gprs") - private int colgpr=2; + public int colgpr=2; /** {@inheritDoc} */ @Override @@ -115,12 +117,12 @@ public class SbmlSetGprsFromFile extends AbstractSbmlSetReaction { if(!flag) { System.err.println("Error in setting gene associations"); - System.exit(0); + System.exit(1); } this.writeSbml(bn); - System.exit(1); + System.exit(0); } diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetNamesFromFile.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetNamesFromFile.java index 7bef87ebbb2642aea3b5f62471fd237c3f797a71..24195b8bd807524f893d6875ce02d2403d4a06ba 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetNamesFromFile.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetNamesFromFile.java @@ -39,6 +39,8 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.attributes; import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.tabulated.attributes.SetNamesFromFile; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; /** @@ -49,8 +51,9 @@ import org.kohsuke.args4j.Option; */ public class SbmlSetNamesFromFile extends AbstractSbmlSetAny { + @ParameterType(name= EnumParameterTypes.Integer) @Option(name="-cname", usage="[2] number of the column where are the names") - private int colname=2; + public int colname=2; /** {@inheritDoc} */ @Override @@ -103,13 +106,13 @@ public class SbmlSetNamesFromFile extends AbstractSbmlSetAny { if(!flag) { System.err.println("Error in SbmlSetNames"); - System.exit(0); + System.exit(1); } this.writeSbml(bn); - System.exit(1); + System.exit(0); } diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetPathwaysFromFile.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetPathwaysFromFile.java index c04f2d23a053d8c9ad1bc629986d928628140700..181b54ef12a89d8e8724007f524299bb6bc1e2c0 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetPathwaysFromFile.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetPathwaysFromFile.java @@ -38,6 +38,8 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.attributes; import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork; import fr.inrae.toulouse.metexplore.met4j_io.tabulated.attributes.SetPathwaysFromFile; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; /** @@ -48,11 +50,12 @@ import org.kohsuke.args4j.Option; */ public class SbmlSetPathwaysFromFile extends AbstractSbmlSetReaction { + @ParameterType(name= EnumParameterTypes.Integer) @Option(name="-cp", usage="[2] number of the column where are the pathways") - private int colp=2; + public int colp=2; @Option(name="-sep", usage="[|] Separator of pathways in the tabulated file") - private String sep = "|"; + public String sep = "|"; /** {@inheritDoc} */ @@ -113,7 +116,7 @@ public class SbmlSetPathwaysFromFile extends AbstractSbmlSetReaction { if(!flag) { System.err.println("Error in "+this.getLabel()); - System.exit(0); + System.exit(1); } diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetRefsFromFile.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetRefsFromFile.java index c30d5de4cebbf42a6334e168735c2de6c3d48ba9..0f8be55508546e28217efc6e9155832d54ffdac1 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetRefsFromFile.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlSetRefsFromFile.java @@ -39,6 +39,8 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.attributes; import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork; import fr.inrae.toulouse.metexplore.met4j_io.tabulated.attributes.SetChargesFromFile; import fr.inrae.toulouse.metexplore.met4j_io.tabulated.attributes.SetRefsFromFile; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; /** @@ -49,11 +51,12 @@ import org.kohsuke.args4j.Option; */ public class SbmlSetRefsFromFile extends AbstractSbmlSetAny { + @ParameterType(name= EnumParameterTypes.Integer) @Option(name="-cr", usage="[2] number of the column where are the references") - private int colRef=2; + public int colRef=2; @Option(name="-ref", usage="Name of the ref. Must exist in identifiers.org", required = true) - private String ref=null; + public String ref=null; /** {@inheritDoc} */ @Override @@ -108,11 +111,11 @@ public class SbmlSetRefsFromFile extends AbstractSbmlSetAny { if(!flag) { System.err.println("Error in "+this.getLabel()); - System.exit(0); + System.exit(1); } this.writeSbml(bn); - System.exit(1); + System.exit(0); } } diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlToMetaboliteTable.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlToMetaboliteTable.java index 9fb436079ffef88235e82ddba4eacad68f8c4778..5d6a38c039bfaff74f9ff1375bc0788744e7227a 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlToMetaboliteTable.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/SbmlToMetaboliteTable.java @@ -41,6 +41,10 @@ import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; import java.io.FileWriter; @@ -55,11 +59,15 @@ import java.io.PrintWriter; */ public class SbmlToMetaboliteTable extends AbstractMet4jApplication { + @ParameterType(name= EnumParameterTypes.InputFile) + @Format(name= EnumFormats.Sbml) @Option(name = "-s", usage = "Sbml file", required = true) - protected String sbml; + public String sbml; + @ParameterType(name= EnumParameterTypes.OutputFile) + @Format(name= EnumFormats.Tsv) @Option(name = "-o", usage = "Output file", required=true) - protected String outputFile; + public String outputFile; /** * <p>main.</p> @@ -104,7 +112,7 @@ public class SbmlToMetaboliteTable extends AbstractMet4jApplication { } catch (IOException e) { e.printStackTrace(); System.err.println("Unable to read the sbml file " + this.sbml); - System.exit(0); + System.exit(1); } BioNetwork bn = null; @@ -113,7 +121,7 @@ public class SbmlToMetaboliteTable extends AbstractMet4jApplication { } catch (Met4jSbmlReaderException e) { e.printStackTrace(); System.err.println("Problem while reading the sbml file " + this.sbml); - System.exit(0); + System.exit(1); } return bn; diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/bigg/GetModelProteome.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/bigg/GetModelProteome.java index fd9c91621d05686fc74dc6d8e4d90e1a3199fc11..cfa96fe68b9ada506228b2bc119e4d4fc12d1e22 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/bigg/GetModelProteome.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/bigg/GetModelProteome.java @@ -37,6 +37,10 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.bigg; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; @@ -65,10 +69,16 @@ import java.util.Set; public class GetModelProteome extends AbstractMet4jApplication { public String description = "Get proteome in fasta format of a model present in BIGG"; + @Option(name = "-m", usage = "[ex: iMM904] id of the BIGG model", required = true) public String modelId = "iMM904"; + + @Format(name= EnumFormats.Fasta) + @ParameterType(name= EnumParameterTypes.OutputFile) @Option(name = "-o", usage = "[proteome.fas] path of the output file") public String outputFile = "proteome.fas"; + + private String baseUrl = "http://bigg.ucsd.edu/api/v2/models/"; /** @@ -86,7 +96,7 @@ public class GetModelProteome extends AbstractMet4jApplication { } catch (CmdLineException e) { System.err.println("Error in arguments"); parser.printUsage(System.err); - System.exit(0); + System.exit(1); } f.run(); @@ -106,13 +116,13 @@ public class GetModelProteome extends AbstractMet4jApplication { } catch (MalformedURLException e) { e.printStackTrace(); System.err.println("Malformed url : please check that the model id does not include spaces or odd characters"); - System.exit(0); + System.exit(1); } Boolean check = this.checkConnection(urlGenes); if (!check) { - System.exit(0); + System.exit(1); } String jsonStringGenes = null; @@ -121,7 +131,7 @@ public class GetModelProteome extends AbstractMet4jApplication { } catch (IOException e) { e.printStackTrace(); System.err.println("Problem when uploading genes"); - System.exit(0); + System.exit(1); } Set<Sequence> sequences = null; @@ -130,7 +140,7 @@ public class GetModelProteome extends AbstractMet4jApplication { } catch (Exception e) { e.printStackTrace(); System.err.println("Problem when reading genes json"); - System.exit(0); + System.exit(1); } try { @@ -138,7 +148,7 @@ public class GetModelProteome extends AbstractMet4jApplication { } catch (IOException e) { e.printStackTrace(); System.err.println("Problem when writing the fasta file"); - System.exit(0); + System.exit(1); } diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/FbcToNotes.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/FbcToNotes.java index 6d6956dd726b0f1f23ef428954e961cd4d8c0c4d..53f2d5e5ff62aada054bb33f5b72c4796e7b60ed 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/FbcToNotes.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/FbcToNotes.java @@ -46,6 +46,9 @@ import fr.inrae.toulouse.metexplore.met4j_io.jsbml.writer.plugin.GroupPathwayWri import fr.inrae.toulouse.metexplore.met4j_io.jsbml.writer.plugin.NotesWriter; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.writer.plugin.PackageWriter; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; @@ -53,6 +56,10 @@ import org.kohsuke.args4j.Option; import java.io.IOException; import java.util.HashSet; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Sbml; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.InputFile; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.OutputFile; + /** * <p>FbcToNotes class.</p> * @@ -61,9 +68,13 @@ import java.util.HashSet; */ public class FbcToNotes extends AbstractMet4jApplication { + @Format(name= Sbml) + @ParameterType(name = InputFile) @Option(name = "-i", usage = "input file", required = true) public String inputPath = null; + @Format(name= Sbml) + @ParameterType(name = OutputFile) @Option(name = "-o", usage = "output file", required = true) public String outputPath = null; @@ -86,7 +97,7 @@ public class FbcToNotes extends AbstractMet4jApplication { } catch (CmdLineException e) { System.err.println("Error in arguments"); parser.printUsage(System.err); - System.exit(0); + System.exit(1); } f.run(); diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Kegg2Sbml.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Kegg2Sbml.java index 81f4b0f9b1f9b7f256648821289350231216ed1d..6695dce70022773378130dd88641b9dbe82b2e00 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Kegg2Sbml.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Kegg2Sbml.java @@ -39,13 +39,21 @@ import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.writer.JsbmlWriter; import fr.inrae.toulouse.metexplore.met4j_io.kegg.Kegg2BioNetwork; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.*; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.OutputFile; + public class Kegg2Sbml extends AbstractMet4jApplication { @Option(name="-org", usage="[] Kegg org id. Must be 3 letters (") public String org = ""; + @Format(name= Sbml) + @ParameterType(name = OutputFile) @Option(name="-sbml", usage="[out.sbml] Out sbml file") public String sbml = "out.sbml"; diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Sbml2Graph.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Sbml2Graph.java index acc2a537790ddccc89442db25c707db5340fedda..2448003842b0aa7fe8b4005f63c5a8c48f312d7d 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Sbml2Graph.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Sbml2Graph.java @@ -10,18 +10,26 @@ import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.plugin.*; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.*; import org.kohsuke.args4j.Option; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashSet; + +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Sbml; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.InputFile; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.OutputFile; public class Sbml2Graph extends AbstractMet4jApplication { + @Format(name = Sbml) + @ParameterType(name = InputFile) @Option(name = "-i", usage = "input SBML file", required = true) public String inputPath = null; + @Format(name = EnumFormats.Text) + @ParameterType(name = OutputFile) @Option(name = "-o", usage = "output Graph file", required = true) public String outputPath = null; diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Sbml2Tab.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Sbml2Tab.java index 338bd4c0300c127e76ad1de7ab0b73f28398e887..ee714696f1863d28eb6f2dc9d1c4b811a29527a7 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Sbml2Tab.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Sbml2Tab.java @@ -39,10 +39,12 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.convert; import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; -import fr.inrae.toulouse.metexplore.met4j_io.jsbml.writer.JsbmlWriter; import fr.inrae.toulouse.metexplore.met4j_io.tabulated.network.BioNetwork2Tab; -import fr.inrae.toulouse.metexplore.met4j_io.tabulated.network.Tab2BioNetwork; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; import java.io.IOException; @@ -61,9 +63,13 @@ public class Sbml2Tab extends AbstractMet4jApplication { @Option(name = "-r", usage = "[<==>] String for reversible reaction") public String r = "<==>"; + @Format(name = EnumFormats.Tsv) + @ParameterType(name = EnumParameterTypes.OutputFile) @Option(name = "-out", usage = "[out.tsv] Tabulated file") public String out = "out.tsv"; + @ParameterType(name = EnumParameterTypes.InputFile) + @Format(name = EnumFormats.Sbml) @Option(name = "-in", usage = "Sbml file", required = true) public String in; diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Tab2Sbml.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Tab2Sbml.java index ffddd18745005810076c8dbfdcbdb264e72dad85..fc54e30c852ffef03cc6e35653f9d2f1928199aa 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Tab2Sbml.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/convert/Tab2Sbml.java @@ -41,6 +41,10 @@ import fr.inrae.toulouse.metexplore.met4j_io.jsbml.writer.JsbmlWriter; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.writer.Met4jSbmlWriterException; import fr.inrae.toulouse.metexplore.met4j_io.tabulated.network.Tab2BioNetwork; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; import java.io.IOException; @@ -53,58 +57,72 @@ import java.io.IOException; */ public class Tab2Sbml extends AbstractMet4jApplication { - @Option(name="-ci", usage="[1] number of the column where are the reaction ids") - public int colid=1; + @ParameterType(name = EnumParameterTypes.Integer) + @Option(name = "-ci", usage = "[1] number of the column where are the reaction ids") + public int colid = 1; - @Option(name="-cf", usage="[2] number of the column where are the reaction formulas") - public int colformula=2; + @ParameterType(name = EnumParameterTypes.Integer) + @Option(name = "-cf", usage = "[2] number of the column where are the reaction formulas") + public int colformula = 2; - @Option(name="-rp", usage="[deactivated] format the reaction ids in a Palsson way (R_***)") - public Boolean rp=false; + @Option(name = "-rp", usage = "[deactivated] format the reaction ids in a Palsson way (R_***)") + public Boolean rp = false; - @Option(name="-mp", usage="[deactivated] format the metabolite ids in a Palsson way (M_***_c)") - public Boolean mp=false; + @Option(name = "-mp", usage = "[deactivated] format the metabolite ids in a Palsson way (M_***_c)") + public Boolean mp = false; - @Option(name="-e", usage="[_b] flag to assign metabolite as external") - public String e="_b"; + @Option(name = "-e", usage = "[_b] flag to assign metabolite as external") + public String e = "_b"; - @Option(name="-i", usage="[-->] String for irreversible reaction") - public String i="-->"; + @Option(name = "-i", usage = "[-->] String for irreversible reaction") + public String i = "-->"; - @Option(name="-r", usage="[<==>] String for reversible reaction") - public String r="<==>"; + @Option(name = "-r", usage = "[<==>] String for reversible reaction") + public String r = "<==>"; - @Option(name="-sbml", usage="[out.sbml] Out sbml file") + @Format(name = EnumFormats.Sbml) + @ParameterType(name = EnumParameterTypes.OutputFile) + @Option(name = "-sbml", usage = "[out.sbml] Out sbml file") public String sbml = "out.sbml"; - @Option(name="-in", usage="Tabulated file") + @Format(name = EnumFormats.Tsv) + @ParameterType(name = EnumParameterTypes.InputFile) + @Option(name = "-in", usage = "Tabulated file") public String in; - @Option(name="-id", usage="[NA] Model id written in the SBML file") - public String id="NA"; + @Option(name = "-id", usage = "[NA] Model id written in the SBML file") + public String id = "NA"; - @Option(name="-cpt", usage="[deactivated] Create compartment from metabolite suffixes. If this option is deactivated, only one compartment (the default compartment) will be created") + @Option(name = "-cpt", usage = "[deactivated] Create compartment from metabolite suffixes. If this option is deactivated, only one compartment (the default compartment) will be created") public Boolean createCompartment = false; - @Option(name="-dcpt", usage="[c] Default compartment") + @Option(name = "-dcpt", usage = "[c] Default compartment") public String defaultCompartment = "c"; - @Option(name="-n", usage="[0] Number of lines to skip at the beginning of the tabulated file") + + @ParameterType(name = EnumParameterTypes.Integer) + @Option(name = "-n", usage = "[0] Number of lines to skip at the beginning of the tabulated file") public int nSkip = 0; - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public String getLabel() { return this.getClass().getSimpleName(); } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public String getLongDescription() { return this.getShortDescription(); } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public String getShortDescription() { return "Create a Sbml File from a tabulated file that contains the reaction ids and the formulas"; @@ -129,40 +147,40 @@ public class Tab2Sbml extends AbstractMet4jApplication { private void run() throws Met4jSbmlWriterException { - Tab2BioNetwork tb = new Tab2BioNetwork(this.id, this.colid-1, - this.colformula-1, - this.rp, this.mp, this.e, this.i, this.r, this.createCompartment, - this.defaultCompartment, this.nSkip); + Tab2BioNetwork tb = new Tab2BioNetwork(this.id, this.colid - 1, + this.colformula - 1, + this.rp, this.mp, this.e, this.i, this.r, this.createCompartment, + this.defaultCompartment, this.nSkip); - String fileIn = this.in; - String sbmlFile = this.sbml; + String fileIn = this.in; + String sbmlFile = this.sbml; - Boolean flag = true; - try { - flag = tb.createReactionsFromFile(fileIn); - } catch (Exception e) { - e.printStackTrace(); - System.err.println("Error in creating the network from "+fileIn); - return; - } + Boolean flag = true; + try { + flag = tb.createReactionsFromFile(fileIn); + } catch (Exception e) { + e.printStackTrace(); + System.err.println("Error in creating the network from " + fileIn); + return; + } - if(! flag) { - System.err.println("Error in creating the network from "+fileIn); - return; - } + if (!flag) { + System.err.println("Error in creating the network from " + fileIn); + return; + } - BioNetwork bn = tb.getBioNetwork(); + BioNetwork bn = tb.getBioNetwork(); - JsbmlWriter writer = new JsbmlWriter(sbmlFile, bn); - writer.write(); + JsbmlWriter writer = new JsbmlWriter(sbmlFile, bn); + writer.write(); - return; + return; - } + } - } +} diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/AbstractMet4jApplication.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/AbstractMet4jApplication.java index ee2d2d2035924fdfec5e4e8011ebe3146e301646..d7ca24738bbcb07c33d545a14e9fb4f6e8a95ddb 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/AbstractMet4jApplication.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/AbstractMet4jApplication.java @@ -36,9 +36,39 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.generic; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; +import org.hibernate.validator.constraints.Range; + +import org.apache.maven.model.Model; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.*; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.*; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; /** * <p>Abstract AbstractMet4jApplication class.</p> @@ -48,6 +78,399 @@ import org.kohsuke.args4j.Option; */ public abstract class AbstractMet4jApplication { + private ArrayList<HashMap<String, String>> options; + + /** + * Inits the options from the field annotations + * + * @throws IllegalArgumentException + * @throws IllegalAccessException + */ + private void initOptions() throws IllegalArgumentException, IllegalAccessException { + + options = new ArrayList<>(); + + // Browse each class field + for (Field f : this.getClass().getFields()) { + + boolean isParameter = Arrays.stream(f.getDeclaredAnnotations()).anyMatch(a -> a instanceof Option); + + if (isParameter) { + + HashMap<String, String> map = new HashMap<>(); + + map.put("name", f.getName()); + + + if (f.getType().isEnum()) { + + Enum<?> enumValue = (Enum<?>) f.get(this); + + Object[] possibleValues = enumValue.getDeclaringClass().getEnumConstants(); + + String choices = ""; + int n = 0; + + for (Object object : possibleValues) { + String choice = object.toString(); + + if (n > 0) { + choices += ","; + } + choices += choice; + n++; + } + + map.put("choices", choices); + + map.put("type", "select"); + + } else if (f.getType().getSimpleName().equals("String")) { + map.put("type", "text"); + } else if (f.getType().getSimpleName().equals("int")) { + map.put("type", "text"); + } else if (f.getType().getSimpleName().equalsIgnoreCase("double")) { + map.put("type", "float"); + } else if (f.getType().getSimpleName().equalsIgnoreCase("boolean")) { + map.put("type", "boolean"); + } else { + map.put("type", f.getType().getSimpleName().toLowerCase()); + } + + String defaultValue = ""; + if (f.get(this) != null) { + defaultValue = f.get(this).toString(); + } + map.put("default", defaultValue); + + for (Annotation a : f.getDeclaredAnnotations()) { + if (a instanceof Option) { + Option option = (Option) a; + + map.put("label", option.usage()); + + if (!option.metaVar().equals("")) { + map.put("metaVar", option.metaVar()); + } else { + map.put("metaVar", ""); + } + + map.put("argument", option.name()); + + String optional = "true"; + if (option.required()) { + optional = "false"; + } + map.put("optional", optional); + } else if (a instanceof Range) { + Range option = (Range) a; + + map.put("min", Double.toString(option.min())); + map.put("max", Double.toString(option.max())); + + } else if (a instanceof ParameterType) { + map.put("type", ((ParameterType) a).name().toString().toLowerCase()); + } else if (a instanceof Format) { + map.put("format", ((Format) a).name().toString().toLowerCase()); + } + } + options.add(map); + } + } + } + + /** + * Prints the description of the application in json format + * + * @return a json representing the detailed description of the class and all + * the parameters available for it's main method + * @throws IllegalAccessException + * @throws IllegalArgumentException + */ + public String json() throws IllegalArgumentException, IllegalAccessException { + + String json = ""; + + this.initOptions(); + + JSONArray parameters = new JSONArray(); + parameters.addAll(options); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("name", new String(this.getLabel())); + jsonObject.put("description", new String(this.getLongDescription())); + jsonObject.put("short_description", new String(this.getShortDescription())); + jsonObject.put("java_class", this.getClass().getSimpleName()); + + String simplePackageName = this.getSimplePackageName(); + + jsonObject.put("package", simplePackageName); + + jsonObject.put("parameters", parameters); + + json = jsonObject.toJSONString(); + + return json; + } + + public String getSimplePackageName() { + String packageName = this.getClass().getPackage().getName(); + + String tab[] = packageName.split("\\."); + String simplePackageName = tab[tab.length - 1]; + + return simplePackageName; + } + + + public void xmlGalaxyWrapper(String outputDirectory, GalaxyPackageType packageType, String version) throws ParserConfigurationException, XmlPullParserException, IOException, IllegalAccessException, TransformerException, SAXException { + + String packageName = this.getSimplePackageName(); + + String className = this.getClass().getSimpleName(); + + File wrapperDirectory = new File(outputDirectory + "/" + packageName + "/" + className); + + if (!wrapperDirectory.exists()) { + wrapperDirectory.mkdirs(); + } + + String fileName = wrapperDirectory.getAbsolutePath() + "/" + className + ".xml"; + + File file = new File(fileName); + + Boolean testExists = false; + + NodeList testList = null; + + if (file.exists()) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + + + // optional, but recommended + // process XML securely, avoid attacks like XML External Entities (XXE) + dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + + // parse XML file + DocumentBuilder db = dbf.newDocumentBuilder(); + + Document doc = db.parse(file); + + testList = doc.getElementsByTagName("test"); + + if (testList.getLength() > 0) { + testExists = true; + } + } + + this.initOptions(); + + DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance(); + + DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder(); + + Document document = documentBuilder.newDocument(); + + Element root = document.createElement("tool"); + root.setAttribute("id", "met4j_" + this.getLabel()); + root.setAttribute("name", this.getLabel()); + root.setAttribute("version", version); + + Element description = document.createElement("description"); + description.setTextContent(this.getShortDescription()); + root.appendChild(description); + + Element xrefs = document.createElement("xrefs"); + Element xref = document.createElement("xref"); + xref.setAttribute("type", "bio.tools"); + xref.setTextContent("met4j"); + xrefs.appendChild(xref); + root.appendChild(xrefs); + + Element requirements = document.createElement("requirements"); + root.appendChild(requirements); + Element container = document.createElement("container"); + + if (packageType.equals(GalaxyPackageType.Docker)) { + container.setAttribute("type", "docker"); + container.setTextContent("metexplore/met4j:" + version); + } else if (packageType.equals(GalaxyPackageType.Singularity)) { + container.setAttribute("type", "singularity"); + container.setTextContent("oras://registry.forgemia.inra.fr/metexplore/met4j/met4j-singularity:" + version); + } + requirements.appendChild(container); + + Element command = document.createElement("command"); + command.setAttribute("detect_errors", "exit_code"); + + String commandText = ""; + + commandText = "sh /usr/bin/met4j.sh " + packageName + "." + className; + /* if(packageType.equals(GalaxyPackageType.Docker)) { + commandText = "sh /usr/bin/met4j.sh " + packageName + "." + className; + } + else if(packageType.equals(GalaxyPackageType.Singularity)) { + + } +*/ + Element inputElements = document.createElement("inputs"); + List<HashMap<String, String>> inputOptions = getInputOptions(); + for (HashMap<String, String> o : inputOptions) { + + Element param = getParamFromOption(document, o); + inputElements.appendChild(param); + + if (o.get("type").equalsIgnoreCase("boolean")) { + commandText += " " + "$" + o.get("name") + "\n"; + } else { + + if (o.get("optional").equals("true")) { + if (o.get("type").startsWith("input")) { + // commandText += "#if str($" + o.get("name") + ") != \"None\":\n"; + commandText += "#if str($" + o.get("name") + ") != 'None':\n"; + } else if (o.get("type").equalsIgnoreCase("Integer") || o.get("type").equalsIgnoreCase("Float")) { + commandText += "#if str($" + o.get("name") + ") != 'nan':\n"; + } else { + commandText += "#if str($" + o.get("name") + "):\n"; + } + } + + commandText += " " + o.get("argument") + " " + "\"$" + o.get("name") + "\"\n"; + + if (o.get("optional").equals("true")) { + commandText += "#end if\n"; + } + + if (o.get("type").startsWith("input")) { + param.setAttribute("type", "data"); + param.setAttribute("format", o.get("format")); + } else { + param.setAttribute("type", o.get("type")); + } + + if (o.get("type").equals("text")) { + Element sanitizer = document.createElement("sanitizer"); + sanitizer.setAttribute("invalid_char", "_"); + Element valid = document.createElement("valid"); + valid.setAttribute("initial", "string.printable"); + sanitizer.appendChild(valid); + param.appendChild(sanitizer); + } + + if (o.get("type").equals("select")) { + String choices = o.get("choices"); + String[] tabChoices = choices.split(","); + for (int i = 0; i < tabChoices.length; i++) { + String choice = tabChoices[i]; + Element option = document.createElement("option"); + option.setAttribute("value", choice); + if (choice.equals(o.get("default"))) { + option.setAttribute("selected", "true"); + } + option.setTextContent(choice); + param.appendChild(option); + } + } + } + + } + + + Element outputElements = document.createElement("outputs"); + List<HashMap<String, String>> outputOptions = getOutputOptions(); + + for (HashMap<String, String> o : outputOptions) { + + Element param = getParamFromOption(document, o); + outputElements.appendChild(param); + commandText += " " + o.get("argument") + " " + "\"$" + o.get("name") + "\"\n"; + } + + Node cDataDescription = document.createCDATASection(commandText); + command.appendChild(cDataDescription); + + root.appendChild(command); + root.appendChild(inputElements); + root.appendChild(outputElements); + + if (testExists) { + Element tests = document.createElement("tests"); + root.appendChild(tests); + for (int i = 0; i < testList.getLength(); i++) { + Node newNode = document.importNode(testList.item(i), true); + tests.appendChild(newNode); + } + } + + Element help = document.createElement("help"); + Node cHelp = document.createCDATASection(this.getLongDescription()); + help.appendChild(cHelp); + root.appendChild(help); + + document.appendChild(root); + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); + DOMSource domSource = new DOMSource(document); + StreamResult streamResult = new StreamResult(new File(wrapperDirectory.getAbsolutePath() + "/" + className + ".xml")); + + transformer.transform(domSource, streamResult); + } + + private Element getParamFromOption(Document document, HashMap<String, String> o) { + + Element param; + if (o.get("type").equals("outputfile")) { + param = document.createElement("data"); + param.setAttribute("name", o.get("name")); + param.setAttribute("format", o.get("format")); + } else { + param = document.createElement("param"); + param.setAttribute("name", o.get("name")); + param.setAttribute("label", o.get("label")); + param.setAttribute("argument", o.get("argument")); + param.setAttribute("value", o.get("default")); + + if (!o.get("type").equalsIgnoreCase("boolean")) { + param.setAttribute("optional", o.get("optional")); + } else { + param.setAttribute("truevalue", o.get("argument")); + param.setAttribute("falsevalue", o.get("")); + param.setAttribute("type", "boolean"); + param.setAttribute("checked", o.get("default")); + } + } + return param; + } + + + private List<HashMap<String, String>> getInputOptions() { + return this.options.stream().filter(o -> !o.containsKey("type") || !o.get("type").equals("outputfile")).collect(Collectors.toList()); + } + + private List<HashMap<String, String>> getOutputOptions() { + return this.options.stream().filter(o -> !o.containsKey("type") || o.get("type").equals("outputfile")).collect(Collectors.toList()); + } + + public static String getVersion() throws IOException, XmlPullParserException { + MavenXpp3Reader reader = new MavenXpp3Reader(); + Model model; + if ((new File("pom.xml")).exists()) + model = reader.read(new FileReader("pom.xml")); + else + model = reader.read( + new InputStreamReader( + AbstractMet4jApplication.class.getResourceAsStream( + "/META-INF/maven/fr.inrae.toulouse.metexplore/met4j-toolbox/pom.xml" + ) + ) + ); + + return model.getVersion().replace("-SNAPSHOT", ""); + } + /** * <p>getLabel.</p> * @@ -74,22 +497,20 @@ public abstract class AbstractMet4jApplication { /** * <p>printHeader.</p> - * + * <p> * Prints the label and the long description */ - public void printLongHeader() - { + public void printLongHeader() { System.out.println(this.getLabel()); System.out.println(this.getLongDescription()); } /** * <p>printHeader.</p> - * + * <p> * Prints the label and the long description */ - public void printShortHeader() - { + public void printShortHeader() { System.out.println(this.getLabel()); System.out.println(this.getShortDescription()); } @@ -113,25 +534,27 @@ public abstract class AbstractMet4jApplication { try { parser.parseArgument(args); } catch (CmdLineException e) { - if(this.h == false) { + if (this.h == false) { this.printShortHeader(); System.err.println("Error in arguments"); parser.printUsage(System.err); - System.exit(0); - } - else { + System.exit(1); + } else { this.printLongHeader(); parser.printUsage(System.err); - System.exit(1); + System.exit(0); } } - if(this.h == true) - { + if (this.h == true) { this.printLongHeader(); parser.printUsage(System.err); - System.exit(1); + System.exit(0); } } + public enum GalaxyPackageType { + Docker, Singularity + } + } diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/annotations/EnumFormats.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/annotations/EnumFormats.java new file mode 100644 index 0000000000000000000000000000000000000000..b86ac0fa466efb517ad3e9e7b0c7d32ed00be725 --- /dev/null +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/annotations/EnumFormats.java @@ -0,0 +1,41 @@ +/* + * Copyright INRAE (2022) + * + * contact-metexplore@inrae.fr + * + * This software is a computer program whose purpose is to [describe + * functionalities and technical features of your software]. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "https://cecill.info/licences/Licence_CeCILL_V2.1-en.html". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * + */ + +package fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations; + +public enum EnumFormats { + Csv, Fasta, Gml, Gsam, Sbml, Text, Tsv +} diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/annotations/EnumParameterTypes.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/annotations/EnumParameterTypes.java new file mode 100644 index 0000000000000000000000000000000000000000..46bd224dad2625853c6ef1e3dff01e258a209645 --- /dev/null +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/annotations/EnumParameterTypes.java @@ -0,0 +1,43 @@ +/* + * Copyright INRAE (2022) + * + * contact-metexplore@inrae.fr + * + * This software is a computer program whose purpose is to [describe + * functionalities and technical features of your software]. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "https://cecill.info/licences/Licence_CeCILL_V2.1-en.html". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * + */ + +package fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations; + +public enum EnumParameterTypes { + + InputFile, OutputFile, Integer, Float, Boolean, Text + +} diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/annotations/Format.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/annotations/Format.java new file mode 100644 index 0000000000000000000000000000000000000000..2cefa74ed1f4ed9b516dda90f4eb4c9828390907 --- /dev/null +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/annotations/Format.java @@ -0,0 +1,48 @@ +/* + * Copyright INRAE (2022) + * + * contact-metexplore@inrae.fr + * + * This software is a computer program whose purpose is to [describe + * functionalities and technical features of your software]. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "https://cecill.info/licences/Licence_CeCILL_V2.1-en.html". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * + */ +package fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Format { + public EnumFormats name(); +} \ No newline at end of file diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/annotations/ParameterType.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/annotations/ParameterType.java new file mode 100644 index 0000000000000000000000000000000000000000..942f4b5b6eb6e880f0c33749ceec522a5ce8a4b8 --- /dev/null +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/annotations/ParameterType.java @@ -0,0 +1,48 @@ +/* + * Copyright INRAE (2022) + * + * contact-metexplore@inrae.fr + * + * This software is a computer program whose purpose is to [describe + * functionalities and technical features of your software]. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "https://cecill.info/licences/Licence_CeCILL_V2.1-en.html". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * + */ + +package fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ParameterType { + public EnumParameterTypes name(); +} diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/CarbonSkeletonNet.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/CarbonSkeletonNet.java index 3c86c369f3e7881bc95706f2828030dc8dc4db95..4d762bbf9ccd116a7dff248eb37c869257a13d15 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/CarbonSkeletonNet.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/CarbonSkeletonNet.java @@ -19,6 +19,7 @@ import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.plugin.NotesParser; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.plugin.PackageParser; import fr.inrae.toulouse.metexplore.met4j_mathUtils.matrix.ExportMatrix; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.*; import org.kohsuke.args4j.Option; import java.io.IOException; @@ -26,14 +27,24 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; -public class CarbonSkeletonNet extends AbstractMet4jApplication { +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.*; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Sbml; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.*; +public class CarbonSkeletonNet extends AbstractMet4jApplication { + + @Format(name = Sbml) + @ParameterType(name = InputFile) @Option(name = "-s", usage = "input SBML file", required = true) public String inputPath = null; + @Format(name = Gsam) + @ParameterType(name = InputFile) @Option(name = "-g", usage = "input GSAM file", required = true) public String inputAAM = null; + @Format(name = Gml) + @ParameterType(name = OutputFile) @Option(name = "-o", usage = "output Graph file", required = true) public String outputPath = null; @@ -87,26 +98,26 @@ public class CarbonSkeletonNet extends AbstractMet4jApplication { System.out.println(" Done."); System.out.print("Processing atom mappings..."); - AtomMappingWeightPolicy wp = ( fromIndexes ? + AtomMappingWeightPolicy wp = (fromIndexes ? new AtomMappingWeightPolicy().fromConservedCarbonIndexes(inputAAM) : new AtomMappingWeightPolicy().fromNumberOfConservedCarbons(inputAAM) ); wp = wp.binarize() - .removeEdgeWithoutMapping() - .removeEdgesWithoutConservedCarbon(); + .removeEdgeWithoutMapping() + .removeEdgesWithoutConservedCarbon(); wp.setWeight(graph); System.out.println(" Done."); //invert graph as undirected (copy edge weight to reversed edge) - if(undirected){ - System.out.print("Create Undirected..."); - graph.asUndirected(); - System.out.println(" Done."); - } + if (undirected) { + System.out.print("Create Undirected..."); + graph.asUndirected(); + System.out.println(" Done."); + } //merge compartment - if(mergeComp){ + if (mergeComp) { System.out.print("Merging compartments..."); VertexContraction vc = new VertexContraction(); graph = vc.decompartmentalize(graph, new VertexContraction.MapByName()); @@ -114,10 +125,10 @@ public class CarbonSkeletonNet extends AbstractMet4jApplication { } //remove single-carbon compounds - if(!keepSingleCarbon){ + if (!keepSingleCarbon) { System.out.println("Skip compounds with less than two carbons detected..."); HashSet<BioMetabolite> toRemove = new HashSet<>(); - for(BioMetabolite n : graph.vertexSet()) { + for (BioMetabolite n : graph.vertexSet()) { if (!graph.edgesOf(n).isEmpty()) { String formula = n.getChemicalFormula(); try { @@ -135,19 +146,19 @@ public class CarbonSkeletonNet extends AbstractMet4jApplication { } //remove isolated nodes - if(removeIsolated){ + if (removeIsolated) { System.out.println("Remove isolated nodes..."); HashSet<BioMetabolite> nodes = new HashSet<>(graph.vertexSet()); graph.removeIsolatedNodes(); nodes.removeAll(graph.vertexSet()); - for(BioMetabolite n : nodes){ + for (BioMetabolite n : nodes) { System.out.println("\tremoving " + n.getName()); } System.out.println(" Done."); } //compute transitions probability from weights - if(computeWeight) { + if (computeWeight) { System.out.print("Compute transition matrix..."); ReactionProbabilityWeight wp2 = new ReactionProbabilityWeight(); wp2.setWeight(graph); @@ -155,7 +166,7 @@ public class CarbonSkeletonNet extends AbstractMet4jApplication { } //merge parallel edges - if(mergeEdges){ + if (mergeEdges) { System.out.print("Merging edges..."); EdgeMerger.mergeEdgesWithOverride(graph); System.out.println(" Done."); @@ -163,11 +174,11 @@ public class CarbonSkeletonNet extends AbstractMet4jApplication { //export graph System.out.print("Exporting..."); - if(asMatrix){ + if (asMatrix) { ComputeAdjacencyMatrix adjBuilder = new ComputeAdjacencyMatrix(graph); - if(!computeWeight) adjBuilder.parallelEdgeWeightsHandling((u, v) -> Math.max(u,v)); - ExportMatrix.toCSV(this.outputPath,adjBuilder.getadjacencyMatrix()); - }else{ + if (!computeWeight) adjBuilder.parallelEdgeWeightsHandling((u, v) -> Math.max(u, v)); + ExportMatrix.toCSV(this.outputPath, adjBuilder.getadjacencyMatrix()); + } else { ExportGraph.toGmlWithAttributes(graph, this.outputPath, true); } System.out.println(" Done."); @@ -175,7 +186,9 @@ public class CarbonSkeletonNet extends AbstractMet4jApplication { } @Override - public String getLabel() {return this.getClass().getSimpleName();} + public String getLabel() { + return this.getClass().getSimpleName(); + } @Override public String getLongDescription() { @@ -187,6 +200,8 @@ public class CarbonSkeletonNet extends AbstractMet4jApplication { } @Override - public String getShortDescription() {return "Create a carbon skeleton graph representation of a SBML file content, using GSAM atom-mapping file (see https://forgemia.inra.fr/metexplore/gsam)";} + public String getShortDescription() { + return "Create a carbon skeleton graph representation of a SBML file content, using GSAM atom-mapping file (see https://forgemia.inra.fr/metexplore/gsam)"; + } } diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChokePoint.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChokePoint.java index f7e0ad85bb5eb788a860b49cbcbe1c942f4bb394..22e04a3043fb1e46bd5cb6076e11463663fbf4ea 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChokePoint.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChokePoint.java @@ -4,6 +4,7 @@ import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioMetabolite; import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork; import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioReaction; import fr.inrae.toulouse.metexplore.met4j_core.biodata.collection.BioCollection; +import fr.inrae.toulouse.metexplore.met4j_core.biodata.utils.BioReactionUtils; import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.DefaultWeightPolicy; import fr.inrae.toulouse.metexplore.met4j_graph.core.WeightingPolicy; import fr.inrae.toulouse.metexplore.met4j_graph.core.compound.CompoundGraph; @@ -11,6 +12,10 @@ import fr.inrae.toulouse.metexplore.met4j_graph.io.Bionetwork2BioGraph; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; import java.io.BufferedReader; @@ -19,14 +24,24 @@ import java.io.FileWriter; import java.io.IOException; import java.util.HashSet; -public class ChokePoint extends AbstractMet4jApplication { +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.*; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.InputFile; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.OutputFile; +public class ChokePoint extends AbstractMet4jApplication { + + @Format(name = Sbml) + @ParameterType(name = InputFile) @Option(name = "-i", usage = "input SBML file", required = true) public String inputPath = null; + @Format(name = Tsv) + @ParameterType(name = OutputFile) @Option(name = "-o", usage = "output results file", required = true) public String outputPath = null; + @Format(name = Text) + @ParameterType(name = InputFile) @Option(name = "-s", aliases = {"--side"}, usage = "an optional file containing list of side compounds to ignore") public String sideCompoundFile = null; @@ -56,23 +71,23 @@ public class ChokePoint extends AbstractMet4jApplication { CompoundGraph graph = builder.getCompoundGraph(); //Graph processing: side compound removal [optional] - if(sideCompoundFile!=null){ + if (sideCompoundFile != null) { System.err.println("removing side compounds..."); - BioCollection<BioMetabolite> sideCpds=new BioCollection<>(); + BioCollection<BioMetabolite> sideCpds = new BioCollection<>(); BufferedReader fr = new BufferedReader(new FileReader(sideCompoundFile)); String line; while ((line = fr.readLine()) != null) { String sId = line.trim().split("\t")[0]; BioMetabolite s = network.getMetabolite(sId); - if(s!=null){ + if (s != null) { sideCpds.add(s); - }else{ - System.err.println(sId+" side compound not found in network."); + } else { + System.err.println(sId + " side compound not found in network."); } } fr.close(); boolean removed = graph.removeAllVertices(sideCpds); - if (removed) System.err.println(sideCpds.size()+" compounds removed."); + if (removed) System.err.println(sideCpds.size() + " compounds removed."); } //Graph processing: set weights @@ -85,8 +100,8 @@ public class ChokePoint extends AbstractMet4jApplication { //export results System.err.println("Export results..."); - for(BioReaction r : choke){ - fw.write(r.getId()+"\t"+r.getName()+"\t"+r.toString()+"\n"); + for (BioReaction r : choke) { + fw.write(r.getId() + "\t" + r.getName() + "\t" + BioReactionUtils.getEquation(r, false, false) + "\n"); } System.err.println("done."); fw.close(); @@ -100,7 +115,7 @@ public class ChokePoint extends AbstractMet4jApplication { @Override public String getLongDescription() { - return this.getShortDescription()+"\nLoad points constitute an indicator of lethality and can help identifying drug target " + + return this.getShortDescription() + "\nLoad points constitute an indicator of lethality and can help identifying drug target " + "Choke points are reactions that are required to consume or produce one compound. Targeting of choke point can lead to the accumulation or the loss of some metabolites, thus choke points constitute an indicator of lethality and can help identifying drug target \n" + "See : Syed Asad Rahman, Dietmar Schomburg; Observing local and global properties of metabolic pathways: ‘load points’ and ‘choke points’ in the metabolic networks. Bioinformatics 2006; 22 (14): 1767-1774. doi: 10.1093/bioinformatics/btl181"; } diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/CompoundNet.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/CompoundNet.java index c09ef4d573adcce0eeb9e3c8597768873d73ebe8..20c0512e4ed302acc0bc22214d746b8b1f074916 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/CompoundNet.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/CompoundNet.java @@ -21,6 +21,10 @@ import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.plugin.NotesParser; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.plugin.PackageParser; import fr.inrae.toulouse.metexplore.met4j_mathUtils.matrix.ExportMatrix; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; import java.io.IOException; @@ -31,19 +35,23 @@ import java.util.function.Function; public class CompoundNet extends AbstractMet4jApplication { + @Format(name= EnumFormats.Sbml) + @ParameterType(name= EnumParameterTypes.InputFile) @Option(name = "-s", usage = "input SBML file", required = true) public String inputPath = null; + @ParameterType(name= EnumParameterTypes.InputFile) @Option(name = "-sc", usage = "input Side compound file", required = false) public String inputSide = null; + @ParameterType(name= EnumParameterTypes.OutputFile) @Option(name = "-o", usage = "output Graph file", required = true) public String outputPath = null; - enum strategy {by_name,by_id} + enum strategy {no, by_name,by_id} @Option(name = "-mc", aliases = {"--mergecomp"}, usage = "merge compartments. " + "Use names if consistent and unambiguous across compartments, or identifiers if compartment suffix is present (id in form \"xxx_y\" with xxx as base identifier and y as compartment label).") - public strategy mergingStrat = null; + public strategy mergingStrat = strategy.no; public String idRegex = "^(\\w+)_\\w$"; @Option(name = "-me", aliases = {"--simple"}, usage = "merge parallel edges to produce a simple graph", required = false) @@ -52,9 +60,12 @@ public class CompoundNet extends AbstractMet4jApplication { @Option(name = "-ri", aliases = {"--removeIsolatedNodes"}, usage = "remove isolated nodes", required = false) public boolean removeIsolated = false; - @Option(name = "-dw", aliases = {"--degreeWeights"}, usage = "penalize traversal of hubs by using degree square weighting", forbids = {"-cw", "-sw"}) + @Option(name = "-dw", aliases = {"--degreeWeights"}, usage = "penalize traversal of hubs by using degree square weighting", forbids = {"-cw"}) public Boolean degree = false; - @Option(name = "-cw", aliases = {"--customWeights"}, usage = "an optional file containing weights for compound pairs", forbids = {"-dw", "-sw"}) + + @ParameterType(name=EnumParameterTypes.InputFile) + @Format(name=EnumFormats.Tsv) + @Option(name = "-cw", aliases = {"--customWeights"}, usage = "an optional file containing weights for compound pairs", forbids = {"-dw"}) public String weightFile = null; @Option(name = "-un", aliases = {"--undirected"}, usage = "create as undirected", required = false) @@ -120,7 +131,7 @@ public class CompoundNet extends AbstractMet4jApplication { } //merge compartment - if(mergingStrat!=null){ + if(mergingStrat!=strategy.no){ System.out.print("Merging compartments..."); VertexContraction vc = new VertexContraction(); VertexContraction.Mapper merger = mergingStrat.equals(strategy.by_name) ? new VertexContraction.MapByName() : new VertexContraction.MapByIdSubString(idRegex); diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DistanceMatrix.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DistanceMatrix.java index 33441d2390512f975b6d5ec6c4531ef9ef27e68f..9d5da9e6b802823f9719f202b8229e03ec9455c3 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DistanceMatrix.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DistanceMatrix.java @@ -16,26 +16,39 @@ import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderExcepti import fr.inrae.toulouse.metexplore.met4j_mathUtils.matrix.BioMatrix; import fr.inrae.toulouse.metexplore.met4j_mathUtils.matrix.ExportMatrix; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.*; import org.kohsuke.args4j.Option; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Csv; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Sbml; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.*; + public class DistanceMatrix extends AbstractMet4jApplication { + @Format(name = Sbml) + @ParameterType(name = InputFile) @Option(name = "-i", usage = "input SBML file", required = true) public String inputPath = null; + @Format(name = Csv) + @ParameterType(name = OutputFile) @Option(name = "-o", usage = "output Matrix file", required = true) public String outputPath = null; + @Format(name = EnumFormats.Text) + @ParameterType(name = InputFile) @Option(name = "-s", aliases = {"--side"}, usage = "an optional file containing list of side compounds to ignore") public String sideCompoundFile = null; - @Option(name = "-dw", aliases = {"--degree"}, usage = "penalize traversal of hubs by using degree square weighting", forbids = {"-w"}) + @Option(name = "-dw", aliases = {"--degree"}, usage = "penalize traversal of hubs by using degree square weighting (-w must not be set)", forbids = {"-w"}) public Boolean degree = false; + @Format(name = EnumFormats.Tsv) + @ParameterType(name = InputFile) @Option(name = "-w", aliases = {"--weights"}, usage = "an optional file containing weights for compound pairs", forbids = {"-d"}) public String weightFile = null; diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ExtractSubNetwork.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ExtractSubNetwork.java index 9371b1c1ca0fd84a04054e9a2268e399cebc5adc..ed34df2e6794f24cad0be7160fb6e26d91bceea0 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ExtractSubNetwork.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ExtractSubNetwork.java @@ -22,31 +22,52 @@ import fr.inrae.toulouse.metexplore.met4j_graph.io.NodeMapping; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.*; import org.kohsuke.args4j.Option; import java.io.IOException; import java.util.HashSet; import java.util.List; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.*; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.InputFile; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.OutputFile; + public class ExtractSubNetwork extends AbstractMet4jApplication { + @Format(name = Sbml) + @ParameterType(name = InputFile) @Option(name = "-i", usage = "input SBML file", required = true) public String inputPath = null; + + @Format(name = Text) + @ParameterType(name = InputFile) @Option(name = "-s", usage = "input sources txt file", required = true) public String sourcePath = null; + + @Format(name = Text) + @ParameterType(name = InputFile) @Option(name = "-t", usage = "input targets txt file", required = true) public String targetPath = null; + + @Format(name = Gml) + @ParameterType(name = OutputFile) @Option(name = "-o", usage = "output gml file", required = true) public String outputPath = null; - + @Format(name = Text) + @ParameterType(name = InputFile) @Option(name = "-sc", aliases = {"--side"}, usage = "an optional file containing list of side compounds to ignore") public String sideCompoundFile = null; @Option(name = "-dw", aliases = {"--degreeWeights"}, usage = "penalize traversal of hubs by using degree square weighting", forbids = {"-cw", "-sw"}) public Boolean degree = false; + + @Format(name = Tsv) + @ParameterType(name = InputFile) @Option(name = "-cw", aliases = {"--customWeights"}, usage = "an optional file containing weights for compound pairs", forbids = {"-dw", "-sw"}) public String weightFile = null; + @Option(name = "-sw", aliases = {"--chemSimWeights"}, usage = "penalize traversal of non-relevant edges by using chemical similarity weighting", forbids = {"-dw", "-cw"}) public Boolean chemicalSim = false; @@ -55,6 +76,7 @@ public class ExtractSubNetwork extends AbstractMet4jApplication { @Option(name = "-k", usage = "Extract k-shortest paths", forbids = {"-st"}) public int k = 1; + @Option(name = "-st", aliases = {"--steinertree"}, usage = "Extract Steiner Tree", forbids = {"-k"}) public boolean st = false; diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ExtractSubReactionNetwork.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ExtractSubReactionNetwork.java index 66b50460c99ab8accd5809f5a476d14c1699051f..44b7807e450f6328cab641a0e1a34fbfbfd32447 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ExtractSubReactionNetwork.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ExtractSubReactionNetwork.java @@ -8,47 +8,64 @@ import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.KShortestPat import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.ShortestPath; import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.SteinerTreeApprox; import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.DefaultWeightPolicy; -import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.DegreeWeightPolicy; import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.WeightsFromFile; import fr.inrae.toulouse.metexplore.met4j_graph.core.BioPath; import fr.inrae.toulouse.metexplore.met4j_graph.core.GraphFactory; import fr.inrae.toulouse.metexplore.met4j_graph.core.WeightingPolicy; -import fr.inrae.toulouse.metexplore.met4j_graph.core.compound.CompoundGraph; import fr.inrae.toulouse.metexplore.met4j_graph.core.reaction.CompoundEdge; import fr.inrae.toulouse.metexplore.met4j_graph.core.reaction.ReactionGraph; -import fr.inrae.toulouse.metexplore.met4j_graph.core.compound.ReactionEdge; import fr.inrae.toulouse.metexplore.met4j_graph.io.Bionetwork2BioGraph; import fr.inrae.toulouse.metexplore.met4j_graph.io.ExportGraph; -import fr.inrae.toulouse.metexplore.met4j_graph.io.NodeMapping; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; import fr.inrae.toulouse.metexplore.met4j_mapping.Mapper; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.*; import org.kohsuke.args4j.Option; import java.io.IOException; import java.util.HashSet; import java.util.List; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.*; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.InputFile; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.OutputFile; + public class ExtractSubReactionNetwork extends AbstractMet4jApplication { + @Format(name = Sbml) + @ParameterType(name = InputFile) @Option(name = "-i", usage = "input SBML file", required = true) public String inputPath = null; + + @Format(name = Text) + @ParameterType(name = InputFile) @Option(name = "-s", usage = "input sources txt file", required = true) public String sourcePath = null; + + @Format(name = Text) + @ParameterType(name = InputFile) @Option(name = "-t", usage = "input targets txt file", required = true) public String targetPath = null; + + @Format(name = Gml) + @ParameterType(name = OutputFile) @Option(name = "-o", usage = "output gml file", required = true) public String outputPath = null; + + @Format(name = Text) + @ParameterType(name = InputFile) @Option(name = "-sc", aliases = {"--side"}, usage = "a file containing list of side compounds to ignore", required = true) public String sideCompoundFile = null; - + @Format(name = Tsv) + @ParameterType(name = InputFile) @Option(name = "-cw", aliases = {"--customWeights"}, usage = "an optional file containing weights for reactions pairs") public String weightFile = null; @Option(name = "-k", usage = "Extract k-shortest paths", forbids = {"-st"}) public int k = 1; + @Option(name = "-st", aliases = {"--steinertree"}, usage = "Extract Steiner Tree", forbids = {"-k"}) public boolean st = false; @@ -60,18 +77,21 @@ public class ExtractSubReactionNetwork extends AbstractMet4jApplication { //Graph processing: import side compounds System.err.println("importing side compounds..."); - Mapper<BioMetabolite> mapper = new Mapper<>(network,BioNetwork::getMetabolitesView).skipIfNotFound(); + Mapper<BioMetabolite> mapper = new Mapper<>(network, BioNetwork::getMetabolitesView).skipIfNotFound(); BioCollection<BioMetabolite> sideCpds = mapper.map(sideCompoundFile); - if(mapper.getNumberOfSkippedEntries()>0) System.err.println(mapper.getNumberOfSkippedEntries() + " side compounds not found in network."); + if (mapper.getNumberOfSkippedEntries() > 0) + System.err.println(mapper.getNumberOfSkippedEntries() + " side compounds not found in network."); System.err.println(sideCpds.size() + " side compounds ignored during graph build."); //get sources and targets System.err.println("extracting sources and targets"); - Mapper<BioReaction> rmapper = new Mapper<>(network,BioNetwork::getReactionsView).skipIfNotFound(); + Mapper<BioReaction> rmapper = new Mapper<>(network, BioNetwork::getReactionsView).skipIfNotFound(); HashSet<BioReaction> sources = new HashSet<>(rmapper.map(sourcePath)); - if(rmapper.getNumberOfSkippedEntries()>0) System.err.println(rmapper.getNumberOfSkippedEntries() + " source not found in network."); + if (rmapper.getNumberOfSkippedEntries() > 0) + System.err.println(rmapper.getNumberOfSkippedEntries() + " source not found in network."); HashSet<BioReaction> targets = new HashSet<>(rmapper.map(targetPath)); - if(rmapper.getNumberOfSkippedEntries()>0) System.err.println(rmapper.getNumberOfSkippedEntries() + " target not found in network."); + if (rmapper.getNumberOfSkippedEntries() > 0) + System.err.println(rmapper.getNumberOfSkippedEntries() + " target not found in network."); //Create reaction graph Bionetwork2BioGraph builder = new Bionetwork2BioGraph(network); diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/LoadPoint.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/LoadPoint.java index 951a09823d4eace362cf19c68f170a419f25c7e7..51aff1be519c2c2f82c6fa2d1620a3f69fc6ea9d 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/LoadPoint.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/LoadPoint.java @@ -11,6 +11,9 @@ import fr.inrae.toulouse.metexplore.met4j_graph.io.Bionetwork2BioGraph; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; import java.io.BufferedReader; @@ -20,14 +23,24 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; -public class LoadPoint extends AbstractMet4jApplication { +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.*; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.InputFile; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.OutputFile; +public class LoadPoint extends AbstractMet4jApplication { + + @Format(name = Sbml) + @ParameterType(name = InputFile) @Option(name = "-i", usage = "input SBML file", required = true) public String inputPath = null; + @Format(name = Tsv) + @ParameterType(name = OutputFile) @Option(name = "-o", usage = "output results file", required = true) public String outputPath = null; + @Format(name = Text) + @ParameterType(name = InputFile) @Option(name = "-s", aliases = {"--side"}, usage = "an optional file containing list of side compounds to ignore") public String sideCompoundFile = null; @@ -59,23 +72,23 @@ public class LoadPoint extends AbstractMet4jApplication { CompoundGraph graph = builder.getCompoundGraph(); //Graph processing: side compound removal [optional] - if(sideCompoundFile!=null){ + if (sideCompoundFile != null) { System.err.println("removing side compounds..."); - BioCollection<BioMetabolite> sideCpds=new BioCollection<>(); + BioCollection<BioMetabolite> sideCpds = new BioCollection<>(); BufferedReader fr = new BufferedReader(new FileReader(sideCompoundFile)); String line; while ((line = fr.readLine()) != null) { String sId = line.trim().split("\t")[0]; BioMetabolite s = network.getMetabolite(sId); - if(s!=null){ + if (s != null) { sideCpds.add(s); - }else{ - System.err.println(sId+" side compound not found in network."); + } else { + System.err.println(sId + " side compound not found in network."); } } fr.close(); boolean removed = graph.removeAllVertices(sideCpds); - if (removed) System.err.println(sideCpds.size()+" compounds removed."); + if (removed) System.err.println(sideCpds.size() + " compounds removed."); } //Graph processing: set weights @@ -84,14 +97,14 @@ public class LoadPoint extends AbstractMet4jApplication { //compute loads System.err.println("Computing load points..."); - fr.inrae.toulouse.metexplore.met4j_graph.computation.analyze.LoadPoint computor = new fr.inrae.toulouse.metexplore.met4j_graph.computation.analyze.LoadPoint<BioMetabolite, ReactionEdge,CompoundGraph>(graph); + fr.inrae.toulouse.metexplore.met4j_graph.computation.analyze.LoadPoint computor = new fr.inrae.toulouse.metexplore.met4j_graph.computation.analyze.LoadPoint<BioMetabolite, ReactionEdge, CompoundGraph>(graph); HashMap<BioMetabolite, Double> loads = computor.getLoads(k); //export results System.err.println("Export results..."); - for(Map.Entry<BioMetabolite, Double> e : loads.entrySet()){ + for (Map.Entry<BioMetabolite, Double> e : loads.entrySet()) { BioMetabolite m = e.getKey(); - fw.write(m.getId()+"\t"+m.getName()+"\t"+e.getValue()+"\n"); + fw.write(m.getId() + "\t" + m.getName() + "\t" + e.getValue() + "\n"); } System.err.println("done."); fw.close(); diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/MetaboRank.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/MetaboRank.java index b678e749a67a7137b6fe374ad1a1650b74d8d521..9b735eec8477423db5f8a57e2f802ab2375cd420 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/MetaboRank.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/MetaboRank.java @@ -52,6 +52,9 @@ import fr.inrae.toulouse.metexplore.met4j_graph.io.Bionetwork2BioGraph; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; import java.io.*; @@ -61,28 +64,46 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Sbml; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Tsv; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.InputFile; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.OutputFile; + /** * @author clement */ public class MetaboRank extends AbstractMet4jApplication { //arguments + @Format(name = Sbml) + @ParameterType(name = InputFile) @Option(name = "-i", usage = "input SBML file: path to network used for computing centrality, in sbml format.", required = true) - String sbmlFilePath; + public String sbmlFilePath; + + @Format(name = Tsv) + @ParameterType(name = InputFile) @Option(name = "-s", usage = "input seeds file: tabulated file containing node of interest ids and weight", required = true) - String seedsFilePath; + public String seedsFilePath; + + @Format(name = Tsv) + @ParameterType(name = OutputFile) @Option(name = "-o", usage = "output file: path to the file where the results will be exported", required = true) - String output; + public String output; //parameters + @Format(name = Tsv) + @ParameterType(name = InputFile) @Option(name = "-w", usage = "input edge weight file: (recommended) path to file containing edges' weights. Will be normalized as transition probabilities") - String edgeWeightsFilePaths; + public String edgeWeightsFilePaths; + @Option(name = "-max", usage = "maximal number of iteration") - int maxNbOfIter = 15000; + public int maxNbOfIter = 15000; + @Option(name = "-t", usage = "convergence tolerance") - double tolerance = 0.001; + public double tolerance = 0.001; + @Option(name = "-d", usage = "damping factor") - double dampingFactor = 0.85; + public double dampingFactor = 0.85; //variables CompoundGraph firstGraph; diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/NetworkSummary.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/NetworkSummary.java index 53ea5f43a0376ebf726b4f751bf7728effdbbef9..427fbbea651bbaaa51c267807dda3c5a0a07eaab 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/NetworkSummary.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/NetworkSummary.java @@ -18,6 +18,9 @@ import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; import fr.inrae.toulouse.metexplore.met4j_mathUtils.matrix.BioMatrix; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.kohsuke.args4j.Option; @@ -28,26 +31,33 @@ import java.io.IOException; import java.util.*; import java.util.stream.Collectors; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Sbml; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.InputFile; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.OutputFile; + public class NetworkSummary extends AbstractMet4jApplication { + @Format(name = Sbml) + @ParameterType(name = InputFile) @Option(name = "-i", usage = "input SBML file", required = true) public String inputPath = null; + @ParameterType(name = OutputFile) @Option(name = "-o", usage = "output report file", required = true) public String outputPath = null; + @ParameterType(name = InputFile) @Option(name = "-s", aliases = {"--side"}, usage = "an optional file containing list of side compounds to ignore (recommended)") public String sideCompoundFile = null; - @Option(name = "-sd", aliases = {"--skipdist"}, usage = "skip full distance matrix computation (quick summary)", forbids={"-w"}) + @Option(name = "-sd", aliases = {"--skipdist"}, usage = "skip full distance matrix computation (quick summary)", forbids = {"-w"}) public Boolean skipdist = false; @Option(name = "-d", aliases = {"--directed"}, usage = "use reaction direction for distances") public Boolean directed = false; - public static void main(String[] args) throws IOException, Met4jSbmlReaderException { NetworkSummary app = new NetworkSummary(); app.parseArguments(args); @@ -58,12 +68,12 @@ public class NetworkSummary extends AbstractMet4jApplication { public void run() throws IOException, Met4jSbmlReaderException { //Start output FileWriter fw = new FileWriter(outputPath); - fw.write("#\tMET4J NETWORK SUMMARY\n"); - fw.write("#\tNetwork: "+this.inputPath+"\n"); - if(sideCompoundFile!=null) fw.write("#\tSide compounds: "+this.sideCompoundFile+"\n"); + fw.write("#\tMET4J NETWORK SUMMARY\n"); + fw.write("#\tNetwork: " + this.inputPath + "\n"); + if (sideCompoundFile != null) fw.write("#\tSide compounds: " + this.sideCompoundFile + "\n"); Date currentDate = new Date(); - fw.write("#\t"+currentDate.toString()+"\n"); - fw.write("#"+"-".repeat(60)+"\n"); + fw.write("#\t" + currentDate.toString() + "\n"); + fw.write("#" + "-".repeat(60) + "\n"); //import network System.err.println("reading SBML..."); @@ -79,23 +89,23 @@ public class NetworkSummary extends AbstractMet4jApplication { wp.setWeight(graph); //Graph processing: side compound removal - if(sideCompoundFile!=null){ + if (sideCompoundFile != null) { System.err.println("removing side compounds..."); - BioCollection<BioMetabolite> sideCpds=new BioCollection<>(); + BioCollection<BioMetabolite> sideCpds = new BioCollection<>(); BufferedReader fr = new BufferedReader(new FileReader(sideCompoundFile)); String line; while ((line = fr.readLine()) != null) { String sId = line.trim().split("\t")[0]; BioMetabolite s = network.getMetabolite(sId); - if(s!=null){ + if (s != null) { sideCpds.add(s); - }else{ - System.err.println(sId+" side compound not found in network."); + } else { + System.err.println(sId + " side compound not found in network."); } } fr.close(); boolean removed = graph.removeAllVertices(sideCpds); - if (removed) System.err.println(sideCpds.size()+" compounds removed."); + if (removed) System.err.println(sideCpds.size() + " compounds removed."); } //Start Anlysis @@ -104,43 +114,43 @@ public class NetworkSummary extends AbstractMet4jApplication { analyzer.adjustEdgeCountForMultiGraph(); //basic stats - fw.write("Number of nodes:\t"+graph.vertexSet().size()+"\n"); - fw.write("Number of edges:\t"+graph.edgeSet().size()+"\n"); - fw.write("Number of neighbor pairs (ignore parallel edges):\t"+(int)analyzer.getNumberOfEdges()+"\n"); + fw.write("Number of nodes:\t" + graph.vertexSet().size() + "\n"); + fw.write("Number of edges:\t" + graph.edgeSet().size() + "\n"); + fw.write("Number of neighbor pairs (ignore parallel edges):\t" + (int) analyzer.getNumberOfEdges() + "\n"); //connectivity System.err.println("extract connected component..."); List<Set<BioMetabolite>> cc = GraphMeasure.getConnectedCompenent(graph); - fw.write("Number of connected component:\t"+cc.size()+"\n"); + fw.write("Number of connected component:\t" + cc.size() + "\n"); Map<Integer, Integer> ccSizes = cc.stream().collect(Collectors.groupingBy(Set::size)) .entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, (e -> e.getValue().size()))); - for(Map.Entry e : ccSizes.entrySet()){ - fw.write("\t"+e.getKey()+" x"+e.getValue()+"\n"); + for (Map.Entry e : ccSizes.entrySet()) { + fw.write("\t" + e.getKey() + " x" + e.getValue() + "\n"); } //density System.err.println("Compute density..."); - fw.write("Density (gamma index):\t"+analyzer.getGamma()+"\n"); + fw.write("Density (gamma index):\t" + analyzer.getGamma() + "\n"); DescriptiveStatistics clusterStats = new DescriptiveStatistics(); System.err.println("Compute local clustering coefficients..."); - GraphLocalMeasure<BioMetabolite,ReactionEdge,CompoundGraph> analyzer2 = new GraphLocalMeasure(graph); - for(BioMetabolite v : graph.vertexSet()){ + GraphLocalMeasure<BioMetabolite, ReactionEdge, CompoundGraph> analyzer2 = new GraphLocalMeasure(graph); + for (BioMetabolite v : graph.vertexSet()) { clusterStats.addValue(analyzer2.getLocalClusteringCoeff(v)); } - fw.write("Average local clustering coefficient:\t"+clusterStats.getMean()+"\n"); + fw.write("Average local clustering coefficient:\t" + clusterStats.getMean() + "\n"); //degree statistics System.err.println("Compute degree statistics..."); DescriptiveStatistics degreeStats = new DescriptiveStatistics(); - for(BioMetabolite v : graph.vertexSet()){ + for (BioMetabolite v : graph.vertexSet()) { degreeStats.addValue(graph.degreeOf(v)); } - fw.write("Max degree:\t"+degreeStats.getMax()+"\n"); - fw.write("Average degree:\t"+degreeStats.getMean()+"\n"); + fw.write("Max degree:\t" + degreeStats.getMax() + "\n"); + fw.write("Average degree:\t" + degreeStats.getMean() + "\n"); //distances statistics - if(!skipdist) { + if (!skipdist) { System.err.println("Compute distances..."); // compute distance matrix ComputeAdjacencyMatrix adjBuilder = new ComputeAdjacencyMatrix(graph); @@ -153,11 +163,11 @@ public class NetworkSummary extends AbstractMet4jApplication { System.err.println("Compute distances statistics..."); DescriptiveStatistics distStats = new DescriptiveStatistics(); // gather all elements in matrix, remove infinity - for(int i=0; i<distM.numRows(); i++){ - for(int j=0; j<distM.numCols(); j++){ - if(i!=j){ - Double d=distM.get(i,j); - if(!d.equals(Double.POSITIVE_INFINITY)){ + for (int i = 0; i < distM.numRows(); i++) { + for (int j = 0; j < distM.numCols(); j++) { + if (i != j) { + Double d = distM.get(i, j); + if (!d.equals(Double.POSITIVE_INFINITY)) { distStats.addValue(d); } } @@ -165,8 +175,8 @@ public class NetworkSummary extends AbstractMet4jApplication { } int diameter = (int) distStats.getMax(); - fw.write("Diameter:\t"+diameter+"\n"); - fw.write("Average shortest path length:\t"+distStats.getMean()+"\n"); + fw.write("Diameter:\t" + diameter + "\n"); + fw.write("Average shortest path length:\t" + distStats.getMean() + "\n"); //Centrality analysis System.err.println("Compute centrality..."); @@ -186,7 +196,7 @@ public class NetworkSummary extends AbstractMet4jApplication { fw.write("Top Closeness:\n"); for (int i = 0; i < 20; i++) { Map.Entry<BioMetabolite, Integer> e = it.next(); - fw.write("\t"+(e.getValue()+1)+"\t"+e.getKey().getName()+"\t"+(closenessRaw.get(e.getKey())*graph.vertexSet().size())+"\n"); + fw.write("\t" + (e.getValue() + 1) + "\t" + e.getKey().getName() + "\t" + (closenessRaw.get(e.getKey()) * graph.vertexSet().size()) + "\n"); } @@ -200,13 +210,18 @@ public class NetworkSummary extends AbstractMet4jApplication { System.err.println("Done."); fw.close(); } + @Override - public String getLabel() {return this.getClass().getSimpleName();} + public String getLabel() { + return this.getClass().getSimpleName(); + } @Override - public String getLongDescription() {return "Use a metabolic network in SBML file and an optional list of side compounds, " + - "and produce a report summarizing several graph measures characterising the structure of the network." + - "This includes (non-exhaustive list): size and order, connectivity, density, degree distribution, shortest paths length, top centrality nodes...";} + public String getLongDescription() { + return "Use a metabolic network in SBML file and an optional list of side compounds, " + + "and produce a report summarizing several graph measures characterising the structure of the network." + + "This includes (non-exhaustive list): size and order, connectivity, density, degree distribution, shortest paths length, top centrality nodes..."; + } @Override public String getShortDescription() { diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/PrecursorNetwork.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/PrecursorNetwork.java index d2bef7f3a37a22756ef626f9975cc59ac12f696f..758dc41a03335661732723d25633c5bb11ef9751 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/PrecursorNetwork.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/PrecursorNetwork.java @@ -12,23 +12,40 @@ import fr.inrae.toulouse.metexplore.met4j_graph.io.NodeMapping; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; import java.io.IOException; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Gml; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Sbml; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.InputFile; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.OutputFile; + public class PrecursorNetwork extends AbstractMet4jApplication { //arguments + @Format(name = Sbml) + @ParameterType(name = InputFile) @Option(name = "-i", usage = "input SBML file: path to network used for computing scope, in sbml format.", required = true) - String sbmlFilePath; + public String sbmlFilePath; + + @ParameterType(name = InputFile) @Option(name = "-t", aliases = {"--targets"}, usage = "input target file: tabulated file containing node of interest ids", required = true) - String targetsFilePath; + public String targetsFilePath; + + @Format(name = Gml) + @ParameterType(name = OutputFile) @Option(name = "-o", usage = "output file: path to the .gml file where the results precursor network will be exported", required = true) - String output; + public String output; //oprtions + @ParameterType(name = InputFile) @Option(name = "-sc", aliases = {"--sides"}, usage = "an optional file containing list of ubiquitous compounds to be considered already available") public String sideCompoundFile = null; + @ParameterType(name = InputFile) @Option(name = "-ir", aliases = {"--ignore"}, usage = "an optional file containing list of reaction to ignore (forbid inclusion in scope") public String reactionToIgnoreFile = null; diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ScopeNetwork.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ScopeNetwork.java index fbe4ce57f4c2a394ddc669349917a0a65e1e67e8..2ad3ef47d087951c1d9d23ee4dfe924d0083a16c 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ScopeNetwork.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ScopeNetwork.java @@ -13,27 +13,47 @@ import fr.inrae.toulouse.metexplore.met4j_graph.io.NodeMapping; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.kohsuke.args4j.Option; import java.io.IOException; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Gml; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Sbml; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.InputFile; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.OutputFile; + public class ScopeNetwork extends AbstractMet4jApplication { //arguments + @Format(name = Sbml) + @ParameterType(name = InputFile) @Option(name = "-i", usage = "input SBML file: path to network used for computing scope, in sbml format.", required = true) - String sbmlFilePath; + public String sbmlFilePath; + + @ParameterType(name = InputFile) @Option(name = "-s", aliases = {"--seeds"}, usage = "input seeds file: tabulated file containing node of interest ids", required = true) - String seedsFilePath; + public String seedsFilePath; + + @Format(name = Gml) + @ParameterType(name = OutputFile) @Option(name = "-o", usage = "output file: path to the .gml file where the results scope network will be exported", required = true) - String output; + public String output; //options + @ParameterType(name = InputFile) @Option(name = "-sc", aliases = {"--sides"}, usage = "an optional file containing list of ubiquitous side compounds to be considered available by default but ignored during expansion") public String sideCompoundFile = null; + @Option(name = "-ssc", aliases = {"--showsides"}, usage = "show side compounds in output network", depends = {"-sc"}) public boolean includeSides = false; + + @ParameterType(name = InputFile) @Option(name = "-ir", aliases = {"--ignore"}, usage = "an optional file containing list of reaction to ignore (forbid inclusion in scope") public String reactionToIgnoreFile = null; + @Option(name = "-t", aliases = {"--trace"}, usage = "trace inclusion step index for each node in output") public boolean trace = false; diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/SideCompoundsScan.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/SideCompoundsScan.java index d9e4e27af1e26757b9431045a7ef0f24882e653a..d23d4309e8ada6cca9391dfcf82a9d08cb6fcbf2 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/SideCompoundsScan.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/SideCompoundsScan.java @@ -11,11 +11,18 @@ import fr.inrae.toulouse.metexplore.met4j_graph.io.Bionetwork2BioGraph; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.kohsuke.args4j.Option; import java.io.FileWriter; import java.io.IOException; + +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Sbml; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats.Tsv; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.InputFile; +import static fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes.OutputFile; import java.util.HashMap; import java.util.Map; import java.util.function.Function; @@ -26,9 +33,13 @@ import java.util.stream.Collectors; */ public class SideCompoundsScan extends AbstractMet4jApplication { + @Format(name = Sbml) + @ParameterType(name = InputFile) @Option(name = "-i", usage = "input SBML file", required = true) public String inputPath = null; + @Format(name = Tsv) + @ParameterType(name = OutputFile) @Option(name = "-o", usage = "output Side-Compounds file", required = true) public String outputPath = null; @@ -53,10 +64,10 @@ public class SideCompoundsScan extends AbstractMet4jApplication { @Option(name = "-nc", aliases = {"--neighborCoupling"}, usage = "flag as side compound any compound with a number of parallel edges shared with a neighbor above the given threshold") public double parallelEdge = Double.NaN; - enum strategy {by_name,by_id} + enum strategy {no, by_name,by_id} @Option(name = "-m", aliases = {"--merge"}, usage = "Degree is shared between compounds in different compartments. " + "Use names if consistent and unambiguous across compartments, or identifiers if compartment suffix is present (id in form \"xxx_y\" with xxx as base identifier and y as compartment label).") - public strategy mergingStrat = null; + public strategy mergingStrat = strategy.no; public static void main(String[] args) throws IOException, Met4jSbmlReaderException { @@ -97,7 +108,7 @@ public class SideCompoundsScan extends AbstractMet4jApplication { //if merging compartment Map<String, Integer> mergedDegree = new HashMap<>(); - Boolean merge = (mergingStrat!=null); + Boolean merge = (mergingStrat!=strategy.no); Function<BioMetabolite,String> getSharedId = BioMetabolite::getName; if(merge){ if(mergingStrat.equals(strategy.by_id)) getSharedId = (new VertexContraction.MapByIdSubString("^(\\w+)_\\w$"))::commonField; @@ -172,14 +183,15 @@ public class SideCompoundsScan extends AbstractMet4jApplication { String validFormula = "true"; try{ FormulaParser fp = new FormulaParser(formula); - if(flagInorganic){ - if(fp.isExpectedInorganic()){ + if (flagInorganic) { + if (fp.isExpectedInorganic()) { inorganic = "true"; side = true; - }else{ + } else { inorganic = "false"; } } + }catch(IllegalArgumentException e){ if(flagNoFormula){ validFormula = "false"; diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/utils/ClassUtils.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/utils/ClassUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..d036e8a0f032acaf904773681c385c49883bbd39 --- /dev/null +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/utils/ClassUtils.java @@ -0,0 +1,61 @@ +/* + * Copyright INRAE (2022) + * + * contact-metexplore@inrae.fr + * + * This software is a computer program whose purpose is to [describe + * functionalities and technical features of your software]. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "https://cecill.info/licences/Licence_CeCILL_V2.1-en.html". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * + */ +package fr.inrae.toulouse.metexplore.met4j_toolbox.utils; + +import java.util.ArrayList; +import java.util.List; + +public class ClassUtils { + + public List<Class<?>> getAllSuperClasses(Class c) { + if(c == null) + { + return null; + } + + List<Class<?>> classes = new ArrayList<>(); + Class<?> superclass = c.getSuperclass(); + + while (superclass != null && superclass != Object.class) { + classes.add(superclass); + superclass = superclass.getSuperclass(); + } + + return classes; + + } + +} diff --git a/met4j.singularity b/met4j.singularity index 109a877b275a289b1561a59214ef567c9d77da1a..190e398210efecb988ae80db9663c1b2786727d6 100644 --- a/met4j.singularity +++ b/met4j.singularity @@ -4,11 +4,9 @@ From: debian:stable-slim %runscript if [ $# -lt 1 ] then - echo "display Help" - exec java -jar /opt/bin/met4j.jar + exec sh /opt/bin/met4j.sh else - echo "Lauch met4j-toolbox" - exec java -Dlog4j.configuration= -cp /opt/bin/met4j.jar fr.inrae.toulouse.metexplore.met4j_toolbox."$@" + exec sh /opt/bin/met4j.sh "$@" fi %help @@ -17,7 +15,10 @@ Usage: met4j.sif This is singularity container for met4j +First launch : +cd met4j-toolbox +mvn package %labels Maintainer Ludovic.Cottret@inrae.fr @@ -27,37 +28,15 @@ This is singularity container for met4j apt-get update && \ apt-get upgrade -y && \ apt-get install -y \ - openjdk-11-jre \ - git \ - maven + openjdk-11-jre apt-get clean && \ - apt-get purge + apt-get purge - mkdir -p /opt - - cd /opt - - git clone https://forgemia.inra.fr/metexplore/met4j.git - - cd met4j/ - - mvn install - - cd met4j-toolbox - - mvn package - - mkdir -p /opt/bin - - cp target/met4j*.jar /opt/bin/met4j.jar - - cd /opt - - rm -rf met4j ~/.m2 - - apt-get remove -y maven git - - apt-get autoremove -y + cd /usr/bin && ln -s /opt/bin/met4j.sh %environment export LC_ALL=C + +%files + ./docker_files/met4j.sh /opt/bin/met4j.sh + ./met4j-toolbox/target/met4j*.jar /opt/bin/met4j.jar