Commit 2abf493a authored by Ludovic Cottret's avatar Ludovic Cottret
Browse files

Merge branch 'toolboxJsonDesc' into 'develop'

[toolbox] Galaxy wrappers and json description

See merge request !11
parents b3df96bd 5a829478
...@@ -19,4 +19,4 @@ met4j-core/src/main/java/fr/inra/toulouse/metexplore/met4j_core/Test\.java ...@@ -19,4 +19,4 @@ met4j-core/src/main/java/fr/inra/toulouse/metexplore/met4j_core/Test\.java
dependency-reduced-pom.xml dependency-reduced-pom.xml
/met4j.sif *.sif
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
stages: stages:
- build - build
- test - test
- package
- deploy - deploy
- build-containers - build-containers
...@@ -11,10 +12,34 @@ stages: ...@@ -11,10 +12,34 @@ stages:
image: docker:latest image: docker:latest
services: services:
- docker:dind - 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: variables:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" 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: cache:
paths: paths:
...@@ -24,15 +49,45 @@ build: ...@@ -24,15 +49,45 @@ build:
image: maven:3.6-adoptopenjdk-14 image: maven:3.6-adoptopenjdk-14
stage: build stage: build
script: 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: test:
image: maven:3.6-adoptopenjdk-14 image: maven:3.6-adoptopenjdk-14
stage: test stage: test
script: 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>' - 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: deploySnapshot:
image: maven:3.6-adoptopenjdk-14 image: maven:3.6-adoptopenjdk-14
stage: deploy stage: deploy
...@@ -71,39 +126,35 @@ buildSingularity: ...@@ -71,39 +126,35 @@ buildSingularity:
entrypoint: [ "" ] entrypoint: [ "" ]
script: script:
- singularity build met4j-toolbox.sif met4j.singularity - 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: rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_BRANCH == "master"
when: manual 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 - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
when: manual when: manual
needs:
- build
- package
buildDockerProdGitlab: buildDockerProdGitlab:
extends: .template_docker extends: .template_docker
before_script: before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script: - DOCKER_IMAGE="$CI_REGISTRY/metexplore/met4j/met4j-docker"
- 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
buildDockerProdDockerhub: buildDockerProdDockerhub:
extends: .template_docker extends: .template_docker
before_script: before_script:
- docker login -u "$DOCKERHUB_USER" -p "$DOCKERHUB_PASSWORD" $DOCKERHUB_REGISTRY - docker login -u "$DOCKERHUB_USER" -p "$DOCKERHUB_PASSWORD" $DOCKERHUB_REGISTRY
script: - DOCKER_IMAGE=$DOCKERHUB_IMAGE
- docker build --pull -t "$DOCKERHUB_IMAGE:latest" . \ No newline at end of file
- docker push "$DOCKERHUB_IMAGE:latest"
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: manual
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
when: manual
...@@ -4,25 +4,16 @@ RUN export DEBIAN_FRONTEND=noninteractive ...@@ -4,25 +4,16 @@ RUN export DEBIAN_FRONTEND=noninteractive
RUN apt-get update \ RUN apt-get update \
&& apt-get upgrade -y \ && 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 clean \
&& apt-get purge && apt-get purge
RUN mkdir -p /opt && cd /opt \ RUN mkdir -p /opt/bin
&& 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
COPY ./docker_files/met4j.sh /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
...@@ -10,17 +10,14 @@ ...@@ -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 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 - [met4j-core](met4j-core/README.md): it's the key module which contains all the core
classes for handling metabolic networks classes for handling metabolic networks
- [met4j-io](met4j-io/README.md): for importing/exporting metabolic networks in several - [met4j-io](met4j-io/README.md): for importing/exporting metabolic networks in several
formats (SBML, MetExploreXml, KEGG) formats (SBML, MetExploreXml, KEGG)
- [met4j-graph](met4j-graph/README.md): for performing graph-based topological analysis of metabolic networks. - [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 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.
The full list of implemented metabolic network analysis can be found in the [met4j-toolbox](met4j-toolbox/README.md)
## Installation ## Installation
...@@ -52,41 +49,22 @@ git clone https://forgemia.inra.fr/metexplore/met4j.git; ...@@ -52,41 +49,22 @@ git clone https://forgemia.inra.fr/metexplore/met4j.git;
cd met4j; cd met4j;
mvn clean install mvn clean install
``` ```
to build the executable toolbox jar:
```
cd met4j-toolbox
mvn clean compile assembly:single
mv ./target/*-jar-with-dependencies.jar ../../../
```
## Usage ## Usage
Documentation for the library modules can be found in each module's own README. 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). 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
```
## Contributing ## 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. 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. Please make sure to update tests as appropriate.
## Issues
Issues or suggestions can be posted [here](https://forgemia.inra.fr/metexplore/met4j/-/issues).
## License ## License
Met4J is distributed under the open license [CeCILL-2.1](https://cecill.info/licences/Licence_CeCILL_V2.1-en.html) (compatible GNU-GPL). Met4J is distributed under the open license [CeCILL-2.1](https://cecill.info/licences/Licence_CeCILL_V2.1-en.html) (compatible GNU-GPL).
......
...@@ -44,6 +44,6 @@ if [ $# -lt 1 ] ...@@ -44,6 +44,6 @@ if [ $# -lt 1 ]
echo "display Help" echo "display Help"
exec java -jar $path_jar exec java -jar $path_jar
else else
echo "Lauch met4j-toolbox" echo "Launch met4j-toolbox"
exec java -Dlog4j.configuration= -cp $path_jar fr.inrae.toulouse.metexplore.met4j_toolbox."$@" exec java -Dlog4j.configuration= -cp $path_jar fr.inrae.toulouse.metexplore.met4j_toolbox."$@"
fi fi
\ No newline at end of file
...@@ -81,7 +81,7 @@ public abstract class BioEntity { ...@@ -81,7 +81,7 @@ public abstract class BioEntity {
*/ */
public BioEntity(String id, String name) { public BioEntity(String id, String name) {
if (StringUtils.isVoid(id)) { if (StringUtils.isVoid(id)) {
String newId = UUID.randomUUID().toString().replaceAll("-", "_"); String newId = "_"+UUID.randomUUID().toString().replaceAll("-", "_");
this.id = newId; this.id = newId;
} else { } else {
this.id = id; this.id = id;
......
...@@ -64,234 +64,225 @@ import static fr.inrae.toulouse.metexplore.met4j_core.utils.StringUtils.*; ...@@ -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 * because they do not extend the {@link fr.inrae.toulouse.metexplore.met4j_core.biodata.BioPhysicalEntity} class
* *
* @author Benjamin * @author Benjamin
* @since 3.0
* @version $Id: $Id * @version $Id: $Id
* @since 3.0
*/ */
public class AnnotationParser implements PackageParser, AdditionalDataTag, ReaderSBML1Compatible, ReaderSBML2Compatible, public class AnnotationParser implements PackageParser, AdditionalDataTag, ReaderSBML1Compatible, ReaderSBML2Compatible,
ReaderSBML3Compatible { ReaderSBML3Compatible {
/** Constant <code>ORIGIN="SBML"</code> */ /**
public static final String ORIGIN = "SBML"; * Constant <code>ORIGIN="SBML"</code>
*/
/** public static final String ORIGIN = "SBML";
* The Jsbml Model
*/ /**
public Model model; * The Jsbml Model
/** */
* The BioNetwork public Model model;
*/ /**
public BioNetwork bionetwork; * The BioNetwork
*/
/** public BioNetwork bionetwork;
* The user defined annotation pattern used in the regular expression of
* this class /**
*/ * The user defined annotation pattern used in the regular expression of
public String annotationPattern; * this class
*/
/** public String annotationPattern;
* The default annotation pattern:
* <ul> /**
* <li>http://identifiers.org/([^/]+)/(.*) * The default annotation pattern:
* </ul> * <ul>
* The first parenthesis group is * <li>http://identifiers.org/([^/]+)/(.*)
*/ * </ul>
public static final String defaultAnnotationPattern = "https?://identifiers.org/([^/]+)/(.*)"; * The first parenthesis group is
*/
/** public static final String defaultAnnotationPattern = "https?://identifiers.org/([^/]+)/(.*)";
* Constructor
* /**
* @param useDefault * Constructor
* true to use the {@link #defaultAnnotationPattern} *
*/ * @param useDefault true to use the {@link #defaultAnnotationPattern}
public AnnotationParser(boolean useDefault) { */
if (useDefault) public AnnotationParser(boolean useDefault) {
this.setAnnotationPattern(defaultAnnotationPattern); if (useDefault)
} this.setAnnotationPattern(defaultAnnotationPattern);
}
/**
* Constructor /**
* * Constructor
* @param pattern *
* the user defined pattern * @param pattern the user defined pattern
*/ */
public AnnotationParser(String pattern) { public AnnotationParser(String pattern) {
this.annotationPattern = pattern; this.annotationPattern = pattern;
} }
/** /**
* <p>getAssociatedPackageName.</p> * <p>getAssociatedPackageName.</p>
* *
* @return a {@link java.lang.String} object. * @return a {@link java.lang.String} object.
*/ */
public String getAssociatedPackageName() { public String getAssociatedPackageName() {
return "annot"; return "annot";
} }
/** {@inheritDoc} */ /**
public boolean isPackageUseableOnModel(Model model) { * {@inheritDoc}
return true; */
} public boolean isPackageUseableOnModel(Model model) {
return true;
/** }
* {@inheritDoc}
* /**
* Parse all model entities to retrieve their annotations and extract the * {@inheritDoc}
* desired information * <p>
*/ * Parse all model entities to retrieve their annotations and extract the
public void parseModel(Model model, BioNetwork bionetwork) { * desired information
System.err.println("Starting " + this.getAssociatedPackageName() + " plugin..."); */
public void parseModel(Model model, BioNetwork bionetwork) {
this.setBionetwork(bionetwork); System.err.println("Starting " + this.getAssociatedPackageName() + " plugin...");
this.setModel(model);
this.setBionetwork(bionetwork);
this.parseAnnotation(bionetwork,model.getAnnotation()); this.setModel(model);
this.parseSbmlAnnotations(bionetwork.getReactionsView()); this.parseAnnotation(bionetwork, model.getAnnotation());
this.parseSbmlAnnotations(bionetwork.getMetabolitesView());
this.parseSbmlAnnotations(bionetwork.getGenesView()); this.parseSbmlAnnotations(bionetwork.getReactionsView());
this.parseSbmlAnnotations(bionetwork.getCompartmentsView()); this.parseSbmlAnnotations(bionetwork.getMetabolitesView());
} this.parseSbmlAnnotations(bionetwork.getGenesView());
this.parseSbmlAnnotations(bionetwork.getCompartmentsView());
/** }
*
* One of the different lists present in the {@link BioNetwork} /**
* class * One of the different lists present in the {@link BioNetwork}
*/ * class
private void parseSbmlAnnotations(BioCollection<?> collection) { */
private void parseSbmlAnnotations(BioCollection<?> collection) {
for (BioEntity entry : collection) {
for (BioEntity entry : collection) {
String id = entry.getId();
String id = entry.getId();
if(entry.getAttribute("oldId") != null)
{ if (entry.getAttribute("oldId") != null) {
id = (String) entry.getAttribute("oldId"); id = (String) entry.getAttribute("oldId");
} }
UniqueNamedSBase sbase = this.getModel().findUniqueNamedSBase(id); UniqueNamedSBase sbase = this.getModel().findUniqueNamedSBase(id);
if (sbase != null && !sbase.getAnnotation().isEmpty() && sbase.hasValidAnnotation()) { if (sbase != null && !sbase.getAnnotation().isEmpty() && sbase.hasValidAnnotation()) {
this.parseAnnotation(entry, sbase.getAnnotation()); this.parseAnnotation(entry, sbase.getAnnotation());
} }
} }
} }
/** /**
* Parse entity's annotation to extract external identifiers * Parse entity's annotation to extract external identifiers
* *
* @param annot * @param annot the SBML annotation element
* the SBML annotation element */
*/ private void parseAnnotation(BioEntity ent, Annotation annot) {
private void parseAnnotation(BioEntity ent, Annotation annot) {
Matcher m;
Matcher m; for (CVTerm cv : annot.getListOfCVTerms()) {
for (CVTerm cv : annot.getListOfCVTerms()) {
String qual;
String qual;
if (cv.isBiologicalQualifier()) {
if(cv.isBiologicalQualifier()) {
qual = cv.getBiologicalQualifierType().getElementNameEquivalent();
qual = cv.getBiologicalQualifierType().getElementNameEquivalent(); } else {
} qual = cv.getModelQualifierType().getElementNameEquivalent();
else { }
qual = cv.getModelQualifierType().getElementNameEquivalent();
} for (String ress : cv.getResources()) {
if (this.getAnnotationPattern() != null
for (String ress : cv.getResources()) { && (m = Pattern.compile(this.getAnnotationPattern()).matcher(ress)).matches()) {
if (this.getAnnotationPattern() != null
&& (m = Pattern.compile(this.getAnnotationPattern()).matcher(ress)).matches()) {