1#!@WHICHPYTHON@ 2""" 3 CGI Module for checking on the status of an OPAL job 4""" 5 6__date__ = "4 January 2010" 7__author__ = "Wes Goodman, Samir Unni, Yong Huang" 8 9import sys 10import cgi 11import cgitb 12import os,shutil,glob,string,time,urllib 13from datetime import timedelta 14from src.server import * 15from src.aconf import * 16from src.utilities import getTrackingScriptString, getEventTrackingString 17 18cgitb.enable() 19form = cgi.FieldStorage() 20 21def printheader(pagetitle,refresh=None,jobid=None): 22 str = "" 23 str+= "<html>\n" 24 str+= "<HEAD>\n" 25 str+= '<img src="https://raw.githubusercontent.com/Electrostatics/apbs-pdb2pqr/master/apbs/doc/icons/APBS_128_v2.png" style="float:right; position:relative;right:200px; top: 2px;">' 26 if refresh: 27 str+= "\t<META HTTP-EQUIV=\"Refresh\" CONTENT=\"%s\">\n" % refresh 28 str+= "\t<TITLE>%s</TITLE>\n" % pagetitle 29 str+= "\t<link rel=\"stylesheet\" href=\"%s\" type=\"text/css\">\n" % STYLESHEET 30 str+= getTrackingScriptString(jobid) 31 str+= "</HEAD>\n" 32 return str 33 34def createcube(dx_input, pqr_input, output): 35 36 with open(dx_input, 'r') as in_f, open(output, 'w') as out_f, open(pqr_input, 'r') as in_pqr: 37 out_f.write("CPMD CUBE FILE.\n" 38 "OUTER LOOP: X, MIDDLE LOOP: Y, INNER LOOP: Z\n") 39 40 #Discard comments at top of file. 41 line = in_f.readline() 42 newline = in_pqr.readline() 43 while line.startswith('#'): 44 line = in_f.readline() 45 46 47 split_line = line.split() 48 grid_sizes = [int(x)*-1 for x in split_line[-3:]] 49 50 split_line = in_f.readline().split() 51 52 origin = [float(x) for x in split_line[-3:]] 53 54 parameter_fmt = "{:>4} {:>11.6f} {:>11.6f} {:>11.6f}\n" 55 atom_num = 0 56 while newline.startswith('REMARK'): 57 newline = in_pqr.readline() 58 59 try: 60 while newline.startswith('ATOM') or newline.startswith('HETATM'): 61 newline = in_pqr.readline() 62 new_split_line = newline.split() 63 atom_num = new_split_line[1] 64 except IndexError: 65 pass 66 in_pqr.seek(0) 67 newline = in_pqr.readline() 68 while newline.startswith('REMARK'): 69 newline = in_pqr.readline() 70 71 origin_line = parameter_fmt.format(atom_num, *origin) 72 out_f.write(origin_line) 73 74 75 for x in xrange(3): 76 split_line = in_f.readline().split() 77 grid_dims = [float(item) for item in split_line[-3:]] 78 79 dim_lin = parameter_fmt.format(grid_sizes[x], *grid_dims) 80 out_f.write(dim_lin) 81 82 atoms_parameter_fmt = "{:>4} {:>11.6f} {:>11.6f} {:>11.6f} {:>11.6f}\n" 83 a = True 84 xreal_center = [] 85 yreal_center = [] 86 zreal_center = [] 87 try: 88 while newline.startswith('ATOM') or newline.startswith('HETATM'): 89 new_split_line = newline.split() 90 radius = new_split_line[-1] 91 xyz = new_split_line[-5:-2] 92 line_atom_num = new_split_line[1] 93 atom_radius = new_split_line[-1] 94 pqr_lin = atoms_parameter_fmt.format(int(line_atom_num), float(new_split_line[-2]), float(xyz[0]), float(xyz[1]), float(xyz[2])) 95 out_f.write(pqr_lin) 96 newline = in_pqr.readline() 97 xreal_center.append(float(xyz[0])) 98 yreal_center.append(float(xyz[1])) 99 zreal_center.append(float(xyz[2])) 100 except IndexError: 101 pass 102 103 x_avg = sum(xreal_center)/float(atom_num) 104 y_avg = sum(yreal_center)/float(atom_num) 105 z_avg = sum(zreal_center)/float(atom_num) 106 107 #print origin 108 #new_origin = [] 109 #for item in origin: 110 # newitem = item/0.529177 111 #new_new = item/2 + newitem/2 112 # new_origin.append(newitem) 113 #print new_origin 114 115 #Consume unneeded object lines. 116 in_f.readline() 117 in_f.readline() 118 119 ##TODO: put atoms here 120 121 value_format = ["{:< 13.5E}"] 122 value_format = ' '.join(value_format * 6) + '\n' 123 group = [] 124 line = in_f.readline() 125 while not line.startswith('attribute'): 126 values = [float(item) for item in line.split()] 127 group.extend(values) 128 129 if len(group) >= 6: 130 out_f.write(value_format.format(*group)) 131 group = [] 132 133 line = in_f.readline() 134 135 if group: 136 group_strs = ["{:< 13.5E}".format(item) for item in group] 137 out_f.write(' '.join(group_strs)) 138 139def checkprogress(jobid=None,appServicePort=None,calctype=None): 140 """ 141 Finds out if the job has been completed 142 """ 143 144 if have_opal: 145 146 # construct soap request 147 try: 148 status=appServicePort.queryStatus(queryStatusRequest(jobid)) 149 except Exception, e: 150 return ["error"] 151 if status._code == 4: 152 return ["error"] 153 154 if status._code == 8: 155 return ["complete",status] 156 else: 157 return ["running",status] 158 159 else: 160 progress = [] 161 file = open('%s%s%s/%s_status' % (INSTALLDIR,TMPDIR,jobid, form["calctype"].value)) 162 163 for line in file.readlines(): 164 progress.append(string.strip(line)) 165 file.close() 166 return progress 167 168def mainCGI(): 169 """ 170 Main method for determining the query page output 171 """ 172 logopts = {} 173 print "Content-type: text/html\n\n" 174 calctype = form["calctype"].value 175 176 # prints version error, if it exists 177 if form["jobid"].value == 'False': 178 print printheader("%s Job Status Page" % calctype.upper()) 179 progress = "version_mismatch" 180 runtime = 0 181 elif form["jobid"].value == 'notenoughmem': 182 print printheader("%s Job Status Page" % calctype.upper()) 183 progress = "not_enough_memory" 184 runtime = 0 185 else: 186 progress = None 187 188 #Check for error html 189 errorpath = '%s%s%s.html' % (INSTALLDIR, TMPDIR, form["jobid"].value) 190 if os.path.isfile(errorpath): 191 string = "" 192 string+= "<html>\n" 193 string+= "\t<head>\n" 194 string+= "\t\t<meta http-equiv=\"Refresh\" content=\"0; url=%s%s%s.html\">\n" % (WEBSITE, TMPDIR, form["jobid"].value) 195 string+= "\t</head>\n" 196 string+= "</html>\n" 197 print string 198 return 199 200 # prepares for Opal query, if necessary 201 if have_opal: 202 if calctype=="pdb2pqr": 203 opal_url = PDB2PQR_OPAL_URL 204 elif calctype=="apbs": 205 opal_url = APBS_OPAL_URL 206 appLocator = AppServiceLocator() 207 appServicePort = appLocator.getAppServicePort(opal_url) 208 else: 209 appServicePort = None 210 211 # if PDB2PQR, determines if link to APBS calculation should be shown 212 if calctype=="pdb2pqr": 213 #if(form["apbsinput"].value=="True"): # change to use a file 214 # apbs_input = True 215 #else: 216 # apbs_input = False 217 apbsInputFile = open('%s%s%s/apbs_input' % (INSTALLDIR, TMPDIR, form["jobid"].value)) 218 apbs_input = apbsInputFile.read() 219 apbsInputFile.close() 220 if apbs_input=="True": 221 apbs_input = True 222 else: 223 apbs_input = False 224 225 typemapInputFile = open('%s%s%s/typemap' % (INSTALLDIR, TMPDIR, form["jobid"].value)) 226 typemap = typemapInputFile.read() 227 typemapInputFile.close() 228 if typemap=="True": 229 typemap = True 230 else: 231 typemap = False 232 233 if have_opal and progress == None: 234 if form["calctype"].value=="pdb2pqr": 235 pdb2pqrJobIDFile = open('%s%s%s/pdb2pqr_opal_job_id' % (INSTALLDIR, TMPDIR, form["jobid"].value)) 236 jobid = pdb2pqrJobIDFile.read() 237 pdb2pqrJobIDFile.close() 238 elif form["calctype"].value=="apbs": 239 apbsJobIDFile = open('%s%s%s/apbs_opal_job_id' % (INSTALLDIR, TMPDIR, form["jobid"].value)) 240 jobid = apbsJobIDFile.read() 241 apbsJobIDFile.close() 242 else: 243 jobid = form["jobid"].value 244 245 if progress == None: 246 cp = checkprogress(jobid,appServicePort,calctype) # finds out status of job 247 progress = cp[0] 248 249 #initialize with bogus value just in case 250 starttime = time.time() 251 252 if progress == "running" or progress == "complete": 253 timefile = open('%s%s%s/%s_start_time' % (INSTALLDIR, TMPDIR, form["jobid"].value, form["calctype"].value)) 254 starttime = float(timefile.read()) 255 timefile.close() 256 257 if progress == "running" or (have_opal and progress not in ("version_mismatch", 258 "not_enough_memory", 259 "error", 260 "complete")): 261 runtime = time.time()-starttime 262 runtime = int(runtime) 263 264 elif progress == "complete": 265 endTimeFileString = '%s%s%s/%s_end_time' % (INSTALLDIR, TMPDIR, form["jobid"].value, form["calctype"].value) 266 if have_opal and not os.path.isfile(endTimeFileString): 267 runtime = time.time()-starttime 268 with open(endTimeFileString, 'w') as endTimeFile: 269 endTimeFile.write(str(time.time())) 270 else: 271 with open(endTimeFileString, 'r') as endTimeFile: 272 runtime = float(endTimeFile.read())-starttime 273 else: 274 runtime = -1 275 276 if progress == "running": 277 #if have_opal: 278 # resultsurl = cp[1]._baseURL 279 #else: 280 if calctype=="pdb2pqr": 281 resultsurl = '%squerystatus.cgi?jobid=%s&apbsinput=%s&calctype=pdb2pqr' % (WEBSITE, form["jobid"].value, apbs_input) 282 else: 283 resultsurl = '%squerystatus.cgi?jobid=%s&calctype=apbs' % (WEBSITE, form["jobid"].value) 284 285 if progress == "complete": 286 print printheader("%s Job Status Page" % calctype.upper(), jobid=form["jobid"].value) 287 288 elif progress == "error": 289 print printheader("%s Job Status Page - Error" % calctype.upper(),0, jobid=form["jobid"].value) 290 291 elif progress == "running": # job is not complete, refresh in 30 seconds 292 print printheader("%s Job Status Page" % calctype.upper(), refresh, jobid=form["jobid"].value) 293 294 print "<BODY>\n<P>" 295 print "<p></p>" 296 print '<div id="content">' 297 print "<h3>Status:" 298 299 color = "FA3434" 300 image = WEBSITE+"images/red_x.png" 301 302 if progress == "complete": 303 color = "2CDE56" 304 image = WEBSITE+"images/green_check.png" 305 elif progress == "running": 306 color = "ffcc00" 307 image = WEBSITE+"images/yellow_exclamation.png" 308 309 print "<strong style=\"color:#%s;\">%s</strong>" % (color, progress) 310 print "<img src=\"%s\"><br />" % image 311 print "</h3>" 312 print "Run time: " + str(timedelta(seconds=round(runtime))) + '<br />' 313 print "Current time: %s<br />" % time.asctime() 314 print "</P>\n<HR>\n<P>" 315 316 if progress == "complete": 317 if calctype=="pdb2pqr": 318 nexturl = 'apbs_cgi.cgi?jobid=%s' % form["jobid"].value 319 else: 320 url_3dmol = 'visualize.cgi?jobid=%s&tool=%s' % (form["jobid"].value,'tool_3dmol') 321 url_jmol = 'visualize.cgi?jobid=%s&tool=%s' % (form["jobid"].value,'tool_jmol') 322 323 324 if have_opal: 325 resp = appServicePort.getOutputs(getOutputsRequest(jobid)) 326 filelist = resp._outputFile 327 328 print "Here are the results:<ul>" 329 print "<li>Input files<ul>" 330 331 if calctype=="pdb2pqr": 332 # this code should be cleaned up once local PDB2PQR runs output the PDB file with the .pdb extension 333 if have_opal: 334 for i in range(0,len(filelist)): 335 file_name = filelist[i]._name 336 if ((len(file_name) == 4 and '.' not in file_name) or 337 (file_name.lower().endswith(".pdb") and "pdb2pka_output" not in file_name)): 338 print "<li><a href=%s>%s</a></li>" % (filelist[i]._url, filelist[i]._name) 339 340 if file_name.lower().endswith((".mol", ".mol2", ".names", ".dat")) and "pdb2pka_output" not in file_name: 341 print "<li><a href=%s>%s</a></li>" % (filelist[i]._url, filelist[i]._name) 342 343 344 else: 345 print "<li><a href=%s%s%s/%s.pdb>%s.pdb</a></li>" % (WEBSITE, TMPDIR, jobid, jobid, jobid) 346 347 elif calctype=="apbs": 348 if have_opal: 349 for i in range(0,len(filelist)): 350 if filelist[i]._name == "apbsinput.in" or filelist[i]._name[-4:] == ".pqr": 351 print "<li><a href=%s>%s</a></li>" % (filelist[i]._url, filelist[i]._name) 352 else: 353 print "<li><a href=%s%s%s/apbsinput.in>apbsinput.in</a></li>" % (WEBSITE, TMPDIR, jobid) 354 print "<li><a href=%s%s%s/%s.pqr>%s.pqr</a></li>" % (WEBSITE, TMPDIR, jobid, jobid, jobid) 355 356 print "</ul></li>" 357 print "<li>Output files<ul>" 358 359 queryString = [str(os.environ["REMOTE_ADDR"])] 360 # Getting PDB2PQR run log info 361 if os.path.isfile('%s%s%s/pdb2pqr_log' % (INSTALLDIR, TMPDIR, jobid)): 362 pdb2pqrLogFile=open('%s%s%s/pdb2pqr_log' % (INSTALLDIR, TMPDIR, jobid), 'r') 363 logstr=pdb2pqrLogFile.read().split('\n') 364 templogopts = eval(logstr[0]) 365 pdb2pqrLogFile.close() 366 queryString.insert(0, templogopts.get('pdb','')) 367 368 if calctype=="pdb2pqr": 369 if have_opal: 370 for i in range(0,len(filelist)): 371 if filelist[i]._name.endswith((".propka", "-typemap.html")): 372 print "<li><a href=%s>%s</a></li>" % (filelist[i]._url, filelist[i]._name) 373 374 if filelist[i]._name.endswith(".in") and "pdb2pka_output" not in filelist[i]._name: 375 print "<li><a href=%s>%s</a></li>" % (filelist[i]._url, filelist[i]._name) 376 377 if filelist[i]._name.endswith(".pqr") and not filelist[i]._name.endswith("background_input.pqr"): 378 print "<li><a href=%s>%s</a></li>" % (filelist[i]._url, filelist[i]._name) 379 380 #Get the first line of the summary file. 381 if filelist[i]._name.endswith(".summary"): 382 f=urllib.urlopen(filelist[i]._url) 383 summaryLine = f.readline().strip() 384 #logopts["pdb"]=logopts.get("pdb", "") + "|" + summaryLine 385 queryString.append(summaryLine) 386 f.close() 387# logRun(logopts, runtime, pqrOpalFileLength, logff, REMOTE_ADDR) 388 else: 389 #Get the first line of the summary file. 390 summaryFile = '%s%s%s/%s%s' % (INSTALLDIR, TMPDIR, jobid, jobid, ".summary") 391 if os.path.isfile(summaryFile): 392 with open(summaryFile) as f: 393 summaryLine = f.readline().strip() 394 #logopts["pdb"]=logopts.get("pdb", "") + "|" + summaryLine 395 queryString.append(summaryLine) 396 397 outputfilelist = glob.glob('%s%s%s/*.propka' % (INSTALLDIR, TMPDIR, jobid)) 398 for i in range(0,len(outputfilelist)): 399 outputfilelist[i] = os.path.basename(outputfilelist[i]) 400 for extension in ["-typemap.html", ".pqr", ".in"]: 401 if extension != ".in" or apbs_input != False: 402 if extension == "-typemap.html" and typemap == False: 403 continue 404 outputfilelist.append('%s%s' % (jobid, extension)) 405 for outputfile in outputfilelist: 406 print "<li><a href=%s%s%s/%s>%s</a></li>" % (WEBSITE, TMPDIR, jobid, outputfile, outputfile) 407 408 logopts['queryPDB2PQR'] = '|'.join(queryString) 409 410 #for extension in ["-typemap.html", ".pqr", ".in"]: 411 # print "<li><a href=%s%s%s/%s%s>%s%s</a></li>" % (WEBSITE, TMPDIR, jobid, jobid, extension, jobid, extension) 412 elif calctype=="apbs": 413 if have_opal: 414 for i in range(0,len(filelist)): 415 if filelist[i]._name[-3:]==".dx": 416 # compressing APBS OpenDX output files 417 currentpath = os.getcwd() 418 zipjobid = filelist[i]._name.split("-")[0] 419 dxfilename = '%s%s%s/%s' % (INSTALLDIR, TMPDIR, zipjobid, filelist[i]._name) 420 urllib.urlretrieve(filelist[i]._url, dxfilename) 421 os.chdir('%s%s%s' % (INSTALLDIR, TMPDIR, zipjobid)) 422 # making both the dx file and the compressed file (.gz) available in the directory 423 syscommand = 'cp %s dxbkupfile' % (filelist[i]._name) 424 os.system(syscommand) 425 syscommand = 'gzip -9 ' + filelist[i]._name 426 os.system(syscommand) 427 syscommand = 'mv dxbkupfile %s' % (filelist[i]._name) 428 os.system(syscommand) 429 outputfilezip = filelist[i]._name + '.gz' 430 431 pqrfilename = '%s%s%s/%s.pqr' % (INSTALLDIR, TMPDIR, zipjobid, zipjobid) 432 cubefilename = '%s%s%s/%s.cube' % (INSTALLDIR, TMPDIR, zipjobid, zipjobid) 433 434 # making both the cube file and the compressed file (.gz) available in the directory 435 createcube(dxfilename, pqrfilename, cubefilename) 436 cubefilebasename = os.path.basename(cubefilename) 437 438 syscommand = 'cp %s cubebkupfile' % cubefilebasename 439 os.system(syscommand) 440 syscommand = 'gzip -9 ' + cubefilebasename 441 os.system(syscommand) 442 syscommand = 'mv cubebkupfile %s' % cubefilebasename 443 os.system(syscommand) 444 os.chdir(currentpath) 445 outputcubefilezip = cubefilebasename+".gz" 446 447 print "<li><a href=%s%s%s/%s>%s</a></li>" % (WEBSITE, TMPDIR, zipjobid, outputfilezip, outputfilezip) 448 print "<li><a href=%s%s%s/%s>%s</a></li>" % (WEBSITE, TMPDIR, zipjobid, outputcubefilezip, outputcubefilezip) 449 450 else: 451 outputfilelist = glob.glob('%s%s%s/%s-*.dx' % (INSTALLDIR, TMPDIR, jobid, jobid)) 452 for dxfile in outputfilelist: 453 # compressing APBS OpenDX output files 454 currentpath = os.getcwd() 455 workingpath = os.path.dirname(dxfile) 456 os.chdir(workingpath) 457 # making both the dx file and the compressed file (.gz) available in the directory 458 syscommand = 'cp %s dxbkupfile' % (os.path.basename(dxfile)) 459 os.system(syscommand) 460 syscommand = 'gzip -9 ' + os.path.basename(dxfile) 461 os.system(syscommand) 462 syscommand = 'mv dxbkupfile %s' % (os.path.basename(dxfile)) 463 os.system(syscommand) 464 os.chdir(currentpath) 465 outputfilezip = dxfile+".gz" 466 467 468 469 cubefilename = '%s%s%s/%s.cube' % (INSTALLDIR, TMPDIR, jobid, jobid) 470 pqrfilename = '%s%s%s/%s.pqr' % (INSTALLDIR, TMPDIR, jobid, jobid) 471 472 473 createcube(dxfile, pqrfilename, cubefilename) 474 475 print "<li><a href=%s%s%s/%s>%s</a></li>" % (WEBSITE, TMPDIR, jobid, os.path.basename(outputfilezip), os.path.basename(outputfilezip)) 476 477 outputcubefilelist = glob.glob('%s%s%s/%s.cube' % (INSTALLDIR, TMPDIR, jobid, jobid)) 478 for cubefile in outputcubefilelist: 479 # compressing cube output file 480 currentpath = os.getcwd() 481 os.chdir(workingpath) 482 # making both the cube file and the compressed file (.gz) available in the directory 483 syscommand = 'cp %s cubebkupfile' % (os.path.basename(cubefile)) 484 os.system(syscommand) 485 syscommand = 'gzip -9 ' + os.path.basename(cubefile) 486 os.system(syscommand) 487 syscommand = 'mv cubebkupfile %s' % (os.path.basename(cubefile)) 488 os.system(syscommand) 489 os.chdir(currentpath) 490 outputcubefilezip = cubefile+".gz" 491 492 print "<li><a href=%s%s%s/%s>%s</a></li>" % (WEBSITE, TMPDIR, jobid, os.path.basename(outputcubefilezip), os.path.basename(outputcubefilezip)) 493 494 logopts['queryAPBS'] = '|'.join(queryString) 495 496 if calctype=="pdb2pqr": 497 if have_opal: 498 outputfilelist = [] 499 for i in range(0,len(filelist)): 500 if filelist[i]._name.endswith((".DAT", ".txt")): 501 outputfilelist.append((filelist[i]._url, os.path.basename(filelist[i]._name))) 502 #print "<li><a href=%s>%s</a></li>" % (filelist[i]._url, filelist[i]._name) 503 if outputfilelist: 504 print "</ul></li>" 505 print "<li>PDB2PKA files<ul>" 506 for outputfile in outputfilelist: 507 print "<li><a href=%s>%s</a></li>" % (outputfile[0], outputfile[1]) 508 else: 509 outputfilelist = glob.glob('%s%s%s/pdb2pka_output/*.DAT' % (INSTALLDIR, TMPDIR, jobid)) 510 outputfilelist.extend(glob.glob('%s%s%s/pdb2pka_output/*.txt' % (INSTALLDIR, TMPDIR, jobid))) 511 outputfilelist = [os.path.basename(outputfile) for outputfile in outputfilelist] 512 if outputfilelist: 513 print "</ul></li>" 514 print "<li>PDB2PKA files<ul>" 515 for outputfile in outputfilelist: 516 print "<li><a href=%s%s%s/pdb2pka_output/%s>%s</a></li>" % (WEBSITE, TMPDIR, jobid, outputfile, outputfile) 517 518 print "</ul></li>" 519 print "<li>Runtime and debugging information<ul>" 520 521 if have_opal: 522 stdouturl = resp._stdOut 523 stderrurl = resp._stdErr 524 else: 525 stdouturl = "%s%s%s/%s_stdout.txt" % (WEBSITE, TMPDIR, jobid, calctype) 526 stderrurl = "%s%s%s/%s_stderr.txt" % (WEBSITE, TMPDIR, jobid, calctype) 527 528 print "<li><a href=%s>Program output (stdout)</a></li>" % stdouturl 529 print "<li><a href=%s>Program errors and warnings (stderr)</a></li>" % stderrurl 530 531 532 print "</ul></li></ul>" 533 534 535 #if have_opal: 536 # resp = appServicePort.getOutputs(getOutputsRequest(jobid)) 537 # for opalfile in resp._outputFile: 538 # if opalfile._name[-8:]!="-input.p": 539 # print "<li><a href=%s>%s</a></li>" % (opalfile._url, opalfile._name) 540 # print "<li><a href=%s>Standard output</a></li>" % (resp._stdOut) 541 # print "<li><a href=%s>Standard error</a></li>" % (resp._stdErr) 542 #else: 543 # for line in cp[1:]: 544 # line = os.path.basename(line) 545 # if line[-8:]!="-input.p": 546 # if line[-11:]=="_stdout.txt": 547 # printname = "Standard output" 548 # elif line[-11:]=="_stderr.txt": 549 # printname = "Standard error" 550 # else: 551 # printname = line 552 # print "<li><a href=%s>%s</a></li>" % (WEBSITE+TMPDIR+jobid+"/"+line,printname) 553 554 if calctype=="pdb2pqr" and apbs_input and HAVE_APBS: 555 print "</ul></p><hr><p><b><a href=%s>Click here</a> to run APBS with your results.</b></p>" % nexturl 556 elif calctype=="apbs": 557 #print "</ul></p><hr><p><b><a href=%s>Click here</a> to visualize your results in Jmol.</b></p>" % nexturl 558 print "</ul></p><hr><p><b>Visualize your results online:" 559 print "<ul> <li><a href=%s>3Dmol</a></li><li><a href=%s>Jmol</a></li></ul>" % (url_3dmol, url_jmol) 560 561 elif progress == "error": 562 print "There was an error with your query request. This page will not refresh." 563 564 print "</ul></li>" 565 print "<li>Runtime and debugging information<ul>" 566 567 if have_opal: 568 resp = appServicePort.getOutputs(getOutputsRequest(jobid)) 569 stdouturl = resp._stdOut 570 stderrurl = resp._stdErr 571 572 else: 573 stdouturl = "%s%s%s/%s_stdout.txt" % (WEBSITE, TMPDIR, jobid, calctype) 574 stderrurl = "%s%s%s/%s_stderr.txt" % (WEBSITE, TMPDIR, jobid, calctype) 575 576 print "<li><a href=%s>Program output (stdout)</a></li>" % stdouturl 577 print "<li><a href=%s>Program errors and warnings (stderr)</a></li>" % stderrurl 578 579 print "</ul></li></ul>" 580 581 if have_opal: 582 print " <br />If your job has been running for a prolonged period of time and failed with no reason listed in the standard out or standard error, then the job probably timed out and was terminated by the system.<br />" 583 584 print '<br />If you are having trouble running PDB2PQR on the webserver, please download the <a href="http://www.poissonboltzmann.org/docs/downloads/">command line version of PDB2PQR</a> and run the job from there.' 585 586 587 588 elif progress == "running": 589 print "Page will refresh in %d seconds<br />" % refresh 590 print "<HR>" 591 592 if not have_opal: 593 print "</ul></li>" 594 print "<li>Runtime and debugging information<ul>" 595 stdouturl = "%s%s%s/%s_stdout.txt" % (WEBSITE, TMPDIR, jobid, calctype) 596 stderrurl = "%s%s%s/%s_stderr.txt" % (WEBSITE, TMPDIR, jobid, calctype) 597 print "<li><a href=%s>Program output (stdout)</a></li>" % stdouturl 598 print "<li><a href=%s>Program errors and warnings (stderr)</a></li>" % stderrurl 599 print "</ul></li></ul>" 600 601 print "<small>Your results will appear at <a href=%s>this page</a>. If you want, you can bookmark it and come back later (note: results are only stored for approximately 12-24 hours).</small>" % resultsurl 602 elif progress == "version_mismatch": 603 print "The versions of APBS on the local server and on the Opal server do not match, so the calculation could not be completed" 604 605 print "</P>" 606 print "<script type=\"text/javascript\">" 607 for key in logopts: 608 print getEventTrackingString('queryData', key, logopts[key]), 609 #print "_gaq.push(['_trackPageview', '/main_cgi/has_%s_%s.html']);" % (key, logopts[key]) 610 print "</script>" 611 print "</div> <!--end content div-->" 612 print "</BODY>" 613 print "</HTML>" 614 615if __name__ == "__main__" and os.environ.has_key("REQUEST_METHOD"): 616 """ Determine if called from command line or CGI """ 617 refresh=30 618 619 if not form.has_key("jobid") and form["calctype"].value=="pdb2pqr": 620 print "Content-type: text/html\n\n" 621 print printheader("PDB2PQR Job Status - Error") 622 text="<BODY>\n" 623 text+="\t<H2>Missing jobid field</H2>\n" 624 text+="\t<P>Your request url is missing the jobid field</P>\n" 625 text += "<script type=\"text/javascript\">" 626 text += "var gaJsHost = ((\"https:\" == document.location.protocol) ? \"https://ssl.\" : \"http://www.\");" 627 text += "document.write(unescape(\"%3Cscript src=\'\" + gaJsHost + \"google-analytics.com/ga.js\' type=\'text/javascript\'%3E%3C/script%3E\"));" 628 text += "</script>" 629 text += "<script type=\"text/javascript\">" 630 text += "try {" 631 text += "var pageTracker = _gat._getTracker(\"UA-11026338-3\");" 632 text += "pageTracker._trackPageview();" 633 text += "} catch(err) {}</script>" 634 text+="</BODY>\n</HTML>" 635 print text 636 sys.exit(2) 637 638 639 if (form["calctype"].value=="pdb2pqr" and HAVE_PDB2PQR_OPAL) or (form["calctype"].value=="apbs" and APBS_OPAL_URL!=""): 640 have_opal = True 641 from AppService_client import AppServiceLocator, queryStatusRequest, getOutputsRequest 642 else: 643 have_opal = False 644 645 mainCGI() 646