endoreg-db 0.6.0__py3-none-any.whl → 0.6.2__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 (416) hide show
  1. endoreg_db/case_generator/__init__.py +0 -0
  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 +118 -0
  6. endoreg_db/data/agl_service/data.yaml +19 -0
  7. endoreg_db/data/ai_model/data.yaml +7 -0
  8. endoreg_db/data/ai_model_label/label/data.yaml +88 -0
  9. endoreg_db/data/ai_model_label/label-set/data.yaml +21 -0
  10. endoreg_db/data/ai_model_label/label-type/data.yaml +7 -0
  11. endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +5 -0
  12. endoreg_db/data/ai_model_type/data.yaml +7 -0
  13. endoreg_db/data/ai_model_video_segmentation_label/base_segmentation.yaml +176 -0
  14. endoreg_db/data/ai_model_video_segmentation_labelset/data.yaml +20 -0
  15. endoreg_db/data/case_template/rule/00_patient_lab_sample_add_default_value.yaml +167 -0
  16. endoreg_db/data/case_template/rule/01_patient-set-age.yaml +8 -0
  17. endoreg_db/data/case_template/rule/01_patient-set-gender.yaml +9 -0
  18. endoreg_db/data/case_template/rule/11_create_patient_lab_sample.yaml +23 -0
  19. endoreg_db/data/case_template/rule/12_create-patient_medication-anticoagulation.yaml +19 -0
  20. endoreg_db/data/case_template/rule/13_create-patient_medication_schedule-anticoagulation.yaml +19 -0
  21. endoreg_db/data/case_template/rule/19_create_patient.yaml +17 -0
  22. endoreg_db/data/case_template/rule_type/base_types.yaml +35 -0
  23. endoreg_db/data/case_template/rule_value/.init +0 -0
  24. endoreg_db/data/case_template/rule_value_type/base_types.yaml +59 -0
  25. endoreg_db/data/case_template/template/base.yaml +8 -0
  26. endoreg_db/data/case_template/template_type/pre_endoscopy.yaml +3 -0
  27. endoreg_db/data/case_template/tmp/_rule_value +13 -0
  28. endoreg_db/data/case_template/tmp/rule/01_atrial_fibrillation.yaml +21 -0
  29. endoreg_db/data/case_template/tmp/rule/02_create_object.yaml +10 -0
  30. endoreg_db/data/case_template/tmp/template/atrial_fibrillation_low_risk.yaml +7 -0
  31. endoreg_db/data/center/data.yaml +90 -0
  32. endoreg_db/data/center_resource/green_endoscopy_dashboard_CenterResource.yaml +144 -0
  33. endoreg_db/data/center_waste/green_endoscopy_dashboard_CenterWaste.yaml +48 -0
  34. endoreg_db/data/contraindication/bleeding.yaml +11 -0
  35. endoreg_db/data/disease/cardiovascular.yaml +37 -0
  36. endoreg_db/data/disease/hepatology.yaml +5 -0
  37. endoreg_db/data/disease/misc.yaml +6 -0
  38. endoreg_db/data/disease/renal.yaml +5 -0
  39. endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +6 -0
  40. endoreg_db/data/disease_classification/coronary_vessel_disease.yaml +6 -0
  41. endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +41 -0
  42. endoreg_db/data/disease_classification_choice/coronary_vessel_disease.yaml +20 -0
  43. endoreg_db/data/distribution/date/patient.yaml +7 -0
  44. endoreg_db/data/distribution/multiple_categorical/.init +0 -0
  45. endoreg_db/data/distribution/numeric/data.yaml +14 -0
  46. endoreg_db/data/distribution/single_categorical/patient.yaml +7 -0
  47. endoreg_db/data/emission_factor/green_endoscopy_dashboard_EmissionFactor.yaml +132 -0
  48. endoreg_db/data/endoscope/data.yaml +93 -0
  49. endoreg_db/data/endoscope_type/data.yaml +11 -0
  50. endoreg_db/data/endoscopy_processor/data.yaml +47 -0
  51. endoreg_db/data/event/cardiology.yaml +28 -0
  52. endoreg_db/data/event/neurology.yaml +14 -0
  53. endoreg_db/data/event/surgery.yaml +13 -0
  54. endoreg_db/data/event/thrombembolism.yaml +20 -0
  55. endoreg_db/data/examination/examinations/data.yaml +66 -0
  56. endoreg_db/data/examination/time/data.yaml +48 -0
  57. endoreg_db/data/examination/time-type/data.yaml +8 -0
  58. endoreg_db/data/examination/type/data.yaml +5 -0
  59. endoreg_db/data/examination_indication/endoscopy.yaml +8 -0
  60. endoreg_db/data/examination_indication_classification/endoscopy.yaml +8 -0
  61. endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +101 -0
  62. endoreg_db/data/finding/data.yaml +141 -0
  63. endoreg_db/data/finding_intervention/endoscopy.yaml +138 -0
  64. endoreg_db/data/finding_intervention_type/endoscopy.yaml +15 -0
  65. endoreg_db/data/finding_location_classification/colonoscopy.yaml +46 -0
  66. endoreg_db/data/finding_location_classification_choice/colonoscopy.yaml +240 -0
  67. endoreg_db/data/finding_morphology_classification/colonoscopy.yaml +48 -0
  68. endoreg_db/data/finding_morphology_classification_choice/colon_lesion_circularity_default.yaml +34 -0
  69. endoreg_db/data/finding_morphology_classification_choice/colon_lesion_nice.yaml +20 -0
  70. endoreg_db/data/finding_morphology_classification_choice/colon_lesion_paris.yaml +65 -0
  71. endoreg_db/data/finding_morphology_classification_choice/colon_lesion_planarity_default.yaml +56 -0
  72. endoreg_db/data/finding_morphology_classification_choice/colon_lesion_surface_intact_default.yaml +39 -0
  73. endoreg_db/data/finding_morphology_classification_choice/colonoscopy_size.yaml +57 -0
  74. endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +79 -0
  75. endoreg_db/data/finding_type/data.yaml +30 -0
  76. endoreg_db/data/gender/data.yaml +35 -0
  77. endoreg_db/data/information_source/data.yaml +30 -0
  78. endoreg_db/data/information_source/medication.yaml +6 -0
  79. endoreg_db/data/lab_value/cardiac_enzymes.yaml +37 -0
  80. endoreg_db/data/lab_value/coagulation.yaml +54 -0
  81. endoreg_db/data/lab_value/electrolytes.yaml +228 -0
  82. endoreg_db/data/lab_value/gastrointestinal_function.yaml +133 -0
  83. endoreg_db/data/lab_value/hematology.yaml +184 -0
  84. endoreg_db/data/lab_value/hormones.yaml +59 -0
  85. endoreg_db/data/lab_value/lipids.yaml +53 -0
  86. endoreg_db/data/lab_value/misc.yaml +33 -0
  87. endoreg_db/data/lab_value/renal_function.yaml +12 -0
  88. endoreg_db/data/log_type/data.yaml +57 -0
  89. endoreg_db/data/lx_client_tag/base.yaml +54 -0
  90. endoreg_db/data/lx_client_type/base.yaml +30 -0
  91. endoreg_db/data/lx_permission/base.yaml +24 -0
  92. endoreg_db/data/lx_permission/endoreg.yaml +52 -0
  93. endoreg_db/data/material/material.yaml +91 -0
  94. endoreg_db/data/medication/anticoagulation.yaml +65 -0
  95. endoreg_db/data/medication/tah.yaml +70 -0
  96. endoreg_db/data/medication_indication/anticoagulation.yaml +115 -0
  97. endoreg_db/data/medication_indication_type/data.yaml +11 -0
  98. endoreg_db/data/medication_indication_type/thrombembolism.yaml +41 -0
  99. endoreg_db/data/medication_intake_time/base.yaml +31 -0
  100. endoreg_db/data/medication_schedule/apixaban.yaml +95 -0
  101. endoreg_db/data/medication_schedule/ass.yaml +12 -0
  102. endoreg_db/data/medication_schedule/enoxaparin.yaml +26 -0
  103. endoreg_db/data/names_first/first_names.yaml +51 -0
  104. endoreg_db/data/names_last/last_names.yaml +51 -0
  105. endoreg_db/data/network_device/data.yaml +59 -0
  106. endoreg_db/data/network_device_type/data.yaml +12 -0
  107. endoreg_db/data/organ/data.yaml +29 -0
  108. endoreg_db/data/patient_lab_sample_type/generic.yaml +6 -0
  109. endoreg_db/data/pdf_type/data.yaml +29 -0
  110. endoreg_db/data/product/green_endoscopy_dashboard_Product.yaml +66 -0
  111. endoreg_db/data/product_group/green_endoscopy_dashboard_ProductGroup.yaml +33 -0
  112. endoreg_db/data/product_material/green_endoscopy_dashboard_ProductMaterial.yaml +308 -0
  113. endoreg_db/data/product_weight/green_endoscopy_dashboard_ProductWeight.yaml +88 -0
  114. endoreg_db/data/profession/data.yaml +70 -0
  115. endoreg_db/data/reference_product/green_endoscopy_dashboard_ReferenceProduct.yaml +55 -0
  116. endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +30 -0
  117. endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +19 -0
  118. endoreg_db/data/resource/green_endoscopy_dashboard_Resource.yaml +15 -0
  119. endoreg_db/data/tmp/chronic_kidney_disease.yaml +0 -0
  120. endoreg_db/data/tmp/congestive_heart_failure.yaml +0 -0
  121. endoreg_db/data/transport_route/green_endoscopy_dashboard_TransportRoute.yaml +12 -0
  122. endoreg_db/data/unit/concentration.yaml +92 -0
  123. endoreg_db/data/unit/data.yaml +17 -0
  124. endoreg_db/data/unit/length.yaml +31 -0
  125. endoreg_db/data/unit/misc.yaml +20 -0
  126. endoreg_db/data/unit/rate.yaml +6 -0
  127. endoreg_db/data/unit/time.yaml +13 -0
  128. endoreg_db/data/unit/volume.yaml +35 -0
  129. endoreg_db/data/unit/weight.yaml +38 -0
  130. endoreg_db/data/waste/data.yaml +12 -0
  131. endoreg_db/forms/__init__.py +5 -0
  132. endoreg_db/forms/examination_form.py +11 -0
  133. endoreg_db/forms/patient_finding_intervention_form.py +19 -0
  134. endoreg_db/forms/patient_form.py +26 -0
  135. endoreg_db/forms/questionnaires/__init__.py +1 -0
  136. endoreg_db/forms/questionnaires/tto_questionnaire.py +23 -0
  137. endoreg_db/forms/settings/__init__.py +8 -0
  138. endoreg_db/forms/unit.py +6 -0
  139. endoreg_db/management/__init__.py +0 -0
  140. endoreg_db/management/commands/__init__.py +0 -0
  141. endoreg_db/management/commands/_load_model_template.py +41 -0
  142. endoreg_db/management/commands/delete_all.py +18 -0
  143. endoreg_db/management/commands/fetch_legacy_image_dataset.py +32 -0
  144. endoreg_db/management/commands/fix_auth_permission.py +20 -0
  145. endoreg_db/management/commands/load_active_model_data.py +45 -0
  146. endoreg_db/management/commands/load_ai_model_data.py +79 -0
  147. endoreg_db/management/commands/load_ai_model_label_data.py +59 -0
  148. endoreg_db/management/commands/load_base_db_data.py +178 -0
  149. endoreg_db/management/commands/load_center_data.py +43 -0
  150. endoreg_db/management/commands/load_contraindication_data.py +41 -0
  151. endoreg_db/management/commands/load_disease_classification_choices_data.py +41 -0
  152. endoreg_db/management/commands/load_disease_classification_data.py +41 -0
  153. endoreg_db/management/commands/load_disease_data.py +62 -0
  154. endoreg_db/management/commands/load_distribution_data.py +66 -0
  155. endoreg_db/management/commands/load_endoscope_data.py +68 -0
  156. endoreg_db/management/commands/load_event_data.py +41 -0
  157. endoreg_db/management/commands/load_examination_data.py +75 -0
  158. endoreg_db/management/commands/load_examination_indication_data.py +65 -0
  159. endoreg_db/management/commands/load_finding_data.py +171 -0
  160. endoreg_db/management/commands/load_g_play_data.py +113 -0
  161. endoreg_db/management/commands/load_gender_data.py +44 -0
  162. endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +133 -0
  163. endoreg_db/management/commands/load_information_source.py +45 -0
  164. endoreg_db/management/commands/load_lab_value_data.py +50 -0
  165. endoreg_db/management/commands/load_logging_data.py +39 -0
  166. endoreg_db/management/commands/load_lx_data.py +64 -0
  167. endoreg_db/management/commands/load_medication_data.py +103 -0
  168. endoreg_db/management/commands/load_medication_indication_data.py +63 -0
  169. endoreg_db/management/commands/load_medication_indication_type_data.py +41 -0
  170. endoreg_db/management/commands/load_medication_intake_time_data.py +41 -0
  171. endoreg_db/management/commands/load_medication_schedule_data.py +55 -0
  172. endoreg_db/management/commands/load_name_data.py +37 -0
  173. endoreg_db/management/commands/load_network_data.py +57 -0
  174. endoreg_db/management/commands/load_organ_data.py +43 -0
  175. endoreg_db/management/commands/load_pdf_type_data.py +61 -0
  176. endoreg_db/management/commands/load_profession_data.py +44 -0
  177. endoreg_db/management/commands/load_report_reader_flag_data.py +46 -0
  178. endoreg_db/management/commands/load_unit_data.py +46 -0
  179. endoreg_db/management/commands/load_user_groups.py +28 -0
  180. endoreg_db/management/commands/register_ai_model.py +64 -0
  181. endoreg_db/management/commands/reset_celery_schedule.py +9 -0
  182. endoreg_db/migrations/0001_initial.py +2045 -0
  183. endoreg_db/migrations/0002_alter_frame_image_alter_rawframe_image.py +23 -0
  184. endoreg_db/migrations/0003_alter_frame_image_alter_rawframe_image.py +23 -0
  185. endoreg_db/migrations/0004_alter_rawvideofile_file_alter_video_file.py +25 -0
  186. endoreg_db/migrations/0005_rawvideofile_frame_count_and_more.py +33 -0
  187. endoreg_db/migrations/0006_frame_extracted_rawframe_extracted.py +23 -0
  188. endoreg_db/migrations/0007_rename_pseudo_patient_video_patient_and_more.py +24 -0
  189. endoreg_db/migrations/0008_remove_reportfile_patient_examination_and_more.py +48 -0
  190. endoreg_db/migrations/__init__.py +0 -0
  191. endoreg_db/models/__init__.py +376 -0
  192. endoreg_db/models/ai_model/__init__.py +4 -0
  193. endoreg_db/models/ai_model/active_model.py +9 -0
  194. endoreg_db/models/ai_model/ai_model.py +103 -0
  195. endoreg_db/models/ai_model/lightning/__init__.py +3 -0
  196. endoreg_db/models/ai_model/lightning/inference_dataset.py +53 -0
  197. endoreg_db/models/ai_model/lightning/multilabel_classification_net.py +155 -0
  198. endoreg_db/models/ai_model/lightning/postprocess.py +53 -0
  199. endoreg_db/models/ai_model/lightning/predict.py +172 -0
  200. endoreg_db/models/ai_model/lightning/prediction_visualizer.py +55 -0
  201. endoreg_db/models/ai_model/lightning/preprocess.py +68 -0
  202. endoreg_db/models/ai_model/lightning/run_visualizer.py +21 -0
  203. endoreg_db/models/ai_model/model_meta.py +250 -0
  204. endoreg_db/models/ai_model/model_type.py +36 -0
  205. endoreg_db/models/ai_model/utils.py +8 -0
  206. endoreg_db/models/annotation/__init__.py +32 -0
  207. endoreg_db/models/annotation/anonymized_image_annotation.py +115 -0
  208. endoreg_db/models/annotation/binary_classification_annotation_task.py +117 -0
  209. endoreg_db/models/annotation/image_classification.py +86 -0
  210. endoreg_db/models/annotation/video_segmentation_annotation.py +52 -0
  211. endoreg_db/models/annotation/video_segmentation_labelset.py +20 -0
  212. endoreg_db/models/case/__init__.py +1 -0
  213. endoreg_db/models/case/case.py +34 -0
  214. endoreg_db/models/case_template/__init__.py +15 -0
  215. endoreg_db/models/case_template/case_template.py +125 -0
  216. endoreg_db/models/case_template/case_template_rule.py +276 -0
  217. endoreg_db/models/case_template/case_template_rule_value.py +88 -0
  218. endoreg_db/models/case_template/case_template_type.py +28 -0
  219. endoreg_db/models/center/__init__.py +11 -0
  220. endoreg_db/models/center/center.py +51 -0
  221. endoreg_db/models/center/center_product.py +33 -0
  222. endoreg_db/models/center/center_resource.py +33 -0
  223. endoreg_db/models/center/center_waste.py +16 -0
  224. endoreg_db/models/contraindication/__init__.py +21 -0
  225. endoreg_db/models/data_file/__init__.py +39 -0
  226. endoreg_db/models/data_file/base_classes/__init__.py +7 -0
  227. endoreg_db/models/data_file/base_classes/abstract_frame.py +100 -0
  228. endoreg_db/models/data_file/base_classes/abstract_pdf.py +136 -0
  229. endoreg_db/models/data_file/base_classes/abstract_video.py +807 -0
  230. endoreg_db/models/data_file/base_classes/frame_helpers.py +17 -0
  231. endoreg_db/models/data_file/base_classes/prepare_bulk_frames.py +19 -0
  232. endoreg_db/models/data_file/base_classes/utils.py +80 -0
  233. endoreg_db/models/data_file/frame.py +29 -0
  234. endoreg_db/models/data_file/import_classes/__init__.py +18 -0
  235. endoreg_db/models/data_file/import_classes/processing_functions/__init__.py +35 -0
  236. endoreg_db/models/data_file/import_classes/processing_functions/pdf.py +28 -0
  237. endoreg_db/models/data_file/import_classes/processing_functions/video.py +260 -0
  238. endoreg_db/models/data_file/import_classes/raw_pdf.py +260 -0
  239. endoreg_db/models/data_file/import_classes/raw_video.py +288 -0
  240. endoreg_db/models/data_file/metadata/__init__.py +13 -0
  241. endoreg_db/models/data_file/metadata/pdf_meta.py +74 -0
  242. endoreg_db/models/data_file/metadata/sensitive_meta.py +290 -0
  243. endoreg_db/models/data_file/metadata/video_meta.py +199 -0
  244. endoreg_db/models/data_file/report_file.py +56 -0
  245. endoreg_db/models/data_file/video/__init__.py +11 -0
  246. endoreg_db/models/data_file/video/import_meta.py +25 -0
  247. endoreg_db/models/data_file/video/video.py +196 -0
  248. endoreg_db/models/data_file/video_segment.py +214 -0
  249. endoreg_db/models/disease.py +79 -0
  250. endoreg_db/models/emission/__init__.py +5 -0
  251. endoreg_db/models/emission/emission_factor.py +85 -0
  252. endoreg_db/models/event.py +73 -0
  253. endoreg_db/models/examination/__init__.py +9 -0
  254. endoreg_db/models/examination/examination.py +67 -0
  255. endoreg_db/models/examination/examination_indication.py +170 -0
  256. endoreg_db/models/examination/examination_time.py +53 -0
  257. endoreg_db/models/examination/examination_time_type.py +48 -0
  258. endoreg_db/models/examination/examination_type.py +40 -0
  259. endoreg_db/models/finding/__init__.py +11 -0
  260. endoreg_db/models/finding/finding.py +75 -0
  261. endoreg_db/models/finding/finding_intervention.py +60 -0
  262. endoreg_db/models/finding/finding_location_classification.py +94 -0
  263. endoreg_db/models/finding/finding_morphology_classification.py +89 -0
  264. endoreg_db/models/finding/finding_type.py +22 -0
  265. endoreg_db/models/hardware/__init__.py +2 -0
  266. endoreg_db/models/hardware/endoscope.py +60 -0
  267. endoreg_db/models/hardware/endoscopy_processor.py +155 -0
  268. endoreg_db/models/information_source.py +29 -0
  269. endoreg_db/models/label/__init__.py +1 -0
  270. endoreg_db/models/label/label.py +112 -0
  271. endoreg_db/models/laboratory/__init__.py +1 -0
  272. endoreg_db/models/laboratory/lab_value.py +111 -0
  273. endoreg_db/models/logging/__init__.py +11 -0
  274. endoreg_db/models/logging/agl_service.py +19 -0
  275. endoreg_db/models/logging/base.py +22 -0
  276. endoreg_db/models/logging/log_type.py +23 -0
  277. endoreg_db/models/logging/network_device.py +27 -0
  278. endoreg_db/models/lx/__init__.py +4 -0
  279. endoreg_db/models/lx/client.py +57 -0
  280. endoreg_db/models/lx/identity.py +34 -0
  281. endoreg_db/models/lx/permission.py +18 -0
  282. endoreg_db/models/lx/user.py +16 -0
  283. endoreg_db/models/medication/__init__.py +19 -0
  284. endoreg_db/models/medication/medication.py +33 -0
  285. endoreg_db/models/medication/medication_indication.py +50 -0
  286. endoreg_db/models/medication/medication_indication_type.py +34 -0
  287. endoreg_db/models/medication/medication_intake_time.py +26 -0
  288. endoreg_db/models/medication/medication_schedule.py +37 -0
  289. endoreg_db/models/network/__init__.py +9 -0
  290. endoreg_db/models/network/agl_service.py +38 -0
  291. endoreg_db/models/network/network_device.py +58 -0
  292. endoreg_db/models/network/network_device_type.py +23 -0
  293. endoreg_db/models/organ/__init__.py +38 -0
  294. endoreg_db/models/other/__init__.py +23 -0
  295. endoreg_db/models/other/distribution/__init__.py +44 -0
  296. endoreg_db/models/other/distribution/base_value_distribution.py +20 -0
  297. endoreg_db/models/other/distribution/date_value_distribution.py +91 -0
  298. endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +32 -0
  299. endoreg_db/models/other/distribution/numeric_value_distribution.py +97 -0
  300. endoreg_db/models/other/distribution/single_categorical_value_distribution.py +22 -0
  301. endoreg_db/models/other/distribution.py +5 -0
  302. endoreg_db/models/other/material.py +20 -0
  303. endoreg_db/models/other/resource.py +18 -0
  304. endoreg_db/models/other/transport_route.py +22 -0
  305. endoreg_db/models/other/waste.py +20 -0
  306. endoreg_db/models/patient/__init__.py +24 -0
  307. endoreg_db/models/patient/patient_examination.py +182 -0
  308. endoreg_db/models/patient/patient_finding.py +143 -0
  309. endoreg_db/models/patient/patient_finding_intervention.py +26 -0
  310. endoreg_db/models/patient/patient_finding_location.py +120 -0
  311. endoreg_db/models/patient/patient_finding_morphology.py +166 -0
  312. endoreg_db/models/permissions/__init__.py +44 -0
  313. endoreg_db/models/persons/__init__.py +34 -0
  314. endoreg_db/models/persons/examiner/__init__.py +2 -0
  315. endoreg_db/models/persons/examiner/examiner.py +60 -0
  316. endoreg_db/models/persons/examiner/examiner_type.py +2 -0
  317. endoreg_db/models/persons/first_name.py +18 -0
  318. endoreg_db/models/persons/gender.py +22 -0
  319. endoreg_db/models/persons/last_name.py +20 -0
  320. endoreg_db/models/persons/patient/__init__.py +8 -0
  321. endoreg_db/models/persons/patient/patient.py +389 -0
  322. endoreg_db/models/persons/patient/patient_disease.py +22 -0
  323. endoreg_db/models/persons/patient/patient_event.py +52 -0
  324. endoreg_db/models/persons/patient/patient_examination_indication.py +32 -0
  325. endoreg_db/models/persons/patient/patient_lab_sample.py +108 -0
  326. endoreg_db/models/persons/patient/patient_lab_value.py +197 -0
  327. endoreg_db/models/persons/patient/patient_medication.py +59 -0
  328. endoreg_db/models/persons/patient/patient_medication_schedule.py +88 -0
  329. endoreg_db/models/persons/person.py +31 -0
  330. endoreg_db/models/persons/portal_user_information.py +27 -0
  331. endoreg_db/models/prediction/__init__.py +8 -0
  332. endoreg_db/models/prediction/image_classification.py +51 -0
  333. endoreg_db/models/prediction/video_prediction_meta.py +306 -0
  334. endoreg_db/models/product/__init__.py +14 -0
  335. endoreg_db/models/product/product.py +110 -0
  336. endoreg_db/models/product/product_group.py +27 -0
  337. endoreg_db/models/product/product_material.py +28 -0
  338. endoreg_db/models/product/product_weight.py +38 -0
  339. endoreg_db/models/product/reference_product.py +115 -0
  340. endoreg_db/models/questionnaires/__init__.py +114 -0
  341. endoreg_db/models/quiz/__init__.py +9 -0
  342. endoreg_db/models/quiz/quiz_answer.py +41 -0
  343. endoreg_db/models/quiz/quiz_question.py +54 -0
  344. endoreg_db/models/report_reader/__init__.py +7 -0
  345. endoreg_db/models/report_reader/report_reader_config.py +53 -0
  346. endoreg_db/models/report_reader/report_reader_flag.py +20 -0
  347. endoreg_db/models/rules/__init__.py +5 -0
  348. endoreg_db/models/rules/rule.py +24 -0
  349. endoreg_db/models/rules/rule_applicator.py +224 -0
  350. endoreg_db/models/rules/rule_attribute_dtype.py +19 -0
  351. endoreg_db/models/rules/rule_type.py +22 -0
  352. endoreg_db/models/rules/ruleset.py +19 -0
  353. endoreg_db/models/unit.py +22 -0
  354. endoreg_db/queries/__init__.py +5 -0
  355. endoreg_db/queries/annotations/__init__.py +3 -0
  356. endoreg_db/queries/annotations/legacy.py +158 -0
  357. endoreg_db/queries/get/__init__.py +6 -0
  358. endoreg_db/queries/get/annotation.py +0 -0
  359. endoreg_db/queries/get/center.py +42 -0
  360. endoreg_db/queries/get/model.py +13 -0
  361. endoreg_db/queries/get/patient.py +14 -0
  362. endoreg_db/queries/get/patient_examination.py +20 -0
  363. endoreg_db/queries/get/prediction.py +0 -0
  364. endoreg_db/queries/get/report_file.py +33 -0
  365. endoreg_db/queries/get/video.py +31 -0
  366. endoreg_db/queries/get/video_import_meta.py +0 -0
  367. endoreg_db/queries/get/video_prediction_meta.py +0 -0
  368. endoreg_db/queries/sanity/__init_.py +0 -0
  369. endoreg_db/serializers/__init__.py +10 -0
  370. endoreg_db/serializers/ai_model.py +19 -0
  371. endoreg_db/serializers/annotation.py +14 -0
  372. endoreg_db/serializers/center.py +11 -0
  373. endoreg_db/serializers/examination.py +33 -0
  374. endoreg_db/serializers/frame.py +9 -0
  375. endoreg_db/serializers/hardware.py +21 -0
  376. endoreg_db/serializers/label.py +22 -0
  377. endoreg_db/serializers/patient.py +33 -0
  378. endoreg_db/serializers/prediction.py +10 -0
  379. endoreg_db/serializers/raw_video_meta_validation.py +13 -0
  380. endoreg_db/serializers/report_file.py +7 -0
  381. endoreg_db/serializers/video.py +20 -0
  382. endoreg_db/serializers/video_segmentation.py +492 -0
  383. endoreg_db/templates/admin/patient_finding_intervention.html +253 -0
  384. endoreg_db/templates/admin/start_examination.html +12 -0
  385. endoreg_db/templates/timeline.html +176 -0
  386. endoreg_db/utils/__init__.py +36 -0
  387. endoreg_db/utils/cropping.py +29 -0
  388. endoreg_db/utils/dataloader.py +118 -0
  389. endoreg_db/utils/dates.py +39 -0
  390. endoreg_db/utils/file_operations.py +30 -0
  391. endoreg_db/utils/hashs.py +152 -0
  392. endoreg_db/utils/legacy_ocr.py +201 -0
  393. endoreg_db/utils/names.py +74 -0
  394. endoreg_db/utils/ocr.py +190 -0
  395. endoreg_db/utils/parse_and_generate_yaml.py +46 -0
  396. endoreg_db/utils/pydantic_models/__init__.py +6 -0
  397. endoreg_db/utils/pydantic_models/db_config.py +57 -0
  398. endoreg_db/utils/uuid.py +4 -0
  399. endoreg_db/utils/validate_endo_roi.py +19 -0
  400. endoreg_db/utils/validate_subcategory_dict.py +91 -0
  401. endoreg_db/utils/video/__init__.py +13 -0
  402. endoreg_db/utils/video/extract_frames.py +121 -0
  403. endoreg_db/utils/video/transcode_videofile.py +111 -0
  404. endoreg_db/views/__init__.py +2 -0
  405. endoreg_db/views/csrf.py +7 -0
  406. endoreg_db/views/patient_views.py +90 -0
  407. endoreg_db/views/raw_video_meta_validation_views.py +38 -0
  408. endoreg_db/views/report_views.py +96 -0
  409. endoreg_db/views/video_segmentation_views.py +149 -0
  410. endoreg_db/views/views_for_timeline.py +46 -0
  411. {endoreg_db-0.6.0.dist-info → endoreg_db-0.6.2.dist-info}/METADATA +14 -4
  412. endoreg_db-0.6.2.dist-info/RECORD +420 -0
  413. {endoreg_db-0.6.0.dist-info → endoreg_db-0.6.2.dist-info}/WHEEL +1 -2
  414. endoreg_db-0.6.0.dist-info/RECORD +0 -11
  415. endoreg_db-0.6.0.dist-info/top_level.txt +0 -1
  416. {endoreg_db-0.6.0.dist-info → endoreg_db-0.6.2.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,253 @@
1
+ {% extends "admin/base_site.html" %}
2
+ {% block content %}
3
+
4
+ <h2>Patient Finding Intervention</h2>
5
+
6
+ <form method="POST" id="intervention-form">
7
+ {% csrf_token %}
8
+
9
+ <!-- Patient Selection -->
10
+ <div>
11
+ <label>Select Patient:</label><br>
12
+ <select name="patient" id="patient-dropdown">
13
+ <option value="">-- Select Patient --</option>
14
+ {% for patient in patients %}
15
+ <option value="{{ patient.id }}">{{ patient.first_name }} {{ patient.last_name }}</option>
16
+ {% endfor %}
17
+ </select>
18
+ </div>
19
+
20
+ <br>
21
+
22
+ <!-- Examination Selection -->
23
+ <div>
24
+ <label>Select Examination:</label><br>
25
+ <select name="examination" id="examination-dropdown">
26
+ <option value="">-- Select Examination --</option>
27
+ {% for examination in examinations %}
28
+ <option value="{{ examination.id }}">{{ examination.name }}</option>
29
+ {% endfor %}
30
+ </select>
31
+ </div>
32
+
33
+ <br>
34
+
35
+ <!-- Finding Selection -->
36
+ <div>
37
+ <label>Select Finding:</label><br>
38
+ <select name="finding" id="finding-dropdown">
39
+ <option value="">-- Select Finding --</option>
40
+ {% for finding in findings %}
41
+ <option value="{{ finding.id }}">{{ finding.name }}</option>
42
+ {% endfor %}
43
+ </select>
44
+ </div>
45
+
46
+ <br>
47
+
48
+ <!-- Select Location -->
49
+ <div>
50
+ <label>Select Location:</label><br>
51
+ <select name="location" id="location-dropdown" onchange="updateFormAction(this)">
52
+ <option value="">-- Select Location --</option>
53
+ {% for location in locations %}
54
+ <option value="{{ location.id }}" {% if location.id == selected_location %}selected{% endif %}>
55
+ {{ location.name }}
56
+ </option>
57
+ {% endfor %}
58
+ </select>
59
+ </div>
60
+
61
+ <br>
62
+
63
+ <!-- Select Location Choice -->
64
+ <div>
65
+ <label>Select Location Choice:</label><br>
66
+ <select name="location_choice" id="location-choice-dropdown">
67
+ <option value="">-- Select Location Choice --</option>
68
+ {% for choice in location_choices %}
69
+ <option value="{{ choice.id }}">{{ choice.name }}</option>
70
+ {% endfor %}
71
+ </select>
72
+ </div>
73
+
74
+ <br>
75
+
76
+ <!-- Select Morphology -->
77
+ <!-- Select Morphology (FindingMorphologyClassification) -->
78
+ <div>
79
+ <label>Select Morphology:</label><br>
80
+ <select name="morphology" id="morphology-dropdown">
81
+ <option value="">-- Select Morphology --</option>
82
+ {% for morphology in morphologies %}
83
+ <option value="{{ morphology.id }}">{{ morphology.name }}</option>
84
+ {% endfor %}
85
+ </select>
86
+ </div>
87
+
88
+ <br>
89
+
90
+ <!-- Select Morphology Choice (FindingMorphologyClassificationChoice) -->
91
+ <div>
92
+ <label>Select Morphology Choice:</label><br>
93
+ <select name="morphology_choice" id="morphology-choice-dropdown">
94
+ <option value="">-- Select Morphology Choice --</option>
95
+ {% for choice in morphology_choices %}
96
+ <option value="{{ choice.id }}">{{ choice.name }}</option>
97
+ {% endfor %}
98
+ </select>
99
+ </div>
100
+
101
+
102
+ <br>
103
+
104
+ <!-- Select Finding Interventions -->
105
+ <div>
106
+ <label>Select Finding Interventions:</label><br>
107
+ <select name="finding_intervention" id="finding-intervention-dropdown">
108
+ <option value="">-- Select Finding Intervention --</option>
109
+ {% for intervention in finding_interventions %}
110
+ <option value="{{ intervention.id }}">{{ intervention.name }}</option>
111
+ {% endfor %}
112
+ </select>
113
+ </div>
114
+
115
+ <br>
116
+
117
+ <div>
118
+ <button type="button" id="generate-report-btn">Generate Report</button>
119
+ </div>
120
+
121
+ <!-- Display Report Section -->
122
+ <div id="report-section" style="display:none; margin-top: 20px;">
123
+ <h3>Generated Report</h3>
124
+ <p><strong>Patient:</strong> <span id="report-patient"></span></p>
125
+ <p><strong>Examination:</strong> <span id="report-examination"></span></p>
126
+ <p><strong>Finding:</strong> <span id="report-finding"></span></p>
127
+ <p><strong>Location:</strong> <span id="report-location"></span></p>
128
+ <p><strong>Location Choice:</strong> <span id="report-location-choice"></span></p>
129
+ <p><strong>Morphology:</strong> <span id="report-morphology"></span></p>
130
+ <p><strong>Morphology Choice:</strong> <span id="report-morphology-choice"></span></p>
131
+ <p><strong>Finding Intervention:</strong> <span id="report-finding-intervention"></span></p>
132
+
133
+ <button id="download-report-btn">Download Report</button>
134
+ </div>
135
+
136
+ </form>
137
+
138
+ <script>
139
+ document.getElementById("location-dropdown").addEventListener("change", function() {
140
+ let locationId = this.value;
141
+ let locationChoiceDropdown = document.getElementById("location-choice-dropdown");
142
+
143
+ // Reset dropdown
144
+ locationChoiceDropdown.innerHTML = '<option value="">-- Select Location Choice --</option>';
145
+
146
+ // Fetch Choices Only If a Location is Selected
147
+ if (locationId) {
148
+ fetch(`/endoreg_db/get-location-choices/${locationId}/`)
149
+ .then(response => response.json())
150
+ .then(data => {
151
+ if (data.location_choices.length === 0) {
152
+ locationChoiceDropdown.innerHTML = `<option value="default">Rectum</option>`; // Default Value
153
+ } else {
154
+ data.location_choices.forEach(choice => {
155
+ locationChoiceDropdown.innerHTML += `<option value="${choice.id}">${choice.name}</option>`;
156
+ });
157
+ }
158
+ })
159
+ .catch(error => {
160
+ console.error("Error loading location choices:", error);
161
+ alert("Error: Could not fetch location choices.");
162
+ });
163
+ } else {
164
+ locationChoiceDropdown.innerHTML = `<option value="default">Rectum</option>`; // Default Value
165
+ }
166
+ });
167
+ </script>
168
+
169
+
170
+ <script>
171
+ document.getElementById("generate-report-btn").addEventListener("click", function() {
172
+ let getText = (id, defaultValue = "Not Selected") => {
173
+ let element = document.getElementById(id);
174
+ return element.selectedOptions.length > 0 ? element.selectedOptions[0].text.trim() : defaultValue;
175
+ };
176
+
177
+ document.getElementById("report-patient").textContent = getText("patient-dropdown");
178
+ document.getElementById("report-examination").textContent = getText("examination-dropdown");
179
+ document.getElementById("report-finding").textContent = getText("finding-dropdown");
180
+ document.getElementById("report-location").textContent = getText("location-dropdown");
181
+ document.getElementById("report-location-choice").textContent = getText("location-choice-dropdown", "Rectum");
182
+ document.getElementById("report-morphology").textContent = getText("morphology-dropdown");
183
+ document.getElementById("report-morphology-choice").textContent = getText("morphology-choice-dropdown");
184
+ document.getElementById("report-finding-intervention").textContent = getText("finding-intervention-dropdown");
185
+
186
+ document.getElementById("report-section").style.display = "block";
187
+ });
188
+
189
+ document.getElementById("download-report-btn").addEventListener("click", function() {
190
+ let reportContent = `
191
+ Patient: ${document.getElementById("report-patient").textContent}
192
+ Examination: ${document.getElementById("report-examination").textContent}
193
+ Finding: ${document.getElementById("report-finding").textContent}
194
+ Location: ${document.getElementById("report-location").textContent}
195
+ Location Choice: ${document.getElementById("report-location-choice").textContent}
196
+ Morphology: ${document.getElementById("report-morphology").textContent}
197
+ Morphology Choice: ${document.getElementById("report-morphology-choice").textContent}
198
+ Finding Intervention: ${document.getElementById("report-finding-intervention").textContent}
199
+ `;
200
+
201
+ let blob = new Blob([reportContent], { type: "text/plain" });
202
+ let link = document.createElement("a");
203
+ link.href = URL.createObjectURL(blob);
204
+ link.download = "Patient_Finding_Report.txt";
205
+ document.body.appendChild(link);
206
+ link.click();
207
+ document.body.removeChild(link);
208
+ });
209
+ </script>
210
+
211
+ <script>
212
+ document.getElementById("morphology-dropdown").addEventListener("change", function() {
213
+ let morphologyId = this.value;
214
+ let morphologyChoiceDropdown = document.getElementById("morphology-choice-dropdown");
215
+
216
+ // Reset Morphology Choice Dropdown
217
+ morphologyChoiceDropdown.innerHTML = '<option value="">-- Select Morphology Choice --</option>';
218
+
219
+ // Fetch Choices Only If a Morphology is Selected
220
+ if (morphologyId) {
221
+ fetch(`/endoreg_db/get-morphology-choices/${morphologyId}/`)
222
+ .then(response => {
223
+ if (!response.ok) {
224
+ throw new Error(`HTTP error! Status: ${response.status}`);
225
+ }
226
+ return response.json();
227
+ })
228
+ .then(data => {
229
+ if (data.error) {
230
+ console.error("Server Error:", data.error);
231
+ alert("Error: " + data.error);
232
+ } else {
233
+ if (data.morphology_choices.length === 0) {
234
+ morphologyChoiceDropdown.innerHTML = `<option value="default">No Choices Available</option>`; // Default Value
235
+ } else {
236
+ data.morphology_choices.forEach(choice => {
237
+ morphologyChoiceDropdown.innerHTML += `<option value="${choice.id}">${choice.name}</option>`;
238
+ });
239
+ }
240
+ }
241
+ })
242
+ .catch(error => {
243
+ console.error("Error loading morphology choices:", error);
244
+ alert("Error: Could not fetch morphology choices.");
245
+ });
246
+ }
247
+ });
248
+ </script>
249
+
250
+
251
+
252
+
253
+ {% endblock %}
@@ -0,0 +1,12 @@
1
+ <!-- start_examination.html -->
2
+ <!DOCTYPE html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Start Examination</title>
8
+ </head>
9
+ <body>
10
+ <h1>Hello World</h1>
11
+ </body>
12
+ </html>
@@ -0,0 +1,176 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>Frames Timeline (Outside Label)</title>
5
+ <style>
6
+ body { font-family: Arial, sans-serif; text-align: center; margin: 20px; }
7
+ video { width: 80%; margin-bottom: 20px; }
8
+
9
+ /* Timeline Container */
10
+ .timeline-container {
11
+ position: relative;
12
+ width: 80%;
13
+ height: 50px;
14
+ margin: auto;
15
+ background: #f0f0f0;
16
+ border-radius: 5px;
17
+ }
18
+
19
+ /* Timeline Bar */
20
+ .timeline-bar {
21
+ width: 100%;
22
+ height: 8px;
23
+ background-color: #ccc;
24
+ position: absolute;
25
+ top: 50%;
26
+ transform: translateY(-50%);
27
+ border-radius: 4px;
28
+ }
29
+
30
+ /* Red Highlight for Outside Label Segments */
31
+ .segment-box {
32
+ position: absolute;
33
+ height: 8px;
34
+ background-color: rgba(255, 0, 0, 0.7);
35
+ border-radius: 4px;
36
+ top: 50%;
37
+ transform: translateY(-50%);
38
+ cursor: pointer;
39
+ }
40
+
41
+ /* Draggable Vertical Markers */
42
+ .frame-marker {
43
+ position: absolute;
44
+ width: 6px;
45
+ height: 20px;
46
+ background-color: blue;
47
+ cursor: grab;
48
+ top: 50%;
49
+ transform: translate(-50%, -50%);
50
+ border-radius: 3px;
51
+ transition: background-color 0.2s;
52
+ }
53
+
54
+ .frame-marker:hover {
55
+ background-color: red;
56
+ }
57
+
58
+ .frame-marker:active {
59
+ cursor: grabbing;
60
+ }
61
+
62
+ </style>
63
+ </head>
64
+ <body>
65
+ <h2>Frames Timeline (Outside Label)</h2>
66
+
67
+ <video id="videoPlayer" controls>
68
+ <source src="{{ video_url }}" type="video/mp4">
69
+ Your browser does not support the video tag.
70
+ </video>
71
+
72
+ <div class="timeline-container">
73
+ <div class="timeline-bar"></div>
74
+ <div id="segments"></div> <!-- Highlighted segments -->
75
+ <div id="frameMarkers"></div> <!-- Start & End markers -->
76
+ </div>
77
+
78
+ <script>
79
+ document.addEventListener("DOMContentLoaded", function () {
80
+ const segments = JSON.parse('{{ segments|safe }}'); // Get "outside" label segments
81
+ const video = document.getElementById("videoPlayer");
82
+ const timelineContainer = document.querySelector(".timeline-container");
83
+ const segmentsContainer = document.getElementById("segments");
84
+ const frameMarkersContainer = document.getElementById("frameMarkers");
85
+
86
+ let videoDuration = {{ video_duration|default:1 }}; // Ensure valid duration
87
+
88
+ console.log("Loaded Segments:", segments);
89
+ console.log("Video Duration:", videoDuration);
90
+
91
+ if (segments.length === 0) {
92
+ console.warn("No segments available!");
93
+ return;
94
+ }
95
+
96
+ // Create segment boxes
97
+ segments.forEach(segment => {
98
+ const segmentDiv = document.createElement("div");
99
+ segmentDiv.classList.add("segment-box");
100
+
101
+ // Convert times to percentage positions
102
+ let startPercent = (segment.start_time / videoDuration) * 100;
103
+ let endPercent = (segment.end_time / videoDuration) * 100;
104
+ let widthPercent = endPercent - startPercent;
105
+
106
+ // Ensure last segment does not go beyond 100%
107
+ startPercent = Math.min(100, startPercent);
108
+ endPercent = Math.min(100, endPercent);
109
+ widthPercent = Math.max(0, endPercent - startPercent);
110
+
111
+ segmentDiv.style.left = startPercent + "%";
112
+ segmentDiv.style.width = widthPercent + "%";
113
+
114
+ // Clicking on segment seeks video
115
+ segmentDiv.addEventListener("click", function () {
116
+ video.currentTime = segment.start_time;
117
+ video.play();
118
+ });
119
+
120
+ segmentsContainer.appendChild(segmentDiv);
121
+ });
122
+
123
+ // Create draggable markers
124
+ segments.forEach(segment => {
125
+ ["start_time", "end_time"].forEach(timeType => {
126
+ const marker = document.createElement("div");
127
+ marker.classList.add("frame-marker");
128
+
129
+ // Position marker
130
+ let percent = (segment[timeType] / videoDuration) * 100;
131
+ percent = Math.min(100, Math.max(0, percent)); // Keep within bounds
132
+ marker.style.left = percent + "%";
133
+
134
+ // Store initial marker time
135
+ marker.dataset.time = segment[timeType];
136
+
137
+ // Enable dragging
138
+ let isDragging = false;
139
+
140
+ marker.addEventListener("pointerdown", (event) => {
141
+ isDragging = true;
142
+ marker.style.cursor = "grabbing";
143
+ event.preventDefault();
144
+ });
145
+
146
+ document.addEventListener("pointermove", (event) => {
147
+ if (!isDragging) return;
148
+
149
+ const rect = timelineContainer.getBoundingClientRect();
150
+ const offsetX = event.clientX - rect.left;
151
+ let percentX = (offsetX / rect.width) * 100;
152
+
153
+ // Keep marker within bounds (0-100%)
154
+ percentX = Math.min(100, Math.max(0, percentX));
155
+
156
+ const newTime = (percentX / 100) * videoDuration;
157
+
158
+ marker.style.left = percentX + "%";
159
+ video.currentTime = newTime;
160
+ });
161
+
162
+ document.addEventListener("pointerup", () => {
163
+ if (isDragging) {
164
+ isDragging = false;
165
+ marker.style.cursor = "grab";
166
+ }
167
+ });
168
+
169
+ frameMarkersContainer.appendChild(marker);
170
+ });
171
+ });
172
+
173
+ });
174
+ </script>
175
+ </body>
176
+ </html>
@@ -0,0 +1,36 @@
1
+ """Module for utility classes and functions."""
2
+
3
+ from .dataloader import load_model_data_from_yaml
4
+ from .parse_and_generate_yaml import collect_center_names
5
+ from .validate_endo_roi import validate_endo_roi
6
+ from .pydantic_models import DbConfig
7
+ from .dates import random_day_by_month_year, random_day_by_year
8
+ from .hashs import (
9
+ get_hash_string,
10
+ get_pdf_hash,
11
+ get_examiner_hash,
12
+ get_video_hash,
13
+ get_patient_examination_hash,
14
+ )
15
+ from .names import (
16
+ create_mock_patient_name,
17
+ create_mock_examiner_name,
18
+ guess_name_gender,
19
+ )
20
+
21
+ __all__ = [
22
+ "load_model_data_from_yaml",
23
+ "collect_center_names",
24
+ "validate_endo_roi",
25
+ "get_examiner_hash",
26
+ "DbConfig",
27
+ "random_day_by_month_year",
28
+ "random_day_by_year",
29
+ "get_hash_string",
30
+ "create_mock_examiner_name",
31
+ "create_mock_patient_name",
32
+ "guess_name_gender",
33
+ "get_pdf_hash",
34
+ "get_video_hash",
35
+ "get_patient_examination_hash",
36
+ ]
@@ -0,0 +1,29 @@
1
+ from PIL import Image
2
+
3
+ def crop_and_insert(image:Image, x, y, h, w, bg_color=(255, 255, 255)):
4
+ """
5
+ Crops a region from an inverted grayscale image and inserts it into a white image of the same size as the original.
6
+
7
+ Parameters:
8
+ - fp: File path or a file object of the original image.
9
+ - x, y: The top-left coordinates of the rectangle to be cropped.
10
+ - h, w: The height and width of the rectangle to be cropped.
11
+
12
+ Returns:
13
+ A PIL Image object containing the original image with the specified region replaced.
14
+ """
15
+ # Load the original image
16
+ original_image = image
17
+
18
+ # Crop the specified region from the inverted image
19
+ crop_rectangle = (x, y, x + w, y + h)
20
+ cropped_content = original_image.crop(crop_rectangle)
21
+
22
+ # Create a new white image of the same size as the original image
23
+ white_background = Image.new('RGB', original_image.size, bg_color)
24
+
25
+ # Paste the cropped content onto the white image at the specified location
26
+ white_background.paste(cropped_content, (x, y))
27
+
28
+ # The final image can be displayed or saved as needed
29
+ return white_background
@@ -0,0 +1,118 @@
1
+ import os
2
+ import yaml
3
+ from django.core.exceptions import ObjectDoesNotExist
4
+
5
+ from icecream import ic
6
+
7
+
8
+ def load_model_data_from_yaml(command, model_name, metadata, verbose):
9
+ """
10
+ Load model data from YAML files.
11
+
12
+ Args:
13
+ command: Command object for stdout writing.
14
+ model_name: Name of the model being loaded.
15
+ metadata: Metadata including directory and foreign key information.
16
+ verbose: Boolean indicating whether to print verbose output.
17
+ """
18
+ if verbose:
19
+ command.stdout.write(f"Start loading {model_name}")
20
+ model = metadata["model"]
21
+ dir_path = metadata["dir"]
22
+ foreign_keys = metadata["foreign_keys"]
23
+ foreign_key_models = metadata["foreign_key_models"]
24
+
25
+ _files = [f for f in os.listdir(dir_path) if f.endswith(".yaml")]
26
+ # sort
27
+ _files.sort()
28
+ for file in _files:
29
+ with open(os.path.join(dir_path, file), "r", encoding="utf-8") as file:
30
+ yaml_data = yaml.safe_load(file)
31
+
32
+ load_data_with_foreign_keys(
33
+ command, model, yaml_data, foreign_keys, foreign_key_models, verbose
34
+ )
35
+
36
+
37
+ def load_data_with_foreign_keys(
38
+ command, model, yaml_data, foreign_keys, foreign_key_models, verbose
39
+ ):
40
+ """
41
+ Load data handling foreign keys and many-to-many relationships.
42
+
43
+ Args:
44
+ command: Command object for stdout writing.
45
+ model: The Django model for the data.
46
+ yaml_data: Data loaded from YAML.
47
+ foreign_keys: List of foreign keys.
48
+ foreign_key_models: Corresponding models for the foreign keys.
49
+ verbose: Boolean indicating whether to print verbose output.
50
+ """
51
+ for entry in yaml_data:
52
+ fields = entry.get("fields", {})
53
+ name = fields.pop("name", None)
54
+ m2m_relationships = {} # Store many-to-many relationships
55
+ # print(entry)
56
+
57
+ # Handle foreign keys and many-to-many relationships
58
+ for fk_field, fk_model in zip(foreign_keys, foreign_key_models):
59
+ # print(fk_field, fk_model)
60
+ target_keys = fields.pop(fk_field, None)
61
+
62
+ # Ensure the foreign key exists
63
+ if target_keys is None:
64
+ if verbose:
65
+ command.stdout.write(
66
+ command.style.WARNING(
67
+ f"Foreign key {fk_field} not found in fields"
68
+ )
69
+ )
70
+ continue # Skip if no foreign key provided
71
+
72
+ # Process many-to-many fields or foreign keys
73
+ if isinstance(target_keys, list): # Assume many-to-many relationship
74
+ related_objects = []
75
+ for key in target_keys:
76
+ obj, created = fk_model.objects.get_or_create(name=key)
77
+ if created and verbose:
78
+ command.stdout.write(
79
+ command.style.SUCCESS(f"Created {fk_model.__name__} {key}")
80
+ )
81
+ related_objects.append(obj)
82
+ m2m_relationships[fk_field] = related_objects
83
+ else: # Single foreign key relationship
84
+ try:
85
+ if model == "endoreg_db.case_template_rule":
86
+ # print(fk_model, target_keys)
87
+ pass
88
+ obj = fk_model.objects.get_by_natural_key(target_keys)
89
+ except ObjectDoesNotExist:
90
+ if verbose:
91
+ command.stdout.write(
92
+ command.style.WARNING(
93
+ f"{fk_model.__name__} with key {target_keys} not found"
94
+ )
95
+ )
96
+ continue
97
+ fields[fk_field] = obj
98
+
99
+ # Create or update the main object
100
+ if name is None:
101
+ obj, created = model.objects.get_or_create(**fields)
102
+ else:
103
+ obj, created = model.objects.update_or_create(defaults=fields, name=name)
104
+ if created and verbose:
105
+ command.stdout.write(
106
+ command.style.SUCCESS(f"Created {model.__name__} {name}")
107
+ )
108
+ elif verbose:
109
+ pass
110
+ # command.stdout.write(
111
+ # command.style.WARNING(
112
+ # f"Skipped {model.__name__} {name}, already exists"
113
+ # )
114
+ # )
115
+
116
+ # Set many-to-many relationships
117
+ for field_name, related_objs in m2m_relationships.items():
118
+ getattr(obj, field_name).set(related_objs)
@@ -0,0 +1,39 @@
1
+ from datetime import datetime, date, timedelta
2
+ from random import randint
3
+ from calendar import monthrange
4
+
5
+ # TODO replace used random_day_by_year function implementation when
6
+ # creating pseudo patients with new function "random date by age_at_date and examination_date"
7
+
8
+
9
+ def random_day_by_age_at_date(age_at_date: int, examination_date: date) -> date:
10
+ """
11
+ Return a random birth day for a patient with the specified age at the specified examination date.
12
+ """
13
+ examination_year = examination_date.year
14
+ latest_birthdate = examination_date.replace(year=examination_year - age_at_date)
15
+ valid_dates = [latest_birthdate - timedelta(days=i) for i in range(365)]
16
+
17
+ select = randint(0, len(valid_dates) - 1)
18
+ birth_date = valid_dates[select]
19
+
20
+ return birth_date
21
+
22
+
23
+ def random_day_by_year(year: int) -> date:
24
+ """
25
+ Return a random birth day within the specified year.
26
+ """
27
+ month = randint(1, 12)
28
+ day = randint(1, monthrange(year, month)[1])
29
+
30
+ return date(year, month, day)
31
+
32
+
33
+ def random_day_by_month_year(month: int, year) -> date:
34
+ """
35
+ Return a random birth day within the specified month and year.
36
+ """
37
+
38
+ day = randint(1, monthrange(year, month)[1])
39
+ return date(year, month, day)