SubvolumeCreator.py 5.2 KB

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