Met­Ex­plore

Find­ing your path through net­work complexity

  1. Data­base Map­ping and Web appli­ca­tion Tutorials
  2. Tuto­r­ial 1: Using an InChI /​InChIKey retrieval web ser­vice using a Bash script
  3. Tuto­r­ial 2: Build­ing a sim­ple HTML/​javascript /​php application

Data­base Map­ping and Web appli­ca­tion Tutorials

In this sec­tion we will see how we can cre­ate a web appli­ca­tion that uses the data­base map­ping and dis­plays the result in an online table.

For this we will use HTML/​php scripts

Skill Require­ments:

  • Shell Script
  • HTML 5 /​CSS 3
  • php 5.3 or higher
  • JavaScript

Soft­ware Requirements

  • OS: Linux ( eg Ubuntu/​Debian) or Mac OS X
  • In-​house InChI /​InChIKey retrieval web ser­vice (optional)

For this tuto­r­ial we will use Peak­For­est web ser­vice as an exam­ple. You can use this web ser­vice if you don’t have any InChI /​InChIKey retrieval web service

Tuto­r­ial 1: Using an InChI /​InChIKey retrieval web ser­vice using a Bash script

In this tuto­r­ial, we will use a shell script to call MetExplore’s web ser­vice and per­form the actual map­pings on the pub­lic net­works present on MetExplore’s database.

In a text edi­tor, cre­ate a new file and copy paste the fol­low­ing code:

#!/bin/bash
name="metexploreTutorial";
email="youremailAtyourdomain.com";
wsUrl="https://rest.peakforest.org/compounds/all/inchi";

url="http://metexplore.toulouse.inra.fr:8080/metExploreWebService/mapping/launch/inchi?name=$name&wsurl=$wsUrl&email=$email";
curl $url;

Replace "youremailAtyourdomain.com" by your actual e-​mail address.

You can also change the name vari­able to fit your dataset.

If you have your own InChI retrieval web ser­vice, change the value of the wsUrl vari­able to match the URL of your own web service


TIPS :

If you wish to use InChIkeys instead of InChIs, use :

wsUrl="https://rest.peakforest.org/compounds/all//inchikey";

url="http://metexplore.toulouse.inra.fr:8080/metExploreWebService/mapping/launch/inchikey?name=$name&wsurl=$wsUrl&email=$email";

Save this file as a shell script (.sh exten­sion) in your home directory.

Open a ter­mi­nal, change per­mis­sions of the file so it can be exe­cuted through the ter­mi­nal (chmod 755 script​.sh) and launch it through the terminal.

This should appear in your terminal:

Map­ping launched, you will receive an email when the result is available.

And you should receive an auto­matic email when all the map­pings are done. In this email, you will have a link that points to the result file of your mapping.


For exam­ple, once the shell script is launch, it will send to your email address the fol­low­ing link:

http://​met​ex​plore​.toulouse​.inra​.fr:8080/​m​e​t​E​x​p​l​o​r​e​W​e​b​S​e​r​v​i​c​e​/​m​a​p​p​i​n​g​/​r​e​s​u​l​t​/​m​e​t​e​x​p​l​o​r​e​T​u​t​o​r​i​a​l (this link will pro­vide an exam­ple of the result file)

Open­ing this URL in a browser, will dis­play the result of the map­ping as a JSON (JavaScript Object Nota­tion) file. This kind of file for­mat is nor­mally used as a data trans­fer for­mat and should not be used for web display.

We will see in the next tuto­ri­als how we can use this data trans­fer file in a dynamic web interface.


TIPS for exper­i­mented Linux Users:

If you want your map­pings to be updated fre­quently, you can launch this script through a Cron Job. Cron jobs can auto­mat­i­cally launch scripts every day, week or months depend­ing on its configuration.

To set this up, run the command

crontab –e

on your ter­mi­nal. On Ubuntu dis­tri­b­u­tion a nano text edi­tor will open on the ter­mi­nal with a small doc­u­men­ta­tion of crontab.

For exam­ple, to have a map­ping done every months, write at the end of the crontab file:

0 5 1 * * /path/to/script.sh

save (ctrl+o) then quit (ctrl+x). Now, a cron job will launch the script we made the 1st of every month at 5am.


Tuto­r­ial 2: Build­ing a sim­ple HTML/​javascript /​php application

In this tuto­r­ial, we will use a sim­ple html/​php to gen­er­ate a web appli­ca­tion to dis­play the result of the mapping.

First open a ter­mi­nal, and go to your server direc­tory ( com­mand cd /​var/​www/​ ), here cre­ate the root folder of your application:

sudo mkdir metexploreTutorial

here you will be prompted your sudo password.

then allow a nor­mal user to write in this folder:

sudo chmod 777 metexploreTutorial/


TIPS:

If you don’t have root access to your machine, con­tact your Sys­tem Admin­is­tra­tor so he can do this for you.


Dis­play map­ping results using Javascript and php:

First let’s pre­pare our html page to host a table where our results will be dis­played. Your index.html should look like this:

<!DOCTYPE html>
<html>
    <head>
       <meta charset="utf-8" />
       <title>Mapping results</title>

       <script type="text/javascript">
           // ...
       </script>
    </head>

    <body>
        <h1>Mapping Results</h1>
        <table style="width:100%"  >
            <thead>
                <tr>
                    <th>Organism name</th>
                    <th>Network name</th>
                    <th>Number of metabolites</th>
                    <th>Metabolites Mapped</th>
                </tr>
            </thead>
            <tbody id="resultContainer">
                
            </tbody>
        </table>
    </body>
</html>

Save this file as “index.html” in your appli­ca­tion folder. Open any web browser and enter the fol­low­ing URL:

http://localhost/metexploreTutorial/

Your browser should dis­play this page:

Now let’s add some JavaScript to dynam­i­cally ren­der the table with the results of all the map­pings per­formed with our shell script.

The main issue here is that we can­not directly call the result URL in the javascript code inside our html page. Doing so will raise a CORS (Cross-​origin resource shar­ing) error.
What does that mean?

Cross-​origin errors means that we are try­ing to access web resources present on a dif­fer­ent host than our web application.

Here for exam­ple, the web– client (ie the web browser) is asked to access a resource present on the Met­Ex­plore server at http://​met​ex​plore​.toulouse​.inra​.fr while our appli­ca­tion is present on local­host.

To get around this, we need to make our application’s server (here local­host ) call MetExplore’s web ser­vice and send back the result to the web client.

Here’s a small fig­ure to illus­trate this:

In order to estab­lish the dia­log between our local­host and MetExplore’s web ser­vice, we will use a php script.

Open a new file in your text edi­tor and add the fol­low­ing code:

<?php
    $url="http://metexplore.toulouse.inra.fr:8080/metExploreWebService/mapping/result/metexploreTutorial";
      
    $result  = file_get_contents($url);

    echo $result;
?>

save this file in your appli­ca­tion root folder, for exam­ple as getResult.php

Be sure to put the url you received by email in the $url vari­able, oth­er­wise this will not work.

Now, we need to make our html call this php script. Because we don’t want the page to be frozen while the data is col­lected by this script, we will use an asyn­chro­nous request to call our php script.

Asyn­chro­nous requests means that the web client will not wait for the script to fin­ish. This kind of request enhance user expe­ri­ence as they can move freely in your web appli­ca­tion while the request is being han­dled by the server.

Go back to your html page and add this to the <script></script> tag :

        <script type="text/javascript">
            function loadResults (){
                var xhttp = new XMLHttpRequest();
                xhttp.onreadystatechange = function() {
                    if (xhttp.readyState == 4 && xhttp.status == 200) {
                        var tbody=document.getElementById("resultContainer");
                        var dataObj = JSON.parse(xhttp.responseText);
                        for(var i in dataObj){
                            var row=tbody.insertRow(-1);
                            row.insertCell(0).innerHTML=dataObj[i].orgName;
                            row.insertCell(1).innerHTML=dataObj[i].nameBioSource;
                            row.insertCell(2).innerHTML=dataObj[i].NumberOfMetabolitInBiosource;
                            row.insertCell(3).innerHTML=dataObj[i].MetaboliteMapped;
                        }
                    }
                };

                xhttp.open("GET","getResult.php" , true);
                xhttp.send();
            }
       </script>

Lets explain this code.

var xhttp =new XMLHttpRequest();

This will cre­ate the object that will exe­cute our php script and receive the result from our localhost.

xhttp.open("GET","getResult.php" , true);

The open func­tion is used to cre­ate a request resource. It has three parameters:

  • The first one is the method used to access the resource (GET, POST, ADD, PUT, DELETE)
  • The sec­ond para­me­ter is the filepath/​URL of the resource we are try­ing to access. Here we used a rel­a­tive filepath because the php file we are using is in the same folder as our index.html
  • the third and last para­me­ter is a boolean to spec­ify if the request should be asyn­chro­nous (true) or not (false)

Once the request has been para­me­ter­ized, we send it to the appro­pri­ate host, here our local­host, with

xhttp.send;

What about the xhttp.onreadystatechange ?

Well this par­tic­u­lar line of code is what we call an event, the func­tion asso­ci­ated with it will be launched every­time this par­tic­u­lar event occurs.

The event we chose to use is the onreadys­tat­e­change event, this event is trig­gered when the state of the request changes. this sta­tus changes from 0 to 4 like this:

  • 0: request not initialized
  • 1: server con­nec­tion established
  • 2: request received
  • 3: pro­cess­ing request
  • 4: request fin­ished and response is ready

So in prac­tice our func­tion is launched 4 times in a row. That’s why we test the actual value of the readyS­tate of our xhttp object in the func­tion by a if statement:

if(xhttp.readyState == 4 && xhttp.status == 200)

In this test we also check if the sta­tus of the response is equal to 200, this sta­tus means that every­thing went ok. Be care­ful, hav­ing a readyS­tate equal to 4 does not nec­es­sar­ily mean that the sta­tus of the response is 200. If an error occurred in your php script the sta­tus of the response will be 500 but the readyS­tate of our XML­HttpRe­quest object will still be 4 as it received a response from the server.


TIPS:

Be sure to define the onreadys­tat­e­change event func­tion before send­ing any request.


So now we are sure that our request to the server has been sent and that every­thing went as it should. How do we process the response to pop­u­late our table?

var dataObj = JSON.parse(xhttp.responseText);

Here we take the actual response as a string vari­able and pass it as a para­me­ter of JSON.parse. This will cre­ate a JSON object from the JSON string rep­re­sen­ta­tion returned by MetExplore’s web service.

In fact, that object is a JSON Array, each ele­ment being the result of the map­ping on a sin­gle network

For each ele­ment of this array we add a row to our table body with:

var row=tbody.insertRow(-1);

Using the –1 index here always adds the row at the end of the table. Then for each row, we add the cells we wanted and add the desired value as the cells’ inner HTML:

   row.insertCell(0).innerHTML=dataObj[i].orgName;
   row.insertCell(1).innerHTML=dataObj[i].nameBioSource;
   row.insertCell(2).innerHTML=dataObj[i].NumberOfMetabolitInBiosource;
   row.insertCell(3).innerHTML=dataObj[i].MetaboliteMapped;

Now we are ready to call our javascript func­tion to load our data on our page. but when and how can we call that function?

For this, we will use some­thing we used just before: events.

Every html ele­ments have pre­de­fined events that can be used to call some scripts. For our exam­ple, we will use the “onload” event of the body ele­ment of our html page. Here is how your body tag should look like:

<body onload="loadResults();">

Save and reload your appli­ca­tion, here is what you should have: