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,19 @@
|
|
|
1
|
+
from endoreg_db.models import FindingClassificationChoice
|
|
2
|
+
from rest_framework import serializers
|
|
3
|
+
|
|
4
|
+
class FindingClassificationChoiceSerializer(serializers.ModelSerializer):
|
|
5
|
+
"""
|
|
6
|
+
Serializer for the FindingClassificationChoice model.
|
|
7
|
+
|
|
8
|
+
Serializes the following fields:
|
|
9
|
+
- id: Unique identifier of the classification choice.
|
|
10
|
+
- name: Name of the classification choice.
|
|
11
|
+
- description: Description of the classification choice.
|
|
12
|
+
- subcategories: Related subcategories for further classification.
|
|
13
|
+
- numerical_descriptors: Associated numerical descriptors for the classification choice.
|
|
14
|
+
"""
|
|
15
|
+
class Meta:
|
|
16
|
+
model = FindingClassificationChoice
|
|
17
|
+
fields = [
|
|
18
|
+
'id', 'name', 'description', 'subcategories', 'numerical_descriptors'
|
|
19
|
+
]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from .choice import FindingClassificationChoiceSerializer
|
|
2
|
+
from endoreg_db.models import FindingClassification
|
|
3
|
+
from rest_framework import serializers
|
|
4
|
+
|
|
5
|
+
class FindingClassificationSerializer(serializers.ModelSerializer):
|
|
6
|
+
choices = FindingClassificationChoiceSerializer(many=True, read_only=True)
|
|
7
|
+
|
|
8
|
+
class Meta:
|
|
9
|
+
model = FindingClassification
|
|
10
|
+
fields = [
|
|
11
|
+
'id', 'name', 'description', 'choices', 'classification_types'
|
|
12
|
+
]
|
|
13
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from rest_framework import serializers
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
from endoreg_db.models import ImageClassificationAnnotation
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ImageClassificationAnnotationSerializer(serializers.ModelSerializer):
|
|
9
|
+
"""
|
|
10
|
+
Serializer for ImageClassificationAnnotation model.
|
|
11
|
+
This serializer is used to represent image classification annotations in the API.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
label_name = serializers.SerializerMethodField()
|
|
15
|
+
confidence = serializers.SerializerMethodField()
|
|
16
|
+
frame_number = serializers.IntegerField(source='frame.frame_number', read_only=True)
|
|
17
|
+
|
|
18
|
+
class Meta:
|
|
19
|
+
model = ImageClassificationAnnotation
|
|
20
|
+
fields = [
|
|
21
|
+
"id",
|
|
22
|
+
"label",
|
|
23
|
+
"confidence",
|
|
24
|
+
"frame_number",
|
|
25
|
+
"information_source",
|
|
26
|
+
"date_created",
|
|
27
|
+
"date_modified",
|
|
28
|
+
"label_name",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
def get_confidence(self, obj: ImageClassificationAnnotation) -> Optional[float]:
|
|
32
|
+
"""
|
|
33
|
+
Retrieve the confidence score associated with the annotation.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
The float value representing the annotation's confidence, or None if not set.
|
|
37
|
+
"""
|
|
38
|
+
if obj.float_value is not None:
|
|
39
|
+
return obj.float_value
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
def get_label_name(self, obj: ImageClassificationAnnotation) -> str:
|
|
43
|
+
"""
|
|
44
|
+
Returns the name of the label associated with the annotation, or "No Label" if no label is set.
|
|
45
|
+
"""
|
|
46
|
+
return obj.label.name if obj.label else "No Label"
|
|
47
|
+
|
|
48
|
+
def to_representation(self, instance: ImageClassificationAnnotation) -> dict:
|
|
49
|
+
"""
|
|
50
|
+
Return the serialized representation of an ImageClassificationAnnotation instance.
|
|
51
|
+
|
|
52
|
+
Overrides the default method to allow for future customization of the serialized output, but currently returns the standard representation unchanged.
|
|
53
|
+
|
|
54
|
+
Parameters:
|
|
55
|
+
instance (ImageClassificationAnnotation): The annotation instance to serialize.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
dict: The serialized data for the annotation.
|
|
59
|
+
"""
|
|
60
|
+
representation = super().to_representation(instance)
|
|
61
|
+
# Add any additional fields or transformations here if needed
|
|
62
|
+
return representation
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from endoreg_db.models import Label
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
from rest_framework import serializers
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class LabelSerializer(serializers.ModelSerializer):
|
|
8
|
+
"""
|
|
9
|
+
Serializer for fetching labels from the `endoreg_db_label` table.
|
|
10
|
+
Includes `id` (for backend processing) and `name` (for dropdown display in Vue.js).
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
class Meta:
|
|
14
|
+
model = Label
|
|
15
|
+
fields = ["id", "name"]
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
from django.core.exceptions import ObjectDoesNotExist
|
|
3
|
+
from rest_framework import serializers
|
|
4
|
+
from endoreg_db.models import (
|
|
5
|
+
Label,
|
|
6
|
+
VideoFile,
|
|
7
|
+
LabelVideoSegment,
|
|
8
|
+
InformationSource
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from endoreg_db.serializers import LabelVideoSegmentSerializer
|
|
16
|
+
|
|
17
|
+
def _get_video_file(self, video_id):
|
|
18
|
+
"""
|
|
19
|
+
Retrieve a VideoFile instance by its ID.
|
|
20
|
+
|
|
21
|
+
Raises a serializers.ValidationError if the VideoFile does not exist.
|
|
22
|
+
"""
|
|
23
|
+
try:
|
|
24
|
+
return VideoFile.objects.get(id=video_id)
|
|
25
|
+
except ObjectDoesNotExist as exc:
|
|
26
|
+
raise serializers.ValidationError(f"VideoFile with id {video_id} does not exist") from exc
|
|
27
|
+
|
|
28
|
+
def _get_label(self, label_id, label_name):
|
|
29
|
+
"""
|
|
30
|
+
Retrieve a Label instance by ID or name, creating it if necessary.
|
|
31
|
+
|
|
32
|
+
Raises a ValidationError if the label cannot be found, created, or if neither identifier is provided.
|
|
33
|
+
"""
|
|
34
|
+
if label_id:
|
|
35
|
+
try:
|
|
36
|
+
return Label.objects.get(id=label_id)
|
|
37
|
+
except ObjectDoesNotExist as exc:
|
|
38
|
+
raise serializers.ValidationError(f"Label with id {label_id} does not exist") from exc
|
|
39
|
+
elif label_name:
|
|
40
|
+
label, _ = Label.get_or_create_from_name(label_name)
|
|
41
|
+
if not label:
|
|
42
|
+
raise serializers.ValidationError(f"Failed to create or retrieve label with name {label_name}")
|
|
43
|
+
return label
|
|
44
|
+
else:
|
|
45
|
+
raise serializers.ValidationError("Either label_id or label_name must be provided")
|
|
46
|
+
|
|
47
|
+
def _validate_fps(self, video_file):
|
|
48
|
+
"""
|
|
49
|
+
Validate and return the frames per second (FPS) value from a video file.
|
|
50
|
+
|
|
51
|
+
Raises a validation error if the FPS is missing, not a positive number, or cannot be converted to a float.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
float: The validated FPS value.
|
|
55
|
+
"""
|
|
56
|
+
fps_raw = video_file.get_fps()
|
|
57
|
+
if fps_raw is None:
|
|
58
|
+
raise serializers.ValidationError("Video file must have a defined FPS")
|
|
59
|
+
try:
|
|
60
|
+
fps = float(fps_raw)
|
|
61
|
+
if fps <= 0:
|
|
62
|
+
raise ValueError("FPS must be a positive number")
|
|
63
|
+
except (ValueError, TypeError):
|
|
64
|
+
raise serializers.ValidationError("Invalid FPS format in video file")
|
|
65
|
+
return fps
|
|
66
|
+
|
|
67
|
+
def _calculate_frame_numbers(self, validated_data, fps):
|
|
68
|
+
"""
|
|
69
|
+
Convert start and end times in the input data to corresponding frame numbers using the provided FPS value.
|
|
70
|
+
|
|
71
|
+
Parameters:
|
|
72
|
+
validated_data (dict): Input data containing 'start_time' and 'end_time' keys.
|
|
73
|
+
fps (float): Frames per second of the video.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
dict: The input data dictionary updated with 'start_frame_number' and 'end_frame_number' keys.
|
|
77
|
+
|
|
78
|
+
Raises:
|
|
79
|
+
serializers.ValidationError: If frame numbers cannot be determined from the provided data.
|
|
80
|
+
"""
|
|
81
|
+
if validated_data.get('start_time') is not None:
|
|
82
|
+
validated_data['start_frame_number'] = int(float(validated_data['start_time']) * fps)
|
|
83
|
+
if validated_data.get('end_time') is not None:
|
|
84
|
+
validated_data['end_frame_number'] = int(float(validated_data['end_time']) * fps)
|
|
85
|
+
if 'start_frame_number' not in validated_data or 'end_frame_number' not in validated_data:
|
|
86
|
+
raise serializers.ValidationError("Could not determine frame numbers from provided data")
|
|
87
|
+
return validated_data
|
|
88
|
+
|
|
89
|
+
def _get_information_source(self):
|
|
90
|
+
"""
|
|
91
|
+
Retrieve or create the information source for manual annotation.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
InformationSource: The source object representing manual annotation.
|
|
95
|
+
"""
|
|
96
|
+
source, _ = InformationSource.objects.get_or_create(
|
|
97
|
+
name='Manual Annotation',
|
|
98
|
+
defaults={
|
|
99
|
+
'description': 'Manually created label segments via web interface',
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
return source
|
|
103
|
+
|
|
104
|
+
def _create(self:"LabelVideoSegmentSerializer", validated_data):
|
|
105
|
+
"""
|
|
106
|
+
Create and persist a new LabelVideoSegment instance from validated input data.
|
|
107
|
+
|
|
108
|
+
This method extracts relevant fields from the input, retrieves or creates related objects (video file, label, information source), validates video FPS, calculates frame numbers from time values, and creates a new LabelVideoSegment. Raises a validation error if required data is missing or invalid, or if creation fails.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
LabelVideoSegment: The newly created and saved segment instance.
|
|
112
|
+
"""
|
|
113
|
+
try:
|
|
114
|
+
# Extract convenience fields
|
|
115
|
+
video_id = validated_data.pop('video_id')
|
|
116
|
+
label_id = validated_data.pop('label_id', None)
|
|
117
|
+
label_name = validated_data.pop('label_name', None)
|
|
118
|
+
start_time = validated_data.pop('start_time', None)
|
|
119
|
+
end_time = validated_data.pop('end_time', None)
|
|
120
|
+
|
|
121
|
+
video_file = self.get_video_file(video_id)
|
|
122
|
+
label = self.get_label(label_id, label_name)
|
|
123
|
+
fps = self.validate_fps(video_file)
|
|
124
|
+
validated_data['start_time'] = start_time
|
|
125
|
+
validated_data['end_time'] = end_time
|
|
126
|
+
validated_data = self.calculate_frame_numbers(validated_data, fps)
|
|
127
|
+
source = self.get_information_source()
|
|
128
|
+
|
|
129
|
+
# Create the segment directly
|
|
130
|
+
segment = LabelVideoSegment.safe_create(
|
|
131
|
+
video_file=video_file,
|
|
132
|
+
label=label,
|
|
133
|
+
source=source,
|
|
134
|
+
start_frame_number=validated_data['start_frame_number'],
|
|
135
|
+
end_frame_number=validated_data['end_frame_number'],
|
|
136
|
+
prediction_meta=None # No prediction meta for manual annotations
|
|
137
|
+
)
|
|
138
|
+
segment.save()
|
|
139
|
+
|
|
140
|
+
logger.info("Created new video segment: %s for video %s with label %s",
|
|
141
|
+
segment.pk, video_id, label.name if label else 'None')
|
|
142
|
+
return segment
|
|
143
|
+
|
|
144
|
+
except serializers.ValidationError as e:
|
|
145
|
+
logger.error("Validation error while creating video segment: %s", str(e))
|
|
146
|
+
raise
|
|
147
|
+
except Exception as e:
|
|
148
|
+
logger.error("Unexpected error while creating video segment: %s", str(e))
|
|
149
|
+
raise serializers.ValidationError(f"Failed to create segment: {str(e)}")
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Dict, Any, Optional
|
|
2
|
+
from django.core.exceptions import ObjectDoesNotExist
|
|
3
|
+
from rest_framework import serializers
|
|
4
|
+
from endoreg_db.models import (
|
|
5
|
+
Label,
|
|
6
|
+
VideoFile,
|
|
7
|
+
LabelVideoSegment
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from endoreg_db.serializers import LabelVideoSegmentSerializer
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _validate_fps(video: "VideoFile"):
|
|
18
|
+
"""Raises a ValidationError if the video's FPS is invalid."""
|
|
19
|
+
fps = video.get_fps()
|
|
20
|
+
if not fps or fps <= 0:
|
|
21
|
+
raise serializers.ValidationError("The video must have a valid FPS to convert times to frames.")
|
|
22
|
+
return fps
|
|
23
|
+
|
|
24
|
+
def _convert_time_to_frame(time_value: float, fps: float) -> int:
|
|
25
|
+
"""Converts a time value in seconds to a frame number."""
|
|
26
|
+
return int(time_value * fps)
|
|
27
|
+
|
|
28
|
+
def _update_frames_from_data(instance: "LabelVideoSegment", validated_data: Dict[str, Any], fps: Optional[float]):
|
|
29
|
+
"""Updates start and end frames from either time or frame data."""
|
|
30
|
+
if 'start_time' in validated_data:
|
|
31
|
+
if fps is None:
|
|
32
|
+
fps = _validate_fps(instance.video)
|
|
33
|
+
instance.start_frame_number = _convert_time_to_frame(validated_data['start_time'], fps)
|
|
34
|
+
elif 'start_frame' in validated_data:
|
|
35
|
+
instance.start_frame_number = validated_data['start_frame']
|
|
36
|
+
|
|
37
|
+
if 'end_time' in validated_data:
|
|
38
|
+
if fps is None:
|
|
39
|
+
fps = _validate_fps(instance.video)
|
|
40
|
+
instance.end_frame_number = _convert_time_to_frame(validated_data['end_time'], fps)
|
|
41
|
+
elif 'end_frame' in validated_data:
|
|
42
|
+
instance.end_frame_number = validated_data['end_frame']
|
|
43
|
+
|
|
44
|
+
def _update(instance: "LabelVideoSegment", validated_data: Dict[str, Any]) -> "LabelVideoSegment":
|
|
45
|
+
"""
|
|
46
|
+
Handles the update logic for a LabelVideoSegment instance.
|
|
47
|
+
This function is designed to be used within a serializer's update method.
|
|
48
|
+
"""
|
|
49
|
+
video: Optional["VideoFile"] = validated_data.get('video')
|
|
50
|
+
fps = None
|
|
51
|
+
|
|
52
|
+
if video and video != instance.video:
|
|
53
|
+
instance.video = video
|
|
54
|
+
fps = _validate_fps(video) # Validate FPS for the new video
|
|
55
|
+
|
|
56
|
+
if 'label' in validated_data:
|
|
57
|
+
instance.label = validated_data['label']
|
|
58
|
+
|
|
59
|
+
_update_frames_from_data(instance, validated_data, fps)
|
|
60
|
+
|
|
61
|
+
# Final validation of frame numbers
|
|
62
|
+
if instance.start_frame_number >= instance.end_frame_number:
|
|
63
|
+
raise serializers.ValidationError("start_frame must be less than end_frame.")
|
|
64
|
+
|
|
65
|
+
if instance.video and instance.end_frame_number > instance.video.frame_count:
|
|
66
|
+
raise serializers.ValidationError("end_frame cannot exceed the total frames of the video.")
|
|
67
|
+
|
|
68
|
+
instance.save()
|
|
69
|
+
return instance
|
|
70
|
+
|
|
71
|
+
def _update(self:"LabelVideoSegmentSerializer", instance, validated_data):
|
|
72
|
+
"""
|
|
73
|
+
Update a LabelVideoSegment instance with new validated data.
|
|
74
|
+
|
|
75
|
+
This method updates the associated video file, label (by ID or name), and segment boundaries (start and end times converted to frame numbers based on the video's FPS). If the referenced video or label does not exist, or if any error occurs during the update, a validation error is raised.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
The updated LabelVideoSegment instance.
|
|
79
|
+
"""
|
|
80
|
+
try:
|
|
81
|
+
# Handle time-based updates
|
|
82
|
+
start_time = validated_data.pop('start_time', None)
|
|
83
|
+
end_time = validated_data.pop('end_time', None)
|
|
84
|
+
video_id = validated_data.pop('video_id', None)
|
|
85
|
+
label_id = validated_data.pop('label_id', None)
|
|
86
|
+
label_name = validated_data.pop('label_name', None)
|
|
87
|
+
|
|
88
|
+
# Update video if provided
|
|
89
|
+
if video_id and (not instance.video_file or video_id != instance.video_file.id):
|
|
90
|
+
try:
|
|
91
|
+
instance.video_file = VideoFile.objects.get(id=video_id)
|
|
92
|
+
except ObjectDoesNotExist as exc:
|
|
93
|
+
raise serializers.ValidationError(f"VideoFile with id {video_id} does not exist") from exc
|
|
94
|
+
|
|
95
|
+
# Update label if provided
|
|
96
|
+
if label_id is not None:
|
|
97
|
+
if label_id:
|
|
98
|
+
try:
|
|
99
|
+
instance.label = Label.objects.get(id=label_id)
|
|
100
|
+
except ObjectDoesNotExist as exc:
|
|
101
|
+
raise serializers.ValidationError(f"Label with id {label_id} does not exist") from exc
|
|
102
|
+
else:
|
|
103
|
+
instance.label = None
|
|
104
|
+
elif label_name is not None:
|
|
105
|
+
if label_name:
|
|
106
|
+
instance.label = self.get_or_create_label_from_name(label_name)
|
|
107
|
+
else:
|
|
108
|
+
instance.label = None
|
|
109
|
+
|
|
110
|
+
def _get_valid_fps(video_file):
|
|
111
|
+
"""
|
|
112
|
+
Extract and validate the frames-per-second (FPS) value from a video file object.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
float: The FPS value as a positive float. Defaults to 30.0 if missing, invalid, or non-positive.
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
# Convert time to frame numbers if provided
|
|
119
|
+
if start_time is not None:
|
|
120
|
+
fps = _validate_fps(instance.video_file)
|
|
121
|
+
instance.start_frame_number = _convert_time_to_frame(start_time, fps)
|
|
122
|
+
|
|
123
|
+
if end_time is not None:
|
|
124
|
+
fps = _validate_fps(instance.video_file)
|
|
125
|
+
instance.end_frame_number = _convert_time_to_frame(end_time, fps)
|
|
126
|
+
|
|
127
|
+
# Update other fields
|
|
128
|
+
for attr, value in validated_data.items():
|
|
129
|
+
setattr(instance, attr, value)
|
|
130
|
+
|
|
131
|
+
instance.save()
|
|
132
|
+
logger.info("Updated video segment: %s", instance.pk)
|
|
133
|
+
return instance
|
|
134
|
+
|
|
135
|
+
except Exception as e:
|
|
136
|
+
logger.error("Error updating video segment %s: %s", instance.pk, str(e))
|
|
137
|
+
raise serializers.ValidationError(f"Failed to update segment: {str(e)}")
|
|
138
|
+
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from rest_framework import serializers
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from endoreg_db.serializers import LabelVideoSegmentSerializer
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
def _validate(self:"LabelVideoSegmentSerializer", attrs):
|
|
10
|
+
"""
|
|
11
|
+
Validate video segment data, ensuring the presence and logical consistency of either time-based or frame-based segment information.
|
|
12
|
+
|
|
13
|
+
Raises:
|
|
14
|
+
ValidationError: If neither valid time nor frame data is provided, or if time/frame constraints are violated.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
dict: The validated attributes for the video segment.
|
|
18
|
+
"""
|
|
19
|
+
logger.debug("Validation started")
|
|
20
|
+
video_id, label_id = self.extract_and_validate_basic_attrs(attrs)
|
|
21
|
+
instance = getattr(self, 'instance', None)
|
|
22
|
+
start_time, end_time = self.process_time_data(attrs, instance)
|
|
23
|
+
start_frame_number, end_frame_number = self.process_frame_data(attrs, instance)
|
|
24
|
+
has_time_data, has_frame_data = self.validate_time_and_frame_presence(start_time, end_time, start_frame_number, end_frame_number)
|
|
25
|
+
label_id = attrs.get('label_id')
|
|
26
|
+
label_name = attrs.get('label_name')
|
|
27
|
+
if not label_id and not label_name:
|
|
28
|
+
logger.info("Creating segment without label")
|
|
29
|
+
if has_time_data:
|
|
30
|
+
self.validate_time_constraints(start_time, end_time)
|
|
31
|
+
if has_frame_data:
|
|
32
|
+
self.validate_frame_constraints(start_frame_number, end_frame_number)
|
|
33
|
+
logger.debug(f"Attributes after validation: {attrs}")
|
|
34
|
+
return attrs
|
|
35
|
+
|
|
36
|
+
def _extract_and_validate_basic_attrs(self:"LabelVideoSegmentSerializer", attrs):
|
|
37
|
+
"""
|
|
38
|
+
Extract and return the video and label identifiers from the provided attributes or initial data.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
Tuple containing the resolved video ID and label ID.
|
|
42
|
+
"""
|
|
43
|
+
video_id = attrs.get('video_id') or self.initial_data.get('video_id') or self.initial_data.get('video_file')
|
|
44
|
+
label_id = attrs.get('label_id') or self.initial_data.get('label_id') or self.initial_data.get('label')
|
|
45
|
+
logger.debug(f"Validating video segment: video_id={video_id}, label_id={label_id}, attrs={{k: v for k, v in attrs.items() if k not in ['video_file', 'label']}}")
|
|
46
|
+
return video_id, label_id
|
|
47
|
+
|
|
48
|
+
def _process_time_data(self:"LabelVideoSegmentSerializer", attrs, instance):
|
|
49
|
+
"""
|
|
50
|
+
Extract and convert start and end time values from input data, ensuring they are floats or None.
|
|
51
|
+
|
|
52
|
+
Parameters:
|
|
53
|
+
attrs (dict): Input attributes containing potential time values.
|
|
54
|
+
instance: Existing object instance to use as a fallback for time values.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
tuple: A pair (start_time, end_time), each as a float or None if missing or invalid.
|
|
58
|
+
"""
|
|
59
|
+
start_time = attrs.get('start_time', None)
|
|
60
|
+
end_time = attrs.get('end_time', None)
|
|
61
|
+
if instance is not None:
|
|
62
|
+
if start_time is None:
|
|
63
|
+
start_time = getattr(instance, 'start_time', None)
|
|
64
|
+
if end_time is None:
|
|
65
|
+
end_time = getattr(instance, 'end_time', None)
|
|
66
|
+
# Always convert start_time/end_time to float if present
|
|
67
|
+
if 'start_time' in self.initial_data:
|
|
68
|
+
try:
|
|
69
|
+
attrs['start_time'] = float(self.initial_data['start_time'])
|
|
70
|
+
except (TypeError, ValueError):
|
|
71
|
+
attrs['start_time'] = None
|
|
72
|
+
start_time = attrs['start_time']
|
|
73
|
+
elif start_time is not None:
|
|
74
|
+
try:
|
|
75
|
+
start_time = float(start_time)
|
|
76
|
+
attrs['start_time'] = start_time
|
|
77
|
+
except (TypeError, ValueError):
|
|
78
|
+
start_time = None
|
|
79
|
+
attrs['start_time'] = None
|
|
80
|
+
if 'end_time' in self.initial_data:
|
|
81
|
+
try:
|
|
82
|
+
attrs['end_time'] = float(self.initial_data['end_time'])
|
|
83
|
+
except (TypeError, ValueError):
|
|
84
|
+
attrs['end_time'] = None
|
|
85
|
+
end_time = attrs['end_time']
|
|
86
|
+
elif end_time is not None:
|
|
87
|
+
try:
|
|
88
|
+
end_time = float(end_time)
|
|
89
|
+
attrs['end_time'] = end_time
|
|
90
|
+
except (TypeError, ValueError):
|
|
91
|
+
end_time = None
|
|
92
|
+
attrs['end_time'] = None
|
|
93
|
+
return start_time, end_time
|
|
94
|
+
|
|
95
|
+
def _process_frame_data(self:"LabelVideoSegmentSerializer", attrs, instance):
|
|
96
|
+
"""
|
|
97
|
+
Retrieve start and end frame numbers from input attributes or an existing instance.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
tuple: A pair containing the start and end frame numbers, or None if not available.
|
|
101
|
+
"""
|
|
102
|
+
start_frame_number = attrs.get('start_frame_number')
|
|
103
|
+
end_frame_number = attrs.get('end_frame_number')
|
|
104
|
+
if instance is not None:
|
|
105
|
+
if start_frame_number is None:
|
|
106
|
+
start_frame_number = getattr(instance, 'start_frame_number', None)
|
|
107
|
+
if end_frame_number is None:
|
|
108
|
+
end_frame_number = getattr(instance, 'end_frame_number', None)
|
|
109
|
+
return start_frame_number, end_frame_number
|
|
110
|
+
|
|
111
|
+
def _validate_time_and_frame_presence(self:"LabelVideoSegmentSerializer", start_time, end_time, start_frame_number, end_frame_number):
|
|
112
|
+
"""
|
|
113
|
+
Check that either both time values or both frame number values are provided for a video segment.
|
|
114
|
+
|
|
115
|
+
Raises a ValidationError if neither a complete time range nor a complete frame range is present.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
has_time_data (bool): True if both start_time and end_time are provided.
|
|
119
|
+
has_frame_data (bool): True if both start_frame_number and end_frame_number are provided.
|
|
120
|
+
"""
|
|
121
|
+
has_time_data = start_time is not None and end_time is not None
|
|
122
|
+
has_frame_data = start_frame_number is not None and end_frame_number is not None
|
|
123
|
+
if not has_time_data and not has_frame_data:
|
|
124
|
+
raise serializers.ValidationError(
|
|
125
|
+
"Either start_time/end_time or start_frame_number/end_frame_number must be provided"
|
|
126
|
+
)
|
|
127
|
+
return has_time_data, has_frame_data
|
|
128
|
+
|
|
129
|
+
def _validate_time_constraints(self:"LabelVideoSegmentSerializer", start_time, end_time):
|
|
130
|
+
"""
|
|
131
|
+
Validate that the start and end times for a video segment are logically consistent.
|
|
132
|
+
|
|
133
|
+
Raises a ValidationError if start_time is negative or if end_time is not strictly greater than start_time.
|
|
134
|
+
"""
|
|
135
|
+
if start_time < 0:
|
|
136
|
+
raise serializers.ValidationError("start_time must be non-negative")
|
|
137
|
+
if end_time <= start_time:
|
|
138
|
+
raise serializers.ValidationError("end_time must be greater than start_time")
|
|
139
|
+
|
|
140
|
+
def _validate_frame_constraints(self:"LabelVideoSegmentSerializer", start_frame_number, end_frame_number):
|
|
141
|
+
"""
|
|
142
|
+
Validate that frame number constraints are satisfied for a video segment.
|
|
143
|
+
|
|
144
|
+
Raises a ValidationError if `start_frame_number` is negative or if `end_frame_number` is not greater than `start_frame_number`.
|
|
145
|
+
"""
|
|
146
|
+
if start_frame_number < 0:
|
|
147
|
+
raise serializers.ValidationError("start_frame_number must be non-negative")
|
|
148
|
+
if end_frame_number <= start_frame_number:
|
|
149
|
+
raise serializers.ValidationError("end_frame_number must be greater than start_frame_number")
|