endoreg-db 0.8.8.0__py3-none-any.whl → 0.8.8.9__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 (402) hide show
  1. endoreg_db/data/__init__.py +22 -8
  2. endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +0 -1
  3. endoreg_db/data/examination/examinations/data.yaml +114 -14
  4. endoreg_db/data/examination/time-type/data.yaml +0 -3
  5. endoreg_db/data/examination_indication/endoscopy.yaml +108 -173
  6. endoreg_db/data/examination_indication_classification/endoscopy.yaml +0 -70
  7. endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +33 -37
  8. endoreg_db/data/finding/00_generic.yaml +35 -0
  9. endoreg_db/data/finding/00_generic_complication.yaml +9 -0
  10. endoreg_db/data/finding/01_gastroscopy_baseline.yaml +88 -0
  11. endoreg_db/data/finding/01_gastroscopy_observation.yaml +113 -0
  12. endoreg_db/data/finding/02_colonoscopy_baseline.yaml +53 -0
  13. endoreg_db/data/finding/02_colonoscopy_hidden.yaml +119 -0
  14. endoreg_db/data/finding/02_colonoscopy_observation.yaml +152 -0
  15. endoreg_db/data/finding_classification/00_generic.yaml +44 -0
  16. endoreg_db/data/finding_classification/00_generic_histology.yaml +28 -0
  17. endoreg_db/data/finding_classification/00_generic_lesion.yaml +52 -0
  18. endoreg_db/data/finding_classification/{colonoscopy_bowel_preparation.yaml → 02_colonoscopy_baseline.yaml} +35 -20
  19. endoreg_db/data/finding_classification/02_colonoscopy_histology.yaml +13 -0
  20. endoreg_db/data/finding_classification/02_colonoscopy_other.yaml +12 -0
  21. endoreg_db/data/finding_classification/02_colonoscopy_polyp.yaml +101 -0
  22. endoreg_db/data/finding_classification_choice/{yes_no_na.yaml → 00_generic.yaml} +5 -1
  23. endoreg_db/data/finding_classification_choice/{examination_setting_generic_types.yaml → 00_generic_baseline.yaml} +10 -2
  24. endoreg_db/data/finding_classification_choice/{complication_generic_types.yaml → 00_generic_complication.yaml} +1 -1
  25. endoreg_db/data/finding_classification_choice/{histology.yaml → 00_generic_histology.yaml} +1 -4
  26. endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
  27. endoreg_db/data/finding_classification_choice/{bowel_preparation.yaml → 02_colonoscopy_bowel_preparation.yaml} +1 -30
  28. endoreg_db/data/{_examples/finding_classification_choice/colonoscopy_not_complete_reason.yaml → finding_classification_choice/02_colonoscopy_generic.yaml} +1 -1
  29. endoreg_db/data/finding_classification_choice/{histology_polyp.yaml → 02_colonoscopy_histology.yaml} +1 -1
  30. endoreg_db/data/{_examples/finding_classification_choice/colonoscopy_location.yaml → finding_classification_choice/02_colonoscopy_location.yaml} +23 -4
  31. endoreg_db/data/finding_classification_choice/02_colonoscopy_other.yaml +34 -0
  32. endoreg_db/data/finding_classification_choice/02_colonoscopy_polyp_advanced_imaging.yaml +76 -0
  33. endoreg_db/data/{_examples/finding_classification_choice/colon_lesion_paris.yaml → finding_classification_choice/02_colonoscopy_polyp_morphology.yaml} +26 -8
  34. endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
  35. endoreg_db/data/finding_classification_type/{colonoscopy_basic.yaml → 00_generic.yaml} +18 -13
  36. endoreg_db/data/finding_classification_type/02_colonoscopy.yaml +9 -0
  37. endoreg_db/data/finding_intervention/00_generic_endoscopy.yaml +59 -0
  38. endoreg_db/data/finding_intervention/00_generic_endoscopy_ablation.yaml +44 -0
  39. endoreg_db/data/finding_intervention/00_generic_endoscopy_bleeding.yaml +55 -0
  40. endoreg_db/data/finding_intervention/00_generic_endoscopy_resection.yaml +85 -0
  41. endoreg_db/data/finding_intervention/00_generic_endoscopy_stenosis.yaml +17 -0
  42. endoreg_db/data/finding_intervention/00_generic_endoscopy_stent.yaml +9 -0
  43. endoreg_db/data/finding_intervention/01_gastroscopy.yaml +19 -0
  44. endoreg_db/data/finding_intervention/04_eus.yaml +39 -0
  45. endoreg_db/data/finding_intervention/05_ercp.yaml +3 -0
  46. endoreg_db/data/finding_type/data.yaml +8 -12
  47. endoreg_db/data/requirement/01_patient_data.yaml +93 -0
  48. endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
  49. endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +0 -2
  50. endoreg_db/data/requirement_set/90_coloreg.yaml +20 -8
  51. endoreg_db/exceptions.py +0 -1
  52. endoreg_db/forms/examination_form.py +1 -1
  53. endoreg_db/helpers/data_loader.py +124 -52
  54. endoreg_db/helpers/default_objects.py +116 -81
  55. endoreg_db/import_files/__init__.py +27 -0
  56. endoreg_db/import_files/context/__init__.py +7 -0
  57. endoreg_db/import_files/context/default_sensitive_meta.py +81 -0
  58. endoreg_db/import_files/context/ensure_center.py +17 -0
  59. endoreg_db/import_files/context/file_lock.py +66 -0
  60. endoreg_db/import_files/context/import_context.py +43 -0
  61. endoreg_db/import_files/context/validate_directories.py +56 -0
  62. endoreg_db/import_files/file_storage/__init__.py +15 -0
  63. endoreg_db/import_files/file_storage/create_report_file.py +76 -0
  64. endoreg_db/import_files/file_storage/create_video_file.py +75 -0
  65. endoreg_db/import_files/file_storage/sensitive_meta_storage.py +39 -0
  66. endoreg_db/import_files/file_storage/state_management.py +400 -0
  67. endoreg_db/import_files/file_storage/storage.py +36 -0
  68. endoreg_db/import_files/import_service.md +26 -0
  69. endoreg_db/import_files/processing/__init__.py +11 -0
  70. endoreg_db/import_files/processing/report_processing/report_anonymization.py +94 -0
  71. endoreg_db/import_files/processing/sensitive_meta_adapter.py +51 -0
  72. endoreg_db/import_files/processing/video_processing/video_anonymization.py +107 -0
  73. endoreg_db/import_files/processing/video_processing/video_cleanup_on_error.py +119 -0
  74. endoreg_db/import_files/pseudonymization/fake.py +52 -0
  75. endoreg_db/import_files/pseudonymization/k_anonymity.py +182 -0
  76. endoreg_db/import_files/pseudonymization/k_pseudonymity.py +128 -0
  77. endoreg_db/import_files/report_import_service.py +141 -0
  78. endoreg_db/import_files/video_import_service.py +150 -0
  79. endoreg_db/management/commands/import_report.py +130 -65
  80. endoreg_db/management/commands/import_video_with_classification.py +1 -1
  81. endoreg_db/management/commands/load_ai_model_data.py +5 -5
  82. endoreg_db/management/commands/load_ai_model_label_data.py +9 -7
  83. endoreg_db/management/commands/load_base_db_data.py +5 -134
  84. endoreg_db/management/commands/load_contraindication_data.py +14 -16
  85. endoreg_db/management/commands/load_disease_classification_choices_data.py +15 -18
  86. endoreg_db/management/commands/load_disease_classification_data.py +15 -18
  87. endoreg_db/management/commands/load_disease_data.py +25 -28
  88. endoreg_db/management/commands/load_endoscope_data.py +20 -27
  89. endoreg_db/management/commands/load_event_data.py +14 -16
  90. endoreg_db/management/commands/load_examination_data.py +31 -44
  91. endoreg_db/management/commands/load_examination_indication_data.py +20 -21
  92. endoreg_db/management/commands/load_finding_data.py +52 -80
  93. endoreg_db/management/commands/load_information_source.py +21 -23
  94. endoreg_db/management/commands/load_lab_value_data.py +17 -26
  95. endoreg_db/management/commands/load_medication_data.py +13 -12
  96. endoreg_db/management/commands/load_organ_data.py +15 -19
  97. endoreg_db/management/commands/load_pdf_type_data.py +19 -18
  98. endoreg_db/management/commands/load_profession_data.py +14 -17
  99. endoreg_db/management/commands/load_qualification_data.py +20 -23
  100. endoreg_db/management/commands/load_report_reader_flag_data.py +17 -19
  101. endoreg_db/management/commands/load_requirement_data.py +14 -20
  102. endoreg_db/management/commands/load_risk_data.py +7 -6
  103. endoreg_db/management/commands/load_shift_data.py +20 -23
  104. endoreg_db/management/commands/load_tag_data.py +8 -11
  105. endoreg_db/management/commands/load_unit_data.py +17 -19
  106. endoreg_db/management/commands/start_filewatcher.py +46 -37
  107. endoreg_db/management/commands/validate_video_files.py +1 -5
  108. endoreg_db/migrations/0001_initial.py +1360 -1812
  109. endoreg_db/models/administration/person/patient/patient.py +72 -46
  110. endoreg_db/models/label/__init__.py +2 -2
  111. endoreg_db/models/label/annotation/video_segmentation_annotation.py +18 -26
  112. endoreg_db/models/label/label_video_segment/label_video_segment.py +23 -1
  113. endoreg_db/models/media/pdf/raw_pdf.py +136 -64
  114. endoreg_db/models/media/pdf/report_reader/report_reader_config.py +34 -10
  115. endoreg_db/models/media/processing_history/__init__.py +5 -0
  116. endoreg_db/models/media/processing_history/processing_history.py +96 -0
  117. endoreg_db/models/media/video/create_from_file.py +101 -31
  118. endoreg_db/models/media/video/video_file.py +125 -105
  119. endoreg_db/models/media/video/video_file_io.py +31 -26
  120. endoreg_db/models/medical/contraindication/README.md +1 -0
  121. endoreg_db/models/medical/examination/examination.py +28 -8
  122. endoreg_db/models/medical/examination/examination_indication.py +13 -79
  123. endoreg_db/models/medical/examination/examination_time.py +8 -3
  124. endoreg_db/models/medical/finding/finding.py +5 -12
  125. endoreg_db/models/medical/finding/finding_classification.py +18 -37
  126. endoreg_db/models/medical/finding/finding_intervention.py +7 -9
  127. endoreg_db/models/medical/hardware/endoscope.py +6 -0
  128. endoreg_db/models/medical/patient/medication_examples.py +5 -1
  129. endoreg_db/models/medical/patient/patient_finding.py +1 -1
  130. endoreg_db/models/metadata/pdf_meta.py +22 -10
  131. endoreg_db/models/metadata/sensitive_meta.py +3 -0
  132. endoreg_db/models/metadata/sensitive_meta_logic.py +200 -124
  133. endoreg_db/models/other/information_source.py +27 -6
  134. endoreg_db/models/report/__init__.py +0 -0
  135. endoreg_db/models/report/images.py +0 -0
  136. endoreg_db/models/report/report.py +6 -0
  137. endoreg_db/models/requirement/requirement.py +59 -399
  138. endoreg_db/models/requirement/requirement_operator.py +86 -98
  139. endoreg_db/models/state/audit_ledger.py +4 -5
  140. endoreg_db/models/state/raw_pdf.py +69 -30
  141. endoreg_db/models/state/video.py +64 -49
  142. endoreg_db/models/upload_job.py +33 -9
  143. endoreg_db/models/utils.py +27 -23
  144. endoreg_db/queries/__init__.py +3 -1
  145. endoreg_db/schemas/examination_evaluation.py +1 -1
  146. endoreg_db/serializers/__init__.py +2 -8
  147. endoreg_db/serializers/label_video_segment/label_video_segment.py +2 -29
  148. endoreg_db/serializers/meta/__init__.py +1 -6
  149. endoreg_db/serializers/misc/sensitive_patient_data.py +50 -26
  150. endoreg_db/serializers/patient_examination/patient_examination.py +3 -3
  151. endoreg_db/serializers/pdf/anony_text_validation.py +39 -23
  152. endoreg_db/serializers/video/video_file_list.py +65 -34
  153. endoreg_db/services/__old/pdf_import.py +1487 -0
  154. endoreg_db/services/__old/video_import.py +1306 -0
  155. endoreg_db/services/anonymization.py +63 -26
  156. endoreg_db/services/lookup_service.py +28 -28
  157. endoreg_db/services/lookup_store.py +2 -2
  158. endoreg_db/services/pdf_import.py +0 -1480
  159. endoreg_db/services/report_import.py +10 -0
  160. endoreg_db/services/video_import.py +6 -1165
  161. endoreg_db/tasks/upload_tasks.py +79 -70
  162. endoreg_db/tasks/video_ingest.py +8 -4
  163. endoreg_db/urls/__init__.py +0 -14
  164. endoreg_db/urls/ai.py +32 -0
  165. endoreg_db/urls/media.py +21 -24
  166. endoreg_db/utils/dataloader.py +87 -57
  167. endoreg_db/utils/paths.py +110 -46
  168. endoreg_db/utils/pipelines/Readme.md +1 -1
  169. endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +97 -0
  170. endoreg_db/views/__init__.py +85 -173
  171. endoreg_db/views/ai/__init__.py +8 -0
  172. endoreg_db/views/ai/label.py +155 -0
  173. endoreg_db/views/anonymization/media_management.py +8 -7
  174. endoreg_db/views/anonymization/overview.py +97 -68
  175. endoreg_db/views/anonymization/validate.py +25 -21
  176. endoreg_db/views/media/__init__.py +5 -20
  177. endoreg_db/views/media/pdf_media.py +109 -65
  178. endoreg_db/views/media/sensitive_metadata.py +163 -148
  179. endoreg_db/views/meta/__init__.py +0 -8
  180. endoreg_db/views/misc/__init__.py +1 -7
  181. endoreg_db/views/misc/upload_views.py +94 -93
  182. endoreg_db/views/report/__init__.py +7 -0
  183. endoreg_db/views/{pdf → report}/reimport.py +45 -24
  184. endoreg_db/views/{pdf/pdf_stream.py → report/report_stream.py} +40 -32
  185. endoreg_db/views/requirement/lookup_store.py +22 -90
  186. endoreg_db/views/video/__init__.py +23 -22
  187. endoreg_db/views/video/correction.py +201 -172
  188. endoreg_db/views/video/reimport.py +1 -1
  189. endoreg_db/views/{media/video_segments.py → video/segments_crud.py} +75 -37
  190. endoreg_db/views/video/{video_meta.py → video_meta_stats.py} +2 -2
  191. endoreg_db/views/video/video_stream.py +7 -8
  192. {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/METADATA +2 -2
  193. {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/RECORD +217 -335
  194. {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/WHEEL +1 -1
  195. endoreg_db/data/_examples/disease.yaml +0 -55
  196. endoreg_db/data/_examples/disease_classification.yaml +0 -13
  197. endoreg_db/data/_examples/disease_classification_choice.yaml +0 -62
  198. endoreg_db/data/_examples/event.yaml +0 -64
  199. endoreg_db/data/_examples/examination.yaml +0 -72
  200. endoreg_db/data/_examples/finding/anatomy_colon.yaml +0 -128
  201. endoreg_db/data/_examples/finding/colonoscopy.yaml +0 -40
  202. endoreg_db/data/_examples/finding/colonoscopy_bowel_prep.yaml +0 -56
  203. endoreg_db/data/_examples/finding/complication.yaml +0 -16
  204. endoreg_db/data/_examples/finding/data.yaml +0 -105
  205. endoreg_db/data/_examples/finding/examination_setting.yaml +0 -16
  206. endoreg_db/data/_examples/finding/medication_related.yaml +0 -18
  207. endoreg_db/data/_examples/finding/outcome.yaml +0 -12
  208. endoreg_db/data/_examples/finding_classification/colonoscopy_bowel_preparation.yaml +0 -68
  209. endoreg_db/data/_examples/finding_classification/colonoscopy_jnet.yaml +0 -22
  210. endoreg_db/data/_examples/finding_classification/colonoscopy_kudo.yaml +0 -25
  211. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
  212. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
  213. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_size.yaml +0 -68
  214. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
  215. endoreg_db/data/_examples/finding_classification/colonoscopy_location.yaml +0 -80
  216. endoreg_db/data/_examples/finding_classification/colonoscopy_lst.yaml +0 -21
  217. endoreg_db/data/_examples/finding_classification/colonoscopy_nice.yaml +0 -20
  218. endoreg_db/data/_examples/finding_classification/colonoscopy_paris.yaml +0 -26
  219. endoreg_db/data/_examples/finding_classification/colonoscopy_sano.yaml +0 -22
  220. endoreg_db/data/_examples/finding_classification/colonoscopy_summary.yaml +0 -53
  221. endoreg_db/data/_examples/finding_classification/complication_generic.yaml +0 -25
  222. endoreg_db/data/_examples/finding_classification/examination_setting_generic.yaml +0 -40
  223. endoreg_db/data/_examples/finding_classification/histology_colo.yaml +0 -51
  224. endoreg_db/data/_examples/finding_classification/intervention_required.yaml +0 -26
  225. endoreg_db/data/_examples/finding_classification/medication_related.yaml +0 -23
  226. endoreg_db/data/_examples/finding_classification/visualized.yaml +0 -33
  227. endoreg_db/data/_examples/finding_classification_choice/bowel_preparation.yaml +0 -78
  228. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
  229. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
  230. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
  231. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_lst.yaml +0 -15
  232. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_nice.yaml +0 -17
  233. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
  234. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_sano.yaml +0 -14
  235. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
  236. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_size.yaml +0 -82
  237. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
  238. endoreg_db/data/_examples/finding_classification_choice/complication_generic_types.yaml +0 -15
  239. endoreg_db/data/_examples/finding_classification_choice/examination_setting_generic_types.yaml +0 -15
  240. endoreg_db/data/_examples/finding_classification_choice/histology.yaml +0 -24
  241. endoreg_db/data/_examples/finding_classification_choice/histology_polyp.yaml +0 -20
  242. endoreg_db/data/_examples/finding_classification_choice/outcome.yaml +0 -19
  243. endoreg_db/data/_examples/finding_classification_choice/yes_no_na.yaml +0 -11
  244. endoreg_db/data/_examples/finding_classification_type/colonoscopy_basic.yaml +0 -48
  245. endoreg_db/data/_examples/finding_intervention/endoscopy.yaml +0 -43
  246. endoreg_db/data/_examples/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
  247. endoreg_db/data/_examples/finding_intervention/endoscopy_egd.yaml +0 -128
  248. endoreg_db/data/_examples/finding_intervention/endoscopy_ercp.yaml +0 -32
  249. endoreg_db/data/_examples/finding_intervention/endoscopy_eus_lower.yaml +0 -9
  250. endoreg_db/data/_examples/finding_intervention/endoscopy_eus_upper.yaml +0 -36
  251. endoreg_db/data/_examples/finding_intervention_type/endoscopy.yaml +0 -15
  252. endoreg_db/data/_examples/finding_type/data.yaml +0 -43
  253. endoreg_db/data/_examples/requirement/age.yaml +0 -26
  254. endoreg_db/data/_examples/requirement/gender.yaml +0 -25
  255. endoreg_db/data/_examples/requirement_set/01_endoscopy_generic.yaml +0 -48
  256. endoreg_db/data/_examples/requirement_set/colonoscopy_austria_screening.yaml +0 -57
  257. endoreg_db/data/_examples/requirement_set/endoscopy_bleeding_risk.yaml +0 -52
  258. endoreg_db/data/_examples/yaml_examples.xlsx +0 -0
  259. endoreg_db/data/finding/anatomy_colon.yaml +0 -128
  260. endoreg_db/data/finding/colonoscopy.yaml +0 -40
  261. endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +0 -56
  262. endoreg_db/data/finding/complication.yaml +0 -16
  263. endoreg_db/data/finding/data.yaml +0 -105
  264. endoreg_db/data/finding/examination_setting.yaml +0 -16
  265. endoreg_db/data/finding/medication_related.yaml +0 -18
  266. endoreg_db/data/finding/outcome.yaml +0 -12
  267. endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +0 -22
  268. endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +0 -25
  269. endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
  270. endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
  271. endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +0 -38
  272. endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
  273. endoreg_db/data/finding_classification/colonoscopy_location.yaml +0 -49
  274. endoreg_db/data/finding_classification/colonoscopy_lst.yaml +0 -21
  275. endoreg_db/data/finding_classification/colonoscopy_nice.yaml +0 -20
  276. endoreg_db/data/finding_classification/colonoscopy_paris.yaml +0 -26
  277. endoreg_db/data/finding_classification/colonoscopy_sano.yaml +0 -22
  278. endoreg_db/data/finding_classification/colonoscopy_summary.yaml +0 -53
  279. endoreg_db/data/finding_classification/complication_generic.yaml +0 -25
  280. endoreg_db/data/finding_classification/examination_setting_generic.yaml +0 -40
  281. endoreg_db/data/finding_classification/histology_colo.yaml +0 -43
  282. endoreg_db/data/finding_classification/intervention_required.yaml +0 -26
  283. endoreg_db/data/finding_classification/medication_related.yaml +0 -23
  284. endoreg_db/data/finding_classification/visualized.yaml +0 -33
  285. endoreg_db/data/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
  286. endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
  287. endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
  288. endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +0 -15
  289. endoreg_db/data/finding_classification_choice/colon_lesion_nice.yaml +0 -17
  290. endoreg_db/data/finding_classification_choice/colon_lesion_paris.yaml +0 -57
  291. endoreg_db/data/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
  292. endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +0 -14
  293. endoreg_db/data/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
  294. endoreg_db/data/finding_classification_choice/colonoscopy_location.yaml +0 -229
  295. endoreg_db/data/finding_classification_choice/colonoscopy_not_complete_reason.yaml +0 -19
  296. endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +0 -82
  297. endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
  298. endoreg_db/data/finding_classification_choice/outcome.yaml +0 -19
  299. endoreg_db/data/finding_intervention/endoscopy.yaml +0 -43
  300. endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
  301. endoreg_db/data/finding_intervention/endoscopy_egd.yaml +0 -128
  302. endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +0 -32
  303. endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +0 -9
  304. endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +0 -36
  305. endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +0 -79
  306. endoreg_db/data/requirement/age.yaml +0 -26
  307. endoreg_db/data/requirement/colonoscopy_baseline_austria.yaml +0 -45
  308. endoreg_db/data/requirement/disease_cardiovascular.yaml +0 -79
  309. endoreg_db/data/requirement/disease_classification_choice_cardiovascular.yaml +0 -41
  310. endoreg_db/data/requirement/disease_hepatology.yaml +0 -12
  311. endoreg_db/data/requirement/disease_misc.yaml +0 -12
  312. endoreg_db/data/requirement/disease_renal.yaml +0 -96
  313. endoreg_db/data/requirement/endoscopy_bleeding_risk.yaml +0 -59
  314. endoreg_db/data/requirement/event_cardiology.yaml +0 -251
  315. endoreg_db/data/requirement/event_requirements.yaml +0 -145
  316. endoreg_db/data/requirement/finding_colon_polyp.yaml +0 -50
  317. endoreg_db/data/requirement/gender.yaml +0 -25
  318. endoreg_db/data/requirement/lab_value.yaml +0 -441
  319. endoreg_db/data/requirement/medication.yaml +0 -93
  320. endoreg_db/data/requirement_operator/age.yaml +0 -13
  321. endoreg_db/data/requirement_operator/lab_operators.yaml +0 -129
  322. endoreg_db/data/requirement_operator/model_operators.yaml +0 -96
  323. endoreg_db/management/commands/init_default_ai_model.py +0 -112
  324. endoreg_db/management/commands/reset_celery_schedule.py +0 -9
  325. endoreg_db/management/commands/validate_video.py +0 -204
  326. endoreg_db/migrations/0002_requirementset_depends_on.py +0 -18
  327. endoreg_db/migrations/_old/0001_initial.py +0 -1857
  328. endoreg_db/migrations/_old/0002_add_video_correction_models.py +0 -52
  329. endoreg_db/migrations/_old/0003_add_center_display_name.py +0 -30
  330. endoreg_db/migrations/_old/0004_employee_city_employee_post_code_employee_street_and_more.py +0 -68
  331. endoreg_db/migrations/_old/0004_remove_casetemplate_rules_and_more.py +0 -77
  332. endoreg_db/migrations/_old/0005_merge_20251111_1003.py +0 -14
  333. endoreg_db/migrations/_old/0006_sensitivemeta_anonymized_text_and_more.py +0 -68
  334. endoreg_db/migrations/_old/0007_remove_rule_attribute_dtype_remove_rule_rule_type_and_more.py +0 -89
  335. endoreg_db/migrations/_old/0008_remove_event_event_classification_and_more.py +0 -27
  336. endoreg_db/migrations/_old/0009_alter_modelmeta_options_and_more.py +0 -21
  337. endoreg_db/renames.yml +0 -8
  338. endoreg_db/serializers/_old/raw_pdf_meta_validation.py +0 -223
  339. endoreg_db/serializers/_old/raw_video_meta_validation.py +0 -179
  340. endoreg_db/serializers/_old/video.py +0 -71
  341. endoreg_db/serializers/meta/pdf_file_meta_extraction.py +0 -115
  342. endoreg_db/serializers/meta/report_meta.py +0 -53
  343. endoreg_db/serializers/report/__init__.py +0 -9
  344. endoreg_db/serializers/report/mixins.py +0 -45
  345. endoreg_db/serializers/report/report.py +0 -105
  346. endoreg_db/serializers/report/report_list.py +0 -22
  347. endoreg_db/serializers/report/secure_file_url.py +0 -26
  348. endoreg_db/services/requirements_object.py +0 -147
  349. endoreg_db/services/storage_aware_video_processor.py +0 -370
  350. endoreg_db/urls/files.py +0 -6
  351. endoreg_db/urls/label_video_segment_validate.py +0 -33
  352. endoreg_db/urls/label_video_segments.py +0 -46
  353. endoreg_db/views/label/__init__.py +0 -5
  354. endoreg_db/views/label/label.py +0 -15
  355. endoreg_db/views/label_video_segment/__init__.py +0 -16
  356. endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +0 -44
  357. endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +0 -50
  358. endoreg_db/views/label_video_segment/label_video_segment.py +0 -77
  359. endoreg_db/views/label_video_segment/label_video_segment_by_label.py +0 -174
  360. endoreg_db/views/label_video_segment/label_video_segment_detail.py +0 -73
  361. endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +0 -46
  362. endoreg_db/views/label_video_segment/validate.py +0 -226
  363. endoreg_db/views/media/segments.py +0 -71
  364. endoreg_db/views/meta/available_files_list.py +0 -146
  365. endoreg_db/views/meta/report_meta.py +0 -53
  366. endoreg_db/views/meta/sensitive_meta_detail.py +0 -85
  367. endoreg_db/views/misc/secure_file_serving_view.py +0 -80
  368. endoreg_db/views/misc/secure_file_url_view.py +0 -84
  369. endoreg_db/views/misc/secure_url_validate.py +0 -79
  370. endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +0 -164
  371. endoreg_db/views/patient_finding_location/__init__.py +0 -5
  372. endoreg_db/views/patient_finding_location/pfl_create.py +0 -70
  373. endoreg_db/views/patient_finding_morphology/__init__.py +0 -5
  374. endoreg_db/views/patient_finding_morphology/pfm_create.py +0 -70
  375. endoreg_db/views/pdf/__init__.py +0 -8
  376. endoreg_db/views/video/segmentation.py +0 -274
  377. endoreg_db/views/video/task_status.py +0 -49
  378. endoreg_db/views/video/timeline.py +0 -46
  379. endoreg_db/views/video/video_analyze.py +0 -52
  380. /endoreg_db/data/requirement/{colon_polyp_intervention.yaml → old/colon_polyp_intervention.yaml} +0 -0
  381. /endoreg_db/data/{_examples/requirement → requirement/old}/colonoscopy_baseline_austria.yaml +0 -0
  382. /endoreg_db/data/requirement/{coloreg_colon_polyp.yaml → old/coloreg_colon_polyp.yaml} +0 -0
  383. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_cardiovascular.yaml +0 -0
  384. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_classification_choice_cardiovascular.yaml +0 -0
  385. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_hepatology.yaml +0 -0
  386. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_misc.yaml +0 -0
  387. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_renal.yaml +0 -0
  388. /endoreg_db/data/{_examples/requirement → requirement/old}/endoscopy_bleeding_risk.yaml +0 -0
  389. /endoreg_db/data/{_examples/requirement → requirement/old}/event_cardiology.yaml +0 -0
  390. /endoreg_db/data/{_examples/requirement → requirement/old}/event_requirements.yaml +0 -0
  391. /endoreg_db/data/{_examples/requirement → requirement/old}/finding_colon_polyp.yaml +0 -0
  392. /endoreg_db/{migrations/__init__.py → data/requirement/old/gender.yaml} +0 -0
  393. /endoreg_db/data/{_examples/requirement → requirement/old}/lab_value.yaml +0 -0
  394. /endoreg_db/data/{_examples/requirement → requirement/old}/medication.yaml +0 -0
  395. /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/age.yaml +0 -0
  396. /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/lab_operators.yaml +0 -0
  397. /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/model_operators.yaml +0 -0
  398. /endoreg_db/{urls/sensitive_meta.py → import_files/pseudonymization/__init__.py} +0 -0
  399. /endoreg_db/{views/pdf/pdf_stream_views.py → import_files/pseudonymization/pseudonymize.py} +0 -0
  400. /endoreg_db/utils/requirement_operator_logic/{lab_value_operators.py → _old/lab_value_operators.py} +0 -0
  401. /endoreg_db/utils/requirement_operator_logic/{model_evaluators.py → _old/model_evaluators.py} +0 -0
  402. {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/licenses/LICENSE +0 -0
@@ -48,8 +48,12 @@ class Patient(Person):
48
48
  first_name = models.CharField(max_length=100)
49
49
  last_name = models.CharField(max_length=100)
50
50
  dob = models.DateField(null=True, blank=True)
51
- gender = models.ForeignKey("Gender", on_delete=models.SET_NULL, null=True, blank=True)
52
- center = models.ForeignKey("Center", on_delete=models.SET_NULL, null=True, blank=True)
51
+ gender = models.ForeignKey(
52
+ "Gender", on_delete=models.SET_NULL, null=True, blank=True
53
+ )
54
+ center = models.ForeignKey(
55
+ "Center", on_delete=models.SET_NULL, null=True, blank=True
56
+ )
53
57
  patient_hash = models.CharField(max_length=255, blank=True, null=True)
54
58
 
55
59
  objects = models.Manager() # Default manager
@@ -73,10 +77,14 @@ class Patient(Person):
73
77
  def patient_examinations(self) -> RelatedManager[PatientExamination]: ...
74
78
 
75
79
  @property
76
- def anonymexaminationreport_set(self) -> RelatedManager[AnonymExaminationReport]: ...
80
+ def anonymexaminationreport_set(
81
+ self,
82
+ ) -> RelatedManager[AnonymExaminationReport]: ...
77
83
 
78
84
  @property
79
- def anonymhistologyreport_set(self) -> RelatedManager[AnonymHistologyReport]: ...
85
+ def anonymhistologyreport_set(
86
+ self,
87
+ ) -> RelatedManager[AnonymHistologyReport]: ...
80
88
 
81
89
  @property
82
90
  def external_ids(self) -> RelatedManager[PatientExternalID]: ...
@@ -114,7 +122,9 @@ class Patient(Person):
114
122
  # If no patient with the given hash exists, create a new pseudo patient
115
123
  assert center, "Center must be provided to create a new pseudo patient"
116
124
  assert gender, "Gender must be provided to create a new pseudo patient"
117
- assert birth_month, "Birth month must be provided to create a new pseudo patient"
125
+ assert birth_month, (
126
+ "Birth month must be provided to create a new pseudo patient"
127
+ )
118
128
  assert birth_year, "Birth year must be provided to create a new pseudo patient"
119
129
 
120
130
  # Ensure gender is a Gender object
@@ -173,35 +183,15 @@ class Patient(Person):
173
183
  )
174
184
 
175
185
  else:
176
- patient_examination = PatientExamination(patient=self, date_start=date_start, date_end=date_end)
186
+ patient_examination = PatientExamination(
187
+ patient=self, date_start=date_start, date_end=date_end
188
+ )
177
189
 
178
190
  if save:
179
191
  patient_examination.save()
180
192
 
181
193
  return patient_examination
182
194
 
183
- def create_examination_by_indication(self, indication: "ExaminationIndication", date_start: Optional[datetime] = None, date_end: Optional[datetime] = None):
184
- from ....medical import (
185
- PatientExamination,
186
- PatientExaminationIndication,
187
- )
188
-
189
- examination = indication.get_examination()
190
-
191
- patient_examination = PatientExamination.objects.create(
192
- patient=self,
193
- examination=examination,
194
- date_start=date_start,
195
- date_end=date_end,
196
- )
197
-
198
- patient_examination.save()
199
-
200
- patient_examination_indication = PatientExaminationIndication.objects.create(patient_examination=patient_examination, examination_indication=indication)
201
- patient_examination_indication.save()
202
-
203
- return patient_examination, patient_examination_indication
204
-
205
195
  def create_event(
206
196
  self,
207
197
  event_name_str: str,
@@ -231,9 +221,9 @@ class Patient(Person):
231
221
 
232
222
  def create_examination_by_pdf(self, pdf: "RawPdfFile"):
233
223
  """
234
- Creates a patient examination and associates it with the provided PDF report file.
224
+ Creates a patient examination and associates it with the provided report report file.
235
225
 
236
- The examination is created for this patient, saved, and linked to the given RawPdfFile instance. The PDF's examination field is updated and saved. Returns the created examination instance.
226
+ The examination is created for this patient, saved, and linked to the given RawPdfFile instance. The report's examination field is updated and saved. Returns the created examination instance.
237
227
 
238
228
  Args:
239
229
  pdf: The RawPdfFile to associate with the new examination.
@@ -273,7 +263,9 @@ class Patient(Person):
273
263
  return gender_obj
274
264
 
275
265
  @classmethod
276
- def get_random_age(cls, min_age=55, max_age=90, mean_age=65, std_age=10, distribution="normal"):
266
+ def get_random_age(
267
+ cls, min_age=55, max_age=90, mean_age=65, std_age=10, distribution="normal"
268
+ ):
277
269
  """
278
270
  Get a random age based on the given distribution.
279
271
 
@@ -371,11 +363,17 @@ class Patient(Person):
371
363
  :return: The age of the patient.
372
364
  """
373
365
  # calculate correct age based on current date including day and month
374
- current_date = timezone.now().date() # Use timezone.now() here too for consistency
366
+ current_date = (
367
+ timezone.now().date()
368
+ ) # Use timezone.now() here too for consistency
375
369
  dob = self.dob
376
370
  # Ensure dob is not None before calculation
377
371
  if dob:
378
- age = current_date.year - dob.year - ((current_date.month, current_date.day) < (dob.month, dob.day))
372
+ age = (
373
+ current_date.year
374
+ - dob.year
375
+ - ((current_date.month, current_date.day) < (dob.month, dob.day))
376
+ )
379
377
  return age
380
378
  return None # Or handle the case where dob is None appropriately
381
379
 
@@ -394,16 +392,24 @@ class Patient(Person):
394
392
  date = timezone.now() # Use timezone.now() instead of datetime.now()
395
393
  # Ensure the provided date is timezone-aware if it's not None
396
394
  elif timezone.is_naive(date):
397
- logger.warning(f"Received naive datetime {date} for PatientLabSample. Making it timezone-aware using current timezone.")
395
+ logger.warning(
396
+ f"Received naive datetime {date} for PatientLabSample. Making it timezone-aware using current timezone."
397
+ )
398
398
  date = timezone.make_aware(date, timezone.get_current_timezone())
399
399
 
400
400
  if isinstance(sample_type, str):
401
401
  sample_type = PatientLabSampleType.objects.get(name=sample_type)
402
- assert sample_type is not None, f"Sample type with name '{sample_type}' not found."
402
+ assert sample_type is not None, (
403
+ f"Sample type with name '{sample_type}' not found."
404
+ )
403
405
  elif not isinstance(sample_type, PatientLabSampleType):
404
- raise ValueError("Sample type must be either a string or a PatientLabSampleType object.")
406
+ raise ValueError(
407
+ "Sample type must be either a string or a PatientLabSampleType object."
408
+ )
405
409
 
406
- patient_lab_sample = PatientLabSample.objects.create(patient=self, sample_type=sample_type, date=date)
410
+ patient_lab_sample = PatientLabSample.objects.create(
411
+ patient=self, sample_type=sample_type, date=date
412
+ )
407
413
 
408
414
  return patient_lab_sample
409
415
 
@@ -414,27 +420,41 @@ class Patient(Person):
414
420
  as a RequirementLinks object. For a Patient, this includes their diseases, associated classification choices,
415
421
  all their lab values, and medication information.
416
422
  """
417
- from endoreg_db.models.medical.disease import Disease, DiseaseClassificationChoice
423
+ from endoreg_db.models.medical.disease import (
424
+ Disease,
425
+ DiseaseClassificationChoice,
426
+ )
418
427
 
419
428
  # Imports for medication related models
420
429
  from endoreg_db.models.medical.medication.medication import Medication
421
- from endoreg_db.models.medical.medication.medication_indication import MedicationIndication
422
- from endoreg_db.models.medical.medication.medication_intake_time import MedicationIntakeTime
430
+ from endoreg_db.models.medical.medication.medication_indication import (
431
+ MedicationIndication,
432
+ )
433
+ from endoreg_db.models.medical.medication.medication_intake_time import (
434
+ MedicationIntakeTime,
435
+ )
423
436
  from endoreg_db.utils.links.requirement_link import RequirementLinks
437
+
424
438
  # PatientMedication objects are retrieved via self.patientmedication_set
425
439
  # PatientLabValue objects are retrieved via self.lab_values
426
440
 
427
- patient_disease_instances = list(self.diseases.all()) # These are PatientDisease model instances
441
+ patient_disease_instances = list(
442
+ self.diseases.all()
443
+ ) # These are PatientDisease model instances
428
444
  actual_diseases: List[Disease] = []
429
445
  all_classification_choices: List[DiseaseClassificationChoice] = []
430
446
 
431
447
  for pd_instance in patient_disease_instances:
432
448
  if pd_instance.disease: # pd_instance.disease is a Disease instance
433
449
  actual_diseases.append(pd_instance.disease)
434
- all_classification_choices.extend(list(pd_instance.classification_choices.all()))
450
+ all_classification_choices.extend(
451
+ list(pd_instance.classification_choices.all())
452
+ )
435
453
 
436
454
  # Assuming self.lab_values is a related manager for PatientLabValue instances
437
- patient_lab_value_instances = list(self.lab_values.all()) # These are PatientLabValue model instances
455
+ patient_lab_value_instances = list(
456
+ self.lab_values.all()
457
+ ) # These are PatientLabValue model instances
438
458
 
439
459
  # Medication information
440
460
  # self.patientmedication_set gives a QuerySet of PatientMedication
@@ -445,11 +465,17 @@ class Patient(Person):
445
465
  med_intake_times: List[MedicationIntakeTime] = []
446
466
 
447
467
  for pm_instance in patient_medication_instances:
448
- if pm_instance.medication: # pm_instance.medication is a Medication instance
468
+ if (
469
+ pm_instance.medication
470
+ ): # pm_instance.medication is a Medication instance
449
471
  actual_medications.append(pm_instance.medication)
450
- if pm_instance.medication_indication: # pm_instance.medication_indication is a MedicationIndication instance
472
+ if (
473
+ pm_instance.medication_indication
474
+ ): # pm_instance.medication_indication is a MedicationIndication instance
451
475
  med_indications.append(pm_instance.medication_indication)
452
- med_intake_times.extend(list(pm_instance.intake_times.all())) # pm_instance.intake_times is a ManyRelatedManager for MedicationIntakeTime
476
+ med_intake_times.extend(
477
+ list(pm_instance.intake_times.all())
478
+ ) # pm_instance.intake_times is a ManyRelatedManager for MedicationIntakeTime
453
479
 
454
480
  return RequirementLinks(
455
481
  diseases=list(set(actual_diseases)),
@@ -1,6 +1,5 @@
1
1
  from .annotation import (
2
2
  ImageClassificationAnnotation,
3
- VideoSegmentationAnnotation,
4
3
  )
5
4
  from .label import Label
6
5
  from .label_set import LabelSet
@@ -10,6 +9,7 @@ from .label_video_segment import (
10
9
  )
11
10
  from .video_segmentation_label import VideoSegmentationLabel
12
11
  from .video_segmentation_labelset import VideoSegmentationLabelSet
12
+ from .annotation import VideoSegmentationAnnotation
13
13
 
14
14
  __all__ = [
15
15
  "Label",
@@ -19,5 +19,5 @@ __all__ = [
19
19
  "VideoSegmentationLabelSet",
20
20
  "LabelVideoSegment",
21
21
  "ImageClassificationAnnotation",
22
- "VideoSegmentationAnnotation",
22
+ "VideoSegmentationAnnotation"
23
23
  ]
@@ -3,6 +3,7 @@ from typing import TYPE_CHECKING
3
3
  from django.db import models
4
4
  from django.db.models import CheckConstraint, F, Q
5
5
 
6
+
6
7
  if TYPE_CHECKING:
7
8
  from ...media.video.video_file import VideoFile
8
9
  from ..video_segmentation_label import VideoSegmentationLabel
@@ -14,27 +15,23 @@ class VideoSegmentationAnnotation(models.Model):
14
15
  within a specific video file.
15
16
 
16
17
  An annotation must be associated with exactly one `VideoFile`.
17
-
18
- Attributes:
19
- video_file (ForeignKey): The video file associated with the annotation.
20
- label (ForeignKey): The label for the annotation.
21
- start_time (float): The start time of the annotation in seconds.
22
- stop_time (float): The stop time of the annotation in seconds.
23
- is_true (bool): Indicates if the annotation is valid (defaults to True).
24
18
  """
25
19
 
26
- # Foreign key to the unified VideoFile model.
27
20
  video_file = models.ForeignKey(
28
21
  "VideoFile",
29
22
  on_delete=models.CASCADE,
30
23
  related_name="video_segmentation_annotations",
31
- null=False,
32
- blank=False,
33
24
  )
34
25
 
35
- label = models.ForeignKey("VideoSegmentationLabel", on_delete=models.CASCADE)
36
- start_time = models.FloatField() # in seconds
37
- stop_time = models.FloatField() # in seconds
26
+ label = models.ForeignKey(
27
+ "VideoSegmentationLabel",
28
+ on_delete=models.CASCADE,
29
+ )
30
+
31
+ # times in seconds
32
+ start_time = models.FloatField()
33
+ stop_time = models.FloatField()
34
+
38
35
  is_true = models.BooleanField(default=True)
39
36
 
40
37
  if TYPE_CHECKING:
@@ -42,28 +39,23 @@ class VideoSegmentationAnnotation(models.Model):
42
39
  label: models.ForeignKey["VideoSegmentationLabel"]
43
40
 
44
41
  def __str__(self) -> str:
45
- """
46
- String representation of the annotation.
47
- """
48
- video_repr = self.get_video() # Get the actual video object for representation
49
- return f"{video_repr} - {self.label.name} - {self.start_time} to {self.stop_time}"
42
+ return f"{self.video_file.pk} - {self.label.name} - {self.start_time} to {self.stop_time}"
50
43
 
51
44
  def get_video(self) -> "VideoFile":
52
45
  """
53
- Get the video file associated with this annotation.
54
-
55
- Returns the `VideoFile` instance.
46
+ Convenience accessor for the associated VideoFile instance.
56
47
  """
57
- if self.video_file:
58
- return self.video_file
59
- else:
60
- # This state should ideally not be reachable due to null=False, blank=False
48
+ if self.video_file.pk is None:
49
+ # Should not happen due to null=False
61
50
  raise ValueError("Annotation is not linked to a VideoFile.")
51
+ return self.video_file
62
52
 
63
53
  class Meta:
64
54
  constraints = [
65
55
  CheckConstraint(
66
- check=Q(start_time__lt=F("stop_time")),
56
+ condition=Q(start_time__lt=F("stop_time")),
67
57
  name="start_time_less_than_stop_time",
68
58
  ),
69
59
  ]
60
+ # optional but usually helpful:
61
+ # ordering = ("video_file_id", "start_time")
@@ -74,7 +74,7 @@ class LabelVideoSegment(models.Model):
74
74
 
75
75
  class Meta:
76
76
  constraints = [
77
- CheckConstraint(check=Q(start_frame_number__lt=F("end_frame_number")), name="segment_start_lt_end"),
77
+ CheckConstraint(condition=Q(start_frame_number__lt=F("end_frame_number")), name="segment_start_lt_end"),
78
78
  ]
79
79
  indexes = [
80
80
  models.Index(fields=["video_file", "label", "start_frame_number"]),
@@ -131,6 +131,28 @@ class LabelVideoSegment(models.Model):
131
131
  # Should not happen if self.state exists and has the is_validated attribute.
132
132
  logger.error("AttributeError accessing 'state.is_validated' for LabelVideoSegment %s.", self.pk)
133
133
  return False
134
+
135
+ def mark_validated(
136
+ self,
137
+ is_validated: bool = True,
138
+ information_source_name: str = "frontend",
139
+ ) -> None:
140
+ """
141
+ Domain helper: update validation state (and optionally information source).
142
+ """
143
+ from endoreg_db.models import InformationSource # avoid import cycle
144
+
145
+ # ensure state exists
146
+ state, _ = self.get_or_create_state()
147
+ state.is_validated = is_validated
148
+ state.save()
149
+
150
+ # update information source
151
+ info_source, _ = InformationSource.objects.get_or_create(
152
+ name=information_source_name
153
+ )
154
+ self.source = info_source
155
+ self.save(update_fields=["source"])
134
156
 
135
157
  def extract_segment_frame_files(self, overwrite: bool = False, **kwargs) -> bool:
136
158
  """