---
# System prepended metadata

title: GA4GH API Demo on mahuika / ga-vl01

---

# GA4GH API Demo on mahuika / ga-vl01


### htsget: PYTHON 3

```bash
## Log in to GA workshop machine
ssh ga-vl01
```

```bash
ml Python
python3 -m venv ~/venv/ga4gh
source ~/venv/ga4gh/bin/activate
pip install htsget 

# copy and paste python code into htsgetTest.py (see below)
python htsgetTest.py
```

Code for `htsgetTest.py`:

```python
import htsget
url = "http://htsnexus.rnd.dnanex.us/v1/reads/BroadHiSeqX_b37/NA12878"
with open("NA12878_2.bam", "wb") as output:
    htsget.get(url, output, reference_name="2", start=1000, end=20000)
```

### htsget: PYTHON 2.7.5

After logging in to ga-vl01:

```bash
# Install pip
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py

# Install virtualenv
python -m pip install --user virtualenv

# Generate virtual environment for Python v2
python -m virtualenv ~/venv/ga4gh_p2

# Activate the Python2 environment
source ~/venv/ga4gh_p2/bin/activate

# Install htsget
pip install htsget

# Run code to retrieve BAM file
python htsgetTest.py
```

### htsget (cmd line) vcf file

```bash
module load BCFtools/1.9-GCC-7.4.0
module load ga4gh

# Subsetting region from vcf
htsget http://htsnexus.rnd.dnanex.us/v1/variants/1000genomes/20130502_autosomes --reference-name=12 --start=112204691 --end=112247789 -O my_vcf.vcf.gz

# subsetting region and extracting a sample from vcf
# also possible to omit '-O /dev/stdout'
htsget http://htsnexus.rnd.dnanex.us/v1/variants/1000genomes/20130502_autosomes --reference-name=12 --start=112204691 --end=112247789 -O /dev/stdout | bcftools view -s HG00096 -o HG00096_range.vcf.gz -O z
```

#### (cmd line) using SnpSift to extract specific fields

```shell=
htsget http://htsnexus.rnd.dnanex.us/v1/variants/1000genomes/20130502_autosomes \
  --reference-name=1 --start=112204 --end=1122477 -O /dev/stdout | \
  bgzip -d | \
  SnpSift extractFields - CHROM POS ID AF | head
```

The result:
```shell=
CHROM   POS     ID      AF
1       104912  rs555881142     1.99681E-4
1       104935  rs575831356     1.99681E-4
1       104971  rs541628624     1.99681E-4
1       105005  rs561611323     1.99681E-4
1       106027  rs566022480     0.00858626
1       106606  rs541390744     1.99681E-4
1       106820  rs564304387     1.99681E-4
1       106845  rs533395091     1.99681E-4
1       108030  rs550285297     0.0317492
```

#### (cmd line) Filter for certain SNPs?

```sh
# create a list of SNPs to filter in a txt file
tee -a my_rs.txt <<EOF
rs538998844
rs5745113
rs255292
EOF

# grab region, uncompress and pass to SnpSift filter
htsget http://htsnexus.rnd.dnanex.us/v1/variants/1000genomes/20130502_autosomes \
  --reference-name=5 --start=172082000 --end=172968480 -O /dev/stdout | \
  bgzip -d | \
  SnpSift filter --set my_rs.txt "ID in SET[0]" > filtered.vcf
```

... and if you want to combine the above:

```shell=
htsget http://htsnexus.rnd.dnanex.us/v1/variants/1000genomes/20130502_autosomes \
  --reference-name=5 --start=172082000 --end=172968480 -O /dev/stdout | \
  bgzip -d | \
  SnpSift filter --set my_rs.txt "ID in SET[0]" | \
  SnpSift extractFields - CHROM POS ID AF
```

result:
```shell=
CHROM   POS     ID      AF
5       172571422       rs538998844     5.99042E-4
5       172573652       rs5745113       0.00698882
5       172580866       rs255292        0.365815
```

#### htsget vcf file in python
```python
url = "http://htsnexus.rnd.dnanex.us/v1/variants/1000genomes/20130502_autosomes"
with open("test.vcf.gz", "wb") as output:
	htsget.get(url, output, reference_name="12", start=112204691, end=112247789)

vcfdata = vcf.Reader("test.vcf.gz")
print(vcfdata)
```

### Notes on R example (from Joep's slides)


On NeSI I used: 

```
module load R/4.0.1-gimkl-2020a
```

to get R 4.0.1.  A matching Bioconductor module isn't available through.

```R
## Install needed Bioconductor packages:

install.packages('BiocManager')
BiocManager::install("GenomicRanges")
BiocManager::install("VariantAnnotation")

BiocManager::install("remotes")
BiocManager::install("Bioconductor/Rhtsget")
```


Load packages

```R
library(GenomicRanges)
library(VariantAnnotation)
library(Rhtsget)
```

R script from slides (first part):

```R
gr <- GenomicRanges::GRanges("chr12:111766922-111817529")
sample_id <- "platinum/NA12878"
url <- "https://htsnexus.rnd.dnanex.us/v1"
fl <- tempfile(fileext=".bam")
bam <- htsget_reads(gr, sample_id, url, destination = fl)
```

On NeSI, the script dies with:

```
Error in curl::curl_fetch_memory(url, handle = handle) : 
  OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to htsnexus.rnd.dnanex.us:443 
```

On my laptop, it dies with:

```
Error in curl::curl_fetch_memory(url, handle = handle) : 
  SSL certificate problem: certificate has expired
```

On my laptop I can get around this via (needs `httr` package):

```R
bam = httr::with_config(
  config = httr::config(ssl_verifypeer = FALSE),
  htsget_reads(gr, sample_id, url, destination = fl)
)
```

but this "fix" doesn't work on NeSI (I still get the same error as previously).

The rest of the script runs fine on my laptop (with a similar "fix" as above
for the `htsget_variants` call):

```R
gr <- GenomicRanges::GRanges("12:112204691-112247789")
sample_id <- "1000genomes/20130502_autosomes"
url <- "https://htsnexus.rnd.dnanex.us/v1"
fl <- tempfile(fileext=".vcf")

## Ignore expired SSL "fix":
vcf <- httr::with_config(
  config = httr::config(ssl_verifypeer = FALSE),
  htsget_variants(gr, sample_id, url, destination = fl)
)
VariantAnnotation::readVcf(vcf)
```

## Section 1. (Joep will run this demo : port config for a single user)

### Running `ga4gh-example-data` 

#### Terminal Session 1 

1. Log into corresponding vm via

                       $ ssh -L 8083:localhost:8083 mahuika

2. clone `ga4gh-example-data` set and the associated `registry.db` file to `$HOME`

```
$ cp -r /nesi/nobackup/nesi02659/GA4GH/ga4gh-example-1 . && cd ga4gh-example-1

$ wget https://github.com/ga4gh/server/releases/download/data/ga4gh-example-data_4.6.tar && tar -xvf ga4gh-example-data_4.6.tar
```


3. Launch apache server

```
$ export REGISTRY_PATH=~/ga4gh-example-1/registry
$ ./run_ga4gh

[Mon Aug 03 16:44:48.587634 2020] [mpm_prefork:notice] [pid 9509] AH00163: Apache/2.4.38 (Debian) PHP/7.4.8 mod_wsgi/4.6.5 Python/2.7 configured -- resuming normal operations
[Mon Aug 03 16:44:48.587766 2020] [core:notice] [pid 9509] AH00094: Command line: 'apache2 -D FOREGROUND'
```

4. We now have a server running in the foreground. When it receives requests, it will print out log entries to the terminal. A summary of the server’s configuration and data is available in HTML format at http://localhost:8083/ga4gh, which can be viewed in a web browser. Leave the server running and open another terminal to complete the rest of the demo.

#### Terminal Session 2

1. Open another terminal session and log into mahuika (please leave the first teminal running)

                                  $ ssh mahuika
2. Launch ga4gh singularity shell

```
$ export REGISTRY_PATH=~/ga4gh-example-1/registry

$ cd ga4gh-example-1/ && ./run_ga4gh_shell
Singularity> 
```
3. To try out the server, we must send some requests to it using the GA4GH protocol. One way in which we can do this is to manually create the JSON requests, and send these to the server using cURL:

```
Singularity> curl -s -N --data '{}' --header 'Content-Type: application/json' http://localhost:8083/ga4gh/datasets/search | jq .
```

In this example, we used the search_datasets method to ask the server for all the Datasets on the server. It responded by sending back some JSON, which we piped into the jq JSON processor to make it easier to read. We get the following result:

```
{
  "nextPageToken": "",
  "datasets": [
    {
      "info": {},
      "description": "Sample data from 1000 Genomes phase 3",
      "id": "WyIxa2ctcDMtc3Vic2V0Il0",
      "name": "1kg-p3-subset"
    }
  ]
}
```
4. In this example we sent a SearchDatasetsRequest object to the server and received a SearchDatasetsResponse object in return. This response object contained one Dataset object, which is contained in the `datasets` array. This approach to interacting with the server is tedious and error prone, as we have to hand-craft the request objects. It is also quite inconvenient, as we may have to request many pages of objects to get all the objects that satisfy our search criteria. To simplify interacting with the server and to abstract away the low-level network-level details of the server, we provide a client application. To try this out, we start another instance of our virtualenv, and then send the equivalent command using: 
    * To simplify interacting with the server and to abstract away the low-level network-level details of the server, we provide a client application. To try this out, we start another instance of our virtualenv, and then send the equivalent command using:

```
Siingularity> ga4gh_client datasets-search http://localhost:8083/ga4gh

WyIxa2ctcDMtc3Vic2V0Il0	1kg-p3-subset
```

5. The output of this command is a summary of the Datasets on that are present on the server. We can also get the output in JSON form such that each object is written on one line:

```
Singularity> ga4gh_client datasets-search -O json http://localhost:8083/ga4gh
```
```
{"info": {}, "description": "Sample data from 1000 Genomes phase 3", "id": "WyIxa2ctcDMtc3Vic2V0Il0", "name": "1kg-p3-subset"}
```

6. This format is quite useful for larger queries, and can be piped into jq to extract fields of interest, pretty printing and so on.

    * We can perform similar queries for variant data using the search_variants API call. First, we find the IDs of the VariantSets on the server using the search_variant_sets method:

```
Singularity> ga4gh_client variantsets-search http://localhost:8083/ga4gh

WyIxa2ctcDMtc3Vic2V0IiwidnMiLCJtdm5jYWxsIl0	mvncall
```
7. This tells us that we have one VariantSet on the server, with ID `WyIxa2ctcDMtc3Vic2V0IiwidnMiLCJtdm5jYWxsIl0`  and name `mvncall`. We can then search for variants overlapping a given interval in a VariantSet as follows:

```
Singularity>  ga4gh_client variants-search http://localhost:8083/ga4gh --referenceName=1 --start=45000 --end=50000
```
   * Although this should have generated a summary of the data in a free text form, a conflict in pre-assigned relative paths in the registry.db file provided with the example dataset will cause an error. ( regenerating the registry using the repo CLI will resolve it)

## Section 2. 

### Host the 1000 Genomes VCF

The GA4GH reference server uses a registry of files and URLs to populate its data repository. In this tutorial we will use the command-line client to create a registry similar to that used by 1kgenomes.ga4gh.org. Your system should have samtools installed, and at least 30GB to host the VCF and reference sets.

#### Repo administrator CLI

The CLI has methods for adding and removing Feature Sets, Read Group Sets, Variant Sets, etc. Before we can begin adding files we must first initialize an empty registry database. The directory that this database is in should be readable and writable by the current user, as well as the user running the server.

Copy the source directory to $HOME or $CWD

```
$ cp -r /nesi/nobackup/nesi02659/GA4GH/ga4gh-example-2 ~
```

Initialises a new registry DB `registry/registry.db`
```

$ ml ga4gh && ga4gh_repo init registry/registry.db 

```


**verify**
The `verify` command is used to check that the integrity of the data in a repository. The command checks each container object in turn and ensures that it can read data from it. Read errors can occur for any number of reasons (for example, a VCF file may have been moved to another location since it was added to the registry), and the verify command allows an administrator to check that all is well in their repository.

```
$ ga4gh_repo verify registry/registry.db
```

Now add a dataset and provide a helpful description using the `--description` flag.

```
$ ga4gh_repo add-dataset registry/registry.db 1kgenomes --description "Variants from the 1000 Genomes project and GENCODE genes annotations"
```
#### Add a Reference Set

```
$ ga4gh_repo add-referenceset registry/registry.db registry/hs37d5.fa.gz \
     --description "NCBI37 assembly of the human genome" \
     --species '{"termId": "NCBI:9606", "term": "Homo sapiens"}' \
     --name NCBI37 \
     --sourceUri ftp://ftp.1000genomes.ebi.ac.uk/vol1/ftp/technical/reference/phase2_reference_assembly_sequence/hs37d5.fa.gz
```
##### Add an ontology
Ontologies provide a source for parsing variant annotations, as well as organizing feature types into ontology terms. A sequence ontology instance must be added to the repository to translate ontology term names in sequence and variant annotations to IDs. Sequence ontology definitions can be downloaded from the Sequence Ontology site.

```
$ ga4gh_repo add-ontology registry/registry.db registry/so-xp.obo -n so-xp
```




#### Add the 1000 Genomes VCFs

The 1000 Genomes are publicly available on the EBI server. This command uses wget to download the “release” VCFs to a directory named release. 

* Downloading files take about 5 minutes.Therefore, use the localy stored copy `/nesi/nobackup/nesi02659/GA4GH/release/`
    

 ```
 $ ga4gh_repo add-variantset registry/registry.db 1kgenomes /nesi/nobackup/nesi02659/GA4GH/release/ --name phase3-release --referenceSetName NCBI37
 ```
 
#### Add a BAM as a Read Group Set
Read Group Sets are the logical equivalent to BAM files within the server. We will add a BAM hosting by the 1000 Genomes S3 bucket. We will first download the index and then add it to the registry.

```
ga4gh_repo add-readgroupset registry/registry.db 1kgenomes \
    -I HG00096.mapped.ILLUMINA.bwa.GBR.low_coverage.20120522.bam.bai \
    --referenceSetName NCBI37 \
    http://s3.amazonaws.com/1000genomes/phase3/data/HG00096/alignment/HG00096.mapped.ILLUMINA.bwa.GBR.low_coverage.20120522.bam 
```
Send some requests to it using the GA4GH protocol

```
$ ml purge && ml Singularity/3.5.2
$ singularity shell ga4gh_nesi.img
```
```
Singularity> curl --data '{}' --header 'Content-Type: application/json' http://localhost:8083/ga4gh/datasets/search | jq .
```




