endoreg-db 0.5.3__py3-none-any.whl → 0.6.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of endoreg-db might be problematic. Click here for more details.

Files changed (268) hide show
  1. endoreg_db/admin.py +90 -1
  2. endoreg_db/case_generator/case_generator.py +159 -0
  3. endoreg_db/case_generator/lab_sample_factory.py +33 -0
  4. endoreg_db/case_generator/utils.py +30 -0
  5. endoreg_db/data/__init__.py +50 -4
  6. endoreg_db/data/ai_model/data.yaml +7 -0
  7. endoreg_db/data/{label → ai_model_label}/label/data.yaml +27 -1
  8. endoreg_db/data/ai_model_label/label-set/data.yaml +21 -0
  9. endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +5 -0
  10. endoreg_db/data/ai_model_video_segmentation_label/base_segmentation.yaml +176 -0
  11. endoreg_db/data/ai_model_video_segmentation_labelset/data.yaml +20 -0
  12. endoreg_db/data/center/data.yaml +35 -5
  13. endoreg_db/data/contraindication/bleeding.yaml +11 -0
  14. endoreg_db/data/distribution/numeric/data.yaml +14 -0
  15. endoreg_db/data/endoscope/data.yaml +93 -0
  16. endoreg_db/data/examination_indication/endoscopy.yaml +8 -0
  17. endoreg_db/data/examination_indication_classification/endoscopy.yaml +8 -0
  18. endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +101 -0
  19. endoreg_db/data/finding/data.yaml +141 -0
  20. endoreg_db/data/finding_intervention/endoscopy.yaml +138 -0
  21. endoreg_db/data/finding_intervention_type/endoscopy.yaml +15 -0
  22. endoreg_db/data/finding_location_classification/colonoscopy.yaml +46 -0
  23. endoreg_db/data/finding_location_classification_choice/colonoscopy.yaml +240 -0
  24. endoreg_db/data/finding_morphology_classification/colonoscopy.yaml +48 -0
  25. endoreg_db/data/finding_morphology_classification_choice/colon_lesion_circularity_default.yaml +34 -0
  26. endoreg_db/data/finding_morphology_classification_choice/colon_lesion_nice.yaml +20 -0
  27. endoreg_db/data/finding_morphology_classification_choice/colon_lesion_paris.yaml +65 -0
  28. endoreg_db/data/finding_morphology_classification_choice/colon_lesion_planarity_default.yaml +56 -0
  29. endoreg_db/data/finding_morphology_classification_choice/colon_lesion_surface_intact_default.yaml +39 -0
  30. endoreg_db/data/finding_morphology_classification_choice/colonoscopy_size.yaml +57 -0
  31. endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +79 -0
  32. endoreg_db/data/finding_type/data.yaml +30 -0
  33. endoreg_db/data/gender/data.yaml +17 -0
  34. endoreg_db/data/lab_value/cardiac_enzymes.yaml +7 -1
  35. endoreg_db/data/lab_value/coagulation.yaml +6 -1
  36. endoreg_db/data/lab_value/electrolytes.yaml +39 -1
  37. endoreg_db/data/lab_value/gastrointestinal_function.yaml +12 -0
  38. endoreg_db/data/lab_value/hematology.yaml +17 -2
  39. endoreg_db/data/lab_value/hormones.yaml +6 -0
  40. endoreg_db/data/lab_value/lipids.yaml +12 -3
  41. endoreg_db/data/lab_value/misc.yaml +5 -2
  42. endoreg_db/data/lab_value/renal_function.yaml +2 -1
  43. endoreg_db/data/lx_client_tag/base.yaml +54 -0
  44. endoreg_db/data/lx_client_type/base.yaml +30 -0
  45. endoreg_db/data/lx_permission/base.yaml +24 -0
  46. endoreg_db/data/lx_permission/endoreg.yaml +52 -0
  47. endoreg_db/data/medication_indication/anticoagulation.yaml +44 -49
  48. endoreg_db/data/names_first/first_names.yaml +51 -0
  49. endoreg_db/data/names_last/last_names.yaml +51 -0
  50. endoreg_db/data/network_device/data.yaml +30 -0
  51. endoreg_db/data/organ/data.yaml +29 -0
  52. endoreg_db/data/pdf_type/data.yaml +2 -1
  53. endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +4 -0
  54. endoreg_db/forms/__init__.py +3 -1
  55. endoreg_db/forms/examination_form.py +11 -0
  56. endoreg_db/forms/patient_finding_intervention_form.py +19 -0
  57. endoreg_db/forms/patient_form.py +26 -0
  58. endoreg_db/management/commands/__init__.py +0 -0
  59. endoreg_db/management/commands/load_ai_model_data.py +57 -23
  60. endoreg_db/management/commands/load_ai_model_label_data.py +59 -0
  61. endoreg_db/management/commands/load_base_db_data.py +160 -118
  62. endoreg_db/management/commands/{load_endoscope_type_data.py → load_contraindication_data.py} +3 -7
  63. endoreg_db/management/commands/load_disease_data.py +29 -7
  64. endoreg_db/management/commands/load_endoscope_data.py +68 -0
  65. endoreg_db/management/commands/load_examination_indication_data.py +65 -0
  66. endoreg_db/management/commands/load_finding_data.py +171 -0
  67. endoreg_db/management/commands/load_lab_value_data.py +3 -3
  68. endoreg_db/management/commands/load_lx_data.py +64 -0
  69. endoreg_db/management/commands/load_medication_data.py +83 -21
  70. endoreg_db/management/commands/load_name_data.py +37 -0
  71. endoreg_db/management/commands/{load_endoscopy_processor_data.py → load_organ_data.py} +7 -9
  72. endoreg_db/migrations/0001_initial.py +1206 -728
  73. endoreg_db/migrations/0002_alter_frame_image_alter_rawframe_image.py +23 -0
  74. endoreg_db/migrations/0003_alter_frame_image_alter_rawframe_image.py +23 -0
  75. endoreg_db/migrations/0004_alter_rawvideofile_file_alter_video_file.py +25 -0
  76. endoreg_db/migrations/0005_rawvideofile_frame_count_and_more.py +33 -0
  77. endoreg_db/migrations/0006_frame_extracted_rawframe_extracted.py +23 -0
  78. endoreg_db/migrations/0007_rename_pseudo_patient_video_patient_and_more.py +24 -0
  79. endoreg_db/migrations/0008_remove_reportfile_patient_examination_and_more.py +48 -0
  80. endoreg_db/models/__init__.py +331 -28
  81. endoreg_db/models/ai_model/__init__.py +1 -0
  82. endoreg_db/models/ai_model/ai_model.py +103 -0
  83. endoreg_db/models/ai_model/lightning/__init__.py +3 -0
  84. endoreg_db/models/ai_model/lightning/inference_dataset.py +53 -0
  85. endoreg_db/models/ai_model/lightning/multilabel_classification_net.py +155 -0
  86. endoreg_db/models/ai_model/lightning/postprocess.py +53 -0
  87. endoreg_db/models/ai_model/lightning/predict.py +172 -0
  88. endoreg_db/models/ai_model/lightning/prediction_visualizer.py +55 -0
  89. endoreg_db/models/ai_model/lightning/preprocess.py +68 -0
  90. endoreg_db/models/ai_model/lightning/run_visualizer.py +21 -0
  91. endoreg_db/models/ai_model/model_meta.py +232 -6
  92. endoreg_db/models/ai_model/model_type.py +13 -3
  93. endoreg_db/models/annotation/__init__.py +31 -2
  94. endoreg_db/models/annotation/anonymized_image_annotation.py +73 -18
  95. endoreg_db/models/annotation/binary_classification_annotation_task.py +94 -57
  96. endoreg_db/models/annotation/image_classification.py +73 -14
  97. endoreg_db/models/annotation/video_segmentation_annotation.py +52 -0
  98. endoreg_db/models/annotation/video_segmentation_labelset.py +20 -0
  99. endoreg_db/models/case/__init__.py +1 -0
  100. endoreg_db/models/{persons/patient/case → case}/case.py +4 -0
  101. endoreg_db/models/case_template/__init__.py +10 -1
  102. endoreg_db/models/case_template/case_template.py +57 -13
  103. endoreg_db/models/case_template/case_template_rule.py +5 -5
  104. endoreg_db/models/case_template/case_template_rule_value.py +19 -4
  105. endoreg_db/models/center/__init__.py +7 -0
  106. endoreg_db/models/center/center.py +31 -5
  107. endoreg_db/models/center/center_product.py +0 -1
  108. endoreg_db/models/center/center_resource.py +16 -2
  109. endoreg_db/models/center/center_waste.py +6 -1
  110. endoreg_db/models/contraindication/__init__.py +21 -0
  111. endoreg_db/models/data_file/__init__.py +38 -5
  112. endoreg_db/models/data_file/base_classes/__init__.py +6 -1
  113. endoreg_db/models/data_file/base_classes/abstract_frame.py +64 -15
  114. endoreg_db/models/data_file/base_classes/abstract_pdf.py +136 -0
  115. endoreg_db/models/data_file/base_classes/abstract_video.py +744 -138
  116. endoreg_db/models/data_file/base_classes/frame_helpers.py +17 -0
  117. endoreg_db/models/data_file/base_classes/prepare_bulk_frames.py +19 -0
  118. endoreg_db/models/data_file/base_classes/utils.py +80 -0
  119. endoreg_db/models/data_file/frame.py +22 -38
  120. endoreg_db/models/data_file/import_classes/__init__.py +4 -18
  121. endoreg_db/models/data_file/import_classes/raw_pdf.py +162 -90
  122. endoreg_db/models/data_file/import_classes/raw_video.py +239 -294
  123. endoreg_db/models/data_file/metadata/__init__.py +10 -0
  124. endoreg_db/models/data_file/metadata/pdf_meta.py +4 -0
  125. endoreg_db/models/data_file/metadata/sensitive_meta.py +265 -6
  126. endoreg_db/models/data_file/metadata/video_meta.py +116 -50
  127. endoreg_db/models/data_file/report_file.py +30 -63
  128. endoreg_db/models/data_file/video/__init__.py +6 -2
  129. endoreg_db/models/data_file/video/video.py +187 -16
  130. endoreg_db/models/data_file/video_segment.py +162 -55
  131. endoreg_db/models/disease.py +25 -2
  132. endoreg_db/models/emission/__init__.py +5 -1
  133. endoreg_db/models/emission/emission_factor.py +71 -6
  134. endoreg_db/models/event.py +51 -0
  135. endoreg_db/models/examination/__init__.py +6 -1
  136. endoreg_db/models/examination/examination.py +53 -12
  137. endoreg_db/models/examination/examination_indication.py +170 -0
  138. endoreg_db/models/examination/examination_time.py +31 -5
  139. endoreg_db/models/examination/examination_time_type.py +28 -4
  140. endoreg_db/models/examination/examination_type.py +28 -6
  141. endoreg_db/models/finding/__init__.py +11 -0
  142. endoreg_db/models/finding/finding.py +75 -0
  143. endoreg_db/models/finding/finding_intervention.py +60 -0
  144. endoreg_db/models/finding/finding_location_classification.py +94 -0
  145. endoreg_db/models/finding/finding_morphology_classification.py +89 -0
  146. endoreg_db/models/finding/finding_type.py +22 -0
  147. endoreg_db/models/hardware/endoscope.py +16 -0
  148. endoreg_db/models/hardware/endoscopy_processor.py +31 -19
  149. endoreg_db/models/label/label.py +35 -7
  150. endoreg_db/models/laboratory/lab_value.py +12 -3
  151. endoreg_db/models/logging/__init__.py +8 -1
  152. endoreg_db/models/lx/__init__.py +4 -0
  153. endoreg_db/models/lx/client.py +57 -0
  154. endoreg_db/models/lx/identity.py +34 -0
  155. endoreg_db/models/lx/permission.py +18 -0
  156. endoreg_db/models/lx/user.py +16 -0
  157. endoreg_db/models/medication/__init__.py +19 -1
  158. endoreg_db/models/medication/medication.py +7 -122
  159. endoreg_db/models/medication/medication_indication.py +50 -0
  160. endoreg_db/models/medication/medication_indication_type.py +34 -0
  161. endoreg_db/models/medication/medication_intake_time.py +26 -0
  162. endoreg_db/models/medication/medication_schedule.py +37 -0
  163. endoreg_db/models/network/__init__.py +7 -1
  164. endoreg_db/models/network/network_device.py +13 -8
  165. endoreg_db/models/organ/__init__.py +38 -0
  166. endoreg_db/models/other/__init__.py +19 -1
  167. endoreg_db/models/other/distribution/__init__.py +44 -0
  168. endoreg_db/models/other/distribution/base_value_distribution.py +20 -0
  169. endoreg_db/models/other/distribution/date_value_distribution.py +91 -0
  170. endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +32 -0
  171. endoreg_db/models/other/distribution/numeric_value_distribution.py +97 -0
  172. endoreg_db/models/other/distribution/single_categorical_value_distribution.py +22 -0
  173. endoreg_db/models/other/distribution.py +1 -211
  174. endoreg_db/models/other/material.py +4 -0
  175. endoreg_db/models/other/transport_route.py +2 -1
  176. endoreg_db/models/patient/__init__.py +24 -0
  177. endoreg_db/models/patient/patient_examination.py +182 -0
  178. endoreg_db/models/patient/patient_finding.py +143 -0
  179. endoreg_db/models/patient/patient_finding_intervention.py +26 -0
  180. endoreg_db/models/patient/patient_finding_location.py +120 -0
  181. endoreg_db/models/patient/patient_finding_morphology.py +166 -0
  182. endoreg_db/models/persons/__init__.py +29 -2
  183. endoreg_db/models/persons/examiner/examiner.py +48 -4
  184. endoreg_db/models/persons/patient/__init__.py +1 -1
  185. endoreg_db/models/persons/patient/patient.py +227 -54
  186. endoreg_db/models/persons/patient/patient_disease.py +6 -0
  187. endoreg_db/models/persons/patient/patient_event.py +31 -1
  188. endoreg_db/models/persons/patient/patient_examination_indication.py +32 -0
  189. endoreg_db/models/persons/patient/patient_lab_sample.py +4 -2
  190. endoreg_db/models/persons/patient/patient_lab_value.py +37 -16
  191. endoreg_db/models/persons/patient/patient_medication.py +27 -12
  192. endoreg_db/models/persons/patient/patient_medication_schedule.py +62 -2
  193. endoreg_db/models/prediction/__init__.py +7 -1
  194. endoreg_db/models/prediction/image_classification.py +20 -6
  195. endoreg_db/models/prediction/video_prediction_meta.py +151 -89
  196. endoreg_db/models/product/__init__.py +10 -1
  197. endoreg_db/models/product/product.py +15 -2
  198. endoreg_db/models/product/product_group.py +8 -0
  199. endoreg_db/models/product/product_material.py +4 -0
  200. endoreg_db/models/product/product_weight.py +12 -0
  201. endoreg_db/models/product/reference_product.py +19 -3
  202. endoreg_db/models/quiz/__init__.py +8 -1
  203. endoreg_db/models/report_reader/__init__.py +6 -1
  204. endoreg_db/serializers/__init__.py +1 -1
  205. endoreg_db/serializers/annotation.py +2 -5
  206. endoreg_db/serializers/frame.py +1 -5
  207. endoreg_db/serializers/patient.py +26 -3
  208. endoreg_db/serializers/prediction.py +2 -7
  209. endoreg_db/serializers/raw_video_meta_validation.py +13 -0
  210. endoreg_db/serializers/video.py +6 -13
  211. endoreg_db/serializers/video_segmentation.py +492 -0
  212. endoreg_db/templates/admin/patient_finding_intervention.html +253 -0
  213. endoreg_db/templates/admin/start_examination.html +12 -0
  214. endoreg_db/templates/timeline.html +176 -0
  215. endoreg_db/urls.py +173 -0
  216. endoreg_db/utils/__init__.py +36 -1
  217. endoreg_db/utils/dataloader.py +45 -19
  218. endoreg_db/utils/dates.py +39 -0
  219. endoreg_db/utils/hashs.py +122 -4
  220. endoreg_db/utils/names.py +74 -0
  221. endoreg_db/utils/parse_and_generate_yaml.py +46 -0
  222. endoreg_db/utils/pydantic_models/__init__.py +6 -0
  223. endoreg_db/utils/pydantic_models/db_config.py +57 -0
  224. endoreg_db/utils/validate_endo_roi.py +19 -0
  225. endoreg_db/utils/validate_subcategory_dict.py +91 -0
  226. endoreg_db/utils/video/__init__.py +13 -0
  227. endoreg_db/utils/video/extract_frames.py +121 -0
  228. endoreg_db/utils/video/transcode_videofile.py +111 -0
  229. endoreg_db/views/__init__.py +2 -0
  230. endoreg_db/views/csrf.py +7 -0
  231. endoreg_db/views/patient_views.py +90 -0
  232. endoreg_db/views/raw_video_meta_validation_views.py +38 -0
  233. endoreg_db/views/report_views.py +96 -0
  234. endoreg_db/views/video_segmentation_views.py +149 -0
  235. endoreg_db/views/views_for_timeline.py +46 -0
  236. endoreg_db/views.py +0 -3
  237. endoreg_db-0.6.1.dist-info/METADATA +151 -0
  238. endoreg_db-0.6.1.dist-info/RECORD +420 -0
  239. {endoreg_db-0.5.3.dist-info → endoreg_db-0.6.1.dist-info}/WHEEL +1 -1
  240. endoreg_db/data/active_model/data.yaml +0 -3
  241. endoreg_db/data/label/label-set/data.yaml +0 -18
  242. endoreg_db/management/commands/delete_legacy_images.py +0 -19
  243. endoreg_db/management/commands/delete_legacy_videos.py +0 -17
  244. endoreg_db/management/commands/extract_legacy_video_frames.py +0 -18
  245. endoreg_db/management/commands/import_legacy_images.py +0 -94
  246. endoreg_db/management/commands/import_legacy_videos.py +0 -76
  247. endoreg_db/management/commands/load_label_data.py +0 -67
  248. endoreg_db/migrations/0002_anonymizedimagelabel_anonymousimageannotation_and_more.py +0 -55
  249. endoreg_db/migrations/0003_anonymousimageannotation_original_image_url_and_more.py +0 -39
  250. endoreg_db/migrations/0004_alter_rawpdffile_file.py +0 -20
  251. endoreg_db/migrations/0005_uploadedfile_alter_rawpdffile_file_anonymizedfile.py +0 -40
  252. endoreg_db/migrations/0006_alter_rawpdffile_file.py +0 -20
  253. endoreg_db/migrations/0007_networkdevicelogentry_datetime_and_more.py +0 -43
  254. endoreg_db/migrations/0008_networkdevicelogentry_aglnet_ip_and_more.py +0 -28
  255. endoreg_db/migrations/0009_alter_networkdevicelogentry_vpn_service_status.py +0 -18
  256. endoreg_db/migrations/0010_remove_networkdevicelogentry_hostname.py +0 -17
  257. endoreg_db/models/legacy_data/__init__.py +0 -3
  258. endoreg_db/models/legacy_data/image.py +0 -34
  259. endoreg_db/models/patient_examination/__init__.py +0 -35
  260. endoreg_db/utils/video_metadata.py +0 -87
  261. endoreg_db-0.5.3.dist-info/METADATA +0 -28
  262. endoreg_db-0.5.3.dist-info/RECORD +0 -319
  263. /endoreg_db/{models/persons/patient/case → case_generator}/__init__.py +0 -0
  264. /endoreg_db/data/{label → ai_model_label}/label-type/data.yaml +0 -0
  265. /endoreg_db/data/{model_type → ai_model_type}/data.yaml +0 -0
  266. /endoreg_db/{data/distribution/numeric/.init → management/__init__.py} +0 -0
  267. /endoreg_db/management/commands/{load_report_reader_flag.py → load_report_reader_flag_data.py} +0 -0
  268. {endoreg_db-0.5.3.dist-info → endoreg_db-0.6.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,19 +0,0 @@
1
- # django command to delete all LegacyImage objects
2
-
3
- from django.core.management.base import BaseCommand, CommandError
4
- from endoreg_db.models import LegacyImage
5
- from tqdm import tqdm
6
-
7
- class Command(BaseCommand):
8
- help = 'Deletes all LegacyImage objects including the linked files (legacy_image.image)'
9
-
10
- def handle(self, *args, **options):
11
- legacy_images = LegacyImage.objects.all()
12
-
13
- for legacy_image in tqdm(legacy_images):
14
- legacy_image.image.delete()
15
- legacy_image.delete()
16
-
17
- self.stdout.write(self.style.SUCCESS('Successfully deleted all LegacyImage objects and linked image files'))
18
-
19
-
@@ -1,17 +0,0 @@
1
- # Django command to fetch all LegacyVideo objects, delete the associated file and delete the object from the database
2
-
3
- from endoreg_db.models.data_file.video import LegacyVideo
4
- from tqdm import tqdm
5
- from django.core.management.base import BaseCommand
6
-
7
- class Command(BaseCommand):
8
- """
9
- Deletes all LegacyVideos in the database.
10
- """
11
- help = 'Deletes all LegacyVideos in the database.'
12
-
13
- def handle(self, *args, **options):
14
- videos = LegacyVideo.objects.all()
15
- for video in tqdm(videos):
16
- video.file.delete()
17
- video.delete()
@@ -1,18 +0,0 @@
1
- # Django Command to:
2
- # fetch all LegacyVideos and extract frames from them
3
- # track progress for all videos and for each video with tqdm
4
-
5
- from endoreg_db.models.data_file.video import LegacyVideo
6
- from tqdm import tqdm
7
- from django.core.management.base import BaseCommand
8
-
9
- class Command(BaseCommand):
10
- """
11
- Extracts frames from all LegacyVideos in the database.
12
- """
13
- help = 'Extracts frames from all LegacyVideos in the database.'
14
-
15
- def handle(self, *args, **options):
16
- videos = LegacyVideo.objects.all()
17
- for video in tqdm(videos):
18
- video.extract_all_frames()
@@ -1,94 +0,0 @@
1
- # command expects a directory as an argument
2
- # directory should contain a img_dicts.jsonl file, a settings.json and an "images" directory
3
- # images should be in jpeg format
4
- # reads the img_dicts.jsonl file and creates a new database entry for each image
5
- # img_dicts contains a line for each image in the following format:
6
- # {"id": 30604292, "path": "images/30604292.jpg", "labels": ["appendix", "polyp"]}
7
-
8
- # import_settings.json example:
9
- # {
10
- # "annotator": "legacy",
11
- # "labelset_name": "multilabel_classification",
12
- # "labelset_version": 0
13
- # }
14
-
15
- import os
16
- import json
17
- from tqdm import tqdm
18
- from django.core.management.base import BaseCommand
19
- from endoreg_db.models import LegacyImage, LabelSet, Label, ImageClassificationAnnotation
20
- from django.core.files import File
21
- from uuid import uuid4
22
-
23
- class Command(BaseCommand):
24
- """
25
- Imports images from a directory into the database
26
-
27
- Usage:
28
- python manage.py import_legacy_images <directory>
29
- """
30
- help = 'Imports images from a directory into the database'
31
-
32
- def add_arguments(self, parser):
33
- parser.add_argument('directory', type=str)
34
-
35
- def handle(self, *args, **options):
36
- directory = options['directory']
37
- if not os.path.isdir(directory):
38
- raise Exception(f"Directory {directory} does not exist")
39
-
40
- # read settings.json
41
- with open(os.path.join(directory, 'import_settings.json'), 'r') as f:
42
- settings = json.load(f)
43
-
44
- # read img_dicts.jsonl
45
- with open(os.path.join(directory, 'img_dicts.jsonl'), 'r') as f:
46
- img_dicts = [json.loads(line) for line in f.readlines()]
47
-
48
- # get labelset
49
- labelset_name = settings['labelset_name']
50
- labelset_version = settings['labelset_version']
51
- try:
52
- labelset = LabelSet.objects.get(name=labelset_name, version=labelset_version)
53
- except LabelSet.DoesNotExist:
54
- raise Exception(f"No labelset found with the name {labelset_name} and version {labelset_version}")
55
-
56
-
57
- # get labels in dict to lookup by name
58
- labels = {label.name: label for label in labelset.labels.all()}
59
-
60
- # create images and image_classification_annotations
61
- for img_dict in tqdm(img_dicts):
62
-
63
- # Open the image file
64
- with open(os.path.join(directory, img_dict['path']), 'rb') as f:
65
- # Create the Django File object
66
- django_file = File(f)
67
-
68
- # Extract only the filename
69
- filename = os.path.basename(img_dict['path'])
70
- img_suffix = os.path.splitext(filename)[1]
71
- # assign uuid as new filename
72
- filename = str(uuid4()) + img_suffix
73
-
74
-
75
- # Create a new LegacyImage instance and save the image
76
- image = LegacyImage(image=filename, suffix=img_suffix)
77
- image.image.save(filename, django_file, save=True)
78
-
79
- image_annotations = []
80
- for label_name, label in labels.items():
81
- if label_name in img_dict['labels']:
82
- value = True
83
- else:
84
- value = False
85
-
86
- image_annotations.append(ImageClassificationAnnotation(
87
- legacy_image=image,
88
- label=label,
89
- value=value,
90
- annotator=settings['annotator']
91
- ))
92
-
93
- ImageClassificationAnnotation.objects.bulk_create(image_annotations)
94
-
@@ -1,76 +0,0 @@
1
- from endoreg_db.utils.hashs import get_video_hash
2
- import subprocess
3
- from django.core.files import File
4
- from django.core.management.base import BaseCommand
5
- from endoreg_db.models.data_file.video import LegacyVideo
6
- import os
7
- from tqdm import tqdm
8
- # import cv2
9
-
10
- def convert_mkv_to_mp4(source_path, target_path):
11
- """
12
- Convert a .mkv file to a .mp4 file using FFmpeg.
13
-
14
- Parameters:
15
- mov_file_path (str): The file path of the input .MOV file.
16
- mp4_file_path (str): The file path where the output .mp4 file should be saved.
17
-
18
- Returns:
19
- None
20
- """
21
- cmd = ["ffmpeg", "-y", "-i", source_path, "-vcodec", "h264", "-acodec", "aac", target_path]
22
- subprocess.run(cmd)
23
-
24
-
25
- class Command(BaseCommand):
26
- """
27
- Imports videos from a directory into the database
28
-
29
- Usage:
30
- python manage.py import_legacy_videos <directory>
31
- """
32
- help = 'Imports videos from a directory into the database'
33
-
34
- def add_arguments(self, parser):
35
- parser.add_argument('directory', type=str)
36
-
37
- def handle(self, *args, **options):
38
- directory = options['directory']
39
- if not os.path.isdir(directory):
40
- raise Exception(f"Directory {directory} does not exist")
41
-
42
- # iterate over all subdirectories and gather all .mkv files
43
- mkv_files = []
44
- for root, dirs, files in os.walk(directory):
45
- for file in files:
46
- if file.endswith(".mkv"):
47
- mkv_files.append(os.path.join(root, file))
48
-
49
- # create videos
50
- for mkv_file in tqdm(mkv_files):
51
- # get the name of the video
52
- video_name = os.path.basename(mkv_file).replace(".mkv", "")
53
-
54
- # convert the .mkv file to a .mp4 file
55
- mp4_file = os.path.join(directory, video_name + ".mp4")
56
- if not os.path.isfile(mp4_file):
57
- convert_mkv_to_mp4(mkv_file, mp4_file)
58
-
59
- # create the video object
60
- video_hash = get_video_hash(mp4_file)
61
-
62
- # check if the video already exists
63
- if LegacyVideo.objects.filter(video_hash=video_hash).exists():
64
- print(f"Video with hash {video_hash} already exists. Skipping...")
65
- continue
66
-
67
- video = LegacyVideo.objects.create(video_hash=video_hash, suffix = "mp4")
68
-
69
- # open the .mp4 file
70
- with open(mp4_file, 'rb') as f:
71
- # create the Django File object
72
- django_file = File(f)
73
- # save the file to the video
74
- video.file.save(video_name + ".mp4", django_file)
75
- raise Exception("Stop here: NEED TO FIX OPENCV DEPENDENCY")
76
- video.initialize_video_specs(cv2.VideoCapture(video.file.path))
@@ -1,67 +0,0 @@
1
- from django.conf import settings
2
- from django.core.management.base import BaseCommand
3
- from ...models import (
4
- Label,
5
- LabelType,
6
- LabelSet
7
- )
8
- import os
9
- from ...utils import load_model_data_from_yaml
10
- from ...data import LABEL_DATA_DIR
11
-
12
- SOURCE_DIR = LABEL_DATA_DIR
13
-
14
- IMPORT_MODELS = [ # string as model key, serves as key in IMPORT_METADATA
15
- "LabelType",
16
- "Label",
17
- "LabelSet",
18
- ]
19
-
20
- IMPORT_METADATA = {
21
- # "": { # same as model name in "import models", e.g. "Intervention"
22
- # "subdir": os.path.join(SOURCE_DIR,""), # e.g. "interventions"
23
- # "model": None, # e.g. Intervention
24
- # "foreign_keys": [], # e.g. ["intervention_types"]
25
- # "foreign_key_models": [] # e.g. [InterventionType]
26
- # },
27
- "LabelType": {
28
- "dir": os.path.join(SOURCE_DIR,"label-type"), # e.g. "interventions"
29
- "model": LabelType, # e.g. Intervention
30
- "foreign_keys": [], # e.g. ["intervention_types"]
31
- "foreign_key_models": [] # e.g. [InterventionType]
32
- },
33
- "Label": {
34
- "dir": os.path.join(SOURCE_DIR,"label"), # e.g. "interventions"
35
- "model": Label, # e.g. Intervention
36
- "foreign_keys": ["label_type"], # e.g. ["intervention_types"]
37
- "foreign_key_models": [LabelType] # e.g. [InterventionType]
38
- },
39
- "LabelSet": {
40
- "dir": os.path.join(SOURCE_DIR,"label-set"), # e.g. "interventions"
41
- "model": LabelSet, # e.g. Intervention
42
- "foreign_keys": ["labels"], # e.g. ["intervention_types"]
43
- "foreign_key_models": [Label] # e.g. [InterventionType]
44
- },
45
- }
46
-
47
- class Command(BaseCommand):
48
- help = """Load all .yaml files in the data/intervention directory
49
- into the Intervention and InterventionType model"""
50
-
51
- def add_arguments(self, parser):
52
- parser.add_argument(
53
- '--verbose',
54
- action='store_true',
55
- help='Display verbose output',
56
- )
57
-
58
- def handle(self, *args, **options):
59
- verbose = options['verbose']
60
- for model_name in IMPORT_MODELS:
61
- _metadata = IMPORT_METADATA[model_name]
62
- load_model_data_from_yaml(
63
- self,
64
- model_name,
65
- _metadata,
66
- verbose
67
- )
@@ -1,55 +0,0 @@
1
- # Generated by Django 4.2.15 on 2024-08-28 11:05
2
-
3
- import django.core.files.storage
4
- import django.core.validators
5
- from django.db import migrations, models
6
- import django.db.models.deletion
7
-
8
-
9
- class Migration(migrations.Migration):
10
-
11
- dependencies = [
12
- ('endoreg_db', '0001_initial'),
13
- ]
14
-
15
- operations = [
16
- migrations.CreateModel(
17
- name='AnonymizedImageLabel',
18
- fields=[
19
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20
- ('name', models.CharField(max_length=255, unique=True)),
21
- ('description', models.TextField(blank=True, null=True)),
22
- ],
23
- ),
24
- migrations.CreateModel(
25
- name='AnonymousImageAnnotation',
26
- fields=[
27
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
28
- ('image_name', models.CharField(max_length=255)),
29
- ('slug', models.SlugField(blank=True, null=True, unique=True)),
30
- ('polyp_count', models.IntegerField()),
31
- ('comments', models.CharField(max_length=255)),
32
- ('gender', models.CharField(max_length=255)),
33
- ('name_image_url', models.CharField(max_length=255)),
34
- ('date_created', models.DateTimeField(auto_now_add=True)),
35
- ('label', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.label')),
36
- ],
37
- ),
38
- migrations.AlterField(
39
- model_name='rawpdffile',
40
- name='file',
41
- field=models.FileField(storage=django.core.files.storage.FileSystemStorage(location='/home/agl-admin/agl-validator-backend/agl_validator_backend/erc_data/raw_pdf'), upload_to='raw_pdf/', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['pdf'])]),
42
- ),
43
- migrations.CreateModel(
44
- name='DroppedName',
45
- fields=[
46
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
47
- ('name', models.CharField(max_length=255)),
48
- ('gender', models.CharField(max_length=255)),
49
- ('x', models.FloatField()),
50
- ('y', models.FloatField()),
51
- ('name_image_url', models.CharField(max_length=255)),
52
- ('annotation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='dropped_names', to='endoreg_db.anonymousimageannotation')),
53
- ],
54
- ),
55
- ]
@@ -1,39 +0,0 @@
1
- # Generated by Django 4.2.15 on 2024-08-29 07:15
2
-
3
- from django.db import migrations, models
4
- import django.db.models.deletion
5
-
6
-
7
- class Migration(migrations.Migration):
8
-
9
- dependencies = [
10
- ('endoreg_db', '0002_anonymizedimagelabel_anonymousimageannotation_and_more'),
11
- ]
12
-
13
- operations = [
14
- migrations.AddField(
15
- model_name='anonymousimageannotation',
16
- name='original_image_url',
17
- field=models.CharField(default='https://example.com/placeholder.jpg', max_length=255),
18
- ),
19
- migrations.AddField(
20
- model_name='anonymousimageannotation',
21
- name='processed',
22
- field=models.BooleanField(default=False),
23
- ),
24
- migrations.AddField(
25
- model_name='droppedname',
26
- name='box_coordinates',
27
- field=models.CharField(blank=True, max_length=255, null=True),
28
- ),
29
- migrations.AlterField(
30
- model_name='anonymousimageannotation',
31
- name='comments',
32
- field=models.TextField(blank=True, null=True),
33
- ),
34
- migrations.AlterField(
35
- model_name='anonymousimageannotation',
36
- name='label',
37
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.anonymizedimagelabel'),
38
- ),
39
- ]
@@ -1,20 +0,0 @@
1
- # Generated by Django 4.2.14 on 2024-09-04 19:48
2
-
3
- import django.core.files.storage
4
- import django.core.validators
5
- from django.db import migrations, models
6
-
7
-
8
- class Migration(migrations.Migration):
9
-
10
- dependencies = [
11
- ('endoreg_db', '0003_anonymousimageannotation_original_image_url_and_more'),
12
- ]
13
-
14
- operations = [
15
- migrations.AlterField(
16
- model_name='rawpdffile',
17
- name='file',
18
- field=models.FileField(storage=django.core.files.storage.FileSystemStorage(location='/home/agl-admin/agl_anonymizer/agl_anonymizer/erc_data/raw_pdf'), upload_to='raw_pdf/', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['pdf'])]),
19
- ),
20
- ]
@@ -1,40 +0,0 @@
1
- # Generated by Django 4.2.15 on 2024-09-17 11:46
2
-
3
- import django.core.files.storage
4
- import django.core.validators
5
- from django.db import migrations, models
6
- import django.db.models.deletion
7
- import django.utils.timezone
8
-
9
-
10
- class Migration(migrations.Migration):
11
-
12
- dependencies = [
13
- ('endoreg_db', '0004_alter_rawpdffile_file'),
14
- ]
15
-
16
- operations = [
17
- migrations.CreateModel(
18
- name='UploadedFile',
19
- fields=[
20
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21
- ('original_file', models.FileField(upload_to='uploads/original/')),
22
- ('upload_date', models.DateTimeField(default=django.utils.timezone.now)),
23
- ('description', models.TextField(blank=True, null=True)),
24
- ],
25
- ),
26
- migrations.AlterField(
27
- model_name='rawpdffile',
28
- name='file',
29
- field=models.FileField(storage=django.core.files.storage.FileSystemStorage(location='/mnt/hdd-sensitive/Pseudo/import/pdf'), upload_to='raw_pdf/', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['pdf'])]),
30
- ),
31
- migrations.CreateModel(
32
- name='AnonymizedFile',
33
- fields=[
34
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
35
- ('anonymized_file', models.FileField(upload_to='uploads/anonymized/')),
36
- ('anonymization_date', models.DateTimeField(default=django.utils.timezone.now)),
37
- ('original_file', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='anonymized_file', to='endoreg_db.uploadedfile')),
38
- ],
39
- ),
40
- ]
@@ -1,20 +0,0 @@
1
- # Generated by Django 5.1.1 on 2024-10-01 16:31
2
-
3
- import django.core.files.storage
4
- import django.core.validators
5
- from django.db import migrations, models
6
-
7
-
8
- class Migration(migrations.Migration):
9
-
10
- dependencies = [
11
- ('endoreg_db', '0005_uploadedfile_alter_rawpdffile_file_anonymizedfile'),
12
- ]
13
-
14
- operations = [
15
- migrations.AlterField(
16
- model_name='rawpdffile',
17
- name='file',
18
- field=models.FileField(storage=django.core.files.storage.FileSystemStorage(location='/home/agl-admin/dev/agl-monitor-flake/agl_monitor/erc_data/raw_pdf'), upload_to='raw_pdf/', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['pdf'])]),
19
- ),
20
- ]
@@ -1,43 +0,0 @@
1
- # Generated by Django 5.1.1 on 2024-10-12 15:28
2
-
3
- from django.db import migrations, models
4
-
5
-
6
- class Migration(migrations.Migration):
7
-
8
- dependencies = [
9
- ('endoreg_db', '0006_alter_rawpdffile_file'),
10
- ]
11
-
12
- operations = [
13
- migrations.AddField(
14
- model_name='networkdevicelogentry',
15
- name='datetime',
16
- field=models.DateTimeField(blank=True, default=None, null=True),
17
- ),
18
- migrations.AddField(
19
- model_name='networkdevicelogentry',
20
- name='ping_vpn',
21
- field=models.BooleanField(default=False),
22
- ),
23
- migrations.AddField(
24
- model_name='networkdevicelogentry',
25
- name='ping_www',
26
- field=models.BooleanField(default=False),
27
- ),
28
- migrations.AddField(
29
- model_name='networkdevicelogentry',
30
- name='vpn_service_restart_attempt',
31
- field=models.BooleanField(default=False),
32
- ),
33
- migrations.AddField(
34
- model_name='networkdevicelogentry',
35
- name='vpn_service_restart_success',
36
- field=models.BooleanField(blank=True, null=True),
37
- ),
38
- migrations.AddField(
39
- model_name='networkdevicelogentry',
40
- name='vpn_service_status',
41
- field=models.BooleanField(default=False),
42
- ),
43
- ]
@@ -1,28 +0,0 @@
1
- # Generated by Django 5.1.1 on 2024-10-12 16:13
2
-
3
- from django.db import migrations, models
4
-
5
-
6
- class Migration(migrations.Migration):
7
-
8
- dependencies = [
9
- ('endoreg_db', '0007_networkdevicelogentry_datetime_and_more'),
10
- ]
11
-
12
- operations = [
13
- migrations.AddField(
14
- model_name='networkdevicelogentry',
15
- name='aglnet_ip',
16
- field=models.GenericIPAddressField(blank=True, null=True),
17
- ),
18
- migrations.AddField(
19
- model_name='networkdevicelogentry',
20
- name='hostname',
21
- field=models.CharField(blank=True, max_length=255, null=True),
22
- ),
23
- migrations.AddField(
24
- model_name='networkdevicelogentry',
25
- name='transferred_to_host',
26
- field=models.BooleanField(default=False),
27
- ),
28
- ]
@@ -1,18 +0,0 @@
1
- # Generated by Django 5.1.1 on 2024-10-12 16:51
2
-
3
- from django.db import migrations, models
4
-
5
-
6
- class Migration(migrations.Migration):
7
-
8
- dependencies = [
9
- ('endoreg_db', '0008_networkdevicelogentry_aglnet_ip_and_more'),
10
- ]
11
-
12
- operations = [
13
- migrations.AlterField(
14
- model_name='networkdevicelogentry',
15
- name='vpn_service_status',
16
- field=models.CharField(blank=True, max_length=255, null=True),
17
- ),
18
- ]
@@ -1,17 +0,0 @@
1
- # Generated by Django 5.1.1 on 2024-10-12 16:54
2
-
3
- from django.db import migrations
4
-
5
-
6
- class Migration(migrations.Migration):
7
-
8
- dependencies = [
9
- ('endoreg_db', '0009_alter_networkdevicelogentry_vpn_service_status'),
10
- ]
11
-
12
- operations = [
13
- migrations.RemoveField(
14
- model_name='networkdevicelogentry',
15
- name='hostname',
16
- ),
17
- ]
@@ -1,3 +0,0 @@
1
- from ..data_file.frame import LegacyFrame
2
- from .image import LegacyImage
3
- from ..data_file.video import LegacyVideo
@@ -1,34 +0,0 @@
1
- from django.db import models
2
- from ..label.label import Label
3
- from ..annotation.image_classification import ImageClassificationAnnotation
4
-
5
- class LegacyImage(models.Model):
6
- # Add any other fields you need to store frame-related information
7
- image = models.ImageField(upload_to="legacy_images") # Or some other field type, depending on how you're storing the frame
8
- suffix = models.CharField(max_length=255)
9
- # ImageClassificationAnnotation has a foreign key to this model (related name: image_classification_annotations)
10
-
11
- def get_classification_annotations(self):
12
- """
13
- Get all image classification annotations for this image.
14
- """
15
- return ImageClassificationAnnotation.objects.filter(legacy_image=self)
16
-
17
- def get_classification_annotations_by_label(self, label:Label):
18
- """
19
- Get all image classification annotations for this image with the given label.
20
- """
21
- return ImageClassificationAnnotation.objects.filter(legacy_image=self, label=label)
22
-
23
- def get_classification_annotations_by_value(self, value:bool):
24
- """
25
- Get all image classification annotations for this image with the given value.
26
- """
27
- return ImageClassificationAnnotation.objects.filter(legacy_image=self, value=value)
28
-
29
- def get_classification_annotations_by_label_and_value(self, label:Label, value:bool):
30
- """
31
- Get all image classification annotations for this image with the given label and value.
32
- """
33
- return ImageClassificationAnnotation.objects.filter(legacy_image=self, label=label, value=value)
34
-
@@ -1,35 +0,0 @@
1
- from django.db import models
2
-
3
- # Serializer located in serializers/examination.py
4
- class PatientExamination(models.Model):
5
- patient = models.ForeignKey('Patient', on_delete=models.CASCADE, related_name='patient_examinations')
6
- examination = models.ForeignKey('Examination', on_delete=models.CASCADE, null = True, blank = True)
7
- video = models.OneToOneField('Video', on_delete=models.CASCADE, null = True, blank = True, related_name='patient_examination')
8
- report_file = models.OneToOneField('ReportFile', on_delete=models.CASCADE, null = True, blank = True, related_name='patient_examination')
9
-
10
- class Meta:
11
- verbose_name = 'Patient Examination'
12
- verbose_name_plural = 'Patient Examinations'
13
- ordering = ['patient', 'examination']
14
-
15
- def __str__(self):
16
- return f"{self.patient} - {self.report_file}"
17
-
18
- def find_matching_video_from_patient(self):
19
- """
20
- Finds a video for this patient examination based on the patient's videos.
21
- For this, the videos date must be the same as the report file's date.
22
- #TODO add more criteria for matching: Examination type
23
- """
24
- videos = self.patient.video_set.filter(date=self.report_file.date, patient_examination__isnull=True)
25
- if videos:
26
- if len(videos) > 1:
27
- print(f"Warning: Found more than one video for patient {self.patient} on date {self.report_file.date}. Choosing the first one.")
28
- return videos[0]
29
- else:
30
- videos = self.patient.video_set.filter(patient_examination__isnull=True)
31
- if len(videos)==1:
32
- return videos[0]
33
-
34
- return None
35
-