Administrator

LIMS*Nucleus characterizes two types of users, regular users and administrators. LIMS*Nucleus users are unique to LIMS*Nucleus and not shared with the operating system nor database. Administrative functionality is listed in the table below.

Item Description
Add User Add a user and password
View all users
Add Project Add a new project; users cannot create projects, only use them
View sessions
Input License Credentials

Architecture

LIMS*Nucleus is amenable to a variety of installation configurations:

Example Client Server 1 Server 2
Data Center Web Browser Application Server Database Server
AWS/EC2 Web Browser Application & Database Server
Personal laptop Browser, Application & Database Server

Most of the LIMS*Nucleus business logic is implemented using Postgres stored procedures. The client utililizes Bootstrap/Datatables to guide/validate user input, and display results in table format.

Artanis modifications needed for Guix packaging

This page discusses modification to the Artanis web server softare required for packaging an Artanis application. Guidelines for writing a Guix compatible Artanis application can be found here.

Artanis

GNU Artanis is a web server written in Guile (a scheme dialect). Artanis -the web server software - has been packaged for Guix. The packaging recipe can be found in …/gnu/packages/guile-xyz.scm. Artanis applications such as LIMS*Nucleus are not by default packageable by guix due to the presence of a writeable ../tmp directory in the application folder. Here is the partial directory structure of LIMS*Nucleus:

The directory ../limsn/limsn/tmp holds temporary files created while users are navigating the application. Since the Guix store is immutable, a temporary folder is not allowed and must be moved outside of the application. Artanis defines a variable ‘current-toplevel’ which, in the above example would be ../limsn/limsn. In the labsolns modified artanis all references to ‘current-toplevel’ are divided into two groups:

variable description
1 current-toplevel redirected to /tmp/limsn i.e. references that create a temporary file
2 immutable-toplevel references that point to the original ‘current-toplevel’ i.e. references that do not create files and can reside in the immutable /gnu/store… directory

Source Code Modifications

To allow for Guix packaging of Artanis applications the following modifications to the Artanis source code are introduced during packaging:

File line Modified source code
utils.scm 279 (if (immutable-toplevel)
280 (format #f “~a/pub/~a” (immutable-toplevel) path)
833 (let* ((toplevel (immutable-toplevel))
1309 (immutable-toplevel) file)))
tpl/parser.scm 40 (format #f “~a/~a/~a” (immutable-toplevel) pub args))))
52 (mfile (format #f “~a/~a/manifest.json” (immutable-toplevel) path))
commands/work.scm 77 (let ((entry (string-append (immutable-toplevel) “/” *artanis-entry*)))
126 (add-to-load-path (immutable-toplevel))
mvc/controller.scm 45 (immutable-toplevel) ’name method)))
62 (define toplevel (immutable-toplevel))
webapi/restful.scm 58 (load (format #f “~a/app/api/~a.scm” (immutable-toplevel) s)))

Recipe File Modifications

The above changes are introduced during the installation of Artanis. Recipe file additions are:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
	  ;;============START forguix mods=========================================================================
;;immutable-toplevel is the original current-toplevel in /gnu/store
;;current-toplevel is the mutable toplevel in /tmp/<appname>/tmp/cache

(substitute* "artanis/commands/work.scm"
(("\\(let \\(\\(entry \\(string-append \\(current-toplevel\\) \"/\" \\*artanis-entry\\*\\)\\)\\)")
"(let ((entry (string-append (immutable-toplevel) \"/\" *artanis-entry*)))")
(("\\(add-to-load-path \\(current-toplevel\\)\\)")
"(add-to-load-path (immutable-toplevel))")
(("\\(add-to-load-path \\(string-append \\(current-toplevel\\) \"/lib\"\\)\\)")
"(add-to-load-path (string-append (immutable-toplevel) \"/lib\"))"))
(substitute* '("artanis/tpl/parser.scm"
"artanis/mvc/controller.scm"
"artanis/webapi/restful.scm")
(("current-toplevel")
"immutable-toplevel"))
(substitute* "artanis/utils.scm"
(("\\(let\\* \\(\\(toplevel \\(current-toplevel\\)\\)")
"(let* ((toplevel (immutable-toplevel))")
(("\\(current-toplevel\\) file\\)\\)\\)")
"(immutable-toplevel) file)))")
(("\\(if \\(current-toplevel\\)")
"(if (immutable-toplevel)")
((" \\(let \\(\\(p \\(-> path\\)\\)\\)")
" (let ((p (-> path))(dummy (format (artanis-current-output) \"current-appname: ~a\" (current-appname) )))")
(("\\(format \\#f \"~a/pub/~a\" \\(current-toplevel\\) path\\)")
"(format #f \"~a/pub/~a\" (immutable-toplevel) path)")
)
(substitute* "artanis/env.scm"
((" current-toplevel\n")
" current-toplevel\n %immutable-toplevel\n immutable-toplevel\n")
(("\\(define \\(current-toplevel\\)\n")
"(define %immutable-toplevel (make-parameter #f))\n")
((" \\(or \\(%current-toplevel\\)\n")
" (define (immutable-toplevel)\n")
((" \\(find-ENTRY-path identity #t\\)\\)\\)\n")
" (or (%immutable-toplevel)\n (find-ENTRY-path identity #t)))\n\n(define (current-toplevel) (string-append \"/tmp/\" (and=> (string-match \".+/(.+)$\" (getcwd)) (lambda (m) (match:substring m 1))))) ")

) ;;use of (current-appname) causes disk thrashing and freezing
;; (find-ENTRY-path identity #t) evaluates to #f and so can't be used

;;============END forguix mods=========================================================================

Get the modified Artanis software

  1. Set up your system so that you can utilize the labsolns channel
  2. guix pull
  3. guix edit artanis (to see the recipe)
  4. guix package -i artanis (to install or upgrade to the modified Artanis)

Caution

Note that the Guix modified Artanis is labeled as v0.5.2 and so (Sept 2022) will “upgrade” your copy of Artanis.

Guix modified Artanis has been tested with LIMS*Nucleus. Modifications may have broken Artanis features that are not used by LIMS*Nucleus.

AWS EC2 Installation

Prerequisites

  • AWS username/password
  • EC2 key pair
  • (Static IP address) A transient IP is adequate and will be used in the video tutorial. Consider a static IP for production. A static IP address is free upon request, but must be used on a running instance. You will be charged for a static IP that is requested but not used.
  • Credit card number - a valid credit card is required to register. Note that these are Amazon requirements.

Installation

Note: the video tutorial of AWS EC2 installation of LIMS*Nucleus describes installation of an older version of LIMS*Nucleus. Though still useful to watch as the overall process and many details are the same, details discussed below supercede what is in the video. The main changes are different names for scripts are being used, LIMS*Nucleus is now packaged as a guix module and so is installed in the store, and because a guix pull must be performed the free tier t2.micro may not provide enough memory. Use t2.medium.

Local: download the archive of install scripts and transfer to AWS with scp:

1
home@HP8300:~$scp -i labsolns.pem $HOME/temp/limsn-ec2.tar.xz  admin@ec2-18-191-151-165.us-east-2.compute.amazonaws.com:.

You must modify the above command with your own keys and the connection address provided to you by Amazon.

AWS: decompress and run the install script:

1
2
admin@ip-172-31-23-11:~$tar -xvf ./limsn-ec2.tar.xz
admin@ip-172-31-23-11:~$./install-limsn-ec2.sh

install-limsn-ec2.sh and guix-install-mod.sh must be in the same directory. Multiple files described below are loaded into the store at PATH_INTO_STORE/limsn/scripts

Supplied Scripts

Scripts available on this website or in /gnu/store are described on the scripts page.

Useful commands

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## start the database server
admin@ip-172-31-25-179:~$ pg_ctl -D /home/admin/lndata -l logfile start

## start the application in detached mode
admin@ip-172-31-25-179:~$ nohup ~/start-limsn.sh

## find the application PID
admin@ip-172-31-25-179:~$ps aux | grep art
admin 1219 1.3 5.5 153504 56172 ? Sl 12:25 0:00 /gnu/store/18hp7flyb3yid3yp49i6qcdq0sbi5l1n-guile-3.0.2/bin/guile \ /gnu/store/imh84i7rcckxd55nndhrnr0j7jr64ffv-artanis-0.5.1/bin/.art-real work -h 0.0.0.0

## kill the application
admin@ip-172-31-25-179:~$kill -9 1219


## delete the database
admin@ip-172-31-25-179:~$ rm -r lndata


## reinstall the database
admin@ip-172-31-25-179:~$ ./install-pg-aws.sh



Import Barcode IDs

Barcode IDs are imported by plate number. The files page provides details on the file format, with a 10 plate sample file available. Navigate into the project of interest and highlight the plate set of interest. From the menu select Utilities/Import Barcodes:

The import barcode form will appear - select file. A truncated sample of file contents will appear belwo the ‘Submit’ button for confirmation:

The example barcode import file looks like:

1
2
3
4
5
6
7
8
9
10
11
plate 	barcode.id
1 LN000001
2 LN000002
3 LN000003
4 LN000004
5 LN000005
6 LN000006
7 LN000007
8 LN000008
9 LN000009
10 LN000010

Once imported, barcode ids will appear in the plate table:

Example barcode ID import file:

File name Description
barcodes.txt Ten 96 well plates in PRJ-10
barcodes1000.txt 1000 barcodes

Artanis applications suitable for Guix packaging

This page discusses the guidelines for writing an Artanis application such as LIMS*Nucleus that is suitable for Guix packaging. If you are looking for modifications needed in the Artanis source code, look here.

Write a Guix packageable Artanis application

First read the discussion on modifications required to the Artanis source code so you are aware that all temporary files created by your application must be moved to a directory outside the application directory. In addition, Artanis’ cache must be move outside the application directory, as well as artanis.conf so it remains editable. These activities can be handled with a post installation initialization file.

One time initialization

Because your artanis app needs some directories outside of the application directory to work with temporary files, configuration files etc., a one time initialization script can be run to set up your server. The overall process would look like:

  1. guix package -i limsn
  2. init-limsn.sh
  3. install-pg-aws.sh
  4. start-limsn.sh

The initialization file would create required directories and copy over the artanis.conf file. Note that the placeholder PATH_INTO_STORE is replaced on installation by the path into the store.

init-limsn-channel.sh
1
2
3
4
5
6
7
8
9
10
#! /bin/bash
export LC_ALL="C"
echo export LC_ALL=\"C\" >> $HOME/.bashrc
echo export GUIX_PROFILE=$HOME/.guix-profile >> $HOME/.bashrc
echo . $HOME/.guix-profile/etc/profile >> $HOME/.bashrc
echo export GUIX_LOCPATH=$HOME/.guix-profile/lib/locale >> $HOME/.bashrc

sudo mkdir -p $HOME/.config/limsn
sudo cp PATH_INTO_STORE/share/guile/site/3.0/limsn/conf/artanis.conf $HOME/.config/limsn

artanis.conf

Because a configuration file outside the project directory is being used, you can use a startup script to launch your application:

start-limsn.sh
1
2
3
4
5
6
#!/bin/bash
!#
export LC_ALL="C"
mkdir -p /var/tmp/limsn/tmp/cache
cd PATH_INTO_STORE/share/guile/site/3.0/limsn
art work -h0.0.0.0 --config=$HOME/.config/limsn/artanis.conf

In this example -h0.0.0.0 is needed for running on Amazon Web Services

GNUPLOT

With regular Artanis Gnuplot can be run on the server and generate *.png files in the ../pub directory that are accessible to the .html.tpl file via:

page1.html.tpl
1
<image src= <%= myplot %>>

Where in the above snippet the variable myplot == “../pub/myplot.png”. With guix modified Artanis, the .png file would have to go into /tmp/limsn and would become inaccessible due to security restrictions. To get around this, load the myplot variable with svg commands. This is accomplished by first creating the gnuplot script with the following commands:

my-gnuplot-script.txt
1
2
3
4
5
6
reset session
set terminal svg size 800,500
save '-'
set key box ins vert right top
set grid
...etc.

The ‘save’-’’ statement will save to standard output so that you can pipe into your variable. Here is a helper function that will collect the svg commands:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(use-modules (ice-9 regex) ;;list-matches
(ice-9 textual-ports)
(ice-9 rdelim) ;;read-line
(ice-9 popen))

(define (get-svg-content gnuplot-script-file)
;;requires: set terminal svg size 600,400
;; save '-'
;;in the script
;;gnuplot-script-file is the script as a text variable
(let* ((port (open-input-pipe (string-append "gnuplot " gnuplot-script-file)))
(a "")
(dummy (let loop ((line (read-line port)))
(if (not (eof-object? line))
(begin
(set! a (string-append a line))
(loop (read-line port))))))
(dummy (close-pipe port))
(dummy (pretty-print a))
(coord-start (string-match "<svg width=" a ))
(coord-end (string-match "</g></svg>" a)))
(xsubstring a (match:start coord-start) (match:end coord-end))
))

Then in your controller:

mycontroller.scm
1
2
(let* ((myplot-svg (get-svg-content gnuplot-script-file))
etc....

And in the web page template:

page1.html.tpl
1
<%= myplot-svg %>

Now in the above snippet myplot-svg == ’<svg width=“600” height=“350” viewBox=“0 0 600 350” xmlns=“http://www.w3.org/2000/svg” xmlns:xlink=“http://www…etc….”

Application specific variables

Application specific variables are defined in ENTRY such as:

ENTRY
1
2
3
...
(conf-set! 'maxnumplates 100)
...

Since ENTRY is in the store, this will only work for variables that are not available to the end user for (re)setting. To provide editable application specific variables, put them in artanis.conf. Variables are grouped in artanis.conf. LIMS*Nucleus specific variable ‘maxnumplates’ is placed in the ‘cookie’ group for convenience, even though it is not a cookie.

artanis.conf
1
cookie.maxnumplates = 100

artanis/config.scm must be patched appropriately:

artanis/config.scm
1
2
3
4
5
6
7
8
(substitute* "artanis/config.scm"		
((" \\(else \\(error parse-namespace-cache \"Config: Invalid item\" item\\)\\)\\)\\)")
"(else (error parse-namespace-cache \"Config: Invalid item\" item))))\n\n(define (parse-namespace-cookie item)\n (match item\n (('expire expire) (conf-set! '(cookie expire) (->integer expire)))\n (('maxplates maxplates) (conf-set! '(cookie maxplates) (->integer maxplates)))\n (else (error parse-namespace-cookie \"Config: Invalid item\" item))))"))

(substitute* "artanis/config.scm"
(("debug.monitor = <PATHs>\")")
"debug.monitor = <PATHs>\")\n ((cookie expire)\n 3600\n \"Cookie expiration time in seconds.\n 1 hour is 3600\n 6 hours 21600\n 1 month 2592000\n cookie.expire = <integer>\")\n\n ((cookie maxplates)\n 10\n \"Maximum number of plates per plate-set.\n cookie.maxplates = <integer>\")"))

Modify controller syntax

Controllers as they are written will generate a warning:

guix package: warning: failed to load ‘(limsn app controllers plates)’: no code for module (lims app controllers plates) /home/mbc/.guix-profile/share/guile/site/3.0/myapp/app/controllers/pages.scm:4:0: warning: module name (app controllers plates) does not match file name ‘limsn/app/controllers/plates.scm’ hint: File `/home/mbc/.guix-profile/share/guile/site/3.0/limsn/app/controllers/plates.scm’ should probably start with: (define-module (limsn app controllers plates))

Guix expects the first statement in a module to begin with (define-module ()….)
Artanis wants modules to (use-modules (artanis mvc controller))
Satisfy both requirements with:

plates.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
(define-module (limsn app controllers plates)
#:use-module (artanis artanis)
#:use-module (artanis mvc controller)) ;;to eliminate error

;;error: define-artanis-controller: unbound variable
;;hint: Did you forget `(use-modules (artanis mvc controller))'?

(define-artanis-controller pages) ; DO NOT REMOVE THIS LINE!!!
;;libraries must be imported after define-artanis-controller
(use-modules (myapp lib mylib) )

(pages-define plates
(lambda (rc)......etc.

Be sure to import libraries after (define-artanis-controller )

Make Libraries accessible

Artanis provides the …./lib directory to hold libraries. This directory is placed on the GUILE_LOAD_PATH for you. To avoid warnings, you may wish to write your library as a module e.g. (define-module (limsn lib mylib)…) in which case you need to place your project directory on GUILE_LOAD_PATH with a statment in ENTRY such as:

(add-to-load-path (string-append (find-ENTRY-path identity #t) “/..”))

Another option is to create a separate package for your library, package separately, and make it available as an input.

Canonical Workflow

Below is the canonical workflow that LIMS*Nucleus is designed to handle.

  1. Create a plate set.
    1.5 Possibly reformat the plate set into higher density plates for assay.
  2. Create assay plates and run an assay. Apply assay data to the assay plate set.
  3. Identify hits
  4. Rearray hits into a new plate set
  5. (Reformat hits into higher density plates), run hits in a secondary assay, identify hits, rearray, etc.

Tutorial 1 will walk you through this workflow.

Next>> Evaluate

LIMS*Nucleus Client Installation

The LIMS*Nucleus client is distributed and installed as a Guix Package. The name of the LIMS*Nucleus package is ‘limsn’. For the package to be available to your system, you must first modify your channels.scm file to include the labsolns channel. You can then issue the install command:

1
guix package -i limsn

This will install not only LIMS*Nucleus but also all of its dependencies, as well as configuration scripts and sql scripts for setting up the database. You may have already set up the database in which case you only need to configure artanis.conf. The sequence of scripts that need to be run are:

Sequence Script Name Function
1 init-limsn.sh create directories that hold temp files and the configuration file; modify .bashrc
2 install-pg-aws.sh install the Postgres database; install-pg-aws.sh is designed for AWS, there are other options
3 start-limsn.sh start the client; run in background mode if desired with ‘nohup’

Other options, such as the AWS installation script will automatically run the init-limsn.sh and install-pg-aws.sh scripts for you.

Request for Invoice

Thank you for your request.

An invoice in the amount of $5000 for a LIMS*Nucleus license key will be emailed to:

info@labsolns.com

Table of Contents

Configuration

Configuration of LIMS*Nucleus is achieved by editing either /etc/artanis/artanis.conf or $HOME/.config/limsn/artanis.conf, depending on how LIMS*Nucleus was installed. LIMS*Nucleus specific parameters are listed below:

Database

These parameter will need to be edited if you utilize a cloud provider. These are the parameters that comprise the connection string. PostgreSQL is the only database with which LIMS*Nucleus is compatible.

Parameter Description Default
db.addr database address:port 127.0.0.1:5432
db.username database username ln_admin
db.passwd database password welcome
db.name database name lndb

Web Server

Parameter Description Default
host.addr Host address - the web server 127.0.0.1
host.port web server port 3000

LIMS*Nucleus specific

Parameter Description Default
cookie.expires Cookie expiration time in seconds; Expiration of the session cookie will require a user to re-login 21600
cookie.maxplates* Maximum number of plates per plate set; Modifications ignored unless registered 10
  • Note that the ‘maxplates’ parameter is in the cookie group only for convenience. A maxplates cookie is never set. The only cookie utilized by LIMS*Nucleus is the session id ‘sid’.