Arthor Documentation for Future Developer: Difference between revisions

From DISI
Jump to navigation Jump to search
No edit summary
(83 intermediate revisions by 2 users not shown)
Line 1: Line 1:
== Introduction ==
== Introduction ==
[https://www.nextmovesoftware.com/downloads/arthor/documentation/Arthor.pdf Here is the link to Arthor's manual]
[https://www.nextmovesoftware.com/downloads/arthor/documentation/Arthor.pdf Here is the link to Arthor's manual]
* Username: ucsf@nextmovesoftware.com
* Password: <Ask jjiteam@googlegroups.com>


Arthor configurations and the frontend files are consolidated in '''/nfs/soft2/arthor_configs/'''.
Arthor configurations and the frontend files are consolidated in '''/nfs/soft2/arthor_configs/'''.
Line 14: Line 16:
#* Username: ucsf@nextmovesoftware.com
#* Username: ucsf@nextmovesoftware.com
#* Password: <Ask jjiteam@googlegroups.com>
#* Password: <Ask jjiteam@googlegroups.com>
# Go to releases. Look for the right OS and copy the link address.
# Go to releases. Look for ''' smallworld-java-<version>.tar.gz ''' and copy the link address.
# Download using wget
# Download using wget
#: <source> wget --user ucsf@nextmovesoftware.com --password <Ask jjiteam@googlegroups.com> <link address> </source>
#: <source> wget --user ucsf@nextmovesoftware.com --password <Ask jjiteam@googlegroups.com> <link address> </source>
Line 21: Line 23:


== How To Launch Arthor For The First Time ==
== How To Launch Arthor For The First Time ==
=== Prepare Files and Directories ===
# Ssh to nfs-exc and become root
# Ssh to nfs-exc and become root
# Open a port in the firewall
# Open a port in the firewall
Line 40: Line 43:
Resolver=https://sw.docking.org/util/smi2mol?smi=%s
Resolver=https://sw.docking.org/util/smi2mol?smi=%s
</source>
</source>
=== Start Arthor Instance ===
# Now ssh into a machine you wish to run an Arthor instance on and become root
# Now ssh into a machine you wish to run an Arthor instance on and become root
# Change your shell to bash if you havn't already
# Change your shell to bash if you havn't already
Line 48: Line 52:
#: <source>export ARTHOR_CONFIG="/nfs/soft2/arthor_configs/arthor-<version>/<name_of_config_file>.cfg"</source>
#: <source>export ARTHOR_CONFIG="/nfs/soft2/arthor_configs/arthor-<version>/<name_of_config_file>.cfg"</source>
# Launch java
# Launch java
#: <source>java -jar /nfs/soft2/arthor_configs/arthor-<version>/arthor-<version>-centos7/java/arthor.jar --httpPort=<port_number></source>
#: <source>java -jar -Dserver.port=<port_number> /nfs/soft2/arthor_configs/arthor-<version>/arthor-server-<version>.war</source>


=== Configuration Details ===
=== Configuration Details ===
Line 67: Line 71:


== How to Build Arthor Databases==
== How to Build Arthor Databases==
===Building Large Databases===
We can build Arthor Databases anywhere. Consolidate smiles into one directory so you can index them all one by one.
At the moment, we are building databases of size 500M molecules by merging smile files. There are multiple methods of trying to create large databases, one being merging based off of the same H?? prefix and stopping once the database reaches > 500M molecules (or whatever upperbound you want to use). Here is some python code that simulates this merging process. Essentially the program takes all of the .smi files within an input directory, sorts them lexiographically, and begins merging these .smi files together in order until the size reaches > 500M molecules.
 
Feel free to modify it if you think a better method exists.
 
  import subprocess
  import sys
  import os                                                                                                                                                                         
 
  from os import listdir
  from os.path import isfile, join
 
  mypath = "<Path to directory holding .smi files>"
  onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
  onlyfiles.sort()
 
  create_fp = True
  cur_mols = 0
  lower_bound = 500000000
  upper_bound = 600000000
  files_to_merge = []
 
  def merge_files(f_t_m):
      arr = f_t_m[0].split(".")
      arr2 = f_t_m[len(f_t_m) - 1].split(".")
      file_name_merge = (arr[0] + "_" + arr2[0] + ".smi")
      print ("File being created: " + file_name_merge)
 
      for file in f_t_m:
        tmp = file.split(".")
        process = subprocess.Popen("cat " + join(mypath, file) + " >> " + file_name_merge, shell=True)
        process.wait()
 
  for file in onlyfiles:
      arr = file.split(".")
 
      if (arr[len(arr) - 1] == "smi"):
        print("Working with " + file)
        mol = sum(1 for line in open(join(mypath, file)))
        print(file, mol, cur_mols)
 
        if (cur_mols + mol > lower_bound):
            if (cur_mols + mol < upper_bound):
              files_to_merge.append(file)
              merge_files(files_to_merge)
              cur_mols = 0
              files_to_merge.clear()
            else:
              merge_files(files_to_merge)
              files_to_merge.clear()
              files_to_merge.append(file)
              merge_files(files_to_merge)
              cur_mols = 0
              files_to_merge.clear()
        else:
            cur_mols += mol
            files_to_merge.append(file)
 
  if (len(files_to_merge) != 0):
      merge_files(files_to_merge)


===Building Arthor Indexes===
Just use the script located at '''/nfs/home/jjg/scripts/arthor_index_script.sh''' at the directory where you stored the smiles.
Once you've merged the .smi files together, it's time to start building the databases themselves. To do this we use the command


  smi2atdb -j 0 -p <The .smi file> <The .atdb>  
Here is the content of the script:
<source>
#!/bin/bash


The flag "-j 0" enables parallel generation and utilizes all available processors to generate the .atdb file. The "-p" flag stores the offset position in the ATDB file. Since we're building indexes for the Web Application, you must use the "-p" flag when building indexes. Please note that the name of the .smi file should also be the name of the .atdb file. That way, the Web Application knows to use these files together and correctly display the required images. Refer to pages 33-34 in the Arthor documentation for more information.
target="*.smi"
threads='48'
version="3.6.1"


If there are too many large .smi files and you do not want to manually build each .atdb file, you can use this python script which takes all of the .smi files in the current directory and converts them to .atdb files. Make sure to modify mypath to the directory containing the .smi files. You can change the variable "create_fp" to false if you don't want to create .atdb.fp files (refer to page 9 in the Arthor documentation).


  import subprocess
export ARTHOR_DIR=/nfs/soft2/arthor_configs/arthor-$version/arthor-$version-centos8/
  import sys
export PATH=$ARTHOR_DIR/bin/:$PATH
  import os
 
  from os import listdir
  from os.path import isfile, join
 
  mypath = "<Path containing the .smi files"
  onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
 
  create_fp = True
 
  for file in onlyfiles:
      arr = file.split(".")
 
      if (arr[len(arr) - 1] == "smi"):
        process = subprocess.Popen("/nfs/ex9/work/xyz/psql/arthor-3.3-centos7/bin/smi2atdb -j 0 -p {0} {1}.atdb".format(join(mypath, file), arr[0]), shell=True)
        process.wait()
 
        print("SUCCESS! {0}.atdb file was created!".format(arr[0]))
 
        if (create_fp):
            process = subprocess.Popen("/nfs/ex9/work/xyz/psql/arthor-3.3-centos7/bin/atdb2fp -j 0 {0}.atdb".format(arr[0]), shell=True)
            process.wait()
     
            print("SUCCESS! {0}.atdb.fp file was created!".format(arr[0]))


==Setting up Round Table==
for j in $target
This is a new feature in Arthor 3.0 and is currently beta (January 2020). See section 2.4 in the manual
do
As explained in the manual, "Round Table allows you to serve and split chemical searches across multiple host machines. The implementation provides a lightweight proxy that forwards requests to other Arthor host servers that do the actual search.  Communication is done using the existing Web APIs.
        echo 'smi2atdb -v -r -j '$threads' -p '$j' '${j}'.atdb |& tee -a '${j}'_log'
        time smi2atdb -v -r -j $threads -p $j ${j}.atdb |& tee -a ${j}_log
echo 'smi2atfp -j '$threads' -p '$j' '${j}.atfp' |& tee -a '${j}'_log'
        time smi2atfp -j $threads -p $j ${j}.atfp |& tee -a ${j}_log
done


Since Arthor requires CentOS 7, as of January 2020 we have 6 servers that are capable of running Arthor with Round Table.
for i in $target*atdb
do
echo 'atdb2fp -j '$threads' '$i
        time atdb2fp -j $threads $i
chmod 744 $i.fp
done
</source>


===Setting up Host Server===
=== Command Details ===
If we want to add machines to the Round Table, for example 'nun' and 'samekh', we need to edit their arthor.cfg file so that when our Local Machine passes commands these secondary servers know to perform the search they are given.
'''smi2atdb''' creates the atdb files needed for Substructure searching.
*'''-v''' verbose
*'''-r''' Compute and store ring size information in the index allowing ring size (3-10) expressions ([r6] and [Z5])
*'''-j''' is the amount of threads to use to index the smiles file
*'''-p''' stores the position of the original file
'''atdb2fp''' makes substructure searching faster


  $ cat arthor.cfg
'''smi2atfp''' creates atfp files for similarity searching
  MaxThreadsPerSearch=4
  AutomaticIndex=false
  DATADIR=<Directory where smiles are located>


We then run the jar server on each of these host machines containing data on any available port.  
==Setting up Round Table==
 
"Round Table allows you to serve and split chemical searches across multiple host machines. The implementation provides a lightweight proxy that forwards requests to other Arthor host servers that do the actual search.  Communication is done using the existing Web APIs.
  java -jar /nfs/ex9/work/xyz/psql/arthor-3.3-centos7/java/arthor.jar --httpPort <port>
===Setting up Host Server===
 
# Ssh to nfs-soft2 and become root
For our local machine, the arthor.cfg file will look different.
# Open a port in the firewall
 
#: <source>firewall-cmd --permanent --add-port=<port_number>/tcp
  $ cat arthor.cfg
firewall-cmd --reload
  [RoundTable]  
</source>
  RemoteClient=http://skynet:<port number where jar server is running>/
# Go to Arthor Config Directory
  RemoteClient=http://hal:<port number where jar server is running>/
#: <source>cd /export/soft2/arthor_configs/arthor-<version></source>
 
# Create Round Table Head configuration file. Here is an example:
Please refer to Section 2 in the RoundTable Documentation file (pages 6-8) for more useful information on configuration.
# <source>
 
[RoundTable]
Then run the following command on n-1-136:
RemoteClient=http://10.20.0.41:8008
RemoteClient=http://10.20.5.19:8008
  java -jar /nfs/ex9/work/xyz/psql/arthor-3.3-centos7/java/arthor.jar --httpPort <port>
Resolver=https://sw.docking.org/util/smi2mol?smi=%s
 
</source>
==='''***Arthor configs and frontend code are located in /nfs/exc/arthor_configs/***'''===
# Now ssh into a machine you wish to run the round table head on and become root
# Change your shell to bash if you havn't already
#: <source>bash</source>
# Create a screen
#: <source>screen -S <screen_name></source>
# Prepare Arthor Config Path
#: <source>export ARTHOR_CONFIG="/nfs/soft2/arthor_configs/arthor-<version>/<round_table_head>.cfg"</source>
# Launch java
#: <source>java -jar /nfs/soft2/arthor_configs/arthor-<version>/arthor-<version>-centos7/java/arthor.jar --httpPort=<port_number></source>


== Active Arthor Instances ==
===Public Arthor===
===Public Arthor===
{| class="wikitable"
{| class="wikitable"
|-
|-
! CentOS 7 Machine
! Rocky Linux Machine
! Port
! Port
! Round Table Data Directory
! Round Table Data Directory
! Active
! Which Arthor
|-
|-
| samekh
| arthor
| 10.20.0.41:8000
| 10.20.200.100:8080
| /local2/public_arthor/
| /local3/public_arthor/
| active
| Public Arthor
|-
| nun
| 10.20.0.40:8000
| /local2/public_arthor/
| active
|-
| n-9-22
| 10.20.9.22:8000
| /export/db4/public_arthor/
| active
|-
|-
|}
|}


===Arthor Round Table Head===
===Private Arthor===
{| class="wikitable"
{| class="wikitable"
|-
|-
! CentOS 7 Machine
! Rocky Linux Machine
! Port
! Port
! Round Table Data Directory
! Round Table Data Directory
! Active
! Which Arthor
|-
| samekh
| 10.20.0.41:8080
| /local2/arthor_database/
| active
|-
|-
| nun
| arthor
| 10.20.0.40:8080
| 10.20.200.100:8081
| /local2/arthor_database/
| /local3/private_arthor/
| active
| Private Arthor
|-
|-
|}
|}


===Arthor Round Table Nodes===
===Super Private Arthor===
{| class="wikitable"
{| class="wikitable"
|-
|-
! CentOS 7 Machine
! Rocky Linux Machine
! Port
! Port
! Round Table Data Directory
! Round Table Data Directory
!Active
! Which Arthor
|-
| samekh
| 10.20.0.41:8008
| /local2/arthor_database/
| active
|-
| nun
| 10.20.0.40:8008
| /local2/arthor_database/
| active
|-
| n-1-17
| 10.20.1.17:8008
| /local2/arthor_database/
| not active
|-
| n-5-32
| 10.20.5.32:8008
| /local2/arthor_database/
| not active
|-
|-
| n-5-33
| arthor
| 10.20.5.33:8008
| 10.20.200.100:8082
| /local2/arthor_database/
| /local3/super_private_arthor/
| not active
| Private Arthor
|-
|-
|}
|}


===Arthor Local 8081 (Datasets all local to samekh/nun)===
===Arthor BB, CC, and Covalent===
{| class="wikitable"
{| class="wikitable"
|-
|-
! CentOS 7 Machine
! CentOS 7 Machine
! Port
! Port
! Round Table Data Directory
! Data Directory
!Active
! Which Arthor
|-
| epyc-A40
| 10.20.200.92:8081
| /local2/arthorbb
| ArthorBB
|-
|-
| samekh
| epyc-A40
| 10.20.0.41:8081
| 10.20.200.92:8082
| /local2/arthor_local_8081/
| /local2/arthorcc
| not active
| ArthorCC
|-
|-
| nun
| epyc-A40
| 10.20.0.40:8081
| 10.20.200.92:8080
| /local2/arthor_local_8081/
| /local2/arthorcovalent
| not active
| Arthor Covalent
|-
|-
|}
|}


== Customizing Arthor Frontend to our needs ==
== Customizing Arthor Frontend To Our Needs (Arthor 4.1) ==
The frontend Arthor code is located at '''/nfs/exc/arthor_configs/*''' and the '''*''' is based on current running version.
'''These instructions only worked and compiled for me in the machine called epyc which is running Rocky 8 Linux operating system.'''
=== Add Arthor Download Options ===
==== For Arthor 3.4: ====
1. vim .extract/webapps/ROOT/WEB-INF/static/index.html


2. search: '''arthor_tsv_link'''
Summary of changes in index.html:
*Add contact info
*Advertise TLDR
*Remove button for Formula
*Database Information Link


3. in the div with the class=”dropdown-content”, add these link options and change the number accordingly:
Summary of changes in index.js:
*Hyperlink the results to zinc20 or cartblanche22
*Copy SMILES with clipboard button


              <a id="arthor_tsv_link" href="#"> TSV-500</a>
Summary of changes in sketcher.js:
              <a id="arthor_tsv_link_5000" href="#"> TSV-5,000</a>
*Input box should be updated as user draws molecule
              <a id="arthor_tsv_link_50000" href="#"> TSV-50,000</a>
 
              <a id="arthor_tsv_link_100000" href="#"> TSV-100,000</a>
Summary of changes in arthor-swagger.yaml.js:
              <a id="arthor_tsv_link_max" href="#"> TSV-max</a>
*Make API point to "/"
              <a id="arthor_csv_link" href="#"> CSV-500</a>
 
              <a id="arthor_csv_link_5000" href="#"> CSV-5,000</a>
 
              <a id="arthor_csv_link_50000" href="#"> CSV-50,000</a>
=== Install Prerequisite Packages ===
              <a id="arthor_csv_link_100000" href="#"> CSV-100,000</a>
# Install Apache Maven
              <a id="arthor_csv_link_max" href="#"> CSV-max</a>
#* <source>dnf install maven -y</source>
              <a id="arthor_sdf_link" href="#"> SDF-500</a>
# Install Node Package Manager (NPM)
              <a id="arthor_sdf_link_5000" href="#"> SDF-5,000</a>
#* <source>dnf install npm -y</source>
              <a id="arthor_sdf_link_50000" href="#"> SDF-50,000</a>
# In your home directory, create a new directory to hold the files for the upcoming procedures
              <a id="arthor_sdf_link_100000" href="#"> SDF-100,000</a>
#* <source>mkdir /mnt/nfs/home/jjg/arthor_build_from_source</source>
              <a id="arthor_sdf_link_max" href="#"> SDF-max</a>
# Download these latest Arthors and store them in 'arthor_build_from_source/'. [[Arthor Documentation for Future Developer#How To Download Arthor|Here's how to download Arthor.]]
#* arthor-4.1-source.tar.gz
#* arthor-4.1-centos8.tar.gz
# Extract contents from the tar.gz files
#* <source>tar -xvf arthor-4.1-source.tar.gz
tar -xvf arthor-4.1-centos8.tar.gz</source>
# Install Apache Maven Arthor dependencies through this script
#* <source>
#!/bin/bash
 
version=4.1
 
export ARTHOR_DIR=/mnt/nfs/home/jjg/arthor_build_from_source/arthor-$version/arthor-$version-centos8/java/
export OS=linux
export VERSION=$version
 
mvn install:install-file -Dfile=$ARTHOR_DIR/arthor-jni-${OS}.jar \
                        -Dpackaging=jar \
                        -DgeneratePom=true \
                        -DartifactId=arthor-jni-${OS} \
                        -DgroupId=com.nextmovesoftware.arthor \
                        -Dversion=$VERSION
mvn install:install-file -Dfile=$ARTHOR_DIR/arthor-jni.jar \
                        -Dpackaging=jar \
                        -DgeneratePom=true \
                        -DartifactId=arthor-jni \
                        -DgroupId=com.nextmovesoftware.arthor \
                        -Dversion=$VERSION
</source>
=== Customizing Index.html ===
Location: /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server/src/main/webapp/WEB-INF/static/index.html
 
==== Add contact info and tldr ====
# vim /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server/src/main/webapp/WEB-INF/static/index.html
# Search for 'arthor_table_list'
#* <source>?arthor_table_list</source>
# Add contact info, a plug to tldr.docking.org, and database link after the div block where arthor_table_list is inside of. It should look like this
#* <source>
      <div class="opt-box-border">
        <label>Databases</label>
        <!-- This will be populated by available databases -->
        <ul id="arthor_table_list">
          <li class="placeholder">Please select a search type</li>
        </ul>
      </div>
      <div class="opt-box-border">
        <label>Ask Questions</label>
        Email us: jjiteam@googlegroups.com
      </div>
      <div class="opt-box-border">
        <label> To Download 100K+ Results</label>
        Sign up for <a href="http://tldr.docking.org/">tldr.docking.org</a> and use arthorbatch
      </div>
      <div class="opt-box-border">
        <label> Database Information</label>
        <a href="https://wiki.docking.org/index.php/Smallworld_and_Arthor_Databases#Smallworld_Databases" target="_blank">Database Information Link</a>
      </div>
</source>
 
==== Remove Similarity and Formula Buttons ====
# vim /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server/src/main/webapp/WEB-INF/static/index.html
# Search for 'arthor_search_list'
#* <source> ?arthor_search_list </source>
# Delete and Replace the whole 'ul' element block with this
#* <source>
          <li value="Similarity" onclick="setSearchType(this)" class="first">
            Similarity
          </li><li value="Substructure" onclick="setSearchType(this)">
            Substructure
          </li><li value="SMARTS" onclick="setSearchType(this)" class="last">
            SMARTS
          </li>
          <!--<li value="Formula" onclick="setSearchType(this)" class="last">
            Formula
          </li>-->
</source>
 
=== Customize Index.js ===
==== Conditional Hyperlinks ====
Location /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1-source/server-ui/src/index.js
 
# Add the zinc20 hyperlink to the Arthor results. Search for this
#* <source>
$info.append($("<tr>").append($('<td class="identifier">').append(id)));
</source>
# Delete the contents of the whole else block and replace it with this
#* <source>
        if (id.substring(0, 6) == "ZINC00") {
          $info.append(
            $('<tr>').append(
            $('<td class="identifier">').append("<b><a target='_blank' href='https://zinc20.docking.org/substances/"+id+"'>" + id + "</a></b>")));
          $info.append(
            $("<tr>").append(
              $("<td>").append(
                "<span class='table_name'>" + table_name + "</span>",
              ),
            ),
          );
        } else if (id.substring(0,4) == "ZINC" && id.substring(4,6) != "00") {
          $info.append(
            $('<tr>').append(
            $('<td class="identifier">').append("<b><a target='_blank' href='https://cartblanche22.docking.org/substance/"+id+"'>" + id + "</a></b>")));
          $info.append(
            $("<tr>").append(
              $("<td>").append(
                "<span class='table_name'>" + table_name + "</span>",
              ),
            ),
          );
        } else {
          $info.append($("<tr>").append($('<td class="identifier">').append(id)));
          $info.append(
            $("<tr>").append(
              $("<td>").append(
                "<span class='table_name'>" + table_name + "</span>",
              ),
            ),
          );
        }
</source>
==== Copy SMILES Clipboard ====
# Search this
#: <source>?parser</source>
# At the end of the the try block add this
#: <source>
        $info.append(
          $('<tr>').append(
            $('<td>').append('Copy SMILES: <a href="#" onclick="navigator.clipboard.writeText(\'' + parser.smi + '\');" ><i class="fa fa-clipboard" aria-hidden="true"></i></a>')));
</source>
# The whole try and catch block should look like this
#: <source>
try {
      var parser = new SmiJs.Parser(data);
      if (parser.parse()) {
        $info.append(
          $('<tr>').append(
            $('<td>').append(parser.mf(true))));
        $info.append(
                $('<tr>').append(
                  $('<td>').append(parser.mw())));
        $info.append(
          $('<tr>').append(
            $('<td>').append('Copy SMILES: <a href="#" onclick="navigator.clipboard.writeText(\'' + parser.smi + '\');" ><i class="fa fa-clipboard" aria-hidden="true"></i></a>')));
      }
    } catch(err) {
      console.log(err);
    }
</source>


4. then vim .extract/webapps/ROOT/WEB-INF/static/js/index.js
=== Customize Sketcher.js ===
Location: /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1-source/server-ui/src/sketcher.js


5. search: '''function $(t){'''
==== Input Box Updates as User Draws ====
#vim /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1-source/server-ui/src/sketcher.js
#Search for this line "var smiles = event.src.smiles();"
#* <source>?var smiles = event.src.smiles();</source>
#Add this new line below it
#* <source>$('#ar_text_input').val(smiles);</source>


6. in the function $(t), add these lines:
=== Customize arthor-swagger.yaml ===
Location: /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server/src/main/webapp/WEB-INF/static/swagger/arthor-swagger.yaml


if(document.getElementById("arthor_tsv_link")) {
==== Change URL Base Path for API Call ====
        var e=i.a.param({query:s.b.query,type:s.b.type,draw:0,start:0,length:t,flags:s.b.flags}),n=s.b.url+"/dt/"+E(s.b.table)+"/search";i()("#arthor_sdf_link").attr("href",n+".sdf?"+e),i() ("#arthor_tsv_link").attr("href",n+".tsv?"+e),i()("#arthor_csv_link").attr("href",n+".csv?"+e)
# vim /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server/src/main/webapp/WEB-INF/static/swagger/arthor-swagger.yaml
}
# Search for "servers"
if (document.getElementById("arthor_tsv_link_5000")) {
#* <source>?basePath</source>
        var e=i.a.param({query:s.b.query,type:s.b.type,draw:0,start:0,length:5000,flags:s.b.flags}),n=s.b.url+"/dt/"+E(s.b.table)+"/search";i()("#arthor_sdf_link_5000").attr("href",n+".sdf?"+e),i()("#arthor_tsv_link_5000").attr("href",n+".tsv?"+e),i()("#arthor_csv_link_5000").attr("href",n+".csv?"+e)
# Remove "/arthor" and keep argument empty
}
if (document.getElementById("arthor_tsv_link_50000")) {
        var e=i.a.param({query:s.b.query,type:s.b.type,draw:0,start:0,length:50000,flags:s.b.flags}),n=s.b.url+"/dt/"+E(s.b.table)+"/search";i()("#arthor_sdf_link_50000").attr("href",n+".sdf?"+e),i()("#arthor_tsv_link_50000").attr("href",n+".tsv?"+e),i()("#arthor_csv_link_50000").attr("href",n+".csv?"+e)
}
if (document.getElementById("arthor_tsv_link_100000")) {
        var e=i.a.param({query:s.b.query,type:s.b.type,draw:0,start:0,length:100000,flags:s.b.flags}),n=s.b.url+"/dt/"+E(s.b.table)+"/search";i()("#arthor_sdf_link_100000").attr("href",n+".sdf?"+e),i()("#arthor_tsv_link_100000").attr("href",n+".tsv?"+e),i()("#arthor_csv_link_100000").attr("href",n+".csv?"+e)
}
if (document.getElementById("arthor_tsv_link_max")) {
        var e=i.a.param({query:s.b.query,type:s.b.type,draw:0,start:0,length:1000000000,flags:s.b.flags}),n=s.b.url+"/dt/"+E(s.b.table)+"/search";i()("#arthor_sdf_link_max").attr("href",n+".sdf?"+e),i()("#arthor_tsv_link_max").attr("href",n+".tsv?"+e),i()("#arthor_csv_link_max").attr("href",n+".csv?"+e)
}


=== Take out Similarity Button ===
=== Compile/Minify Code through NPM ===
vim .extract/webapps/ROOT/WEB-INF/static/index.html
# Install NPM packages and Minify Code
search: '''Similarity'''
#* <source>
Comment out this line '''< li value="Similarity" onclick="setSearchType(this)" class="first"> Similarity </li >''' //added spaces at the beginning and end so prevent wiki from converting it
cd /nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server-ui
Then add "first" in Substructure's class
npm install
=== Hyperlink to zinc20 ===
npx webpack-dev-server
vim .extract/webapps/ROOT/WEB-INF/static/js/index.js
npx webpack --mode=production
search: '''table_name'''
</source>
*find this line "< b>" + d + "< /b>"
# If the npx commands don't work, try updating node and npm version to the latest one.
*replace with '''"< b><a target='_blank' href='https://zinc20.docking.org/substances/"+d+"'>" + d + "</a></b >"''' //added spaces at the beginning and end so prevent wiki from converting it
# Build the war file
#* <source>
cd /nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server
mvn install -Pbootable
</source>
# If it works, then the path to new war file is at /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server/target/arthor-server-4.1.war


=== Make Input Box Work ===
== Adding Arthor to Systemd (example) ==
At the end of the Arthor config file add this:
# Create service files
    Resolver=https://sw.docking.org/util/smi2mol?smi=%s
#: <source>
To copy smiles in the input box:
touch /etc/systemd/system/arthor.service
    vim .extract/webapps/ROOT/WEB-INF/static/js/index.js
</source>
    search this: “var e=t.src.smiles()”
# Add this code block in the service file
    add this after the semi-colon
#: <source>
        document.getElementById("ar_text_input").value = e;


== Restarting Arthor Instance(s) Instructions ==
[Unit]
Public, Private, and SuperPrivate Arthors are all started the same way.
Description=Arthor Public Instance
After=network.target


Public Arthor lives and runs on both '''samekh''' and '''nun'''.
[Service]
Type=exec
Restart=always
RestartSec=3
User=root
ExecStart=/usr/bin/bash /nfs/soft2/arthor_configs/start_arthor_service.sh -arthor
ExecStop=/bin/kill -15 $MAINPID


Private Arthor lives and runs on '''samekh'''.
[Install]
WantedBy=multi-user.target
</source>
# Change "ExecStart" to other Arthor Instances


Super Private Arthor lives and runs on '''nun'''.
== Restarting Arthor Instance(s) Instructions ==
=== Public, Private Arthor, and Super Private Arthor ===
# ssh to "arthor" server and run
#: <source>
systemctl <start|stop|restart> <arthor|arthorp|arthorc>
</source>


=== Instructions ===
=== ArthorBB, ArthorCC, and ArthorCovalent ===
* To start an instance
# ssh to "epyc-a40" server and run
# ssh into appropriate machine
#: <source>
# become root
systemctl <start|stop|restart> <arthorbb|arthorcc|arthorcovalent>
# cat run_arthors_on_reboot.sh
</source>
# copy and run screen command
#* Public Arthor only needs one line.
#** /usr/bin/screen -dmS public_arthor /root/screen_public_arthor.sh
#* Private and Super Private needs two lines.
#** /usr/bin/screen -dmS private_arthor /root/screen_private_arthor.sh
#** /usr/bin/screen -dmS private_arthor_rt_head /root/screen_private_round_table_head.sh


* To stop an instance
[[Category:Arthor]]
# ssh into appropriate machine
[[Category:Developer]]
# become root
# One Way
#* screen -ls
#* screen -r <instance_screen_name or instance_screen_number>
#* ctrl + C
# Second Way
#* screen -ls, find instance name or number
#* screen -X -S <instance_screen_name or instance_screen_number> kill
#* screen -ls, to double check

Revision as of 23:48, 26 June 2024

Introduction

Here is the link to Arthor's manual

  • Username: ucsf@nextmovesoftware.com
  • Password: <Ask jjiteam@googlegroups.com>

Arthor configurations and the frontend files are consolidated in /nfs/soft2/arthor_configs/.

/nfs/soft2/arthor_configs/start_arthor_script.sh can start/restart Arthor instances on respective machines.

Launch the script to see the options available.

How To Download Arthor

  1. Ssh to nfs-soft2 and become root. Prepare directory
     mkdir /export/soft2/arthor_configs/arthor-<version> && cd /export/soft2/arthor_configs/arthor-<version>
  2. Download Software with this link
    • Username: ucsf@nextmovesoftware.com
    • Password: <Ask jjiteam@googlegroups.com>
  3. Go to releases. Look for smallworld-java-<version>.tar.gz and copy the link address.
  4. Download using wget
     wget --user ucsf@nextmovesoftware.com --password <Ask jjiteam@googlegroups.com> <link address>
  5. Decompress the file
    •  tar -xvf <file_name>

How To Launch Arthor For The First Time

Prepare Files and Directories

  1. Ssh to nfs-exc and become root
  2. Open a port in the firewall
    firewall-cmd --permanent --add-port=<port_number>/tcp 
    firewall-cmd --reload
  3. Go to Arthor Config directory
    cd /export/soft2/arthor_configs/arthor-<latest_version>
  4. Create an Arthor config file
    vim <name_of_file>.cfg
    • Add these lines in the file. Check the manual for more options.
    DataDir=/local2/public_arthor
    MaxConcurrentSearches=6
    MaxThreadsPerSearch=8
    AutomaticIndex=false
    AsyncHitCountMax=20000
    Depiction=./depict/bot/svg?w=%w&h=%h&svgunits=px&smi=%s&zoom=0.8&sma=%m&smalim=1
    Resolver=https://sw.docking.org/util/smi2mol?smi=%s

Start Arthor Instance

  1. Now ssh into a machine you wish to run an Arthor instance on and become root
  2. Change your shell to bash if you havn't already
    bash
  3. Create a screen
    screen -S <screen_name>
  4. Prepare Arthor Config Path
    export ARTHOR_CONFIG="/nfs/soft2/arthor_configs/arthor-<version>/<name_of_config_file>.cfg"
  5. Launch java
    java -jar -Dserver.port=<port_number> /nfs/soft2/arthor_configs/arthor-<version>/arthor-server-<version>.war

Configuration Details

  • DataDir: This is the directory where the Arthor data files live. Location where the index files will be created and loaded from.
  • MaxConcurrentSearches: Controls the maximum number of searches that can be run concurrently by setting the database pool size. When switching between a large number of databases it can be useful to have a larger pool size, the only trade off is keeping file pointers open.
  • MaxThreadsPerSearch: The number of threads to use for both ATDB and ATFP searches
  • Set AutomaticIndex to false if you don't want new smiles files added to the data directory to be indexed automatically
  • AsyncHitCountMax: The upper-bound for the number of hits to retrieve in background searches.
  • Resolver: Using Smallworld API, allows input box to take in a SMILE format and automatically draw on the board.

Check Arthor manual for more configuration options

How to Build Arthor Databases

We can build Arthor Databases anywhere. Consolidate smiles into one directory so you can index them all one by one.

Just use the script located at /nfs/home/jjg/scripts/arthor_index_script.sh at the directory where you stored the smiles.

Here is the content of the script:

#!/bin/bash

target="*.smi"
threads='48'
version="3.6.1"


export ARTHOR_DIR=/nfs/soft2/arthor_configs/arthor-$version/arthor-$version-centos8/
export PATH=$ARTHOR_DIR/bin/:$PATH

for j in $target
do
        echo 'smi2atdb -v -r -j '$threads' -p '$j' '${j}'.atdb |& tee -a '${j}'_log'
        time smi2atdb -v -r -j $threads -p $j ${j}.atdb |& tee -a ${j}_log
	echo 'smi2atfp -j '$threads' -p '$j' '${j}.atfp' |& tee -a '${j}'_log'
        time smi2atfp -j $threads -p $j ${j}.atfp |& tee -a ${j}_log
done

for i in $target*atdb
do
	echo 'atdb2fp -j '$threads' '$i
        time atdb2fp -j $threads $i
	chmod 744 $i.fp
done

Command Details

smi2atdb creates the atdb files needed for Substructure searching.

  • -v verbose
  • -r Compute and store ring size information in the index allowing ring size (3-10) expressions ([r6] and [Z5])
  • -j is the amount of threads to use to index the smiles file
  • -p stores the position of the original file

atdb2fp makes substructure searching faster

smi2atfp creates atfp files for similarity searching

Setting up Round Table

"Round Table allows you to serve and split chemical searches across multiple host machines. The implementation provides a lightweight proxy that forwards requests to other Arthor host servers that do the actual search. Communication is done using the existing Web APIs.

Setting up Host Server

  1. Ssh to nfs-soft2 and become root
  2. Open a port in the firewall
    firewall-cmd --permanent --add-port=<port_number>/tcp 
    firewall-cmd --reload
  3. Go to Arthor Config Directory
    cd /export/soft2/arthor_configs/arthor-<version>
  4. Create Round Table Head configuration file. Here is an example:
  5. [RoundTable]
    RemoteClient=http://10.20.0.41:8008
    RemoteClient=http://10.20.5.19:8008
    Resolver=https://sw.docking.org/util/smi2mol?smi=%s
  6. Now ssh into a machine you wish to run the round table head on and become root
  7. Change your shell to bash if you havn't already
    bash
  8. Create a screen
    screen -S <screen_name>
  9. Prepare Arthor Config Path
    export ARTHOR_CONFIG="/nfs/soft2/arthor_configs/arthor-<version>/<round_table_head>.cfg"
  10. Launch java
    java -jar /nfs/soft2/arthor_configs/arthor-<version>/arthor-<version>-centos7/java/arthor.jar --httpPort=<port_number>

Active Arthor Instances

Public Arthor

Rocky Linux Machine Port Round Table Data Directory Which Arthor
arthor 10.20.200.100:8080 /local3/public_arthor/ Public Arthor

Private Arthor

Rocky Linux Machine Port Round Table Data Directory Which Arthor
arthor 10.20.200.100:8081 /local3/private_arthor/ Private Arthor

Super Private Arthor

Rocky Linux Machine Port Round Table Data Directory Which Arthor
arthor 10.20.200.100:8082 /local3/super_private_arthor/ Private Arthor

Arthor BB, CC, and Covalent

CentOS 7 Machine Port Data Directory Which Arthor
epyc-A40 10.20.200.92:8081 /local2/arthorbb ArthorBB
epyc-A40 10.20.200.92:8082 /local2/arthorcc ArthorCC
epyc-A40 10.20.200.92:8080 /local2/arthorcovalent Arthor Covalent

Customizing Arthor Frontend To Our Needs (Arthor 4.1)

These instructions only worked and compiled for me in the machine called epyc which is running Rocky 8 Linux operating system.

Summary of changes in index.html:

  • Add contact info
  • Advertise TLDR
  • Remove button for Formula
  • Database Information Link

Summary of changes in index.js:

  • Hyperlink the results to zinc20 or cartblanche22
  • Copy SMILES with clipboard button

Summary of changes in sketcher.js:

  • Input box should be updated as user draws molecule

Summary of changes in arthor-swagger.yaml.js:

  • Make API point to "/"


Install Prerequisite Packages

  1. Install Apache Maven
    • dnf install maven -y
  2. Install Node Package Manager (NPM)
    • dnf install npm -y
  3. In your home directory, create a new directory to hold the files for the upcoming procedures
    • mkdir /mnt/nfs/home/jjg/arthor_build_from_source
  4. Download these latest Arthors and store them in 'arthor_build_from_source/'. Here's how to download Arthor.
    • arthor-4.1-source.tar.gz
    • arthor-4.1-centos8.tar.gz
  5. Extract contents from the tar.gz files
    • tar -xvf arthor-4.1-source.tar.gz
      tar -xvf arthor-4.1-centos8.tar.gz
  6. Install Apache Maven Arthor dependencies through this script
    • #!/bin/bash
      
      version=4.1
      
      export ARTHOR_DIR=/mnt/nfs/home/jjg/arthor_build_from_source/arthor-$version/arthor-$version-centos8/java/
      export OS=linux
      export VERSION=$version
      
      mvn install:install-file -Dfile=$ARTHOR_DIR/arthor-jni-${OS}.jar \
                               -Dpackaging=jar \
                               -DgeneratePom=true \
                               -DartifactId=arthor-jni-${OS} \
                               -DgroupId=com.nextmovesoftware.arthor \
                               -Dversion=$VERSION
      mvn install:install-file -Dfile=$ARTHOR_DIR/arthor-jni.jar \
                               -Dpackaging=jar \
                               -DgeneratePom=true \
                               -DartifactId=arthor-jni \
                               -DgroupId=com.nextmovesoftware.arthor \
                               -Dversion=$VERSION

Customizing Index.html

Location: /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server/src/main/webapp/WEB-INF/static/index.html

Add contact info and tldr

  1. vim /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server/src/main/webapp/WEB-INF/static/index.html
  2. Search for 'arthor_table_list'
    • ?arthor_table_list
  3. Add contact info, a plug to tldr.docking.org, and database link after the div block where arthor_table_list is inside of. It should look like this
    •       <div class="opt-box-border">
              <label>Databases</label>
              <!-- This will be populated by available databases -->
              <ul id="arthor_table_list">
                <li class="placeholder">Please select a search type</li>
              </ul>
            </div>
            <div class="opt-box-border">
              <label>Ask Questions</label>
              Email us: jjiteam@googlegroups.com
            </div>
            <div class="opt-box-border">
              <label> To Download 100K+ Results</label>
              Sign up for <a href="http://tldr.docking.org/">tldr.docking.org</a> and use arthorbatch
            </div>
            <div class="opt-box-border">
              <label> Database Information</label>
              <a href="https://wiki.docking.org/index.php/Smallworld_and_Arthor_Databases#Smallworld_Databases" target="_blank">Database Information Link</a>
            </div>

Remove Similarity and Formula Buttons

  1. vim /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server/src/main/webapp/WEB-INF/static/index.html
  2. Search for 'arthor_search_list'
    •  ?arthor_search_list
  3. Delete and Replace the whole 'ul' element block with this
    •           <li value="Similarity" onclick="setSearchType(this)" class="first">
                  Similarity
                </li><li value="Substructure" onclick="setSearchType(this)">
                  Substructure
                </li><li value="SMARTS" onclick="setSearchType(this)" class="last">
                  SMARTS
                </li>
                <!--<li value="Formula" onclick="setSearchType(this)" class="last">
                  Formula
                </li>-->

Customize Index.js

Conditional Hyperlinks

Location /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1-source/server-ui/src/index.js

  1. Add the zinc20 hyperlink to the Arthor results. Search for this
    • $info.append($("<tr>").append($('<td class="identifier">').append(id)));
  2. Delete the contents of the whole else block and replace it with this
    •         if (id.substring(0, 6) == "ZINC00") {
                $info.append(
                  $('<tr>').append(
                  $('<td class="identifier">').append("<b><a target='_blank' href='https://zinc20.docking.org/substances/"+id+"'>" + id + "</a></b>")));
                $info.append(
                  $("<tr>").append(
                    $("<td>").append(
                      "<span class='table_name'>" + table_name + "</span>",
                    ),
                  ),
                );
              } else if (id.substring(0,4) == "ZINC" && id.substring(4,6) != "00") {
                $info.append(
                  $('<tr>').append(
                  $('<td class="identifier">').append("<b><a target='_blank' href='https://cartblanche22.docking.org/substance/"+id+"'>" + id + "</a></b>")));
                $info.append(
                  $("<tr>").append(
                    $("<td>").append(
                      "<span class='table_name'>" + table_name + "</span>",
                    ),
                  ),
                );
              } else {
                $info.append($("<tr>").append($('<td class="identifier">').append(id)));
                $info.append(
                  $("<tr>").append(
                    $("<td>").append(
                      "<span class='table_name'>" + table_name + "</span>",
                    ),
                  ),
                );
              }

Copy SMILES Clipboard

  1. Search this
    ?parser
  2. At the end of the the try block add this
            $info.append(
              $('<tr>').append(
                $('<td>').append('Copy SMILES: <a href="#" onclick="navigator.clipboard.writeText(\'' + parser.smi + '\');"  ><i class="fa fa-clipboard" aria-hidden="true"></i></a>')));
  3. The whole try and catch block should look like this
    try {
          var parser = new SmiJs.Parser(data);
          if (parser.parse()) {
            $info.append(
              $('<tr>').append(
                $('<td>').append(parser.mf(true))));
            $info.append(
                    $('<tr>').append(
                      $('<td>').append(parser.mw())));
            $info.append(
              $('<tr>').append(
                $('<td>').append('Copy SMILES: <a href="#" onclick="navigator.clipboard.writeText(\'' + parser.smi + '\');"  ><i class="fa fa-clipboard" aria-hidden="true"></i></a>')));
          }
        } catch(err) {
          console.log(err);
        }

Customize Sketcher.js

Location: /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1-source/server-ui/src/sketcher.js

Input Box Updates as User Draws

  1. vim /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1-source/server-ui/src/sketcher.js
  2. Search for this line "var smiles = event.src.smiles();"
    • ?var smiles = event.src.smiles();
  3. Add this new line below it
    • $('#ar_text_input').val(smiles);

Customize arthor-swagger.yaml

Location: /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server/src/main/webapp/WEB-INF/static/swagger/arthor-swagger.yaml

Change URL Base Path for API Call

  1. vim /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server/src/main/webapp/WEB-INF/static/swagger/arthor-swagger.yaml
  2. Search for "servers"
    • ?basePath
  3. Remove "/arthor" and keep argument empty

Compile/Minify Code through NPM

  1. Install NPM packages and Minify Code
    • cd /nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server-ui
      npm install
      npx webpack-dev-server
      npx webpack --mode=production
  2. If the npx commands don't work, try updating node and npm version to the latest one.
  3. Build the war file
    • cd /nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server
      mvn install -Pbootable
  4. If it works, then the path to new war file is at /mnt/nfs/home/jjg/arthor_build_from_source/arthor-4.1/arthor-4.1-source/server/target/arthor-server-4.1.war

Adding Arthor to Systemd (example)

  1. Create service files
    touch /etc/systemd/system/arthor.service
  2. Add this code block in the service file
    [Unit]
    Description=Arthor Public Instance
    After=network.target
    
    [Service]
    Type=exec
    Restart=always
    RestartSec=3
    User=root
    ExecStart=/usr/bin/bash /nfs/soft2/arthor_configs/start_arthor_service.sh -arthor
    ExecStop=/bin/kill -15 $MAINPID
    
    [Install]
    WantedBy=multi-user.target
  3. Change "ExecStart" to other Arthor Instances

Restarting Arthor Instance(s) Instructions

Public, Private Arthor, and Super Private Arthor

  1. ssh to "arthor" server and run
    systemctl <start|stop|restart> <arthor|arthorp|arthorc>

ArthorBB, ArthorCC, and ArthorCovalent

  1. ssh to "epyc-a40" server and run
    systemctl <start|stop|restart> <arthorbb|arthorcc|arthorcovalent>