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.
- endoreg_db/data/__init__.py +22 -8
- endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +0 -1
- endoreg_db/data/examination/examinations/data.yaml +114 -14
- endoreg_db/data/examination/time-type/data.yaml +0 -3
- endoreg_db/data/examination_indication/endoscopy.yaml +108 -173
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +0 -70
- endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +33 -37
- endoreg_db/data/finding/00_generic.yaml +35 -0
- endoreg_db/data/finding/00_generic_complication.yaml +9 -0
- endoreg_db/data/finding/01_gastroscopy_baseline.yaml +88 -0
- endoreg_db/data/finding/01_gastroscopy_observation.yaml +113 -0
- endoreg_db/data/finding/02_colonoscopy_baseline.yaml +53 -0
- endoreg_db/data/finding/02_colonoscopy_hidden.yaml +119 -0
- endoreg_db/data/finding/02_colonoscopy_observation.yaml +152 -0
- endoreg_db/data/finding_classification/00_generic.yaml +44 -0
- endoreg_db/data/finding_classification/00_generic_histology.yaml +28 -0
- endoreg_db/data/finding_classification/00_generic_lesion.yaml +52 -0
- endoreg_db/data/finding_classification/{colonoscopy_bowel_preparation.yaml → 02_colonoscopy_baseline.yaml} +35 -20
- endoreg_db/data/finding_classification/02_colonoscopy_histology.yaml +13 -0
- endoreg_db/data/finding_classification/02_colonoscopy_other.yaml +12 -0
- endoreg_db/data/finding_classification/02_colonoscopy_polyp.yaml +101 -0
- endoreg_db/data/finding_classification_choice/{yes_no_na.yaml → 00_generic.yaml} +5 -1
- endoreg_db/data/finding_classification_choice/{examination_setting_generic_types.yaml → 00_generic_baseline.yaml} +10 -2
- endoreg_db/data/finding_classification_choice/{complication_generic_types.yaml → 00_generic_complication.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{histology.yaml → 00_generic_histology.yaml} +1 -4
- endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
- endoreg_db/data/finding_classification_choice/{bowel_preparation.yaml → 02_colonoscopy_bowel_preparation.yaml} +1 -30
- endoreg_db/data/{_examples/finding_classification_choice/colonoscopy_not_complete_reason.yaml → finding_classification_choice/02_colonoscopy_generic.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{histology_polyp.yaml → 02_colonoscopy_histology.yaml} +1 -1
- endoreg_db/data/{_examples/finding_classification_choice/colonoscopy_location.yaml → finding_classification_choice/02_colonoscopy_location.yaml} +23 -4
- endoreg_db/data/finding_classification_choice/02_colonoscopy_other.yaml +34 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_polyp_advanced_imaging.yaml +76 -0
- endoreg_db/data/{_examples/finding_classification_choice/colon_lesion_paris.yaml → finding_classification_choice/02_colonoscopy_polyp_morphology.yaml} +26 -8
- endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
- endoreg_db/data/finding_classification_type/{colonoscopy_basic.yaml → 00_generic.yaml} +18 -13
- endoreg_db/data/finding_classification_type/02_colonoscopy.yaml +9 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy.yaml +59 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_ablation.yaml +44 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_bleeding.yaml +55 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_resection.yaml +85 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_stenosis.yaml +17 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_stent.yaml +9 -0
- endoreg_db/data/finding_intervention/01_gastroscopy.yaml +19 -0
- endoreg_db/data/finding_intervention/04_eus.yaml +39 -0
- endoreg_db/data/finding_intervention/05_ercp.yaml +3 -0
- endoreg_db/data/finding_type/data.yaml +8 -12
- endoreg_db/data/requirement/01_patient_data.yaml +93 -0
- endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +0 -2
- endoreg_db/data/requirement_set/90_coloreg.yaml +20 -8
- endoreg_db/exceptions.py +0 -1
- endoreg_db/forms/examination_form.py +1 -1
- endoreg_db/helpers/data_loader.py +124 -52
- endoreg_db/helpers/default_objects.py +116 -81
- endoreg_db/import_files/__init__.py +27 -0
- endoreg_db/import_files/context/__init__.py +7 -0
- endoreg_db/import_files/context/default_sensitive_meta.py +81 -0
- endoreg_db/import_files/context/ensure_center.py +17 -0
- endoreg_db/import_files/context/file_lock.py +66 -0
- endoreg_db/import_files/context/import_context.py +43 -0
- endoreg_db/import_files/context/validate_directories.py +56 -0
- endoreg_db/import_files/file_storage/__init__.py +15 -0
- endoreg_db/import_files/file_storage/create_report_file.py +76 -0
- endoreg_db/import_files/file_storage/create_video_file.py +75 -0
- endoreg_db/import_files/file_storage/sensitive_meta_storage.py +39 -0
- endoreg_db/import_files/file_storage/state_management.py +400 -0
- endoreg_db/import_files/file_storage/storage.py +36 -0
- endoreg_db/import_files/import_service.md +26 -0
- endoreg_db/import_files/processing/__init__.py +11 -0
- endoreg_db/import_files/processing/report_processing/report_anonymization.py +94 -0
- endoreg_db/import_files/processing/sensitive_meta_adapter.py +51 -0
- endoreg_db/import_files/processing/video_processing/video_anonymization.py +107 -0
- endoreg_db/import_files/processing/video_processing/video_cleanup_on_error.py +119 -0
- endoreg_db/import_files/pseudonymization/fake.py +52 -0
- endoreg_db/import_files/pseudonymization/k_anonymity.py +182 -0
- endoreg_db/import_files/pseudonymization/k_pseudonymity.py +128 -0
- endoreg_db/import_files/report_import_service.py +141 -0
- endoreg_db/import_files/video_import_service.py +150 -0
- endoreg_db/management/commands/import_report.py +130 -65
- endoreg_db/management/commands/import_video_with_classification.py +1 -1
- endoreg_db/management/commands/load_ai_model_data.py +5 -5
- endoreg_db/management/commands/load_ai_model_label_data.py +9 -7
- endoreg_db/management/commands/load_base_db_data.py +5 -134
- endoreg_db/management/commands/load_contraindication_data.py +14 -16
- endoreg_db/management/commands/load_disease_classification_choices_data.py +15 -18
- endoreg_db/management/commands/load_disease_classification_data.py +15 -18
- endoreg_db/management/commands/load_disease_data.py +25 -28
- endoreg_db/management/commands/load_endoscope_data.py +20 -27
- endoreg_db/management/commands/load_event_data.py +14 -16
- endoreg_db/management/commands/load_examination_data.py +31 -44
- endoreg_db/management/commands/load_examination_indication_data.py +20 -21
- endoreg_db/management/commands/load_finding_data.py +52 -80
- endoreg_db/management/commands/load_information_source.py +21 -23
- endoreg_db/management/commands/load_lab_value_data.py +17 -26
- endoreg_db/management/commands/load_medication_data.py +13 -12
- endoreg_db/management/commands/load_organ_data.py +15 -19
- endoreg_db/management/commands/load_pdf_type_data.py +19 -18
- endoreg_db/management/commands/load_profession_data.py +14 -17
- endoreg_db/management/commands/load_qualification_data.py +20 -23
- endoreg_db/management/commands/load_report_reader_flag_data.py +17 -19
- endoreg_db/management/commands/load_requirement_data.py +14 -20
- endoreg_db/management/commands/load_risk_data.py +7 -6
- endoreg_db/management/commands/load_shift_data.py +20 -23
- endoreg_db/management/commands/load_tag_data.py +8 -11
- endoreg_db/management/commands/load_unit_data.py +17 -19
- endoreg_db/management/commands/start_filewatcher.py +46 -37
- endoreg_db/management/commands/validate_video_files.py +1 -5
- endoreg_db/migrations/0001_initial.py +1360 -1812
- endoreg_db/models/administration/person/patient/patient.py +72 -46
- endoreg_db/models/label/__init__.py +2 -2
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +18 -26
- endoreg_db/models/label/label_video_segment/label_video_segment.py +23 -1
- endoreg_db/models/media/pdf/raw_pdf.py +136 -64
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +34 -10
- endoreg_db/models/media/processing_history/__init__.py +5 -0
- endoreg_db/models/media/processing_history/processing_history.py +96 -0
- endoreg_db/models/media/video/create_from_file.py +101 -31
- endoreg_db/models/media/video/video_file.py +125 -105
- endoreg_db/models/media/video/video_file_io.py +31 -26
- endoreg_db/models/medical/contraindication/README.md +1 -0
- endoreg_db/models/medical/examination/examination.py +28 -8
- endoreg_db/models/medical/examination/examination_indication.py +13 -79
- endoreg_db/models/medical/examination/examination_time.py +8 -3
- endoreg_db/models/medical/finding/finding.py +5 -12
- endoreg_db/models/medical/finding/finding_classification.py +18 -37
- endoreg_db/models/medical/finding/finding_intervention.py +7 -9
- endoreg_db/models/medical/hardware/endoscope.py +6 -0
- endoreg_db/models/medical/patient/medication_examples.py +5 -1
- endoreg_db/models/medical/patient/patient_finding.py +1 -1
- endoreg_db/models/metadata/pdf_meta.py +22 -10
- endoreg_db/models/metadata/sensitive_meta.py +3 -0
- endoreg_db/models/metadata/sensitive_meta_logic.py +200 -124
- endoreg_db/models/other/information_source.py +27 -6
- endoreg_db/models/report/__init__.py +0 -0
- endoreg_db/models/report/images.py +0 -0
- endoreg_db/models/report/report.py +6 -0
- endoreg_db/models/requirement/requirement.py +59 -399
- endoreg_db/models/requirement/requirement_operator.py +86 -98
- endoreg_db/models/state/audit_ledger.py +4 -5
- endoreg_db/models/state/raw_pdf.py +69 -30
- endoreg_db/models/state/video.py +64 -49
- endoreg_db/models/upload_job.py +33 -9
- endoreg_db/models/utils.py +27 -23
- endoreg_db/queries/__init__.py +3 -1
- endoreg_db/schemas/examination_evaluation.py +1 -1
- endoreg_db/serializers/__init__.py +2 -8
- endoreg_db/serializers/label_video_segment/label_video_segment.py +2 -29
- endoreg_db/serializers/meta/__init__.py +1 -6
- endoreg_db/serializers/misc/sensitive_patient_data.py +50 -26
- endoreg_db/serializers/patient_examination/patient_examination.py +3 -3
- endoreg_db/serializers/pdf/anony_text_validation.py +39 -23
- endoreg_db/serializers/video/video_file_list.py +65 -34
- endoreg_db/services/__old/pdf_import.py +1487 -0
- endoreg_db/services/__old/video_import.py +1306 -0
- endoreg_db/services/anonymization.py +63 -26
- endoreg_db/services/lookup_service.py +28 -28
- endoreg_db/services/lookup_store.py +2 -2
- endoreg_db/services/pdf_import.py +0 -1480
- endoreg_db/services/report_import.py +10 -0
- endoreg_db/services/video_import.py +6 -1165
- endoreg_db/tasks/upload_tasks.py +79 -70
- endoreg_db/tasks/video_ingest.py +8 -4
- endoreg_db/urls/__init__.py +0 -14
- endoreg_db/urls/ai.py +32 -0
- endoreg_db/urls/media.py +21 -24
- endoreg_db/utils/dataloader.py +87 -57
- endoreg_db/utils/paths.py +110 -46
- endoreg_db/utils/pipelines/Readme.md +1 -1
- endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +97 -0
- endoreg_db/views/__init__.py +85 -173
- endoreg_db/views/ai/__init__.py +8 -0
- endoreg_db/views/ai/label.py +155 -0
- endoreg_db/views/anonymization/media_management.py +8 -7
- endoreg_db/views/anonymization/overview.py +97 -68
- endoreg_db/views/anonymization/validate.py +25 -21
- endoreg_db/views/media/__init__.py +5 -20
- endoreg_db/views/media/pdf_media.py +109 -65
- endoreg_db/views/media/sensitive_metadata.py +163 -148
- endoreg_db/views/meta/__init__.py +0 -8
- endoreg_db/views/misc/__init__.py +1 -7
- endoreg_db/views/misc/upload_views.py +94 -93
- endoreg_db/views/report/__init__.py +7 -0
- endoreg_db/views/{pdf → report}/reimport.py +45 -24
- endoreg_db/views/{pdf/pdf_stream.py → report/report_stream.py} +40 -32
- endoreg_db/views/requirement/lookup_store.py +22 -90
- endoreg_db/views/video/__init__.py +23 -22
- endoreg_db/views/video/correction.py +201 -172
- endoreg_db/views/video/reimport.py +1 -1
- endoreg_db/views/{media/video_segments.py → video/segments_crud.py} +75 -37
- endoreg_db/views/video/{video_meta.py → video_meta_stats.py} +2 -2
- endoreg_db/views/video/video_stream.py +7 -8
- {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/METADATA +2 -2
- {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/RECORD +217 -335
- {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/WHEEL +1 -1
- endoreg_db/data/_examples/disease.yaml +0 -55
- endoreg_db/data/_examples/disease_classification.yaml +0 -13
- endoreg_db/data/_examples/disease_classification_choice.yaml +0 -62
- endoreg_db/data/_examples/event.yaml +0 -64
- endoreg_db/data/_examples/examination.yaml +0 -72
- endoreg_db/data/_examples/finding/anatomy_colon.yaml +0 -128
- endoreg_db/data/_examples/finding/colonoscopy.yaml +0 -40
- endoreg_db/data/_examples/finding/colonoscopy_bowel_prep.yaml +0 -56
- endoreg_db/data/_examples/finding/complication.yaml +0 -16
- endoreg_db/data/_examples/finding/data.yaml +0 -105
- endoreg_db/data/_examples/finding/examination_setting.yaml +0 -16
- endoreg_db/data/_examples/finding/medication_related.yaml +0 -18
- endoreg_db/data/_examples/finding/outcome.yaml +0 -12
- endoreg_db/data/_examples/finding_classification/colonoscopy_bowel_preparation.yaml +0 -68
- endoreg_db/data/_examples/finding_classification/colonoscopy_jnet.yaml +0 -22
- endoreg_db/data/_examples/finding_classification/colonoscopy_kudo.yaml +0 -25
- endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
- endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
- endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_size.yaml +0 -68
- endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
- endoreg_db/data/_examples/finding_classification/colonoscopy_location.yaml +0 -80
- endoreg_db/data/_examples/finding_classification/colonoscopy_lst.yaml +0 -21
- endoreg_db/data/_examples/finding_classification/colonoscopy_nice.yaml +0 -20
- endoreg_db/data/_examples/finding_classification/colonoscopy_paris.yaml +0 -26
- endoreg_db/data/_examples/finding_classification/colonoscopy_sano.yaml +0 -22
- endoreg_db/data/_examples/finding_classification/colonoscopy_summary.yaml +0 -53
- endoreg_db/data/_examples/finding_classification/complication_generic.yaml +0 -25
- endoreg_db/data/_examples/finding_classification/examination_setting_generic.yaml +0 -40
- endoreg_db/data/_examples/finding_classification/histology_colo.yaml +0 -51
- endoreg_db/data/_examples/finding_classification/intervention_required.yaml +0 -26
- endoreg_db/data/_examples/finding_classification/medication_related.yaml +0 -23
- endoreg_db/data/_examples/finding_classification/visualized.yaml +0 -33
- endoreg_db/data/_examples/finding_classification_choice/bowel_preparation.yaml +0 -78
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_lst.yaml +0 -15
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_nice.yaml +0 -17
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_sano.yaml +0 -14
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
- endoreg_db/data/_examples/finding_classification_choice/colonoscopy_size.yaml +0 -82
- endoreg_db/data/_examples/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
- endoreg_db/data/_examples/finding_classification_choice/complication_generic_types.yaml +0 -15
- endoreg_db/data/_examples/finding_classification_choice/examination_setting_generic_types.yaml +0 -15
- endoreg_db/data/_examples/finding_classification_choice/histology.yaml +0 -24
- endoreg_db/data/_examples/finding_classification_choice/histology_polyp.yaml +0 -20
- endoreg_db/data/_examples/finding_classification_choice/outcome.yaml +0 -19
- endoreg_db/data/_examples/finding_classification_choice/yes_no_na.yaml +0 -11
- endoreg_db/data/_examples/finding_classification_type/colonoscopy_basic.yaml +0 -48
- endoreg_db/data/_examples/finding_intervention/endoscopy.yaml +0 -43
- endoreg_db/data/_examples/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
- endoreg_db/data/_examples/finding_intervention/endoscopy_egd.yaml +0 -128
- endoreg_db/data/_examples/finding_intervention/endoscopy_ercp.yaml +0 -32
- endoreg_db/data/_examples/finding_intervention/endoscopy_eus_lower.yaml +0 -9
- endoreg_db/data/_examples/finding_intervention/endoscopy_eus_upper.yaml +0 -36
- endoreg_db/data/_examples/finding_intervention_type/endoscopy.yaml +0 -15
- endoreg_db/data/_examples/finding_type/data.yaml +0 -43
- endoreg_db/data/_examples/requirement/age.yaml +0 -26
- endoreg_db/data/_examples/requirement/gender.yaml +0 -25
- endoreg_db/data/_examples/requirement_set/01_endoscopy_generic.yaml +0 -48
- endoreg_db/data/_examples/requirement_set/colonoscopy_austria_screening.yaml +0 -57
- endoreg_db/data/_examples/requirement_set/endoscopy_bleeding_risk.yaml +0 -52
- endoreg_db/data/_examples/yaml_examples.xlsx +0 -0
- endoreg_db/data/finding/anatomy_colon.yaml +0 -128
- endoreg_db/data/finding/colonoscopy.yaml +0 -40
- endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +0 -56
- endoreg_db/data/finding/complication.yaml +0 -16
- endoreg_db/data/finding/data.yaml +0 -105
- endoreg_db/data/finding/examination_setting.yaml +0 -16
- endoreg_db/data/finding/medication_related.yaml +0 -18
- endoreg_db/data/finding/outcome.yaml +0 -12
- endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +0 -22
- endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +0 -25
- endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
- endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +0 -38
- endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_location.yaml +0 -49
- endoreg_db/data/finding_classification/colonoscopy_lst.yaml +0 -21
- endoreg_db/data/finding_classification/colonoscopy_nice.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_paris.yaml +0 -26
- endoreg_db/data/finding_classification/colonoscopy_sano.yaml +0 -22
- endoreg_db/data/finding_classification/colonoscopy_summary.yaml +0 -53
- endoreg_db/data/finding_classification/complication_generic.yaml +0 -25
- endoreg_db/data/finding_classification/examination_setting_generic.yaml +0 -40
- endoreg_db/data/finding_classification/histology_colo.yaml +0 -43
- endoreg_db/data/finding_classification/intervention_required.yaml +0 -26
- endoreg_db/data/finding_classification/medication_related.yaml +0 -23
- endoreg_db/data/finding_classification/visualized.yaml +0 -33
- endoreg_db/data/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
- endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
- endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
- endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +0 -15
- endoreg_db/data/finding_classification_choice/colon_lesion_nice.yaml +0 -17
- endoreg_db/data/finding_classification_choice/colon_lesion_paris.yaml +0 -57
- endoreg_db/data/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
- endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +0 -14
- endoreg_db/data/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
- endoreg_db/data/finding_classification_choice/colonoscopy_location.yaml +0 -229
- endoreg_db/data/finding_classification_choice/colonoscopy_not_complete_reason.yaml +0 -19
- endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +0 -82
- endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
- endoreg_db/data/finding_classification_choice/outcome.yaml +0 -19
- endoreg_db/data/finding_intervention/endoscopy.yaml +0 -43
- endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
- endoreg_db/data/finding_intervention/endoscopy_egd.yaml +0 -128
- endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +0 -32
- endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +0 -9
- endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +0 -36
- endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +0 -79
- endoreg_db/data/requirement/age.yaml +0 -26
- endoreg_db/data/requirement/colonoscopy_baseline_austria.yaml +0 -45
- endoreg_db/data/requirement/disease_cardiovascular.yaml +0 -79
- endoreg_db/data/requirement/disease_classification_choice_cardiovascular.yaml +0 -41
- endoreg_db/data/requirement/disease_hepatology.yaml +0 -12
- endoreg_db/data/requirement/disease_misc.yaml +0 -12
- endoreg_db/data/requirement/disease_renal.yaml +0 -96
- endoreg_db/data/requirement/endoscopy_bleeding_risk.yaml +0 -59
- endoreg_db/data/requirement/event_cardiology.yaml +0 -251
- endoreg_db/data/requirement/event_requirements.yaml +0 -145
- endoreg_db/data/requirement/finding_colon_polyp.yaml +0 -50
- endoreg_db/data/requirement/gender.yaml +0 -25
- endoreg_db/data/requirement/lab_value.yaml +0 -441
- endoreg_db/data/requirement/medication.yaml +0 -93
- endoreg_db/data/requirement_operator/age.yaml +0 -13
- endoreg_db/data/requirement_operator/lab_operators.yaml +0 -129
- endoreg_db/data/requirement_operator/model_operators.yaml +0 -96
- endoreg_db/management/commands/init_default_ai_model.py +0 -112
- endoreg_db/management/commands/reset_celery_schedule.py +0 -9
- endoreg_db/management/commands/validate_video.py +0 -204
- endoreg_db/migrations/0002_requirementset_depends_on.py +0 -18
- endoreg_db/migrations/_old/0001_initial.py +0 -1857
- endoreg_db/migrations/_old/0002_add_video_correction_models.py +0 -52
- endoreg_db/migrations/_old/0003_add_center_display_name.py +0 -30
- endoreg_db/migrations/_old/0004_employee_city_employee_post_code_employee_street_and_more.py +0 -68
- endoreg_db/migrations/_old/0004_remove_casetemplate_rules_and_more.py +0 -77
- endoreg_db/migrations/_old/0005_merge_20251111_1003.py +0 -14
- endoreg_db/migrations/_old/0006_sensitivemeta_anonymized_text_and_more.py +0 -68
- endoreg_db/migrations/_old/0007_remove_rule_attribute_dtype_remove_rule_rule_type_and_more.py +0 -89
- endoreg_db/migrations/_old/0008_remove_event_event_classification_and_more.py +0 -27
- endoreg_db/migrations/_old/0009_alter_modelmeta_options_and_more.py +0 -21
- endoreg_db/renames.yml +0 -8
- endoreg_db/serializers/_old/raw_pdf_meta_validation.py +0 -223
- endoreg_db/serializers/_old/raw_video_meta_validation.py +0 -179
- endoreg_db/serializers/_old/video.py +0 -71
- endoreg_db/serializers/meta/pdf_file_meta_extraction.py +0 -115
- endoreg_db/serializers/meta/report_meta.py +0 -53
- endoreg_db/serializers/report/__init__.py +0 -9
- endoreg_db/serializers/report/mixins.py +0 -45
- endoreg_db/serializers/report/report.py +0 -105
- endoreg_db/serializers/report/report_list.py +0 -22
- endoreg_db/serializers/report/secure_file_url.py +0 -26
- endoreg_db/services/requirements_object.py +0 -147
- endoreg_db/services/storage_aware_video_processor.py +0 -370
- endoreg_db/urls/files.py +0 -6
- endoreg_db/urls/label_video_segment_validate.py +0 -33
- endoreg_db/urls/label_video_segments.py +0 -46
- endoreg_db/views/label/__init__.py +0 -5
- endoreg_db/views/label/label.py +0 -15
- endoreg_db/views/label_video_segment/__init__.py +0 -16
- endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +0 -44
- endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +0 -50
- endoreg_db/views/label_video_segment/label_video_segment.py +0 -77
- endoreg_db/views/label_video_segment/label_video_segment_by_label.py +0 -174
- endoreg_db/views/label_video_segment/label_video_segment_detail.py +0 -73
- endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +0 -46
- endoreg_db/views/label_video_segment/validate.py +0 -226
- endoreg_db/views/media/segments.py +0 -71
- endoreg_db/views/meta/available_files_list.py +0 -146
- endoreg_db/views/meta/report_meta.py +0 -53
- endoreg_db/views/meta/sensitive_meta_detail.py +0 -85
- endoreg_db/views/misc/secure_file_serving_view.py +0 -80
- endoreg_db/views/misc/secure_file_url_view.py +0 -84
- endoreg_db/views/misc/secure_url_validate.py +0 -79
- endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +0 -164
- endoreg_db/views/patient_finding_location/__init__.py +0 -5
- endoreg_db/views/patient_finding_location/pfl_create.py +0 -70
- endoreg_db/views/patient_finding_morphology/__init__.py +0 -5
- endoreg_db/views/patient_finding_morphology/pfm_create.py +0 -70
- endoreg_db/views/pdf/__init__.py +0 -8
- endoreg_db/views/video/segmentation.py +0 -274
- endoreg_db/views/video/task_status.py +0 -49
- endoreg_db/views/video/timeline.py +0 -46
- endoreg_db/views/video/video_analyze.py +0 -52
- /endoreg_db/data/requirement/{colon_polyp_intervention.yaml → old/colon_polyp_intervention.yaml} +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/colonoscopy_baseline_austria.yaml +0 -0
- /endoreg_db/data/requirement/{coloreg_colon_polyp.yaml → old/coloreg_colon_polyp.yaml} +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/disease_cardiovascular.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/disease_classification_choice_cardiovascular.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/disease_hepatology.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/disease_misc.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/disease_renal.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/endoscopy_bleeding_risk.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/event_cardiology.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/event_requirements.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/finding_colon_polyp.yaml +0 -0
- /endoreg_db/{migrations/__init__.py → data/requirement/old/gender.yaml} +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/lab_value.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/medication.yaml +0 -0
- /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/age.yaml +0 -0
- /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/lab_operators.yaml +0 -0
- /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/model_operators.yaml +0 -0
- /endoreg_db/{urls/sensitive_meta.py → import_files/pseudonymization/__init__.py} +0 -0
- /endoreg_db/{views/pdf/pdf_stream_views.py → import_files/pseudonymization/pseudonymize.py} +0 -0
- /endoreg_db/utils/requirement_operator_logic/{lab_value_operators.py → _old/lab_value_operators.py} +0 -0
- /endoreg_db/utils/requirement_operator_logic/{model_evaluators.py → _old/model_evaluators.py} +0 -0
- {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/licenses/LICENSE +0 -0
endoreg_db/models/upload_job.py
CHANGED
|
@@ -7,7 +7,7 @@ from django.db import models
|
|
|
7
7
|
class UploadJob(models.Model):
|
|
8
8
|
"""
|
|
9
9
|
Tracks file upload jobs and their processing status.
|
|
10
|
-
Supports both
|
|
10
|
+
Supports both report and video file uploads with asynchronous processing.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
class Status(models.TextChoices):
|
|
@@ -16,23 +16,47 @@ class UploadJob(models.Model):
|
|
|
16
16
|
ANONYMIZED = "anonymized", "Anonymized"
|
|
17
17
|
ERROR = "error", "Error"
|
|
18
18
|
|
|
19
|
-
id = models.UUIDField(
|
|
19
|
+
id = models.UUIDField(
|
|
20
|
+
primary_key=True,
|
|
21
|
+
default=uuid.uuid4,
|
|
22
|
+
editable=False,
|
|
23
|
+
help_text="Unique identifier for the upload job",
|
|
24
|
+
)
|
|
20
25
|
|
|
21
|
-
file = models.FileField(
|
|
26
|
+
file = models.FileField(
|
|
27
|
+
upload_to="uploads/%Y/%m/%d/", help_text="Uploaded file (report or video)"
|
|
28
|
+
)
|
|
22
29
|
|
|
23
|
-
status = models.CharField(
|
|
30
|
+
status = models.CharField(
|
|
31
|
+
max_length=20,
|
|
32
|
+
choices=Status.choices,
|
|
33
|
+
default=Status.PENDING,
|
|
34
|
+
help_text="Current processing status of the upload",
|
|
35
|
+
)
|
|
24
36
|
|
|
25
|
-
content_type = models.CharField(
|
|
37
|
+
content_type = models.CharField(
|
|
38
|
+
max_length=100, blank=True, help_text="MIME type of the uploaded file"
|
|
39
|
+
)
|
|
26
40
|
|
|
27
41
|
sensitive_meta = models.ForeignKey(
|
|
28
|
-
"SensitiveMeta",
|
|
42
|
+
"SensitiveMeta",
|
|
43
|
+
null=True,
|
|
44
|
+
blank=True,
|
|
45
|
+
on_delete=models.SET_NULL,
|
|
46
|
+
help_text="Link to the created SensitiveMeta record after processing",
|
|
29
47
|
)
|
|
30
48
|
|
|
31
|
-
error_detail = models.TextField(
|
|
49
|
+
error_detail = models.TextField(
|
|
50
|
+
blank=True, help_text="Error message if processing failed"
|
|
51
|
+
)
|
|
32
52
|
|
|
33
|
-
created_at = models.DateTimeField(
|
|
53
|
+
created_at = models.DateTimeField(
|
|
54
|
+
auto_now_add=True, help_text="When the upload job was created"
|
|
55
|
+
)
|
|
34
56
|
|
|
35
|
-
updated_at = models.DateTimeField(
|
|
57
|
+
updated_at = models.DateTimeField(
|
|
58
|
+
auto_now=True, help_text="When the upload job was last updated"
|
|
59
|
+
)
|
|
36
60
|
|
|
37
61
|
if TYPE_CHECKING:
|
|
38
62
|
from django.db.models.fields.files import FieldFile
|
endoreg_db/models/utils.py
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
from ..utils import (
|
|
2
|
-
data_paths,
|
|
3
|
-
DJANGO_NAME_SALT,
|
|
4
|
-
)
|
|
5
|
-
from django.core.files import File
|
|
6
|
-
from django.core.files.storage import FileSystemStorage
|
|
7
1
|
import io
|
|
8
2
|
import os
|
|
9
|
-
import numpy as np
|
|
10
|
-
import cv2
|
|
11
|
-
from typing import TYPE_CHECKING, List, Tuple
|
|
12
3
|
from pathlib import Path
|
|
4
|
+
from typing import TYPE_CHECKING, List, Tuple
|
|
5
|
+
|
|
6
|
+
import cv2
|
|
7
|
+
import numpy as np
|
|
8
|
+
from django.core.files import File
|
|
9
|
+
from django.core.files.storage import FileSystemStorage
|
|
10
|
+
|
|
11
|
+
from ..utils import DJANGO_NAME_SALT, data_paths
|
|
12
|
+
|
|
13
13
|
if TYPE_CHECKING:
|
|
14
14
|
pass
|
|
15
15
|
|
|
@@ -18,14 +18,12 @@ from logging import getLogger
|
|
|
18
18
|
logger = getLogger(__name__)
|
|
19
19
|
|
|
20
20
|
STORAGE_DIR = data_paths["storage"]
|
|
21
|
-
FILE_STORAGE = FileSystemStorage(location
|
|
22
|
-
|
|
23
|
-
TMP_VIDEO_DIR = VIDEO_DIR / "tmp"
|
|
24
|
-
ANONYM_VIDEO_DIR = data_paths["video_export"]
|
|
21
|
+
FILE_STORAGE = FileSystemStorage(location=str(STORAGE_DIR))
|
|
22
|
+
TRANSCODING_DIR = data_paths["transcoding"]
|
|
25
23
|
FRAME_DIR = data_paths["frame"]
|
|
26
24
|
WEIGHTS_DIR = data_paths["weights"]
|
|
27
|
-
|
|
28
|
-
DOCUMENT_DIR = data_paths["
|
|
25
|
+
REPORT_DIR = data_paths["import_report"]
|
|
26
|
+
DOCUMENT_DIR = data_paths["documents"] #TODO Verify if this is still used and assign correct dir
|
|
29
27
|
|
|
30
28
|
TEST_RUN = os.environ.get("TEST_RUN", "False")
|
|
31
29
|
TEST_RUN = TEST_RUN.lower() == "true"
|
|
@@ -70,8 +68,13 @@ def find_segments_in_prediction_array(prediction_array: np.array, min_frame_len:
|
|
|
70
68
|
|
|
71
69
|
return segments
|
|
72
70
|
|
|
71
|
+
|
|
73
72
|
def anonymize_frame(
|
|
74
|
-
raw_frame_path: Path,
|
|
73
|
+
raw_frame_path: Path,
|
|
74
|
+
target_frame_path: Path,
|
|
75
|
+
endo_roi,
|
|
76
|
+
all_black: bool = False,
|
|
77
|
+
censor_color: Tuple[int, int, int] = (0, 0, 0), # Added censor_color param
|
|
75
78
|
):
|
|
76
79
|
"""
|
|
77
80
|
Anonymize the frame by blacking out pixels outside the endoscope ROI or making the whole frame black.
|
|
@@ -88,7 +91,9 @@ def anonymize_frame(
|
|
|
88
91
|
# Validate ROI dictionary keys
|
|
89
92
|
required_keys = {"x", "y", "width", "height"}
|
|
90
93
|
if not required_keys.issubset(endo_roi):
|
|
91
|
-
raise ValueError(
|
|
94
|
+
raise ValueError(
|
|
95
|
+
f"Invalid endo_roi dictionary provided: {endo_roi}. Missing keys."
|
|
96
|
+
)
|
|
92
97
|
|
|
93
98
|
x = endo_roi["x"]
|
|
94
99
|
y = endo_roi["y"]
|
|
@@ -101,7 +106,9 @@ def anonymize_frame(
|
|
|
101
106
|
x2, y2 = min(w_orig, x + width), min(h_orig, y + height)
|
|
102
107
|
|
|
103
108
|
if x1 >= x2 or y1 >= y2:
|
|
104
|
-
logger.warning(
|
|
109
|
+
logger.warning(
|
|
110
|
+
f"ROI [{x},{y},{width},{height}] is outside or invalid for frame dimensions {w_orig}x{h_orig}. Resulting frame might be all black."
|
|
111
|
+
)
|
|
105
112
|
else:
|
|
106
113
|
# copy valid endoscope roi part to black frame
|
|
107
114
|
new_frame[y1:y2, x1:x2] = frame[y1:y2, x1:x2]
|
|
@@ -119,16 +126,13 @@ __all__ = [
|
|
|
119
126
|
"DJANGO_NAME_SALT",
|
|
120
127
|
"data_paths",
|
|
121
128
|
"FILE_STORAGE",
|
|
122
|
-
"VIDEO_DIR",
|
|
123
|
-
"TMP_VIDEO_DIR",
|
|
124
129
|
"ANONYM_VIDEO_DIR",
|
|
125
130
|
"FRAME_DIR",
|
|
126
131
|
"WEIGHTS_DIR",
|
|
127
|
-
"
|
|
128
|
-
"DOCUMENT_DIR",
|
|
132
|
+
"REPORT_DIR",
|
|
129
133
|
"prepare_bulk_frames",
|
|
130
134
|
"anonymize_frame",
|
|
131
135
|
"find_segments_in_prediction_array",
|
|
132
136
|
"TEST_RUN",
|
|
133
137
|
"TEST_RUN_FRAME_NUMBER",
|
|
134
|
-
]
|
|
138
|
+
]
|
endoreg_db/queries/__init__.py
CHANGED
|
@@ -19,7 +19,7 @@ class RequirementSetEval(BaseModel):
|
|
|
19
19
|
linked_sets: List["RequirementSetEval"] = Field(default_factory=list)
|
|
20
20
|
|
|
21
21
|
class ExaminationEvalReport(BaseModel):
|
|
22
|
-
examination_id: int
|
|
22
|
+
examination_id: int | None = None
|
|
23
23
|
summary: dict
|
|
24
24
|
sets: List[RequirementSetEval]
|
|
25
25
|
errors: List[str] = Field(default_factory=list)
|
|
@@ -12,8 +12,7 @@ from .examination import (
|
|
|
12
12
|
)
|
|
13
13
|
from .finding import FindingSerializer
|
|
14
14
|
from .finding_classification import (
|
|
15
|
-
FindingClassificationChoiceSerializer,
|
|
16
|
-
FindingClassificationSerializer,
|
|
15
|
+
FindingClassificationSerializer, # FindingClassificationChoiceSerializer,
|
|
17
16
|
)
|
|
18
17
|
from .label import ImageClassificationAnnotationSerializer, LabelSerializer
|
|
19
18
|
from .label_video_segment import (
|
|
@@ -21,8 +20,6 @@ from .label_video_segment import (
|
|
|
21
20
|
LabelVideoSegmentSerializer,
|
|
22
21
|
)
|
|
23
22
|
from .meta import (
|
|
24
|
-
PDFFileForMetaSerializer,
|
|
25
|
-
ReportMetaSerializer,
|
|
26
23
|
SensitiveMetaDetailSerializer,
|
|
27
24
|
SensitiveMetaUpdateSerializer,
|
|
28
25
|
SensitiveMetaVerificationSerializer,
|
|
@@ -47,7 +44,6 @@ from .patient_finding import (
|
|
|
47
44
|
PatientFindingWriteSerializer,
|
|
48
45
|
)
|
|
49
46
|
from .pdf import RawPdfAnonyTextSerializer
|
|
50
|
-
from .report import ReportDataSerializer, ReportListSerializer, SecureFileUrlSerializer
|
|
51
47
|
from .video.video_processing_history import VideoProcessingHistorySerializer
|
|
52
48
|
from .video_examination import (
|
|
53
49
|
VideoExaminationCreateSerializer,
|
|
@@ -76,8 +72,6 @@ __all__ = [
|
|
|
76
72
|
"LabelVideoSegmentSerializer",
|
|
77
73
|
"LabelVideoSegmentAnnotationSerializer",
|
|
78
74
|
# Meta
|
|
79
|
-
"PDFFileForMetaSerializer",
|
|
80
|
-
"ReportMetaSerializer",
|
|
81
75
|
"SensitiveMetaDetailSerializer",
|
|
82
76
|
"SensitiveMetaUpdateSerializer",
|
|
83
77
|
"SensitiveMetaVerificationSerializer",
|
|
@@ -101,7 +95,7 @@ __all__ = [
|
|
|
101
95
|
"PatientFindingInterventionSerializer",
|
|
102
96
|
"PatientFindingListSerializer",
|
|
103
97
|
"PatientFindingWriteSerializer",
|
|
104
|
-
#
|
|
98
|
+
# report
|
|
105
99
|
"RawPdfAnonyTextSerializer",
|
|
106
100
|
# Report
|
|
107
101
|
"ReportListSerializer",
|
|
@@ -142,7 +142,7 @@ class LabelVideoSegmentSerializer(serializers.ModelSerializer):
|
|
|
142
142
|
logger.debug(f"Serializer initialized with data: {self.initial_data}")
|
|
143
143
|
|
|
144
144
|
|
|
145
|
-
def get_time_segments(self, obj: LabelVideoSegment) ->
|
|
145
|
+
def get_time_segments(self, obj: LabelVideoSegment) -> dict[str, dict]:
|
|
146
146
|
frames = obj.frames
|
|
147
147
|
time_segments = {
|
|
148
148
|
"segment_id": obj.id,
|
|
@@ -225,34 +225,7 @@ class LabelVideoSegmentSerializer(serializers.ModelSerializer):
|
|
|
225
225
|
"""
|
|
226
226
|
return ImageClassificationAnnotationSerializer(obj.all_frame_annotations, many=True).data
|
|
227
227
|
|
|
228
|
-
|
|
229
|
-
"""
|
|
230
|
-
Return the German translation of the label name for display purposes.
|
|
231
|
-
|
|
232
|
-
If the segment has no label, returns "Unbekannt". If a translation is not available, returns the original label name.
|
|
233
|
-
"""
|
|
234
|
-
if not obj.label:
|
|
235
|
-
return "Unbekannt"
|
|
236
|
-
|
|
237
|
-
label_name = obj.label.name
|
|
238
|
-
#TODO Refactor
|
|
239
|
-
translations = {
|
|
240
|
-
'appendix': 'Appendix',
|
|
241
|
-
'blood': 'Blut',
|
|
242
|
-
'diverticule': 'Divertikel',
|
|
243
|
-
'grasper': 'Greifer',
|
|
244
|
-
'ileocaecalvalve': 'Ileozäkalklappe',
|
|
245
|
-
'ileum': 'Ileum',
|
|
246
|
-
'low_quality': 'Niedrige Bildqualität',
|
|
247
|
-
'nbi': 'Narrow Band Imaging',
|
|
248
|
-
'needle': 'Nadel',
|
|
249
|
-
'outside': 'Außerhalb',
|
|
250
|
-
'polyp': 'Polyp',
|
|
251
|
-
'snare': 'Snare',
|
|
252
|
-
'water_jet': 'Wasserstrahl',
|
|
253
|
-
'wound': 'Wunde'
|
|
254
|
-
}
|
|
255
|
-
return translations.get(label_name, label_name)
|
|
228
|
+
|
|
256
229
|
|
|
257
230
|
def get_video_name(self, obj):
|
|
258
231
|
"""
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
from .report_meta import (
|
|
3
|
-
ReportMetaSerializer,
|
|
4
|
-
)
|
|
1
|
+
|
|
5
2
|
from .sensitive_meta_detail import SensitiveMetaDetailSerializer
|
|
6
3
|
from .sensitive_meta_update import SensitiveMetaUpdateSerializer
|
|
7
4
|
from .sensitive_meta_verification import SensitiveMetaVerificationSerializer
|
|
@@ -10,8 +7,6 @@ from .video_meta import (
|
|
|
10
7
|
)
|
|
11
8
|
|
|
12
9
|
__all__ = [
|
|
13
|
-
"PDFFileForMetaSerializer",
|
|
14
|
-
"ReportMetaSerializer",
|
|
15
10
|
"SensitiveMetaDetailSerializer",
|
|
16
11
|
"SensitiveMetaUpdateSerializer",
|
|
17
12
|
"SensitiveMetaVerificationSerializer",
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
from endoreg_db.models.media import RawPdfFile, VideoFile
|
|
2
|
-
|
|
3
|
-
|
|
4
1
|
from rest_framework import serializers
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
from endoreg_db.models.media import RawPdfFile, VideoFile
|
|
4
|
+
|
|
5
|
+
# TODO add this "naming convention" to the documentation
|
|
7
6
|
# VoP: Video or Pdf
|
|
8
7
|
|
|
8
|
+
|
|
9
9
|
class VoPPatientDataSerializer(serializers.Serializer):
|
|
10
10
|
"""
|
|
11
|
-
Serializer that converts a VideoFile or RawPdfFile to the structure
|
|
11
|
+
Serializer that converts a VideoFile or RawPdfFile to the structure
|
|
12
12
|
the Pinia store needs for validation workflow.
|
|
13
13
|
"""
|
|
14
14
|
|
|
@@ -24,12 +24,12 @@ class VoPPatientDataSerializer(serializers.Serializer):
|
|
|
24
24
|
def to_representation(self, instance):
|
|
25
25
|
"""
|
|
26
26
|
Serialize a VideoFile or RawPdfFile instance into a structured dictionary for validation workflows.
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
Depending on the instance type, constructs a dictionary containing identifiers, sensitive metadata, text summaries, anonymized text, processing status, and error flag. For VideoFile instances, generates a text summary from associated sensitive metadata and anonymizes personal identifiers. For RawPdfFile instances, uses the instance's text fields directly. Raises a TypeError if the instance is neither type.
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
Parameters:
|
|
31
31
|
instance: A VideoFile or RawPdfFile model instance to serialize.
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
Returns:
|
|
34
34
|
dict: A structured representation of the instance suitable for Pinia store consumption.
|
|
35
35
|
"""
|
|
@@ -62,44 +62,62 @@ class VoPPatientDataSerializer(serializers.Serializer):
|
|
|
62
62
|
# Create anonymized version
|
|
63
63
|
anonym_text = text
|
|
64
64
|
if sm.patient_first_name:
|
|
65
|
-
anonym_text = anonym_text.replace(
|
|
65
|
+
anonym_text = anonym_text.replace(
|
|
66
|
+
sm.patient_first_name, "[FIRST_NAME]"
|
|
67
|
+
)
|
|
66
68
|
if sm.patient_last_name:
|
|
67
|
-
anonym_text = anonym_text.replace(
|
|
69
|
+
anonym_text = anonym_text.replace(
|
|
70
|
+
sm.patient_last_name, "[LAST_NAME]"
|
|
71
|
+
)
|
|
68
72
|
if sm.patient_dob:
|
|
69
|
-
anonym_text = anonym_text.replace(
|
|
73
|
+
anonym_text = anonym_text.replace(
|
|
74
|
+
str(sm.patient_dob.date()), "[DOB]"
|
|
75
|
+
)
|
|
70
76
|
|
|
71
77
|
return {
|
|
72
78
|
"id": instance.pk,
|
|
73
|
-
"sensitiveMetaId": instance.sensitive_meta.pk
|
|
79
|
+
"sensitiveMetaId": instance.sensitive_meta.pk
|
|
80
|
+
if instance.sensitive_meta
|
|
81
|
+
else None,
|
|
74
82
|
"text": text,
|
|
75
83
|
"anonymizedText": anonym_text,
|
|
76
|
-
"reportMeta": self._serialize_sensitive_meta(instance.sensitive_meta)
|
|
77
|
-
|
|
84
|
+
"reportMeta": self._serialize_sensitive_meta(instance.sensitive_meta)
|
|
85
|
+
if instance.sensitive_meta
|
|
86
|
+
else None,
|
|
87
|
+
"status": "processing"
|
|
88
|
+
if instance.state and instance.state.frames_extracted
|
|
89
|
+
else "not_started",
|
|
78
90
|
"error": False,
|
|
79
91
|
}
|
|
80
92
|
|
|
81
93
|
elif isinstance(instance, RawPdfFile):
|
|
82
|
-
# Generate
|
|
83
|
-
|
|
84
|
-
|
|
94
|
+
# Generate report streaming URL using pdf_id (RawPdfFile.id)
|
|
95
|
+
report_stream_url = f"/api/media/pdfs/{instance.pk}/stream/"
|
|
96
|
+
|
|
85
97
|
return {
|
|
86
98
|
"id": instance.pk,
|
|
87
|
-
"sensitiveMetaId": instance.sensitive_meta.pk
|
|
99
|
+
"sensitiveMetaId": instance.sensitive_meta.pk
|
|
100
|
+
if instance.sensitive_meta
|
|
101
|
+
else None,
|
|
88
102
|
"text": instance.text or "",
|
|
89
103
|
"anonymizedText": instance.anonymized_text or "",
|
|
90
|
-
"reportMeta": self._serialize_sensitive_meta(instance.sensitive_meta)
|
|
104
|
+
"reportMeta": self._serialize_sensitive_meta(instance.sensitive_meta)
|
|
105
|
+
if instance.sensitive_meta
|
|
106
|
+
else None,
|
|
91
107
|
"status": "done" if instance.anonymized_text else "not_started",
|
|
92
108
|
"error": False,
|
|
93
|
-
"pdfStreamUrl":
|
|
109
|
+
"pdfStreamUrl": report_stream_url,
|
|
94
110
|
}
|
|
95
111
|
|
|
96
112
|
else:
|
|
97
|
-
raise TypeError(
|
|
113
|
+
raise TypeError(
|
|
114
|
+
f"Unsupported instance for VoPPatientDataSerializer: {type(instance)}"
|
|
115
|
+
)
|
|
98
116
|
|
|
99
117
|
def _serialize_sensitive_meta(self, sensitive_meta):
|
|
100
118
|
"""
|
|
101
119
|
Serialize a SensitiveMeta object into a dictionary with patient and examination details.
|
|
102
|
-
|
|
120
|
+
|
|
103
121
|
Returns:
|
|
104
122
|
dict or None: A dictionary containing patient and examination metadata fields, or None if sensitive_meta is not provided.
|
|
105
123
|
"""
|
|
@@ -110,11 +128,17 @@ class VoPPatientDataSerializer(serializers.Serializer):
|
|
|
110
128
|
"id": sensitive_meta.pk,
|
|
111
129
|
"patientFirstName": sensitive_meta.patient_first_name or "",
|
|
112
130
|
"patientLastName": sensitive_meta.patient_last_name or "",
|
|
113
|
-
"patientDob": sensitive_meta.patient_dob.isoformat()
|
|
114
|
-
|
|
115
|
-
|
|
131
|
+
"patientDob": sensitive_meta.patient_dob.isoformat()
|
|
132
|
+
if sensitive_meta.patient_dob
|
|
133
|
+
else "",
|
|
134
|
+
"patientGender": str(sensitive_meta.patient_gender)
|
|
135
|
+
if sensitive_meta.patient_gender
|
|
136
|
+
else "",
|
|
137
|
+
"examinationDate": sensitive_meta.examination_date.isoformat()
|
|
138
|
+
if sensitive_meta.examination_date
|
|
139
|
+
else "",
|
|
116
140
|
"centerName": sensitive_meta.center.name if sensitive_meta.center else "",
|
|
117
141
|
"endoscopeType": sensitive_meta.endoscope_type or "",
|
|
118
142
|
"endoscopeSn": sensitive_meta.endoscope_sn or "",
|
|
119
143
|
"isVerified": getattr(sensitive_meta, "is_verified", False),
|
|
120
|
-
}
|
|
144
|
+
}
|
|
@@ -135,7 +135,7 @@ class PatientExaminationSerializer(serializers.ModelSerializer):
|
|
|
135
135
|
|
|
136
136
|
def get_findings(self, patient_examination_id):
|
|
137
137
|
"""Gibt die zugehörigen Befunde zurück"""
|
|
138
|
-
|
|
138
|
+
pe = PatientExamination()
|
|
139
|
+
obj = pe.get_or_create_patient_examination_by_id(patient_examination_id)
|
|
139
140
|
self.instance = obj
|
|
140
|
-
|
|
141
|
-
return self.instance.patient_findings.all() if self.instance else []
|
|
141
|
+
return self.instance.get_available_findings() if self.instance else []
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
from django.conf import settings
|
|
4
|
+
from rest_framework import serializers
|
|
5
|
+
|
|
4
6
|
from ...models import RawPdfFile
|
|
5
7
|
|
|
8
|
+
|
|
6
9
|
class RawPdfAnonyTextSerializer(serializers.ModelSerializer):
|
|
7
10
|
"""
|
|
8
|
-
Serializer to fetch
|
|
11
|
+
Serializer to fetch report metadata along with `anonymized_text` from `RawPdfFile`.
|
|
9
12
|
Ensures Vue.js can process JSON efficiently.
|
|
10
13
|
"""
|
|
11
14
|
|
|
@@ -15,36 +18,46 @@ class RawPdfAnonyTextSerializer(serializers.ModelSerializer):
|
|
|
15
18
|
|
|
16
19
|
class Meta:
|
|
17
20
|
model = RawPdfFile
|
|
18
|
-
fields = [
|
|
19
|
-
|
|
21
|
+
fields = [
|
|
22
|
+
"id",
|
|
23
|
+
"file",
|
|
24
|
+
"pdf_url",
|
|
25
|
+
"full_pdf_path",
|
|
26
|
+
"sensitive_meta_id",
|
|
27
|
+
"anonymized_text",
|
|
28
|
+
]
|
|
20
29
|
|
|
21
30
|
@staticmethod
|
|
22
31
|
def get_next_pdf(last_id=None):
|
|
23
32
|
"""
|
|
24
|
-
Retrieves the first available
|
|
25
|
-
Otherwise, fetches the next available
|
|
33
|
+
Retrieves the first available report if `last_id` is NOT provided.
|
|
34
|
+
Otherwise, fetches the next available report where `id > last_id`.
|
|
26
35
|
"""
|
|
27
36
|
query_filter = {} if last_id is None else {"id__gt": int(last_id)}
|
|
28
|
-
pdf_entry = RawPdfFile.objects.filter(**query_filter).order_by(
|
|
29
|
-
return pdf_entry
|
|
37
|
+
pdf_entry = RawPdfFile.objects.filter(**query_filter).order_by("id").first()
|
|
38
|
+
return pdf_entry
|
|
30
39
|
|
|
31
40
|
def get_pdf_url(self, obj):
|
|
32
41
|
"""
|
|
33
|
-
Returns the absolute URL for accessing the anonymized text
|
|
34
|
-
|
|
42
|
+
Returns the absolute URL for accessing the anonymized text report endpoint for the given object.
|
|
43
|
+
|
|
35
44
|
If the request context or file is missing, returns None.
|
|
36
45
|
"""
|
|
37
|
-
request = self.context.get(
|
|
38
|
-
return
|
|
46
|
+
request = self.context.get("request")
|
|
47
|
+
return (
|
|
48
|
+
request.build_absolute_uri(f"/pdf/anony_text/?id={obj.id}")
|
|
49
|
+
if request and obj.file
|
|
50
|
+
else None
|
|
51
|
+
)
|
|
39
52
|
|
|
40
53
|
def get_file(self, obj):
|
|
41
54
|
"""
|
|
42
|
-
Retrieves the relative file path of the
|
|
43
|
-
|
|
55
|
+
Retrieves the relative file path of the report from the model instance.
|
|
56
|
+
|
|
44
57
|
Returns:
|
|
45
58
|
The relative file path as a string, or None if no file is associated.
|
|
46
59
|
"""
|
|
47
|
-
return str(obj.file.name).strip() if obj.file else None
|
|
60
|
+
return str(obj.file.name).strip() if obj.file else None
|
|
48
61
|
|
|
49
62
|
def get_full_pdf_path(self, obj):
|
|
50
63
|
"""
|
|
@@ -54,32 +67,35 @@ class RawPdfAnonyTextSerializer(serializers.ModelSerializer):
|
|
|
54
67
|
return None
|
|
55
68
|
pdf_relative_path = str(obj.file.name)
|
|
56
69
|
full_path = Path(settings.MEDIA_ROOT) / pdf_relative_path
|
|
57
|
-
return str(full_path) if full_path.exists() else None
|
|
70
|
+
return str(full_path) if full_path.exists() else None
|
|
58
71
|
|
|
59
72
|
def validate_anonymized_text(self, value):
|
|
60
73
|
"""
|
|
61
74
|
Validates that the anonymized text is non-empty and does not exceed 5000 characters.
|
|
62
|
-
|
|
75
|
+
|
|
63
76
|
Raises:
|
|
64
77
|
serializers.ValidationError: If the text is empty or exceeds the length limit.
|
|
65
78
|
"""
|
|
66
79
|
if not value.strip():
|
|
67
80
|
raise serializers.ValidationError("Anonymized text cannot be empty.")
|
|
68
|
-
#FIXME move this to a settings variable @Hamzaukw @maxhild
|
|
81
|
+
# FIXME move this to a settings variable @Hamzaukw @maxhild
|
|
69
82
|
if len(value) > 5000: # Arbitrary limit to prevent excessively long text
|
|
70
|
-
raise serializers.ValidationError(
|
|
83
|
+
raise serializers.ValidationError(
|
|
84
|
+
"Anonymized text exceeds the maximum length of 5000 characters."
|
|
85
|
+
)
|
|
71
86
|
return value
|
|
72
87
|
|
|
73
88
|
def update(self, instance, validated_data):
|
|
74
89
|
"""
|
|
75
90
|
Update the `anonymized_text` field of a RawPdfFile instance with validated data.
|
|
76
|
-
|
|
91
|
+
|
|
77
92
|
Only the `anonymized_text` field is modified; all other fields remain unchanged.
|
|
78
|
-
|
|
93
|
+
|
|
79
94
|
Returns:
|
|
80
95
|
The updated RawPdfFile instance.
|
|
81
96
|
"""
|
|
82
|
-
instance.anonymized_text = validated_data.get(
|
|
97
|
+
instance.anonymized_text = validated_data.get(
|
|
98
|
+
"anonymized_text", instance.anonymized_text
|
|
99
|
+
)
|
|
83
100
|
instance.save()
|
|
84
101
|
return instance
|
|
85
|
-
|