endoreg-db 0.8.6.4__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/admin.py +92 -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 +18 -0
- endoreg_db/assets/dummy_model.ckpt +1 -0
- endoreg_db/codemods/readme.md +88 -0
- endoreg_db/codemods/rename_datetime_fields.py +92 -0
- endoreg_db/config/__init__.py +0 -0
- endoreg_db/config/env.py +101 -0
- endoreg_db/data/__init__.py +144 -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 +91 -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/examination/examinations/data.yaml +72 -0
- endoreg_db/data/examination/time/data.yaml +48 -0
- endoreg_db/data/examination/time-type/data.yaml +8 -0
- endoreg_db/data/examination/type/data.yaml +17 -0
- endoreg_db/data/examination_indication/endoscopy.yaml +424 -0
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +160 -0
- endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +101 -0
- endoreg_db/data/examination_requirement_set/colonoscopy.yaml +15 -0
- endoreg_db/data/finding/anatomy_colon.yaml +128 -0
- endoreg_db/data/finding/colonoscopy.yaml +40 -0
- endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +56 -0
- endoreg_db/data/finding/complication.yaml +16 -0
- endoreg_db/data/finding/data.yaml +105 -0
- endoreg_db/data/finding/examination_setting.yaml +16 -0
- endoreg_db/data/finding/medication_related.yaml +18 -0
- endoreg_db/data/finding/outcome.yaml +12 -0
- endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +95 -0
- endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +22 -0
- endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +25 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +20 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +24 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +68 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +20 -0
- endoreg_db/data/finding_classification/colonoscopy_location.yaml +80 -0
- endoreg_db/data/finding_classification/colonoscopy_lst.yaml +21 -0
- endoreg_db/data/finding_classification/colonoscopy_nice.yaml +20 -0
- endoreg_db/data/finding_classification/colonoscopy_paris.yaml +26 -0
- endoreg_db/data/finding_classification/colonoscopy_sano.yaml +22 -0
- endoreg_db/data/finding_classification/colonoscopy_summary.yaml +53 -0
- endoreg_db/data/finding_classification/complication_generic.yaml +25 -0
- endoreg_db/data/finding_classification/examination_setting_generic.yaml +40 -0
- endoreg_db/data/finding_classification/histology_colo.yaml +51 -0
- endoreg_db/data/finding_classification/intervention_required.yaml +26 -0
- endoreg_db/data/finding_classification/medication_related.yaml +23 -0
- endoreg_db/data/finding_classification/visualized.yaml +33 -0
- endoreg_db/data/finding_classification_choice/bowel_preparation.yaml +78 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_circularity_default.yaml +32 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +15 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +23 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +15 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_nice.yaml +17 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_paris.yaml +57 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_planarity_default.yaml +49 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +14 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_surface_intact_default.yaml +36 -0
- endoreg_db/data/finding_classification_choice/colonoscopy_location.yaml +229 -0
- endoreg_db/data/finding_classification_choice/colonoscopy_not_complete_reason.yaml +19 -0
- endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +82 -0
- endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +15 -0
- endoreg_db/data/finding_classification_choice/complication_generic_types.yaml +15 -0
- endoreg_db/data/finding_classification_choice/examination_setting_generic_types.yaml +15 -0
- endoreg_db/data/finding_classification_choice/histology.yaml +24 -0
- endoreg_db/data/finding_classification_choice/histology_polyp.yaml +20 -0
- endoreg_db/data/finding_classification_choice/outcome.yaml +19 -0
- endoreg_db/data/finding_classification_choice/yes_no_na.yaml +11 -0
- endoreg_db/data/finding_classification_type/colonoscopy_basic.yaml +48 -0
- endoreg_db/data/finding_intervention/endoscopy.yaml +43 -0
- endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +168 -0
- endoreg_db/data/finding_intervention/endoscopy_egd.yaml +128 -0
- endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +32 -0
- endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +9 -0
- endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +36 -0
- endoreg_db/data/finding_intervention_type/endoscopy.yaml +15 -0
- endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +79 -0
- endoreg_db/data/finding_type/data.yaml +43 -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/age.yaml +26 -0
- endoreg_db/data/requirement/colonoscopy_baseline_austria.yaml +45 -0
- endoreg_db/data/requirement/disease_cardiovascular.yaml +79 -0
- endoreg_db/data/requirement/disease_classification_choice_cardiovascular.yaml +41 -0
- endoreg_db/data/requirement/disease_hepatology.yaml +12 -0
- endoreg_db/data/requirement/disease_misc.yaml +12 -0
- endoreg_db/data/requirement/disease_renal.yaml +96 -0
- endoreg_db/data/requirement/endoscopy_bleeding_risk.yaml +59 -0
- endoreg_db/data/requirement/event_cardiology.yaml +251 -0
- endoreg_db/data/requirement/event_requirements.yaml +145 -0
- endoreg_db/data/requirement/finding_colon_polyp.yaml +50 -0
- endoreg_db/data/requirement/gender.yaml +25 -0
- endoreg_db/data/requirement/lab_value.yaml +441 -0
- endoreg_db/data/requirement/medication.yaml +93 -0
- endoreg_db/data/requirement_operator/age.yaml +13 -0
- endoreg_db/data/requirement_operator/lab_operators.yaml +129 -0
- endoreg_db/data/requirement_operator/model_operators.yaml +96 -0
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +48 -0
- endoreg_db/data/requirement_set/colonoscopy_austria_screening.yaml +57 -0
- endoreg_db/data/requirement_set/endoscopy_bleeding_risk.yaml +52 -0
- endoreg_db/data/requirement_set_type/data.yaml +20 -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 +11 -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 +19 -0
- endoreg_db/factories/__init__.py +0 -0
- endoreg_db/forms/__init__.py +5 -0
- endoreg_db/forms/examination_form.py +11 -0
- endoreg_db/forms/patient_finding_intervention_form.py +18 -0
- endoreg_db/forms/patient_form.py +27 -0
- endoreg_db/forms/questionnaires/__init__.py +1 -0
- endoreg_db/forms/questionnaires/tto_questionnaire.py +23 -0
- endoreg_db/forms/settings/__init__.py +8 -0
- endoreg_db/forms/unit.py +6 -0
- endoreg_db/helpers/__init__.py +0 -0
- endoreg_db/helpers/count_db.py +45 -0
- endoreg_db/helpers/data_loader.py +208 -0
- endoreg_db/helpers/default_objects.py +378 -0
- endoreg_db/helpers/download_segmentation_model.py +31 -0
- endoreg_db/helpers/interact.py +6 -0
- endoreg_db/helpers/test_video_helper.py +119 -0
- endoreg_db/logger_conf.py +140 -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 +125 -0
- endoreg_db/management/commands/create_model_meta_from_huggingface.py +115 -0
- endoreg_db/management/commands/create_multilabel_model_meta.py +214 -0
- endoreg_db/management/commands/fix_missing_patient_data.py +172 -0
- endoreg_db/management/commands/fix_video_paths.py +165 -0
- endoreg_db/management/commands/import_fallback_video.py +203 -0
- endoreg_db/management/commands/import_report.py +298 -0
- endoreg_db/management/commands/import_video.py +423 -0
- endoreg_db/management/commands/import_video_with_classification.py +367 -0
- endoreg_db/management/commands/init_default_ai_model.py +112 -0
- endoreg_db/management/commands/load_ai_model_data.py +77 -0
- endoreg_db/management/commands/load_ai_model_label_data.py +59 -0
- endoreg_db/management/commands/load_base_db_data.py +192 -0
- endoreg_db/management/commands/load_center_data.py +68 -0
- endoreg_db/management/commands/load_contraindication_data.py +41 -0
- endoreg_db/management/commands/load_disease_classification_choices_data.py +41 -0
- endoreg_db/management/commands/load_disease_classification_data.py +41 -0
- endoreg_db/management/commands/load_disease_data.py +62 -0
- endoreg_db/management/commands/load_distribution_data.py +66 -0
- endoreg_db/management/commands/load_endoscope_data.py +68 -0
- endoreg_db/management/commands/load_event_data.py +41 -0
- endoreg_db/management/commands/load_examination_data.py +75 -0
- endoreg_db/management/commands/load_examination_indication_data.py +86 -0
- endoreg_db/management/commands/load_finding_data.py +128 -0
- endoreg_db/management/commands/load_gender_data.py +44 -0
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +132 -0
- endoreg_db/management/commands/load_information_source.py +51 -0
- endoreg_db/management/commands/load_lab_value_data.py +50 -0
- endoreg_db/management/commands/load_medication_data.py +103 -0
- endoreg_db/management/commands/load_name_data.py +37 -0
- endoreg_db/management/commands/load_organ_data.py +43 -0
- endoreg_db/management/commands/load_pdf_type_data.py +61 -0
- endoreg_db/management/commands/load_profession_data.py +44 -0
- endoreg_db/management/commands/load_qualification_data.py +59 -0
- endoreg_db/management/commands/load_report_reader_flag_data.py +46 -0
- endoreg_db/management/commands/load_requirement_data.py +180 -0
- endoreg_db/management/commands/load_risk_data.py +56 -0
- endoreg_db/management/commands/load_shift_data.py +60 -0
- endoreg_db/management/commands/load_tag_data.py +57 -0
- endoreg_db/management/commands/load_unit_data.py +46 -0
- endoreg_db/management/commands/load_user_groups.py +28 -0
- endoreg_db/management/commands/register_ai_model.py +64 -0
- endoreg_db/management/commands/reset_celery_schedule.py +9 -0
- endoreg_db/management/commands/setup_endoreg_db.py +381 -0
- endoreg_db/management/commands/start_filewatcher.py +106 -0
- endoreg_db/management/commands/storage_management.py +548 -0
- endoreg_db/management/commands/summarize_db_content.py +189 -0
- endoreg_db/management/commands/validate_video.py +204 -0
- endoreg_db/management/commands/validate_video_files.py +161 -0
- endoreg_db/management/commands/video_validation.py +22 -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 +1857 -0
- endoreg_db/migrations/0002_add_video_correction_models.py +52 -0
- endoreg_db/migrations/0003_add_center_display_name.py +30 -0
- endoreg_db/migrations/__init__.py +0 -0
- endoreg_db/models/__init__.py +359 -0
- endoreg_db/models/administration/__init__.py +116 -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 +156 -0
- endoreg_db/models/administration/ai/model_type.py +41 -0
- endoreg_db/models/administration/case/__init__.py +19 -0
- endoreg_db/models/administration/case/case.py +114 -0
- endoreg_db/models/administration/case/case_template/__init__.py +15 -0
- endoreg_db/models/administration/case/case_template/case_template.py +125 -0
- endoreg_db/models/administration/case/case_template/case_template_rule.py +269 -0
- endoreg_db/models/administration/case/case_template/case_template_rule_value.py +86 -0
- endoreg_db/models/administration/case/case_template/case_template_type.py +26 -0
- endoreg_db/models/administration/center/__init__.py +13 -0
- endoreg_db/models/administration/center/center.py +67 -0
- endoreg_db/models/administration/center/center_product.py +64 -0
- endoreg_db/models/administration/center/center_resource.py +49 -0
- endoreg_db/models/administration/center/center_shift.py +88 -0
- endoreg_db/models/administration/center/center_waste.py +30 -0
- endoreg_db/models/administration/permissions/__init__.py +44 -0
- endoreg_db/models/administration/person/__init__.py +24 -0
- endoreg_db/models/administration/person/employee/__init__.py +3 -0
- endoreg_db/models/administration/person/employee/employee.py +35 -0
- endoreg_db/models/administration/person/employee/employee_qualification.py +39 -0
- endoreg_db/models/administration/person/employee/employee_type.py +42 -0
- endoreg_db/models/administration/person/examiner/__init__.py +4 -0
- endoreg_db/models/administration/person/examiner/examiner.py +54 -0
- endoreg_db/models/administration/person/names/__init__.py +0 -0
- endoreg_db/models/administration/person/names/first_name.py +18 -0
- endoreg_db/models/administration/person/names/last_name.py +19 -0
- endoreg_db/models/administration/person/patient/__init__.py +5 -0
- endoreg_db/models/administration/person/patient/patient.py +460 -0
- endoreg_db/models/administration/person/person.py +31 -0
- endoreg_db/models/administration/person/profession/__init__.py +24 -0
- endoreg_db/models/administration/person/user/__init__.py +5 -0
- endoreg_db/models/administration/person/user/portal_user_information.py +37 -0
- endoreg_db/models/administration/product/__init__.py +14 -0
- endoreg_db/models/administration/product/product.py +97 -0
- endoreg_db/models/administration/product/product_group.py +39 -0
- endoreg_db/models/administration/product/product_material.py +54 -0
- endoreg_db/models/administration/product/product_weight.py +47 -0
- endoreg_db/models/administration/product/reference_product.py +130 -0
- endoreg_db/models/administration/qualification/__init__.py +7 -0
- endoreg_db/models/administration/qualification/qualification.py +37 -0
- endoreg_db/models/administration/qualification/qualification_type.py +35 -0
- endoreg_db/models/administration/shift/__init__.py +9 -0
- endoreg_db/models/administration/shift/scheduled_days.py +69 -0
- endoreg_db/models/administration/shift/shift.py +51 -0
- endoreg_db/models/administration/shift/shift_type.py +108 -0
- endoreg_db/models/label/__init__.py +24 -0
- endoreg_db/models/label/annotation/__init__.py +12 -0
- endoreg_db/models/label/annotation/image_classification.py +84 -0
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +66 -0
- endoreg_db/models/label/label.py +83 -0
- endoreg_db/models/label/label_set.py +53 -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 +41 -0
- endoreg_db/models/label/label_video_segment/label_video_segment.py +511 -0
- endoreg_db/models/label/video_segmentation_label.py +31 -0
- endoreg_db/models/label/video_segmentation_labelset.py +27 -0
- endoreg_db/models/media/__init__.py +16 -0
- endoreg_db/models/media/frame/__init__.py +3 -0
- endoreg_db/models/media/frame/frame.py +111 -0
- endoreg_db/models/media/pdf/__init__.py +11 -0
- endoreg_db/models/media/pdf/raw_pdf.py +757 -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 +77 -0
- endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +20 -0
- endoreg_db/models/media/video/__init__.py +8 -0
- endoreg_db/models/media/video/create_from_file.py +358 -0
- endoreg_db/models/media/video/pipe_1.py +213 -0
- endoreg_db/models/media/video/pipe_2.py +105 -0
- endoreg_db/models/media/video/refactor_plan.md +0 -0
- endoreg_db/models/media/video/video_file.py +825 -0
- endoreg_db/models/media/video/video_file_ai.py +443 -0
- endoreg_db/models/media/video/video_file_anonymize.py +349 -0
- endoreg_db/models/media/video/video_file_frames/__init__.py +47 -0
- endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +22 -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 +104 -0
- endoreg_db/models/media/video/video_file_frames/_extract_frames.py +174 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame.py +28 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +27 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +20 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +27 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +34 -0
- endoreg_db/models/media/video/video_file_frames/_get_frames.py +27 -0
- endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +129 -0
- endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +141 -0
- endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +65 -0
- endoreg_db/models/media/video/video_file_frames.py +0 -0
- endoreg_db/models/media/video/video_file_io.py +168 -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 +45 -0
- endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +39 -0
- endoreg_db/models/media/video/video_file_meta/get_fps.py +147 -0
- endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +143 -0
- endoreg_db/models/media/video/video_file_meta/text_meta.py +134 -0
- endoreg_db/models/media/video/video_file_meta/video_meta.py +70 -0
- endoreg_db/models/media/video/video_file_segments.py +209 -0
- endoreg_db/models/media/video/video_metadata.py +65 -0
- endoreg_db/models/media/video/video_processing.py +152 -0
- endoreg_db/models/medical/__init__.py +146 -0
- endoreg_db/models/medical/contraindication/__init__.py +17 -0
- endoreg_db/models/medical/disease.py +156 -0
- endoreg_db/models/medical/event.py +137 -0
- endoreg_db/models/medical/examination/__init__.py +9 -0
- endoreg_db/models/medical/examination/examination.py +148 -0
- endoreg_db/models/medical/examination/examination_indication.py +278 -0
- endoreg_db/models/medical/examination/examination_time.py +49 -0
- endoreg_db/models/medical/examination/examination_time_type.py +41 -0
- endoreg_db/models/medical/examination/examination_type.py +48 -0
- endoreg_db/models/medical/finding/__init__.py +18 -0
- endoreg_db/models/medical/finding/finding.py +96 -0
- endoreg_db/models/medical/finding/finding_classification.py +142 -0
- endoreg_db/models/medical/finding/finding_intervention.py +52 -0
- endoreg_db/models/medical/finding/finding_type.py +35 -0
- endoreg_db/models/medical/hardware/__init__.py +8 -0
- endoreg_db/models/medical/hardware/endoscope.py +65 -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 +419 -0
- endoreg_db/models/medical/medication/__init__.py +19 -0
- endoreg_db/models/medical/medication/medication.py +31 -0
- endoreg_db/models/medical/medication/medication_indication.py +50 -0
- endoreg_db/models/medical/medication/medication_indication_type.py +39 -0
- endoreg_db/models/medical/medication/medication_intake_time.py +44 -0
- endoreg_db/models/medical/medication/medication_schedule.py +45 -0
- endoreg_db/models/medical/organ/__init__.py +35 -0
- endoreg_db/models/medical/patient/__init__.py +56 -0
- endoreg_db/models/medical/patient/medication_examples.py +38 -0
- endoreg_db/models/medical/patient/patient_disease.py +63 -0
- endoreg_db/models/medical/patient/patient_event.py +75 -0
- endoreg_db/models/medical/patient/patient_examination.py +249 -0
- endoreg_db/models/medical/patient/patient_examination_indication.py +44 -0
- endoreg_db/models/medical/patient/patient_finding.py +357 -0
- endoreg_db/models/medical/patient/patient_finding_classification.py +207 -0
- endoreg_db/models/medical/patient/patient_finding_intervention.py +40 -0
- endoreg_db/models/medical/patient/patient_lab_sample.py +148 -0
- endoreg_db/models/medical/patient/patient_lab_value.py +222 -0
- endoreg_db/models/medical/patient/patient_medication.py +104 -0
- endoreg_db/models/medical/patient/patient_medication_schedule.py +136 -0
- endoreg_db/models/medical/risk/__init__.py +7 -0
- endoreg_db/models/medical/risk/risk.py +72 -0
- endoreg_db/models/medical/risk/risk_type.py +51 -0
- endoreg_db/models/metadata/__init__.py +19 -0
- endoreg_db/models/metadata/frame_ocr_result.py +0 -0
- endoreg_db/models/metadata/model_meta.py +206 -0
- endoreg_db/models/metadata/model_meta_logic.py +343 -0
- endoreg_db/models/metadata/pdf_meta.py +89 -0
- endoreg_db/models/metadata/sensitive_meta.py +288 -0
- endoreg_db/models/metadata/sensitive_meta_logic.py +1048 -0
- endoreg_db/models/metadata/video_meta.py +332 -0
- endoreg_db/models/metadata/video_prediction_logic.py +190 -0
- endoreg_db/models/metadata/video_prediction_meta.py +270 -0
- endoreg_db/models/other/__init__.py +40 -0
- endoreg_db/models/other/distribution/__init__.py +44 -0
- endoreg_db/models/other/distribution/base_value_distribution.py +20 -0
- endoreg_db/models/other/distribution/date_value_distribution.py +89 -0
- endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +32 -0
- endoreg_db/models/other/distribution/numeric_value_distribution.py +125 -0
- endoreg_db/models/other/distribution/single_categorical_value_distribution.py +22 -0
- endoreg_db/models/other/emission/__init__.py +5 -0
- endoreg_db/models/other/emission/emission_factor.py +94 -0
- endoreg_db/models/other/gender.py +27 -0
- endoreg_db/models/other/information_source.py +159 -0
- endoreg_db/models/other/material.py +28 -0
- endoreg_db/models/other/resource.py +22 -0
- endoreg_db/models/other/tag.py +27 -0
- endoreg_db/models/other/transport_route.py +33 -0
- endoreg_db/models/other/unit.py +32 -0
- endoreg_db/models/other/waste.py +27 -0
- endoreg_db/models/requirement/__init__.py +11 -0
- endoreg_db/models/requirement/requirement.py +767 -0
- endoreg_db/models/requirement/requirement_evaluation/__init__.py +6 -0
- endoreg_db/models/requirement/requirement_evaluation/get_values.py +40 -0
- endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +9 -0
- endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +95 -0
- endoreg_db/models/requirement/requirement_operator.py +176 -0
- endoreg_db/models/requirement/requirement_set.py +287 -0
- endoreg_db/models/rule/__init__.py +13 -0
- endoreg_db/models/rule/rule.py +27 -0
- endoreg_db/models/rule/rule_applicator.py +224 -0
- endoreg_db/models/rule/rule_attribute_dtype.py +17 -0
- endoreg_db/models/rule/rule_type.py +20 -0
- endoreg_db/models/rule/ruleset.py +17 -0
- endoreg_db/models/state/__init__.py +12 -0
- endoreg_db/models/state/abstract.py +11 -0
- endoreg_db/models/state/audit_ledger.py +150 -0
- endoreg_db/models/state/label_video_segment.py +22 -0
- endoreg_db/models/state/raw_pdf.py +187 -0
- endoreg_db/models/state/sensitive_meta.py +46 -0
- endoreg_db/models/state/video.py +232 -0
- endoreg_db/models/upload_job.py +99 -0
- endoreg_db/models/utils.py +135 -0
- endoreg_db/queries/__init__.py +5 -0
- endoreg_db/queries/annotations/__init__.py +3 -0
- endoreg_db/queries/annotations/legacy.py +158 -0
- endoreg_db/queries/sanity/__init_.py +0 -0
- endoreg_db/renames.yml +8 -0
- endoreg_db/root_urls.py +9 -0
- endoreg_db/schemas/__init__.py +0 -0
- endoreg_db/schemas/examination_evaluation.py +27 -0
- endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +775 -0
- endoreg_db/serializers/__init__.py +118 -0
- endoreg_db/serializers/_old/raw_pdf_meta_validation.py +223 -0
- endoreg_db/serializers/_old/raw_video_meta_validation.py +179 -0
- endoreg_db/serializers/_old/video.py +71 -0
- endoreg_db/serializers/administration/__init__.py +14 -0
- endoreg_db/serializers/administration/ai/__init__.py +10 -0
- endoreg_db/serializers/administration/ai/active_model.py +10 -0
- endoreg_db/serializers/administration/ai/ai_model.py +18 -0
- endoreg_db/serializers/administration/ai/model_type.py +10 -0
- endoreg_db/serializers/administration/center.py +9 -0
- endoreg_db/serializers/administration/gender.py +9 -0
- endoreg_db/serializers/anonymization.py +69 -0
- endoreg_db/serializers/evaluation/examination_evaluation.py +1 -0
- endoreg_db/serializers/examination/__init__.py +10 -0
- endoreg_db/serializers/examination/base.py +46 -0
- endoreg_db/serializers/examination/dropdown.py +21 -0
- endoreg_db/serializers/examination_serializer.py +12 -0
- endoreg_db/serializers/finding/__init__.py +5 -0
- endoreg_db/serializers/finding/finding.py +54 -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 +13 -0
- endoreg_db/serializers/label/__init__.py +7 -0
- endoreg_db/serializers/label/image_classification_annotation.py +62 -0
- endoreg_db/serializers/label/label.py +15 -0
- endoreg_db/serializers/label_video_segment/__init__.py +7 -0
- endoreg_db/serializers/label_video_segment/_lvs_create.py +149 -0
- endoreg_db/serializers/label_video_segment/_lvs_update.py +138 -0
- endoreg_db/serializers/label_video_segment/_lvs_validate.py +149 -0
- endoreg_db/serializers/label_video_segment/label_video_segment.py +344 -0
- endoreg_db/serializers/label_video_segment/label_video_segment_annotation.py +99 -0
- endoreg_db/serializers/label_video_segment/label_video_segment_update.py +163 -0
- endoreg_db/serializers/meta/__init__.py +19 -0
- endoreg_db/serializers/meta/pdf_file_meta_extraction.py +115 -0
- endoreg_db/serializers/meta/report_meta.py +53 -0
- endoreg_db/serializers/meta/sensitive_meta_detail.py +162 -0
- endoreg_db/serializers/meta/sensitive_meta_update.py +148 -0
- endoreg_db/serializers/meta/sensitive_meta_verification.py +59 -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 +182 -0
- endoreg_db/serializers/misc/sensitive_patient_data.py +120 -0
- endoreg_db/serializers/misc/stats.py +33 -0
- endoreg_db/serializers/misc/translatable_field_mix_in.py +44 -0
- endoreg_db/serializers/misc/upload_job.py +71 -0
- endoreg_db/serializers/patient/__init__.py +11 -0
- endoreg_db/serializers/patient/patient.py +86 -0
- endoreg_db/serializers/patient/patient_dropdown.py +27 -0
- endoreg_db/serializers/patient_examination/__init__.py +7 -0
- endoreg_db/serializers/patient_examination/patient_examination.py +141 -0
- endoreg_db/serializers/patient_finding/__init__.py +15 -0
- endoreg_db/serializers/patient_finding/patient_finding.py +31 -0
- endoreg_db/serializers/patient_finding/patient_finding_classification.py +39 -0
- endoreg_db/serializers/patient_finding/patient_finding_detail.py +53 -0
- endoreg_db/serializers/patient_finding/patient_finding_intervention.py +26 -0
- endoreg_db/serializers/patient_finding/patient_finding_list.py +41 -0
- endoreg_db/serializers/patient_finding/patient_finding_write.py +126 -0
- endoreg_db/serializers/pdf/__init__.py +5 -0
- endoreg_db/serializers/pdf/anony_text_validation.py +85 -0
- endoreg_db/serializers/report/__init__.py +9 -0
- endoreg_db/serializers/report/mixins.py +45 -0
- endoreg_db/serializers/report/report.py +105 -0
- endoreg_db/serializers/report/report_list.py +22 -0
- endoreg_db/serializers/report/secure_file_url.py +26 -0
- endoreg_db/serializers/requirements/requirement_schema.py +25 -0
- endoreg_db/serializers/requirements/requirement_sets.py +29 -0
- endoreg_db/serializers/sensitive_meta_serializer.py +282 -0
- endoreg_db/serializers/video/__init__.py +7 -0
- endoreg_db/serializers/video/segmentation.py +263 -0
- endoreg_db/serializers/video/video_file_brief.py +10 -0
- endoreg_db/serializers/video/video_file_detail.py +83 -0
- endoreg_db/serializers/video/video_file_list.py +67 -0
- endoreg_db/serializers/video/video_metadata.py +105 -0
- endoreg_db/serializers/video/video_processing_history.py +153 -0
- endoreg_db/serializers/video_examination.py +198 -0
- endoreg_db/services/__init__.py +5 -0
- endoreg_db/services/anonymization.py +223 -0
- endoreg_db/services/examination_evaluation.py +149 -0
- endoreg_db/services/finding_description_service.py +0 -0
- endoreg_db/services/lookup_service.py +411 -0
- endoreg_db/services/lookup_store.py +266 -0
- endoreg_db/services/pdf_import.py +1382 -0
- endoreg_db/services/polling_coordinator.py +288 -0
- endoreg_db/services/pseudonym_service.py +89 -0
- endoreg_db/services/requirements_object.py +147 -0
- endoreg_db/services/segment_sync.py +155 -0
- endoreg_db/services/storage_aware_video_processor.py +344 -0
- endoreg_db/services/video_import.py +1259 -0
- endoreg_db/tasks/upload_tasks.py +207 -0
- endoreg_db/tasks/video_ingest.py +157 -0
- endoreg_db/tasks/video_processing_tasks.py +327 -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 +83 -0
- endoreg_db/urls/anonymization.py +32 -0
- endoreg_db/urls/auth.py +16 -0
- endoreg_db/urls/classification.py +39 -0
- endoreg_db/urls/examination.py +54 -0
- endoreg_db/urls/files.py +6 -0
- endoreg_db/urls/label_video_segment_validate.py +33 -0
- endoreg_db/urls/label_video_segments.py +46 -0
- endoreg_db/urls/media.py +227 -0
- endoreg_db/urls/patient.py +19 -0
- endoreg_db/urls/report.py +48 -0
- endoreg_db/urls/requirements.py +13 -0
- endoreg_db/urls/sensitive_meta.py +0 -0
- endoreg_db/urls/stats.py +46 -0
- endoreg_db/urls/upload.py +20 -0
- endoreg_db/urls/video.py +61 -0
- endoreg_db/urls.py +9 -0
- endoreg_db/utils/__init__.py +88 -0
- endoreg_db/utils/ai/__init__.py +9 -0
- endoreg_db/utils/ai/get.py +5 -0
- endoreg_db/utils/ai/inference_dataset.py +52 -0
- endoreg_db/utils/ai/multilabel_classification_net.py +159 -0
- endoreg_db/utils/ai/postprocess.py +63 -0
- endoreg_db/utils/ai/predict.py +291 -0
- endoreg_db/utils/ai/preprocess.py +68 -0
- endoreg_db/utils/calc_duration_seconds.py +24 -0
- endoreg_db/utils/case_generator/__init__.py +0 -0
- endoreg_db/utils/case_generator/case_generator.py +159 -0
- endoreg_db/utils/case_generator/lab_sample_factory.py +33 -0
- endoreg_db/utils/case_generator/utils.py +30 -0
- endoreg_db/utils/check_video_files.py +148 -0
- endoreg_db/utils/cropping.py +29 -0
- endoreg_db/utils/dataloader.py +175 -0
- endoreg_db/utils/dates.py +60 -0
- endoreg_db/utils/env.py +33 -0
- endoreg_db/utils/extract_specific_frames.py +72 -0
- endoreg_db/utils/file_operations.py +58 -0
- endoreg_db/utils/fix_video_path_direct.py +141 -0
- endoreg_db/utils/frame_anonymization_utils.py +463 -0
- endoreg_db/utils/hashs.py +153 -0
- endoreg_db/utils/links/__init__.py +0 -0
- endoreg_db/utils/links/requirement_link.py +193 -0
- endoreg_db/utils/mime_types.py +0 -0
- endoreg_db/utils/names.py +76 -0
- endoreg_db/utils/ocr.py +190 -0
- endoreg_db/utils/parse_and_generate_yaml.py +46 -0
- endoreg_db/utils/paths.py +95 -0
- endoreg_db/utils/permissions.py +143 -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 +120 -0
- endoreg_db/utils/product/__init__.py +0 -0
- endoreg_db/utils/product/sum_emissions.py +20 -0
- endoreg_db/utils/product/sum_weights.py +18 -0
- endoreg_db/utils/pydantic_models/__init__.py +6 -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/lab_value_operators.py +578 -0
- endoreg_db/utils/requirement_operator_logic/model_evaluators.py +368 -0
- endoreg_db/utils/setup_config.py +177 -0
- endoreg_db/utils/translation.py +27 -0
- endoreg_db/utils/uuid.py +4 -0
- endoreg_db/utils/validate_endo_roi.py +19 -0
- endoreg_db/utils/validate_subcategory_dict.py +91 -0
- endoreg_db/utils/validate_video_detailed.py +357 -0
- endoreg_db/utils/video/__init__.py +26 -0
- endoreg_db/utils/video/extract_frames.py +88 -0
- endoreg_db/utils/video/ffmpeg_wrapper.py +835 -0
- endoreg_db/utils/video/names.py +42 -0
- endoreg_db/utils/video/streaming_processor.py +312 -0
- endoreg_db/utils/video/video_splitter.py +94 -0
- endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +238 -0
- endoreg_db/views/__init__.py +274 -0
- endoreg_db/views/anonymization/__init__.py +27 -0
- endoreg_db/views/anonymization/media_management.py +454 -0
- endoreg_db/views/anonymization/overview.py +216 -0
- endoreg_db/views/anonymization/validate.py +107 -0
- endoreg_db/views/auth/__init__.py +13 -0
- endoreg_db/views/auth/keycloak.py +113 -0
- endoreg_db/views/examination/__init__.py +33 -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 +59 -0
- endoreg_db/views/examination/get_finding_classifications.py +36 -0
- endoreg_db/views/examination/get_findings.py +41 -0
- endoreg_db/views/examination/get_instruments.py +18 -0
- endoreg_db/views/examination/get_interventions.py +14 -0
- endoreg_db/views/finding/__init__.py +9 -0
- endoreg_db/views/finding/finding.py +112 -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 +42 -0
- endoreg_db/views/finding_classification/get_classification_choices.py +55 -0
- endoreg_db/views/label/__init__.py +5 -0
- endoreg_db/views/label/label.py +15 -0
- endoreg_db/views/label_video_segment/__init__.py +16 -0
- endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +44 -0
- endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +50 -0
- endoreg_db/views/label_video_segment/label_video_segment.py +77 -0
- endoreg_db/views/label_video_segment/label_video_segment_by_label.py +174 -0
- endoreg_db/views/label_video_segment/label_video_segment_detail.py +73 -0
- endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +46 -0
- endoreg_db/views/label_video_segment/validate.py +226 -0
- endoreg_db/views/media/__init__.py +45 -0
- endoreg_db/views/media/pdf_media.py +388 -0
- endoreg_db/views/media/segments.py +71 -0
- endoreg_db/views/media/sensitive_metadata.py +314 -0
- endoreg_db/views/media/video_media.py +272 -0
- endoreg_db/views/media/video_segments.py +524 -0
- endoreg_db/views/meta/__init__.py +15 -0
- endoreg_db/views/meta/available_files_list.py +146 -0
- endoreg_db/views/meta/report_meta.py +53 -0
- endoreg_db/views/meta/sensitive_meta_detail.py +148 -0
- endoreg_db/views/meta/sensitive_meta_list.py +104 -0
- endoreg_db/views/meta/sensitive_meta_verification.py +71 -0
- endoreg_db/views/misc/__init__.py +63 -0
- endoreg_db/views/misc/center.py +13 -0
- endoreg_db/views/misc/csrf.py +7 -0
- endoreg_db/views/misc/gender.py +14 -0
- endoreg_db/views/misc/secure_file_serving_view.py +80 -0
- endoreg_db/views/misc/secure_file_url_view.py +84 -0
- endoreg_db/views/misc/secure_url_validate.py +79 -0
- endoreg_db/views/misc/stats.py +220 -0
- endoreg_db/views/misc/translation.py +182 -0
- endoreg_db/views/misc/upload_views.py +240 -0
- endoreg_db/views/patient/__init__.py +5 -0
- endoreg_db/views/patient/patient.py +210 -0
- endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +164 -0
- endoreg_db/views/patient_examination/__init__.py +11 -0
- endoreg_db/views/patient_examination/patient_examination.py +140 -0
- endoreg_db/views/patient_examination/patient_examination_create.py +63 -0
- endoreg_db/views/patient_examination/patient_examination_detail.py +66 -0
- endoreg_db/views/patient_examination/patient_examination_list.py +68 -0
- endoreg_db/views/patient_examination/video.py +194 -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 +64 -0
- endoreg_db/views/patient_finding/patient_finding_optimized.py +259 -0
- endoreg_db/views/patient_finding_classification/__init__.py +5 -0
- endoreg_db/views/patient_finding_classification/pfc_create.py +67 -0
- endoreg_db/views/patient_finding_location/__init__.py +5 -0
- endoreg_db/views/patient_finding_location/pfl_create.py +70 -0
- endoreg_db/views/patient_finding_morphology/__init__.py +5 -0
- endoreg_db/views/patient_finding_morphology/pfm_create.py +70 -0
- endoreg_db/views/pdf/__init__.py +8 -0
- endoreg_db/views/pdf/pdf_stream.py +186 -0
- endoreg_db/views/pdf/reimport.py +177 -0
- endoreg_db/views/report/__init__.py +9 -0
- endoreg_db/views/report/report_list.py +112 -0
- endoreg_db/views/report/report_with_secure_url.py +28 -0
- endoreg_db/views/report/start_examination.py +7 -0
- endoreg_db/views/requirement/__init__.py +10 -0
- endoreg_db/views/requirement/evaluate.py +279 -0
- endoreg_db/views/requirement/lookup.py +367 -0
- endoreg_db/views/requirement/lookup_store.py +252 -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 +229 -0
- endoreg_db/views/video/__init__.py +59 -0
- endoreg_db/views/video/correction.py +530 -0
- endoreg_db/views/video/reimport.py +195 -0
- endoreg_db/views/video/segmentation.py +274 -0
- endoreg_db/views/video/task_status.py +49 -0
- endoreg_db/views/video/timeline.py +46 -0
- endoreg_db/views/video/video_analyze.py +52 -0
- endoreg_db/views/video/video_apply_mask.py +48 -0
- endoreg_db/views/video/video_correction.py +21 -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_meta.py +29 -0
- endoreg_db/views/video/video_processing_history.py +24 -0
- endoreg_db/views/video/video_remove_frames.py +48 -0
- endoreg_db/views/video/video_stream.py +306 -0
- endoreg_db/views.py +0 -0
- endoreg_db-0.8.6.4.dist-info/METADATA +383 -0
- endoreg_db-0.8.6.4.dist-info/RECORD +793 -0
- endoreg_db-0.8.6.4.dist-info/WHEEL +4 -0
- endoreg_db-0.8.6.4.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
from .abstract import AbstractState
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
class SensitiveMetaState(AbstractState):
|
|
6
|
+
"""State for sensitive meta data."""
|
|
7
|
+
|
|
8
|
+
dob_verified = models.BooleanField(default=False)
|
|
9
|
+
names_verified = models.BooleanField(default=False)
|
|
10
|
+
|
|
11
|
+
origin = models.OneToOneField(
|
|
12
|
+
"SensitiveMeta",
|
|
13
|
+
on_delete=models.CASCADE,
|
|
14
|
+
related_name="state",
|
|
15
|
+
null=True,
|
|
16
|
+
blank=True,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from endoreg_db.models import SensitiveMeta
|
|
21
|
+
|
|
22
|
+
origin: "SensitiveMeta"
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def is_verified(self) -> bool:
|
|
26
|
+
"""
|
|
27
|
+
Return True if both date of birth and names have been verified; otherwise, return False.
|
|
28
|
+
"""
|
|
29
|
+
return self.dob_verified and self.names_verified
|
|
30
|
+
|
|
31
|
+
def mark_dob_verified(self):
|
|
32
|
+
"""
|
|
33
|
+
Set the date of birth verification status to True and persist the change to the database.
|
|
34
|
+
"""
|
|
35
|
+
self.dob_verified = True
|
|
36
|
+
self.save(update_fields=["dob_verified"])
|
|
37
|
+
|
|
38
|
+
def mark_names_verified(self):
|
|
39
|
+
"""
|
|
40
|
+
Mark the names as verified and persist the change to the database.
|
|
41
|
+
"""
|
|
42
|
+
self.names_verified = True
|
|
43
|
+
self.save(update_fields=["names_verified"])
|
|
44
|
+
class Meta:
|
|
45
|
+
verbose_name = "Sensitive Meta State"
|
|
46
|
+
verbose_name_plural = "Sensitive Meta States"
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Defines state tracking models related to video processing.
|
|
3
|
+
"""
|
|
4
|
+
from django.db import models
|
|
5
|
+
from .abstract import AbstractState
|
|
6
|
+
from typing import TYPE_CHECKING, Optional
|
|
7
|
+
import logging
|
|
8
|
+
from enum import Enum
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from ..media import VideoFile
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AnonymizationStatus(str, Enum):
|
|
17
|
+
NOT_STARTED = "not_started"
|
|
18
|
+
EXTRACTING_FRAMES = "extracting_frames"
|
|
19
|
+
PROCESSING_ANONYMIZING = "processing_anonymization"
|
|
20
|
+
DONE = "done"
|
|
21
|
+
VALIDATED = "validated"
|
|
22
|
+
FAILED = "failed"
|
|
23
|
+
STARTED = "started"
|
|
24
|
+
|
|
25
|
+
class VideoState(models.Model):
|
|
26
|
+
"""
|
|
27
|
+
Tracks the processing state of a VideoFile instance.
|
|
28
|
+
Uses BooleanFields for clear, distinct states.
|
|
29
|
+
"""
|
|
30
|
+
# Frame related states
|
|
31
|
+
if TYPE_CHECKING:
|
|
32
|
+
video_file: Optional["VideoFile"]
|
|
33
|
+
|
|
34
|
+
frames_extracted = models.BooleanField(default=False, help_text="True if raw frames have been extracted to files.")
|
|
35
|
+
frames_initialized = models.BooleanField(default=False, help_text="True if Frame DB objects have been created.")
|
|
36
|
+
frame_count = models.PositiveIntegerField(null=True, blank=True, help_text="Number of frames extracted/initialized.")
|
|
37
|
+
|
|
38
|
+
# Metadata related states
|
|
39
|
+
video_meta_extracted = models.BooleanField(default=False, help_text="True if VideoMeta (technical specs) has been extracted.")
|
|
40
|
+
text_meta_extracted = models.BooleanField(default=False, help_text="True if text metadata (OCR) has been extracted.")
|
|
41
|
+
|
|
42
|
+
# AI / Annotation related states
|
|
43
|
+
initial_prediction_completed = models.BooleanField(default=False, help_text="True if initial AI prediction has run.")
|
|
44
|
+
lvs_created = models.BooleanField(default=False, help_text="True if LabelVideoSegments have been created from predictions.")
|
|
45
|
+
frame_annotations_generated = models.BooleanField(default=False, help_text="True if frame-level annotations have been generated from segments.")
|
|
46
|
+
|
|
47
|
+
# Processing state
|
|
48
|
+
sensitive_meta_processed = models.BooleanField(default=False, help_text="True if the video has been fully processed, meaning a anonymized person was created.")
|
|
49
|
+
|
|
50
|
+
# Anonymization state
|
|
51
|
+
anonymized = models.BooleanField(default=False, help_text="True if the anonymized video file has been created.")
|
|
52
|
+
anonymization_validated = models.BooleanField(default=False, help_text="True if the anonymization process has been validated and confirmed.")
|
|
53
|
+
anonymization_status: AnonymizationStatus
|
|
54
|
+
|
|
55
|
+
processing_started = models.BooleanField(default=False, help_text="True if the processing has started, but not yet completed.")
|
|
56
|
+
|
|
57
|
+
# Timestamps
|
|
58
|
+
date_created = models.DateTimeField(auto_now_add=True)
|
|
59
|
+
date_modified = models.DateTimeField(auto_now=True)
|
|
60
|
+
|
|
61
|
+
# Segment Annotation State
|
|
62
|
+
segment_annotations_created = models.BooleanField(default=False, help_text="True if segment annotations have been created from LabelVideoSegments.")
|
|
63
|
+
segment_annotations_validated = models.BooleanField(default=False, help_text="True if segment annotations have been validated.")
|
|
64
|
+
|
|
65
|
+
was_created = models.BooleanField(default=True, help_text="True if this state was created for the first time.")
|
|
66
|
+
|
|
67
|
+
objects = models.Manager()
|
|
68
|
+
|
|
69
|
+
def __str__(self):
|
|
70
|
+
# Find the related VideoFile's UUID if possible
|
|
71
|
+
video_uuid = "Unknown"
|
|
72
|
+
try:
|
|
73
|
+
# Access the related VideoFile via the reverse relation 'video_file'
|
|
74
|
+
if hasattr(self, 'video_file') and self.video_file:
|
|
75
|
+
video_uuid = self.video_file.uuid
|
|
76
|
+
except Exception:
|
|
77
|
+
pass # Ignore errors if relation doesn't exist or causes issues
|
|
78
|
+
|
|
79
|
+
states = [
|
|
80
|
+
f"FramesExtracted={self.frames_extracted}",
|
|
81
|
+
f"FramesInit={self.frames_initialized}",
|
|
82
|
+
f"VideoMetaExtracted={self.video_meta_extracted}",
|
|
83
|
+
f"TextMetaExtracted={self.text_meta_extracted}",
|
|
84
|
+
f"PredictionDone={self.initial_prediction_completed}",
|
|
85
|
+
f"LvsCreated={self.lvs_created}",
|
|
86
|
+
f"Anonymized={self.anonymized}",
|
|
87
|
+
f"AnonymizationValidated={self.anonymization_validated}",
|
|
88
|
+
f"SensitiveMetaProcessed={self.sensitive_meta_processed}",
|
|
89
|
+
f"FrameCount={self.frame_count}" if self.frame_count is not None else "FrameCount=None",
|
|
90
|
+
f"SegmentAnnotationsCreated={self.segment_annotations_created}",
|
|
91
|
+
f"SegmentAnnotationsValidated={self.segment_annotations_validated}",
|
|
92
|
+
f"DateCreated={self.date_created.isoformat()}",
|
|
93
|
+
f"DateModified={self.date_modified.isoformat()}"
|
|
94
|
+
]
|
|
95
|
+
return f"VideoState(Video:{video_uuid}): {', '.join(states)}"
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def anonymization_status(self) -> AnonymizationStatus:
|
|
99
|
+
"""
|
|
100
|
+
Fast, side‑effect‑free status resolution used by API & UI.
|
|
101
|
+
"""
|
|
102
|
+
if self.anonymization_validated:
|
|
103
|
+
return AnonymizationStatus.VALIDATED
|
|
104
|
+
if self.sensitive_meta_processed:
|
|
105
|
+
return AnonymizationStatus.DONE
|
|
106
|
+
if self.frames_extracted and not self.anonymized:
|
|
107
|
+
return AnonymizationStatus.PROCESSING_ANONYMIZING
|
|
108
|
+
if self.was_created and not self.frames_extracted:
|
|
109
|
+
return AnonymizationStatus.EXTRACTING_FRAMES
|
|
110
|
+
if getattr(self, "processing_error", False):
|
|
111
|
+
return AnonymizationStatus.FAILED
|
|
112
|
+
if self.processing_started:
|
|
113
|
+
return AnonymizationStatus.STARTED
|
|
114
|
+
return AnonymizationStatus.NOT_STARTED
|
|
115
|
+
|
|
116
|
+
# ---- Single‑responsibility mutators ---------------------------------
|
|
117
|
+
def mark_sensitive_meta_processed(self, *, save: bool = True) -> None:
|
|
118
|
+
self.sensitive_meta_processed = True
|
|
119
|
+
if save:
|
|
120
|
+
self.save(update_fields=["sensitive_meta_processed", "date_modified"])
|
|
121
|
+
|
|
122
|
+
def mark_anonymization_validated(self, *, save: bool = True) -> None:
|
|
123
|
+
"""
|
|
124
|
+
Mark the anonymization process as validated for this video state.
|
|
125
|
+
|
|
126
|
+
Parameters:
|
|
127
|
+
save (bool): If True, persist the change to the database immediately.
|
|
128
|
+
"""
|
|
129
|
+
self.anonymization_validated = True
|
|
130
|
+
if save:
|
|
131
|
+
self.save(update_fields=["anonymization_validated", "date_modified"])
|
|
132
|
+
|
|
133
|
+
def mark_frames_extracted(self, *, save: bool = True) -> None:
|
|
134
|
+
"""
|
|
135
|
+
Mark the video as having its frames extracted.
|
|
136
|
+
|
|
137
|
+
Parameters:
|
|
138
|
+
save (bool): If True, persist the change to the database immediately.
|
|
139
|
+
"""
|
|
140
|
+
self.frames_extracted = True
|
|
141
|
+
if save:
|
|
142
|
+
self.save(update_fields=["frames_extracted", "date_modified"])
|
|
143
|
+
|
|
144
|
+
def mark_frames_not_extracted(self, *, save: bool = True) -> None:
|
|
145
|
+
"""
|
|
146
|
+
Mark the video as having no extracted frames.
|
|
147
|
+
|
|
148
|
+
If `save` is True, updates the database record for this state.
|
|
149
|
+
"""
|
|
150
|
+
self.frames_extracted = False
|
|
151
|
+
if save:
|
|
152
|
+
self.save(update_fields=["frames_extracted", "date_modified"])
|
|
153
|
+
|
|
154
|
+
def mark_anonymized(self, *, save: bool = True) -> None:
|
|
155
|
+
"""
|
|
156
|
+
Mark the video as anonymized by setting the anonymized flag to True.
|
|
157
|
+
|
|
158
|
+
Parameters:
|
|
159
|
+
save (bool): If True, immediately saves the updated state to the database.
|
|
160
|
+
"""
|
|
161
|
+
self.anonymized = True
|
|
162
|
+
if save:
|
|
163
|
+
self.save(update_fields=["anonymized", "date_modified"])
|
|
164
|
+
|
|
165
|
+
def mark_initial_prediction_completed(self, *, save: bool = True) -> None:
|
|
166
|
+
"""
|
|
167
|
+
Mark the initial AI prediction as completed for this video state.
|
|
168
|
+
|
|
169
|
+
Parameters:
|
|
170
|
+
save (bool): If True, persist the change to the database immediately.
|
|
171
|
+
"""
|
|
172
|
+
self.initial_prediction_completed = True
|
|
173
|
+
if save:
|
|
174
|
+
self.save(update_fields=["initial_prediction_completed", "date_modified"])
|
|
175
|
+
|
|
176
|
+
def mark_video_meta_extracted(self, *, save: bool = True) -> None:
|
|
177
|
+
"""
|
|
178
|
+
Mark the video metadata as extracted for this video state.
|
|
179
|
+
|
|
180
|
+
Parameters:
|
|
181
|
+
save (bool): If True, immediately saves the updated state to the database.
|
|
182
|
+
"""
|
|
183
|
+
self.video_meta_extracted = True
|
|
184
|
+
if save:
|
|
185
|
+
self.save(update_fields=["video_meta_extracted", "date_modified"])
|
|
186
|
+
|
|
187
|
+
def mark_text_meta_extracted(self, *, save: bool = True) -> None:
|
|
188
|
+
"""
|
|
189
|
+
Mark the video as having its text metadata extracted.
|
|
190
|
+
|
|
191
|
+
Parameters:
|
|
192
|
+
save (bool): If True, immediately saves the updated state to the database.
|
|
193
|
+
"""
|
|
194
|
+
self.text_meta_extracted = True
|
|
195
|
+
if save:
|
|
196
|
+
self.save(update_fields=["text_meta_extracted", "date_modified"])
|
|
197
|
+
|
|
198
|
+
def get_or_create_state(self):
|
|
199
|
+
"""
|
|
200
|
+
Get the current state of the video, or create a new one if it doesn't exist.
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
VideoState: The current or newly created state.
|
|
204
|
+
"""
|
|
205
|
+
if not hasattr(self, 'video_file'):
|
|
206
|
+
raise ValueError("This method requires a related VideoFile instance.")
|
|
207
|
+
|
|
208
|
+
# If the state already exists, return it
|
|
209
|
+
if self.video_file.state:
|
|
210
|
+
return self.video_file.state
|
|
211
|
+
|
|
212
|
+
# Otherwise, create a new state
|
|
213
|
+
new_state = VideoState(video_file=self.video_file)
|
|
214
|
+
new_state.save()
|
|
215
|
+
return new_state
|
|
216
|
+
|
|
217
|
+
def mark_processing_started(self, *, save: bool = True) -> None:
|
|
218
|
+
"""
|
|
219
|
+
Mark the processing as started for this video state.
|
|
220
|
+
|
|
221
|
+
Parameters:
|
|
222
|
+
save (bool): If True, immediately saves the updated state to the database.
|
|
223
|
+
"""
|
|
224
|
+
self.processing_started = True
|
|
225
|
+
if save:
|
|
226
|
+
self.save(update_fields=["processing_started", "date_modified"])
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
class Meta:
|
|
231
|
+
verbose_name = "Video Processing State"
|
|
232
|
+
verbose_name_plural = "Video Processing States"
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
from django.db import models
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class UploadJob(models.Model):
|
|
6
|
+
"""
|
|
7
|
+
Tracks file upload jobs and their processing status.
|
|
8
|
+
Supports both PDF and video file uploads with asynchronous processing.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
class Status(models.TextChoices):
|
|
12
|
+
PENDING = 'pending', 'Pending'
|
|
13
|
+
PROCESSING = 'processing', 'Processing'
|
|
14
|
+
ANONYMIZED = 'anonymized', 'Anonymized'
|
|
15
|
+
ERROR = 'error', 'Error'
|
|
16
|
+
|
|
17
|
+
id = models.UUIDField(
|
|
18
|
+
primary_key=True,
|
|
19
|
+
default=uuid.uuid4,
|
|
20
|
+
editable=False,
|
|
21
|
+
help_text="Unique identifier for the upload job"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
file = models.FileField(
|
|
25
|
+
upload_to='uploads/%Y/%m/%d/',
|
|
26
|
+
help_text="Uploaded file (PDF or video)"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
status = models.CharField(
|
|
30
|
+
max_length=20,
|
|
31
|
+
choices=Status.choices,
|
|
32
|
+
default=Status.PENDING,
|
|
33
|
+
help_text="Current processing status of the upload"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
content_type = models.CharField(
|
|
37
|
+
max_length=100,
|
|
38
|
+
blank=True,
|
|
39
|
+
help_text="MIME type of the uploaded file"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
sensitive_meta = models.ForeignKey(
|
|
43
|
+
'SensitiveMeta',
|
|
44
|
+
null=True,
|
|
45
|
+
blank=True,
|
|
46
|
+
on_delete=models.SET_NULL,
|
|
47
|
+
help_text="Link to the created SensitiveMeta record after processing"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
error_detail = models.TextField(
|
|
51
|
+
blank=True,
|
|
52
|
+
help_text="Error message if processing failed"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
created_at = models.DateTimeField(
|
|
56
|
+
auto_now_add=True,
|
|
57
|
+
help_text="When the upload job was created"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
updated_at = models.DateTimeField(
|
|
61
|
+
auto_now=True,
|
|
62
|
+
help_text="When the upload job was last updated"
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
class Meta:
|
|
66
|
+
ordering = ['-created_at']
|
|
67
|
+
verbose_name = "Upload Job"
|
|
68
|
+
verbose_name_plural = "Upload Jobs"
|
|
69
|
+
|
|
70
|
+
def __str__(self):
|
|
71
|
+
return f"UploadJob {self.id} - {self.status} ({self.content_type})"
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def is_complete(self):
|
|
75
|
+
"""Returns True if the job has finished processing (success or error)."""
|
|
76
|
+
return self.status in [self.Status.ANONYMIZED, self.Status.ERROR]
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def is_successful(self):
|
|
80
|
+
"""Returns True if the job completed successfully."""
|
|
81
|
+
return self.status == self.Status.ANONYMIZED
|
|
82
|
+
|
|
83
|
+
def mark_processing(self):
|
|
84
|
+
"""Mark the job as processing."""
|
|
85
|
+
self.status = self.Status.PROCESSING
|
|
86
|
+
self.save(update_fields=['status', 'updated_at'])
|
|
87
|
+
|
|
88
|
+
def mark_completed(self, sensitive_meta=None):
|
|
89
|
+
"""Mark the job as successfully completed."""
|
|
90
|
+
self.status = self.Status.ANONYMIZED
|
|
91
|
+
if sensitive_meta:
|
|
92
|
+
self.sensitive_meta = sensitive_meta
|
|
93
|
+
self.save(update_fields=['status', 'sensitive_meta', 'updated_at'])
|
|
94
|
+
|
|
95
|
+
def mark_error(self, error_detail: str):
|
|
96
|
+
"""Mark the job as failed with error details."""
|
|
97
|
+
self.status = self.Status.ERROR
|
|
98
|
+
self.error_detail = error_detail
|
|
99
|
+
self.save(update_fields=['status', 'error_detail', 'updated_at'])
|
|
@@ -0,0 +1,135 @@
|
|
|
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
|
+
import io
|
|
8
|
+
import os
|
|
9
|
+
from tqdm import tqdm
|
|
10
|
+
import numpy as np
|
|
11
|
+
import cv2
|
|
12
|
+
from typing import TYPE_CHECKING, List, Tuple
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from ..models.media import VideoFile
|
|
16
|
+
|
|
17
|
+
from logging import getLogger
|
|
18
|
+
|
|
19
|
+
logger = getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
STORAGE_DIR = data_paths["storage"]
|
|
22
|
+
FILE_STORAGE = FileSystemStorage(location = STORAGE_DIR)
|
|
23
|
+
VIDEO_DIR = data_paths["video"]
|
|
24
|
+
TMP_VIDEO_DIR = VIDEO_DIR / "tmp"
|
|
25
|
+
ANONYM_VIDEO_DIR = data_paths["video_export"]
|
|
26
|
+
FRAME_DIR = data_paths["frame"]
|
|
27
|
+
WEIGHTS_DIR = data_paths["weights"]
|
|
28
|
+
PDF_DIR = data_paths["raw_pdf"]
|
|
29
|
+
DOCUMENT_DIR = data_paths["pdf"]
|
|
30
|
+
|
|
31
|
+
TEST_RUN = os.environ.get("TEST_RUN", "False")
|
|
32
|
+
TEST_RUN = TEST_RUN.lower() == "true"
|
|
33
|
+
|
|
34
|
+
TEST_RUN_FRAME_NUMBER = int(os.environ.get("TEST_RUN_FRAME_NUMBER", "500"))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def prepare_bulk_frames(frame_paths: List[Path]):
|
|
38
|
+
"""
|
|
39
|
+
Reads the frame paths into memory as Django File objects.
|
|
40
|
+
This avoids 'seek of closed file' errors by using BytesIO for each frame.
|
|
41
|
+
"""
|
|
42
|
+
for path in frame_paths:
|
|
43
|
+
frame_number = int(path.stem.split("_")[1])
|
|
44
|
+
with open(path, "rb") as f:
|
|
45
|
+
content = f.read()
|
|
46
|
+
file_obj = File(io.BytesIO(content), name=path.name)
|
|
47
|
+
yield frame_number, file_obj
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def find_segments_in_prediction_array(prediction_array: np.array, min_frame_len: int):
|
|
51
|
+
"""
|
|
52
|
+
Expects a prediction array of shape (num_frames) and a minimum frame length.
|
|
53
|
+
Returns a list of tuples (start_frame_number, end_frame_number) that represent the segments.
|
|
54
|
+
"""
|
|
55
|
+
# Add False to the beginning and end to detect changes at the array boundaries
|
|
56
|
+
padded_prediction = np.pad(
|
|
57
|
+
prediction_array, (1, 1), "constant", constant_values=False
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Find the start points and end points of the segments
|
|
61
|
+
diffs = np.diff(padded_prediction.astype(int))
|
|
62
|
+
segment_starts = np.where(diffs == 1)[0]
|
|
63
|
+
segment_ends = np.where(diffs == -1)[0]
|
|
64
|
+
|
|
65
|
+
# Filter segments based on min_frame_len
|
|
66
|
+
segments = [
|
|
67
|
+
(start, end)
|
|
68
|
+
for start, end in zip(segment_starts, segment_ends)
|
|
69
|
+
if end - start >= min_frame_len
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
return segments
|
|
73
|
+
|
|
74
|
+
def anonymize_frame(
|
|
75
|
+
raw_frame_path: Path, target_frame_path: Path, endo_roi, all_black: bool = False, censor_color: Tuple[int, int, int] = (0, 0, 0) # Added censor_color param
|
|
76
|
+
):
|
|
77
|
+
"""
|
|
78
|
+
Anonymize the frame by blacking out pixels outside the endoscope ROI or making the whole frame black.
|
|
79
|
+
"""
|
|
80
|
+
frame = cv2.imread(raw_frame_path.as_posix())
|
|
81
|
+
if frame is None:
|
|
82
|
+
# Raise error instead of returning None/frame
|
|
83
|
+
raise FileNotFoundError(f"Could not read frame at {raw_frame_path}")
|
|
84
|
+
|
|
85
|
+
# make black frame with same size as original frame
|
|
86
|
+
new_frame = np.zeros_like(frame)
|
|
87
|
+
|
|
88
|
+
if not all_black:
|
|
89
|
+
# Validate ROI dictionary keys
|
|
90
|
+
required_keys = {"x", "y", "width", "height"}
|
|
91
|
+
if not required_keys.issubset(endo_roi):
|
|
92
|
+
raise ValueError(f"Invalid endo_roi dictionary provided: {endo_roi}. Missing keys.")
|
|
93
|
+
|
|
94
|
+
x = endo_roi["x"]
|
|
95
|
+
y = endo_roi["y"]
|
|
96
|
+
width = endo_roi["width"]
|
|
97
|
+
height = endo_roi["height"]
|
|
98
|
+
|
|
99
|
+
# Add boundary checks for ROI coordinates
|
|
100
|
+
h_orig, w_orig, _ = frame.shape
|
|
101
|
+
x1, y1 = max(0, x), max(0, y)
|
|
102
|
+
x2, y2 = min(w_orig, x + width), min(h_orig, y + height)
|
|
103
|
+
|
|
104
|
+
if x1 >= x2 or y1 >= y2:
|
|
105
|
+
logger.warning(f"ROI [{x},{y},{width},{height}] is outside or invalid for frame dimensions {w_orig}x{h_orig}. Resulting frame might be all black.")
|
|
106
|
+
else:
|
|
107
|
+
# copy valid endoscope roi part to black frame
|
|
108
|
+
new_frame[y1:y2, x1:x2] = frame[y1:y2, x1:x2]
|
|
109
|
+
else:
|
|
110
|
+
# If all_black, fill with censor_color (defaults to black)
|
|
111
|
+
new_frame[:] = censor_color
|
|
112
|
+
|
|
113
|
+
# Check if writing the anonymized frame was successful
|
|
114
|
+
success = cv2.imwrite(target_frame_path.as_posix(), new_frame)
|
|
115
|
+
if not success:
|
|
116
|
+
raise IOError(f"Failed to write anonymized frame to {target_frame_path}")
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
__all__ = [
|
|
120
|
+
"DJANGO_NAME_SALT",
|
|
121
|
+
"data_paths",
|
|
122
|
+
"FILE_STORAGE",
|
|
123
|
+
"VIDEO_DIR",
|
|
124
|
+
"TMP_VIDEO_DIR",
|
|
125
|
+
"ANONYM_VIDEO_DIR",
|
|
126
|
+
"FRAME_DIR",
|
|
127
|
+
"WEIGHTS_DIR",
|
|
128
|
+
"PDF_DIR",
|
|
129
|
+
"DOCUMENT_DIR",
|
|
130
|
+
"prepare_bulk_frames",
|
|
131
|
+
"anonymize_frame",
|
|
132
|
+
"find_segments_in_prediction_array",
|
|
133
|
+
"TEST_RUN",
|
|
134
|
+
"TEST_RUN_FRAME_NUMBER",
|
|
135
|
+
]
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
from ...models import LabelSet, ImageClassificationAnnotation
|
|
2
|
+
from django.db.models import Q, F
|
|
3
|
+
from django.db import models
|
|
4
|
+
from tqdm import tqdm
|
|
5
|
+
from collections import defaultdict
|
|
6
|
+
|
|
7
|
+
# def get_legacy_annotations_for_labelset(labelset_name, version=None):
|
|
8
|
+
# """
|
|
9
|
+
# Retrieve annotations for a given label set for training.
|
|
10
|
+
|
|
11
|
+
# Args:
|
|
12
|
+
# - labelset_name (str): The name of the label set.
|
|
13
|
+
# - version (int, optional): The version of the label set. If not specified, the latest version is fetched.
|
|
14
|
+
|
|
15
|
+
# Returns:
|
|
16
|
+
# - list[dict]: A list of dictionaries. Each dictionary represents an image and its annotations.
|
|
17
|
+
# Format: [{"frame": <frame_object>, "annotations": [{"label": <label_name>, "value": <value>}, ...]}, ...]
|
|
18
|
+
|
|
19
|
+
# Example:
|
|
20
|
+
# annotations_for_training = get_annotations_for_labelset("YourLabelSetName", version=2)
|
|
21
|
+
|
|
22
|
+
# """
|
|
23
|
+
|
|
24
|
+
# # Fetch the label set based on the name and optionally the version
|
|
25
|
+
# if version:
|
|
26
|
+
# labelset = LabelSet.objects.get(name=labelset_name, version=version)
|
|
27
|
+
# else:
|
|
28
|
+
# labelset = LabelSet.objects.filter(name=labelset_name).order_by('-version').first()
|
|
29
|
+
# if not labelset:
|
|
30
|
+
# raise ValueError(f"No label set found with the name: {labelset_name}")
|
|
31
|
+
|
|
32
|
+
# # Retrieve all labels in the label set
|
|
33
|
+
# labels_in_set = labelset.labels.all()
|
|
34
|
+
|
|
35
|
+
# # Get the most recent annotations for each frame/label combination
|
|
36
|
+
# annotations = ImageClassificationAnnotation.objects.filter(label__in=labels_in_set)
|
|
37
|
+
# annotations = annotations.annotate(
|
|
38
|
+
# latest_annotation=models.Window(
|
|
39
|
+
# expression=models.functions.RowNumber(),
|
|
40
|
+
# partition_by=[F('legacy_image'), F('label')],
|
|
41
|
+
# order_by=F('date_modified').desc()
|
|
42
|
+
# )
|
|
43
|
+
# ).filter(latest_annotation=1)
|
|
44
|
+
|
|
45
|
+
# # Organize the annotations by image/frame
|
|
46
|
+
# organized_annotations = []
|
|
47
|
+
|
|
48
|
+
# for annotation in tqdm(annotations):
|
|
49
|
+
# # ic(annotation)
|
|
50
|
+
# # Check if the frame is already in the organized list
|
|
51
|
+
# existing_entry = next((entry for entry in organized_annotations if entry['legacy_image'] == annotation.legacy_frame), None)
|
|
52
|
+
|
|
53
|
+
# if existing_entry:
|
|
54
|
+
# # Add this annotation to the existing frame's annotations
|
|
55
|
+
# existing_entry['annotations'].append({
|
|
56
|
+
# "label": annotation.label.name,
|
|
57
|
+
# "value": annotation.value
|
|
58
|
+
# })
|
|
59
|
+
# else:
|
|
60
|
+
# # Create a new entry for this frame
|
|
61
|
+
# organized_annotations.append({
|
|
62
|
+
# "legacy_image": annotation.legacy_image,
|
|
63
|
+
# "annotations": [{
|
|
64
|
+
# "label": annotation.label.name,
|
|
65
|
+
# "value": annotation.value
|
|
66
|
+
# }]
|
|
67
|
+
# })
|
|
68
|
+
|
|
69
|
+
# return organized_annotations
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def get_legacy_annotations_for_labelset(labelset_name, version=None):
|
|
74
|
+
"""
|
|
75
|
+
... [rest of your docstring]
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
# Fetch the label set based on the name and optionally the version
|
|
79
|
+
if version:
|
|
80
|
+
labelset = LabelSet.objects.get(name=labelset_name, version=version)
|
|
81
|
+
else:
|
|
82
|
+
labelset = LabelSet.objects.filter(name=labelset_name).order_by('-version').first()
|
|
83
|
+
if not labelset:
|
|
84
|
+
raise ValueError(f"No label set found with the name: {labelset_name}")
|
|
85
|
+
|
|
86
|
+
# Retrieve all labels in the label set
|
|
87
|
+
labels_in_set = labelset.labels.all()
|
|
88
|
+
|
|
89
|
+
# Get the most recent annotations for each frame/label combination
|
|
90
|
+
annotations = (ImageClassificationAnnotation.objects
|
|
91
|
+
.filter(label__in=labels_in_set)
|
|
92
|
+
.select_related('legacy_image', 'label') # Reduce number of queries
|
|
93
|
+
.annotate(
|
|
94
|
+
latest_annotation=models.Window(
|
|
95
|
+
expression=models.functions.RowNumber(),
|
|
96
|
+
partition_by=[F('legacy_image'), F('label')],
|
|
97
|
+
order_by=F('date_modified').desc()
|
|
98
|
+
)
|
|
99
|
+
).filter(latest_annotation=1))
|
|
100
|
+
|
|
101
|
+
# Organize the annotations by image/frame using a defaultdict
|
|
102
|
+
organized_annotations_dict = defaultdict(lambda: {
|
|
103
|
+
"legacy_image": None,
|
|
104
|
+
"annotations": []
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
for annotation in tqdm(annotations):
|
|
108
|
+
organized_entry = organized_annotations_dict[annotation.legacy_image.id]
|
|
109
|
+
organized_entry["legacy_image"] = annotation.legacy_image
|
|
110
|
+
organized_entry["annotations"].append({
|
|
111
|
+
"label": annotation.label.name,
|
|
112
|
+
"value": annotation.value
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
# Convert organized_annotations_dict to a list
|
|
116
|
+
organized_annotations = list(organized_annotations_dict.values())
|
|
117
|
+
|
|
118
|
+
return organized_annotations
|
|
119
|
+
|
|
120
|
+
def generate_legacy_dataset_output(labelset_name, version=None):
|
|
121
|
+
"""
|
|
122
|
+
Generate an output suitable for creating PyTorch datasets.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
- labelset_name (str): The name of the label set.
|
|
126
|
+
- version (int, optional): The version of the label set. If not specified, the latest version is fetched.
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
- list[dict]: A list of dictionaries, where each dictionary contains the file path and the labels.
|
|
130
|
+
Format: [{"path": <file_path>, "labels": [<label_1_value>, <label_2_value>, ...]}, ...]
|
|
131
|
+
- labelset[LabelSet]: The label set that was used to generate the output.
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
# First, retrieve the organized annotations using the previously defined function
|
|
135
|
+
organized_annotations = get_legacy_annotations_for_labelset(labelset_name, version)
|
|
136
|
+
|
|
137
|
+
# Fetch all labels from the labelset for consistent ordering
|
|
138
|
+
labelset = LabelSet.objects.get(name=labelset_name, version=version)
|
|
139
|
+
all_labels = labelset.get_labels_in_order()
|
|
140
|
+
|
|
141
|
+
dataset_output = []
|
|
142
|
+
|
|
143
|
+
for entry in organized_annotations:
|
|
144
|
+
# Prepare a dictionary for each frame
|
|
145
|
+
frame_data = {
|
|
146
|
+
"path": entry['legacy_image'].image.path, # Assuming 'image' field stores the file path
|
|
147
|
+
"labels": [-1] * len(all_labels) # Initialize with -1 for all labels
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
# Update the labels based on the annotations
|
|
151
|
+
for annotation in entry['annotations']:
|
|
152
|
+
index = next((i for i, label in enumerate(all_labels) if label.name == annotation['label']), None)
|
|
153
|
+
if index is not None:
|
|
154
|
+
frame_data['labels'][index] = int(annotation['value'])
|
|
155
|
+
|
|
156
|
+
dataset_output.append(frame_data)
|
|
157
|
+
|
|
158
|
+
return dataset_output, labelset
|
|
File without changes
|