Package omeroweb :: Package webemdb :: Module views
[hide private]
[frames] | no frames]

Source Code for Module omeroweb.webemdb.views

   1  from django.http import HttpResponseRedirect, HttpResponse, Http404 
   2  from django.core.urlresolvers import reverse 
   3  from django.shortcuts import render_to_response 
   4  from django.utils import simplejson 
   5  from django.core.servers.basehttp import FileWrapper 
   6  from django.conf import settings 
   7  from django.core.cache import cache  
   8   
   9  from omeroweb.webgateway.views import getBlitzConnection, _session_logout 
  10  from omeroweb.webgateway import views as webgateway_views 
  11  import settings 
  12  import logging 
  13  import traceback 
  14  import omero 
  15  import omero.constants 
  16  import omero.scripts 
  17  from omero.rtypes import rstring, rint, rlong, robject, unwrap, rdouble 
  18  from omero.sys import Parameters, Filter 
  19  import omero.util.script_utils as scriptUtil 
  20   
  21  import os 
  22  from django.core.servers.basehttp import FileWrapper 
  23  import random 
  24  import math 
  25  from numpy import zeros     # numpy for doing local projections 
  26   
  27  logger = logging.getLogger('webemdb') 
  28   
  29  PUBLICATION_NAMESPACE = "openmicroscopy.org/omero/emdb/publication" 
  30  RESOLUTION_NAMESPACE = "openmicroscopy.org/omero/emdb/resolutionByAuthor"   
  31  FITTED_PDB_NAMESPACE = "openmicroscopy.org/omero/emdb/fittedPDBEntry"       # distinguish fittedPDBEntries from other pdbEntries (docked) 
  32   
  33   
  34  EMAN2_IMPORTED = False 
  35  try: 
  36      from EMAN2 import * 
  37      EMAN2_IMPORTED = True 
  38  except: 
  39      logger.warning("Failed to import EMAN2. Some features of webemdb will not be supported.") 
  40   
  41   
42 -def eman(request, imageId, **kwargs):
43 44 if not EMAN2_IMPORTED: 45 return HttpResponse("EMAN2 not found") 46 47 conn = getConnection(request) 48 49 rawPixelStore = conn.createRawPixelsStore() 50 queryService = conn.getQueryService() 51 52 query_string = "select p from Pixels p join fetch p.image as i join fetch p.pixelsType where i.id='%s'" % imageId 53 pixels = queryService.findByQuery(query_string, None) 54 55 theZ, theC, theT = (0,0,0) 56 bypassOriginalFile = True 57 rawPixelStore.setPixelsId(pixels.getId().getValue(), bypassOriginalFile) 58 plane2D = scriptUtil.downloadPlane(rawPixelStore, pixels, theZ, theC, theT) 59 60 sizeX = pixels.getSizeX().getValue() 61 sizeY = pixels.getSizeY().getValue() 62 sizeZ = 1 63 #em = EMData() 64 65 em = EMNumPy.numpy2em(plane2D) 66 67 f = kwargs['filter'] 68 if f == "fft": 69 filterName = "basis.fft" 70 filterParamMap = {"dir": 1, } 71 em.process_inplace(filterName, filterParamMap) 72 elif f == "median": 73 if 'radius' in kwargs: 74 filterParamMap = {"radius": int(kwargs['radius'])} 75 em.process_inplace("eman1.filter.median", filterParamMap) 76 else: em.process_inplace("eman1.filter.median") 77 elif f == "log": 78 em.process_inplace("math.log") 79 80 tempdir = settings.FILE_UPLOAD_TEMP_DIR 81 tempJpg = os.path.join(tempdir, ('%s.emanFilter.jpg' % (conn._sessionUuid))).replace('\\','/') 82 83 em.write_image(tempJpg) 84 85 originalFile_data = FileWrapper(file(tempJpg)) 86 87 rsp = HttpResponse(originalFile_data) 88 89 rsp['Content-Type'] = "image/jpg" 90 91 return rsp
92 93
94 -def script_run(request, scriptId):
95 """ 96 Runs a script using values in a POST 97 """ 98 conn = getConnection(request) 99 #print dir(conn) 100 scriptService = conn.getScriptService() 101 102 inputMap = {} 103 104 sId = long(scriptId) 105 106 params = scriptService.getParams(sId) 107 scriptName = params.name.replace("_", " ") 108 109 for key, param in params.inputs.items(): 110 if key in request.POST: 111 value = request.POST[key] 112 if len(value) == 0: continue 113 prototype = param.prototype 114 pclass = prototype.__class__ 115 if pclass == omero.rtypes.RListI: 116 valueList = [] 117 listClass = omero.rtypes.rstring 118 l = prototype.val # list 119 if len(l) > 0: # check if a value type has been set (first item of prototype list) 120 listClass = l[0].getValue().__class__ 121 if listClass == int(1).__class__: 122 listClass = omero.rtypes.rint 123 if listClass == long(1).__class__: 124 listClass = omero.rtypes.rlong 125 126 for v in value.split(","): 127 try: 128 obj = listClass(str(v.strip())) # seem to need the str() for some reason 129 except: 130 # print "Invalid entry for '%s' : %s" % (key, v) 131 continue 132 if isinstance(obj, omero.model.IObject): 133 valueList.append(omero.rtypes.robject(obj)) 134 else: 135 valueList.append(obj) 136 inputMap[key] = omero.rtypes.rlist(valueList) 137 138 elif pclass == omero.rtypes.RMapI: 139 # TODO: Handle maps same way as lists. 140 valueMap = {} 141 m = prototype.val # check if a value type has been set for the map 142 143 else: 144 try: 145 inputMap[key] = pclass(value) 146 except: 147 # print "Invalid entry for '%s' : %s" % (key, value) 148 continue 149 150 151 proc = scriptService.runScript(sId, inputMap, None) 152 153 # E.g. ProcessCallback/4ab13b23-22c9-4b5f-9318-40f9a1acc4e9 -t:tcp -h 10.37.129.2 -p 53154:tcp -h 10.211.55.2 -p 53154:tcp -h 10.12.1.230 -p 53154 154 request.session.modified = True # allows us to modify session... 155 i = 0 156 while str(i) in request.session['processors']: 157 i += 1 158 key = str(i) 159 request.session['processors'][key] = str(proc) 160 161 # TODO - return the input map, to display what the user entered. 162 return render_to_response('webemdb/scripts/script_running.html', {'scriptName': scriptName, 'jobId': key})
163 164
165 -def script_results(request, jobId):
166 167 if jobId not in request.session['processors']: 168 return HttpResponse("Results not found (may have already been returned)") 169 170 request.session.modified = True # allows us to modify session... 171 procString = request.session['processors'][jobId] 172 del request.session['processors'][jobId] # delete this, since we cannot use it again to get the results 173 174 conn = getConnection(request) 175 client = conn.c 176 177 proc = omero.grid.ScriptProcessPrx.checkedCast(client.ic.stringToProxy(procString)) 178 179 try: 180 cb = omero.scripts.ProcessCallbackI(client, proc) 181 while not cb.block(1000): # ms. 182 pass 183 cb.close() 184 results = proc.getResults(0) # ms 185 finally: 186 proc.close(False) 187 188 message = None 189 # Handle the expected 'Message' in results. 190 if 'Message' in results: 191 message = results['Message'].getValue() 192 193 # if we have stdout or stderr, download the file and return it. 194 rawFileService = conn.createRawFileStore() 195 queryService = conn.getQueryService() 196 stdout = None 197 stderr = None 198 if 'stdout' in results: 199 origFile = results['stdout'].getValue() 200 fileId = origFile.getId().getValue() 201 stdout = scriptUtil.readFromOriginalFile(rawFileService, queryService, fileId) 202 if 'stderr' in results: 203 origFile = results['stderr'].getValue() 204 fileId = origFile.getId().getValue() 205 stderr = scriptUtil.readFromOriginalFile(rawFileService, queryService, fileId) 206 207 # look for any other string values and images in results... 208 resultMap = {} 209 strings = [] 210 images = [] 211 for key, value in results.items(): 212 if key not in ["Message", "stdout", "stderr"]: 213 obj = value.getValue() 214 # if rstring, value is "string" 215 if type(obj) == type(""): 216 strings.append({"key":key, "value": obj }) 217 elif type(obj) == omero.model.ImageI: 218 images.append({"key":key, "name": obj.getName().getValue(), "id": obj.getId().getValue() }) 219 elif type(obj) == omero.model.DatasetI: 220 resultMap['dataset'] = {"name": obj.getName().getValue(), "id": obj.getId().getValue()} 221 resultMap['strings'] = strings 222 images.sort(key=lambda i: i["id"]) 223 resultMap['images'] = images 224 225 # html will give users links to any Image, stdout, stderr and any strings returned in results 226 return render_to_response('webemdb/scripts/script_results.html', 227 {'message': message, 'resultMap': resultMap, 'stdout': stdout, 'stderr': stderr})
228 229
230 -def script_form(request, scriptId):
231 """ 232 Generates an html form for the parameters of a defined script. 233 """ 234 conn = getConnection(request) 235 scriptService = conn.getScriptService() 236 237 params = scriptService.getParams(long(scriptId)) 238 if params == None: 239 return HttpResponse() 240 241 paramData = {} 242 243 paramData["id"] = long(scriptId) 244 paramData["name"] = params.name.replace("_", " ") 245 paramData["description"] = params.description 246 paramData["authors"] = ", ".join([a for a in params.authors]) 247 paramData["contact"] = params.contact 248 paramData["version"] = params.version 249 paramData["institutions"] = ", ".join([i for i in params.institutions]) 250 251 inputs = [] # use a list so we can sort by 'grouping' 252 for key, param in params.inputs.items(): 253 i = {} 254 i["name"] = key.replace("_", " ") 255 i["key"] = key 256 if not param.optional: 257 i["required"] = True 258 i["description"] = param.description 259 if param.min: 260 i["min"] = param.min.getValue() 261 if param.max: 262 i["max"] = param.max.getValue() 263 if param.values: 264 i["options"] = [v.getValue() for v in param.values.getValue()] 265 pt = unwrap(param.prototype) 266 #print key, pt.__class__ 267 if pt.__class__ == type(True): 268 i["boolean"] = True 269 elif pt.__class__ == type(0) or pt.__class__ == type(long(0)): 270 i["number"] = "number" # will stop the user entering anything other than numbers. 271 elif pt.__class__ == type(float(0.0)): 272 #print "Float!" 273 i["number"] = "float" 274 i["prototype"] = unwrap(param.prototype) # E.g "" (string) or [0] (int list) or 0.0 (float) 275 i["grouping"] = param.grouping 276 inputs.append(i) 277 inputs.sort(key=lambda i: i["grouping"]) 278 paramData["inputs"] = inputs 279 280 return render_to_response('webemdb/scripts/script_form.html', {'paramData': paramData})
281 282
283 -def dataset_stack(request, datasetId):
284 """ 285 Downloads a dataset of single-plane images as a .mrc file 286 """ 287 conn = getConnection(request) 288 289 queryService = conn.getQueryService() 290 rawPixelStore = conn.createRawPixelsStore() 291 292 def getImagePlane(imageId): 293 query_string = "select p from Pixels p join fetch p.image as i join fetch p.pixelsType where i.id='%s'" % imageId 294 pixels = queryService.findByQuery(query_string, None) 295 theZ, theC, theT = (0,0,0) 296 bypassOriginalFile = True 297 rawPixelStore.setPixelsId(pixels.getId().getValue(), bypassOriginalFile) 298 plane2D = scriptUtil.downloadPlane(rawPixelStore, pixels, theZ, theC, theT) 299 return plane2D
300 301 dataset = conn.getObject("Dataset", datasetId) 302 303 em = None 304 for z, i in enumerate(dataset.listChildren()): 305 plane = getImagePlane(i.getId()) 306 e = EMNumPy.numpy2em(plane) 307 308 if em == None: 309 sizeY, sizeX = plane.shape 310 sizeZ = dataset.countChildren() 311 em = EMData(sizeY, sizeX, sizeZ) # x,y,z or y,x,z ? 312 313 em.insert_clip(e,(0,0,z)) 314 315 tempdir = settings.FILE_UPLOAD_TEMP_DIR 316 tempMrc = os.path.join(tempdir, ('%sdataset_stack.mrc' % (conn._sessionUuid))).replace('\\','/') 317 em.write_image(tempMrc) 318 319 originalFile_data = FileWrapper(file(tempMrc)) 320 rsp = HttpResponse(originalFile_data) 321 rsp['Content-Type'] = 'application/octet-stream' 322 # this tells the browser to give the user a 'download' dialog 323 rsp['Content-Disposition'] = 'attachment; filename=%s.mrc' % (dataset.getName().replace(" ","_")) 324 return rsp 325 326
327 -def projection(request, imageId, projkey):
328 """ Simply add the projkey (intmean, intsum or intmax) to the request and delegate to webgateway render_image() """ 329 330 """ NB: Not sure if we should be modifying request.REQUEST since http://docs.djangoproject.com/en/1.1/ref/request-response/ 331 says 'All attributes except session should be considered read-only.' """ 332 333 conn = getConnection(request) 334 request.REQUEST.dicts += ({'p': projkey},) 335 336 #from django.http import QueryDict 337 #q = QueryDict('', mutable=True) 338 #q.update({'p': projkey}) 339 #request.REQUEST.dicts += (q,) 340 341 return webgateway_views.render_image(request, imageId, 0, 0)
342 343
344 -def projection_axis(request, imageId, axis, get_slice=False):
345 346 conn = getConnection(request) 347 import time 348 349 startTime = time.time() 350 351 x_proj_key = "x_proj_%s" % imageId 352 y_proj_key = "y_proj_%s" % imageId 353 z_proj_key = "z_proj_%s" % imageId 354 x_slice_key = "x_slice_%s" % imageId 355 y_slice_key = "y_slice_%s" % imageId 356 z_slice_key = "z_slice_%s" % imageId 357 358 # see if we have cached the projection we need 359 key = "%s_proj_%s" % (axis, imageId) 360 if get_slice: 361 key = "%s_slice_%s" % (axis, imageId) 362 #print "\n\nchecking cache for array: %s" % key 363 #print " %s secs" % (time.time() - startTime) 364 proj = cache.get(key) 365 366 if proj == None: 367 368 #print "creating cube of data..." 369 #print " %s secs" % (time.time() - startTime) 370 rawPixelStore = conn.createRawPixelsStore() 371 queryService = conn.getQueryService() 372 373 query_string = "select p from Pixels p join fetch p.image as i join fetch p.pixelsType where i.id='%s'" % imageId 374 pixels = queryService.findByQuery(query_string, None) 375 376 theZ, theC, theT = (0,0,0) 377 bypassOriginalFile = True 378 rawPixelStore.setPixelsId(pixels.getId().getValue(), bypassOriginalFile) 379 380 sizeX = pixels.getSizeX().getValue() 381 sizeY = pixels.getSizeY().getValue() 382 sizeZ = pixels.getSizeZ().getValue() 383 384 # create a 3D numpy array, and populate it with data 385 cube = zeros( (sizeZ,sizeY,sizeX) ) 386 theC, theT = (0,0) 387 for theZ in range(sizeZ): 388 plane2D = scriptUtil.downloadPlane(rawPixelStore, pixels, theZ, theC, theT) 389 cube[sizeZ-theZ-1] = plane2D 390 391 # do the 3 projections and 3 central slices while we have the cube - save projections, not cube 392 #print "doing projection" 393 #print " %s secs" % (time.time() - startTime) 394 395 proj_z = zeros( (sizeY,sizeX) ) 396 for z in range(sizeZ): 397 zPlane = cube[z, :, :] 398 proj_z += zPlane 399 slice_z = cube[sizeZ/2, :, :] 400 401 proj_x = zeros( (sizeZ,sizeY) ) 402 for x in range(sizeX): 403 xPlane = cube[:, :, x] 404 proj_x += xPlane 405 slice_x = cube[:, :, sizeX/2] 406 407 proj_y = zeros( (sizeZ,sizeX) ) 408 for y in range(sizeY): 409 yPlane = cube[:, y, :] 410 proj_y += yPlane 411 slice_y = cube[:, sizeY/2, :] 412 413 #print "setting cache" 414 #print " %s secs" % (time.time() - startTime) 415 # save arrays to cache 416 cache.set(x_proj_key, proj_x) 417 cache.set(x_slice_key, slice_x) 418 cache.set(y_proj_key, proj_y) 419 cache.set(y_slice_key, slice_y) 420 cache.set(z_proj_key, proj_z) 421 cache.set(z_slice_key, slice_z) 422 423 if axis == "z": 424 if get_slice: 425 proj = slice_z 426 else: 427 proj = proj_z 428 429 elif axis == "x": 430 if get_slice: 431 proj = slice_x 432 else: 433 proj = proj_x 434 435 elif axis == "y": 436 if get_slice: 437 proj = slice_y 438 else: 439 proj = proj_y 440 441 #print "got 2D plane...", proj.shape 442 #print " %s secs" % (time.time() - startTime) 443 444 tempdir = settings.FILE_UPLOAD_TEMP_DIR 445 tempJpg = os.path.join(tempdir, ('%s.projection.jpg' % (conn._sessionUuid))).replace('\\','/') 446 447 #import matplotlib.pyplot as plt 448 #plt.savefig(tempJpg) 449 450 #import scipy 451 #scipy.misc.imsave(tempJpg, proj) 452 453 em = EMNumPy.numpy2em(proj) 454 em.write_image(tempJpg) 455 456 originalFile_data = FileWrapper(file(tempJpg)) 457 rsp = HttpResponse(originalFile_data) 458 rsp['Content-Type'] = "image/jpg" 459 460 return rsp
461 462
463 -def mapmodelemdb(request, entryId):
464 """ 465 We need to work out the OMERO imageId for the emd_map for this entryId, then call mapmodel(). 466 Do this via project, named entryId etc... 467 """ 468 conn = getConnection(request) 469 470 entryName = str(entryId) 471 project = conn.getObject("Project", attributes={'name':entryName}) 472 473 if project == None: 474 raise Http404 475 476 # find the mrc map image. E.g emd_1003.map In a dataset named same as project E.g. 1003 477 imageMap = get_entry_map(project) 478 return mapmodel(request, imageMap.getId(), entryId)
479 480
481 -def get_entry_map(project):
482 """ 483 For a project, named by entryId (E.g. "1003") this returns the image named "emd_1003.map" in a dataset named "1003" 484 """ 485 entryName = project.getName() 486 imgName = "emd_%s.map" % entryName 487 for d in project.listChildren(): 488 if d.getName() == entryName: 489 for i in d.listChildren(): 490 if i.getName() == imgName: 491 return i
492 493
494 -def mapmodel(request, imageId, entryId=None):
495 """ 496 Shows an image projections, slices etc. 497 """ 498 499 conn = getConnection(request) 500 501 image = conn.getObject("Image", imageId) 502 503 z = image.getSizeZ()/2 504 505 return render_to_response('webemdb/data/mapmodel.html', {'image': image, 'z':z, 'entryId': entryId})
506 507
508 -def image(request, imageId):
509 """ 510 Shows an image preview (single plane), Name, Description etc. links to datasets. 511 """ 512 conn = getConnection(request) 513 514 image = conn.getObject("Image", imageId) 515 516 scriptService = conn.getScriptService() 517 scripts = [] 518 scriptNames = {"/EMAN2/Nonlinear_Anisotropic_Diffusion.py": "IMOD: Nonlinear Anisotropic Diffusion", 519 "/EMAN2/Segger_Segmentation.py": "Segger: Segmentation", 520 "/EMAN2/Eman_Filters.py": "EMAN2: Filtering", 521 "/EMAN2/Ctf_Correction.py": "EMAN2: CTF Correction", 522 "/EMAN2/Run_Spider_Procedure.py": "Spider: Run Procedure"} 523 for path, display in scriptNames.items(): 524 scriptId = scriptService.getScriptID(path) 525 if scriptId and scriptId > 0: 526 s = {} 527 s["name"] = display 528 s["id"] = scriptId 529 scripts.append(s) 530 531 if not image: 532 return render_to_response('webemdb/data/image.html', {'image': image, "scripts": scripts}) 533 default_z = image.getSizeZ()/2 534 535 return render_to_response('webemdb/data/image.html', {'image': image, "scripts": scripts, "default_z": default_z})
536 537
538 -def dataset(request, datasetId):
539 """ 540 Shows the thumbnails in a dataset, provides a link back to EMDB entry (project) 541 """ 542 conn = getConnection(request) 543 544 dataset = conn.getObject("Dataset", datasetId) 545 546 entryId = None 547 548 # look for parent project that has EMDB entry name (EMDB ID) 549 for p in dataset.listParents(): 550 try: 551 emdbId = long(p.getName()) 552 entryId = str(emdbId) 553 break 554 except: 555 pass 556 557 # add some scripts that we can run on a dataset 558 scriptService = conn.getScriptService() 559 scripts = [] 560 scriptNames = {"/EMAN2/Nonlinear_Anisotropic_Diffusion.py": "IMOD: Nonlinear Anisotropic Diffusion", 561 "/EMAN2/Segger_Segmentation.py": "Segger: Segmentation", 562 "/EMAN2/Eman_Filters.py": "EMAN2: Filtering", 563 "/EMAN2/Ctf_Correction.py": "EMAN2: CTF Correction", 564 "/EMAN2/Run_Spider_Procedure.py": "Spider: Run Procedure"} 565 for path, display in scriptNames.items(): 566 scriptId = scriptService.getScriptID(path) 567 if scriptId and scriptId > 0: 568 s = {} 569 s["name"] = display 570 s["id"] = scriptId 571 scripts.append(s) 572 573 # gets list of {"id":annotationId, "name":fileName, "text":fileText} for .spf files 574 spfFiles = getSpfFiles(conn.getQueryService(), conn.createRawFileStore()) 575 576 return render_to_response('webemdb/data/dataset.html', {'dataset': dataset, 'entryId': entryId, 'scripts': scripts, 'spfFiles':spfFiles})
577 578
579 -def data(request, entryId):
580 conn = getConnection(request) 581 582 entryName = str(entryId) 583 project = conn.getObject("Project", attributes={'name':entryName}) 584 585 # only want the first few images from each dataset 586 p = omero.sys.Parameters() 587 p.map = {} 588 f = omero.sys.Filter() 589 f.limit = rint(5) 590 f.offset = rint(0) 591 p.theFilter = f 592 593 datasets = [] 594 entryId = project.getName() 595 for d in project.listChildren(): 596 ds = {} 597 ds["getId"] = str(d.getId()) 598 name = d.getName() 599 if name == entryId: continue # this dataset contains the map, not associated data. 600 ds["getName"] = name 601 ds["getDescription"] = d.getDescription() 602 ds["countChildren"] = d.countChildren() 603 ds["listChildren"] = d.listChildren(params=p) 604 datasets.append(ds) 605 606 if project == None: 607 # project not found (None) handled by template 608 return render_to_response('webemdb/data/data.html', {'project':project}) 609 610 return render_to_response('webemdb/data/data.html', {'project':project, 'datasets': datasets})
611 612
613 -def entry (request, entryId):
614 conn = getConnection(request) 615 616 entryName = str(entryId) 617 project = conn.getObject("Project", attributes={'name':entryName}) 618 619 if project == None: 620 # project not found (None) handled by template 621 return render_to_response('webemdb/entries/entry.html', {'project':project}) 622 623 # find the mrc map image. E.g emd_1003.map In a dataset named same as project E.g. 1003 624 img = get_entry_map(project) 625 mrcMap = None 626 smallMap = None 627 segFiles = [] # Segger file.seg 628 namespace = omero.constants.namespaces.NSCOMPANIONFILE 629 smallMapName = "small_%s.map" % entryName 630 if img: 631 imgName = img.getName() 632 for a in img.listAnnotations(): 633 if a.getFileName().endswith(".seg"): 634 segFiles.append(a) 635 elif imgName == a.getFileName() and a.getNs() == namespace: 636 mrcMap = a 637 elif smallMapName == a.getFileName(): 638 smallMap = a 639 640 xml = None 641 gif = None 642 bit = None 643 pdbs = [] 644 fittedPdbs = [] 645 xmlName = "emd-%s.xml" % entryName 646 gifName = "400_%s.gif" % entryName 647 bitName = "%s.bit" % entryName 648 sizeWarning = False 649 650 for a in project.listAnnotations(): 651 try: # not all annotations have getFileName() E.g. comment annotations 652 if xmlName == a.getFileName(): 653 xml = a 654 elif gifName == a.getFileName(): 655 gif = a 656 elif bitName == a.getFileName(): 657 bit = a 658 if bit.getFileSize() > 2000000: 659 sizeWarning = True 660 elif a.getFileName().endswith(".pdb.gz"): 661 if a.getNs() == FITTED_PDB_NAMESPACE: 662 fittedPdbs.append(a) 663 else: 664 pdbs.append(a) 665 except: 666 pass 667 668 data = project.countChildren() > 1 669 670 return render_to_response('webemdb/entries/entry.html', 671 {'project':project, 'xml': xml, 'gif': gif, 'img': img, 'map': mrcMap, 'smallMap': smallMap, 'bit': bit, 'pdbs': pdbs, 672 'fittedPdbs': fittedPdbs, 'sizeWarning':sizeWarning, 'data': data, 'segFiles': segFiles})
673 674
675 -def oa_viewer(request, fileId):
676 """ Returns simply the <applet> element of Open Astex Viewer, for loading into another page. 677 The <applet> contains a script that will load a bit mask, identified by fileId """ 678 679 conn = getConnection(request) 680 681 ann = conn.getObject("Annotation", long(fileId)) 682 # determine mapType by name 683 mapType = "map" 684 if ann: 685 fileName = ann.getFileName() 686 if fileName.endswith(".bit"): 687 mapType = "bit" 688 689 return render_to_response('webemdb/entries/oa_viewer.html', {'fileId': fileId, 'mapType': mapType}) 690 691
692 -def viewport(request, imageId):
693 conn = getConnection(request) 694 return render_to_response('webemdb/entries/viewport.html', {'imageId': imageId})
695 696
697 -def gif (request, entryId):
698 """ 699 Looks up the preview gif E.g. "80_1001.gif" for the specified entry, based on name of originalfile. 700 701 TODO: This method gets the file via it's project, because it's wrapped nicely. Same as def file() below... 702 """ 703 conn = getConnection(request) 704 705 entryName = str(entryId) 706 project = conn.getObject("Project", attributes={'name':entryName}) 707 708 if project == None: return HttpResponse() 709 710 # get the file by name 711 gif = None 712 gifName = "80_%s.gif" % entryId 713 for a in project.listAnnotations(): 714 try: 715 if a.getFileName() == gifName: 716 gif = a 717 except: 718 pass 719 720 if gif: 721 return getFile(request, gif.getId()) 722 else: 723 return HttpResponse()
724 725
726 -def getFile (request, fileId):
727 """ 728 Gets the file by Id and returns it according to mime type for display. 729 """ 730 conn = getConnection(request) 731 732 # get the file by ID 733 ann = None 734 ann = conn.getObject("Annotation", long(fileId)) 735 736 # determine mime type to assign 737 if ann: 738 739 fileName = ann.getFileName() 740 mimetype = "text/plain" 741 742 if fileName.endswith(".bit") or fileName.endswith(".pdb.gz") or fileName.endswith(".map") or fileName.endswith(".seg"): 743 mimetype='application/octet-stream' 744 if fileName.endswith(".xml"): mimetype='text/xml' 745 if fileName.endswith(".gif"): mimetype='image/gif' 746 747 # file_data = ann.getFile() 748 # return HttpResponse(file_data, mimetype=mimetype) 749 750 # if the file data is large, we will have a temp file 751 tempdir = settings.FILE_UPLOAD_TEMP_DIR 752 temp = os.path.join(tempdir, ('%i-%s.download' % (ann.file.id.val, conn._sessionUuid))).replace('\\','/') 753 logger.info("temp path: %s" % str(temp)) 754 f = open(str(temp),"wb") 755 for piece in ann.getFileInChunks(): 756 f.write(piece) 757 f.seek(0) 758 f.close() 759 760 originalFile_data = FileWrapper(file(temp)) 761 762 rsp = HttpResponse(originalFile_data) 763 764 rsp['Content-Type'] = mimetype 765 rsp['Content-Length'] = ann.getFileSize() 766 # this tells the browser to give the user a 'download' dialog 767 rsp['Content-Disposition'] = 'attachment; filename=%s' % (ann.getFileName().replace(" ","_")) 768 769 return rsp 770 771 return HttpResponse()
772 773
774 -def logout (request):
775 """ Shouldn't ever be used (public db)""" 776 _session_logout(request, request.session['server']) 777 try: 778 del request.session['username'] 779 except KeyError: 780 logger.error(traceback.format_exc()) 781 try: 782 del request.session['password'] 783 except KeyError: 784 logger.error(traceback.format_exc()) 785 return HttpResponseRedirect(reverse('webemdb_loggedout'))
786
787 -def loggedout (request):
788 return render_to_response('webemdb/loggedout.html', {})
789
790 -def about (request):
791 return render_to_response('webemdb/about.html', {})
792
793 -def index (request):
794 """ Show a selection of the latest EMDB entries """ 795 conn = getConnection(request) 796 797 entryIds = [] # names of projects 798 for p in conn.listProjects(): 799 try: 800 # make sure we only list projects that are emdb entries "1001" etc 801 int(p.getName()) 802 entryIds.append(p.getName()) 803 except: pass 804 entryIds.sort() 805 entryIds.reverse() 806 # truncate. 807 lastIds = entryIds[:5] 808 809 if len(entryIds) > 0: 810 randomIds = [random.choice(entryIds) for i in range(10)] 811 else: randomIds = [] 812 813 projects = [] 814 for entryName in lastIds: 815 p = conn.getObject("Project", attributes={'name':entryName}) 816 rows = p.getDescription().split("\n") 817 title = rows[0] 818 if len(rows) > 1: sample = rows[1] 819 else: sample = "" 820 e = {"id": entryName, "title": title, "sample": sample } 821 projects.append(e) 822 823 return render_to_response('webemdb/index.html', {'projects': projects, 'entryCount': len(entryIds), 'randomIds': randomIds})
824 825
826 -def autocompleteQuery(request):
827 """ 828 Returns json data for autocomplete. Search terms must be provided in the request "GET". 829 E.g. returns a list of ("1003": "Title") results for entries that start with numbers specified. 830 """ 831 conn = getConnection(request) 832 qs = conn.getQueryService() 833 834 # limit the number of results we return 835 p = omero.sys.Parameters() 836 p.map = {} 837 f = omero.sys.Filter() 838 f.limit = rint(15) 839 f.offset = rint(0) 840 p.theFilter = f 841 842 projects = [] 843 844 entryText = request.REQUEST.get('entry') 845 if entryText: 846 query = "select p from Project as p where p.name like '%s%s' order by p.name" % (entryText, "%") # like '123%' 847 projects = qs.findAllByQuery(query, p) 848 849 results = [] 850 851 for p in projects: 852 entryId = p.getName().getValue() 853 desc = p.getDescription().getValue() 854 title, sample = desc.split("\n") 855 results.append((entryId, title)) 856 857 return HttpResponse(simplejson.dumps(results), mimetype='application/javascript')
858 859
860 -def search(request):
861 862 conn = getConnection(request) 863 864 qs = conn.getQueryService() 865 import omero.model 866 searchTerm = request.REQUEST.get('search') 867 868 # set up pagination 869 page = int(request.REQUEST.get('page', 1)) # 1-based 870 resultsPerPage = 20 871 #f.limit = rint(resultsPerPage * page) 872 #f.offset = rint(resultsPerPage * (page-1)) 873 874 p = omero.sys.Parameters() 875 p.map = {} 876 f = omero.sys.Filter() 877 f.limit = rint(5) 878 f.offset = rint(0) 879 p.theFilter = f 880 881 results = [] 882 if searchTerm: 883 projects = qs.findAllByFullText('Project', "file.contents:%s" % searchTerm, p) 884 for p in projects: 885 entryId = p.getName().getValue() 886 desc = p.getDescription().getValue() 887 title, sample = desc.split("\n") 888 results.append({"entryId":entryId, "title": title, "sample": sample}) 889 890 891 return render_to_response('webemdb/browse/search.html', {'searchString': searchTerm, 'results': results, 'nextPage': page+1 })
892 893
894 -def getSpfFiles(queryService, rawFileService):
895 """ list original files ending with .spf and get text for each, but provide the annotation ID (same as Insight) 896 returns a list of (id, name, text)""" 897 898 query = "select a from Annotation a join fetch a.file as f where f.name like '%.spf'" 899 900 annotations = queryService.findAllByQuery(query, None) 901 902 spfFiles = [] 903 904 for a in annotations: 905 aId = a.getId().getValue() 906 fileName = a.file.getName().getValue() 907 fileId = a.file.getId().getValue() 908 text = scriptUtil.readFromOriginalFile(rawFileService, queryService, fileId) 909 spfFiles.append({"id": aId, "name": fileName, "text": text}) 910 911 return spfFiles
912
913 -def entries (request):
914 915 conn = getConnection(request) 916 qs = conn.getQueryService() 917 918 sortString = "" # make a string of the current sort, to use in pagination links. E.g. &sort=entry&order=reverse 919 sortBy = request.REQUEST.get('sort', 'entry') 920 if sortBy == 'resolution': 921 order = "a.doubleValue" 922 sortString += "&sort=resolution" 923 elif sortBy == 'title': 924 order = "p.description" 925 sortString += "&sort=title" 926 elif sortBy == 'entry': 927 order = "p.name" 928 sortString += "&sort=entry" 929 930 desc = "" 931 if "reverse" == request.REQUEST.get('order'): 932 desc = "desc" 933 sortString += "&order=reverse" 934 935 namespace = RESOLUTION_NAMESPACE 936 # If I don't need to get Projects when there is no child annotation, 937 # then you don't need "outer join" which is intended to return rows (here projects) where a joined table (annotations) are null. 938 #"left outer join fetch p.annotationLinks as a_link " \ 939 query = "Project as p " \ 940 "join fetch p.annotationLinks as a_link " \ 941 "join fetch a_link.child as a " \ 942 "where a.ns='%s'" % namespace 943 944 # do a query for total count before we add restrictions. 945 totalEntries = qs.projection("select count(p.id) from " + query.replace(" fetch", ""), None)[0][0].getValue() 946 947 searchString = "" # build up a query and search string (for sort-links in the results page) 948 minRes = request.REQUEST.get('min') 949 maxRes = request.REQUEST.get('max') 950 entryText = request.REQUEST.get('entry') 951 titleText = request.REQUEST.get('title') 952 if minRes and len(minRes) > 0: 953 query += " and a.doubleValue >= %s" % minRes 954 searchString += '&min=%s' % minRes 955 if maxRes and len(maxRes) > 0: 956 query += " and a.doubleValue <= %s" % maxRes 957 searchString += '&max=%s' % maxRes 958 if entryText and len(entryText) > 0: 959 query += " and p.name like '%s%s'" % (entryText, "%") 960 searchString += '&entry=%s' % entryText 961 if titleText and len(titleText) > 0: 962 query += " and p.description like '%s%s%s'" % ("%", titleText, "%") 963 searchString += '&title=%s' % titleText 964 965 page = int(request.REQUEST.get('page', 1)) # 1-based 966 resultsPerPage = 20 967 968 p = omero.sys.Parameters() 969 p.map = {} 970 f = omero.sys.Filter() 971 f.limit = rint(resultsPerPage * page) 972 f.offset = rint(resultsPerPage * (page-1)) 973 logger.debug("Entries page: %s" % page) 974 logger.debug("Offset: %s Limit: %s" % (f.offset.val, f.limit.val)) 975 p.theFilter = f 976 977 # get the total number of results with no pagination. Returns a list of lists 978 # the inner list is of len==1 because you only asked for one column ("count(p.id)") and 979 # the outer list is of size one because you're just asking for the size of one thing. 980 countQuery = "select count(p.id) from "+ query.replace("fetch ", "") # don't fetch, since we don't want to load data 981 tr = qs.projection(countQuery, None)[0][0] 982 totalResults = tr.getValue() 983 984 if order: 985 query += " order by %s %s" % (order, desc) 986 # do the search 987 projectsQuery = "select p from " + query 988 #totalResults = len(qs.findAllByQuery(projectsQuery, None)) 989 #print projectsQuery 990 projects = qs.findAllByQuery(projectsQuery, p) 991 logger.debug("Entries query returned %s projects" % len(projects) ) 992 993 resolutions = [] 994 995 resData = [] 996 997 for p in projects: 998 entryId = p.getName().getValue() 999 desc = p.getDescription().getValue() 1000 title, sample = desc.split("\n") 1001 for a in p.copyAnnotationLinks(): 1002 r = a.child.getDoubleValue().getValue() 1003 break 1004 resData.append({"entryId":entryId, "title": title, "resolution": r, "sample": sample}) 1005 1006 pcount = int(math.ceil(float(totalResults)/resultsPerPage)) 1007 pageLinks = range(1, pcount+1) 1008 1009 return render_to_response('webemdb/browse/entries.html', {'totalResults': totalResults, 'pageLinks': pageLinks, 1010 'totalEntries': totalEntries, 'sortString':sortString, 'resolutions': resData, 'sorted': sortBy, 1011 'searchString': searchString, "minRes": minRes, "maxRes": maxRes, "title": titleText})
1012 1013
1014 -def publications (request):
1015 """ List all the publications, which are stored as CommentAnnotations with namespace """ 1016 1017 conn = getConnection(request) 1018 qs = conn.getQueryService() 1019 1020 namespace = PUBLICATION_NAMESPACE 1021 comments = qs.findAllByQuery("select a from CommentAnnotation a where a.ns='%s'" % namespace, None) 1022 1023 pubs = [] 1024 # entryId is the first EMDB entry for this publication 1025 pubAttributes = ["entryId", "authors", "title", "journal", "volume", "pages", "year", "externalReference"] 1026 1027 for c in comments: 1028 txt = c.getTextValue().getValue() 1029 values = txt.split('\n') 1030 pub = {} 1031 for a in zip(pubAttributes, values): 1032 pub[a[0]] = a[1] 1033 pub["commentId"] = c.getId().getValue() 1034 pubs.append(pub) 1035 1036 pubs.sort(key=lambda p: p['entryId']) 1037 pubs.reverse() 1038 1039 return render_to_response('webemdb/browse/publications.html', {'publications': pubs})
1040 1041
1042 -def getEntriesByPub (request, publicationId):
1043 1044 conn = getConnection(request) 1045 qs = conn.getQueryService() 1046 1047 projects = qs.findAllByQuery("select p from Project as p " \ 1048 "left outer join fetch p.annotationLinks as a_link " \ 1049 "left outer join fetch a_link.child " \ 1050 "where a_link.child.id = %s" % publicationId, None) 1051 1052 pData = {} 1053 1054 for p in projects: 1055 entryId = p.getName().getValue() 1056 desc = p.getDescription().getValue() 1057 title, sample = desc.split("\n") 1058 pData[entryId] = sample 1059 1060 return HttpResponse(simplejson.dumps(pData), mimetype='application/javascript')
1061 1062
1063 -def getConnection(request):
1064 1065 conn = None 1066 if request.session.get('username', None): 1067 logger.debug('attempting to retrieve emdb connection with username: %s' % request.session.get('username', None)) 1068 conn = getBlitzConnection(request, useragent="OMERO.webemdb") 1069 if not request.session.has_key('processors'): 1070 request.session['processors'] = {} 1071 if conn != None: 1072 logger.debug('emdb connection: %s' % conn._sessionUuid) 1073 if conn == None: 1074 # session has timed out. Need to logout and log in again. 1075 try: 1076 _session_logout(request, request.session['server']) 1077 except: 1078 import traceback 1079 logger.debug("Failed to log out %s" % traceback.format_exc()) 1080 server_id = request.REQUEST.get('server',None) 1081 if server_id is not None: 1082 blitz = settings.SERVER_LIST.get(pk=int(server_id)) 1083 else: 1084 blitz = settings.SERVER_LIST.get(pk=1) 1085 logger.debug('attempting to connect emdb with blitz: %s' % blitz) 1086 request.session['server'] = blitz.id 1087 request.session['host'] = blitz.host 1088 request.session['port'] = blitz.port 1089 request.session['password'] = "ome" 1090 request.session['username'] = "emdb" 1091 request.session['processors'] = {} 1092 request.session.modified = True 1093 conn = getBlitzConnection (request, useragent="OMERO.webemdb") 1094 1095 logger.debug('emdb connection: %s server %s' % (conn._sessionUuid, blitz.host)) 1096 return conn
1097 1098
1099 -def image_viewer (request, iid, **kwargs):
1100 """ This view is responsible for showing pixel data as images """ 1101 1102 conn = getBlitzConnection (request, useragent="OMERO.webemdb") 1103 if conn is None or not conn.isConnected(): 1104 return HttpResponseRedirect(reverse('webemdb_login')) 1105 1106 kwargs['viewport_server'] = '/webclient' 1107 1108 return webgateway_views.full_viewer(request, iid, _conn=conn, **kwargs)
1109