Commit 5a829478 authored by Ludovic Cottret's avatar Ludovic Cottret
Browse files

[toolbox] Galaxy wrappers and json description

parent b3df96bd
......@@ -19,4 +19,4 @@ met4j-core/src/main/java/fr/inra/toulouse/metexplore/met4j_core/Test\.java
dependency-reduced-pom.xml
/met4j.sif
*.sif
......@@ -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
......@@ -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
......@@ -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
```
## 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).
......
......@@ -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
......@@ -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;
......
......@@ -64,13 +64,15 @@ 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> */
/**
* Constant <code>ORIGIN="SBML"</code>
*/
public static final String ORIGIN = "SBML";
/**
......@@ -100,8 +102,7 @@ public class AnnotationParser implements PackageParser, AdditionalDataTag, Reade
/**
* Constructor
*
* @param useDefault
* true to use the {@link #defaultAnnotationPattern}
* @param useDefault true to use the {@link #defaultAnnotationPattern}
*/
public AnnotationParser(boolean useDefault) {
if (useDefault)
......@@ -111,8 +112,7 @@ public class AnnotationParser implements PackageParser, AdditionalDataTag, Reade
/**
* Constructor
*
* @param pattern
* the user defined pattern
* @param pattern the user defined pattern
*/
public AnnotationParser(String pattern) {
this.annotationPattern = pattern;
......@@ -127,14 +127,16 @@ public class AnnotationParser implements PackageParser, AdditionalDataTag, Reade
return "annot";
}
/** {@inheritDoc} */
/**
* {@inheritDoc}
*/
public boolean isPackageUseableOnModel(Model model) {
return true;
}
/**
* {@inheritDoc}
*
* <p>
* Parse all model entities to retrieve their annotations and extract the
* desired information
*/
......@@ -144,7 +146,7 @@ public class AnnotationParser implements PackageParser, AdditionalDataTag, Reade
this.setBionetwork(bionetwork);
this.setModel(model);
this.parseAnnotation(bionetwork,model.getAnnotation());
this.parseAnnotation(bionetwork, model.getAnnotation());
this.parseSbmlAnnotations(bionetwork.getReactionsView());
this.parseSbmlAnnotations(bionetwork.getMetabolitesView());
......@@ -153,7 +155,6 @@ public class AnnotationParser implements PackageParser, AdditionalDataTag, Reade
}
/**
*
* One of the different lists present in the {@link BioNetwork}
* class
*/
......@@ -163,8 +164,7 @@ public class AnnotationParser implements PackageParser, AdditionalDataTag, Reade
String id = entry.getId();
if(entry.getAttribute("oldId") != null)
{
if (entry.getAttribute("oldId") != null) {
id = (String) entry.getAttribute("oldId");
}
......@@ -181,8 +181,7 @@ public class AnnotationParser implements PackageParser, AdditionalDataTag, Reade
/**
* Parse entity's annotation to extract external identifiers
*
* @param annot
* the SBML annotation element
* @param annot the SBML annotation element
*/
private void parseAnnotation(BioEntity ent, Annotation annot) {
......@@ -191,11 +190,10 @@ public class AnnotationParser implements PackageParser, AdditionalDataTag, Reade
String qual;
if(cv.isBiologicalQualifier()) {
if (cv.isBiologicalQualifier()) {
qual = cv.getBiologicalQualifierType().getElementNameEquivalent();
}
else {
} else {
qual = cv.getModelQualifierType().getElementNameEquivalent();
}
......@@ -205,12 +203,10 @@ public class AnnotationParser implements PackageParser, AdditionalDataTag, Reade
if (m.group(1).equalsIgnoreCase("ec-code") && ent instanceof BioReaction) {
String oldEc = ((BioReaction) ent).getEcNumber();
if(isVoid(oldEc))
{
if (isVoid(oldEc)) {
((BioReaction) ent).setEcNumber(m.group(2));
}
else {
((BioReaction) ent).setEcNumber(oldEc+";"+m.group(2));
} else {
((BioReaction) ent).setEcNumber(oldEc + ";" + m.group(2));
}
}
ent.addRef(m.group(1), m.group(2), 1, qual, ORIGIN);
......@@ -221,17 +217,15 @@ public class AnnotationParser implements PackageParser, AdditionalDataTag, Reade
String nonrdfAnnot = annot.getNonRDFannotationAsString();
if (ent instanceof BioMetabolite && nonrdfAnnot != null && !nonrdfAnnot.isEmpty()) {
String specialInchiPattern = "<in:inchi xmlns:in=\"([^\"]+)\">InChI=([^<]+)</in:inchi>";
String specialInchiPattern = "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);
String inchi = m.group(1);
if (!ent.hasRef("inchi", inchi)) {
ent.addRef("inchi", inchi, 1, "is", ORIGIN);
}
((BioMetabolite) ent).setInchi(inchi);
}
}
}
......@@ -249,8 +243,7 @@ public class AnnotationParser implements PackageParser, AdditionalDataTag, Reade
/**
* <p>Setter for the field <code>model</code>.</p>
*
* @param model
* the model to set
* @param model the model to set
*/
public void setModel(Model model) {
this.model = model;
......@@ -268,8 +261,7 @@ public class AnnotationParser implements PackageParser, AdditionalDataTag, Reade
/**
* <p>Setter for the field <code>bionetwork</code>.</p>
*
* @param bionetwork
* the bionetwork to set
* @param bionetwork the bionetwork to set
*/
public void setBionetwork(BioNetwork bionetwork) {
this.bionetwork = bionetwork;
......@@ -287,8 +279,7 @@ public class AnnotationParser implements PackageParser, AdditionalDataTag, Reade
/**
* <p>Setter for the field <code>annotationPattern</code>.</p>
*
* @param annotationPattern
* the annotationPattern to set
* @param annotationPattern the annotationPattern to set
*/
public void setAnnotationPattern(String annotationPattern) {
this.annotationPattern = annotationPattern;
......
......@@ -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;
......
......@@ -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();
......
......@@ -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");
}
......
......@@ -260,6 +260,9 @@ public class AnnotationParserTest {
assertEquals(refInchis, s1.getRefs());
System.err.println(s1.getInchi());
assertEquals("truc", s1.getInchi());
}
}
# 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 \