endoreg-db 0.8.9.32__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/__init__.py +0 -0
- endoreg_db/_version.py +34 -0
- endoreg_db/admin.py +97 -0
- endoreg_db/api/serializers/finding_descriptions.py +0 -0
- endoreg_db/api/views/finding_descriptions.py +0 -0
- endoreg_db/api_urls.py +4 -0
- endoreg_db/apps.py +17 -0
- endoreg_db/assets/dummy_model.ckpt +1 -0
- endoreg_db/authz/auth.py +78 -0
- endoreg_db/authz/backends.py +168 -0
- endoreg_db/authz/management/commands/list_routes.py +20 -0
- endoreg_db/authz/middleware.py +84 -0
- endoreg_db/authz/permissions.py +138 -0
- endoreg_db/authz/policy.py +224 -0
- endoreg_db/authz/settings.py +64 -0
- endoreg_db/authz/views_auth.py +70 -0
- endoreg_db/codemods/readme.md +88 -0
- endoreg_db/codemods/rename_datetime_fields.py +99 -0
- endoreg_db/config/__init__.py +0 -0
- endoreg_db/config/env.py +106 -0
- endoreg_db/config/settings/__init__.py +6 -0
- endoreg_db/config/settings/base.py +148 -0
- endoreg_db/config/settings/case_gen.py +32 -0
- endoreg_db/config/settings/dev.py +108 -0
- endoreg_db/config/settings/keycloak.py +177 -0
- endoreg_db/config/settings/prod.py +66 -0
- endoreg_db/config/settings/test.py +72 -0
- endoreg_db/data/__init__.py +135 -0
- endoreg_db/data/ai_model/data.yaml +7 -0
- endoreg_db/data/ai_model_label/label/data.yaml +88 -0
- endoreg_db/data/ai_model_label/label/polyp_classification.yaml +52 -0
- endoreg_db/data/ai_model_label/label-set/data.yaml +40 -0
- endoreg_db/data/ai_model_label/label-set/polyp_classifications.yaml +25 -0
- endoreg_db/data/ai_model_label/label-type/data.yaml +7 -0
- endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +27 -0
- endoreg_db/data/ai_model_type/data.yaml +7 -0
- endoreg_db/data/ai_model_video_segmentation_label/base_segmentation.yaml +176 -0
- endoreg_db/data/ai_model_video_segmentation_labelset/data.yaml +20 -0
- endoreg_db/data/case_template/rule/00_patient_lab_sample_add_default_value.yaml +167 -0
- endoreg_db/data/case_template/rule/01_patient-set-age.yaml +8 -0
- endoreg_db/data/case_template/rule/01_patient-set-gender.yaml +9 -0
- endoreg_db/data/case_template/rule/11_create_patient_lab_sample.yaml +23 -0
- endoreg_db/data/case_template/rule/12_create-patient_medication-anticoagulation.yaml +19 -0
- endoreg_db/data/case_template/rule/13_create-patient_medication_schedule-anticoagulation.yaml +19 -0
- endoreg_db/data/case_template/rule/19_create_patient.yaml +17 -0
- endoreg_db/data/case_template/rule_type/base_types.yaml +35 -0
- endoreg_db/data/case_template/rule_value/.init +0 -0
- endoreg_db/data/case_template/rule_value_type/base_types.yaml +59 -0
- endoreg_db/data/case_template/template/base.yaml +8 -0
- endoreg_db/data/case_template/template_type/pre_endoscopy.yaml +3 -0
- endoreg_db/data/case_template/tmp/_rule_value +13 -0
- endoreg_db/data/case_template/tmp/rule/01_atrial_fibrillation.yaml +21 -0
- endoreg_db/data/case_template/tmp/rule/02_create_object.yaml +10 -0
- endoreg_db/data/case_template/tmp/template/atrial_fibrillation_low_risk.yaml +7 -0
- endoreg_db/data/center/data.yaml +99 -0
- endoreg_db/data/center_resource/green_endoscopy_dashboard_CenterResource.yaml +144 -0
- endoreg_db/data/center_shift/ukw.yaml +9 -0
- endoreg_db/data/center_waste/green_endoscopy_dashboard_CenterWaste.yaml +48 -0
- endoreg_db/data/contraindication/bleeding.yaml +11 -0
- endoreg_db/data/db_summary.csv +58 -0
- endoreg_db/data/db_summary.xlsx +0 -0
- endoreg_db/data/disease/cardiovascular.yaml +37 -0
- endoreg_db/data/disease/hepatology.yaml +5 -0
- endoreg_db/data/disease/misc.yaml +5 -0
- endoreg_db/data/disease/renal.yaml +5 -0
- endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +6 -0
- endoreg_db/data/disease_classification/coronary_vessel_disease.yaml +6 -0
- endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +41 -0
- endoreg_db/data/disease_classification_choice/coronary_vessel_disease.yaml +20 -0
- endoreg_db/data/distribution/date/patient.yaml +7 -0
- endoreg_db/data/distribution/multiple_categorical/.init +0 -0
- endoreg_db/data/distribution/numeric/data.yaml +14 -0
- endoreg_db/data/distribution/single_categorical/patient.yaml +7 -0
- endoreg_db/data/emission_factor/green_endoscopy_dashboard_EmissionFactor.yaml +132 -0
- endoreg_db/data/endoscope/data.yaml +93 -0
- endoreg_db/data/endoscope_type/data.yaml +11 -0
- endoreg_db/data/endoscopy_processor/data.yaml +50 -0
- endoreg_db/data/event/cardiology.yaml +15 -0
- endoreg_db/data/event/neurology.yaml +14 -0
- endoreg_db/data/event/surgery.yaml +13 -0
- endoreg_db/data/event/thrombembolism.yaml +20 -0
- endoreg_db/data/event_classification/data.yaml +4 -0
- endoreg_db/data/event_classification_choice/data.yaml +9 -0
- endoreg_db/data/examination/examinations/data.yaml +172 -0
- endoreg_db/data/examination/time/data.yaml +48 -0
- endoreg_db/data/examination/time-type/data.yaml +5 -0
- endoreg_db/data/examination/type/data.yaml +17 -0
- endoreg_db/data/examination_indication/endoscopy.yaml +359 -0
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +90 -0
- endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +97 -0
- endoreg_db/data/examination_requirement_set/colonoscopy.yaml +15 -0
- 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/02_colonoscopy_baseline.yaml +83 -0
- 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/00_generic.yaml +15 -0
- endoreg_db/data/finding_classification_choice/00_generic_baseline.yaml +23 -0
- endoreg_db/data/finding_classification_choice/00_generic_complication.yaml +15 -0
- endoreg_db/data/finding_classification_choice/00_generic_histology.yaml +21 -0
- endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_bowel_preparation.yaml +49 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_generic.yaml +19 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_histology.yaml +20 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_location.yaml +248 -0
- 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/finding_classification_choice/02_colonoscopy_polyp_morphology.yaml +75 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
- endoreg_db/data/finding_classification_type/00_generic.yaml +53 -0
- 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_intervention_type/endoscopy.yaml +15 -0
- endoreg_db/data/finding_type/data.yaml +39 -0
- endoreg_db/data/gender/data.yaml +42 -0
- endoreg_db/data/information_source/annotation.yaml +6 -0
- endoreg_db/data/information_source/data.yaml +30 -0
- endoreg_db/data/information_source/endoscopy_guidelines.yaml +7 -0
- endoreg_db/data/information_source/medication.yaml +6 -0
- endoreg_db/data/information_source/prediction.yaml +7 -0
- endoreg_db/data/information_source_type/data.yaml +8 -0
- endoreg_db/data/lab_value/cardiac_enzymes.yaml +37 -0
- endoreg_db/data/lab_value/coagulation.yaml +54 -0
- endoreg_db/data/lab_value/electrolytes.yaml +228 -0
- endoreg_db/data/lab_value/gastrointestinal_function.yaml +133 -0
- endoreg_db/data/lab_value/hematology.yaml +184 -0
- endoreg_db/data/lab_value/hormones.yaml +59 -0
- endoreg_db/data/lab_value/lipids.yaml +53 -0
- endoreg_db/data/lab_value/misc.yaml +76 -0
- endoreg_db/data/lab_value/renal_function.yaml +12 -0
- endoreg_db/data/log_type/data.yaml +57 -0
- endoreg_db/data/lx_client_tag/base.yaml +54 -0
- endoreg_db/data/lx_client_type/base.yaml +30 -0
- endoreg_db/data/lx_permission/base.yaml +24 -0
- endoreg_db/data/lx_permission/endoreg.yaml +52 -0
- endoreg_db/data/material/material.yaml +91 -0
- endoreg_db/data/medication/anticoagulation.yaml +65 -0
- endoreg_db/data/medication/tah.yaml +70 -0
- endoreg_db/data/medication_indication/anticoagulation.yaml +115 -0
- endoreg_db/data/medication_indication_type/data.yaml +11 -0
- endoreg_db/data/medication_indication_type/thrombembolism.yaml +41 -0
- endoreg_db/data/medication_intake_time/base.yaml +31 -0
- endoreg_db/data/medication_schedule/apixaban.yaml +95 -0
- endoreg_db/data/medication_schedule/ass.yaml +12 -0
- endoreg_db/data/medication_schedule/enoxaparin.yaml +26 -0
- endoreg_db/data/names_first/first_names.yaml +54 -0
- endoreg_db/data/names_last/last_names.yaml +51 -0
- endoreg_db/data/network_device/data.yaml +59 -0
- endoreg_db/data/network_device_type/data.yaml +12 -0
- endoreg_db/data/organ/data.yaml +29 -0
- endoreg_db/data/patient_lab_sample_type/generic.yaml +6 -0
- endoreg_db/data/pdf_type/data.yaml +46 -0
- endoreg_db/data/product/green_endoscopy_dashboard_Product.yaml +66 -0
- endoreg_db/data/product_group/green_endoscopy_dashboard_ProductGroup.yaml +33 -0
- endoreg_db/data/product_material/green_endoscopy_dashboard_ProductMaterial.yaml +308 -0
- endoreg_db/data/product_weight/green_endoscopy_dashboard_ProductWeight.yaml +88 -0
- endoreg_db/data/profession/data.yaml +70 -0
- endoreg_db/data/qualification/endoscopy.yaml +36 -0
- endoreg_db/data/qualification/m2.yaml +39 -0
- endoreg_db/data/qualification/outpatient_clinic.yaml +35 -0
- endoreg_db/data/qualification/sonography.yaml +36 -0
- endoreg_db/data/qualification_type/base.yaml +29 -0
- endoreg_db/data/reference_product/green_endoscopy_dashboard_ReferenceProduct.yaml +55 -0
- endoreg_db/data/report_reader_flag/rkh-histology-generic.yaml +10 -0
- endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +30 -0
- endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +24 -0
- endoreg_db/data/requirement/01_patient_data.yaml +93 -0
- endoreg_db/data/requirement/old/colon_polyp_intervention.yaml +49 -0
- endoreg_db/data/requirement/old/colonoscopy_baseline_austria.yaml +45 -0
- endoreg_db/data/requirement/old/coloreg_colon_polyp.yaml +49 -0
- endoreg_db/data/requirement/old/disease_cardiovascular.yaml +79 -0
- endoreg_db/data/requirement/old/disease_classification_choice_cardiovascular.yaml +41 -0
- endoreg_db/data/requirement/old/disease_hepatology.yaml +12 -0
- endoreg_db/data/requirement/old/disease_misc.yaml +12 -0
- endoreg_db/data/requirement/old/disease_renal.yaml +96 -0
- endoreg_db/data/requirement/old/endoscopy_bleeding_risk.yaml +59 -0
- endoreg_db/data/requirement/old/event_cardiology.yaml +251 -0
- endoreg_db/data/requirement/old/event_requirements.yaml +145 -0
- endoreg_db/data/requirement/old/finding_colon_polyp.yaml +50 -0
- endoreg_db/data/requirement/old/gender.yaml +0 -0
- endoreg_db/data/requirement/old/lab_value.yaml +441 -0
- endoreg_db/data/requirement/old/medication.yaml +93 -0
- endoreg_db/data/requirement_operator/_old/age.yaml +13 -0
- endoreg_db/data/requirement_operator/_old/lab_operators.yaml +129 -0
- endoreg_db/data/requirement_operator/_old/model_operators.yaml +96 -0
- endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +65 -0
- endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
- endoreg_db/data/requirement_set/02_endoscopy_bleeding_risk.yaml +46 -0
- endoreg_db/data/requirement_set/90_coloreg.yaml +190 -0
- endoreg_db/data/requirement_set/_old_ +109 -0
- endoreg_db/data/requirement_set/colonoscopy_austria_screening.yaml +57 -0
- endoreg_db/data/requirement_set_type/data.yaml +41 -0
- endoreg_db/data/requirement_type/requirement_types.yaml +165 -0
- endoreg_db/data/resource/green_endoscopy_dashboard_Resource.yaml +15 -0
- endoreg_db/data/risk/bleeding.yaml +26 -0
- endoreg_db/data/risk/thrombosis.yaml +37 -0
- endoreg_db/data/risk_type/data.yaml +27 -0
- endoreg_db/data/setup_config.yaml +38 -0
- endoreg_db/data/shift/endoscopy.yaml +21 -0
- endoreg_db/data/shift/m2.yaml +0 -0
- endoreg_db/data/shift_type/base.yaml +35 -0
- endoreg_db/data/tag/requirement_set_tags.yaml +32 -0
- endoreg_db/data/tmp/chronic_kidney_disease.yaml +0 -0
- endoreg_db/data/tmp/congestive_heart_failure.yaml +0 -0
- endoreg_db/data/transport_route/green_endoscopy_dashboard_TransportRoute.yaml +12 -0
- endoreg_db/data/unit/concentration.yaml +115 -0
- endoreg_db/data/unit/data.yaml +17 -0
- endoreg_db/data/unit/length.yaml +31 -0
- endoreg_db/data/unit/misc.yaml +20 -0
- endoreg_db/data/unit/rate.yaml +6 -0
- endoreg_db/data/unit/time.yaml +48 -0
- endoreg_db/data/unit/volume.yaml +35 -0
- endoreg_db/data/unit/weight.yaml +38 -0
- endoreg_db/data/waste/data.yaml +12 -0
- endoreg_db/exceptions.py +24 -0
- endoreg_db/export/frames/export.py +6 -0
- endoreg_db/export/frames/export_frames_with_labels.py +616 -0
- endoreg_db/factories/__init__.py +0 -0
- endoreg_db/forms/__init__.py +4 -0
- endoreg_db/forms/examination_form.py +12 -0
- endoreg_db/forms/patient_finding_intervention_form.py +40 -0
- endoreg_db/forms/patient_form.py +23 -0
- endoreg_db/forms/questionnaires/__init__.py +1 -0
- endoreg_db/forms/questionnaires/tto_questionnaire.py +23 -0
- endoreg_db/forms/settings/__init__.py +11 -0
- endoreg_db/forms/unit.py +7 -0
- endoreg_db/helpers/__init__.py +0 -0
- endoreg_db/helpers/count_db.py +48 -0
- endoreg_db/helpers/data_loader.py +280 -0
- endoreg_db/helpers/default_objects.py +414 -0
- endoreg_db/helpers/download_segmentation_model.py +32 -0
- endoreg_db/helpers/interact.py +1 -0
- endoreg_db/helpers/test_video_helper.py +127 -0
- 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 +83 -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 +42 -0
- endoreg_db/import_files/context/validate_directories.py +57 -0
- endoreg_db/import_files/file_storage/__init__.py +15 -0
- endoreg_db/import_files/file_storage/create_report_file.py +99 -0
- endoreg_db/import_files/file_storage/create_video_file.py +104 -0
- endoreg_db/import_files/file_storage/sensitive_meta_storage.py +42 -0
- endoreg_db/import_files/file_storage/state_management.py +463 -0
- endoreg_db/import_files/file_storage/storage.py +42 -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 +99 -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/pseudonymization/__init__.py +0 -0
- endoreg_db/import_files/pseudonymization/fake.py +52 -0
- endoreg_db/import_files/pseudonymization/k_anonymity.py +181 -0
- endoreg_db/import_files/pseudonymization/k_pseudonymity.py +139 -0
- endoreg_db/import_files/pseudonymization/pseudonymize.py +0 -0
- endoreg_db/import_files/report_import_service.py +147 -0
- endoreg_db/import_files/video_import_service.py +154 -0
- endoreg_db/logger_conf.py +156 -0
- endoreg_db/management/__init__.py +1 -0
- endoreg_db/management/commands/__init__.py +1 -0
- endoreg_db/management/commands/anonymize_video.py +0 -0
- endoreg_db/management/commands/check_auth.py +132 -0
- endoreg_db/management/commands/create_model_meta_from_huggingface.py +177 -0
- endoreg_db/management/commands/create_multilabel_model_meta.py +419 -0
- endoreg_db/management/commands/export_frame_annot.py +196 -0
- endoreg_db/management/commands/fix_missing_patient_data.py +206 -0
- endoreg_db/management/commands/fix_video_paths.py +186 -0
- endoreg_db/management/commands/import_report.py +361 -0
- endoreg_db/management/commands/list_routes.py +20 -0
- endoreg_db/management/commands/load_ai_model_data.py +83 -0
- endoreg_db/management/commands/load_ai_model_label_data.py +60 -0
- endoreg_db/management/commands/load_base_db_data.py +63 -0
- endoreg_db/management/commands/load_center_data.py +68 -0
- endoreg_db/management/commands/load_contraindication_data.py +39 -0
- endoreg_db/management/commands/load_disease_classification_choices_data.py +38 -0
- endoreg_db/management/commands/load_disease_classification_data.py +38 -0
- endoreg_db/management/commands/load_disease_data.py +59 -0
- endoreg_db/management/commands/load_distribution_data.py +63 -0
- endoreg_db/management/commands/load_endoscope_data.py +58 -0
- endoreg_db/management/commands/load_event_data.py +39 -0
- endoreg_db/management/commands/load_examination_data.py +78 -0
- endoreg_db/management/commands/load_examination_indication_data.py +85 -0
- endoreg_db/management/commands/load_finding_data.py +115 -0
- endoreg_db/management/commands/load_gender_data.py +37 -0
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +142 -0
- endoreg_db/management/commands/load_information_source.py +46 -0
- endoreg_db/management/commands/load_lab_value_data.py +52 -0
- endoreg_db/management/commands/load_legacy_data.py +303 -0
- endoreg_db/management/commands/load_medication_data.py +104 -0
- endoreg_db/management/commands/load_name_data.py +36 -0
- endoreg_db/management/commands/load_organ_data.py +39 -0
- endoreg_db/management/commands/load_pdf_type_data.py +58 -0
- endoreg_db/management/commands/load_profession_data.py +40 -0
- endoreg_db/management/commands/load_qualification_data.py +56 -0
- endoreg_db/management/commands/load_report_reader_flag_data.py +40 -0
- endoreg_db/management/commands/load_requirement_data.py +207 -0
- endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
- endoreg_db/management/commands/load_risk_data.py +57 -0
- endoreg_db/management/commands/load_shift_data.py +57 -0
- endoreg_db/management/commands/load_tag_data.py +54 -0
- endoreg_db/management/commands/load_unit_data.py +40 -0
- endoreg_db/management/commands/load_user_groups.py +26 -0
- endoreg_db/management/commands/model_input.py +169 -0
- endoreg_db/management/commands/register_ai_model.py +70 -0
- endoreg_db/management/commands/setup_endoreg_db.py +459 -0
- endoreg_db/management/commands/start_filewatcher.py +115 -0
- endoreg_db/management/commands/storage_management.py +622 -0
- endoreg_db/management/commands/summarize_db_content.py +280 -0
- endoreg_db/management/commands/train_image_multilabel_model.py +144 -0
- endoreg_db/management/commands/validate_video_files.py +189 -0
- endoreg_db/management/commands/video_validation.py +20 -0
- endoreg_db/mermaid/Overall_flow_patient_finding_intervention.md +10 -0
- endoreg_db/mermaid/anonymized_image_annotation.md +20 -0
- endoreg_db/mermaid/binary_classification_annotation.md +50 -0
- endoreg_db/mermaid/classification.md +8 -0
- endoreg_db/mermaid/examination.md +8 -0
- endoreg_db/mermaid/findings.md +7 -0
- endoreg_db/mermaid/image_classification.md +28 -0
- endoreg_db/mermaid/interventions.md +8 -0
- endoreg_db/mermaid/morphology.md +8 -0
- endoreg_db/mermaid/patient_creation.md +14 -0
- endoreg_db/mermaid/video_segmentation_annotation.md +17 -0
- endoreg_db/migrations/0001_initial.py +1953 -0
- endoreg_db/migrations/__init__.py +0 -0
- endoreg_db/models/__init__.py +322 -0
- endoreg_db/models/administration/__init__.py +95 -0
- endoreg_db/models/administration/ai/__init__.py +9 -0
- endoreg_db/models/administration/ai/active_model.py +35 -0
- endoreg_db/models/administration/ai/ai_model.py +180 -0
- endoreg_db/models/administration/ai/model_type.py +42 -0
- endoreg_db/models/administration/case/__init__.py +5 -0
- endoreg_db/models/administration/case/case.py +114 -0
- endoreg_db/models/administration/case/case_template/__init__.py +3 -0
- endoreg_db/models/administration/case/case_template/case_template.py +3 -0
- endoreg_db/models/administration/case/case_template/case_template_rule.py +3 -0
- endoreg_db/models/administration/case/case_template/case_template_rule_value.py +3 -0
- endoreg_db/models/administration/case/case_template/case_template_type.py +3 -0
- endoreg_db/models/administration/center/__init__.py +13 -0
- endoreg_db/models/administration/center/center.py +85 -0
- endoreg_db/models/administration/center/center_product.py +67 -0
- endoreg_db/models/administration/center/center_resource.py +69 -0
- endoreg_db/models/administration/center/center_shift.py +94 -0
- endoreg_db/models/administration/center/center_waste.py +42 -0
- endoreg_db/models/administration/person/__init__.py +26 -0
- endoreg_db/models/administration/person/employee/__init__.py +3 -0
- endoreg_db/models/administration/person/employee/employee.py +40 -0
- endoreg_db/models/administration/person/employee/employee_qualification.py +44 -0
- endoreg_db/models/administration/person/employee/employee_type.py +50 -0
- endoreg_db/models/administration/person/examiner/__init__.py +4 -0
- endoreg_db/models/administration/person/examiner/examiner.py +64 -0
- endoreg_db/models/administration/person/names/__init__.py +0 -0
- endoreg_db/models/administration/person/names/first_name.py +20 -0
- endoreg_db/models/administration/person/names/last_name.py +20 -0
- endoreg_db/models/administration/person/patient/__init__.py +7 -0
- endoreg_db/models/administration/person/patient/patient.py +488 -0
- endoreg_db/models/administration/person/patient/patient_external_id.py +36 -0
- endoreg_db/models/administration/person/person.py +35 -0
- endoreg_db/models/administration/person/profession/__init__.py +28 -0
- endoreg_db/models/administration/person/user/__init__.py +5 -0
- endoreg_db/models/administration/person/user/portal_user_information.py +41 -0
- endoreg_db/models/administration/product/__init__.py +15 -0
- endoreg_db/models/administration/product/product.py +106 -0
- endoreg_db/models/administration/product/product_group.py +41 -0
- endoreg_db/models/administration/product/product_material.py +60 -0
- endoreg_db/models/administration/product/product_weight.py +51 -0
- endoreg_db/models/administration/product/reference_product.py +147 -0
- endoreg_db/models/administration/qualification/__init__.py +7 -0
- endoreg_db/models/administration/qualification/qualification.py +43 -0
- endoreg_db/models/administration/qualification/qualification_type.py +39 -0
- endoreg_db/models/administration/shift/__init__.py +9 -0
- endoreg_db/models/administration/shift/scheduled_days.py +72 -0
- endoreg_db/models/administration/shift/shift.py +57 -0
- endoreg_db/models/administration/shift/shift_type.py +108 -0
- endoreg_db/models/aidataset/__init__.py +5 -0
- endoreg_db/models/aidataset/aidataset.py +193 -0
- endoreg_db/models/label/__init__.py +23 -0
- endoreg_db/models/label/annotation/__init__.py +12 -0
- endoreg_db/models/label/annotation/image_classification.py +85 -0
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +61 -0
- endoreg_db/models/label/label.py +91 -0
- endoreg_db/models/label/label_set.py +68 -0
- endoreg_db/models/label/label_type.py +29 -0
- endoreg_db/models/label/label_video_segment/__init__.py +3 -0
- endoreg_db/models/label/label_video_segment/_create_from_video.py +42 -0
- endoreg_db/models/label/label_video_segment/label_video_segment.py +611 -0
- endoreg_db/models/label/video_segmentation_label.py +35 -0
- endoreg_db/models/label/video_segmentation_labelset.py +28 -0
- endoreg_db/models/media/__init__.py +23 -0
- endoreg_db/models/media/frame/__init__.py +3 -0
- endoreg_db/models/media/frame/frame.py +137 -0
- endoreg_db/models/media/pdf/__init__.py +12 -0
- endoreg_db/models/media/pdf/raw_pdf.py +764 -0
- endoreg_db/models/media/pdf/report_file.py +162 -0
- endoreg_db/models/media/pdf/report_reader/__init__.py +7 -0
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +85 -0
- endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +46 -0
- endoreg_db/models/media/video/__init__.py +9 -0
- endoreg_db/models/media/video/create_from_file.py +402 -0
- endoreg_db/models/media/video/pipe_1.py +258 -0
- endoreg_db/models/media/video/pipe_2.py +129 -0
- endoreg_db/models/media/video/video_file.py +907 -0
- endoreg_db/models/media/video/video_file_ai.py +828 -0
- endoreg_db/models/media/video/video_file_anonymize.py +524 -0
- endoreg_db/models/media/video/video_file_frames/__init__.py +49 -0
- endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +25 -0
- endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +23 -0
- endoreg_db/models/media/video/video_file_frames/_delete_frames.py +126 -0
- endoreg_db/models/media/video/video_file_frames/_extract_frames.py +233 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame.py +36 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +13 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +24 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +40 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +44 -0
- endoreg_db/models/media/video/video_file_frames/_get_frames.py +30 -0
- endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +205 -0
- endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +228 -0
- endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +107 -0
- endoreg_db/models/media/video/video_file_io.py +272 -0
- endoreg_db/models/media/video/video_file_meta/__init__.py +22 -0
- endoreg_db/models/media/video/video_file_meta/get_crop_template.py +58 -0
- endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +62 -0
- endoreg_db/models/media/video/video_file_meta/get_fps.py +183 -0
- endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +198 -0
- endoreg_db/models/media/video/video_file_meta/text_meta.py +178 -0
- endoreg_db/models/media/video/video_file_meta/video_meta.py +105 -0
- endoreg_db/models/media/video/video_file_segments.py +317 -0
- endoreg_db/models/media/video/video_metadata.py +67 -0
- endoreg_db/models/media/video/video_processing.py +192 -0
- endoreg_db/models/medical/__init__.py +136 -0
- endoreg_db/models/medical/contraindication/README.md +1 -0
- endoreg_db/models/medical/contraindication/__init__.py +29 -0
- endoreg_db/models/medical/disease.py +174 -0
- endoreg_db/models/medical/event.py +154 -0
- endoreg_db/models/medical/examination/__init__.py +20 -0
- endoreg_db/models/medical/examination/examination.py +183 -0
- endoreg_db/models/medical/examination/examination_indication.py +229 -0
- endoreg_db/models/medical/examination/examination_time.py +68 -0
- endoreg_db/models/medical/examination/examination_time_type.py +44 -0
- endoreg_db/models/medical/examination/examination_type.py +47 -0
- endoreg_db/models/medical/finding/__init__.py +20 -0
- endoreg_db/models/medical/finding/finding.py +113 -0
- endoreg_db/models/medical/finding/finding_classification.py +131 -0
- endoreg_db/models/medical/finding/finding_intervention.py +68 -0
- endoreg_db/models/medical/finding/finding_type.py +38 -0
- endoreg_db/models/medical/hardware/__init__.py +8 -0
- endoreg_db/models/medical/hardware/endoscope.py +77 -0
- endoreg_db/models/medical/hardware/endoscopy_processor.py +182 -0
- endoreg_db/models/medical/laboratory/__init__.py +5 -0
- endoreg_db/models/medical/laboratory/lab_value.py +490 -0
- endoreg_db/models/medical/medication/__init__.py +23 -0
- endoreg_db/models/medical/medication/medication.py +45 -0
- endoreg_db/models/medical/medication/medication_indication.py +78 -0
- endoreg_db/models/medical/medication/medication_indication_type.py +58 -0
- endoreg_db/models/medical/medication/medication_intake_time.py +58 -0
- endoreg_db/models/medical/medication/medication_schedule.py +58 -0
- endoreg_db/models/medical/organ/__init__.py +38 -0
- endoreg_db/models/medical/patient/__init__.py +48 -0
- endoreg_db/models/medical/patient/medication_examples.py +56 -0
- endoreg_db/models/medical/patient/patient_disease.py +72 -0
- endoreg_db/models/medical/patient/patient_event.py +80 -0
- endoreg_db/models/medical/patient/patient_examination.py +280 -0
- endoreg_db/models/medical/patient/patient_examination_indication.py +57 -0
- endoreg_db/models/medical/patient/patient_finding.py +416 -0
- endoreg_db/models/medical/patient/patient_finding_classification.py +231 -0
- endoreg_db/models/medical/patient/patient_finding_intervention.py +37 -0
- endoreg_db/models/medical/patient/patient_lab_sample.py +157 -0
- endoreg_db/models/medical/patient/patient_lab_value.py +247 -0
- endoreg_db/models/medical/patient/patient_medication.py +111 -0
- endoreg_db/models/medical/patient/patient_medication_schedule.py +152 -0
- endoreg_db/models/medical/risk/__init__.py +7 -0
- endoreg_db/models/medical/risk/risk.py +73 -0
- endoreg_db/models/medical/risk/risk_type.py +54 -0
- endoreg_db/models/metadata/__init__.py +19 -0
- endoreg_db/models/metadata/model_meta.py +266 -0
- endoreg_db/models/metadata/model_meta_logic.py +485 -0
- endoreg_db/models/metadata/pdf_meta.py +96 -0
- endoreg_db/models/metadata/sensitive_meta.py +345 -0
- endoreg_db/models/metadata/sensitive_meta_logic.py +1161 -0
- endoreg_db/models/metadata/video_meta.py +459 -0
- endoreg_db/models/metadata/video_prediction_logic.py +232 -0
- endoreg_db/models/metadata/video_prediction_meta.py +319 -0
- endoreg_db/models/operation_log.py +63 -0
- endoreg_db/models/other/__init__.py +40 -0
- endoreg_db/models/other/distribution/__init__.py +46 -0
- endoreg_db/models/other/distribution/base_value_distribution.py +22 -0
- endoreg_db/models/other/distribution/date_value_distribution.py +163 -0
- endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +50 -0
- endoreg_db/models/other/distribution/numeric_value_distribution.py +211 -0
- endoreg_db/models/other/distribution/single_categorical_value_distribution.py +23 -0
- endoreg_db/models/other/emission/__init__.py +5 -0
- endoreg_db/models/other/emission/emission_factor.py +110 -0
- endoreg_db/models/other/gender.py +32 -0
- endoreg_db/models/other/information_source.py +190 -0
- endoreg_db/models/other/material.py +34 -0
- endoreg_db/models/other/resource.py +24 -0
- endoreg_db/models/other/tag.py +32 -0
- endoreg_db/models/other/transport_route.py +40 -0
- endoreg_db/models/other/unit.py +40 -0
- endoreg_db/models/other/waste.py +28 -0
- endoreg_db/models/report/__init__.py +0 -0
- endoreg_db/models/report/images.py +0 -0
- endoreg_db/models/report/report.py +5 -0
- endoreg_db/models/requirement/__init__.py +11 -0
- endoreg_db/models/requirement/requirement.py +792 -0
- endoreg_db/models/requirement/requirement_error.py +84 -0
- endoreg_db/models/requirement/requirement_evaluation/__init__.py +6 -0
- endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
- endoreg_db/models/requirement/requirement_evaluation/get_values.py +40 -0
- endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +6 -0
- endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +137 -0
- endoreg_db/models/requirement/requirement_operator.py +187 -0
- endoreg_db/models/requirement/requirement_set.py +327 -0
- endoreg_db/models/state/__init__.py +13 -0
- endoreg_db/models/state/abstract.py +11 -0
- endoreg_db/models/state/anonymization.py +30 -0
- endoreg_db/models/state/audit_ledger.py +155 -0
- endoreg_db/models/state/label_video_segment.py +31 -0
- endoreg_db/models/state/processing_history/__init__.py +3 -0
- endoreg_db/models/state/processing_history/processing_history.py +136 -0
- endoreg_db/models/state/raw_pdf.py +219 -0
- endoreg_db/models/state/sensitive_meta.py +50 -0
- endoreg_db/models/state/video.py +251 -0
- endoreg_db/models/upload_job.py +100 -0
- endoreg_db/models/utils.py +138 -0
- endoreg_db/queries/__init__.py +3 -0
- endoreg_db/queries/annotations/__init__.py +1 -0
- endoreg_db/queries/annotations/legacy.py +169 -0
- endoreg_db/queries/sanity/__init_.py +0 -0
- endoreg_db/root_urls.py +27 -0
- endoreg_db/schemas/__init__.py +0 -0
- endoreg_db/schemas/examination_evaluation.py +30 -0
- endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +861 -0
- endoreg_db/serializers/__init__.py +104 -0
- endoreg_db/serializers/administration/__init__.py +13 -0
- endoreg_db/serializers/administration/ai/__init__.py +9 -0
- endoreg_db/serializers/administration/ai/active_model.py +12 -0
- endoreg_db/serializers/administration/ai/ai_model.py +20 -0
- endoreg_db/serializers/administration/ai/model_type.py +12 -0
- endoreg_db/serializers/administration/center.py +14 -0
- endoreg_db/serializers/administration/gender.py +11 -0
- endoreg_db/serializers/anonymization.py +77 -0
- endoreg_db/serializers/evaluation/examination_evaluation.py +0 -0
- endoreg_db/serializers/examination/__init__.py +10 -0
- endoreg_db/serializers/examination/base.py +45 -0
- endoreg_db/serializers/examination/dropdown.py +20 -0
- endoreg_db/serializers/examination_serializer.py +9 -0
- endoreg_db/serializers/finding/__init__.py +5 -0
- endoreg_db/serializers/finding/finding.py +61 -0
- endoreg_db/serializers/finding_classification/__init__.py +7 -0
- endoreg_db/serializers/finding_classification/choice.py +19 -0
- endoreg_db/serializers/finding_classification/classification.py +11 -0
- endoreg_db/serializers/label_video_segment/__init__.py +9 -0
- endoreg_db/serializers/label_video_segment/image_classification_annotation.py +62 -0
- endoreg_db/serializers/label_video_segment/label/__init__.py +6 -0
- endoreg_db/serializers/label_video_segment/label/label.py +15 -0
- endoreg_db/serializers/label_video_segment/label_video_segment.py +427 -0
- endoreg_db/serializers/meta/__init__.py +13 -0
- endoreg_db/serializers/meta/sensitive_meta_detail.py +122 -0
- endoreg_db/serializers/meta/sensitive_meta_update.py +153 -0
- endoreg_db/serializers/meta/sensitive_meta_verification.py +62 -0
- endoreg_db/serializers/meta/video_meta.py +39 -0
- endoreg_db/serializers/misc/__init__.py +14 -0
- endoreg_db/serializers/misc/file_overview.py +72 -0
- endoreg_db/serializers/misc/sensitive_patient_data.py +144 -0
- endoreg_db/serializers/misc/stats.py +35 -0
- endoreg_db/serializers/misc/translatable_field_mix_in.py +44 -0
- endoreg_db/serializers/misc/upload_job.py +74 -0
- endoreg_db/serializers/patient/__init__.py +12 -0
- endoreg_db/serializers/patient/patient.py +103 -0
- endoreg_db/serializers/patient/patient_dropdown.py +35 -0
- endoreg_db/serializers/patient_examination/__init__.py +7 -0
- endoreg_db/serializers/patient_examination/patient_examination.py +168 -0
- endoreg_db/serializers/patient_finding/__init__.py +15 -0
- endoreg_db/serializers/patient_finding/patient_finding.py +32 -0
- endoreg_db/serializers/patient_finding/patient_finding_classification.py +47 -0
- endoreg_db/serializers/patient_finding/patient_finding_detail.py +62 -0
- endoreg_db/serializers/patient_finding/patient_finding_intervention.py +28 -0
- endoreg_db/serializers/patient_finding/patient_finding_list.py +40 -0
- endoreg_db/serializers/patient_finding/patient_finding_write.py +135 -0
- endoreg_db/serializers/pdf/__init__.py +3 -0
- endoreg_db/serializers/pdf/anony_text_validation.py +101 -0
- endoreg_db/serializers/requirements/requirement_schema.py +20 -0
- endoreg_db/serializers/requirements/requirement_sets.py +99 -0
- endoreg_db/serializers/sensitive_meta_serializer.py +301 -0
- endoreg_db/serializers/video/__init__.py +7 -0
- endoreg_db/serializers/video/video_file.py +283 -0
- endoreg_db/serializers/video/video_file_brief.py +14 -0
- endoreg_db/serializers/video/video_file_detail.py +96 -0
- endoreg_db/serializers/video/video_file_list.py +100 -0
- endoreg_db/serializers/video/video_processing_history.py +172 -0
- endoreg_db/serializers/video_examination.py +198 -0
- endoreg_db/services/__init__.py +5 -0
- endoreg_db/services/anonymization.py +274 -0
- endoreg_db/services/examination_evaluation.py +172 -0
- endoreg_db/services/finding_description_service.py +0 -0
- endoreg_db/services/lookup_service.py +424 -0
- endoreg_db/services/lookup_store.py +266 -0
- endoreg_db/services/model_meta_from_hf.py +76 -0
- endoreg_db/services/pdf_import.py +0 -0
- endoreg_db/services/polling_coordinator.py +319 -0
- endoreg_db/services/pseudonym_service.py +94 -0
- endoreg_db/services/report_import.py +13 -0
- endoreg_db/services/segment_sync.py +171 -0
- endoreg_db/services/video_import.py +9 -0
- endoreg_db/templates/admin/patient_finding_intervention.html +253 -0
- endoreg_db/templates/admin/start_examination.html +12 -0
- endoreg_db/templates/timeline.html +176 -0
- endoreg_db/urls/__init__.py +56 -0
- endoreg_db/urls/ai.py +14 -0
- endoreg_db/urls/anonymization.py +78 -0
- endoreg_db/urls/auth.py +16 -0
- endoreg_db/urls/classification.py +34 -0
- endoreg_db/urls/examination.py +63 -0
- endoreg_db/urls/media.py +251 -0
- endoreg_db/urls/patient.py +23 -0
- endoreg_db/urls/requirements.py +15 -0
- endoreg_db/urls/root_urls.py +28 -0
- endoreg_db/urls/stats.py +54 -0
- endoreg_db/urls/upload.py +12 -0
- endoreg_db/urls.py +9 -0
- endoreg_db/utils/__init__.py +97 -0
- endoreg_db/utils/ai/__init__.py +9 -0
- endoreg_db/utils/ai/data_loader_for_model_input.py +262 -0
- endoreg_db/utils/ai/data_loader_for_model_training.py +262 -0
- endoreg_db/utils/ai/get.py +6 -0
- endoreg_db/utils/ai/inference_dataset.py +51 -0
- endoreg_db/utils/ai/model_training/config.py +117 -0
- endoreg_db/utils/ai/model_training/dataset.py +74 -0
- endoreg_db/utils/ai/model_training/losses.py +68 -0
- endoreg_db/utils/ai/model_training/metrics.py +78 -0
- endoreg_db/utils/ai/model_training/model_backbones.py +155 -0
- endoreg_db/utils/ai/model_training/model_gastronet_resnet.py +118 -0
- endoreg_db/utils/ai/model_training/trainer_gastronet_multilabel.py +771 -0
- endoreg_db/utils/ai/multilabel_classification_net.py +270 -0
- endoreg_db/utils/ai/postprocess.py +63 -0
- endoreg_db/utils/ai/predict.py +293 -0
- endoreg_db/utils/ai/preprocess.py +76 -0
- endoreg_db/utils/calc_duration_seconds.py +24 -0
- endoreg_db/utils/case_generator/__init__.py +3 -0
- endoreg_db/utils/case_generator/lab_sample_factory.py +32 -0
- endoreg_db/utils/check_video_files.py +175 -0
- endoreg_db/utils/cropping.py +30 -0
- endoreg_db/utils/dataloader.py +285 -0
- endoreg_db/utils/dates.py +59 -0
- endoreg_db/utils/defaults/set_default_center.py +33 -0
- endoreg_db/utils/env.py +37 -0
- endoreg_db/utils/extract_specific_frames.py +87 -0
- endoreg_db/utils/file_operations.py +70 -0
- endoreg_db/utils/fix_video_path_direct.py +157 -0
- endoreg_db/utils/frame_anonymization_utils.py +463 -0
- endoreg_db/utils/hashs.py +138 -0
- endoreg_db/utils/links/__init__.py +0 -0
- endoreg_db/utils/links/requirement_link.py +237 -0
- endoreg_db/utils/mime_types.py +0 -0
- endoreg_db/utils/names.py +82 -0
- endoreg_db/utils/ocr.py +195 -0
- endoreg_db/utils/operation_log.py +87 -0
- endoreg_db/utils/parse_and_generate_yaml.py +45 -0
- endoreg_db/utils/paths.py +159 -0
- endoreg_db/utils/permissions.py +160 -0
- endoreg_db/utils/pipelines/Readme.md +235 -0
- endoreg_db/utils/pipelines/__init__.py +0 -0
- endoreg_db/utils/pipelines/process_video_dir.py +144 -0
- endoreg_db/utils/product/__init__.py +0 -0
- endoreg_db/utils/product/sum_emissions.py +22 -0
- endoreg_db/utils/product/sum_weights.py +20 -0
- endoreg_db/utils/pydantic_models/__init__.py +5 -0
- endoreg_db/utils/pydantic_models/db_config.py +57 -0
- endoreg_db/utils/requirement_helpers.py +0 -0
- endoreg_db/utils/requirement_operator_logic/__init__.py +0 -0
- endoreg_db/utils/requirement_operator_logic/_old/lab_value_operators.py +678 -0
- endoreg_db/utils/requirement_operator_logic/_old/model_evaluators.py +842 -0
- endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +114 -0
- endoreg_db/utils/setup_config.py +196 -0
- endoreg_db/utils/storage.py +117 -0
- endoreg_db/utils/translation.py +31 -0
- endoreg_db/utils/uuid.py +5 -0
- endoreg_db/utils/validate_endo_roi.py +33 -0
- endoreg_db/utils/validate_subcategory_dict.py +93 -0
- endoreg_db/utils/validate_video_detailed.py +415 -0
- endoreg_db/utils/video/__init__.py +30 -0
- endoreg_db/utils/video/extract_frames.py +100 -0
- endoreg_db/utils/video/ffmpeg_wrapper.py +996 -0
- endoreg_db/utils/video/names.py +47 -0
- endoreg_db/utils/video/streaming_processor.py +386 -0
- endoreg_db/utils/video/video_splitter.py +105 -0
- endoreg_db/versioning.md +79 -0
- endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +247 -0
- endoreg_db/views/__init__.py +157 -0
- endoreg_db/views/anonymization/__init__.py +31 -0
- endoreg_db/views/anonymization/media_management.py +486 -0
- endoreg_db/views/anonymization/overview.py +307 -0
- endoreg_db/views/anonymization/validate.py +310 -0
- endoreg_db/views/auth/__init__.py +13 -0
- endoreg_db/views/auth/keycloak.py +146 -0
- endoreg_db/views/examination/__init__.py +30 -0
- endoreg_db/views/examination/examination.py +37 -0
- endoreg_db/views/examination/examination_manifest_cache.py +26 -0
- endoreg_db/views/examination/get_finding_classification_choices.py +62 -0
- endoreg_db/views/examination/get_finding_classifications.py +38 -0
- endoreg_db/views/examination/get_findings.py +39 -0
- endoreg_db/views/examination/get_instruments.py +19 -0
- endoreg_db/views/examination/get_interventions.py +14 -0
- endoreg_db/views/finding/__init__.py +9 -0
- endoreg_db/views/finding/finding.py +116 -0
- endoreg_db/views/finding/get_classifications.py +14 -0
- endoreg_db/views/finding/get_interventions.py +17 -0
- endoreg_db/views/finding_classification/__init__.py +13 -0
- endoreg_db/views/finding_classification/base.py +0 -0
- endoreg_db/views/finding_classification/finding_classification.py +41 -0
- endoreg_db/views/finding_classification/get_classification_choices.py +54 -0
- endoreg_db/views/media/__init__.py +32 -0
- endoreg_db/views/media/pdf_media.py +411 -0
- endoreg_db/views/media/sensitive_metadata.py +372 -0
- endoreg_db/views/media/video_media.py +275 -0
- endoreg_db/views/meta/__init__.py +7 -0
- endoreg_db/views/meta/sensitive_meta_list.py +102 -0
- endoreg_db/views/meta/sensitive_meta_verification.py +74 -0
- endoreg_db/views/misc/__init__.py +29 -0
- endoreg_db/views/misc/center.py +14 -0
- endoreg_db/views/misc/csrf.py +8 -0
- endoreg_db/views/misc/gender.py +15 -0
- endoreg_db/views/misc/stats.py +255 -0
- endoreg_db/views/misc/upload_views.py +241 -0
- endoreg_db/views/patient/__init__.py +3 -0
- endoreg_db/views/patient/patient.py +253 -0
- endoreg_db/views/patient_examination/__init__.py +11 -0
- endoreg_db/views/patient_examination/patient_examination.py +141 -0
- endoreg_db/views/patient_examination/patient_examination_create.py +58 -0
- endoreg_db/views/patient_examination/patient_examination_detail.py +63 -0
- endoreg_db/views/patient_examination/patient_examination_list.py +72 -0
- endoreg_db/views/patient_examination/video.py +228 -0
- endoreg_db/views/patient_finding/__init__.py +7 -0
- endoreg_db/views/patient_finding/base.py +0 -0
- endoreg_db/views/patient_finding/patient_finding.py +71 -0
- endoreg_db/views/patient_finding/patient_finding_optimized.py +291 -0
- endoreg_db/views/patient_finding_classification/__init__.py +5 -0
- endoreg_db/views/patient_finding_classification/pfc_create.py +75 -0
- endoreg_db/views/report/__init__.py +7 -0
- endoreg_db/views/report/reimport.py +177 -0
- endoreg_db/views/report/report_stream.py +191 -0
- endoreg_db/views/requirement/__init__.py +11 -0
- endoreg_db/views/requirement/evaluate.py +278 -0
- endoreg_db/views/requirement/lookup.py +380 -0
- endoreg_db/views/requirement/lookup_store.py +183 -0
- endoreg_db/views/requirement/requirement_utils.py +87 -0
- endoreg_db/views/requirement_lookup/lookup.py +0 -0
- endoreg_db/views/requirement_lookup/lookup_store.py +0 -0
- endoreg_db/views/stats/__init__.py +13 -0
- endoreg_db/views/stats/stats_views.py +266 -0
- endoreg_db/views/video/__init__.py +49 -0
- endoreg_db/views/video/ai/__init__.py +8 -0
- endoreg_db/views/video/ai/label.py +159 -0
- endoreg_db/views/video/correction.py +529 -0
- endoreg_db/views/video/reimport.py +230 -0
- endoreg_db/views/video/segments_crud.py +709 -0
- endoreg_db/views/video/video_apply_mask.py +49 -0
- endoreg_db/views/video/video_correction.py +22 -0
- endoreg_db/views/video/video_download_processed.py +58 -0
- endoreg_db/views/video/video_examination_viewset.py +242 -0
- endoreg_db/views/video/video_metadata.py +101 -0
- endoreg_db/views/video/video_processing_history.py +25 -0
- endoreg_db/views/video/video_remove_frames.py +49 -0
- endoreg_db/views/video/video_stream.py +334 -0
- endoreg_db-0.8.9.32.dist-info/METADATA +404 -0
- endoreg_db-0.8.9.32.dist-info/RECORD +787 -0
- endoreg_db-0.8.9.32.dist-info/WHEEL +4 -0
- endoreg_db-0.8.9.32.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Video Examination Serializer
|
|
3
|
+
|
|
4
|
+
Serializes PatientExamination instances that are associated with VideoFile records.
|
|
5
|
+
This allows frontend components like VideoExaminationAnnotation.vue to display
|
|
6
|
+
and manage examinations within the video annotation workflow.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from rest_framework import serializers
|
|
10
|
+
|
|
11
|
+
from ..models import Examination, PatientExamination, VideoFile
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class VideoExaminationSerializer(serializers.ModelSerializer):
|
|
15
|
+
"""
|
|
16
|
+
Serializer for video-based patient examinations.
|
|
17
|
+
|
|
18
|
+
Exposes examination data within the context of video annotation:
|
|
19
|
+
- Basic examination metadata (type, date, hash)
|
|
20
|
+
- Related patient information (anonymized)
|
|
21
|
+
- Video reference
|
|
22
|
+
- Associated findings
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
# Custom fields for frontend compatibility
|
|
26
|
+
examination_name = serializers.CharField(source="examination.name", read_only=True)
|
|
27
|
+
examination_id = serializers.IntegerField(source="examination.id", read_only=True)
|
|
28
|
+
video_id = serializers.IntegerField(source="video.id", read_only=True)
|
|
29
|
+
patient_hash = serializers.CharField(source="patient.patient_hash", read_only=True)
|
|
30
|
+
|
|
31
|
+
# Nested findings data
|
|
32
|
+
findings = serializers.SerializerMethodField()
|
|
33
|
+
|
|
34
|
+
class Meta:
|
|
35
|
+
model = PatientExamination
|
|
36
|
+
fields = [
|
|
37
|
+
"id",
|
|
38
|
+
"hash",
|
|
39
|
+
"examination_id",
|
|
40
|
+
"examination_name",
|
|
41
|
+
"video_id",
|
|
42
|
+
"patient_hash",
|
|
43
|
+
"date_start",
|
|
44
|
+
"date_end",
|
|
45
|
+
"findings",
|
|
46
|
+
]
|
|
47
|
+
read_only_fields = ["hash", "patient_hash"]
|
|
48
|
+
|
|
49
|
+
def get_findings(self, obj):
|
|
50
|
+
"""
|
|
51
|
+
Return serialized findings associated with this examination.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
obj: PatientExamination instance
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
List of finding dictionaries with basic metadata
|
|
58
|
+
"""
|
|
59
|
+
patient_findings = obj.patient_findings.all()
|
|
60
|
+
return [
|
|
61
|
+
{
|
|
62
|
+
"id": pf.id,
|
|
63
|
+
"finding_id": pf.finding.id if pf.finding else None,
|
|
64
|
+
"finding_name": pf.finding.name if pf.finding else None,
|
|
65
|
+
"created_at": pf.created_at if hasattr(pf, "created_at") else None,
|
|
66
|
+
}
|
|
67
|
+
for pf in patient_findings
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class VideoExaminationCreateSerializer(serializers.Serializer):
|
|
72
|
+
"""
|
|
73
|
+
Serializer for creating video examinations via API.
|
|
74
|
+
|
|
75
|
+
Handles the complex creation logic required to link:
|
|
76
|
+
- VideoFile (must exist)
|
|
77
|
+
- Examination type (must exist)
|
|
78
|
+
- Patient (derived from video's SensitiveMeta)
|
|
79
|
+
- New PatientExamination record
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
video_id = serializers.IntegerField(required=True)
|
|
83
|
+
examination_id = serializers.IntegerField(required=True)
|
|
84
|
+
date_start = serializers.DateField(required=False, allow_null=True)
|
|
85
|
+
date_end = serializers.DateField(required=False, allow_null=True)
|
|
86
|
+
|
|
87
|
+
def validate_video_id(self, value):
|
|
88
|
+
"""Ensure video exists"""
|
|
89
|
+
if not VideoFile.objects.filter(id=value).exists():
|
|
90
|
+
raise serializers.ValidationError(f"Video with id {value} does not exist")
|
|
91
|
+
return value
|
|
92
|
+
|
|
93
|
+
def validate_examination_id(self, value):
|
|
94
|
+
"""Ensure examination type exists"""
|
|
95
|
+
if not Examination.objects.filter(id=value).exists():
|
|
96
|
+
raise serializers.ValidationError(
|
|
97
|
+
f"Examination with id {value} does not exist"
|
|
98
|
+
)
|
|
99
|
+
return value
|
|
100
|
+
|
|
101
|
+
def create(self, validated_data):
|
|
102
|
+
"""
|
|
103
|
+
Create PatientExamination record.
|
|
104
|
+
|
|
105
|
+
Links video to examination through patient relationship:
|
|
106
|
+
1. Get video and extract patient from SensitiveMeta
|
|
107
|
+
2. Get examination type
|
|
108
|
+
3. Create PatientExamination linking patient, examination, video
|
|
109
|
+
|
|
110
|
+
Raises:
|
|
111
|
+
ValidationError: If video has no patient or sensitive_meta
|
|
112
|
+
"""
|
|
113
|
+
video = VideoFile.objects.get(id=validated_data["video_id"])
|
|
114
|
+
examination = Examination.objects.get(id=validated_data["examination_id"])
|
|
115
|
+
|
|
116
|
+
# Get patient from video's sensitive metadata
|
|
117
|
+
if not hasattr(video, "sensitive_meta") or not video.sensitive_meta:
|
|
118
|
+
raise serializers.ValidationError(
|
|
119
|
+
"Video must have sensitive metadata with patient information"
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
sensitive_meta = video.sensitive_meta
|
|
123
|
+
if not sensitive_meta.pseudo_patient:
|
|
124
|
+
raise serializers.ValidationError(
|
|
125
|
+
"Video's sensitive metadata must have an associated pseudo patient"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
patient = sensitive_meta.pseudo_patient
|
|
129
|
+
|
|
130
|
+
# Check if PatientExamination already exists for this video
|
|
131
|
+
existing_exam = PatientExamination.objects.filter(video=video).first()
|
|
132
|
+
if existing_exam:
|
|
133
|
+
# Update existing
|
|
134
|
+
patient_exam = existing_exam
|
|
135
|
+
patient_exam.examination = examination
|
|
136
|
+
if "date_start" in validated_data:
|
|
137
|
+
patient_exam.date_start = validated_data["date_start"]
|
|
138
|
+
if "date_end" in validated_data:
|
|
139
|
+
patient_exam.date_end = validated_data["date_end"]
|
|
140
|
+
patient_exam.save()
|
|
141
|
+
else:
|
|
142
|
+
# Create new
|
|
143
|
+
patient_exam = PatientExamination.objects.create(
|
|
144
|
+
patient=patient,
|
|
145
|
+
examination=examination,
|
|
146
|
+
video=video,
|
|
147
|
+
date_start=validated_data.get("date_start"),
|
|
148
|
+
date_end=validated_data.get("date_end"),
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
return patient_exam
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class VideoExaminationUpdateSerializer(serializers.Serializer):
|
|
155
|
+
"""
|
|
156
|
+
Serializer for updating video examinations.
|
|
157
|
+
|
|
158
|
+
Allows modification of:
|
|
159
|
+
- Examination type
|
|
160
|
+
- Date range
|
|
161
|
+
- Associated findings (via separate endpoint)
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
examination_id = serializers.IntegerField(required=False)
|
|
165
|
+
date_start = serializers.DateField(required=False, allow_null=True)
|
|
166
|
+
date_end = serializers.DateField(required=False, allow_null=True)
|
|
167
|
+
|
|
168
|
+
def validate_examination_id(self, value):
|
|
169
|
+
"""Ensure examination type exists if provided"""
|
|
170
|
+
if value is not None and not Examination.objects.filter(id=value).exists():
|
|
171
|
+
raise serializers.ValidationError(
|
|
172
|
+
f"Examination with id {value} does not exist"
|
|
173
|
+
)
|
|
174
|
+
return value
|
|
175
|
+
|
|
176
|
+
def update(self, instance, validated_data):
|
|
177
|
+
"""
|
|
178
|
+
Update PatientExamination fields.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
instance: Existing PatientExamination
|
|
182
|
+
validated_data: Validated update data
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
Updated PatientExamination instance
|
|
186
|
+
"""
|
|
187
|
+
if "examination_id" in validated_data:
|
|
188
|
+
examination = Examination.objects.get(id=validated_data["examination_id"])
|
|
189
|
+
instance.examination = examination
|
|
190
|
+
|
|
191
|
+
if "date_start" in validated_data:
|
|
192
|
+
instance.date_start = validated_data["date_start"]
|
|
193
|
+
|
|
194
|
+
if "date_end" in validated_data:
|
|
195
|
+
instance.date_end = validated_data["date_end"]
|
|
196
|
+
|
|
197
|
+
instance.save()
|
|
198
|
+
return instance
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# endoreg_db/services/anonymization.py
|
|
2
|
+
import logging
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional, Literal
|
|
5
|
+
|
|
6
|
+
from django.db import transaction
|
|
7
|
+
|
|
8
|
+
from endoreg_db.models import RawPdfFile, VideoFile
|
|
9
|
+
from endoreg_db.services.video_import import VideoImportService
|
|
10
|
+
from endoreg_db.services.report_import import ReportImportService
|
|
11
|
+
from endoreg_db.utils.paths import STORAGE_DIR
|
|
12
|
+
from endoreg_db.utils.storage import ensure_local_file, file_exists
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class AnonymizationService:
|
|
18
|
+
"""
|
|
19
|
+
Orchestrates long‑running anonymization tasks so the view only
|
|
20
|
+
does HTTP <-> Service translation.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, project_root: Optional[Path] = None):
|
|
24
|
+
"""
|
|
25
|
+
Initialize the AnonymizationService with service instances.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
project_root: Path to the project root. If None, uses settings.BASE_DIR
|
|
29
|
+
"""
|
|
30
|
+
self.project_root: Path = project_root or STORAGE_DIR
|
|
31
|
+
self.video_service = VideoImportService()
|
|
32
|
+
self.pdf_service = ReportImportService()
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def get_status(file_id: int, kind: Optional[str] = None) -> Optional[dict]:
|
|
36
|
+
"""
|
|
37
|
+
Retrieve status.
|
|
38
|
+
Handles 'pdf' vs 'report' alias.
|
|
39
|
+
If kind is None, checks both tables (Video priority).
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
# 1. Normalize the input kind if legacy name pdf is used
|
|
43
|
+
if kind == 'pdf':
|
|
44
|
+
kind = 'report'
|
|
45
|
+
|
|
46
|
+
# 2. Define lookup logic
|
|
47
|
+
check_video = kind == "video" or kind is None
|
|
48
|
+
check_report = kind == "report" or kind is None
|
|
49
|
+
|
|
50
|
+
# 3. Check VideoFile
|
|
51
|
+
if check_video:
|
|
52
|
+
vf = (
|
|
53
|
+
VideoFile.objects.select_related("state", "sensitive_meta")
|
|
54
|
+
.filter(pk=file_id)
|
|
55
|
+
.first()
|
|
56
|
+
)
|
|
57
|
+
if vf:
|
|
58
|
+
return {
|
|
59
|
+
"mediaType": "video",
|
|
60
|
+
"anonymizationStatus": vf.state.anonymization_status
|
|
61
|
+
if vf.state
|
|
62
|
+
else "not_started",
|
|
63
|
+
"fileExists": file_exists(vf.raw_file),
|
|
64
|
+
"uuid": str(vf.video_hash) if vf.video_hash else None,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# 4. Check RawPdfFile
|
|
68
|
+
if check_report:
|
|
69
|
+
pdf = (
|
|
70
|
+
RawPdfFile.objects.select_related("state", "sensitive_meta")
|
|
71
|
+
.filter(pk=file_id)
|
|
72
|
+
.first()
|
|
73
|
+
)
|
|
74
|
+
if pdf:
|
|
75
|
+
return {
|
|
76
|
+
"mediaType": "pdf",
|
|
77
|
+
"anonymizationStatus": pdf.state.anonymization_status
|
|
78
|
+
if pdf.state
|
|
79
|
+
else "not_started",
|
|
80
|
+
"fileExists": file_exists(pdf.file),
|
|
81
|
+
"hash": pdf.pdf_hash,
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# 5. Not found in either (or the specific requested type wasn't found)
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
# ---------- COMMANDS ------------------------------------------------
|
|
88
|
+
@transaction.atomic
|
|
89
|
+
def start(self, file_id: int, kind: Optional[str] = None) -> Optional[str]:
|
|
90
|
+
"""
|
|
91
|
+
Start anonymization process for a file by its ID.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
file_id: The ID of the file to anonymize
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
str or None: Media type if successful, None if file not found
|
|
98
|
+
"""
|
|
99
|
+
# Try VideoFile first
|
|
100
|
+
if kind == "video" or kind is None:
|
|
101
|
+
vf = (
|
|
102
|
+
VideoFile.objects.select_related(
|
|
103
|
+
"state", "sensitive_meta", "center", "video_meta__processor"
|
|
104
|
+
)
|
|
105
|
+
.filter(pk=file_id)
|
|
106
|
+
.first()
|
|
107
|
+
)
|
|
108
|
+
if vf:
|
|
109
|
+
try:
|
|
110
|
+
logger.info(f"Starting video anonymization for VideoFile ID: {file_id}")
|
|
111
|
+
|
|
112
|
+
# Check if already processed
|
|
113
|
+
if vf.state and vf.state.anonymized:
|
|
114
|
+
logger.info(f"VideoFile {file_id} already anonymized, skipping")
|
|
115
|
+
return "video"
|
|
116
|
+
|
|
117
|
+
# Get file path
|
|
118
|
+
file_path = vf.get_raw_file_path()
|
|
119
|
+
if not file_path or not Path(file_path).exists():
|
|
120
|
+
logger.error(
|
|
121
|
+
f"Raw file not found for VideoFile {file_id}: {file_path}"
|
|
122
|
+
)
|
|
123
|
+
return None
|
|
124
|
+
|
|
125
|
+
# Get processor name
|
|
126
|
+
processor_name = None
|
|
127
|
+
if vf.video_meta and vf.video_meta.processor:
|
|
128
|
+
processor_name = vf.video_meta.processor.name
|
|
129
|
+
elif hasattr(vf, "processor") and vf.processor:
|
|
130
|
+
processor_name = vf.processor.name
|
|
131
|
+
|
|
132
|
+
# Get center name
|
|
133
|
+
center_name = vf.center.name if vf.center else "unknown_center"
|
|
134
|
+
|
|
135
|
+
# Mark as started
|
|
136
|
+
if vf.state:
|
|
137
|
+
vf.state.processing_started = True
|
|
138
|
+
vf.state.save(update_fields=["processing_started"])
|
|
139
|
+
|
|
140
|
+
# Use VideoImportService for anonymization
|
|
141
|
+
safe_processor_name = processor_name or "unknown_processor"
|
|
142
|
+
self.video_service.import_and_anonymize(
|
|
143
|
+
file_path=file_path,
|
|
144
|
+
center_name=center_name,
|
|
145
|
+
processor_name=safe_processor_name,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
logger.info(
|
|
149
|
+
f"Video anonymization completed for VideoFile ID: {file_id}"
|
|
150
|
+
)
|
|
151
|
+
return "video"
|
|
152
|
+
|
|
153
|
+
except Exception as e:
|
|
154
|
+
logger.error(f"Failed to anonymize VideoFile {file_id}: {e}")
|
|
155
|
+
# Mark as failed if state exists
|
|
156
|
+
if vf.state:
|
|
157
|
+
vf.state.processing_started = (
|
|
158
|
+
False # Mark processing as not started due to failure
|
|
159
|
+
)
|
|
160
|
+
vf.state.save(update_fields=["processing_started"])
|
|
161
|
+
raise
|
|
162
|
+
elif kind == "report" or kind is None:
|
|
163
|
+
# Try RawPdfFile
|
|
164
|
+
pdf = (
|
|
165
|
+
RawPdfFile.objects.select_related("state", "sensitive_meta", "center")
|
|
166
|
+
.filter(pk=file_id)
|
|
167
|
+
.first()
|
|
168
|
+
)
|
|
169
|
+
if pdf:
|
|
170
|
+
try:
|
|
171
|
+
logger.info(f"Starting report processing for RawPdfFile ID: {file_id}")
|
|
172
|
+
|
|
173
|
+
# Check if already processed
|
|
174
|
+
if pdf.state and getattr(pdf.state, "anonymized", False):
|
|
175
|
+
logger.info(f"RawPdfFile {file_id} already processed, skipping")
|
|
176
|
+
return "pdf"
|
|
177
|
+
|
|
178
|
+
file_field = pdf.file
|
|
179
|
+
if not file_field or not file_field.name:
|
|
180
|
+
logger.error(f"report file not found for RawPdfFile {file_id}")
|
|
181
|
+
return None
|
|
182
|
+
|
|
183
|
+
if not file_exists(file_field):
|
|
184
|
+
logger.error(
|
|
185
|
+
"report file missing from storage for RawPdfFile %s", file_id
|
|
186
|
+
)
|
|
187
|
+
return None
|
|
188
|
+
|
|
189
|
+
# Get center name
|
|
190
|
+
center_name = pdf.center.name if pdf.center else "unknown_center"
|
|
191
|
+
|
|
192
|
+
# Mark as started
|
|
193
|
+
if pdf.state:
|
|
194
|
+
pdf.state.processing_started = True
|
|
195
|
+
pdf.state.save(update_fields=["processing_started"])
|
|
196
|
+
|
|
197
|
+
with ensure_local_file(file_field) as local_path:
|
|
198
|
+
self.pdf_service.import_and_anonymize(
|
|
199
|
+
file_path=local_path,
|
|
200
|
+
center_name=center_name,
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
logger.info(f"report processing completed for RawPdfFile ID: {file_id}")
|
|
204
|
+
return "pdf"
|
|
205
|
+
|
|
206
|
+
except Exception as e:
|
|
207
|
+
logger.error(f"Failed to process RawPdfFile {file_id}: {e}")
|
|
208
|
+
# Mark as failed if state exists
|
|
209
|
+
if pdf.state and hasattr(pdf.state, "processing_failed"):
|
|
210
|
+
pdf.state.save(update_fields=["processing_failed"])
|
|
211
|
+
elif pdf.sensitive_meta and hasattr(
|
|
212
|
+
pdf.sensitive_meta, "processing_failed"
|
|
213
|
+
):
|
|
214
|
+
pdf.sensitive_meta.save(update_fields=["processing_failed"])
|
|
215
|
+
raise
|
|
216
|
+
|
|
217
|
+
logger.warning(f"No file found with ID: {file_id}")
|
|
218
|
+
return None
|
|
219
|
+
|
|
220
|
+
@staticmethod
|
|
221
|
+
@transaction.atomic
|
|
222
|
+
def validate(file_id: int) -> None | Literal['video'] | Literal['pdf']:
|
|
223
|
+
from endoreg_db.views.anonymization.validate import AnonymizationValidateView
|
|
224
|
+
|
|
225
|
+
vf = VideoFile.objects.select_related("state").filter(pk=file_id).first()
|
|
226
|
+
if vf:
|
|
227
|
+
state = vf.state or vf.get_or_create_state()
|
|
228
|
+
if hasattr(state, "mark_anonymization_validated"):
|
|
229
|
+
state.mark_anonymization_validated()
|
|
230
|
+
return "video"
|
|
231
|
+
|
|
232
|
+
pdf = RawPdfFile.objects.select_related("state").filter(pk=file_id).first()
|
|
233
|
+
if pdf:
|
|
234
|
+
state = pdf.state or pdf.get_or_create_state()
|
|
235
|
+
if hasattr(state, "mark_anonymization_validated"):
|
|
236
|
+
state.mark_anonymization_validated()
|
|
237
|
+
return "pdf"
|
|
238
|
+
|
|
239
|
+
return None
|
|
240
|
+
|
|
241
|
+
@staticmethod
|
|
242
|
+
def list_items():
|
|
243
|
+
video_files = VideoFile.objects.select_related("state").all()
|
|
244
|
+
pdf_files = RawPdfFile.objects.select_related(
|
|
245
|
+
"state"
|
|
246
|
+
).all() # was sensitive_meta
|
|
247
|
+
|
|
248
|
+
data = []
|
|
249
|
+
for vf in video_files:
|
|
250
|
+
data.append(
|
|
251
|
+
{
|
|
252
|
+
"id": vf.pk,
|
|
253
|
+
"mediaType": "video",
|
|
254
|
+
"anonymizationStatus": vf.state.anonymization_status
|
|
255
|
+
if vf.state
|
|
256
|
+
else "not_started",
|
|
257
|
+
"createdAt": vf.date_created,
|
|
258
|
+
"updatedAt": vf.date_modified,
|
|
259
|
+
}
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
for pdf in pdf_files:
|
|
263
|
+
data.append(
|
|
264
|
+
{
|
|
265
|
+
"id": pdf.pk,
|
|
266
|
+
"mediaType": "pdf",
|
|
267
|
+
"anonymizationStatus": pdf.state.anonymization_status
|
|
268
|
+
if pdf.state
|
|
269
|
+
else "not_started",
|
|
270
|
+
"createdAt": pdf.date_created,
|
|
271
|
+
"updatedAt": pdf.date_modified,
|
|
272
|
+
}
|
|
273
|
+
)
|
|
274
|
+
return data
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# app/services/evaluation.py
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from typing import List, Set, Tuple
|
|
4
|
+
|
|
5
|
+
from endoreg_db.schemas.examination_evaluation import (
|
|
6
|
+
ExaminationEvalReport,
|
|
7
|
+
RequirementSetEval,
|
|
8
|
+
RequirementEval,
|
|
9
|
+
)
|
|
10
|
+
from endoreg_db.models.medical.patient.patient_examination import PatientExamination
|
|
11
|
+
from endoreg_db.models.requirement.requirement_set import RequirementSet
|
|
12
|
+
import endoreg_db.services.lookup_service
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _get_requirement_sets_for_exam(exam: PatientExamination) -> List[RequirementSet]:
|
|
16
|
+
"""
|
|
17
|
+
Decide how an examination maps to requirement sets.
|
|
18
|
+
Adjust this to your actual relation:
|
|
19
|
+
- maybe exam.type.requirement_sets
|
|
20
|
+
- or via information_sources
|
|
21
|
+
- or a direct M2M on Examination
|
|
22
|
+
"""
|
|
23
|
+
# The new loader prefetches via `examination.exam_reqset_links`.
|
|
24
|
+
# We extract the RequirementSet from each link.
|
|
25
|
+
sets = []
|
|
26
|
+
if hasattr(exam, "examination") and hasattr(exam.examination, "exam_reqset_links"):
|
|
27
|
+
for link in exam.examination.exam_reqset_links.all():
|
|
28
|
+
if hasattr(link, "requirement_set"):
|
|
29
|
+
sets.append(link.requirement_set)
|
|
30
|
+
return sets
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _eval_requirement(
|
|
34
|
+
requirement, input_object, mode="loose"
|
|
35
|
+
) -> Tuple[bool, str | None]:
|
|
36
|
+
"""
|
|
37
|
+
Evaluate a single Requirement and return (bool, message).
|
|
38
|
+
The `message` can be None or contain a short explanation.
|
|
39
|
+
"""
|
|
40
|
+
ok = requirement.evaluate(input_object, mode=mode)
|
|
41
|
+
msg = None
|
|
42
|
+
# If your Requirement has a reason/explanation API, inject it here.
|
|
43
|
+
# Example: msg = requirement.last_reason if hasattr(requirement, "last_reason") else None
|
|
44
|
+
return ok, msg
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _reduce_bools(bools: List[bool], set_type_name: str | None) -> bool:
|
|
48
|
+
from endoreg_db.models.requirement.requirement_set import (
|
|
49
|
+
REQUIREMENT_SET_TYPE_FUNCTION_LOOKUP,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
func = REQUIREMENT_SET_TYPE_FUNCTION_LOOKUP.get(set_type_name or "all", all)
|
|
53
|
+
return bool(func(bools))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _eval_set_tree(
|
|
57
|
+
root: RequirementSet, input_object, visited: Set[int]
|
|
58
|
+
) -> RequirementSetEval:
|
|
59
|
+
"""
|
|
60
|
+
Recursively evaluate a RequirementSet node and linked children.
|
|
61
|
+
Protect against cycles with visited set.
|
|
62
|
+
"""
|
|
63
|
+
if root.pk in visited:
|
|
64
|
+
# Cycle detected -> treat as already evaluated (neutral element for AND is True; but better: skip node)
|
|
65
|
+
# We skip to avoid infinite recursion; AND/OR exact treatment depends on your business semantics.
|
|
66
|
+
return RequirementSetEval(
|
|
67
|
+
id=root.pk,
|
|
68
|
+
name=root.name,
|
|
69
|
+
type=(
|
|
70
|
+
root.requirement_set_type.name if root.requirement_set_type else None
|
|
71
|
+
),
|
|
72
|
+
is_satisfied=True,
|
|
73
|
+
requirements=[],
|
|
74
|
+
linked_sets=[],
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
visited.add(root.pk)
|
|
78
|
+
|
|
79
|
+
# Evaluate direct requirements
|
|
80
|
+
req_evals: List[RequirementEval] = []
|
|
81
|
+
for r in root.requirements.all():
|
|
82
|
+
ok, msg = _eval_requirement(r, input_object)
|
|
83
|
+
req_evals.append(
|
|
84
|
+
RequirementEval(
|
|
85
|
+
id=r.pk,
|
|
86
|
+
name=getattr(r, "name", f"Requirement {r.pk}"),
|
|
87
|
+
description=getattr(r, "description", None),
|
|
88
|
+
satisfied=ok,
|
|
89
|
+
message=msg,
|
|
90
|
+
)
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Evaluate linked sets
|
|
94
|
+
child_evals: List[RequirementSetEval] = []
|
|
95
|
+
for child in root.links_to_sets.all():
|
|
96
|
+
child_evals.append(_eval_set_tree(child, input_object, visited))
|
|
97
|
+
|
|
98
|
+
# Combine booleans
|
|
99
|
+
bools = [re.satisfied for re in req_evals] + [ce.is_satisfied for ce in child_evals]
|
|
100
|
+
set_type_name = (
|
|
101
|
+
root.requirement_set_type.name if root.requirement_set_type else "all"
|
|
102
|
+
)
|
|
103
|
+
satisfied = _reduce_bools(bools, set_type_name)
|
|
104
|
+
|
|
105
|
+
return RequirementSetEval(
|
|
106
|
+
id=root.pk,
|
|
107
|
+
name=root.name,
|
|
108
|
+
type=set_type_name,
|
|
109
|
+
is_satisfied=satisfied,
|
|
110
|
+
requirements=req_evals,
|
|
111
|
+
linked_sets=child_evals,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def evaluate_examination(request: dict) -> ExaminationEvalReport:
|
|
116
|
+
"""
|
|
117
|
+
Communicates with: components/RequirementGenerator
|
|
118
|
+
Evaluates a PatientExamination by its Lookup. The frontend sends this structure:
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
requirement_set_ids: plainRequirementSetIds,
|
|
122
|
+
lookup_token: lookupToken,
|
|
123
|
+
patient_examination_id: patientExaminationId
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
And expects a response to be processed like this:
|
|
127
|
+
|
|
128
|
+
const response = await axiosInstance.post('/api/evaluate-requirements/', payload);
|
|
129
|
+
const results = response.data.results || [];
|
|
130
|
+
const summary = response.data.summary || {};
|
|
131
|
+
|
|
132
|
+
// Update evaluation results
|
|
133
|
+
plainRequirementSetIds.forEach((setId: number) => {
|
|
134
|
+
evaluationResults.value[setId] = results.filter((r: RequirementEvaluationResult) =>
|
|
135
|
+
summary[setId]?.requirements.includes(r.requirement_name)
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
"""
|
|
139
|
+
exam_id = request.get("patient_examination_id")
|
|
140
|
+
if not exam_id:
|
|
141
|
+
return ExaminationEvalReport(
|
|
142
|
+
examination_id=None,
|
|
143
|
+
summary={"is_satisfied": True, "failed_count": 0, "total_sets": 0},
|
|
144
|
+
sets=[],
|
|
145
|
+
errors=["No patient_examination_id provided in request."],
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Use the dedicated loader function from the lookup service.
|
|
149
|
+
exam = endoreg_db.services.lookup_service.load_patient_exam_for_eval(pk=exam_id)
|
|
150
|
+
|
|
151
|
+
# This object (exam) is the "input_object" for requirement.evaluate(...)
|
|
152
|
+
sets = _get_requirement_sets_for_exam(exam)
|
|
153
|
+
|
|
154
|
+
visited: Set[int] = set()
|
|
155
|
+
set_evals: List[RequirementSetEval] = [
|
|
156
|
+
_eval_set_tree(s, exam, visited) for s in sets
|
|
157
|
+
]
|
|
158
|
+
|
|
159
|
+
# Aggregate summary
|
|
160
|
+
overall = all(se.is_satisfied for se in set_evals) if set_evals else True
|
|
161
|
+
failed = sum(1 for se in set_evals if not se.is_satisfied)
|
|
162
|
+
|
|
163
|
+
return ExaminationEvalReport(
|
|
164
|
+
examination_id=exam.pk,
|
|
165
|
+
summary={
|
|
166
|
+
"is_satisfied": overall,
|
|
167
|
+
"failed_count": failed,
|
|
168
|
+
"total_sets": len(set_evals),
|
|
169
|
+
},
|
|
170
|
+
sets=set_evals,
|
|
171
|
+
errors=[], # fill with any global issues you detect
|
|
172
|
+
)
|
|
File without changes
|