SubvolumeCreator.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. from django.conf import settings
  2. from django.core.cache import cache
  3. import io
  4. import logging
  5. import math
  6. import numpy as np
  7. import os
  8. from PIL import Image
  9. from skimage import img_as_ubyte
  10. from skimage.transform import resize
  11. from skimage.io import imsave
  12. import time
  13. from threading import Thread
  14. from multiprocessing import Process
  15. from volumes.models import Volume
  16. import loadtests.facade as loadtests
  17. logger = logging.getLogger(__name__)
  18. class SubvolumeCreator(Thread):
  19. ''' this implementation is only needed for testing'''
  20. def __init__(self, volumeId, x, y, z, t, minWidth, sqrtZ, numberOfLayers, spriteId, requestedRes, starttime, testId):
  21. Thread.__init__(self)
  22. self.volumeId = volumeId
  23. self.x = x
  24. self.y = y
  25. self.z = z
  26. self.t = t
  27. self.minWidth = minWidth
  28. self.sqrtZ = sqrtZ
  29. self.numberOfLayers = numberOfLayers
  30. self.spriteId = spriteId
  31. self.requestedRes = requestedRes
  32. self.starttime = starttime
  33. self.testId = testId
  34. def run(self):
  35. subvolumeCreator(self.volumeId,
  36. self.x,
  37. self.y,
  38. self.z,
  39. self.t,
  40. self.minWidth,
  41. self.sqrtZ,
  42. self.numberOfLayers,
  43. self.spriteId,
  44. self.requestedRes,
  45. self.starttime,
  46. self.testId)
  47. def subvolumeCreator(volumeId, x, y, z, t, minWidth, sqrtZ, numberOfLayers, spriteId, spriteformat, requestedRes, starttime, testId):
  48. ''' this method is either called in view or SubvolumeCreator.SubvolumeCreator thread '''
  49. volume = Volume.objects(id=volumeId).first()
  50. requestedRes = int(requestedRes)
  51. requestedShape = (requestedRes, requestedRes)
  52. logger.debug('running')
  53. if settings.SUBVOLUME_STATIC:
  54. logger.debug('debugging context, generate read image')
  55. subvolume = np.zeros((minWidth * sqrtZ, minWidth * sqrtZ), dtype=np.uint8)
  56. subvolume[:, :] = 200
  57. image = Image.fromarray(subvolume)
  58. image = image.resize(requestedShape)
  59. format = "jpeg"
  60. buff = io.BytesIO()
  61. image.save(buff, format=format, progressive=True, quality=95)
  62. buff.seek(0, 0)
  63. cache.set(get_sprite_filename(spriteId, spriteformat), buff, settings.SUBVOLUME_CACHING_TIME)
  64. '''gridfshelper.savefile(get_sprite_filename(spriteId, spriteformat), buff)'''
  65. return
  66. imageAsArray = volume.get_frame_numpy_array(t)
  67. logger.debug('generating subvolume width shape (%d, %d, %d)' % (numberOfLayers, minWidth, minWidth))
  68. logger.debug('timeframe (%d)' % t)
  69. logger.debug('roi (%d, %d, %d)' % (x, y, z))
  70. subvolume = np.empty((minWidth * sqrtZ, minWidth * sqrtZ), dtype=imageAsArray.dtype)
  71. logger.debug('resulting sprite shape: %d, %d' % subvolume.shape)
  72. logger.debug('minWidth: %d' % minWidth)
  73. logger.debug('layers per row: %d' % sqrtZ)
  74. layerCounter = 0
  75. copy_start_time = time.time()
  76. zArea = imageAsArray[z:z+numberOfLayers, :, :]
  77. for index in range(0, numberOfLayers):
  78. yoffset = math.floor(layerCounter / sqrtZ) * minWidth
  79. xoffset = (layerCounter % sqrtZ) * minWidth
  80. subvolume[yoffset: yoffset+minWidth, xoffset: xoffset+minWidth] = zArea[index, y: y+minWidth, x: x+minWidth]
  81. layerCounter += 1
  82. copy_end_time = time.time()
  83. subvolume = img_as_ubyte(subvolume)
  84. image = Image.fromarray(subvolume)
  85. image = image.resize(requestedShape, resample=Image.BILINEAR)
  86. # subvolume = resize(subvolume, requestedShape)
  87. format = spriteformat
  88. buff = io.BytesIO()
  89. image.save(buff, format=format, progressive=True, quality=95)
  90. # imsave(buff, subvolume, pluginargs={'progressive':True, 'quality':95})
  91. buff.seek(0, 0)
  92. spriteFilename = get_sprite_filename(spriteId, spriteformat)
  93. bufferValue = buff.getvalue()
  94. logger.debug('requestedRes: %d' % requestedRes)
  95. if testId is None:
  96. cache.set(spriteFilename, bufferValue, settings.SUBVOLUME_CACHING_TIME)
  97. processing_endtime = time.time()
  98. copy_duration = copy_end_time - copy_start_time
  99. processing_duration = processing_endtime - starttime
  100. if testId is not None:
  101. loadtests.addTestResult(
  102. testId,
  103. imageAsArray.shape,
  104. (numberOfLayers, minWidth, minWidth),
  105. (x, y, z),
  106. processing_duration,
  107. copy_duration,
  108. imageAsArray.dtype,
  109. volumeId
  110. )
  111. else:
  112. logger.debug('no testid given')
  113. logger.debug(str(os.getpid()) + 'finished, duration: %s of ' % (str(processing_duration)))
  114. def get_sprite_filename(sprite_id, sprite_format):
  115. return '%s.%s' % (str(sprite_id), sprite_format)
  116. def preread_volume(volume_id):
  117. logger.debug('preread called')
  118. process = Process(target=_preread_volume, args=(volume_id,))
  119. process.start()
  120. def _preread_volume(volume_id):
  121. logger.debug('_prearead called');
  122. volume = Volume.objects(id=volume_id).first()
  123. raw_frames = volume.rawFrames
  124. for framenumber in range(0, len(raw_frames)):
  125. logger.debug('read frame array with framenumber %d' % framenumber)
  126. raw = volume.get_frame_numpy_array(framenumber)
  127. logger.debug(raw.shape)
  128. tmpdata = np.empty((raw.shape[1], raw.shape[2]),dtype=raw.dtype)
  129. for slice in raw:
  130. tmpdata[:, :] = slice[:, :]
  131. logger.debug('end _preread')