Mercurial > repos > in_silico > cravat_annotate_mutations
changeset 15:a46b42bda5d7 draft
Uploaded
author | in_silico |
---|---|
date | Tue, 12 Jun 2018 12:05:40 -0400 |
parents | a28f1f52eb93 |
children | efb15a586f5e |
files | cravat_annotate/cravat_annotate.py cravat_annotate/cravat_annotate.xml cravat_convert/base_converter.py cravat_submit/cravat_submit.py cravat_submit/cravat_submit.xml |
diffstat | 5 files changed, 137 insertions(+), 293 deletions(-) [+] |
line wrap: on
line diff
--- a/cravat_annotate/cravat_annotate.py Tue Jun 12 12:04:45 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,246 +0,0 @@ -""" -A galaxy wrapper for the /rest/service/query API endpoint on Cravat. - - -Notes on Mapping: ------------------ -The CravatQuery class uses static method 'from_array' to interpret an array of values -into a query string for the /rest/service/query API service on the cravat server. -This involves using a mapping dictionary to know how to associate the array's index positions -in to query-ing attributes, such as the chromosome, position, etc. The CravatQuery -class contains a default value ('default_mapping'); however, this could also be -offered as a user-configurable option. -""" - - -import requests -import json -import sys -import re - - -class CravatQueryException(Exception): - - def __init__(self, message, errors=None): - super(CravatQueryException, self).__init__(message) - # Support for custom error codes - self.errors = errors - - -class CravatQuery(object): - """ - : A class for handling Cravat query strings. - : Args (all required): - : chr - Chromosome - : pos - Position - : strand - Strand - : ref - Reference Base - : alt - Alternate Base - """ - - # The endpoint that CravatQuerys are submitted to - endpoint = 'http://cravat.us/CRAVAT/rest/service/query' - - # The value delimiter used in the Cravat input file to delimit values - delimiter = "\t" - - # Defualt indices for intepretting a cravat file's row of data in to a CravatQuery - default_mapping = { - 'chromosome': 1, - 'position': 2, - 'strand': 3, - 'reference': 4, - 'alternate': 5 - } - - # Defualt values. Used as backup for CravatQuery to resolve query with incomplete information - default_values = { - 'strand': '+' - } - - # The neccessary attributes neeeded to submit a query. - query_keys = [ - 'chromosome', 'position', 'strand', 'reference', 'alternate' - ] - - # Expected response keys from server. Ordered in list so that galaxy output has uniform column ordering run-to-run. - # If cravat server returns additional keys, they are appended to and included in output. - response_keys = [ - "Chromosome", "Position", "Strand", "Reference base(s)", "Alternate base(s)", - "HUGO symbol", "S.O. transcript", "Sequence ontology protein change", "Sequence ontology", - "S.O. all transcripts", "gnomAD AF", "gnomAD AF (African)", "gnomAD AF (Amrican)", - "gnomAD AF (Ashkenazi Jewish)", "gnomAD AF (East Asian)", "gnomAD AF (Finnish)", - "gnomAD AF (Non-Finnish European)", "gnomAD AF (Other)", "gnomAD AF (South Asian)", - "1000 Genomes AF", "ESP6500 AF (average)", "ESP6500 AF (European American)", - "ESP6500 AF (African American)", "COSMIC transcript", "COSMIC protein change", - "COSMIC variant count [exact nucleotide change]", "cosmic_site_nt", "CGL driver class", - "TARGET", "dbSNP", "cgc_role", "cgc_inheritance", "cgc_tumor_type_somatic", - "cgc_tumor_type_germline", "ClinVar", "ClinVar disease identifier", "ClinVar XRef", - "GWAS Phenotype (GRASP)", "GWAS PMID (GRASP)", "Protein 3D variant" - ] - - - def __init__(self, _chr, pos, strand, ref, alt): - # '_chr' used to avoid naming confliction with python built-in 'chr' - self.chromosome = CravatQuery.format_chromosome(_chr) - self.position = pos - self.strand = strand - self.reference = ref - self.alternate = alt - self.values = [self.chromosome, self.position, self.strand, self.reference, self.alternate] - - - def __str__(self): - """ : Represent the CravatQuery as a valid query string for call to Cravat server """ - return "_".join(map(lambda x: str(x), self.values)) - - - def as_query_string(self): - return str(self) - - - @staticmethod - def from_dictionary(d): - """ - : Instantiate a CravatQuery from a dictionary representation. - : Args: - : d <dictionary>: A dictionary representing a CravatQuery, containing keys: [{}] - """.format(CravatQuery.query_keys) - - for key in CravatQuery.query_keys: - if key not in d: - raise CravatQueryException("CravatQuery.from_dictionary requires keys: [{}], however key: '{}' was not provided " - .format(CravatQuery.query_keys, key)) - return CravatQuery(d["chromosome"], d["position"], d["strand"], d["reference"], d["alternate"]) - - - @staticmethod - def from_array(array, mapping=None): - """ - : Instantiate a CravatQuery from an array of values. Useful when translating read lines from a file. - : Args: - : fmt <str> - Either 'cr' or 'vcf', describing input format - : array <list> - The values to instantiate the CravatQuery from - : mapping <dict> - Optional. A dictionary associating cravat parameters to indicies in the array. - Valid values are: 'chromosome', 'position', 'strand', 'reference', 'alternate' - """ - - # Set the mapping value. Either recieved from user, or obtained via defualt associated to 'fmt' - if mapping == None: - mapping = CravatQuery.default_mapping - - # Build a dict of cravat querying keys to values. - d = {} - for key in CravatQuery.query_keys: - # Try to get index position from mapping by the key, and value from array by the index - if key in mapping: - index = mapping[key] - d[key] = array[index] - # If index not provided in mapping, check if there is a defualt value - elif key in CravatQuery.default_values: - d[key] = CravatQuery.default_values[key] - # Unable to get value for querying key, meaning can't construct the minimum requirements for query - else: - raise CravatQueryException("CravatQuery.from_array requires a mapping index for key: '{}', however value was not provided".format(key)) - return CravatQuery.from_dictionary(d) - - - - @staticmethod - def format_chromosome(_chr): - """ - : Format a chromosome for use as query parameter. '_chr' name used to avoid python built-in name confliction. - : Args: - : _chr - Either an interger [1,23], or 'x'/'X', or 'y'/'Y', or a string of the form - : 'chr<z>' where '<z>' is one of the previously described values - """ - inRange = lambda x: 1 <= x and x <= 23 - _chr = _chr.lower() - _chr = _chr.strip('chr') - # Handler interger chromosomes 1 to 23 - try: - _chr = int(_chr) - if inRange(_chr): - return 'chr' + str(_chr) - else: - raise CravatQueryException("Chromsomme of '{}' was out of range [1,23]".format(_chr)) - except: - pass - # Handle chromosomes chromosomes x and y - if _chr == 'x' or _chr == 'y': - return 'chr' + _chr - raise CravatQueryException("Unable to resolve input: '{}' into a valid chromosome representation".format(_chr)) - - - @staticmethod - def jump_header(in_file, out_file, headerlines=0): - """ - : Jumps over a header space of line number 'headerlines'. Sets up in_file so that - : the next execution of in_file.readline() will return the first non-header line. - """ - in_file.seek(0) - for line in range(headerlines): - in_file.readline() - - -def main(in_path, out_path, pre_callback=None, user_mapping=None): - """ - : Read the file line by line and use data to query cravat server. - : Args: - : fmt <str>: 'cr' or 'vcf'. The input format - : in_path <str>: Path to input file - : in_path <str>: Path to output file - : header_callback <function>: A function to handle the header space. Executed - before main loop. Recieves in_file, out_file, and fmt as argumnets - """ - - with open(in_path, 'r') as in_file, \ - open(out_path, 'w') as out_file: - - # Perform any pre-processing steps, such as jumping a header space - if pre_callback: - pre_callback(in_file, out_file, fmt) - - # main loop - for line in in_file: - - # Create query from line of input data - line = line.strip().split('\t') - query = CravatQuery.from_array(line, user_mapping) - # Make request, and write respone data - call = requests.get(CravatQuery.endpoint, params={ 'mutation': query.as_query_string }) - try: - if call.status_code != 200 or call.text == "": - raise CravatQueryException("Bad Server Response. Respone code: '{}', Response Text: '{}'".format(call.status_code, call.text)) - json_response = json.loads(call.text) - wrote = False - for key, val in json_response.items(): - # Set numeric values to uniform format - try: - val = float(val) - val = format(val, ".4f") - except: - pass - if wrote: - out_file.write("\t") - out_file.write(val) - wrote = True - out_file.write("\n") - except CravatQueryException as e: - print(e) - - - - -if __name__ == "__main__": - - # Input and output file paths, obtained form command line - in_path = sys.argv[1] - out_path = sys.argv[2] - - # Possibly allow user mapping configuration thourgh here. Not fully implemented - if len(sys.argv) > 2: - user_mapping = sys.argv[3] - - # Run the main operation - main(in_path, out_path) \ No newline at end of file
--- a/cravat_annotate/cravat_annotate.xml Tue Jun 12 12:04:45 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -<tool id="cravat_query" name="CRAVAT Query" version="1.0.0"> - <description>Queries CRAVAT for cancer annotation</description> - <command interpreter="python">cravat_annotate.py $input $output</command> - - <inputs> - <param format="tabular" name="input" type="data" label="Source file"/> - </inputs> - - <outputs> - <data format="tabular" name="output" /> - </outputs> - - <tests> - <test> - <param name="input" value="input_call.txt"/> - <output name="output" file="Galaxy23-[CRAVAT_Query_on_data_22].tabular"/> - </test> - </tests> - - <help> - This tool queries CRAVAT for cancer annotation. - </help> - -</tool> -
--- a/cravat_convert/base_converter.py Tue Jun 12 12:04:45 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -class BaseConverter(object): - def __init__(self): - self.format_name = None - def check_format(self,*args,**kwargs): - err_msg = 'Converter for %s format has no method check_format' %\ - self.format_name - raise NotImplementedError(err_msg) - def setup(self,*args,**kwargs): - err_msg = 'Converter for %s format has no method setup' %\ - self.format_name - raise NotImplementedError(err_msg) - def convert_line(self,*args,**kwargs): - err_msg = 'Converter for %s format has no method convert_line' %\ - self.format_name - raise NotImplementedError(err_msg) - - -class BadFormatError(Exception): - def __init__(self, message, errors=None): - super(BadFormatError, self).__init__(message) - # Support for custom error codes, if added later - self.errors = errors \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cravat_submit/cravat_submit.py Tue Jun 12 12:05:40 2018 -0400 @@ -0,0 +1,103 @@ +import requests +import json +import time +import urllib +import sys +import csv + +input_filename = sys.argv[1] +input_select_bar = sys.argv[2] +output_filename = sys.argv[3] + +# HACK: Input args corrections. +if input_select_bar == "None": + # The server represents an analyses of None as ""; however, submitting a blank string on command line throws off arg position + input_select_bar = "" + # The server represents the "Vest and Chasm" analyses as "VEST;CHASM; however, galaxy converts the semi-colon to an 'X'. Switch it back. +elif input_select_bar == "VESTXCHASM": + input_select_bar = "VEST;CHASM" + +write_header = True + +#plugs in params to given URL +submit = requests.post('http://staging.cravat.us/CRAVAT/rest/service/submit', files={'inputfile':open(input_filename)}, data={'email':'znylund@insilico.us.com', 'analyses': input_select_bar}) +#,'analysis':input_select_bar,'functionalannotation': "on"}) +#Makes the data a json dictionary, takes out only the job ID +jobid = json.loads(submit.text)['jobid'] +#out_file.write(jobid) +submitted = json.loads(submit.text)['status'] +#out_file.write('\t' + submitted) + +#loops until we find a status equal to Success, then breaks +while True: + check = requests.get('http://staging.cravat.us/CRAVAT/rest/service/status', params={'jobid': jobid}) + status = json.loads(check.text)['status'] + resultfileurl = json.loads(check.text)['resultfileurl'] + #out_file.write(str(status) + ', ') + if status == 'Success': + #out_file.write('\t' + resultfileurl) + break + else: + time.sleep(2) + +#out_file.write('\n') + +#creates three files +file_1 = time.strftime("%H:%M") + '_Z_Variant_Result.tsv' +file_2 = time.strftime("%H:%M") + '_Z_Additional_Details.tsv' +file_3 = time.strftime("%H:%M") + 'Combined_Variant_Results.tsv' + + +#Download the two results +urllib.urlretrieve("http://staging.cravat.us/CRAVAT/results/" + jobid + "/" + "Variant.Result.tsv", file_1) +urllib.urlretrieve("http://staging.cravat.us/CRAVAT/results/" + jobid + "/" + "Variant_Additional_Details.Result.tsv", file_2) + +headers = [] +duplicates = [] + +#opens the Variant Result file and the Variant Additional Details file as csv readers, then opens the output file (galaxy) as a writer +with open(file_1) as tsvin_1, open(file_2) as tsvin_2, open(output_filename, 'wb') as tsvout: + tsvreader_1 = csv.reader(tsvin_1, delimiter='\t') + tsvreader_2 = csv.reader(tsvin_2, delimiter='\t') + tsvout = csv.writer(tsvout, delimiter='\t') + +#loops through each row in the Variant Additional Details file + for row in tsvreader_2: + #sets row_2 equal to the same row in Variant Result file + row_2 = tsvreader_1.next() + #checks if row is empty or if the first term contains '#' + if row == [] or row[0][0] == '#': + continue + #checks if the row begins with input line + if row[0] == 'Input line': + #Goes through each value in the headers list in VAD + for value in row: + #Adds each value into headers + headers.append(value) + #Loops through the Keys in VR + for value in row_2: + #Checks if the value is already in headers + if value in headers: + continue + #else adds the header to headers + else: + headers.append(value) + + print headers + tsvout.writerow(headers) + + + else: + + cells = [] + #Goes through each value in the next list + for value in row: + #adds it to cells + cells.append(value) + #Goes through each value from the VR file after position 11 (After it is done repeating from VAD file) + for value in row_2[11:]: + #adds in the rest of the values to cells + cells.append(value) + + print cells + tsvout.writerow(cells) \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cravat_submit/cravat_submit.xml Tue Jun 12 12:05:40 2018 -0400 @@ -0,0 +1,34 @@ +<tool id="cravat_submit" name="CRAVAT Submit, Check, and Retrieve" version="0.1.0"> + <description>Submits, checks for, and retrieves data for cancer annotation</description> + <command interpreter="python">cravat_submit.py $input $dropdown $output</command> + + + <inputs> + + <param format="tabular" name="input" type="data" label="Source file"> </param> + <param format="tabular" name="dropdown" type="select" label="Analysis Program"> + <option value="None">None</option> + <option value="VEST">VEST</option> + <option value="CHASM">CHASM</option> + <option value="VEST;CHASM">VEST and CHASM</option> + </param> + + + </inputs> + + <outputs> + <data format="tabular" name="output" /> + </outputs> + + <tests> + <test> + <param name="input" value="fa_gc_content_input.fa"/> + <output name="out_file1" file="fa_gc_content_output.txt"/> + </test> + </tests> + + <help> + This tool submits, checks for, and retrieves data for cancer annotation. + </help> + +</tool>