endoreg-db 0.6.3__py3-none-any.whl → 0.8.1__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/admin.py +26 -26
- endoreg_db/api_urls.py +4 -0
- endoreg_db/apps.py +12 -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/env.py +101 -0
- endoreg_db/data/__init__.py +26 -0
- endoreg_db/data/ai_model/data.yaml +1 -1
- endoreg_db/data/ai_model_label/label/polyp_classification.yaml +52 -0
- endoreg_db/data/ai_model_label/label-set/data.yaml +20 -1
- endoreg_db/data/ai_model_label/label-set/polyp_classifications.yaml +25 -0
- endoreg_db/data/center/data.yaml +13 -12
- endoreg_db/data/center_shift/ukw.yaml +9 -0
- endoreg_db/data/db_summary.csv +58 -0
- endoreg_db/data/db_summary.xlsx +0 -0
- endoreg_db/data/disease/misc.yaml +1 -2
- endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +2 -2
- endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +6 -6
- endoreg_db/data/endoscopy_processor/data.yaml +3 -0
- endoreg_db/data/event/cardiology.yaml +0 -13
- endoreg_db/data/examination/examinations/data.yaml +34 -28
- endoreg_db/data/examination/type/data.yaml +12 -0
- endoreg_db/data/examination_indication/endoscopy.yaml +418 -2
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +157 -5
- 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 +8 -44
- 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_morphology_classification_choice → finding_classification_choice}/colon_lesion_circularity_default.yaml +0 -2
- 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_morphology_classification_choice → finding_classification_choice}/colon_lesion_nice.yaml +4 -7
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_paris.yaml +0 -8
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_planarity_default.yaml +6 -13
- endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +14 -0
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_surface_intact_default.yaml +3 -6
- endoreg_db/data/{finding_location_classification_choice/colonoscopy.yaml → finding_classification_choice/colonoscopy_location.yaml} +11 -22
- 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 +26 -121
- 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_morphology_classification_type/colonoscopy.yaml +6 -6
- endoreg_db/data/finding_type/data.yaml +23 -10
- endoreg_db/data/gender/data.yaml +8 -1
- endoreg_db/data/information_source/annotation.yaml +6 -0
- endoreg_db/data/information_source/endoscopy_guidelines.yaml +7 -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/misc.yaml +43 -0
- endoreg_db/data/medication/anticoagulation.yaml +5 -5
- endoreg_db/data/medication/tah.yaml +5 -5
- endoreg_db/data/medication_indication/anticoagulation.yaml +4 -4
- endoreg_db/data/medication_intake_time/base.yaml +4 -4
- endoreg_db/data/names_first/first_names.yaml +3 -0
- endoreg_db/data/pdf_type/data.yaml +27 -10
- 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/report_reader_flag/rkh-histology-generic.yaml +10 -0
- endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +5 -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/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/shift/endoscopy.yaml +21 -0
- endoreg_db/data/shift_type/base.yaml +35 -0
- endoreg_db/data/tag/requirement_set_tags.yaml +11 -0
- endoreg_db/data/unit/concentration.yaml +23 -0
- endoreg_db/data/unit/time.yaml +36 -1
- endoreg_db/exceptions.py +19 -0
- endoreg_db/forms/patient_finding_intervention_form.py +4 -5
- endoreg_db/forms/patient_form.py +7 -6
- endoreg_db/forms/questionnaires/__init__.py +1 -1
- endoreg_db/forms/questionnaires/tto_questionnaire.py +19 -19
- endoreg_db/helpers/count_db.py +45 -0
- endoreg_db/helpers/data_loader.py +208 -0
- endoreg_db/helpers/default_objects.py +359 -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_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 +422 -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 +2 -7
- endoreg_db/management/commands/load_base_db_data.py +15 -1
- endoreg_db/management/commands/load_center_data.py +46 -21
- endoreg_db/management/commands/load_endoscope_data.py +2 -2
- endoreg_db/management/commands/load_examination_indication_data.py +49 -28
- endoreg_db/management/commands/load_finding_data.py +49 -92
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +0 -1
- endoreg_db/management/commands/load_information_source.py +13 -7
- endoreg_db/management/commands/load_qualification_data.py +59 -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/register_ai_model.py +1 -1
- 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/migrations/0001_initial.py +625 -813
- endoreg_db/migrations/0002_add_video_correction_models.py +52 -0
- endoreg_db/models/__init__.py +274 -291
- endoreg_db/models/administration/__init__.py +116 -0
- endoreg_db/models/{ai_model → administration/ai}/__init__.py +6 -1
- endoreg_db/models/administration/ai/active_model.py +35 -0
- endoreg_db/models/administration/ai/ai_model.py +156 -0
- endoreg_db/models/{ai_model → administration/ai}/model_type.py +6 -1
- endoreg_db/models/administration/case/__init__.py +19 -0
- endoreg_db/models/administration/case/case.py +114 -0
- endoreg_db/models/{case_template → administration/case/case_template}/case_template.py +3 -3
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule.py +3 -10
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule_value.py +2 -4
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_type.py +1 -3
- endoreg_db/models/{center → administration/center}/__init__.py +3 -1
- endoreg_db/models/administration/center/center.py +61 -0
- endoreg_db/models/administration/center/center_product.py +64 -0
- endoreg_db/models/{center → administration/center}/center_resource.py +19 -3
- 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/{persons → administration/person/names}/first_name.py +1 -1
- endoreg_db/models/{persons → administration/person/names}/last_name.py +2 -3
- 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/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/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/{product → administration/product}/product_weight.py +9 -0
- endoreg_db/models/{product → administration/product}/reference_product.py +26 -11
- 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 -1
- 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 +45 -74
- 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/{annotation → label}/video_segmentation_labelset.py +7 -0
- endoreg_db/models/media/__init__.py +14 -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 +608 -0
- endoreg_db/models/media/pdf/report_file.py +162 -0
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +77 -0
- endoreg_db/models/media/video/__init__.py +4 -0
- endoreg_db/models/media/video/create_from_file.py +336 -0
- endoreg_db/models/media/video/pipe_1.py +195 -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 +680 -0
- endoreg_db/models/media/video/video_file_ai.py +443 -0
- endoreg_db/models/media/video/video_file_anonymize.py +348 -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 +129 -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 +166 -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_meta.py +11 -0
- endoreg_db/models/media/video/video_file_segments.py +209 -0
- endoreg_db/models/medical/__init__.py +146 -0
- endoreg_db/models/{contraindication → medical/contraindication}/__init__.py +1 -5
- endoreg_db/models/medical/disease.py +156 -0
- endoreg_db/models/medical/event.py +137 -0
- endoreg_db/models/{examination → medical/examination}/__init__.py +1 -1
- endoreg_db/models/medical/examination/examination.py +148 -0
- endoreg_db/models/medical/examination/examination_indication.py +278 -0
- endoreg_db/models/{examination → medical/examination}/examination_time.py +0 -4
- endoreg_db/models/{examination → medical/examination}/examination_time_type.py +1 -8
- endoreg_db/models/{examination → medical/examination}/examination_type.py +18 -10
- 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/{finding → medical/finding}/finding_intervention.py +2 -10
- endoreg_db/models/medical/finding/finding_type.py +35 -0
- endoreg_db/models/medical/hardware/__init__.py +8 -0
- endoreg_db/models/{hardware → medical/hardware}/endoscope.py +28 -23
- endoreg_db/models/medical/laboratory/__init__.py +5 -0
- endoreg_db/models/medical/laboratory/lab_value.py +419 -0
- endoreg_db/models/{medication → medical/medication}/medication.py +1 -3
- endoreg_db/models/{medication → medical/medication}/medication_indication_type.py +8 -3
- endoreg_db/models/{medication → medical/medication}/medication_intake_time.py +21 -3
- endoreg_db/models/{medication → medical/medication}/medication_schedule.py +13 -5
- endoreg_db/models/{organ → medical/organ}/__init__.py +3 -6
- 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/{persons → medical}/patient/patient_examination_indication.py +21 -9
- endoreg_db/models/medical/patient/patient_finding.py +357 -0
- endoreg_db/models/medical/patient/patient_finding_classification.py +207 -0
- endoreg_db/models/{patient → medical/patient}/patient_finding_intervention.py +15 -1
- endoreg_db/models/medical/patient/patient_lab_sample.py +148 -0
- endoreg_db/models/{persons → medical}/patient/patient_lab_value.py +40 -15
- 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/{data_file/metadata → metadata}/__init__.py +6 -0
- endoreg_db/models/metadata/frame_ocr_result.py +0 -0
- endoreg_db/models/metadata/model_meta.py +193 -0
- endoreg_db/models/metadata/model_meta_logic.py +236 -0
- endoreg_db/models/{data_file/metadata → metadata}/pdf_meta.py +28 -13
- endoreg_db/models/metadata/sensitive_meta.py +288 -0
- endoreg_db/models/metadata/sensitive_meta_logic.py +643 -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 +17 -0
- endoreg_db/models/other/distribution/date_value_distribution.py +0 -2
- endoreg_db/models/other/distribution/numeric_value_distribution.py +30 -2
- endoreg_db/models/{emission → other/emission}/emission_factor.py +15 -6
- endoreg_db/models/{persons → other}/gender.py +8 -3
- endoreg_db/models/other/information_source.py +159 -0
- endoreg_db/models/other/material.py +10 -2
- endoreg_db/models/other/resource.py +6 -2
- endoreg_db/models/other/tag.py +27 -0
- endoreg_db/models/other/transport_route.py +13 -2
- endoreg_db/models/{unit.py → other/unit.py} +16 -6
- endoreg_db/models/other/waste.py +10 -3
- 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/{rules → rule}/rule.py +6 -3
- endoreg_db/models/{rules → rule}/rule_attribute_dtype.py +0 -2
- endoreg_db/models/{rules → rule}/rule_type.py +0 -2
- endoreg_db/models/{rules → rule}/ruleset.py +0 -2
- 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/models/video_metadata.py +66 -0
- endoreg_db/models/video_processing.py +153 -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 +147 -10
- endoreg_db/serializers/{raw_pdf_meta_validation.py → _old/raw_pdf_meta_validation.py} +3 -3
- endoreg_db/serializers/{raw_video_meta_validation.py → _old/raw_video_meta_validation.py} +18 -14
- 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 +66 -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 +152 -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/misc/vop_patient_data.py +120 -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/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 +241 -0
- endoreg_db/services/lookup_store.py +122 -0
- endoreg_db/services/ollama_api_docs.py +1528 -0
- endoreg_db/services/pdf_import.py +993 -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 +915 -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/urls/__init__.py +72 -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 +44 -0
- endoreg_db/urls/media.py +32 -0
- endoreg_db/urls/patient.py +19 -0
- endoreg_db/urls/pdf.py +0 -0
- endoreg_db/urls/report.py +78 -0
- endoreg_db/urls/requirements.py +13 -0
- endoreg_db/urls/sensitive_meta.py +36 -0
- endoreg_db/urls/stats.py +46 -0
- endoreg_db/urls/upload.py +20 -0
- endoreg_db/urls/video.py +119 -0
- endoreg_db/urls.py +6 -269
- endoreg_db/utils/__init__.py +68 -16
- endoreg_db/utils/ai/__init__.py +9 -0
- endoreg_db/{models/ai_model/utils.py → utils/ai/get.py} +1 -4
- endoreg_db/{models/ai_model/lightning → utils/ai}/inference_dataset.py +0 -1
- endoreg_db/{models/ai_model/lightning → utils/ai}/multilabel_classification_net.py +14 -10
- endoreg_db/{models/ai_model/lightning → utils/ai}/postprocess.py +15 -5
- endoreg_db/utils/ai/predict.py +291 -0
- endoreg_db/{models/ai_model/lightning → utils/ai}/preprocess.py +1 -1
- endoreg_db/utils/calc_duration_seconds.py +24 -0
- endoreg_db/utils/case_generator/__init__.py +0 -0
- endoreg_db/utils/check_video_files.py +148 -0
- endoreg_db/utils/dataloader.py +88 -31
- endoreg_db/utils/dates.py +21 -0
- endoreg_db/utils/env.py +33 -0
- endoreg_db/utils/extract_specific_frames.py +72 -0
- endoreg_db/utils/file_operations.py +29 -1
- endoreg_db/utils/fix_video_path_direct.py +141 -0
- endoreg_db/utils/frame_anonymization_utils.py +463 -0
- endoreg_db/utils/hashs.py +1 -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 +2 -0
- endoreg_db/utils/paths.py +104 -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/db_config.py +1 -1
- 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/translation.py +27 -0
- endoreg_db/utils/validate_video_detailed.py +357 -0
- endoreg_db/utils/video/__init__.py +19 -6
- endoreg_db/utils/video/extract_frames.py +37 -70
- endoreg_db/utils/video/ffmpeg_wrapper.py +772 -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 +282 -2
- 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 +63 -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 +9 -0
- endoreg_db/views/media/pdf_media.py +386 -0
- endoreg_db/views/media/video_media.py +272 -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/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 +11 -0
- endoreg_db/views/pdf/pdf_media.py +239 -0
- endoreg_db/views/pdf/pdf_stream_views.py +127 -0
- endoreg_db/views/pdf/reimport.py +151 -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 +483 -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 +72 -0
- endoreg_db/views/video/correction.py +672 -0
- endoreg_db/views/video/media/__init__.py +23 -0
- endoreg_db/views/video/media/task_status.py +49 -0
- endoreg_db/views/video/media/video_analyze.py +52 -0
- endoreg_db/views/video/media/video_apply_mask.py +48 -0
- endoreg_db/views/video/media/video_correction.py +21 -0
- endoreg_db/views/video/media/video_download_processed.py +58 -0
- endoreg_db/views/video/media/video_media.py +158 -0
- endoreg_db/views/video/media/video_meta.py +29 -0
- endoreg_db/views/video/media/video_processing_history.py +24 -0
- endoreg_db/views/video/media/video_remove_frames.py +48 -0
- endoreg_db/views/video/media/video_reprocess.py +40 -0
- endoreg_db/views/video/reimport.py +192 -0
- endoreg_db/views/video/segmentation.py +274 -0
- endoreg_db/views/{views_for_timeline.py → video/timeline.py} +3 -3
- endoreg_db/views/video/video_examination_viewset.py +329 -0
- endoreg_db/views/video/video_stream.py +188 -0
- endoreg_db-0.8.1.dist-info/METADATA +384 -0
- endoreg_db-0.8.1.dist-info/RECORD +789 -0
- endoreg_db/data/agl_service/data.yaml +0 -19
- endoreg_db/data/finding_location_classification/colonoscopy.yaml +0 -46
- endoreg_db/data/finding_morphology_classification/colonoscopy.yaml +0 -48
- endoreg_db/data/finding_morphology_classification_choice/colonoscopy_size.yaml +0 -57
- endoreg_db/management/commands/_load_model_template.py +0 -41
- endoreg_db/management/commands/delete_all.py +0 -18
- endoreg_db/management/commands/fetch_legacy_image_dataset.py +0 -32
- endoreg_db/management/commands/fix_auth_permission.py +0 -20
- endoreg_db/management/commands/load_active_model_data.py +0 -45
- endoreg_db/management/commands/load_g_play_data.py +0 -113
- endoreg_db/management/commands/load_logging_data.py +0 -39
- endoreg_db/management/commands/load_lx_data.py +0 -64
- endoreg_db/management/commands/load_medication_indication_data.py +0 -63
- endoreg_db/management/commands/load_medication_indication_type_data.py +0 -41
- endoreg_db/management/commands/load_medication_intake_time_data.py +0 -41
- endoreg_db/management/commands/load_medication_schedule_data.py +0 -55
- endoreg_db/management/commands/load_network_data.py +0 -57
- endoreg_db/migrations/0002_alter_frame_image_alter_rawframe_image.py +0 -23
- endoreg_db/migrations/0003_alter_frame_image_alter_rawframe_image.py +0 -23
- endoreg_db/migrations/0004_alter_rawvideofile_file_alter_video_file.py +0 -25
- endoreg_db/migrations/0005_rawvideofile_frame_count_and_more.py +0 -33
- endoreg_db/migrations/0006_frame_extracted_rawframe_extracted.py +0 -23
- endoreg_db/migrations/0007_rename_pseudo_patient_video_patient_and_more.py +0 -24
- endoreg_db/migrations/0008_remove_reportfile_patient_examination_and_more.py +0 -48
- endoreg_db/models/ai_model/active_model.py +0 -9
- endoreg_db/models/ai_model/ai_model.py +0 -103
- endoreg_db/models/ai_model/lightning/__init__.py +0 -3
- endoreg_db/models/ai_model/lightning/predict.py +0 -172
- endoreg_db/models/ai_model/lightning/prediction_visualizer.py +0 -55
- endoreg_db/models/ai_model/lightning/run_visualizer.py +0 -21
- endoreg_db/models/ai_model/model_meta.py +0 -250
- endoreg_db/models/annotation/__init__.py +0 -32
- endoreg_db/models/annotation/anonymized_image_annotation.py +0 -115
- endoreg_db/models/annotation/binary_classification_annotation_task.py +0 -117
- endoreg_db/models/annotation/image_classification.py +0 -86
- endoreg_db/models/annotation/video_segmentation_annotation.py +0 -52
- endoreg_db/models/case/__init__.py +0 -1
- endoreg_db/models/case/case.py +0 -34
- endoreg_db/models/center/center.py +0 -51
- endoreg_db/models/center/center_product.py +0 -33
- endoreg_db/models/center/center_waste.py +0 -16
- endoreg_db/models/data_file/__init__.py +0 -39
- endoreg_db/models/data_file/base_classes/__init__.py +0 -7
- endoreg_db/models/data_file/base_classes/abstract_frame.py +0 -100
- endoreg_db/models/data_file/base_classes/abstract_pdf.py +0 -136
- endoreg_db/models/data_file/base_classes/abstract_video.py +0 -807
- endoreg_db/models/data_file/base_classes/frame_helpers.py +0 -17
- endoreg_db/models/data_file/base_classes/prepare_bulk_frames.py +0 -19
- endoreg_db/models/data_file/base_classes/utils.py +0 -80
- endoreg_db/models/data_file/frame.py +0 -29
- endoreg_db/models/data_file/import_classes/__init__.py +0 -18
- endoreg_db/models/data_file/import_classes/processing_functions/__init__.py +0 -35
- endoreg_db/models/data_file/import_classes/processing_functions/pdf.py +0 -28
- endoreg_db/models/data_file/import_classes/processing_functions/video.py +0 -260
- endoreg_db/models/data_file/import_classes/raw_pdf.py +0 -260
- endoreg_db/models/data_file/import_classes/raw_video.py +0 -288
- endoreg_db/models/data_file/metadata/sensitive_meta.py +0 -290
- endoreg_db/models/data_file/metadata/video_meta.py +0 -199
- endoreg_db/models/data_file/report_file.py +0 -56
- endoreg_db/models/data_file/video/__init__.py +0 -11
- endoreg_db/models/data_file/video/import_meta.py +0 -25
- endoreg_db/models/data_file/video/video.py +0 -196
- endoreg_db/models/data_file/video_segment.py +0 -214
- endoreg_db/models/disease.py +0 -79
- endoreg_db/models/event.py +0 -73
- endoreg_db/models/examination/examination.py +0 -67
- endoreg_db/models/examination/examination_indication.py +0 -170
- endoreg_db/models/finding/__init__.py +0 -11
- endoreg_db/models/finding/finding.py +0 -75
- endoreg_db/models/finding/finding_location_classification.py +0 -94
- endoreg_db/models/finding/finding_morphology_classification.py +0 -89
- endoreg_db/models/finding/finding_type.py +0 -22
- endoreg_db/models/hardware/__init__.py +0 -2
- endoreg_db/models/information_source.py +0 -29
- endoreg_db/models/laboratory/__init__.py +0 -1
- endoreg_db/models/laboratory/lab_value.py +0 -111
- endoreg_db/models/logging/__init__.py +0 -11
- endoreg_db/models/logging/agl_service.py +0 -19
- endoreg_db/models/logging/base.py +0 -22
- endoreg_db/models/logging/log_type.py +0 -23
- endoreg_db/models/logging/network_device.py +0 -27
- endoreg_db/models/lx/__init__.py +0 -4
- endoreg_db/models/lx/client.py +0 -57
- endoreg_db/models/lx/identity.py +0 -34
- endoreg_db/models/lx/permission.py +0 -18
- endoreg_db/models/lx/user.py +0 -16
- endoreg_db/models/network/__init__.py +0 -9
- endoreg_db/models/network/agl_service.py +0 -38
- endoreg_db/models/network/network_device.py +0 -58
- endoreg_db/models/network/network_device_type.py +0 -23
- endoreg_db/models/other/distribution.py +0 -5
- endoreg_db/models/patient/__init__.py +0 -24
- endoreg_db/models/patient/patient_examination.py +0 -182
- endoreg_db/models/patient/patient_finding.py +0 -143
- endoreg_db/models/patient/patient_finding_location.py +0 -120
- endoreg_db/models/patient/patient_finding_morphology.py +0 -166
- endoreg_db/models/permissions/__init__.py +0 -44
- endoreg_db/models/persons/__init__.py +0 -34
- endoreg_db/models/persons/examiner/__init__.py +0 -2
- endoreg_db/models/persons/examiner/examiner.py +0 -60
- endoreg_db/models/persons/examiner/examiner_type.py +0 -2
- endoreg_db/models/persons/patient/__init__.py +0 -8
- endoreg_db/models/persons/patient/patient.py +0 -389
- endoreg_db/models/persons/patient/patient_disease.py +0 -22
- endoreg_db/models/persons/patient/patient_event.py +0 -52
- endoreg_db/models/persons/patient/patient_lab_sample.py +0 -108
- endoreg_db/models/persons/patient/patient_medication.py +0 -59
- endoreg_db/models/persons/patient/patient_medication_schedule.py +0 -88
- endoreg_db/models/persons/portal_user_information.py +0 -27
- endoreg_db/models/prediction/__init__.py +0 -8
- endoreg_db/models/prediction/image_classification.py +0 -51
- endoreg_db/models/prediction/video_prediction_meta.py +0 -306
- endoreg_db/models/product/product.py +0 -110
- endoreg_db/models/product/product_group.py +0 -27
- endoreg_db/models/product/product_material.py +0 -28
- endoreg_db/models/questionnaires/__init__.py +0 -114
- endoreg_db/models/quiz/__init__.py +0 -9
- endoreg_db/models/quiz/quiz_answer.py +0 -41
- endoreg_db/models/quiz/quiz_question.py +0 -54
- endoreg_db/models/report_reader/report_reader_config.py +0 -53
- endoreg_db/models/rules/__init__.py +0 -5
- endoreg_db/queries/get/__init__.py +0 -6
- endoreg_db/queries/get/center.py +0 -42
- endoreg_db/queries/get/model.py +0 -13
- endoreg_db/queries/get/patient.py +0 -14
- endoreg_db/queries/get/patient_examination.py +0 -20
- endoreg_db/queries/get/report_file.py +0 -33
- endoreg_db/queries/get/video.py +0 -31
- endoreg_db/serializers/ai_model.py +0 -19
- endoreg_db/serializers/annotation.py +0 -14
- endoreg_db/serializers/center.py +0 -11
- endoreg_db/serializers/examination.py +0 -33
- endoreg_db/serializers/frame.py +0 -9
- endoreg_db/serializers/hardware.py +0 -21
- endoreg_db/serializers/label.py +0 -22
- endoreg_db/serializers/patient.py +0 -33
- endoreg_db/serializers/prediction.py +0 -10
- endoreg_db/serializers/raw_pdf_anony_text_validation.py +0 -137
- endoreg_db/serializers/report_file.py +0 -7
- endoreg_db/serializers/video.py +0 -20
- endoreg_db/serializers/video_segmentation.py +0 -587
- endoreg_db/tests.py +0 -3
- endoreg_db/utils/legacy_ocr.py +0 -201
- endoreg_db/utils/video/transcode_videofile.py +0 -111
- endoreg_db/views/patient_views.py +0 -90
- endoreg_db/views/raw_pdf_anony_text_validation_views.py +0 -95
- endoreg_db/views/raw_pdf_meta_validation_views.py +0 -111
- endoreg_db/views/raw_video_meta_validation_views.py +0 -148
- endoreg_db/views/report_views.py +0 -96
- endoreg_db/views/video_segmentation_views.py +0 -166
- endoreg_db-0.6.3.dist-info/METADATA +0 -161
- endoreg_db-0.6.3.dist-info/RECORD +0 -435
- /endoreg_db/{case_generator/__init__.py → api/serializers/finding_descriptions.py} +0 -0
- /endoreg_db/{queries/get/annotation.py → api/views/finding_descriptions.py} +0 -0
- /endoreg_db/{queries/get/prediction.py → data/shift/m2.yaml} +0 -0
- /endoreg_db/{queries/get/video_import_meta.py → factories/__init__.py} +0 -0
- /endoreg_db/{queries/get/video_prediction_meta.py → helpers/__init__.py} +0 -0
- /endoreg_db/models/{case_template → administration/case/case_template}/__init__.py +0 -0
- /endoreg_db/models/{persons → administration/person}/person.py +0 -0
- /endoreg_db/models/{product → administration/product}/__init__.py +0 -0
- /endoreg_db/models/{report_reader → media/pdf/report_reader}/__init__.py +0 -0
- /endoreg_db/models/{report_reader → media/pdf/report_reader}/report_reader_flag.py +0 -0
- /endoreg_db/models/{hardware → medical/hardware}/endoscopy_processor.py +0 -0
- /endoreg_db/models/{medication → medical/medication}/__init__.py +0 -0
- /endoreg_db/models/{medication → medical/medication}/medication_indication.py +0 -0
- /endoreg_db/models/{emission → other/emission}/__init__.py +0 -0
- /endoreg_db/models/{rules → rule}/rule_applicator.py +0 -0
- /endoreg_db/{case_generator → utils/case_generator}/case_generator.py +0 -0
- /endoreg_db/{case_generator → utils/case_generator}/lab_sample_factory.py +0 -0
- /endoreg_db/{case_generator → utils/case_generator}/utils.py +0 -0
- /endoreg_db/views/{csrf.py → misc/csrf.py} +0 -0
- {endoreg_db-0.6.3.dist-info → endoreg_db-0.8.1.dist-info}/WHEEL +0 -0
- {endoreg_db-0.6.3.dist-info → endoreg_db-0.8.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,291 @@
|
|
|
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
|
+
dl = DataLoader(
|
|
74
|
+
dataset=dataset,
|
|
75
|
+
batch_size=self.config["batchsize"],
|
|
76
|
+
num_workers=self.config["num_workers"],
|
|
77
|
+
shuffle=False,
|
|
78
|
+
pin_memory=True,
|
|
79
|
+
)
|
|
80
|
+
if verbose:
|
|
81
|
+
ic("Dataloader created")
|
|
82
|
+
|
|
83
|
+
predictions = []
|
|
84
|
+
|
|
85
|
+
with torch.inference_mode():
|
|
86
|
+
if self.verbose:
|
|
87
|
+
ic("Starting inference")
|
|
88
|
+
|
|
89
|
+
# Ensure model exists
|
|
90
|
+
if self.model is None:
|
|
91
|
+
raise ValueError("Model is not loaded")
|
|
92
|
+
|
|
93
|
+
# Use the device the model is currently on, with fallback to CPU
|
|
94
|
+
try:
|
|
95
|
+
# Check what device the model parameters are on
|
|
96
|
+
model_device = next(self.model.parameters()).device
|
|
97
|
+
device = model_device
|
|
98
|
+
if verbose:
|
|
99
|
+
print(f"Using device: {device}")
|
|
100
|
+
except StopIteration:
|
|
101
|
+
# Model has no parameters, default to CPU
|
|
102
|
+
device = torch.device("cpu")
|
|
103
|
+
if verbose:
|
|
104
|
+
print("Model has no parameters, defaulting to CPU")
|
|
105
|
+
except Exception as e:
|
|
106
|
+
# Any other issue, fall back to CPU
|
|
107
|
+
device = torch.device("cpu")
|
|
108
|
+
if verbose:
|
|
109
|
+
print(f"Device detection failed, using CPU: {e}")
|
|
110
|
+
|
|
111
|
+
# Ensure model is in eval mode
|
|
112
|
+
self.model.eval()
|
|
113
|
+
|
|
114
|
+
for batch in tqdm(dl):
|
|
115
|
+
batch = batch.to(device, non_blocking=True)
|
|
116
|
+
prediction = self.model(batch)
|
|
117
|
+
prediction = (
|
|
118
|
+
self.config["activation"](prediction).cpu().tolist()
|
|
119
|
+
) # .numpy().tolist()
|
|
120
|
+
predictions += prediction
|
|
121
|
+
|
|
122
|
+
return predictions
|
|
123
|
+
|
|
124
|
+
def __call__(self, image, crop=None):
|
|
125
|
+
return self.pipe([image], [crop])
|
|
126
|
+
|
|
127
|
+
def readable(self, predictions):
|
|
128
|
+
"""
|
|
129
|
+
Converts a list of predictions into a readable dictionary format.
|
|
130
|
+
Args:
|
|
131
|
+
predictions (list): A list of prediction values.
|
|
132
|
+
Returns:
|
|
133
|
+
dict: A dictionary where the keys are labels from the configuration
|
|
134
|
+
and the values are the corresponding predictions. If a prediction
|
|
135
|
+
value is of type numpy.int64, it is converted to a standard int.
|
|
136
|
+
"""
|
|
137
|
+
readable_dict = {
|
|
138
|
+
label: prediction
|
|
139
|
+
for label, prediction in zip(self.config["labels"], predictions)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
# when dumping to json we need to convert numpy.int64 to int
|
|
143
|
+
readable_dict = {
|
|
144
|
+
key: int(value) if isinstance(value, np.int64) else value
|
|
145
|
+
for key, value in readable_dict.items()
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return readable_dict
|
|
149
|
+
|
|
150
|
+
def get_prediction_dict(self, predictions, paths):
|
|
151
|
+
"""
|
|
152
|
+
Constructs a dictionary containing prediction results.
|
|
153
|
+
Args:
|
|
154
|
+
predictions (list): A list of prediction results.
|
|
155
|
+
paths (list): A list of paths corresponding to the predictions.
|
|
156
|
+
Returns:
|
|
157
|
+
dict: A dictionary with the following keys:
|
|
158
|
+
- "labels": The labels from the configuration.
|
|
159
|
+
- "paths": The provided paths.
|
|
160
|
+
- "predictions": The provided predictions.
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
json_dict = {
|
|
164
|
+
"labels": self.config["labels"],
|
|
165
|
+
"paths": paths,
|
|
166
|
+
"predictions": predictions,
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return json_dict
|
|
170
|
+
|
|
171
|
+
def get_prediction_json(self, predictions, paths, json_target_path: str = None):
|
|
172
|
+
"""
|
|
173
|
+
Saves predictions to a JSON file.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
predictions (list): A list of prediction results.
|
|
177
|
+
paths (list): A list of paths corresponding to the predictions.
|
|
178
|
+
json_target_path (str, optional): The path to save the JSON file. Defaults to None.
|
|
179
|
+
"""
|
|
180
|
+
if not json_target_path:
|
|
181
|
+
json_target_path = "predictions.json"
|
|
182
|
+
|
|
183
|
+
json_dict = self.get_prediction_dict(predictions, paths)
|
|
184
|
+
|
|
185
|
+
with open(json_target_path, "w", encoding="utf-8") as f:
|
|
186
|
+
json.dump(json_dict, f)
|
|
187
|
+
|
|
188
|
+
if self.verbose:
|
|
189
|
+
ic(f"Saved predictions to {json_target_path}")
|
|
190
|
+
|
|
191
|
+
def post_process_predictions(
|
|
192
|
+
self, pred_dicts, window_size_s=1, fps=50, min_seq_len_s=0.5
|
|
193
|
+
):
|
|
194
|
+
"""
|
|
195
|
+
pred_dicts: list of dictionaries with the same keys
|
|
196
|
+
window_size_s: size of the window in seconds for smoothing
|
|
197
|
+
fps: frames per second
|
|
198
|
+
min_seq_len_s: minimum length of a sequence in seconds
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
predictions: concatenated predictions
|
|
202
|
+
smooth_predictions: smoothed predictions
|
|
203
|
+
binary_predictions: binary predictions
|
|
204
|
+
raw_sequences: raw sequences
|
|
205
|
+
filtered_sequences: filtered sequences
|
|
206
|
+
"""
|
|
207
|
+
# Concatenate the predictions
|
|
208
|
+
predictions = concat_pred_dicts(pred_dicts)
|
|
209
|
+
|
|
210
|
+
smooth_predictions = {key: [] for key in predictions.keys()}
|
|
211
|
+
for key in predictions.keys():
|
|
212
|
+
smooth_predictions[key] = make_smooth_preds(
|
|
213
|
+
predictions[key], window_size_s=window_size_s, fps=fps
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
binary_predictions = {}
|
|
217
|
+
for key in smooth_predictions.keys():
|
|
218
|
+
binary_predictions[key] = np.array(
|
|
219
|
+
[p > 0.5 for p in smooth_predictions[key]]
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
raw_sequences = {}
|
|
223
|
+
for key, value in binary_predictions.items():
|
|
224
|
+
raw_sequences[key] = find_true_pred_sequences(value)
|
|
225
|
+
|
|
226
|
+
filtered_sequences = {}
|
|
227
|
+
min_seq_len = int(min_seq_len_s * fps)
|
|
228
|
+
for key, sequences in raw_sequences.items():
|
|
229
|
+
filtered_sequences[key] = [
|
|
230
|
+
s for s in sequences if s[1] - s[0] > min_seq_len
|
|
231
|
+
]
|
|
232
|
+
|
|
233
|
+
return (
|
|
234
|
+
predictions,
|
|
235
|
+
smooth_predictions,
|
|
236
|
+
binary_predictions,
|
|
237
|
+
raw_sequences,
|
|
238
|
+
filtered_sequences,
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
def post_process_predictions_serializable(
|
|
242
|
+
self, pred_dicts, window_size_s=1, fps=50, min_seq_len_s=0.5
|
|
243
|
+
):
|
|
244
|
+
"""
|
|
245
|
+
Post-processes prediction dictionaries to make them serializable.
|
|
246
|
+
This method takes prediction dictionaries, processes them to ensure all
|
|
247
|
+
elements are serializable (e.g., converting numpy arrays to lists), and
|
|
248
|
+
organizes the results into a dictionary of dictionaries.
|
|
249
|
+
Args:
|
|
250
|
+
pred_dicts (list): List of prediction dictionaries.
|
|
251
|
+
window_size_s (int, optional): Window size in seconds. Defaults to 1.
|
|
252
|
+
fps (int, optional): Frames per second. Defaults to 50.
|
|
253
|
+
min_seq_len_s (float, optional): Minimum sequence length in seconds. Defaults to 0.5.
|
|
254
|
+
Returns:
|
|
255
|
+
dict: A dictionary containing processed prediction results with the following keys:
|
|
256
|
+
- "predictions": Processed predictions.
|
|
257
|
+
- "smooth_predictions": Smoothed predictions.
|
|
258
|
+
- "binary_predictions": Binary predictions.
|
|
259
|
+
- "raw_sequences": Raw sequences.
|
|
260
|
+
- "filtered_sequences": Filtered sequences.
|
|
261
|
+
"""
|
|
262
|
+
|
|
263
|
+
result = self.post_process_predictions(
|
|
264
|
+
pred_dicts, window_size_s, fps, min_seq_len_s
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
for i, _dict in enumerate(result):
|
|
268
|
+
_keys = list(_dict.keys())
|
|
269
|
+
for key in _keys:
|
|
270
|
+
# if numpy array
|
|
271
|
+
if hasattr(_dict[key], "tolist"):
|
|
272
|
+
result[i][key] = _dict[key].tolist()
|
|
273
|
+
|
|
274
|
+
# check if list of tuples
|
|
275
|
+
# if so, make sure each tuple has 2 elements and split to two lists (start, stop)
|
|
276
|
+
if all(isinstance(x, tuple) for x in _dict[key]):
|
|
277
|
+
if all(len(x) == 2 for x in _dict[key]):
|
|
278
|
+
result[i][f"{key}_start"] = [int(x[0]) for x in _dict[key]]
|
|
279
|
+
result[i][f"{key}_stop"] = [int(x[1]) for x in _dict[key]]
|
|
280
|
+
del result[i][key]
|
|
281
|
+
|
|
282
|
+
# make dict of dicts
|
|
283
|
+
result_dict = {
|
|
284
|
+
"predictions": result[0],
|
|
285
|
+
"smooth_predictions": result[1],
|
|
286
|
+
"binary_predictions": result[2],
|
|
287
|
+
"raw_sequences": result[3],
|
|
288
|
+
"filtered_sequences": result[4],
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return result_dict
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
if TYPE_CHECKING:
|
|
4
|
+
from endoreg_db.models import VideoFile
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def _calc_duration_vf(obj:"VideoFile") -> float:
|
|
8
|
+
"""
|
|
9
|
+
Calculate duration of a VideoFile.
|
|
10
|
+
"""
|
|
11
|
+
if not obj.ffmpeg_meta:
|
|
12
|
+
raise ValueError("ffmpeg_meta is missing, cannot calculate duration.")
|
|
13
|
+
|
|
14
|
+
fps = obj.get_fps()
|
|
15
|
+
frame_count = obj.frame_count #TODO similar implementation as in get_fps
|
|
16
|
+
|
|
17
|
+
duration = frame_count / fps if fps > 0 else -1
|
|
18
|
+
if duration > 0:
|
|
19
|
+
return duration
|
|
20
|
+
else:
|
|
21
|
+
raise ValueError(
|
|
22
|
+
f"Invalid duration calculated for video {obj.uuid}: {duration}. "
|
|
23
|
+
"Ensure the video file is valid and accessible."
|
|
24
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Simple video file existence checker and path corrector for VideoFile records.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import argparse
|
|
10
|
+
|
|
11
|
+
# Parse command-line arguments and environment variables for configuration
|
|
12
|
+
parser = argparse.ArgumentParser(description="Simple video file existence checker and path corrector for VideoFile records.")
|
|
13
|
+
parser.add_argument('--django-base', type=str, default=os.environ.get('ENDOREG_DJANGO_PROJECT_PATH', str(Path(__file__).resolve().parent.parent.parent)),
|
|
14
|
+
help='Path to the Django project base (default: env ENDOREG_DJANGO_PROJECT_PATH or project root)')
|
|
15
|
+
parser.add_argument('--django-settings', type=str, default=os.environ.get('DJANGO_SETTINGS_MODULE', 'dev.dev_settings'),
|
|
16
|
+
help='Django settings module (default: env DJANGO_SETTINGS_MODULE or dev.dev_settings)')
|
|
17
|
+
parser.add_argument('--storage-dir', type=str, default=os.environ.get('ENDOREG_STORAGE_DIR', './storage'),
|
|
18
|
+
help='Path to the storage directory (default: ./storage or $ENDOREG_STORAGE_DIR)')
|
|
19
|
+
args, unknown = parser.parse_known_args()
|
|
20
|
+
|
|
21
|
+
sys.path.insert(0, args.django_base)
|
|
22
|
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', args.django_settings)
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
import django
|
|
26
|
+
django.setup()
|
|
27
|
+
from endoreg_db.models import VideoFile
|
|
28
|
+
DJANGO_AVAILABLE = True
|
|
29
|
+
except Exception as e:
|
|
30
|
+
print(f"Django not available: {e}")
|
|
31
|
+
DJANGO_AVAILABLE = False
|
|
32
|
+
|
|
33
|
+
def find_video_files():
|
|
34
|
+
"""Find all video files in storage directory."""
|
|
35
|
+
storage_dir = Path(args.storage_dir)
|
|
36
|
+
video_files = []
|
|
37
|
+
|
|
38
|
+
for pattern in ['**/*.mp4', '**/*.avi', '**/*.mov', '**/*.mkv']:
|
|
39
|
+
video_files.extend(storage_dir.glob(pattern))
|
|
40
|
+
|
|
41
|
+
return video_files
|
|
42
|
+
|
|
43
|
+
def check_video_file_accessibility(file_path):
|
|
44
|
+
"""Check if a video file is accessible and valid."""
|
|
45
|
+
try:
|
|
46
|
+
if not file_path.exists():
|
|
47
|
+
return False, "File does not exist"
|
|
48
|
+
|
|
49
|
+
if file_path.stat().st_size == 0:
|
|
50
|
+
return False, "File is empty (0 bytes)"
|
|
51
|
+
|
|
52
|
+
if not os.access(file_path, os.R_OK):
|
|
53
|
+
return False, "File is not readable"
|
|
54
|
+
|
|
55
|
+
# Try to read first few bytes to check if it's actually a file
|
|
56
|
+
with open(file_path, 'rb') as f:
|
|
57
|
+
header = f.read(8)
|
|
58
|
+
if len(header) < 8:
|
|
59
|
+
return False, "File too small or corrupted"
|
|
60
|
+
|
|
61
|
+
return True, f"OK - {file_path.stat().st_size / (1024*1024):.1f} MB"
|
|
62
|
+
|
|
63
|
+
except Exception as e:
|
|
64
|
+
return False, f"Error checking file: {e}"
|
|
65
|
+
|
|
66
|
+
def main():
|
|
67
|
+
print("🔍 VIDEO FILE EXISTENCE CHECKER")
|
|
68
|
+
print("=" * 40)
|
|
69
|
+
|
|
70
|
+
# Find all video files
|
|
71
|
+
print("1. Scanning for video files...")
|
|
72
|
+
video_files = find_video_files()
|
|
73
|
+
print(f"Found {len(video_files)} video files in storage directory")
|
|
74
|
+
|
|
75
|
+
if not video_files:
|
|
76
|
+
print("❌ No video files found in storage directory!")
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
# Check each file
|
|
80
|
+
print("\n2. Checking file accessibility...")
|
|
81
|
+
accessible_files = []
|
|
82
|
+
|
|
83
|
+
for video_file in video_files[:10]: # Check first 10
|
|
84
|
+
accessible, message = check_video_file_accessibility(video_file)
|
|
85
|
+
status = "✅" if accessible else "❌"
|
|
86
|
+
print(f"{status} {video_file.name}: {message}")
|
|
87
|
+
|
|
88
|
+
if accessible:
|
|
89
|
+
accessible_files.append(video_file)
|
|
90
|
+
|
|
91
|
+
if not accessible_files:
|
|
92
|
+
print("\n❌ No accessible video files found!")
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
print(f"\n✅ Found {len(accessible_files)} accessible video files")
|
|
96
|
+
|
|
97
|
+
# If Django is available, check database records
|
|
98
|
+
if DJANGO_AVAILABLE:
|
|
99
|
+
print("\n3. Checking database records...")
|
|
100
|
+
try:
|
|
101
|
+
video_5 = VideoFile.objects.get(pk=5)
|
|
102
|
+
print(f"📋 Video ID 5 found in database:")
|
|
103
|
+
print(f" UUID: {video_5.uuid}")
|
|
104
|
+
|
|
105
|
+
# Check different file path attributes
|
|
106
|
+
for attr in ['raw_file', 'processed_file']:
|
|
107
|
+
if hasattr(video_5, attr):
|
|
108
|
+
file_field = getattr(video_5, attr)
|
|
109
|
+
if file_field:
|
|
110
|
+
try:
|
|
111
|
+
file_path = Path(file_field.path)
|
|
112
|
+
accessible, message = check_video_file_accessibility(file_path)
|
|
113
|
+
status = "✅" if accessible else "❌"
|
|
114
|
+
print(f" {attr}: {status} {file_path} ({message})")
|
|
115
|
+
except Exception as e:
|
|
116
|
+
print(f" {attr}: ❌ Error accessing path: {e}")
|
|
117
|
+
else:
|
|
118
|
+
print(f" {attr}: ❌ No file set")
|
|
119
|
+
|
|
120
|
+
# Check if UUID matches any found files
|
|
121
|
+
uuid_str = str(video_5.uuid)
|
|
122
|
+
matching_files = [f for f in accessible_files if uuid_str in str(f)]
|
|
123
|
+
|
|
124
|
+
if matching_files:
|
|
125
|
+
print(f"\n💡 Found matching files for UUID {uuid_str}:")
|
|
126
|
+
for match in matching_files:
|
|
127
|
+
accessible, message = check_video_file_accessibility(match)
|
|
128
|
+
print(f" ✅ {match} ({message})")
|
|
129
|
+
|
|
130
|
+
print(f"\n🔧 SOLUTION: Update VideoFile record to use:")
|
|
131
|
+
print(f" {matching_files[0]}")
|
|
132
|
+
print(f"\n🐍 Django command to fix:")
|
|
133
|
+
print(f" video = VideoFile.objects.get(pk=5)")
|
|
134
|
+
print(f" video.raw_file.name = '{matching_files[0].relative_to(Path(args.storage_dir))}'")
|
|
135
|
+
print(f" video.save()")
|
|
136
|
+
else:
|
|
137
|
+
print(f"\n❌ No files found matching UUID {uuid_str}")
|
|
138
|
+
|
|
139
|
+
except Exception as e:
|
|
140
|
+
print(f"❌ Error checking database: {e}")
|
|
141
|
+
|
|
142
|
+
print(f"\n4. 🎯 QUICK TEST RECOMMENDATION:")
|
|
143
|
+
print(f" Use this accessible file for testing:")
|
|
144
|
+
print(f" {accessible_files[0]}")
|
|
145
|
+
print(f" Size: {accessible_files[0].stat().st_size / (1024*1024):.1f} MB")
|
|
146
|
+
|
|
147
|
+
if __name__ == "__main__":
|
|
148
|
+
main()
|
endoreg_db/utils/dataloader.py
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import yaml
|
|
3
3
|
from django.core.exceptions import ObjectDoesNotExist
|
|
4
|
-
|
|
5
|
-
from icecream import ic
|
|
4
|
+
from django.db import OperationalError, transaction
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
def load_model_data_from_yaml(command, model_name, metadata, verbose):
|
|
@@ -38,25 +37,53 @@ def load_data_with_foreign_keys(
|
|
|
38
37
|
command, model, yaml_data, foreign_keys, foreign_key_models, verbose
|
|
39
38
|
):
|
|
40
39
|
"""
|
|
41
|
-
Load data
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
Load YAML data into Django model instances with FK and M2M support.
|
|
41
|
+
|
|
42
|
+
Processes each YAML entry to create or update a model instance. For each entry, the
|
|
43
|
+
function extracts field data and uses the presence of a 'name' field to decide whether
|
|
44
|
+
to update an existing instance or create a new one. Foreign key fields listed in
|
|
45
|
+
foreign_keys are handled by retrieving related objects via natural keys. When a field
|
|
46
|
+
contains a list, it is treated as a many-to-many relationship and the corresponding
|
|
47
|
+
objects are set after the instance is saved. Missing or unresolved foreign keys trigger
|
|
48
|
+
warnings if verbose output is enabled.
|
|
49
|
+
|
|
50
|
+
Parameters:
|
|
51
|
+
model: The Django model class representing the data.
|
|
52
|
+
yaml_data: A list of dictionaries representing YAML entries.
|
|
53
|
+
foreign_keys: A list of foreign key field names to process from each entry.
|
|
54
|
+
foreign_key_models: The corresponding Django model classes for each foreign key.
|
|
55
|
+
verbose: If True, prints detailed output and warnings during processing.
|
|
50
56
|
"""
|
|
51
57
|
for entry in yaml_data:
|
|
52
58
|
fields = entry.get("fields", {})
|
|
53
59
|
name = fields.pop("name", None)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
####################
|
|
63
|
+
#TODO REMOVE AFTER TRANSLATION SUPPORT IS ADDED
|
|
64
|
+
SKIP_NAMES=[
|
|
65
|
+
"name_de", # German name, not used
|
|
66
|
+
"name_en", # English name, not used
|
|
67
|
+
"description_de", # German description
|
|
68
|
+
"description_en", # English description
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# Remove fields that are not needed
|
|
73
|
+
for skip_name in SKIP_NAMES:
|
|
74
|
+
if skip_name in fields:
|
|
75
|
+
fields.pop(skip_name)
|
|
76
|
+
########################
|
|
77
|
+
|
|
54
78
|
m2m_relationships = {} # Store many-to-many relationships
|
|
55
79
|
# print(entry)
|
|
56
80
|
|
|
57
81
|
# Handle foreign keys and many-to-many relationships
|
|
58
82
|
for fk_field, fk_model in zip(foreign_keys, foreign_key_models):
|
|
59
|
-
#
|
|
83
|
+
# Skip fields that are not in the data
|
|
84
|
+
if fk_field not in fields:
|
|
85
|
+
continue
|
|
86
|
+
|
|
60
87
|
target_keys = fields.pop(fk_field, None)
|
|
61
88
|
|
|
62
89
|
# Ensure the foreign key exists
|
|
@@ -73,18 +100,20 @@ def load_data_with_foreign_keys(
|
|
|
73
100
|
if isinstance(target_keys, list): # Assume many-to-many relationship
|
|
74
101
|
related_objects = []
|
|
75
102
|
for key in target_keys:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
103
|
+
try:
|
|
104
|
+
obj = fk_model.objects.get_by_natural_key(key)
|
|
105
|
+
except ObjectDoesNotExist:
|
|
106
|
+
if verbose:
|
|
107
|
+
command.stdout.write(
|
|
108
|
+
command.style.WARNING(
|
|
109
|
+
f"{fk_model.__name__} with key {key} not found"
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
continue
|
|
81
113
|
related_objects.append(obj)
|
|
82
114
|
m2m_relationships[fk_field] = related_objects
|
|
83
115
|
else: # Single foreign key relationship
|
|
84
116
|
try:
|
|
85
|
-
if model == "endoreg_db.case_template_rule":
|
|
86
|
-
# print(fk_model, target_keys)
|
|
87
|
-
pass
|
|
88
117
|
obj = fk_model.objects.get_by_natural_key(target_keys)
|
|
89
118
|
except ObjectDoesNotExist:
|
|
90
119
|
if verbose:
|
|
@@ -96,23 +125,51 @@ def load_data_with_foreign_keys(
|
|
|
96
125
|
continue
|
|
97
126
|
fields[fk_field] = obj
|
|
98
127
|
|
|
99
|
-
# Create or update the main object
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
128
|
+
# Create or update the main object (avoid update_or_create to prevent SQLite locks)
|
|
129
|
+
def _save_instance():
|
|
130
|
+
if name is None:
|
|
131
|
+
# Try to find an existing object by all provided fields
|
|
132
|
+
obj = model.objects.filter(**fields).first()
|
|
133
|
+
if obj is None:
|
|
134
|
+
obj = model.objects.create(**fields)
|
|
135
|
+
created = True
|
|
136
|
+
else:
|
|
137
|
+
created = False
|
|
138
|
+
else:
|
|
139
|
+
obj = model.objects.filter(name=name).first()
|
|
140
|
+
if obj is None:
|
|
141
|
+
obj = model.objects.create(name=name, **fields)
|
|
142
|
+
created = True
|
|
143
|
+
else:
|
|
144
|
+
# Update fields
|
|
145
|
+
for k, v in fields.items():
|
|
146
|
+
setattr(obj, k, v)
|
|
147
|
+
obj.save()
|
|
148
|
+
created = False
|
|
149
|
+
return obj, created
|
|
150
|
+
|
|
151
|
+
try:
|
|
152
|
+
# Attempt save inside a transaction for consistency
|
|
153
|
+
with transaction.atomic():
|
|
154
|
+
obj, created = _save_instance()
|
|
155
|
+
except OperationalError:
|
|
156
|
+
# Retry once on SQLite lock
|
|
157
|
+
obj, created = _save_instance()
|
|
158
|
+
|
|
104
159
|
if created and verbose:
|
|
105
160
|
command.stdout.write(
|
|
106
161
|
command.style.SUCCESS(f"Created {model.__name__} {name}")
|
|
107
162
|
)
|
|
108
163
|
elif verbose:
|
|
109
164
|
pass
|
|
110
|
-
# command.stdout.write(
|
|
111
|
-
# command.style.WARNING(
|
|
112
|
-
# f"Skipped {model.__name__} {name}, already exists"
|
|
113
|
-
# )
|
|
114
|
-
# )
|
|
115
165
|
|
|
116
166
|
# Set many-to-many relationships
|
|
117
167
|
for field_name, related_objs in m2m_relationships.items():
|
|
118
|
-
|
|
168
|
+
if related_objs: # Only set if there are objects to set
|
|
169
|
+
getattr(obj, field_name).set(related_objs)
|
|
170
|
+
if verbose:
|
|
171
|
+
command.stdout.write(
|
|
172
|
+
command.style.SUCCESS(
|
|
173
|
+
f"Set {len(related_objs)} {field_name} for {model.__name__} {name}"
|
|
174
|
+
)
|
|
175
|
+
)
|
endoreg_db/utils/dates.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from datetime import datetime, date, timedelta
|
|
2
2
|
from random import randint
|
|
3
3
|
from calendar import monthrange
|
|
4
|
+
from django.utils import timezone
|
|
5
|
+
import datetime
|
|
4
6
|
|
|
5
7
|
# TODO replace used random_day_by_year function implementation when
|
|
6
8
|
# creating pseudo patients with new function "random date by age_at_date and examination_date"
|
|
@@ -37,3 +39,22 @@ def random_day_by_month_year(month: int, year) -> date:
|
|
|
37
39
|
|
|
38
40
|
day = randint(1, monthrange(year, month)[1])
|
|
39
41
|
return date(year, month, day)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def ensure_aware_datetime(dt):
|
|
45
|
+
"""
|
|
46
|
+
Ensures a datetime object is timezone-aware.
|
|
47
|
+
If the datetime is naive (has no timezone info), the current timezone is applied.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
dt: A datetime object that may be naive
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
A timezone-aware datetime object
|
|
54
|
+
"""
|
|
55
|
+
if dt is None:
|
|
56
|
+
return None
|
|
57
|
+
|
|
58
|
+
if isinstance(dt, datetime.datetime) and timezone.is_naive(dt):
|
|
59
|
+
return timezone.make_aware(dt)
|
|
60
|
+
return dt
|