def __init__(self, run_type, chem_struct=None, smiles=None, name=None, formula=None, mass=None, chemaxon=None, epi=None, test=None, sparc=None, measured=None, melting_point=None, boiling_point=None, water_sol=None, vapor_press=None, mol_diss=None, ion_con=None, henrys_law_con=None, kow_no_ph=None, kow_wph=None, kow_ph=None, koc=None): self.run_type = run_type # defaults to "single", "batch" coming soon... self.jid = cts_rest.gen_jid() # get time of run # chemical structure self.chem_struct = chem_struct self.smiles = smiles self.name = name self.formula = formula # make sure to include units when assigning mass - 'g/mol' self.mass = "{} g/mol".format(mass) # chemical properties (values 'on' or None) -- django params self.melting_point = melting_point self.boiling_point = boiling_point self.water_sol = water_sol self.vapor_press = vapor_press self.mol_diss = mol_diss self.ion_con = ion_con self.henrys_law_con = henrys_law_con self.kow_no_ph = kow_no_ph self.kow_wph = kow_wph self.kow_ph = kow_ph self.koc = koc self.chemaxon = chemaxon self.sparc = sparc self.epi = epi self.test = test self.measured = measured self.checkedPropsDict = {} self.calcluatorsDict = {} # Property checkboxes' values: self.checkedPropsDict = { "melting_point": self.melting_point, "boiling_point": self.boiling_point, "water_sol": self.water_sol, "vapor_press": self.vapor_press, "mol_diss": self.mol_diss, "ion_con": self.ion_con, "henrys_law_con": self.henrys_law_con, "kow_no_ph": self.kow_no_ph, "kow_wph": self.kow_wph, "kow_ph": self.kow_ph, "koc": self.koc } # calculator checkboxes' values: self.calcluatorsDict = { "chemaxon": self.chemaxon, "epi": self.epi, "test": self.test, "sparc": self.sparc, "measured": self.measured }
def htmlReceiver(request, model=''): """ Save output as HTML """ input_str = '' input_str += parsePOST(request) packet = StringIO.StringIO(input_str) # write to memory jid = cts_rest.gen_jid() # create timestamp response = HttpResponse(packet.getvalue(), content_type='application/html') response['Content-Disposition'] = 'attachment; filename=' + model + '_' + jid + '.html' # packet.truncate(0) # clear from memory? packet.close() return response
def batchOutputPage(request, model='none', header='none'): viewmodule = importlib.import_module('.views', 'cts_app.models.'+model) batchoutputmodule = importlib.import_module('.'+model+'_batch', 'cts_app.models.'+model) header = viewmodule.header # linksleft = linksLeft.linksLeft() html = render_to_string('01cts_uberheader.html', {'title': header+' Batch'}) # html += render_to_string('02cts_uberintroblock_wmodellinks.html', {'model':model,'page':'batchinput'}) html += render_to_string('02cts_uberintroblock_wmodellinks.html', {'model':model,'page':'output'}) html += linksLeft.linksLeft() html += render_to_string('04cts_uberbatch_start.html', { 'model': model, 'model_attributes': header+' Batch Output'}) # timestamp / version section st = datetime.datetime.strptime(cts_rest.gen_jid(), '%Y%m%d%H%M%S%f').strftime('%A, %Y-%B-%d %H:%M:%S') html += """ <div class="out_"> <b>{} Batch Version 1.0</a> (Beta)<br> """.format(header) html += st html += " (EST)</b>" html += """ </div><br><br>""" html = html + render_to_string('cts_export.html', {}) batchOutputPageFunc = getattr(batchoutputmodule, model+'BatchOutputPage') # function name = 'model'BatchOutputPage (e.g. 'sipBatchOutputPage') # batchOutputTuple = batchOutputPageFunc(request) # html = html + batchOutputTuple[0] html += batchOutputPageFunc(request) # html = html + render_to_string('export.html', {}) html = html + render_to_string('04cts_uberoutput_end.html', {}) response = HttpResponse() response.write(html) return response
def pdfReceiver(request, model=''): """ PDF Generation Receiver function. Sends POST data as string for processing """ input_str = '' input_str += parsePOST(request) packet = StringIO.StringIO() # write to memory try: pisa.CreatePDF(input_str, dest=packet) except ValueError as error: # triggered from the elusive invalid color value issue: logging.warning("elusive invalid color value, defaulting html background-color to FFFFFF") pisa.CreatePDF(input_str, dest=packet, default_css="body{background-color:#FFFFFF;}") jid = cts_rest.gen_jid() # create timestamp response = HttpResponse(packet.getvalue(), content_type='application/pdf') response['Content-Disposition'] = 'attachment; filename=' + model + '_' + jid + '.pdf' packet.close() # todo: figure out why this doesn't solve the 'caching problem' return response
def __init__(self, run_type, chem_struct, smiles, orig_smiles, iupac, formula, mass, exact_mass, abiotic_hydrolysis, abiotic_reduction, mamm_metabolism, gen_limit, pop_limit, likely_limit): self.jid = cts_rest.gen_jid() # get time of run self.run_type = run_type # single or batch # Chemical Structure self.chem_struct = chem_struct # chemical structure self.smiles = smiles self.orig_smiles = orig_smiles self.iupac = iupac self.formula = formula self.mass = '{} g/mol'.format(mass) self.exact_mass = '{} g/mol'.format(exact_mass) # Reaction Libraries self.abiotic_hydrolysis = abiotic_hydrolysis # values: on or None self.abiotic_reduction = abiotic_reduction self.mamm_metabolism = mamm_metabolism self.gen_max = gen_limit self.gen_limit = gen_limit # generation limit self.pop_limit = pop_limit # population limit self.likely_limit = likely_limit # self.pchemprop_obj = pchemprop_obj # pchemprop object with inputs # Known keys for metabolizer on pnnl server (11-5-14) # metabolizerList = ["hydrolysis", "abiotic_reduction", "human_biotransformation"] metabolizerList = ["hydrolysis", "abiotic_reduction"] reactionLibs = { "hydrolysis": self.abiotic_hydrolysis, "abiotic_reduction": self.abiotic_reduction, # "human_biotransformation": self.mamm_metabolism } self.trans_libs = [] for key, value in reactionLibs.items(): if value: self.trans_libs.append(key) # NOTE: populationLimit is hard-coded to 0 as it currently does nothing dataDict = { 'structure': self.smiles, 'generationLimit': self.gen_limit, 'populationLimit': 0, # 'likelyLimit': self.likely_limit, 'likelyLimit': 0.001, # 'transformationLibraries': self.trans_libs, 'excludeCondition': "" # 'generateImages': False } if len(self.trans_libs) > 0: dataDict.update({'transformationLibraries': self.trans_libs}) if self.run_type != 'batch': try: response = jchem_rest.getTransProducts(dataDict) except Exception as e: logging.warning("error making data request: {}".format(e)) raise # reformat data for outputting to tree structure: data_walks.j = 0 data_walks.metID = 0 self.results = data_walks.recursive(response, int(self.gen_limit)) # Initializing here to fix ajax call script test_results being blank, triggering syntax error.. self.test_results = [] self.run_data = { 'title': "Transformation Products Output", 'jid': self.jid, 'time': datetime.datetime.strptime(self.jid, '%Y%m%d%H%M%S%f').strftime('%A, %Y-%B-%d %H:%M:%S'), 'chem_struct': self.chem_struct, 'smiles': self.smiles, 'iupac': self.iupac, 'formula': self.formula, 'mass': self.mass }
def parseToCSV(self, run_data): jid = cts_rest.gen_jid() # create timestamp time_str = datetime.datetime.strptime(jid, '%Y%m%d%H%M%S%f').strftime('%A, %Y-%B-%d %H:%M:%S') response = HttpResponse(content_type='text/csv') content_disposition = '' if 'batch_data' in run_data: content_disposition = 'attachment; filename=' + self.model + '_batch_' + jid + '.csv' else: content_disposition = 'attachment; filename=' + self.model + '_' + jid + '.csv' response['Content-Disposition'] = content_disposition # writer = csv.writer(response) # bind writer to http response # # build title section of csv.. # writer.writerow([run_data['run_data']['title']]) # writer.writerow([run_data['run_data']['time']]) # writer.writerow([""]) rows = [] headers = [] # Build rows for chemicals: if 'batch_data' in run_data: if 'workflow' in run_data and run_data['workflow'] == 'gentrans': for i in range(0, len(run_data['batch_data'])): parent_products = run_data['batch_data'][i] for j in range(0, len(parent_products)): rows.append([]) else: for i in range(0, len(run_data['batch_chems'])): rows.append([]) else: if 'workflow' in run_data and run_data['workflow'] == 'gentrans': for i in range(0, len(run_data['data'])): rows.append([]) else: rows.append([]) # write parent info first and in order.. for prop in self.molecular_info: if not 'batch_data' in run_data: if run_data['workflow'] == 'gentrans': headers.append(prop) i = 0 for metabolite in run_data['data']: for key, val in metabolite.items(): if key == prop and key not in rows[i]: # headers.append(key) rows[i].append(val) i += 1 else: for key, val in run_data['run_data'].items(): if key == prop: headers.append(key) rows[0].append(val) else: headers.append(prop) i = 0 j = 0 # trying it here for gentrans batch mode! # for chem_data in run_data['batch_data']: for chem_data in run_data['batch_chems']: if run_data['workflow'] == 'gentrans': for product in run_data['batch_data'][i]: data = product[prop] rows[j].append(data) j += 1 i += 1 else: data = chem_data[prop] rows[i].append(data) i += 1 if self.model == 'chemspec': if 'run_type' in run_data and run_data['run_type'] == 'batch': for spec_prop in self.speciation_props: for chem_data in run_data['batch_data']: if spec_prop == 'isoelectricPoint': header = "isoelectric point" if not header in headers: headers.append(header) header_index = headers.index(header) for i in range(0, len(rows)): if rows[i][0] == chem_data['node']['smiles']: rows[i].insert(header_index, chem_data['data'][spec_prop]) elif spec_prop == 'pka' or spec_prop == 'pkb': j = 1 for item in chem_data['data'][spec_prop]: header = "pka_{}".format(j) j += 1 if not header in headers: headers.append(header) for n in range(0, len(rows)): rows[n].append("") header_index = headers.index(header) for n in range(0, len(rows)): if rows[n][0] == chem_data['node']['smiles']: rows[n].insert(header_index, item) elif spec_prop == 'majorMicrospecies': if not spec_prop in headers: headers.append(spec_prop) header_index = headers.index(spec_prop) for i in range(0, len(rows)): if rows[i][0] == chem_data['node']['smiles']: rows[i].insert(header_index, chem_data['data'][spec_prop]['smiles']) elif spec_prop == 'pka-micospecies': j = 1 for ms in chem_data['data'][spec_prop].items(): header = "microspecies_{}".format(j) j += 1 if not header in headers: headers.append(header) header_index = headers.index(header) for i in range(0, len(rows)): if rows[i][0] == chem_data['node']['smiles']: rows[i].insert(header_index, chem_data['data'][spec_prop]['smiles']) # i += 1 else: run_data = run_data['run_data'] for key, val in run_data.items(): if key not in self.molecular_info: if key == 'isoelectricPoint': headers.append(key) rows[0].append(val) elif key == 'pka' or key == 'pkb': i = 0 # pka counter for item in val: headers.append(key + "_" + str(i)) rows[0].append(item) i+=1 elif key == 'majorMicrospecies': headers.append(key + '-smiles') rows[0].append(val['smiles']) elif key == 'pka-micospecies': for ms in val.items(): # each ms is a jchem_structure object headers.append(key + '-smiles') rows[0].append(val['smiles']) # elif key == 'stereoisomers' or key == 'tautomers': elif key == 'tautomers': i = 0 for item in val: headers.append(item['key'] + "_" + str(i)) rows[0].append(item['smiles']) i+=1 elif self.model == 'pchemprop': if 'batch_data' in run_data: multiChemPchemDataRowBuilder(headers, rows, self.props, run_data) else: for prop in self.props: for calc, calc_props in run_data['checkedCalcsAndProps'].items(): if prop in calc_props: if prop == "ion_con": for pka_key, pka_val in calc_props[prop].items(): if pka_val and pka_val != 'none': pka_num = str(int(pka_key[-1:]) + 1) new_pka_key = pka_key[:-1] + "_" + pka_num headers.append("{} ({})".format(new_pka_key, calc)) rows[0].append(roundData(prop, pka_val)) elif calc == 'chemaxon' and prop == 'kow_no_ph' or calc == 'chemaxon' and prop == 'kow_wph': # e.g., "-1.102 (KLOP)<br>-1.522 (VG)<br>-1.344 (PHYS)<br>" method_data = calc_props[prop].split('<br>') method_data.remove('') # remove trailing '' list item for method_datum in method_data: value = method_datum.split()[0] # value, method method = method_datum.split()[1] headers.append("{} ({}, {})".format(prop, calc, method)) rows[0].append(roundData(prop, value)) else: headers.append("{} ({})".format(prop, calc)) rows[0].append(roundData(prop, calc_props[prop])) elif self.model == 'gentrans': # TODO: class this, e.g., Metabolizer (jchem_rest) if 'batch_data' in run_data: metabolites_data = run_data['batch_data'] else: metabolites_data = run_data['data'] if not metabolites_data: return HttpResponse("error building csv for metabolites..") headers.insert(0, 'genKey') # insert generation headers first if 'batch_data' in run_data: parent_index = 0 products_index = 0 for parent in metabolites_data: # products_index = 0 for product in parent: header_index = headers.index('genKey') # make new gen key to keep track of parents parent_genkey = int(product['genKey'][:1]) # first value of genKey remaining_genkey = product['genKey'][1:] new_genkey = str(parent_genkey + parent_index) + remaining_genkey rows[products_index].insert(header_index, new_genkey) products_index += 1 parent_index += 1 else: # inserts genKey into first column of batch chems csv: products_index = 0 for metabolite in metabolites_data: header_index = headers.index('genKey') if 'genKey' not in rows[products_index]: rows[products_index].insert(header_index, metabolite['genKey']) products_index += 1 # for chem_data in metabolites_data: for prop in self.props: if run_data['checkedCalcsAndProps']: for calc, calc_props in run_data['checkedCalcsAndProps'].items(): if prop in calc_props: for chem_data in metabolites_data: if 'pchemprops' in chem_data: for pchem in chem_data['pchemprops']: if pchem['prop'] == prop and pchem['calc'] == calc: if pchem['prop'] == "ion_con": j = 1 for pka in pchem['data']['pKa']: header = "pka_{} ({})".format(j, calc) j += 1 if not header in headers: headers.append(header) for i in range(0, len(rows)): rows[i].append("") header_index = headers.index(header) for i in range(0, len(rows)): if rows[i][1] == chem_data['smiles']: rows[i].insert(header_index, roundData(prop, pka)) else: if 'method' in pchem: header = "{} ({}, {})".format(prop, calc, pchem['method']) else: header = "{} ({})".format(prop, calc) if not header in headers: headers.append(header) header_index = headers.index(header) for i in range(0, len(rows)): if run_data['workflow'] == 'gentrans': chem_smiles = rows[i][1] # smiles after genKey column else: chem_smiles = rows[i][0] # if chem_smiles == chem_data['smiles'] and pchem['data'] not in rows[i]: # temporary error handling... if chem_smiles == chem_data['smiles'] and pchem['prop'] == prop: if 'error' in chem_data: # rows[i].insert(header_index, chem_data['data']) rows[i].insert(header_index, roundData(prop, pchem['data'])) elif 'method' in chem_data: # rows[i].insert(header_index, roundData(chem_data['data'])) rows[i].insert(header_index, roundData(prop, pchem['data'])) else: # rows[i].insert(header_index, roundData(chem_data['data'])) rows[i].insert(header_index, roundData(prop, pchem['data'])) # # might have to add code to keep row order.. # # writer.writerow(rows['headers']) # writer.writerow(headers) # if self.model == 'gentrans': # for row in rows: # writer.writerow(row) # else: # for row in rows: # encoded_row_data = [] # for datum in row: # if isinstance(datum, unicode): datum = datum.encode('utf8') # encoded_row_data.append(datum) # writer.writerow(encoded_row_data) # check for encoding issues that are laid out in the commented # out conditional above..qQ. return some_streaming_csv_view(headers, rows, run_data, content_disposition)
def __init__(self, run_type, chem_struct, smiles, orig_smiles, name, formula, mass, exactMass, get_pka, get_taut, get_stereo, pKa_decimals, pKa_pH_lower, pKa_pH_upper, pKa_pH_increment, pH_microspecies, isoelectricPoint_pH_increment, tautomer_maxNoOfStructures, tautomer_pH, stereoisomers_maxNoOfStructures): self.jid = cts_rest.gen_jid() # timestamp self.run_type = run_type # Chemical Editor Tab self.chem_struct = chem_struct # SMILE of chemical on 'Chemical Editor' tab self.smiles = smiles self.orig_smiles = orig_smiles self.name = name self.formula = formula self.mass = "{} g/mol".format(mass) self.exactMass = "{} g/mol".format(exactMass) # Checkboxes: self.get_pka = cts_rest.booleanize(get_pka) # convert 'on'/'off' to bool self.get_taut = cts_rest.booleanize(get_taut) self.get_stereo = cts_rest.booleanize(get_stereo) # Chemical Speciation Tab self.pKa_decimals = None if pKa_decimals: self.pKa_decimals = int(pKa_decimals) self.pKa_pH_lower = pKa_pH_lower self.pKa_pH_upper = pKa_pH_upper self.pKa_pH_increment = pKa_pH_increment self.pH_microspecies = pH_microspecies self.isoelectricPoint_pH_increment = isoelectricPoint_pH_increment self.tautomer_maxNoOfStructures = tautomer_maxNoOfStructures self.tautomer_pH = tautomer_pH self.stereoisomers_maxNoOfStructures = stereoisomers_maxNoOfStructures # Output stuff: self.jchemPropObjects = {} self.jchemDictResults = {} self.speciation_inputs = {} # for batch mode use pkaObj, majorMsObj, isoPtObj, tautObj, stereoObj = None, None, None, None, None if self.run_type != 'batch': logging.info("Making calls inside chemspec model, single mode...") if self.get_pka: # make call for pKa: pkaObj = JchemProperty.getPropObject('pKa') pkaObj.setPostDataValues({ "pHLower": self.pKa_pH_lower, "pHUpper": self.pKa_pH_upper, "pHStep": self.pKa_pH_increment, }) pkaObj.makeDataRequest(self.smiles) # make call for majorMS: majorMsObj = JchemProperty.getPropObject('majorMicrospecies') majorMsObj.setPostDataValue('pH', self.pH_microspecies) majorMsObj.makeDataRequest(self.smiles) # make call for isoPt: isoPtObj = JchemProperty.getPropObject('isoelectricPoint') isoPtObj.setPostDataValue('pHStep', self.isoelectricPoint_pH_increment) isoPtObj.makeDataRequest(self.smiles) if self.get_taut: tautObj = JchemProperty.getPropObject('tautomerization') tautObj.setPostDataValues({ "maxStructureCount": self.tautomer_maxNoOfStructures, "pH": self.tautomer_pH, "considerPH": True }) tautObj.makeDataRequest(self.smiles) if self.get_stereo: # TODO: set values for max stereos!!! stereoObj = JchemProperty.getPropObject('stereoisomer') stereoObj.setPostDataValue('maxStructureCount', self.stereoisomers_maxNoOfStructures) stereoObj.makeDataRequest(self.smiles) self.jchemPropObjects = { 'pKa': pkaObj, 'majorMicrospecies': majorMsObj, 'isoelectricPoint': isoPtObj, 'tautomerization': tautObj, 'stereoisomers': stereoObj } else: # for batch mode, get inputs but don't get # data until output page loads. this is because batch # speciation calls are done through nodejs/socket.io # using cts_pchemprop_requests.html self.speciation_inputs = { 'pKa_decimals': pKa_decimals, 'pKa_pH_lower': pKa_pH_lower, 'pKa_pH_upper': pKa_pH_upper, 'pKa_pH_increment': pKa_pH_increment, 'pH_microspecies': pH_microspecies, 'isoelectricPoint_pH_increment': isoelectricPoint_pH_increment } self.speciation_inputs = json.dumps(self.speciation_inputs) self.run_data = { 'title': "Chemical Speciation Output", 'jid': self.jid, 'time': datetime.datetime.strptime(self.jid, '%Y%m%d%H%M%S%f').strftime('%A, %Y-%B-%d %H:%M:%S'), 'chem_struct': self.chem_struct, 'smiles': self.smiles, 'name': self.name, 'formula': self.formula, 'mass': self.mass, 'exactMass': self.exactMass } for key, value in self.jchemPropObjects.items(): if value: if key == 'pKa': self.jchemDictResults.update({ 'pka': pkaObj.getMostAcidicPka(), 'pkb': pkaObj.getMostBasicPka(), 'pka_parent': pkaObj.getParent(), 'pka_microspecies': pkaObj.getMicrospecies(), 'pka_chartdata': pkaObj.getChartData() }) elif key == 'majorMicrospecies': self.jchemDictResults.update({key: majorMsObj.getMajorMicrospecies()}) elif key == 'isoelectricPoint': self.jchemDictResults.update({ key: isoPtObj.getIsoelectricPoint(), 'isopt_chartdata': isoPtObj.getChartData() }) elif key == 'tautomerization': self.jchemDictResults.update({'tautomers': tautObj.getTautomers()}) elif key == 'stereoisomers': self.jchemDictResults.update({key: stereoObj.getStereoisomers()}) self.run_data.update(self.jchemDictResults)