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,270 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import torch
|
|
5
|
+
from torchvision import models
|
|
6
|
+
import torch.nn as nn
|
|
7
|
+
from pytorch_lightning import LightningModule
|
|
8
|
+
import numpy as np
|
|
9
|
+
from safetensors.torch import load_file
|
|
10
|
+
from sklearn.metrics import precision_score, recall_score, f1_score
|
|
11
|
+
|
|
12
|
+
try: # Torchvision >= 0.13 exposes explicit weight enums
|
|
13
|
+
from torchvision.models import EfficientNet_B4_Weights, RegNet_X_800MF_Weights
|
|
14
|
+
except ImportError: # pragma: no cover - compatibility with older torchvision
|
|
15
|
+
EfficientNet_B4_Weights = None
|
|
16
|
+
RegNet_X_800MF_Weights = None
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
METRICS_ON_STEP = False
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def calculate_metrics(pred, target, threshold=0.5):
|
|
24
|
+
pred = np.array(pred > threshold, dtype=float)
|
|
25
|
+
return {
|
|
26
|
+
"micro/precision": precision_score(
|
|
27
|
+
y_true=target, y_pred=pred, average="micro", zero_division=0
|
|
28
|
+
),
|
|
29
|
+
"micro/recall": recall_score(
|
|
30
|
+
y_true=target, y_pred=pred, average="micro", zero_division=0
|
|
31
|
+
),
|
|
32
|
+
"micro/f1": f1_score(
|
|
33
|
+
y_true=target, y_pred=pred, average="micro", zero_division=0
|
|
34
|
+
),
|
|
35
|
+
"macro/precision": precision_score(
|
|
36
|
+
y_true=target, y_pred=pred, average="macro", zero_division=0
|
|
37
|
+
),
|
|
38
|
+
"macro/recall": recall_score(
|
|
39
|
+
y_true=target, y_pred=pred, average="macro", zero_division=0
|
|
40
|
+
),
|
|
41
|
+
"macro/f1": f1_score(
|
|
42
|
+
y_true=target, y_pred=pred, average="macro", zero_division=0
|
|
43
|
+
),
|
|
44
|
+
"samples/precision": precision_score(
|
|
45
|
+
y_true=target, y_pred=pred, average=None, zero_division=0
|
|
46
|
+
),
|
|
47
|
+
"samples/recall": recall_score(
|
|
48
|
+
y_true=target, y_pred=pred, average=None, zero_division=0
|
|
49
|
+
),
|
|
50
|
+
"samples/f1": f1_score(
|
|
51
|
+
y_true=target, y_pred=pred, average=None, zero_division=0
|
|
52
|
+
),
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _load_torchvision_backbone(factory, *, weights_enum=None, load_pretrained=False):
|
|
57
|
+
"""Instantiate a torchvision model without triggering unwanted downloads."""
|
|
58
|
+
if weights_enum is not None:
|
|
59
|
+
try:
|
|
60
|
+
weights = weights_enum.DEFAULT if load_pretrained else None
|
|
61
|
+
return factory(weights=weights)
|
|
62
|
+
except (TypeError, AttributeError):
|
|
63
|
+
# Fall back to legacy keyword on older torchvision versions
|
|
64
|
+
pass
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
return factory(pretrained=load_pretrained)
|
|
68
|
+
except TypeError:
|
|
69
|
+
# Newer torchvision versions removed the pretrained kwarg; call without hints
|
|
70
|
+
try:
|
|
71
|
+
return factory()
|
|
72
|
+
except Exception as exc: # pragma: no cover - surfaced to caller for visibility
|
|
73
|
+
raise RuntimeError(
|
|
74
|
+
"Failed to instantiate torchvision backbone with load_pretrained="
|
|
75
|
+
f"{load_pretrained}."
|
|
76
|
+
) from exc
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class MultiLabelClassificationNet(LightningModule):
|
|
80
|
+
def __init__(
|
|
81
|
+
self,
|
|
82
|
+
labels=None,
|
|
83
|
+
lr=6e-3,
|
|
84
|
+
weight_decay=0.001,
|
|
85
|
+
pos_weight=2,
|
|
86
|
+
model_type="EfficientNetB4",
|
|
87
|
+
load_imagenet_weights: bool = False,
|
|
88
|
+
track_hparams: bool = True,
|
|
89
|
+
):
|
|
90
|
+
super().__init__()
|
|
91
|
+
if track_hparams:
|
|
92
|
+
self.save_hyperparameters()
|
|
93
|
+
if labels is None:
|
|
94
|
+
raise ValueError(
|
|
95
|
+
"labels must be provided to initialize MultiLabelClassificationNet"
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
self.model_type = model_type
|
|
99
|
+
self.labels = list(labels)
|
|
100
|
+
self.n_classes = len(self.labels)
|
|
101
|
+
self.val_preds: list[np.ndarray] = []
|
|
102
|
+
self.val_targets: list[np.ndarray] = []
|
|
103
|
+
self.pos_weight = pos_weight
|
|
104
|
+
self.weight_decay = weight_decay
|
|
105
|
+
self.lr = lr
|
|
106
|
+
self.sigm = nn.Sigmoid()
|
|
107
|
+
|
|
108
|
+
if model_type == "EfficientNetB4":
|
|
109
|
+
self.model = _load_torchvision_backbone(
|
|
110
|
+
models.efficientnet_b4,
|
|
111
|
+
weights_enum=EfficientNet_B4_Weights,
|
|
112
|
+
load_pretrained=load_imagenet_weights,
|
|
113
|
+
)
|
|
114
|
+
num_ftrs = self.model.classifier[1].in_features
|
|
115
|
+
self.model.classifier[1] = nn.Linear(num_ftrs, len(labels))
|
|
116
|
+
|
|
117
|
+
elif model_type == "RegNetX800MF":
|
|
118
|
+
self.model = _load_torchvision_backbone(
|
|
119
|
+
models.regnet_x_800mf,
|
|
120
|
+
weights_enum=RegNet_X_800MF_Weights,
|
|
121
|
+
load_pretrained=load_imagenet_weights,
|
|
122
|
+
)
|
|
123
|
+
num_ftrs = self.model.fc.in_features
|
|
124
|
+
self.model.fc = nn.Linear(num_ftrs, len(labels))
|
|
125
|
+
|
|
126
|
+
self.criterion = nn.BCEWithLogitsLoss(
|
|
127
|
+
pos_weight=torch.Tensor([self.pos_weight] * len(self.labels))
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
@classmethod
|
|
131
|
+
def load_from_checkpoint(cls, checkpoint_path, *args, **kwargs):
|
|
132
|
+
path = Path(checkpoint_path)
|
|
133
|
+
suffix = path.suffix.lower()
|
|
134
|
+
|
|
135
|
+
if suffix == ".safetensors":
|
|
136
|
+
map_location = kwargs.pop("map_location", "cpu")
|
|
137
|
+
strict = kwargs.pop("strict", True)
|
|
138
|
+
labels = kwargs.pop("labels", None)
|
|
139
|
+
if not labels:
|
|
140
|
+
raise ValueError(
|
|
141
|
+
"labels must be provided when loading .safetensors checkpoints"
|
|
142
|
+
)
|
|
143
|
+
model_type = kwargs.pop("model_type", None) or "EfficientNetB4"
|
|
144
|
+
load_imagenet = kwargs.pop("load_imagenet_weights", False)
|
|
145
|
+
|
|
146
|
+
device = (
|
|
147
|
+
torch.device(map_location)
|
|
148
|
+
if map_location is not None
|
|
149
|
+
else torch.device("cpu")
|
|
150
|
+
)
|
|
151
|
+
if isinstance(device, torch.device):
|
|
152
|
+
device_hint = (
|
|
153
|
+
f"{device.type}:{device.index}"
|
|
154
|
+
if device.index is not None
|
|
155
|
+
else device.type
|
|
156
|
+
)
|
|
157
|
+
else:
|
|
158
|
+
device_hint = device
|
|
159
|
+
|
|
160
|
+
state_dict = load_file(path, device=device_hint)
|
|
161
|
+
|
|
162
|
+
instance = cls(
|
|
163
|
+
labels=labels,
|
|
164
|
+
model_type=model_type,
|
|
165
|
+
load_imagenet_weights=load_imagenet,
|
|
166
|
+
track_hparams=False,
|
|
167
|
+
*args,
|
|
168
|
+
**kwargs,
|
|
169
|
+
)
|
|
170
|
+
missing, unexpected = instance.load_state_dict(state_dict, strict=strict)
|
|
171
|
+
|
|
172
|
+
if missing:
|
|
173
|
+
logger.warning("Missing parameters when loading %s: %s", path, missing)
|
|
174
|
+
if unexpected:
|
|
175
|
+
logger.warning(
|
|
176
|
+
"Unexpected parameters when loading %s: %s", path, unexpected
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
instance.to(device)
|
|
180
|
+
return instance
|
|
181
|
+
|
|
182
|
+
return super(MultiLabelClassificationNet, cls).load_from_checkpoint(
|
|
183
|
+
checkpoint_path, *args, **kwargs
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
def forward(self, x): # pylint: disable=arguments-differ
|
|
187
|
+
x = self.model(x)
|
|
188
|
+
return x
|
|
189
|
+
|
|
190
|
+
def training_step(self, batch, _batch_idx): # pylint: disable=arguments-differ
|
|
191
|
+
x, y = batch
|
|
192
|
+
y_pred = self(x)
|
|
193
|
+
loss = self.criterion(y_pred, y)
|
|
194
|
+
self.log(
|
|
195
|
+
"train/loss", loss, on_step=METRICS_ON_STEP, on_epoch=True, prog_bar=True
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
preds = np.array(self.sigm(y_pred).cpu() > 0.5, dtype=float)
|
|
199
|
+
|
|
200
|
+
return {"loss": loss, "preds": preds, "targets": y}
|
|
201
|
+
|
|
202
|
+
def validation_step(self, batch, _batch_idx): # pylint: disable=arguments-differ
|
|
203
|
+
x, y = batch
|
|
204
|
+
y_pred = self(x)
|
|
205
|
+
loss = self.criterion(y_pred, y)
|
|
206
|
+
self.log("val/loss", loss, on_epoch=True, prog_bar=True)
|
|
207
|
+
|
|
208
|
+
preds = np.array(self.sigm(y_pred).cpu() > 0.5, dtype=float)
|
|
209
|
+
self.val_preds.append(preds)
|
|
210
|
+
self.val_targets.append(y.cpu().numpy())
|
|
211
|
+
|
|
212
|
+
return {"loss": loss, "preds": preds, "targets": y}
|
|
213
|
+
|
|
214
|
+
def validation_epoch_end(self, _outputs):
|
|
215
|
+
"""Called at the end of validation to aggregate outputs"""
|
|
216
|
+
val_preds_np = np.concatenate(self.val_preds)
|
|
217
|
+
val_targets_np = np.concatenate(self.val_targets)
|
|
218
|
+
|
|
219
|
+
metrics = calculate_metrics(val_preds_np, val_targets_np, threshold=0.5)
|
|
220
|
+
for key, metric_value in metrics.items():
|
|
221
|
+
if isinstance(metric_value, np.ndarray):
|
|
222
|
+
processed_value = metric_value.tolist()
|
|
223
|
+
elif isinstance(metric_value, (list, tuple)):
|
|
224
|
+
processed_value = list(metric_value)
|
|
225
|
+
else:
|
|
226
|
+
processed_value = float(metric_value)
|
|
227
|
+
|
|
228
|
+
if isinstance(processed_value, list):
|
|
229
|
+
for i, single_value in enumerate(processed_value):
|
|
230
|
+
name = "val/" + f"{key}/{self.labels[i]}"
|
|
231
|
+
self.log(
|
|
232
|
+
name,
|
|
233
|
+
float(single_value),
|
|
234
|
+
on_epoch=True,
|
|
235
|
+
on_step=METRICS_ON_STEP,
|
|
236
|
+
prog_bar=False,
|
|
237
|
+
)
|
|
238
|
+
else:
|
|
239
|
+
name = "val/" + f"{key}"
|
|
240
|
+
self.log(
|
|
241
|
+
name,
|
|
242
|
+
float(processed_value),
|
|
243
|
+
on_epoch=True,
|
|
244
|
+
on_step=METRICS_ON_STEP,
|
|
245
|
+
prog_bar=True,
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
self.val_preds = []
|
|
249
|
+
self.val_targets = []
|
|
250
|
+
|
|
251
|
+
def configure_optimizers(self):
|
|
252
|
+
"""Choose what optimizers and learning-rate schedulers to use in your optimization.
|
|
253
|
+
Normally you'd need one. But in the case of GANs or similar you might have multiple.
|
|
254
|
+
|
|
255
|
+
See examples here:
|
|
256
|
+
https://pytorch-lightning.readthedocs.io/en/latest/common/lightning_module.html#configure-optimizers
|
|
257
|
+
"""
|
|
258
|
+
optimizer = torch.optim.SGD(
|
|
259
|
+
self.parameters(), self.lr, momentum=0.5, weight_decay=self.weight_decay
|
|
260
|
+
)
|
|
261
|
+
lr_scheduler = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(
|
|
262
|
+
optimizer,
|
|
263
|
+
T_0=20,
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
return {
|
|
267
|
+
"optimizer": optimizer,
|
|
268
|
+
"lr_scheduler": lr_scheduler,
|
|
269
|
+
"monitor": "val/loss",
|
|
270
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def concat_pred_dicts(pred_dicts):
|
|
5
|
+
"""Shoulkd be a list of dictionaries with the same keys"""
|
|
6
|
+
assert len(pred_dicts) > 0
|
|
7
|
+
keys = pred_dicts[0].keys()
|
|
8
|
+
|
|
9
|
+
merged_predictions = {key: [] for key in keys}
|
|
10
|
+
for p in pred_dicts:
|
|
11
|
+
for key in p.keys():
|
|
12
|
+
merged_predictions[key].append(p[key])
|
|
13
|
+
|
|
14
|
+
for key in merged_predictions.keys():
|
|
15
|
+
merged_predictions[key] = np.array(merged_predictions[key])
|
|
16
|
+
|
|
17
|
+
return merged_predictions
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def make_smooth_preds(prediction_array, window_size_s=1, fps=50):
|
|
21
|
+
window_size = int(window_size_s * fps)
|
|
22
|
+
smooth_prediction_array = np.convolve(
|
|
23
|
+
prediction_array, np.ones(window_size) / window_size, mode="valid"
|
|
24
|
+
)
|
|
25
|
+
return smooth_prediction_array
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def find_true_pred_sequences(predictions):
|
|
29
|
+
"""
|
|
30
|
+
Efficiently finds sequences of 'outside' predictions in the binary predictions array using NumPy.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
predictions (np.array): An array of boolean values, where True represents an 'outside' image
|
|
34
|
+
and False represents an 'inside' image.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
list of tuples: A list where each tuple represents a sequence of 'outside' predictions,
|
|
38
|
+
with the first element as the start index and the second element as the stop index.
|
|
39
|
+
"""
|
|
40
|
+
# Identify where the value changes in the binary array (from False to True or True to False)
|
|
41
|
+
change_indices = np.where(np.diff(predictions.astype(int)) != 0)[0]
|
|
42
|
+
|
|
43
|
+
# Since diff reduces the length by 1, we adjust indices to align with the original array
|
|
44
|
+
change_indices += 1
|
|
45
|
+
|
|
46
|
+
# If the first element is 'outside', prepend a 0 to indicate the start
|
|
47
|
+
if predictions[0]:
|
|
48
|
+
change_indices = np.insert(change_indices, 0, 0)
|
|
49
|
+
|
|
50
|
+
# If the last element is 'outside', append the length of the array to indicate the end
|
|
51
|
+
if predictions[-1]:
|
|
52
|
+
change_indices = np.append(change_indices, predictions.size)
|
|
53
|
+
|
|
54
|
+
# Extract the 'outside' sequences by slicing the change_indices array in steps of two
|
|
55
|
+
outside_sequences = [
|
|
56
|
+
(change_indices[i], change_indices[i + 1] - 1)
|
|
57
|
+
for i in range(0, len(change_indices), 2)
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
# make sure the result is serializable
|
|
61
|
+
outside_sequences = [(int(start), int(stop)) for start, stop in outside_sequences]
|
|
62
|
+
|
|
63
|
+
return outside_sequences
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains the Classifier class for making predictions using a trained model.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import torch
|
|
7
|
+
from torch.utils.data import DataLoader
|
|
8
|
+
from torch import nn
|
|
9
|
+
import numpy as np
|
|
10
|
+
from tqdm import tqdm
|
|
11
|
+
from icecream import ic
|
|
12
|
+
from .inference_dataset import InferenceDataset
|
|
13
|
+
from .postprocess import concat_pred_dicts, make_smooth_preds, find_true_pred_sequences
|
|
14
|
+
|
|
15
|
+
sample_config = {
|
|
16
|
+
# mean and std for normalization
|
|
17
|
+
"mean": (0.45211223, 0.27139644, 0.19264949),
|
|
18
|
+
"std": (0.31418097, 0.21088019, 0.16059452),
|
|
19
|
+
# Image Size
|
|
20
|
+
"size_x": 716,
|
|
21
|
+
"size_y": 716,
|
|
22
|
+
# how to wrangle axes of the image before putting them in the network
|
|
23
|
+
"axes": [2, 0, 1], # 2,1,0 for opencv
|
|
24
|
+
"batchsize": 16,
|
|
25
|
+
"num_workers": 0, # always 1 for Windows systems # FIXME: fix celery crash if multiprocessing
|
|
26
|
+
# maybe add sigmoid after prediction?
|
|
27
|
+
"activation": nn.Sigmoid(),
|
|
28
|
+
"labels": [
|
|
29
|
+
"appendix",
|
|
30
|
+
"blood",
|
|
31
|
+
"diverticule",
|
|
32
|
+
"grasper",
|
|
33
|
+
"ileocaecalvalve",
|
|
34
|
+
"ileum",
|
|
35
|
+
"low_quality",
|
|
36
|
+
"nbi",
|
|
37
|
+
"needle",
|
|
38
|
+
"outside",
|
|
39
|
+
"polyp",
|
|
40
|
+
"snare",
|
|
41
|
+
"water_jet",
|
|
42
|
+
"wound",
|
|
43
|
+
],
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class Classifier:
|
|
48
|
+
def __init__(self, model=None, config=None, verbose=False):
|
|
49
|
+
if config is None:
|
|
50
|
+
config = sample_config.copy()
|
|
51
|
+
self.config = config
|
|
52
|
+
self.model = model
|
|
53
|
+
self.verbose = verbose
|
|
54
|
+
|
|
55
|
+
def pipe(self, paths, crops, verbose=None):
|
|
56
|
+
"""
|
|
57
|
+
Processes input data through the model pipeline and returns predictions.
|
|
58
|
+
Args:
|
|
59
|
+
paths (list): List of file paths to the input data.
|
|
60
|
+
crops (list): List of crop regions for the input data.
|
|
61
|
+
verbose (bool, optional): If True, prints detailed logs. Defaults to None.
|
|
62
|
+
Returns:
|
|
63
|
+
list: Predictions generated by the model.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
if verbose is None:
|
|
67
|
+
verbose = self.verbose
|
|
68
|
+
|
|
69
|
+
dataset = InferenceDataset(paths, crops, self.config)
|
|
70
|
+
if verbose:
|
|
71
|
+
ic("Dataset created")
|
|
72
|
+
|
|
73
|
+
use_cuda = torch.cuda.is_available()
|
|
74
|
+
|
|
75
|
+
dl = DataLoader(
|
|
76
|
+
dataset=dataset,
|
|
77
|
+
batch_size=self.config["batchsize"],
|
|
78
|
+
num_workers=self.config["num_workers"],
|
|
79
|
+
shuffle=False,
|
|
80
|
+
pin_memory=use_cuda,
|
|
81
|
+
)
|
|
82
|
+
if verbose:
|
|
83
|
+
ic("Dataloader created")
|
|
84
|
+
|
|
85
|
+
predictions = []
|
|
86
|
+
|
|
87
|
+
with torch.inference_mode():
|
|
88
|
+
if self.verbose:
|
|
89
|
+
ic("Starting inference")
|
|
90
|
+
|
|
91
|
+
# Ensure model exists
|
|
92
|
+
if self.model is None:
|
|
93
|
+
raise ValueError("Model is not loaded")
|
|
94
|
+
|
|
95
|
+
# Use the device the model is currently on, with fallback to CPU
|
|
96
|
+
try:
|
|
97
|
+
# Check what device the model parameters are on
|
|
98
|
+
model_device = next(self.model.parameters()).device
|
|
99
|
+
device = model_device
|
|
100
|
+
if verbose:
|
|
101
|
+
print(f"Using device: {device}")
|
|
102
|
+
except StopIteration:
|
|
103
|
+
# Model has no parameters, default to CPU
|
|
104
|
+
device = torch.device("cpu")
|
|
105
|
+
if verbose:
|
|
106
|
+
print("Model has no parameters, defaulting to CPU")
|
|
107
|
+
except Exception as e:
|
|
108
|
+
# Any other issue, fall back to CPU
|
|
109
|
+
device = torch.device("cpu")
|
|
110
|
+
if verbose:
|
|
111
|
+
print(f"Device detection failed, using CPU: {e}")
|
|
112
|
+
|
|
113
|
+
# Ensure model is in eval mode
|
|
114
|
+
self.model.eval()
|
|
115
|
+
|
|
116
|
+
for batch in tqdm(dl):
|
|
117
|
+
batch = batch.to(device, non_blocking=True)
|
|
118
|
+
prediction = self.model(batch)
|
|
119
|
+
prediction = (
|
|
120
|
+
self.config["activation"](prediction).cpu().tolist()
|
|
121
|
+
) # .numpy().tolist()
|
|
122
|
+
predictions += prediction
|
|
123
|
+
|
|
124
|
+
return predictions
|
|
125
|
+
|
|
126
|
+
def __call__(self, image, crop=None):
|
|
127
|
+
return self.pipe([image], [crop])
|
|
128
|
+
|
|
129
|
+
def readable(self, predictions):
|
|
130
|
+
"""
|
|
131
|
+
Converts a list of predictions into a readable dictionary format.
|
|
132
|
+
Args:
|
|
133
|
+
predictions (list): A list of prediction values.
|
|
134
|
+
Returns:
|
|
135
|
+
dict: A dictionary where the keys are labels from the configuration
|
|
136
|
+
and the values are the corresponding predictions. If a prediction
|
|
137
|
+
value is of type numpy.int64, it is converted to a standard int.
|
|
138
|
+
"""
|
|
139
|
+
readable_dict = {
|
|
140
|
+
label: prediction
|
|
141
|
+
for label, prediction in zip(self.config["labels"], predictions)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
# when dumping to json we need to convert numpy.int64 to int
|
|
145
|
+
readable_dict = {
|
|
146
|
+
key: int(value) if isinstance(value, np.int64) else value
|
|
147
|
+
for key, value in readable_dict.items()
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return readable_dict
|
|
151
|
+
|
|
152
|
+
def get_prediction_dict(self, predictions, paths):
|
|
153
|
+
"""
|
|
154
|
+
Constructs a dictionary containing prediction results.
|
|
155
|
+
Args:
|
|
156
|
+
predictions (list): A list of prediction results.
|
|
157
|
+
paths (list): A list of paths corresponding to the predictions.
|
|
158
|
+
Returns:
|
|
159
|
+
dict: A dictionary with the following keys:
|
|
160
|
+
- "labels": The labels from the configuration.
|
|
161
|
+
- "paths": The provided paths.
|
|
162
|
+
- "predictions": The provided predictions.
|
|
163
|
+
"""
|
|
164
|
+
|
|
165
|
+
json_dict = {
|
|
166
|
+
"labels": self.config["labels"],
|
|
167
|
+
"paths": paths,
|
|
168
|
+
"predictions": predictions,
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return json_dict
|
|
172
|
+
|
|
173
|
+
def get_prediction_json(self, predictions, paths, json_target_path: str = None):
|
|
174
|
+
"""
|
|
175
|
+
Saves predictions to a JSON file.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
predictions (list): A list of prediction results.
|
|
179
|
+
paths (list): A list of paths corresponding to the predictions.
|
|
180
|
+
json_target_path (str, optional): The path to save the JSON file. Defaults to None.
|
|
181
|
+
"""
|
|
182
|
+
if not json_target_path:
|
|
183
|
+
json_target_path = "predictions.json"
|
|
184
|
+
|
|
185
|
+
json_dict = self.get_prediction_dict(predictions, paths)
|
|
186
|
+
|
|
187
|
+
with open(json_target_path, "w", encoding="utf-8") as f:
|
|
188
|
+
json.dump(json_dict, f)
|
|
189
|
+
|
|
190
|
+
if self.verbose:
|
|
191
|
+
ic(f"Saved predictions to {json_target_path}")
|
|
192
|
+
|
|
193
|
+
def post_process_predictions(
|
|
194
|
+
self, pred_dicts, window_size_s=1, fps=50, min_seq_len_s=0.5
|
|
195
|
+
):
|
|
196
|
+
"""
|
|
197
|
+
pred_dicts: list of dictionaries with the same keys
|
|
198
|
+
window_size_s: size of the window in seconds for smoothing
|
|
199
|
+
fps: frames per second
|
|
200
|
+
min_seq_len_s: minimum length of a sequence in seconds
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
predictions: concatenated predictions
|
|
204
|
+
smooth_predictions: smoothed predictions
|
|
205
|
+
binary_predictions: binary predictions
|
|
206
|
+
raw_sequences: raw sequences
|
|
207
|
+
filtered_sequences: filtered sequences
|
|
208
|
+
"""
|
|
209
|
+
# Concatenate the predictions
|
|
210
|
+
predictions = concat_pred_dicts(pred_dicts)
|
|
211
|
+
|
|
212
|
+
smooth_predictions = {key: [] for key in predictions.keys()}
|
|
213
|
+
for key in predictions.keys():
|
|
214
|
+
smooth_predictions[key] = make_smooth_preds(
|
|
215
|
+
predictions[key], window_size_s=window_size_s, fps=fps
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
binary_predictions = {}
|
|
219
|
+
for key in smooth_predictions.keys():
|
|
220
|
+
binary_predictions[key] = np.array(
|
|
221
|
+
[p > 0.5 for p in smooth_predictions[key]]
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
raw_sequences = {}
|
|
225
|
+
for key, value in binary_predictions.items():
|
|
226
|
+
raw_sequences[key] = find_true_pred_sequences(value)
|
|
227
|
+
|
|
228
|
+
filtered_sequences = {}
|
|
229
|
+
min_seq_len = int(min_seq_len_s * fps)
|
|
230
|
+
for key, sequences in raw_sequences.items():
|
|
231
|
+
filtered_sequences[key] = [
|
|
232
|
+
s for s in sequences if s[1] - s[0] > min_seq_len
|
|
233
|
+
]
|
|
234
|
+
|
|
235
|
+
return (
|
|
236
|
+
predictions,
|
|
237
|
+
smooth_predictions,
|
|
238
|
+
binary_predictions,
|
|
239
|
+
raw_sequences,
|
|
240
|
+
filtered_sequences,
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
def post_process_predictions_serializable(
|
|
244
|
+
self, pred_dicts, window_size_s=1, fps=50, min_seq_len_s=0.5
|
|
245
|
+
):
|
|
246
|
+
"""
|
|
247
|
+
Post-processes prediction dictionaries to make them serializable.
|
|
248
|
+
This method takes prediction dictionaries, processes them to ensure all
|
|
249
|
+
elements are serializable (e.g., converting numpy arrays to lists), and
|
|
250
|
+
organizes the results into a dictionary of dictionaries.
|
|
251
|
+
Args:
|
|
252
|
+
pred_dicts (list): List of prediction dictionaries.
|
|
253
|
+
window_size_s (int, optional): Window size in seconds. Defaults to 1.
|
|
254
|
+
fps (int, optional): Frames per second. Defaults to 50.
|
|
255
|
+
min_seq_len_s (float, optional): Minimum sequence length in seconds. Defaults to 0.5.
|
|
256
|
+
Returns:
|
|
257
|
+
dict: A dictionary containing processed prediction results with the following keys:
|
|
258
|
+
- "predictions": Processed predictions.
|
|
259
|
+
- "smooth_predictions": Smoothed predictions.
|
|
260
|
+
- "binary_predictions": Binary predictions.
|
|
261
|
+
- "raw_sequences": Raw sequences.
|
|
262
|
+
- "filtered_sequences": Filtered sequences.
|
|
263
|
+
"""
|
|
264
|
+
|
|
265
|
+
result = self.post_process_predictions(
|
|
266
|
+
pred_dicts, window_size_s, fps, min_seq_len_s
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
for i, _dict in enumerate(result):
|
|
270
|
+
_keys = list(_dict.keys())
|
|
271
|
+
for key in _keys:
|
|
272
|
+
# if numpy array
|
|
273
|
+
if hasattr(_dict[key], "tolist"):
|
|
274
|
+
result[i][key] = _dict[key].tolist()
|
|
275
|
+
|
|
276
|
+
# check if list of tuples
|
|
277
|
+
# if so, make sure each tuple has 2 elements and split to two lists (start, stop)
|
|
278
|
+
if all(isinstance(x, tuple) for x in _dict[key]):
|
|
279
|
+
if all(len(x) == 2 for x in _dict[key]):
|
|
280
|
+
result[i][f"{key}_start"] = [int(x[0]) for x in _dict[key]]
|
|
281
|
+
result[i][f"{key}_stop"] = [int(x[1]) for x in _dict[key]]
|
|
282
|
+
del result[i][key]
|
|
283
|
+
|
|
284
|
+
# make dict of dicts
|
|
285
|
+
result_dict = {
|
|
286
|
+
"predictions": result[0],
|
|
287
|
+
"smooth_predictions": result[1],
|
|
288
|
+
"binary_predictions": result[2],
|
|
289
|
+
"raw_sequences": result[3],
|
|
290
|
+
"filtered_sequences": result[4],
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return result_dict
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from PIL import Image, ImageOps # Import the required modules from Pillow
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def crop_img(img, crop):
|
|
6
|
+
"""
|
|
7
|
+
Crops the image based on the specified dimensions and adds padding to maintain aspect ratio.
|
|
8
|
+
|
|
9
|
+
Parameters:
|
|
10
|
+
img: PIL Image object.
|
|
11
|
+
crop: Tuple of (ymin, ymax, xmin, xmax) specifying the crop area.
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
PIL Image object that has been cropped and padded as necessary.
|
|
15
|
+
"""
|
|
16
|
+
# Convert crop dimensions to Pillow format: left, upper, right, lower
|
|
17
|
+
ymin, ymax, xmin, xmax = crop
|
|
18
|
+
img_cropped = img.crop((xmin, ymin, xmax, ymax))
|
|
19
|
+
|
|
20
|
+
# Calculate the new size and the required padding
|
|
21
|
+
width, height = img_cropped.size
|
|
22
|
+
delta = width - height
|
|
23
|
+
|
|
24
|
+
if delta > 0:
|
|
25
|
+
padding = (
|
|
26
|
+
0,
|
|
27
|
+
abs(delta) // 2,
|
|
28
|
+
0,
|
|
29
|
+
abs(delta) - abs(delta) // 2,
|
|
30
|
+
) # (left, top, right, bottom)
|
|
31
|
+
elif delta < 0:
|
|
32
|
+
padding = (abs(delta) // 2, 0, abs(delta) - abs(delta) // 2, 0)
|
|
33
|
+
else:
|
|
34
|
+
padding = (0, 0, 0, 0)
|
|
35
|
+
|
|
36
|
+
# Pad the image to make it square
|
|
37
|
+
img_padded = ImageOps.expand(img_cropped, padding)
|
|
38
|
+
|
|
39
|
+
return img_padded
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class Cropper:
|
|
43
|
+
def __init__(self):
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
def __call__(
|
|
47
|
+
self, img, crop=None, scale=None, scale_method=Image.Resampling.LANCZOS
|
|
48
|
+
):
|
|
49
|
+
"""
|
|
50
|
+
Applies cropping and scaling transformations to the input image.
|
|
51
|
+
|
|
52
|
+
Parameters:
|
|
53
|
+
img: PIL Image object or numpy array of the image.
|
|
54
|
+
crop: Optional tuple specifying the cropping area (y_min, y_max, x_min, x_max).
|
|
55
|
+
scale: Optional tuple specifying the new size (width, height).
|
|
56
|
+
scale_method: Resampling method used for scaling (default is Image.Resampling.LANCZOS).
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
Numpy array of the processed image.
|
|
60
|
+
"""
|
|
61
|
+
# Convert numpy array to PIL Image if necessary
|
|
62
|
+
if isinstance(img, np.ndarray):
|
|
63
|
+
img = Image.fromarray(img.astype("uint8"), "RGB")
|
|
64
|
+
|
|
65
|
+
if crop is not None:
|
|
66
|
+
img = crop_img(img, crop)
|
|
67
|
+
else:
|
|
68
|
+
raise Exception("Automatic crop detection not implemented yet")
|
|
69
|
+
|
|
70
|
+
if scale is not None:
|
|
71
|
+
img = img.resize(scale, resample=scale_method)
|
|
72
|
+
|
|
73
|
+
# Convert PIL Image back to numpy array
|
|
74
|
+
img = np.array(img)
|
|
75
|
+
|
|
76
|
+
return img
|