endoreg-db 0.8.8.9__py3-none-any.whl → 0.8.9.10__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 (453) hide show
  1. endoreg_db/admin.py +10 -5
  2. endoreg_db/apps.py +4 -7
  3. endoreg_db/authz/auth.py +1 -0
  4. endoreg_db/authz/backends.py +1 -1
  5. endoreg_db/authz/management/commands/list_routes.py +2 -0
  6. endoreg_db/authz/middleware.py +8 -7
  7. endoreg_db/authz/permissions.py +21 -10
  8. endoreg_db/authz/policy.py +14 -19
  9. endoreg_db/authz/views_auth.py +14 -10
  10. endoreg_db/codemods/rename_datetime_fields.py +8 -1
  11. endoreg_db/exceptions.py +5 -2
  12. endoreg_db/forms/__init__.py +0 -1
  13. endoreg_db/forms/examination_form.py +4 -3
  14. endoreg_db/forms/patient_finding_intervention_form.py +30 -8
  15. endoreg_db/forms/patient_form.py +9 -13
  16. endoreg_db/forms/questionnaires/__init__.py +1 -1
  17. endoreg_db/forms/settings/__init__.py +4 -1
  18. endoreg_db/forms/unit.py +2 -1
  19. endoreg_db/helpers/count_db.py +17 -14
  20. endoreg_db/helpers/default_objects.py +2 -1
  21. endoreg_db/helpers/download_segmentation_model.py +4 -3
  22. endoreg_db/helpers/interact.py +0 -5
  23. endoreg_db/helpers/test_video_helper.py +33 -25
  24. endoreg_db/import_files/__init__.py +1 -1
  25. endoreg_db/import_files/context/__init__.py +1 -1
  26. endoreg_db/import_files/context/default_sensitive_meta.py +11 -9
  27. endoreg_db/import_files/context/ensure_center.py +4 -4
  28. endoreg_db/import_files/context/file_lock.py +3 -3
  29. endoreg_db/import_files/context/import_context.py +11 -12
  30. endoreg_db/import_files/context/validate_directories.py +1 -0
  31. endoreg_db/import_files/file_storage/create_report_file.py +57 -34
  32. endoreg_db/import_files/file_storage/create_video_file.py +64 -35
  33. endoreg_db/import_files/file_storage/sensitive_meta_storage.py +5 -2
  34. endoreg_db/import_files/file_storage/state_management.py +146 -83
  35. endoreg_db/import_files/file_storage/storage.py +5 -1
  36. endoreg_db/import_files/processing/report_processing/report_anonymization.py +24 -19
  37. endoreg_db/import_files/processing/sensitive_meta_adapter.py +3 -3
  38. endoreg_db/import_files/processing/video_processing/video_anonymization.py +18 -18
  39. endoreg_db/import_files/pseudonymization/k_anonymity.py +8 -9
  40. endoreg_db/import_files/pseudonymization/k_pseudonymity.py +16 -5
  41. endoreg_db/import_files/report_import_service.py +36 -30
  42. endoreg_db/import_files/video_import_service.py +27 -23
  43. endoreg_db/logger_conf.py +56 -40
  44. endoreg_db/management/__init__.py +1 -1
  45. endoreg_db/management/commands/__init__.py +1 -1
  46. endoreg_db/management/commands/check_auth.py +45 -38
  47. endoreg_db/management/commands/create_model_meta_from_huggingface.py +53 -2
  48. endoreg_db/management/commands/create_multilabel_model_meta.py +54 -19
  49. endoreg_db/management/commands/fix_missing_patient_data.py +105 -71
  50. endoreg_db/management/commands/fix_video_paths.py +75 -54
  51. endoreg_db/management/commands/import_report.py +1 -3
  52. endoreg_db/management/commands/list_routes.py +2 -0
  53. endoreg_db/management/commands/load_ai_model_data.py +8 -2
  54. endoreg_db/management/commands/load_ai_model_label_data.py +0 -1
  55. endoreg_db/management/commands/load_center_data.py +3 -3
  56. endoreg_db/management/commands/load_distribution_data.py +35 -38
  57. endoreg_db/management/commands/load_endoscope_data.py +0 -3
  58. endoreg_db/management/commands/load_examination_data.py +20 -4
  59. endoreg_db/management/commands/load_finding_data.py +18 -3
  60. endoreg_db/management/commands/load_gender_data.py +17 -24
  61. endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +95 -85
  62. endoreg_db/management/commands/load_information_source.py +0 -3
  63. endoreg_db/management/commands/load_lab_value_data.py +14 -3
  64. endoreg_db/management/commands/load_legacy_data.py +303 -0
  65. endoreg_db/management/commands/load_name_data.py +1 -2
  66. endoreg_db/management/commands/load_pdf_type_data.py +4 -8
  67. endoreg_db/management/commands/load_profession_data.py +0 -1
  68. endoreg_db/management/commands/load_report_reader_flag_data.py +0 -4
  69. endoreg_db/management/commands/load_requirement_data.py +6 -2
  70. endoreg_db/management/commands/load_unit_data.py +0 -4
  71. endoreg_db/management/commands/load_user_groups.py +5 -7
  72. endoreg_db/management/commands/model_input.py +169 -0
  73. endoreg_db/management/commands/register_ai_model.py +22 -16
  74. endoreg_db/management/commands/setup_endoreg_db.py +110 -32
  75. endoreg_db/management/commands/storage_management.py +14 -8
  76. endoreg_db/management/commands/summarize_db_content.py +154 -63
  77. endoreg_db/management/commands/train_image_multilabel_model.py +144 -0
  78. endoreg_db/management/commands/validate_video_files.py +82 -50
  79. endoreg_db/management/commands/video_validation.py +4 -6
  80. endoreg_db/migrations/0001_initial.py +112 -63
  81. endoreg_db/migrations/__init__.py +0 -0
  82. endoreg_db/models/__init__.py +8 -0
  83. endoreg_db/models/administration/ai/active_model.py +5 -5
  84. endoreg_db/models/administration/ai/ai_model.py +41 -18
  85. endoreg_db/models/administration/ai/model_type.py +1 -0
  86. endoreg_db/models/administration/case/case.py +22 -22
  87. endoreg_db/models/administration/center/__init__.py +5 -5
  88. endoreg_db/models/administration/center/center.py +6 -2
  89. endoreg_db/models/administration/center/center_resource.py +18 -4
  90. endoreg_db/models/administration/center/center_shift.py +3 -1
  91. endoreg_db/models/administration/center/center_waste.py +6 -2
  92. endoreg_db/models/administration/person/__init__.py +1 -1
  93. endoreg_db/models/administration/person/employee/__init__.py +1 -1
  94. endoreg_db/models/administration/person/employee/employee_type.py +3 -1
  95. endoreg_db/models/administration/person/examiner/__init__.py +1 -1
  96. endoreg_db/models/administration/person/examiner/examiner.py +10 -2
  97. endoreg_db/models/administration/person/names/first_name.py +6 -4
  98. endoreg_db/models/administration/person/names/last_name.py +4 -3
  99. endoreg_db/models/administration/person/patient/__init__.py +1 -1
  100. endoreg_db/models/administration/person/patient/patient.py +0 -1
  101. endoreg_db/models/administration/person/patient/patient_external_id.py +0 -1
  102. endoreg_db/models/administration/person/person.py +1 -1
  103. endoreg_db/models/administration/product/__init__.py +7 -6
  104. endoreg_db/models/administration/product/product.py +6 -2
  105. endoreg_db/models/administration/product/product_group.py +9 -7
  106. endoreg_db/models/administration/product/product_material.py +9 -2
  107. endoreg_db/models/administration/product/reference_product.py +64 -15
  108. endoreg_db/models/administration/qualification/qualification.py +3 -1
  109. endoreg_db/models/administration/shift/shift.py +3 -1
  110. endoreg_db/models/administration/shift/shift_type.py +12 -4
  111. endoreg_db/models/aidataset/__init__.py +5 -0
  112. endoreg_db/models/aidataset/aidataset.py +193 -0
  113. endoreg_db/models/label/__init__.py +1 -1
  114. endoreg_db/models/label/label.py +10 -2
  115. endoreg_db/models/label/label_set.py +3 -1
  116. endoreg_db/models/label/label_video_segment/_create_from_video.py +6 -2
  117. endoreg_db/models/label/label_video_segment/label_video_segment.py +148 -44
  118. endoreg_db/models/media/__init__.py +12 -5
  119. endoreg_db/models/media/frame/__init__.py +1 -1
  120. endoreg_db/models/media/frame/frame.py +34 -8
  121. endoreg_db/models/media/pdf/__init__.py +2 -1
  122. endoreg_db/models/media/pdf/raw_pdf.py +11 -4
  123. endoreg_db/models/media/pdf/report_file.py +6 -2
  124. endoreg_db/models/media/pdf/report_reader/__init__.py +3 -3
  125. endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +15 -5
  126. endoreg_db/models/media/video/create_from_file.py +20 -41
  127. endoreg_db/models/media/video/pipe_1.py +75 -30
  128. endoreg_db/models/media/video/pipe_2.py +37 -12
  129. endoreg_db/models/media/video/video_file.py +36 -24
  130. endoreg_db/models/media/video/video_file_ai.py +235 -70
  131. endoreg_db/models/media/video/video_file_anonymize.py +240 -65
  132. endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +6 -1
  133. endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +3 -1
  134. endoreg_db/models/media/video/video_file_frames/_delete_frames.py +30 -9
  135. endoreg_db/models/media/video/video_file_frames/_extract_frames.py +95 -29
  136. endoreg_db/models/media/video/video_file_frames/_get_frame.py +13 -3
  137. endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +4 -1
  138. endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +15 -3
  139. endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +15 -3
  140. endoreg_db/models/media/video/video_file_frames/_get_frames.py +7 -2
  141. endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +109 -23
  142. endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +111 -27
  143. endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +46 -13
  144. endoreg_db/models/media/video/video_file_io.py +85 -33
  145. endoreg_db/models/media/video/video_file_meta/__init__.py +6 -6
  146. endoreg_db/models/media/video/video_file_meta/get_crop_template.py +17 -4
  147. endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +28 -7
  148. endoreg_db/models/media/video/video_file_meta/get_fps.py +46 -13
  149. endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +81 -20
  150. endoreg_db/models/media/video/video_file_meta/text_meta.py +61 -20
  151. endoreg_db/models/media/video/video_file_meta/video_meta.py +40 -12
  152. endoreg_db/models/media/video/video_file_segments.py +118 -27
  153. endoreg_db/models/media/video/video_metadata.py +25 -6
  154. endoreg_db/models/media/video/video_processing.py +54 -15
  155. endoreg_db/models/medical/__init__.py +3 -13
  156. endoreg_db/models/medical/contraindication/__init__.py +3 -1
  157. endoreg_db/models/medical/disease.py +18 -6
  158. endoreg_db/models/medical/event.py +6 -2
  159. endoreg_db/models/medical/examination/__init__.py +5 -1
  160. endoreg_db/models/medical/examination/examination.py +22 -6
  161. endoreg_db/models/medical/examination/examination_indication.py +23 -7
  162. endoreg_db/models/medical/examination/examination_time.py +6 -2
  163. endoreg_db/models/medical/finding/__init__.py +3 -1
  164. endoreg_db/models/medical/finding/finding.py +37 -12
  165. endoreg_db/models/medical/finding/finding_classification.py +27 -8
  166. endoreg_db/models/medical/finding/finding_intervention.py +19 -6
  167. endoreg_db/models/medical/finding/finding_type.py +3 -1
  168. endoreg_db/models/medical/hardware/__init__.py +1 -1
  169. endoreg_db/models/medical/hardware/endoscope.py +14 -2
  170. endoreg_db/models/medical/laboratory/__init__.py +1 -1
  171. endoreg_db/models/medical/laboratory/lab_value.py +139 -39
  172. endoreg_db/models/medical/medication/__init__.py +7 -3
  173. endoreg_db/models/medical/medication/medication.py +3 -1
  174. endoreg_db/models/medical/medication/medication_indication.py +3 -1
  175. endoreg_db/models/medical/medication/medication_indication_type.py +11 -3
  176. endoreg_db/models/medical/medication/medication_intake_time.py +3 -1
  177. endoreg_db/models/medical/medication/medication_schedule.py +3 -1
  178. endoreg_db/models/medical/patient/__init__.py +2 -10
  179. endoreg_db/models/medical/patient/medication_examples.py +3 -14
  180. endoreg_db/models/medical/patient/patient_disease.py +17 -5
  181. endoreg_db/models/medical/patient/patient_event.py +12 -4
  182. endoreg_db/models/medical/patient/patient_examination.py +52 -15
  183. endoreg_db/models/medical/patient/patient_examination_indication.py +15 -4
  184. endoreg_db/models/medical/patient/patient_finding.py +105 -29
  185. endoreg_db/models/medical/patient/patient_finding_classification.py +41 -12
  186. endoreg_db/models/medical/patient/patient_finding_intervention.py +11 -3
  187. endoreg_db/models/medical/patient/patient_lab_sample.py +6 -2
  188. endoreg_db/models/medical/patient/patient_lab_value.py +42 -10
  189. endoreg_db/models/medical/patient/patient_medication.py +25 -7
  190. endoreg_db/models/medical/patient/patient_medication_schedule.py +34 -10
  191. endoreg_db/models/metadata/model_meta.py +40 -12
  192. endoreg_db/models/metadata/model_meta_logic.py +51 -16
  193. endoreg_db/models/metadata/sensitive_meta.py +65 -28
  194. endoreg_db/models/metadata/sensitive_meta_logic.py +28 -26
  195. endoreg_db/models/metadata/video_meta.py +146 -39
  196. endoreg_db/models/metadata/video_prediction_logic.py +70 -21
  197. endoreg_db/models/metadata/video_prediction_meta.py +80 -27
  198. endoreg_db/models/operation_log.py +63 -0
  199. endoreg_db/models/other/__init__.py +10 -10
  200. endoreg_db/models/other/distribution/__init__.py +9 -7
  201. endoreg_db/models/other/distribution/base_value_distribution.py +3 -1
  202. endoreg_db/models/other/distribution/date_value_distribution.py +19 -5
  203. endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +3 -1
  204. endoreg_db/models/other/distribution/numeric_value_distribution.py +34 -9
  205. endoreg_db/models/other/emission/__init__.py +1 -1
  206. endoreg_db/models/other/emission/emission_factor.py +9 -3
  207. endoreg_db/models/other/information_source.py +15 -5
  208. endoreg_db/models/other/material.py +3 -1
  209. endoreg_db/models/other/transport_route.py +3 -1
  210. endoreg_db/models/other/unit.py +6 -2
  211. endoreg_db/models/report/report.py +0 -1
  212. endoreg_db/models/requirement/requirement.py +84 -27
  213. endoreg_db/models/requirement/requirement_error.py +5 -6
  214. endoreg_db/models/requirement/requirement_evaluation/__init__.py +1 -1
  215. endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +8 -8
  216. endoreg_db/models/requirement/requirement_evaluation/get_values.py +3 -3
  217. endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +24 -8
  218. endoreg_db/models/requirement/requirement_operator.py +28 -8
  219. endoreg_db/models/requirement/requirement_set.py +34 -11
  220. endoreg_db/models/state/__init__.py +1 -0
  221. endoreg_db/models/state/audit_ledger.py +9 -2
  222. endoreg_db/models/{media → state}/processing_history/__init__.py +1 -3
  223. endoreg_db/models/state/processing_history/processing_history.py +136 -0
  224. endoreg_db/models/state/raw_pdf.py +0 -1
  225. endoreg_db/models/state/video.py +2 -3
  226. endoreg_db/models/utils.py +4 -2
  227. endoreg_db/queries/__init__.py +2 -6
  228. endoreg_db/queries/annotations/__init__.py +1 -3
  229. endoreg_db/queries/annotations/legacy.py +37 -26
  230. endoreg_db/root_urls.py +3 -4
  231. endoreg_db/schemas/examination_evaluation.py +3 -0
  232. endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +249 -163
  233. endoreg_db/serializers/__init__.py +2 -8
  234. endoreg_db/serializers/administration/__init__.py +1 -2
  235. endoreg_db/serializers/administration/ai/__init__.py +0 -1
  236. endoreg_db/serializers/administration/ai/active_model.py +3 -1
  237. endoreg_db/serializers/administration/ai/ai_model.py +5 -3
  238. endoreg_db/serializers/administration/ai/model_type.py +3 -1
  239. endoreg_db/serializers/administration/center.py +7 -2
  240. endoreg_db/serializers/administration/gender.py +4 -2
  241. endoreg_db/serializers/anonymization.py +13 -13
  242. endoreg_db/serializers/evaluation/examination_evaluation.py +0 -1
  243. endoreg_db/serializers/examination/__init__.py +1 -1
  244. endoreg_db/serializers/examination/base.py +12 -13
  245. endoreg_db/serializers/examination/dropdown.py +6 -7
  246. endoreg_db/serializers/examination_serializer.py +3 -6
  247. endoreg_db/serializers/finding/__init__.py +1 -1
  248. endoreg_db/serializers/finding/finding.py +14 -7
  249. endoreg_db/serializers/finding_classification/__init__.py +3 -3
  250. endoreg_db/serializers/finding_classification/choice.py +3 -3
  251. endoreg_db/serializers/finding_classification/classification.py +2 -4
  252. endoreg_db/serializers/label_video_segment/__init__.py +5 -3
  253. endoreg_db/serializers/{label → label_video_segment}/image_classification_annotation.py +5 -5
  254. endoreg_db/serializers/label_video_segment/label/__init__.py +6 -0
  255. endoreg_db/serializers/{label → label_video_segment/label}/label.py +1 -1
  256. endoreg_db/serializers/label_video_segment/label_video_segment.py +338 -228
  257. endoreg_db/serializers/meta/__init__.py +1 -2
  258. endoreg_db/serializers/meta/sensitive_meta_detail.py +28 -13
  259. endoreg_db/serializers/meta/sensitive_meta_update.py +51 -46
  260. endoreg_db/serializers/meta/sensitive_meta_verification.py +19 -16
  261. endoreg_db/serializers/misc/__init__.py +2 -2
  262. endoreg_db/serializers/misc/file_overview.py +11 -7
  263. endoreg_db/serializers/misc/stats.py +10 -8
  264. endoreg_db/serializers/misc/translatable_field_mix_in.py +6 -6
  265. endoreg_db/serializers/misc/upload_job.py +32 -29
  266. endoreg_db/serializers/patient/__init__.py +2 -1
  267. endoreg_db/serializers/patient/patient.py +32 -15
  268. endoreg_db/serializers/patient/patient_dropdown.py +11 -3
  269. endoreg_db/serializers/patient_examination/__init__.py +1 -1
  270. endoreg_db/serializers/patient_examination/patient_examination.py +67 -40
  271. endoreg_db/serializers/patient_finding/__init__.py +1 -1
  272. endoreg_db/serializers/patient_finding/patient_finding.py +2 -1
  273. endoreg_db/serializers/patient_finding/patient_finding_classification.py +17 -9
  274. endoreg_db/serializers/patient_finding/patient_finding_detail.py +26 -17
  275. endoreg_db/serializers/patient_finding/patient_finding_intervention.py +7 -5
  276. endoreg_db/serializers/patient_finding/patient_finding_list.py +10 -11
  277. endoreg_db/serializers/patient_finding/patient_finding_write.py +36 -27
  278. endoreg_db/serializers/pdf/__init__.py +1 -3
  279. endoreg_db/serializers/requirements/requirement_schema.py +1 -6
  280. endoreg_db/serializers/sensitive_meta_serializer.py +100 -81
  281. endoreg_db/serializers/video/__init__.py +2 -2
  282. endoreg_db/serializers/video/{segmentation.py → video_file.py} +66 -47
  283. endoreg_db/serializers/video/video_file_brief.py +6 -2
  284. endoreg_db/serializers/video/video_file_detail.py +36 -23
  285. endoreg_db/serializers/video/video_file_list.py +4 -2
  286. endoreg_db/serializers/video/video_processing_history.py +54 -50
  287. endoreg_db/services/__init__.py +1 -1
  288. endoreg_db/services/anonymization.py +2 -2
  289. endoreg_db/services/examination_evaluation.py +40 -17
  290. endoreg_db/services/model_meta_from_hf.py +76 -0
  291. endoreg_db/services/polling_coordinator.py +101 -70
  292. endoreg_db/services/pseudonym_service.py +27 -22
  293. endoreg_db/services/report_import.py +6 -3
  294. endoreg_db/services/segment_sync.py +75 -59
  295. endoreg_db/services/video_import.py +6 -7
  296. endoreg_db/urls/__init__.py +2 -2
  297. endoreg_db/urls/ai.py +7 -25
  298. endoreg_db/urls/anonymization.py +61 -15
  299. endoreg_db/urls/auth.py +4 -4
  300. endoreg_db/urls/classification.py +4 -9
  301. endoreg_db/urls/examination.py +27 -18
  302. endoreg_db/urls/media.py +27 -34
  303. endoreg_db/urls/patient.py +11 -7
  304. endoreg_db/urls/requirements.py +3 -1
  305. endoreg_db/urls/root_urls.py +2 -3
  306. endoreg_db/urls/stats.py +24 -16
  307. endoreg_db/urls/upload.py +3 -11
  308. endoreg_db/utils/__init__.py +14 -15
  309. endoreg_db/utils/ai/__init__.py +1 -1
  310. endoreg_db/utils/ai/data_loader_for_model_input.py +262 -0
  311. endoreg_db/utils/ai/data_loader_for_model_training.py +262 -0
  312. endoreg_db/utils/ai/get.py +2 -1
  313. endoreg_db/utils/ai/inference_dataset.py +14 -15
  314. endoreg_db/utils/ai/model_training/config.py +117 -0
  315. endoreg_db/utils/ai/model_training/dataset.py +74 -0
  316. endoreg_db/utils/ai/model_training/losses.py +68 -0
  317. endoreg_db/utils/ai/model_training/metrics.py +78 -0
  318. endoreg_db/utils/ai/model_training/model_backbones.py +155 -0
  319. endoreg_db/utils/ai/model_training/model_gastronet_resnet.py +118 -0
  320. endoreg_db/utils/ai/model_training/trainer_gastronet_multilabel.py +771 -0
  321. endoreg_db/utils/ai/multilabel_classification_net.py +21 -6
  322. endoreg_db/utils/ai/predict.py +4 -4
  323. endoreg_db/utils/ai/preprocess.py +19 -11
  324. endoreg_db/utils/calc_duration_seconds.py +4 -4
  325. endoreg_db/utils/case_generator/lab_sample_factory.py +3 -4
  326. endoreg_db/utils/check_video_files.py +74 -47
  327. endoreg_db/utils/cropping.py +10 -9
  328. endoreg_db/utils/dataloader.py +11 -3
  329. endoreg_db/utils/dates.py +3 -4
  330. endoreg_db/utils/defaults/set_default_center.py +7 -6
  331. endoreg_db/utils/env.py +6 -2
  332. endoreg_db/utils/extract_specific_frames.py +24 -9
  333. endoreg_db/utils/file_operations.py +30 -18
  334. endoreg_db/utils/fix_video_path_direct.py +57 -41
  335. endoreg_db/utils/frame_anonymization_utils.py +157 -157
  336. endoreg_db/utils/hashs.py +3 -18
  337. endoreg_db/utils/links/requirement_link.py +96 -52
  338. endoreg_db/utils/ocr.py +30 -25
  339. endoreg_db/utils/operation_log.py +61 -0
  340. endoreg_db/utils/parse_and_generate_yaml.py +12 -13
  341. endoreg_db/utils/paths.py +6 -6
  342. endoreg_db/utils/permissions.py +40 -24
  343. endoreg_db/utils/pipelines/process_video_dir.py +50 -26
  344. endoreg_db/utils/product/sum_emissions.py +5 -3
  345. endoreg_db/utils/product/sum_weights.py +4 -2
  346. endoreg_db/utils/pydantic_models/__init__.py +3 -4
  347. endoreg_db/utils/requirement_operator_logic/_old/lab_value_operators.py +207 -107
  348. endoreg_db/utils/requirement_operator_logic/_old/model_evaluators.py +252 -65
  349. endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +27 -10
  350. endoreg_db/utils/setup_config.py +21 -5
  351. endoreg_db/utils/storage.py +3 -1
  352. endoreg_db/utils/translation.py +19 -15
  353. endoreg_db/utils/uuid.py +1 -0
  354. endoreg_db/utils/validate_endo_roi.py +12 -4
  355. endoreg_db/utils/validate_subcategory_dict.py +26 -24
  356. endoreg_db/utils/validate_video_detailed.py +207 -149
  357. endoreg_db/utils/video/__init__.py +7 -3
  358. endoreg_db/utils/video/extract_frames.py +30 -18
  359. endoreg_db/utils/video/ffmpeg_wrapper.py +217 -52
  360. endoreg_db/utils/video/names.py +11 -6
  361. endoreg_db/utils/video/streaming_processor.py +175 -101
  362. endoreg_db/utils/video/video_splitter.py +30 -19
  363. endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +59 -50
  364. endoreg_db/views/__init__.py +0 -20
  365. endoreg_db/views/anonymization/__init__.py +6 -2
  366. endoreg_db/views/anonymization/media_management.py +2 -6
  367. endoreg_db/views/anonymization/overview.py +34 -1
  368. endoreg_db/views/anonymization/validate.py +79 -18
  369. endoreg_db/views/auth/__init__.py +1 -1
  370. endoreg_db/views/auth/keycloak.py +16 -14
  371. endoreg_db/views/examination/__init__.py +12 -15
  372. endoreg_db/views/examination/examination.py +5 -5
  373. endoreg_db/views/examination/examination_manifest_cache.py +5 -5
  374. endoreg_db/views/examination/get_finding_classification_choices.py +8 -5
  375. endoreg_db/views/examination/get_finding_classifications.py +9 -7
  376. endoreg_db/views/examination/get_findings.py +8 -10
  377. endoreg_db/views/examination/get_instruments.py +3 -2
  378. endoreg_db/views/examination/get_interventions.py +1 -1
  379. endoreg_db/views/finding/__init__.py +2 -2
  380. endoreg_db/views/finding/finding.py +58 -54
  381. endoreg_db/views/finding/get_classifications.py +1 -1
  382. endoreg_db/views/finding/get_interventions.py +1 -1
  383. endoreg_db/views/finding_classification/__init__.py +5 -5
  384. endoreg_db/views/finding_classification/finding_classification.py +5 -6
  385. endoreg_db/views/finding_classification/get_classification_choices.py +3 -4
  386. endoreg_db/views/media/__init__.py +13 -13
  387. endoreg_db/views/media/pdf_media.py +9 -9
  388. endoreg_db/views/media/sensitive_metadata.py +10 -7
  389. endoreg_db/views/media/video_media.py +4 -4
  390. endoreg_db/views/meta/__init__.py +1 -1
  391. endoreg_db/views/meta/sensitive_meta_list.py +20 -22
  392. endoreg_db/views/meta/sensitive_meta_verification.py +14 -11
  393. endoreg_db/views/misc/__init__.py +6 -34
  394. endoreg_db/views/misc/center.py +2 -1
  395. endoreg_db/views/misc/csrf.py +2 -1
  396. endoreg_db/views/misc/gender.py +2 -1
  397. endoreg_db/views/misc/stats.py +141 -106
  398. endoreg_db/views/patient/__init__.py +1 -3
  399. endoreg_db/views/patient/patient.py +141 -99
  400. endoreg_db/views/patient_examination/__init__.py +5 -5
  401. endoreg_db/views/patient_examination/patient_examination.py +43 -42
  402. endoreg_db/views/patient_examination/patient_examination_create.py +10 -15
  403. endoreg_db/views/patient_examination/patient_examination_detail.py +12 -15
  404. endoreg_db/views/patient_examination/patient_examination_list.py +21 -17
  405. endoreg_db/views/patient_examination/video.py +114 -80
  406. endoreg_db/views/patient_finding/__init__.py +1 -1
  407. endoreg_db/views/patient_finding/patient_finding.py +17 -10
  408. endoreg_db/views/patient_finding/patient_finding_optimized.py +127 -95
  409. endoreg_db/views/patient_finding_classification/__init__.py +1 -1
  410. endoreg_db/views/patient_finding_classification/pfc_create.py +35 -27
  411. endoreg_db/views/report/reimport.py +1 -1
  412. endoreg_db/views/report/report_stream.py +5 -8
  413. endoreg_db/views/requirement/__init__.py +2 -1
  414. endoreg_db/views/requirement/evaluate.py +7 -9
  415. endoreg_db/views/requirement/lookup.py +2 -3
  416. endoreg_db/views/requirement/lookup_store.py +0 -1
  417. endoreg_db/views/requirement/requirement_utils.py +2 -4
  418. endoreg_db/views/stats/__init__.py +4 -4
  419. endoreg_db/views/stats/stats_views.py +152 -115
  420. endoreg_db/views/video/__init__.py +18 -27
  421. endoreg_db/views/{ai → video/ai}/__init__.py +2 -2
  422. endoreg_db/views/{ai → video/ai}/label.py +20 -16
  423. endoreg_db/views/video/correction.py +5 -6
  424. endoreg_db/views/video/reimport.py +134 -99
  425. endoreg_db/views/video/segments_crud.py +134 -44
  426. endoreg_db/views/video/video_apply_mask.py +13 -12
  427. endoreg_db/views/video/video_correction.py +2 -1
  428. endoreg_db/views/video/video_download_processed.py +15 -15
  429. endoreg_db/views/video/video_meta_stats.py +7 -6
  430. endoreg_db/views/video/video_processing_history.py +3 -2
  431. endoreg_db/views/video/video_remove_frames.py +13 -12
  432. endoreg_db/views/video/video_stream.py +110 -82
  433. {endoreg_db-0.8.8.9.dist-info → endoreg_db-0.8.9.10.dist-info}/METADATA +9 -3
  434. {endoreg_db-0.8.8.9.dist-info → endoreg_db-0.8.9.10.dist-info}/RECORD +436 -433
  435. endoreg_db/import_files/processing/video_processing/video_cleanup_on_error.py +0 -119
  436. endoreg_db/management/commands/import_fallback_video.py +0 -203
  437. endoreg_db/management/commands/import_video.py +0 -422
  438. endoreg_db/management/commands/import_video_with_classification.py +0 -367
  439. endoreg_db/models/media/processing_history/processing_history.py +0 -96
  440. endoreg_db/serializers/label/__init__.py +0 -7
  441. endoreg_db/serializers/label_video_segment/_lvs_create.py +0 -149
  442. endoreg_db/serializers/label_video_segment/_lvs_update.py +0 -138
  443. endoreg_db/serializers/label_video_segment/_lvs_validate.py +0 -149
  444. endoreg_db/serializers/label_video_segment/label_video_segment_annotation.py +0 -99
  445. endoreg_db/serializers/label_video_segment/label_video_segment_update.py +0 -163
  446. endoreg_db/services/__old/pdf_import.py +0 -1487
  447. endoreg_db/services/__old/video_import.py +0 -1306
  448. endoreg_db/tasks/upload_tasks.py +0 -216
  449. endoreg_db/tasks/video_ingest.py +0 -161
  450. endoreg_db/tasks/video_processing_tasks.py +0 -327
  451. endoreg_db/views/misc/translation.py +0 -182
  452. {endoreg_db-0.8.8.9.dist-info → endoreg_db-0.8.9.10.dist-info}/WHEEL +0 -0
  453. {endoreg_db-0.8.8.9.dist-info → endoreg_db-0.8.9.10.dist-info}/licenses/LICENSE +0 -0
@@ -1,19 +1,25 @@
1
1
  """
2
2
  Django model for AI models.
3
3
  """
4
+
4
5
  from django.db import models
5
6
  from icecream import ic
6
7
  from typing import TYPE_CHECKING
8
+ from logging import getLogger
9
+
10
+ logger = getLogger(__name__)
7
11
 
8
12
  if TYPE_CHECKING:
9
13
  from .model_type import ModelType
10
- from ...metadata import ModelMeta
14
+ from ...metadata import ModelMeta
11
15
  from ...label import VideoSegmentationLabelSet
16
+
12
17
  # Forward reference AiModel for use in type hints within the class itself
13
18
  from typing import ForwardRef
19
+
14
20
  AiModelRef = ForwardRef("'AiModel'")
15
21
 
16
-
22
+
17
23
  class AiModelManager(models.Manager):
18
24
  """
19
25
  Manager for AI models with custom query methods.
@@ -22,13 +28,13 @@ class AiModelManager(models.Manager):
22
28
  def get_by_natural_key(self, name: str):
23
29
  """
24
30
  Retrieves the AiModel instance with the specified unique name.
25
-
31
+
26
32
  Args:
27
33
  name: The unique identifier of the AiModel to retrieve.
28
-
34
+
29
35
  Returns:
30
36
  The AiModel instance matching the given name.
31
-
37
+
32
38
  Raises:
33
39
  AiModel.DoesNotExist: If no AiModel with the specified name exists.
34
40
  """
@@ -48,6 +54,7 @@ class AiModel(models.Model):
48
54
  video_segmentation_labelset (VideoSegmentationLabelSet): Optional associated label set for video segmentation tasks.
49
55
  active_meta (ModelMeta): Optional reference to the currently active ModelMeta instance associated with the model.
50
56
  """
57
+
51
58
  objects = AiModelManager()
52
59
 
53
60
  name = models.CharField(max_length=255, unique=True)
@@ -71,29 +78,29 @@ class AiModel(models.Model):
71
78
  active_meta = models.ForeignKey(
72
79
  "ModelMeta",
73
80
  on_delete=models.SET_NULL,
74
- related_name="active_model",
81
+ related_name="active_model",
75
82
  blank=True,
76
83
  null=True,
77
84
  )
78
85
 
79
86
  if TYPE_CHECKING:
80
87
  metadata_versions: models.QuerySet["ModelMeta"]
81
- model_type:models.ForeignKey["ModelType|None"]
82
- active_meta:models.ForeignKey["ModelMeta|None"]
83
- video_segmentation_labelset:models.ForeignKey["VideoSegmentationLabelSet|None"]
88
+ model_type: models.ForeignKey["ModelType|None"]
89
+ active_meta: models.ForeignKey["ModelMeta|None"]
90
+ video_segmentation_labelset: models.ForeignKey["VideoSegmentationLabelSet|None"]
84
91
 
85
92
  def get_version(self, version: int) -> "ModelMeta":
86
93
  """
87
94
  Retrieves the ModelMeta instance for the specified version.
88
-
95
+
89
96
  If the active_meta matches the requested version, it is returned. Otherwise, searches related metadata_versions for a matching version. Raises ValueError if no matching metadata is found.
90
-
97
+
91
98
  Args:
92
99
  version: The version number of the desired ModelMeta.
93
-
100
+
94
101
  Returns:
95
102
  The ModelMeta instance corresponding to the specified version.
96
-
103
+
97
104
  Raises:
98
105
  ValueError: If no ModelMeta with the given version exists.
99
106
  """
@@ -108,24 +115,40 @@ class AiModel(models.Model):
108
115
  raise ValueError(f"No model metadata found for version {version}.")
109
116
 
110
117
  def get_latest_version(self) -> "ModelMeta":
111
- """
112
- Get the model_metadata object from metadata_versions with the highest version number.
113
- """
114
118
  if self.active_meta is not None:
115
119
  return self.active_meta
116
120
 
117
- # Get the latest version of the model metadata
118
121
  latest_version = self.metadata_versions.order_by("-version").first()
119
122
  if latest_version is not None:
120
123
  return latest_version
121
124
 
125
+ # Only in environments where auto-download is acceptable:
126
+ try:
127
+ logger.info(
128
+ "Locally, no segmentation model was available. We are using colo_segmentation_RegNetX800MF_base."
129
+ )
130
+ from endoreg_db.services.model_meta_from_hf import ensure_model_meta_from_hf
131
+
132
+ model_meta = ensure_model_meta_from_hf(
133
+ model_id="wg-lux/colo_segmentation_RegNetX800MF_base",
134
+ model_name="image_multilabel_classification_colonoscopy_default",
135
+ labelset_name="multilabel_classification_colonoscopy_default",
136
+ meta_version="1",
137
+ )
138
+ return model_meta
139
+ except Exception:
140
+ logger.exception(
141
+ "Failed to ensure ModelMeta from Hugging Face for AiModel '%s'",
142
+ self.name,
143
+ )
144
+
122
145
  raise ValueError("No model metadata found for this model.")
123
146
 
124
147
  @classmethod
125
148
  def set_active_model_meta(cls, model_name: str, meta_name: str, meta_version: int):
126
149
  """
127
150
  Sets the active metadata version for the specified AI model.
128
-
151
+
129
152
  Updates the `active_meta` field of the AiModel identified by `model_name` to the ModelMeta instance matching `meta_name` and `meta_version`.
130
153
  """
131
154
  from ...metadata import ModelMeta
@@ -4,6 +4,7 @@ from typing import TYPE_CHECKING
4
4
  if TYPE_CHECKING:
5
5
  from .ai_model import AiModel
6
6
 
7
+
7
8
  class ModelTypeManager(models.Manager):
8
9
  """
9
10
  Custom manager for ModelType with additional query methods.
@@ -1,11 +1,13 @@
1
1
  from django.db import models
2
2
 
3
3
  from typing import TYPE_CHECKING
4
+
4
5
  if TYPE_CHECKING:
5
6
  from ..person import Patient
6
7
  from ...medical.patient.patient_examination import PatientExamination
7
8
  from django.utils import timezone
8
9
 
10
+
9
11
  class Case(models.Model):
10
12
  """
11
13
  Represents a clinical case, linking a patient to one or more examinations over a specific period.
@@ -22,64 +24,62 @@ class Case(models.Model):
22
24
  created_at (datetime): Timestamp of case creation.
23
25
  updated_at (datetime): Timestamp of last case update.
24
26
  """
27
+
25
28
  patient = models.ForeignKey(
26
- 'Patient',
29
+ "Patient",
27
30
  on_delete=models.CASCADE,
28
- related_name='cases',
31
+ related_name="cases",
29
32
  help_text="The patient associated with this case.",
30
- db_index=True
33
+ db_index=True,
31
34
  )
32
35
  patient_examinations = models.ManyToManyField(
33
- 'PatientExamination',
34
- related_name='cases',
35
- help_text="The examinations included in this case."
36
+ "PatientExamination",
37
+ related_name="cases",
38
+ help_text="The examinations included in this case.",
36
39
  )
37
40
  hash = models.CharField(
38
41
  max_length=255,
39
42
  blank=True,
40
43
  null=True,
41
- help_text="An optional hash value associated with the case."
44
+ help_text="An optional hash value associated with the case.",
42
45
  )
43
46
 
44
47
  start_date = models.DateTimeField(
45
- help_text="The start date and time of the case.",
46
- db_index=True
48
+ help_text="The start date and time of the case.", db_index=True
47
49
  )
48
50
  end_date = models.DateTimeField(
49
- null=True,
50
- blank=True,
51
- help_text="The end date and time of the case (optional)."
51
+ null=True, blank=True, help_text="The end date and time of the case (optional)."
52
52
  )
53
53
  is_active = models.BooleanField(
54
54
  default=True,
55
55
  help_text="Flag indicating if the case is currently active.",
56
- db_index=True
56
+ db_index=True,
57
57
  )
58
58
  is_closed = models.BooleanField(
59
59
  default=False,
60
60
  help_text="Flag indicating if the case has been closed.",
61
- db_index=True
61
+ db_index=True,
62
62
  )
63
63
  is_deleted = models.BooleanField(
64
64
  default=False,
65
65
  help_text="Flag indicating if the case is marked as deleted.",
66
- db_index=True
66
+ db_index=True,
67
67
  )
68
68
  created_at = models.DateTimeField(
69
- auto_now_add=True,
70
- help_text="The date and time the case was created."
69
+ auto_now_add=True, help_text="The date and time the case was created."
71
70
  )
72
71
  updated_at = models.DateTimeField(
73
- auto_now=True,
74
- help_text="The date and time the case was last updated."
72
+ auto_now=True, help_text="The date and time the case was last updated."
75
73
  )
76
74
 
77
75
  if TYPE_CHECKING:
78
76
  patient: models.ForeignKey["Patient"]
79
- patient_examinations: models.ManyToManyField["PatientExamination", "PatientExamination"]
80
-
77
+ patient_examinations: models.ManyToManyField[
78
+ "PatientExamination", "PatientExamination"
79
+ ]
80
+
81
81
  class Meta:
82
- ordering = ['-start_date', 'patient']
82
+ ordering = ["-start_date", "patient"]
83
83
  verbose_name = "Case"
84
84
  verbose_name_plural = "Cases"
85
85
 
@@ -5,9 +5,9 @@ from .center_waste import CenterWaste
5
5
  from .center_shift import CenterShift
6
6
 
7
7
  __all__ = [
8
- 'Center',
9
- 'CenterProduct',
10
- 'CenterResource',
11
- 'CenterWaste',
12
- 'CenterShift',
8
+ "Center",
9
+ "CenterProduct",
10
+ "CenterResource",
11
+ "CenterWaste",
12
+ "CenterShift",
13
13
  ]
@@ -48,10 +48,14 @@ class Center(models.Model):
48
48
  def endoscopes(self) -> RelatedManager[Endoscope]: ...
49
49
 
50
50
  @property
51
- def anonymexaminationreport_set(self) -> RelatedManager[AnonymExaminationReport]: ...
51
+ def anonymexaminationreport_set(
52
+ self,
53
+ ) -> RelatedManager[AnonymExaminationReport]: ...
52
54
 
53
55
  @property
54
- def anonymhistologyreport_set(self) -> RelatedManager[AnonymHistologyReport]: ...
56
+ def anonymhistologyreport_set(
57
+ self,
58
+ ) -> RelatedManager[AnonymHistologyReport]: ...
55
59
 
56
60
  @classmethod
57
61
  def get_by_name(cls, name):
@@ -19,9 +19,17 @@ class CenterResource(models.Model):
19
19
  quantity = models.FloatField()
20
20
  resource = models.ForeignKey("Resource", on_delete=models.CASCADE)
21
21
  transport_emission_factor = models.ForeignKey(
22
- "EmissionFactor", on_delete=models.SET_NULL, null=True, related_name="center_resource_transport_emission_factor"
22
+ "EmissionFactor",
23
+ on_delete=models.SET_NULL,
24
+ null=True,
25
+ related_name="center_resource_transport_emission_factor",
26
+ )
27
+ use_emission_factor = models.ForeignKey(
28
+ "EmissionFactor",
29
+ on_delete=models.SET_NULL,
30
+ null=True,
31
+ related_name="center_resource_use_emission_factor",
23
32
  )
24
- use_emission_factor = models.ForeignKey("EmissionFactor", on_delete=models.SET_NULL, null=True, related_name="center_resource_use_emission_factor")
25
33
  year = models.IntegerField()
26
34
  unit = models.ForeignKey("Unit", on_delete=models.SET_NULL, null=True)
27
35
 
@@ -46,9 +54,15 @@ class CenterResource(models.Model):
46
54
  result_string += "\tUnit\t-\t" + str(self.unit) + "\n"
47
55
 
48
56
  if self.transport_emission_factor is not None:
49
- result_string += "\tTransport Emission Factor\t-\t" + str(self.transport_emission_factor) + "\n"
57
+ result_string += (
58
+ "\tTransport Emission Factor\t-\t"
59
+ + str(self.transport_emission_factor)
60
+ + "\n"
61
+ )
50
62
 
51
- result_string += "\tUse Emission Factor\t-\t" + str(self.use_emission_factor) + "\n"
63
+ result_string += (
64
+ "\tUse Emission Factor\t-\t" + str(self.use_emission_factor) + "\n"
65
+ )
52
66
 
53
67
  result_string += "\n"
54
68
 
@@ -61,7 +61,9 @@ class CenterShift(models.Model):
61
61
  if TYPE_CHECKING:
62
62
  center: models.ForeignKey["Center"]
63
63
  shift: models.ForeignKey["Shift"]
64
- scheduled_days = cast(models.manager.RelatedManager["ScheduledDays"], scheduled_days)
64
+ scheduled_days = cast(
65
+ models.manager.RelatedManager["ScheduledDays"], scheduled_days
66
+ )
65
67
 
66
68
  def __str__(self):
67
69
  """
@@ -16,10 +16,14 @@ class CenterWaste(models.Model):
16
16
  related_name="center_wastes",
17
17
  )
18
18
  year = models.IntegerField()
19
- waste: models.ForeignKey["Waste"] = models.ForeignKey("Waste", on_delete=models.CASCADE)
19
+ waste: models.ForeignKey["Waste"] = models.ForeignKey(
20
+ "Waste", on_delete=models.CASCADE
21
+ )
20
22
  quantity = models.FloatField()
21
23
  unit = models.ForeignKey("Unit", on_delete=models.SET_NULL, null=True)
22
- emission_factor = models.ForeignKey("EmissionFactor", on_delete=models.SET_NULL, null=True)
24
+ emission_factor = models.ForeignKey(
25
+ "EmissionFactor", on_delete=models.SET_NULL, null=True
26
+ )
23
27
 
24
28
  if TYPE_CHECKING:
25
29
  center: models.ForeignKey["Center"]
@@ -23,4 +23,4 @@ __all__ = [
23
23
  "Employee",
24
24
  "EmployeeType",
25
25
  "EmployeeQualification",
26
- ]
26
+ ]
@@ -1,3 +1,3 @@
1
1
  from .employee import Employee
2
2
  from .employee_type import EmployeeType
3
- from .employee_qualification import EmployeeQualification
3
+ from .employee_qualification import EmployeeQualification
@@ -34,7 +34,9 @@ class EmployeeType(models.Model):
34
34
  )
35
35
 
36
36
  if TYPE_CHECKING:
37
- qualifications = cast(models.manager.RelatedManager["Qualification"], qualifications)
37
+ qualifications = cast(
38
+ models.manager.RelatedManager["Qualification"], qualifications
39
+ )
38
40
 
39
41
  @property
40
42
  def employees(self) -> models.QuerySet["Employee"]: ...
@@ -1,4 +1,4 @@
1
1
  from .examiner import Examiner
2
2
 
3
3
 
4
- __all__ = ["Examiner"]
4
+ __all__ = ["Examiner"]
@@ -12,7 +12,9 @@ if TYPE_CHECKING:
12
12
 
13
13
 
14
14
  class Examiner(Person):
15
- center = models.ForeignKey("Center", on_delete=models.CASCADE, blank=True, null=True)
15
+ center = models.ForeignKey(
16
+ "Center", on_delete=models.CASCADE, blank=True, null=True
17
+ )
16
18
  hash = models.CharField(max_length=255, unique=True)
17
19
 
18
20
  if TYPE_CHECKING:
@@ -23,7 +25,13 @@ class Examiner(Person):
23
25
  return self.first_name + " " + self.last_name
24
26
 
25
27
  @classmethod
26
- def custom_get_or_create(cls, first_name: str, last_name: str, center: "administration.Center", substitute_names: bool = True):
28
+ def custom_get_or_create(
29
+ cls,
30
+ first_name: str,
31
+ last_name: str,
32
+ center: "administration.Center",
33
+ substitute_names: bool = True,
34
+ ):
27
35
  from endoreg_db.models import (
28
36
  FirstName,
29
37
  LastName,
@@ -3,16 +3,18 @@
3
3
 
4
4
  from django.db import models
5
5
 
6
+
6
7
  class FirstNameManager(models.Manager):
7
8
  def get_by_natural_key(self, name):
8
9
  return self.get(name=name)
9
-
10
+
11
+
10
12
  class FirstName(models.Model):
11
13
  objects = FirstNameManager()
12
14
  name = models.CharField(max_length=255, unique=True)
13
-
15
+
14
16
  def natural_key(self):
15
17
  return (self.name,)
16
-
18
+
17
19
  def __str__(self):
18
- return str(self.name)
20
+ return str(self.name)
@@ -1,10 +1,11 @@
1
-
2
1
  from django.db import models
3
2
 
3
+
4
4
  class LastNameManager(models.Manager):
5
5
  def get_by_natural_key(self, name):
6
6
  return self.get(name=name)
7
7
 
8
+
8
9
  class LastName(models.Model):
9
10
  objects = LastNameManager()
10
11
  name = models.CharField(max_length=255, unique=True)
@@ -14,6 +15,6 @@ class LastName(models.Model):
14
15
 
15
16
  def __str__(self):
16
17
  return str(self.name)
17
-
18
+
19
+
18
20
  # Path: endoreg_db/models/persons/first_name.py
19
-
@@ -4,4 +4,4 @@ from .patient_external_id import PatientExternalID
4
4
  __all__ = [
5
5
  "Patient",
6
6
  "PatientExternalID",
7
- ]
7
+ ]
@@ -18,7 +18,6 @@ if TYPE_CHECKING:
18
18
  AnonymExaminationReport,
19
19
  AnonymHistologyReport,
20
20
  Center,
21
- ExaminationIndication,
22
21
  Gender,
23
22
  PatientDisease,
24
23
  PatientEvent,
@@ -34,4 +34,3 @@ class PatientExternalID(models.Model):
34
34
  if TYPE_CHECKING:
35
35
  patient: models.ForeignKey["Patient"]
36
36
  origin: models.CharField[str]
37
-
@@ -1,6 +1,7 @@
1
1
  from abc import abstractmethod
2
2
  from django.db import models
3
3
 
4
+
4
5
  class Person(models.Model):
5
6
  """
6
7
  Abstract base class for a person.
@@ -32,4 +33,3 @@ class Person(models.Model):
32
33
 
33
34
  class Meta:
34
35
  abstract = True
35
-
@@ -1,4 +1,5 @@
1
- '''Module for product models'''
1
+ """Module for product models"""
2
+
2
3
  from .product import Product
3
4
  from .product_material import ProductMaterial
4
5
  from .product_group import ProductGroup
@@ -6,9 +7,9 @@ from .reference_product import ReferenceProduct
6
7
  from .product_weight import ProductWeight
7
8
 
8
9
  __all__ = [
9
- 'Product',
10
- 'ProductMaterial',
11
- 'ProductGroup',
12
- 'ReferenceProduct',
13
- 'ProductWeight',
10
+ "Product",
11
+ "ProductMaterial",
12
+ "ProductGroup",
13
+ "ReferenceProduct",
14
+ "ProductWeight",
14
15
  ]
@@ -23,7 +23,9 @@ class Product(models.Model):
23
23
 
24
24
  name = models.CharField(max_length=255)
25
25
 
26
- transport_route = models.ForeignKey("TransportRoute", on_delete=models.SET_NULL, null=True)
26
+ transport_route = models.ForeignKey(
27
+ "TransportRoute", on_delete=models.SET_NULL, null=True
28
+ )
27
29
  product_group = models.ForeignKey(
28
30
  "ProductGroup",
29
31
  on_delete=models.SET_NULL,
@@ -56,7 +58,9 @@ class Product(models.Model):
56
58
 
57
59
  def _calculate_material_metric(self, component: str, calculation_func):
58
60
  """Helper method to calculate weight or emission for materials of a specific component."""
59
- from .product_material import ProductMaterial # Import locally to avoid circular dependency issues at module level
61
+ from .product_material import (
62
+ ProductMaterial,
63
+ ) # Import locally to avoid circular dependency issues at module level
60
64
 
61
65
  materials = ProductMaterial.objects.filter(product=self, component=component)
62
66
  return calculation_func(materials)
@@ -7,33 +7,35 @@ if TYPE_CHECKING:
7
7
  ReferenceProduct,
8
8
  )
9
9
 
10
+
10
11
  class ProductGroupManager(models.Manager):
11
12
  def get_by_natural_key(self, name):
12
13
  return self.get(name=name)
13
-
14
+
15
+
14
16
  class ProductGroup(models.Model):
15
17
  objects = ProductGroupManager()
16
18
 
17
19
  name = models.CharField(max_length=255)
18
-
20
+
19
21
  if TYPE_CHECKING:
20
22
  reference_product: "ReferenceProduct"
21
23
  products: models.QuerySet["Product"]
22
24
 
23
25
  def natural_key(self):
24
26
  return (self.name,)
25
-
27
+
26
28
  def __str__(self):
27
29
  return str(self.name)
28
-
30
+
29
31
  def get_products(self) -> models.QuerySet["Product"]:
30
32
  from .product import Product
33
+
31
34
  products = self.products.all()
32
35
  if products:
33
36
  return products
34
37
  else:
35
38
  return Product.objects.none()
36
-
37
- def get_reference_product(self) -> "None | ReferenceProduct":
38
- return self.reference_product
39
39
 
40
+ def get_reference_product(self) -> "None | ReferenceProduct":
41
+ return self.reference_product
@@ -37,12 +37,19 @@ class ProductMaterial(models.Model):
37
37
  def get_emission(self) -> tuple[float, Unit]:
38
38
  emission_factor = self.material.emission_factor
39
39
  if emission_factor is None:
40
- raise Exception("No emission factor for material " + self.material.name + " found.")
40
+ raise Exception(
41
+ "No emission factor for material " + self.material.name + " found."
42
+ )
41
43
 
42
44
  # make sure product_material.unit is the same as emission_factor.unit
43
45
  if self.unit is not None and emission_factor.unit is not None:
44
46
  if self.unit != emission_factor.unit:
45
- raise Exception("Unit mismatch: " + self.unit.name + " != " + emission_factor.unit.name)
47
+ raise Exception(
48
+ "Unit mismatch: "
49
+ + self.unit.name
50
+ + " != "
51
+ + emission_factor.unit.name
52
+ )
46
53
 
47
54
  emmision_value = emission_factor.value * self.quantity
48
55
  assert isinstance(emission_factor.unit, Unit)