reco.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import os
  2. import dm
  3. import datetime
  4. import math
  5. import multiprocessing
  6. import tofu
  7. import tofu.config
  8. import tofu.reco
  9. import logging
  10. import logging.config
  11. import xdg.BaseDirectory
  12. APP_NAME = 'recofoo'
  13. LOG_INI = 'log.ini'
  14. DATA_PATH = xdg.BaseDirectory.save_data_path(APP_NAME)
  15. CONFIG_PATH = xdg.BaseDirectory.save_config_path(APP_NAME)
  16. TIMESTAMP_PATH = os.path.join(DATA_PATH, 'timestamp')
  17. class RecoProcess(multiprocessing.Process):
  18. def __init__(self, params):
  19. super(RecoProcess, self).__init__()
  20. self.params = params
  21. def run(self):
  22. time = tofu.reco.tomo(self.params)
  23. def get_last_timestamp():
  24. if not os.path.exists(TIMESTAMP_PATH):
  25. return datetime.datetime.min
  26. with open(TIMESTAMP_PATH) as f:
  27. time = f.read()
  28. return datetime.datetime.strptime(time, '%Y-%m-%dT%H:%M:%S')
  29. def update_timestamp(timestamp):
  30. with open(TIMESTAMP_PATH, 'w') as f:
  31. f.write(timestamp.strftime('%Y-%m-%dT%H:%M:%S'))
  32. def configure_logging():
  33. config_path = os.path.join(CONFIG_PATH, LOG_INI)
  34. log_path = LOG_INI if os.path.exists(LOG_INI) else None
  35. if not log_path:
  36. log_path = config_path if os.path.exists(config_path) else None
  37. if log_path:
  38. logging.config.fileConfig(log_path)
  39. else:
  40. logging.basicConfig(level=logging.INFO)
  41. def reconstruct_scan(input_path, output_path):
  42. log = logging.getLogger(APP_NAME)
  43. params = tofu.config.TomoParams().get_defaults()
  44. params.input = os.path.join(input_path, 'radios')
  45. params.from_projections = True
  46. params.output = os.path.join(output_path, 'data', 'slices', 'slice-%05i.tif')
  47. params.number = 1698
  48. params.axis = 500
  49. params.angle_step = math.radians(0.105945)
  50. log.info(" Reconstructing ... writing to {}".format(params.output))
  51. proc = RecoProcess(params)
  52. proc.start()
  53. proc.join()
  54. log.info(" Done.")
  55. class Application(object):
  56. def __init__(self):
  57. self.client = dm.Client(token="TjMgcEtjGyL2qXZ4", token_secret="xBJS0Oq9j5Hjc8Kq")
  58. self.log = logging.getLogger(APP_NAME)
  59. def run(self):
  60. last_update = get_last_timestamp()
  61. self.objects = {o.uuid: o for o in self.client.get_objects() if o.note == 'raw'}
  62. self.accesspoint = self.client.get_accesspoints('file://')[0]
  63. downloads = {d.object_uuid: d for d in self.client.get_downloads()}
  64. for uuid, obj in self.objects.items():
  65. self.log.info("Checking downloads for {}".format(obj))
  66. if uuid in downloads:
  67. download = downloads[uuid]
  68. self.log.info("Using download={}".format(download))
  69. self.reconstruct(obj, download)
  70. else:
  71. download = obj.create_download(ap)
  72. self.log.warn("No download found, created {}".format(download))
  73. now = datetime.datetime.now()
  74. update_timestamp(now)
  75. def reconstruct(self, obj, download):
  76. _, path = download.url.split('file:', 1)
  77. data_path = os.path.join(path, 'data')
  78. if os.path.isdir(data_path) and 'radios' in os.listdir(data_path):
  79. user_client, new_ingest = self.create_ingest(obj)
  80. if new_ingest:
  81. _, output_path = new_ingest.staging_url.split('file:', 1)
  82. reconstruct_scan(data_path, output_path)
  83. new_ingest.status = dm.models.IngestStatus.PRE_INGEST_FINISHED
  84. else:
  85. self.log.error("No raw data found in {}".format(data_path))
  86. def create_ingest(self, obj):
  87. try:
  88. user = self.client.get_user(obj.uploader)
  89. user_client = dm.Client(token=user.credentials.key, token_secret=user.credentials.secret)
  90. new_obj = user_client.create_object(obj.investigation_id, user, label='reco')
  91. self.log.info(" Created new object={}".format(new_obj))
  92. new_ingest = new_obj.create_ingest(self.accesspoint)
  93. # get the ingest again to acccess the staging url ...
  94. new_ingest = dm.models.Ingest(user_client, new_ingest.id)
  95. self.log.info(" Created new ingest={}".format(new_ingest))
  96. return (user_client, new_ingest)
  97. except dm.exceptions.NotFoundError:
  98. self.log.warn(" No credentials found for user={}".format(obj.uploader))
  99. except dm.exceptions.ArbitraryError as e:
  100. self.log.error(" Could not create object [{}]".format(e))
  101. if __name__ == '__main__':
  102. configure_logging()
  103. Application().run()