<repo_name>rcurrie/bme230b<file_sep>/Makefile
build:
	docker build --rm -t robcurrie/bme230b .

push:
	docker push robcurrie/bme230b

upload:
	docker run -it -v ${HOME}:/root microsoft/azure-cli
	az storage blob upload -c data --name tcga_target_gtex.h5 --file ~/tcga_target_gtex.h5

nbviewer:
	docker run -d \
		-v /mnt/students:/notebooks \
		-p 8080:8080 \
		jupyter/nbviewer \
		python3 -m nbviewer --port=8080 --no-cache --localfiles=/notebooks
<file_sep>/leaderboard.py
import os
import re
import operator
import subprocess

root = "/mnt/students"

cmd = "Rscript class/BME230_F1score_V2.R /mnt/students/{}/predict.tsv /mnt/data/tcga_mutation_test_labels.tsv"

leaderboard = {}

for id in os.listdir(root):
    if os.path.exists(os.path.join(root, id, "predict.tsv")):
	leaderboard[id] = {}
	print("Ranking {}".format(id))
	try:
	    scores = subprocess.check_output(cmd.format(id).split(" "))
        except subprocess.CalledProcessError as e:
	    print("Problems ranking {}: {}".format(id, e.output))
	leaderboard[id]["Tissue"] = float(re.findall("Tissue F1 score: (NaN|[0-9]*\.?[0-9]*)", scores)[0])
	leaderboard[id]["TP53"] = float(re.findall("TP53_F1_score: (NaN|[0-9]*\.?[0-9]*)", scores)[0])
	leaderboard[id]["KRAS"] = float(re.findall("KRAS_F1_score: (NaN|[0-9]*\.?[0-9]*)", scores)[0])
	leaderboard[id]["BRAF"] = float(re.findall("BRAF_F1_score: (NaN|[0-9]*\.?[0-9]*)", scores)[0])
	leaderboard[id]["Mutation"] = float(re.findall("Mutation_F1_score: (NaN|[0-9]*\.?[0-9]*)", scores)[0])
	leaderboard[id]["Overall"] = float(re.findall("Final_F1_score: (NaN|[0-9]*\.?[0-9]*)", scores)[0])

for id in sorted(leaderboard.keys(), key=lambda x: leaderboard[x]["Overall"], reverse=True):
    print(id)
    print("Overall: {:.6f}".format(leaderboard[id]["Overall"]))
    print("Tissue: {:.6f}".format(leaderboard[id]["Tissue"]))
    print("TP53: {:.6f}".format(leaderboard[id]["TP53"]))
    print("KRAS: {:.6f}".format(leaderboard[id]["KRAS"]))
    print("BRAF: {:.6f}".format(leaderboard[id]["BRAF"]))
    print("Mutation: {:.6f}".format(leaderboard[id]["Mutation"]))
    print("")
<file_sep>/class/README.txt
Contents of this folder is read only and populated by the TAs

Anything in this folder may be overwritten by future assignments - copy any templates to your home before working on them.
<file_sep>/Dockerfile
FROM jupyter/datascience-notebook:96f2f777be6e

USER root

RUN apt-get update \
  && apt-get install -y --no-install-recommends \
    curl \
    wget \
    zip \
    zlib1g-dev \
    time \
    samtools \
    bedtools \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

RUN curl -sSL https://get.docker.com/ | sh
RUN usermod -aG docker jovyan

RUN wget -qO- https://github.com/lomereiter/sambamba/releases/download/v0.6.7/sambamba_v0.6.7_linux.tar.bz2 \
  | tar xj -C /usr/local/bin

# The order of these is intentional to work around conflicts
# RUN conda install --yes pytorch torchvision -c pytorch
# pytorch repo has older versions only...
RUN conda install --yes pytorch torchvision -c soumith

RUN conda install --yes tensorflow keras

RUN pip install --upgrade pip
ADD requirements.txt requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

RUN conda install --yes numpy==1.14.1 scikit-learn==0.19.0

USER jovyan
<file_sep>/requirements.txt
awscli==1.14.32
boto3==1.5.22
docker==3.0.0
docutils==0.14
networkx==2.0
pybedtools==0.7.10
pysam==0.13
PyVCF==0.6.8
tables==3.4.2
<file_sep>/class/BME230_F1score_V2.R
# score BME assignment using F1 score
# script takes two arguments, the first argument is the prediction file and the second is the actual file
# example:
# Rscript BME230_F1score.R davids_pancan_response.tsv tcga_mutation_test_labels.tsv
# outputs a file named with the <predictions input filename>_scored.tsv

# load input file
args = commandArgs(trailingOnly=TRUE)
predict_input_file<<-args[1]
actual_labels_file<<-args[2]

# load files
predicted_response<-read.csv(file=predict_input_file,sep="\t")
# colnames(predicted_response)<-c("TumorTypePrediction","TP53MutationPrediction","KRASMutationPrediction","BRAFMutationPrediction")
true_response<-read.csv(file=actual_labels_file,sep="\t")


# for testing
#predicted_response<-read.csv(file="davids_tissue_specific_response.tsv",sep="\t")
#colnames(predicted_response)<-c("TumorTypePrediction","TP53MutationPrediction","KRASMutationPrediction","BRAFMutationPrediction")
#true_response<-read.csv(file="tcga_mutation_test_labels.tsv",sep="\t")

# score tumor type
# for each tumor type calculate an F1 score
tissue_scores<-data.frame(matrix(ncol=2,nrow=0))
tissues<-unique(true_response$primary.disease.or.tissue)
tissues_predict<-unique(predicted_response$TumorTypePrediction)

running_precision<-c()
running_recall<-c()
for (tissue in tissues) {
  TP<-length(which(predicted_response$TumorTypePrediction == tissue & true_response$primary.disease.or.tissue == tissue))
  FP<-length(which(predicted_response$TumorTypePrediction == tissue & true_response$primary.disease.or.tissue != tissue))
  FN<-length(which(predicted_response$TumorTypePrediction != tissue & true_response$primary.disease.or.tissue == tissue))
  if ((TP+FP) > 0) { precision<-TP/(TP+FP) } else { precision<-0 }
  if ((TP+FN) > 0) { recall<-TP/(TP+FN) } else { recall <- 0 }
  running_precision<-c(running_precision,precision)
  running_recall<-c(running_recall,recall)
  if ((precision*recall)!=0) 
    { tissue_specific_F1_score<-(2*precision*recall)/(precision+recall) }
  else 
    {tissue_specific_F1_score<-0}
  tissue_scores<-rbind(tissue_scores,cbind(paste0(tissue,"_F1_score"),"V2"=tissue_specific_F1_score))
  print(paste0(tissue,"_F1_score: ",tissue_specific_F1_score))
  }

# take mean of precision and recall
tissue_precision<-sum(running_precision)/length(tissues)
tissue_recall<-sum(running_recall)/length(tissues)
tissue_F1_score<-(2*tissue_precision*tissue_recall)/(tissue_precision+tissue_recall)
print(paste("Overall Tissue F1 score:",tissue_F1_score))

  # score TP53 mutation predictions
TP<-length(which(predicted_response$TP53MutationPrediction ==1 & true_response$TP53_mutant==1))
FP<-length(which(predicted_response$TP53MutationPrediction ==1 & true_response$TP53_mutant==0))
FN<-length(which(predicted_response$TP53MutationPrediction ==0 & true_response$TP53_mutant==1))
if ((TP+FP) > 0) { TP53_precision<-TP/(TP+FP) } else { TP53_precision<-0 }
if ((TP+FN) > 0) { TP53_recall<-TP/(TP+FN) } else { TP53_recall <- 0 }
TP53_F1_score<-(2*TP53_precision*TP53_recall)/(TP53_precision+TP53_recall)
print(paste("TP53_F1_score:",TP53_F1_score))


# score KRAS mutation predictions
TP<-length(which(predicted_response$KRASMutationPrediction ==1 & true_response$KRAS_mutant==1))
FP<-length(which(predicted_response$KRASMutationPrediction ==1 & true_response$KRAS_mutant==0))
FN<-length(which(predicted_response$KRASMutationPrediction ==0 & true_response$KRAS_mutant==1))
if ((TP+FP) > 0) { KRAS_precision<-TP/(TP+FP) } else { KRAS_precision<-0 }
if ((TP+FN) > 0) { KRAS_recall<-TP/(TP+FN) } else { KRAS_recall <- 0 }
KRAS_F1_score<-(2*KRAS_precision*KRAS_recall)/(KRAS_precision+KRAS_recall)
print(paste("KRAS_F1_score:",KRAS_F1_score))


# score BRAF mutation predictions
TP<-length(which(predicted_response$BRAFMutationPrediction ==1 & true_response$BRAF_mutant==1))
FP<-length(which(predicted_response$BRAFMutationPrediction ==1 & true_response$BRAF_mutant==0))
FN<-length(which(predicted_response$BRAFMutationPrediction ==0 & true_response$BRAF_mutant==1))
if ((TP+FP) > 0) { BRAF_precision<-TP/(TP+FP) } else { BRAF_precision<-0 }
if ((TP+FN) > 0) { BRAF_recall<-TP/(TP+FN) } else { BRAF_recall <- 0 }
BRAF_F1_score<-(2*BRAF_precision*BRAF_recall)/(BRAF_precision+BRAF_recall)
print(paste("BRAF_F1_score:",BRAF_F1_score))



mutation_precision<-(TP53_precision+KRAS_precision+BRAF_precision)/3
mutation_recall<-(TP53_recall+KRAS_recall+BRAF_recall)/3
mutation_F1_score<-(2*mutation_precision*mutation_recall)/(mutation_precision+mutation_recall)
print(paste("Mutation_F1_score:",mutation_F1_score))



final_precision<-(mutation_precision+tissue_precision)/2
final_recall<-(mutation_recall+tissue_recall)/2
final_F1_score<-(2*final_precision*final_recall)/(final_precision+final_recall)
print(paste("Final_F1_score:",final_F1_score))


other_scores<-rbind(c("Tumor_Type_F1_score",tissue_F1_score),
                    c("TP53_F1_score",TP53_F1_score),
                    c("KRAS_F1_score",KRAS_F1_score),
                    c("BRAF_F1_score",BRAF_F1_score),
                    c("Mutation_F1_score",mutation_F1_score),
                    c("Final_F1_score",final_F1_score))
score_vector<-rbind(tissue_scores,other_scores)

output_filename<-paste0(strsplit(predict_input_file,"\\.")[[1]][1],"_scored.tsv")

# write.table((score_vector),quote=FALSE,file=output_filename,sep="\t",col.names = FALSE,row.names = FALSE)

<file_sep>/fabfile.py
"""
Tooling to spin up hosts running jupyter on Azure for BME230B
"""
import os
import glob
import json
import datetime
import pprint
from StringIO import StringIO
from fabric.api import env, local, run, sudo, runs_once, parallel, warn_only, cd, settings
from fabric.operations import put, get
from fabric.contrib.console import confirm

# To debug communication issues un-comment the following
# import logging
# logging.basicConfig(level=logging.DEBUG)


def _find_machines():
    """ Fill in host globals from docker-machine """
    env.user = "ubuntu"
    machines = [json.loads(open(m).read())["Driver"]
                for m in glob.glob(os.path.expanduser("~/.docker/machine/machines/*/config.json"))]
    env.hostnames = [m["MachineName"] for m in machines
                     if not env.hosts or m["MachineName"] in env.hosts]
    env.hosts = [local("docker-machine ip {}".format(m["MachineName"]), capture=True) for m in machines
                 if not env.hosts or m["MachineName"] in env.hosts]
    # env.key_filename = [m["SSHKeyPath"] for m in machines]
    # Use single key due to https://github.com/UCSC-Treehouse/pipelines/issues/5
    # env.key_filename = [m["SSHKeyPath"] for m in machines]
    env.key_filename = "~/.ssh/id_rsa"



_find_machines()


@runs_once
def cluster_up(count=1):
    """ Spin up 'count' docker machines """
    print("Spinning up {} more cluster machines".format(count))
    for i in range(int(count)):
        hostname = "bme230b-{:%Y%m%d-%H%M%S}".format(datetime.datetime.now())
        local("""
              docker-machine create --driver azure \
		--azure-subscription-id "11ef7f2c-6e06-44dc-a389-1d6b1bea9489" \
		--azure-location "westus" \
		--azure-ssh-user "ubuntu" \
		--azure-open-port 80 \
		--azure-size "Standard_D8_v3" \
		--azure-storage-type "Standard_LRS" \
		--azure-resource-group "bme230bstudents" \
              {}
              """.format(hostname))
        local("cat ~/.ssh/id_rsa.pub" +
              "| docker-machine ssh {} 'cat >> ~/.ssh/authorized_keys'".format(hostname))

    # In case additional commands are called after up
    _find_machines()

@parallel
def configure_machines():
    """ Push out class templates and download data sets """
    run("sudo usermod -aG docker ${USER}")

    put("class")

    run("sudo chown ubuntu:ubuntu /mnt")
    run("mkdir -p /mnt/data /mnt/scratch")
    with cd("/mnt/data"):
        # run("wget -r -np -R 'index.html*' -N https://bme230badmindiag811.blob.core.windows.net/data/") 
        run("wget -q -N https://bme230badmindiag811.blob.core.windows.net/data/tcga_target_gtex_train.h5") 
        run("wget -q -N https://bme230badmindiag811.blob.core.windows.net/data/tcga_mutation_train.h5") 
        run("wget -q -N https://bme230badmindiag811.blob.core.windows.net/data/breast-cancer-wisconsin.data.csv") 
        run("wget -q -N https://bme230badmindiag811.blob.core.windows.net/data/c2.cp.kegg.v6.1.symbols.gmt") 
        run("wget -q -N https://bme230badmindiag811.blob.core.windows.net/data/tcga_mutation_test_unlabeled.h5") 
    run("sudo chown ubuntu:ubuntu /mnt")

    run("""sudo docker pull robcurrie/jupyter | grep -e 'Pulling from' -e Digest -e Status -e Error""")
    # run("chmod -R +r-w class/")


@runs_once
def cluster_down():
    """ Terminate ALL docker-machine machines """
    if confirm("Stop and delete all cluster machines?", default=False):
        for host in env.hostnames:
            print("Terminating {}".format(host))
            with warn_only():
                local("docker-machine stop {}".format(host))
            with warn_only():
                local("docker-machine rm -f {}".format(host))


@runs_once
def machines():
    """ Print hostname, ip, and ssh key location of each machine """
    print("Machines:")
    for machine in zip(env.hostnames, env.hosts):
        print("{}/{}".format(machine[0], machine[1]))

def ps():
    """ List dockers running on each machine """
    run("docker ps")


def jupyter_up():
    """ Launch a jupyter notebook server on each cluster machine """
    with warn_only():
        run("""
            nohup docker run -d --name jupyter \
                    --user root \
                    -e JUPYTER_ENABLE_LAB=1 \
                    -e GRANT_SUDO=yes \
                    -e NB_UID=`id -u` \
                    -e NB_GID=`id -g` \
                    -p 80:8888 \
                    -v `echo ~`:/home/jovyan \
                    -v /mnt/data:/home/jovyan/data \
                    -v /mnt/scratch:/scratch/home/jovyan/data \
                    robcurrie/jupyter start-notebook.sh \
                    --NotebookApp.password='<PASSWORD>:<PASSWORD>'
            """, pty=False)

def jupyter_down():
    """ Shutdown the jupyter notebook server on each cluster machine """
    with warn_only():
        run("docker stop jupyter && docker rm jupyter")

def backhaul():
    """ Backhaul notebooks from all the cluster machines into /mnt/students """
    username = env.host
    with warn_only():
        fd = StringIO()
        paths = get("~/username.txt", fd)
        if paths.succeeded:
            username=fd.getvalue().strip()
    local("mkdir -p /mnt/students/{}".format(username))
    local("rsync -av --max-size=10m --delete ubuntu@{}:~/* /mnt/students/{}".format(env.host, username))
    # with cd("/mnt/students/{}".format(username)):
    #     get("/home/ubuntu/*", "/mnt/students/{}/".format(username))
