endoreg-db 0.6.0__py3-none-any.whl → 0.6.2__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/case_generator/__init__.py +0 -0
- endoreg_db/case_generator/case_generator.py +159 -0
- endoreg_db/case_generator/lab_sample_factory.py +33 -0
- endoreg_db/case_generator/utils.py +30 -0
- endoreg_db/data/__init__.py +118 -0
- endoreg_db/data/agl_service/data.yaml +19 -0
- endoreg_db/data/ai_model/data.yaml +7 -0
- endoreg_db/data/ai_model_label/label/data.yaml +88 -0
- endoreg_db/data/ai_model_label/label-set/data.yaml +21 -0
- endoreg_db/data/ai_model_label/label-type/data.yaml +7 -0
- endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +5 -0
- endoreg_db/data/ai_model_type/data.yaml +7 -0
- endoreg_db/data/ai_model_video_segmentation_label/base_segmentation.yaml +176 -0
- endoreg_db/data/ai_model_video_segmentation_labelset/data.yaml +20 -0
- endoreg_db/data/case_template/rule/00_patient_lab_sample_add_default_value.yaml +167 -0
- endoreg_db/data/case_template/rule/01_patient-set-age.yaml +8 -0
- endoreg_db/data/case_template/rule/01_patient-set-gender.yaml +9 -0
- endoreg_db/data/case_template/rule/11_create_patient_lab_sample.yaml +23 -0
- endoreg_db/data/case_template/rule/12_create-patient_medication-anticoagulation.yaml +19 -0
- endoreg_db/data/case_template/rule/13_create-patient_medication_schedule-anticoagulation.yaml +19 -0
- endoreg_db/data/case_template/rule/19_create_patient.yaml +17 -0
- endoreg_db/data/case_template/rule_type/base_types.yaml +35 -0
- endoreg_db/data/case_template/rule_value/.init +0 -0
- endoreg_db/data/case_template/rule_value_type/base_types.yaml +59 -0
- endoreg_db/data/case_template/template/base.yaml +8 -0
- endoreg_db/data/case_template/template_type/pre_endoscopy.yaml +3 -0
- endoreg_db/data/case_template/tmp/_rule_value +13 -0
- endoreg_db/data/case_template/tmp/rule/01_atrial_fibrillation.yaml +21 -0
- endoreg_db/data/case_template/tmp/rule/02_create_object.yaml +10 -0
- endoreg_db/data/case_template/tmp/template/atrial_fibrillation_low_risk.yaml +7 -0
- endoreg_db/data/center/data.yaml +90 -0
- endoreg_db/data/center_resource/green_endoscopy_dashboard_CenterResource.yaml +144 -0
- endoreg_db/data/center_waste/green_endoscopy_dashboard_CenterWaste.yaml +48 -0
- endoreg_db/data/contraindication/bleeding.yaml +11 -0
- endoreg_db/data/disease/cardiovascular.yaml +37 -0
- endoreg_db/data/disease/hepatology.yaml +5 -0
- endoreg_db/data/disease/misc.yaml +6 -0
- endoreg_db/data/disease/renal.yaml +5 -0
- endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +6 -0
- endoreg_db/data/disease_classification/coronary_vessel_disease.yaml +6 -0
- endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +41 -0
- endoreg_db/data/disease_classification_choice/coronary_vessel_disease.yaml +20 -0
- endoreg_db/data/distribution/date/patient.yaml +7 -0
- endoreg_db/data/distribution/multiple_categorical/.init +0 -0
- endoreg_db/data/distribution/numeric/data.yaml +14 -0
- endoreg_db/data/distribution/single_categorical/patient.yaml +7 -0
- endoreg_db/data/emission_factor/green_endoscopy_dashboard_EmissionFactor.yaml +132 -0
- endoreg_db/data/endoscope/data.yaml +93 -0
- endoreg_db/data/endoscope_type/data.yaml +11 -0
- endoreg_db/data/endoscopy_processor/data.yaml +47 -0
- endoreg_db/data/event/cardiology.yaml +28 -0
- endoreg_db/data/event/neurology.yaml +14 -0
- endoreg_db/data/event/surgery.yaml +13 -0
- endoreg_db/data/event/thrombembolism.yaml +20 -0
- endoreg_db/data/examination/examinations/data.yaml +66 -0
- endoreg_db/data/examination/time/data.yaml +48 -0
- endoreg_db/data/examination/time-type/data.yaml +8 -0
- endoreg_db/data/examination/type/data.yaml +5 -0
- endoreg_db/data/examination_indication/endoscopy.yaml +8 -0
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +8 -0
- endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +101 -0
- endoreg_db/data/finding/data.yaml +141 -0
- endoreg_db/data/finding_intervention/endoscopy.yaml +138 -0
- endoreg_db/data/finding_intervention_type/endoscopy.yaml +15 -0
- endoreg_db/data/finding_location_classification/colonoscopy.yaml +46 -0
- endoreg_db/data/finding_location_classification_choice/colonoscopy.yaml +240 -0
- endoreg_db/data/finding_morphology_classification/colonoscopy.yaml +48 -0
- endoreg_db/data/finding_morphology_classification_choice/colon_lesion_circularity_default.yaml +34 -0
- endoreg_db/data/finding_morphology_classification_choice/colon_lesion_nice.yaml +20 -0
- endoreg_db/data/finding_morphology_classification_choice/colon_lesion_paris.yaml +65 -0
- endoreg_db/data/finding_morphology_classification_choice/colon_lesion_planarity_default.yaml +56 -0
- endoreg_db/data/finding_morphology_classification_choice/colon_lesion_surface_intact_default.yaml +39 -0
- endoreg_db/data/finding_morphology_classification_choice/colonoscopy_size.yaml +57 -0
- endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +79 -0
- endoreg_db/data/finding_type/data.yaml +30 -0
- endoreg_db/data/gender/data.yaml +35 -0
- endoreg_db/data/information_source/data.yaml +30 -0
- endoreg_db/data/information_source/medication.yaml +6 -0
- endoreg_db/data/lab_value/cardiac_enzymes.yaml +37 -0
- endoreg_db/data/lab_value/coagulation.yaml +54 -0
- endoreg_db/data/lab_value/electrolytes.yaml +228 -0
- endoreg_db/data/lab_value/gastrointestinal_function.yaml +133 -0
- endoreg_db/data/lab_value/hematology.yaml +184 -0
- endoreg_db/data/lab_value/hormones.yaml +59 -0
- endoreg_db/data/lab_value/lipids.yaml +53 -0
- endoreg_db/data/lab_value/misc.yaml +33 -0
- endoreg_db/data/lab_value/renal_function.yaml +12 -0
- endoreg_db/data/log_type/data.yaml +57 -0
- endoreg_db/data/lx_client_tag/base.yaml +54 -0
- endoreg_db/data/lx_client_type/base.yaml +30 -0
- endoreg_db/data/lx_permission/base.yaml +24 -0
- endoreg_db/data/lx_permission/endoreg.yaml +52 -0
- endoreg_db/data/material/material.yaml +91 -0
- endoreg_db/data/medication/anticoagulation.yaml +65 -0
- endoreg_db/data/medication/tah.yaml +70 -0
- endoreg_db/data/medication_indication/anticoagulation.yaml +115 -0
- endoreg_db/data/medication_indication_type/data.yaml +11 -0
- endoreg_db/data/medication_indication_type/thrombembolism.yaml +41 -0
- endoreg_db/data/medication_intake_time/base.yaml +31 -0
- endoreg_db/data/medication_schedule/apixaban.yaml +95 -0
- endoreg_db/data/medication_schedule/ass.yaml +12 -0
- endoreg_db/data/medication_schedule/enoxaparin.yaml +26 -0
- endoreg_db/data/names_first/first_names.yaml +51 -0
- endoreg_db/data/names_last/last_names.yaml +51 -0
- endoreg_db/data/network_device/data.yaml +59 -0
- endoreg_db/data/network_device_type/data.yaml +12 -0
- endoreg_db/data/organ/data.yaml +29 -0
- endoreg_db/data/patient_lab_sample_type/generic.yaml +6 -0
- endoreg_db/data/pdf_type/data.yaml +29 -0
- endoreg_db/data/product/green_endoscopy_dashboard_Product.yaml +66 -0
- endoreg_db/data/product_group/green_endoscopy_dashboard_ProductGroup.yaml +33 -0
- endoreg_db/data/product_material/green_endoscopy_dashboard_ProductMaterial.yaml +308 -0
- endoreg_db/data/product_weight/green_endoscopy_dashboard_ProductWeight.yaml +88 -0
- endoreg_db/data/profession/data.yaml +70 -0
- endoreg_db/data/reference_product/green_endoscopy_dashboard_ReferenceProduct.yaml +55 -0
- endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +30 -0
- endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +19 -0
- endoreg_db/data/resource/green_endoscopy_dashboard_Resource.yaml +15 -0
- endoreg_db/data/tmp/chronic_kidney_disease.yaml +0 -0
- endoreg_db/data/tmp/congestive_heart_failure.yaml +0 -0
- endoreg_db/data/transport_route/green_endoscopy_dashboard_TransportRoute.yaml +12 -0
- endoreg_db/data/unit/concentration.yaml +92 -0
- endoreg_db/data/unit/data.yaml +17 -0
- endoreg_db/data/unit/length.yaml +31 -0
- endoreg_db/data/unit/misc.yaml +20 -0
- endoreg_db/data/unit/rate.yaml +6 -0
- endoreg_db/data/unit/time.yaml +13 -0
- endoreg_db/data/unit/volume.yaml +35 -0
- endoreg_db/data/unit/weight.yaml +38 -0
- endoreg_db/data/waste/data.yaml +12 -0
- endoreg_db/forms/__init__.py +5 -0
- endoreg_db/forms/examination_form.py +11 -0
- endoreg_db/forms/patient_finding_intervention_form.py +19 -0
- endoreg_db/forms/patient_form.py +26 -0
- endoreg_db/forms/questionnaires/__init__.py +1 -0
- endoreg_db/forms/questionnaires/tto_questionnaire.py +23 -0
- endoreg_db/forms/settings/__init__.py +8 -0
- endoreg_db/forms/unit.py +6 -0
- endoreg_db/management/__init__.py +0 -0
- endoreg_db/management/commands/__init__.py +0 -0
- endoreg_db/management/commands/_load_model_template.py +41 -0
- endoreg_db/management/commands/delete_all.py +18 -0
- endoreg_db/management/commands/fetch_legacy_image_dataset.py +32 -0
- endoreg_db/management/commands/fix_auth_permission.py +20 -0
- endoreg_db/management/commands/load_active_model_data.py +45 -0
- endoreg_db/management/commands/load_ai_model_data.py +79 -0
- endoreg_db/management/commands/load_ai_model_label_data.py +59 -0
- endoreg_db/management/commands/load_base_db_data.py +178 -0
- endoreg_db/management/commands/load_center_data.py +43 -0
- endoreg_db/management/commands/load_contraindication_data.py +41 -0
- endoreg_db/management/commands/load_disease_classification_choices_data.py +41 -0
- endoreg_db/management/commands/load_disease_classification_data.py +41 -0
- endoreg_db/management/commands/load_disease_data.py +62 -0
- endoreg_db/management/commands/load_distribution_data.py +66 -0
- endoreg_db/management/commands/load_endoscope_data.py +68 -0
- endoreg_db/management/commands/load_event_data.py +41 -0
- endoreg_db/management/commands/load_examination_data.py +75 -0
- endoreg_db/management/commands/load_examination_indication_data.py +65 -0
- endoreg_db/management/commands/load_finding_data.py +171 -0
- endoreg_db/management/commands/load_g_play_data.py +113 -0
- endoreg_db/management/commands/load_gender_data.py +44 -0
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +133 -0
- endoreg_db/management/commands/load_information_source.py +45 -0
- endoreg_db/management/commands/load_lab_value_data.py +50 -0
- endoreg_db/management/commands/load_logging_data.py +39 -0
- endoreg_db/management/commands/load_lx_data.py +64 -0
- endoreg_db/management/commands/load_medication_data.py +103 -0
- endoreg_db/management/commands/load_medication_indication_data.py +63 -0
- endoreg_db/management/commands/load_medication_indication_type_data.py +41 -0
- endoreg_db/management/commands/load_medication_intake_time_data.py +41 -0
- endoreg_db/management/commands/load_medication_schedule_data.py +55 -0
- endoreg_db/management/commands/load_name_data.py +37 -0
- endoreg_db/management/commands/load_network_data.py +57 -0
- endoreg_db/management/commands/load_organ_data.py +43 -0
- endoreg_db/management/commands/load_pdf_type_data.py +61 -0
- endoreg_db/management/commands/load_profession_data.py +44 -0
- endoreg_db/management/commands/load_report_reader_flag_data.py +46 -0
- endoreg_db/management/commands/load_unit_data.py +46 -0
- endoreg_db/management/commands/load_user_groups.py +28 -0
- endoreg_db/management/commands/register_ai_model.py +64 -0
- endoreg_db/management/commands/reset_celery_schedule.py +9 -0
- endoreg_db/migrations/0001_initial.py +2045 -0
- endoreg_db/migrations/0002_alter_frame_image_alter_rawframe_image.py +23 -0
- endoreg_db/migrations/0003_alter_frame_image_alter_rawframe_image.py +23 -0
- endoreg_db/migrations/0004_alter_rawvideofile_file_alter_video_file.py +25 -0
- endoreg_db/migrations/0005_rawvideofile_frame_count_and_more.py +33 -0
- endoreg_db/migrations/0006_frame_extracted_rawframe_extracted.py +23 -0
- endoreg_db/migrations/0007_rename_pseudo_patient_video_patient_and_more.py +24 -0
- endoreg_db/migrations/0008_remove_reportfile_patient_examination_and_more.py +48 -0
- endoreg_db/migrations/__init__.py +0 -0
- endoreg_db/models/__init__.py +376 -0
- endoreg_db/models/ai_model/__init__.py +4 -0
- endoreg_db/models/ai_model/active_model.py +9 -0
- endoreg_db/models/ai_model/ai_model.py +103 -0
- endoreg_db/models/ai_model/lightning/__init__.py +3 -0
- endoreg_db/models/ai_model/lightning/inference_dataset.py +53 -0
- endoreg_db/models/ai_model/lightning/multilabel_classification_net.py +155 -0
- endoreg_db/models/ai_model/lightning/postprocess.py +53 -0
- endoreg_db/models/ai_model/lightning/predict.py +172 -0
- endoreg_db/models/ai_model/lightning/prediction_visualizer.py +55 -0
- endoreg_db/models/ai_model/lightning/preprocess.py +68 -0
- endoreg_db/models/ai_model/lightning/run_visualizer.py +21 -0
- endoreg_db/models/ai_model/model_meta.py +250 -0
- endoreg_db/models/ai_model/model_type.py +36 -0
- endoreg_db/models/ai_model/utils.py +8 -0
- endoreg_db/models/annotation/__init__.py +32 -0
- endoreg_db/models/annotation/anonymized_image_annotation.py +115 -0
- endoreg_db/models/annotation/binary_classification_annotation_task.py +117 -0
- endoreg_db/models/annotation/image_classification.py +86 -0
- endoreg_db/models/annotation/video_segmentation_annotation.py +52 -0
- endoreg_db/models/annotation/video_segmentation_labelset.py +20 -0
- endoreg_db/models/case/__init__.py +1 -0
- endoreg_db/models/case/case.py +34 -0
- endoreg_db/models/case_template/__init__.py +15 -0
- endoreg_db/models/case_template/case_template.py +125 -0
- endoreg_db/models/case_template/case_template_rule.py +276 -0
- endoreg_db/models/case_template/case_template_rule_value.py +88 -0
- endoreg_db/models/case_template/case_template_type.py +28 -0
- endoreg_db/models/center/__init__.py +11 -0
- endoreg_db/models/center/center.py +51 -0
- endoreg_db/models/center/center_product.py +33 -0
- endoreg_db/models/center/center_resource.py +33 -0
- endoreg_db/models/center/center_waste.py +16 -0
- endoreg_db/models/contraindication/__init__.py +21 -0
- endoreg_db/models/data_file/__init__.py +39 -0
- endoreg_db/models/data_file/base_classes/__init__.py +7 -0
- endoreg_db/models/data_file/base_classes/abstract_frame.py +100 -0
- endoreg_db/models/data_file/base_classes/abstract_pdf.py +136 -0
- endoreg_db/models/data_file/base_classes/abstract_video.py +807 -0
- endoreg_db/models/data_file/base_classes/frame_helpers.py +17 -0
- endoreg_db/models/data_file/base_classes/prepare_bulk_frames.py +19 -0
- endoreg_db/models/data_file/base_classes/utils.py +80 -0
- endoreg_db/models/data_file/frame.py +29 -0
- endoreg_db/models/data_file/import_classes/__init__.py +18 -0
- endoreg_db/models/data_file/import_classes/processing_functions/__init__.py +35 -0
- endoreg_db/models/data_file/import_classes/processing_functions/pdf.py +28 -0
- endoreg_db/models/data_file/import_classes/processing_functions/video.py +260 -0
- endoreg_db/models/data_file/import_classes/raw_pdf.py +260 -0
- endoreg_db/models/data_file/import_classes/raw_video.py +288 -0
- endoreg_db/models/data_file/metadata/__init__.py +13 -0
- endoreg_db/models/data_file/metadata/pdf_meta.py +74 -0
- endoreg_db/models/data_file/metadata/sensitive_meta.py +290 -0
- endoreg_db/models/data_file/metadata/video_meta.py +199 -0
- endoreg_db/models/data_file/report_file.py +56 -0
- endoreg_db/models/data_file/video/__init__.py +11 -0
- endoreg_db/models/data_file/video/import_meta.py +25 -0
- endoreg_db/models/data_file/video/video.py +196 -0
- endoreg_db/models/data_file/video_segment.py +214 -0
- endoreg_db/models/disease.py +79 -0
- endoreg_db/models/emission/__init__.py +5 -0
- endoreg_db/models/emission/emission_factor.py +85 -0
- endoreg_db/models/event.py +73 -0
- endoreg_db/models/examination/__init__.py +9 -0
- endoreg_db/models/examination/examination.py +67 -0
- endoreg_db/models/examination/examination_indication.py +170 -0
- endoreg_db/models/examination/examination_time.py +53 -0
- endoreg_db/models/examination/examination_time_type.py +48 -0
- endoreg_db/models/examination/examination_type.py +40 -0
- endoreg_db/models/finding/__init__.py +11 -0
- endoreg_db/models/finding/finding.py +75 -0
- endoreg_db/models/finding/finding_intervention.py +60 -0
- endoreg_db/models/finding/finding_location_classification.py +94 -0
- endoreg_db/models/finding/finding_morphology_classification.py +89 -0
- endoreg_db/models/finding/finding_type.py +22 -0
- endoreg_db/models/hardware/__init__.py +2 -0
- endoreg_db/models/hardware/endoscope.py +60 -0
- endoreg_db/models/hardware/endoscopy_processor.py +155 -0
- endoreg_db/models/information_source.py +29 -0
- endoreg_db/models/label/__init__.py +1 -0
- endoreg_db/models/label/label.py +112 -0
- endoreg_db/models/laboratory/__init__.py +1 -0
- endoreg_db/models/laboratory/lab_value.py +111 -0
- endoreg_db/models/logging/__init__.py +11 -0
- endoreg_db/models/logging/agl_service.py +19 -0
- endoreg_db/models/logging/base.py +22 -0
- endoreg_db/models/logging/log_type.py +23 -0
- endoreg_db/models/logging/network_device.py +27 -0
- endoreg_db/models/lx/__init__.py +4 -0
- endoreg_db/models/lx/client.py +57 -0
- endoreg_db/models/lx/identity.py +34 -0
- endoreg_db/models/lx/permission.py +18 -0
- endoreg_db/models/lx/user.py +16 -0
- endoreg_db/models/medication/__init__.py +19 -0
- endoreg_db/models/medication/medication.py +33 -0
- endoreg_db/models/medication/medication_indication.py +50 -0
- endoreg_db/models/medication/medication_indication_type.py +34 -0
- endoreg_db/models/medication/medication_intake_time.py +26 -0
- endoreg_db/models/medication/medication_schedule.py +37 -0
- endoreg_db/models/network/__init__.py +9 -0
- endoreg_db/models/network/agl_service.py +38 -0
- endoreg_db/models/network/network_device.py +58 -0
- endoreg_db/models/network/network_device_type.py +23 -0
- endoreg_db/models/organ/__init__.py +38 -0
- endoreg_db/models/other/__init__.py +23 -0
- endoreg_db/models/other/distribution/__init__.py +44 -0
- endoreg_db/models/other/distribution/base_value_distribution.py +20 -0
- endoreg_db/models/other/distribution/date_value_distribution.py +91 -0
- endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +32 -0
- endoreg_db/models/other/distribution/numeric_value_distribution.py +97 -0
- endoreg_db/models/other/distribution/single_categorical_value_distribution.py +22 -0
- endoreg_db/models/other/distribution.py +5 -0
- endoreg_db/models/other/material.py +20 -0
- endoreg_db/models/other/resource.py +18 -0
- endoreg_db/models/other/transport_route.py +22 -0
- endoreg_db/models/other/waste.py +20 -0
- endoreg_db/models/patient/__init__.py +24 -0
- endoreg_db/models/patient/patient_examination.py +182 -0
- endoreg_db/models/patient/patient_finding.py +143 -0
- endoreg_db/models/patient/patient_finding_intervention.py +26 -0
- endoreg_db/models/patient/patient_finding_location.py +120 -0
- endoreg_db/models/patient/patient_finding_morphology.py +166 -0
- endoreg_db/models/permissions/__init__.py +44 -0
- endoreg_db/models/persons/__init__.py +34 -0
- endoreg_db/models/persons/examiner/__init__.py +2 -0
- endoreg_db/models/persons/examiner/examiner.py +60 -0
- endoreg_db/models/persons/examiner/examiner_type.py +2 -0
- endoreg_db/models/persons/first_name.py +18 -0
- endoreg_db/models/persons/gender.py +22 -0
- endoreg_db/models/persons/last_name.py +20 -0
- endoreg_db/models/persons/patient/__init__.py +8 -0
- endoreg_db/models/persons/patient/patient.py +389 -0
- endoreg_db/models/persons/patient/patient_disease.py +22 -0
- endoreg_db/models/persons/patient/patient_event.py +52 -0
- endoreg_db/models/persons/patient/patient_examination_indication.py +32 -0
- endoreg_db/models/persons/patient/patient_lab_sample.py +108 -0
- endoreg_db/models/persons/patient/patient_lab_value.py +197 -0
- endoreg_db/models/persons/patient/patient_medication.py +59 -0
- endoreg_db/models/persons/patient/patient_medication_schedule.py +88 -0
- endoreg_db/models/persons/person.py +31 -0
- endoreg_db/models/persons/portal_user_information.py +27 -0
- endoreg_db/models/prediction/__init__.py +8 -0
- endoreg_db/models/prediction/image_classification.py +51 -0
- endoreg_db/models/prediction/video_prediction_meta.py +306 -0
- endoreg_db/models/product/__init__.py +14 -0
- endoreg_db/models/product/product.py +110 -0
- endoreg_db/models/product/product_group.py +27 -0
- endoreg_db/models/product/product_material.py +28 -0
- endoreg_db/models/product/product_weight.py +38 -0
- endoreg_db/models/product/reference_product.py +115 -0
- endoreg_db/models/questionnaires/__init__.py +114 -0
- endoreg_db/models/quiz/__init__.py +9 -0
- endoreg_db/models/quiz/quiz_answer.py +41 -0
- endoreg_db/models/quiz/quiz_question.py +54 -0
- endoreg_db/models/report_reader/__init__.py +7 -0
- endoreg_db/models/report_reader/report_reader_config.py +53 -0
- endoreg_db/models/report_reader/report_reader_flag.py +20 -0
- endoreg_db/models/rules/__init__.py +5 -0
- endoreg_db/models/rules/rule.py +24 -0
- endoreg_db/models/rules/rule_applicator.py +224 -0
- endoreg_db/models/rules/rule_attribute_dtype.py +19 -0
- endoreg_db/models/rules/rule_type.py +22 -0
- endoreg_db/models/rules/ruleset.py +19 -0
- endoreg_db/models/unit.py +22 -0
- endoreg_db/queries/__init__.py +5 -0
- endoreg_db/queries/annotations/__init__.py +3 -0
- endoreg_db/queries/annotations/legacy.py +158 -0
- endoreg_db/queries/get/__init__.py +6 -0
- endoreg_db/queries/get/annotation.py +0 -0
- endoreg_db/queries/get/center.py +42 -0
- endoreg_db/queries/get/model.py +13 -0
- endoreg_db/queries/get/patient.py +14 -0
- endoreg_db/queries/get/patient_examination.py +20 -0
- endoreg_db/queries/get/prediction.py +0 -0
- endoreg_db/queries/get/report_file.py +33 -0
- endoreg_db/queries/get/video.py +31 -0
- endoreg_db/queries/get/video_import_meta.py +0 -0
- endoreg_db/queries/get/video_prediction_meta.py +0 -0
- endoreg_db/queries/sanity/__init_.py +0 -0
- endoreg_db/serializers/__init__.py +10 -0
- endoreg_db/serializers/ai_model.py +19 -0
- endoreg_db/serializers/annotation.py +14 -0
- endoreg_db/serializers/center.py +11 -0
- endoreg_db/serializers/examination.py +33 -0
- endoreg_db/serializers/frame.py +9 -0
- endoreg_db/serializers/hardware.py +21 -0
- endoreg_db/serializers/label.py +22 -0
- endoreg_db/serializers/patient.py +33 -0
- endoreg_db/serializers/prediction.py +10 -0
- endoreg_db/serializers/raw_video_meta_validation.py +13 -0
- endoreg_db/serializers/report_file.py +7 -0
- endoreg_db/serializers/video.py +20 -0
- endoreg_db/serializers/video_segmentation.py +492 -0
- endoreg_db/templates/admin/patient_finding_intervention.html +253 -0
- endoreg_db/templates/admin/start_examination.html +12 -0
- endoreg_db/templates/timeline.html +176 -0
- endoreg_db/utils/__init__.py +36 -0
- endoreg_db/utils/cropping.py +29 -0
- endoreg_db/utils/dataloader.py +118 -0
- endoreg_db/utils/dates.py +39 -0
- endoreg_db/utils/file_operations.py +30 -0
- endoreg_db/utils/hashs.py +152 -0
- endoreg_db/utils/legacy_ocr.py +201 -0
- endoreg_db/utils/names.py +74 -0
- endoreg_db/utils/ocr.py +190 -0
- endoreg_db/utils/parse_and_generate_yaml.py +46 -0
- endoreg_db/utils/pydantic_models/__init__.py +6 -0
- endoreg_db/utils/pydantic_models/db_config.py +57 -0
- endoreg_db/utils/uuid.py +4 -0
- endoreg_db/utils/validate_endo_roi.py +19 -0
- endoreg_db/utils/validate_subcategory_dict.py +91 -0
- endoreg_db/utils/video/__init__.py +13 -0
- endoreg_db/utils/video/extract_frames.py +121 -0
- endoreg_db/utils/video/transcode_videofile.py +111 -0
- endoreg_db/views/__init__.py +2 -0
- endoreg_db/views/csrf.py +7 -0
- endoreg_db/views/patient_views.py +90 -0
- endoreg_db/views/raw_video_meta_validation_views.py +38 -0
- endoreg_db/views/report_views.py +96 -0
- endoreg_db/views/video_segmentation_views.py +149 -0
- endoreg_db/views/views_for_timeline.py +46 -0
- {endoreg_db-0.6.0.dist-info → endoreg_db-0.6.2.dist-info}/METADATA +14 -4
- endoreg_db-0.6.2.dist-info/RECORD +420 -0
- {endoreg_db-0.6.0.dist-info → endoreg_db-0.6.2.dist-info}/WHEEL +1 -2
- endoreg_db-0.6.0.dist-info/RECORD +0 -11
- endoreg_db-0.6.0.dist-info/top_level.txt +0 -1
- {endoreg_db-0.6.0.dist-info → endoreg_db-0.6.2.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the ModelMeta and ModelMetaManager classes for managing AI model metadata.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Optional, TYPE_CHECKING
|
|
8
|
+
import shutil
|
|
9
|
+
|
|
10
|
+
from django.db import models
|
|
11
|
+
from django.core.validators import FileExtensionValidator
|
|
12
|
+
from icecream import ic
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from endoreg_db.models import LabelSet, AiModel # pylint: disable=import-outside-toplevel
|
|
16
|
+
|
|
17
|
+
PSEUDO_DIR = Path(os.environ.get("DJANGO_PSEUDO_DIR", Path("./erc_data")))
|
|
18
|
+
|
|
19
|
+
STORAGE_LOCATION = PSEUDO_DIR
|
|
20
|
+
WEIGHTS_DIR_NAME = "db_model_weights"
|
|
21
|
+
WEIGHTS_DIR = STORAGE_LOCATION / WEIGHTS_DIR_NAME
|
|
22
|
+
|
|
23
|
+
if not WEIGHTS_DIR.exists():
|
|
24
|
+
WEIGHTS_DIR.mkdir(parents=True)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ModelMetaManager(models.Manager):
|
|
28
|
+
"""
|
|
29
|
+
Custom manager for ModelMeta with additional query methods.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def get_by_natural_key(self, name: str, version: str) -> "ModelMeta":
|
|
33
|
+
"""Get the model by its natural key"""
|
|
34
|
+
return self.get(name=name, version=version)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ModelMeta(models.Model):
|
|
38
|
+
"""
|
|
39
|
+
Attributes:
|
|
40
|
+
name (str): The name of the model.
|
|
41
|
+
version (str): The version of the model.
|
|
42
|
+
type (ModelType): The type of the model.
|
|
43
|
+
labelset (LabelSet): Associated labels.
|
|
44
|
+
weights (FileField): Path to the model weights.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
name = models.CharField(max_length=255)
|
|
48
|
+
version = models.CharField(max_length=255)
|
|
49
|
+
|
|
50
|
+
model = models.ForeignKey(
|
|
51
|
+
"AiModel", on_delete=models.CASCADE, related_name="models"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
labelset = models.ForeignKey(
|
|
55
|
+
"LabelSet", on_delete=models.CASCADE, related_name="models"
|
|
56
|
+
)
|
|
57
|
+
activation = models.CharField(max_length=255, default="sigmoid")
|
|
58
|
+
|
|
59
|
+
weights = models.FileField(
|
|
60
|
+
upload_to=WEIGHTS_DIR_NAME,
|
|
61
|
+
validators=[FileExtensionValidator(allowed_extensions=["ckpt"])],
|
|
62
|
+
# storage=FileSystemStorage(location=STORAGE_LOCATION.resolve().as_posix()),
|
|
63
|
+
null=True,
|
|
64
|
+
blank=True,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Means and stds for normalization
|
|
68
|
+
mean = models.CharField(max_length=255, default="0.45211223,0.27139644,0.19264949")
|
|
69
|
+
std = models.CharField(max_length=255, default="0.31418097,0.21088019,0.16059452")
|
|
70
|
+
|
|
71
|
+
size_x = models.IntegerField(default=716)
|
|
72
|
+
size_y = models.IntegerField(default=716)
|
|
73
|
+
axes = models.CharField(max_length=255, default="2,0,1")
|
|
74
|
+
batchsize = models.IntegerField(default=16)
|
|
75
|
+
num_workers = models.IntegerField(default=0)
|
|
76
|
+
|
|
77
|
+
description = models.TextField(blank=True, null=True)
|
|
78
|
+
date_created = models.DateTimeField(auto_now_add=True)
|
|
79
|
+
|
|
80
|
+
objects = ModelMetaManager()
|
|
81
|
+
|
|
82
|
+
if TYPE_CHECKING:
|
|
83
|
+
labelset: "LabelSet"
|
|
84
|
+
ai_model: "AiModel"
|
|
85
|
+
|
|
86
|
+
@classmethod
|
|
87
|
+
def create_from_file(
|
|
88
|
+
cls,
|
|
89
|
+
meta_name,
|
|
90
|
+
model_name,
|
|
91
|
+
model_meta_version,
|
|
92
|
+
labelset_name,
|
|
93
|
+
weights_file,
|
|
94
|
+
bump_version,
|
|
95
|
+
**kwargs,
|
|
96
|
+
):
|
|
97
|
+
"""Create a new model meta from a file"""
|
|
98
|
+
|
|
99
|
+
from endoreg_db.models import LabelSet, AiModel # pylint: disable=import-outside-toplevel
|
|
100
|
+
|
|
101
|
+
ic("Start")
|
|
102
|
+
model_meta_version = kwargs.get("model_meta_version", None)
|
|
103
|
+
|
|
104
|
+
ai_model = AiModel.objects.get(name=model_name)
|
|
105
|
+
|
|
106
|
+
# check If ModelMeta with same name and model already exists
|
|
107
|
+
if not model_meta_version:
|
|
108
|
+
if cls.objects.filter(name=meta_name, model=ai_model).exists():
|
|
109
|
+
# get highest version number
|
|
110
|
+
highest_version = (
|
|
111
|
+
cls.objects.filter(name=meta_name, model=ai_model)
|
|
112
|
+
.latest("version")
|
|
113
|
+
.version
|
|
114
|
+
)
|
|
115
|
+
version = int(highest_version) + 1
|
|
116
|
+
else:
|
|
117
|
+
version = 1
|
|
118
|
+
else:
|
|
119
|
+
version = model_meta_version
|
|
120
|
+
|
|
121
|
+
meta_exists = cls.objects.filter(
|
|
122
|
+
name=meta_name, model=ai_model, version=version
|
|
123
|
+
).exists()
|
|
124
|
+
if meta_exists and not bump_version:
|
|
125
|
+
raise ValueError(
|
|
126
|
+
f"ModelMeta with name {meta_name} and version {version} already exists"
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
assert labelset_name is not None, "Labelset name must be provided"
|
|
130
|
+
labelset = LabelSet.objects.get(name=labelset_name)
|
|
131
|
+
assert labelset is not None, "Labelset not found"
|
|
132
|
+
|
|
133
|
+
weights_path = Path(weights_file)
|
|
134
|
+
# If not under our WEIGHTS_DIR, copy it there
|
|
135
|
+
if not str(weights_path).startswith(str(WEIGHTS_DIR)):
|
|
136
|
+
target_path = WEIGHTS_DIR / weights_path.name
|
|
137
|
+
if not target_path.exists():
|
|
138
|
+
shutil.copy(weights_path, target_path)
|
|
139
|
+
weights_file = target_path
|
|
140
|
+
|
|
141
|
+
return cls.objects.create(
|
|
142
|
+
name=meta_name,
|
|
143
|
+
model=ai_model,
|
|
144
|
+
version=version,
|
|
145
|
+
labelset=labelset,
|
|
146
|
+
weights=str(weights_file),
|
|
147
|
+
**kwargs,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
@classmethod
|
|
151
|
+
def get_latest_version(cls, name) -> int:
|
|
152
|
+
"""
|
|
153
|
+
get the model meta with the highest version. Assumes Model Name and Meta Name are the same
|
|
154
|
+
"""
|
|
155
|
+
from endoreg_db.models import AiModel # pylint: disable=import-outside-toplevel
|
|
156
|
+
|
|
157
|
+
ai_model = AiModel.objects.get(name=name)
|
|
158
|
+
ic(f"Model: {ai_model}")
|
|
159
|
+
assert ai_model is not None, "Model not found"
|
|
160
|
+
|
|
161
|
+
model_meta = cls.objects.filter(name=name, model=ai_model).latest("version")
|
|
162
|
+
ic(f"Latest ModelMeta: {model_meta}")
|
|
163
|
+
|
|
164
|
+
latest_version = model_meta.version
|
|
165
|
+
ic(f"Latest Version: {latest_version}")
|
|
166
|
+
|
|
167
|
+
return int(latest_version)
|
|
168
|
+
|
|
169
|
+
@classmethod
|
|
170
|
+
def get_activation_function(cls, activation: str):
|
|
171
|
+
"""get the activation function"""
|
|
172
|
+
from torch import nn # pylint: disable=import-outside-toplevel
|
|
173
|
+
|
|
174
|
+
lookup = {
|
|
175
|
+
"sigmoid": nn.Sigmoid(),
|
|
176
|
+
"softmax": nn.Softmax(),
|
|
177
|
+
"none": nn.Identity(),
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return lookup[activation]
|
|
181
|
+
|
|
182
|
+
def get_inference_dataset_config(self):
|
|
183
|
+
"""
|
|
184
|
+
Creates a dictionary with the configuration for the inference dataset.
|
|
185
|
+
|
|
186
|
+
Example:
|
|
187
|
+
sample_config = {
|
|
188
|
+
# mean and std for normalization
|
|
189
|
+
"mean": (0.45211223, 0.27139644, 0.19264949),
|
|
190
|
+
"std": (0.31418097, 0.21088019, 0.16059452),
|
|
191
|
+
# Image Size
|
|
192
|
+
"size_x": 716,
|
|
193
|
+
"size_y": 716,
|
|
194
|
+
# how to wrangle axes of the image before putting them in the network
|
|
195
|
+
"axes": [2,0,1], # 2,1,0 for opencv
|
|
196
|
+
"batchsize": 16,
|
|
197
|
+
"num_workers": 0, # always 1 for Windows systems # FIXME: fix celery crash if multiprocessing
|
|
198
|
+
# maybe add sigmoid after prediction?
|
|
199
|
+
"activation": nn.Sigmoid(),
|
|
200
|
+
"labels": ['appendix', 'blood', 'diverticule', 'grasper', 'ileocaecalvalve', 'ileum', 'low_quality', 'nbi', 'needle', 'outside', 'polyp', 'snare', 'water_jet', 'wound']
|
|
201
|
+
}
|
|
202
|
+
"""
|
|
203
|
+
mean = list(map(float, str(self.mean).split(",")))
|
|
204
|
+
std = list(map(float, str(self.std).split(",")))
|
|
205
|
+
axes = list(map(int, str(self.axes).split(",")))
|
|
206
|
+
|
|
207
|
+
config = {
|
|
208
|
+
"mean": mean,
|
|
209
|
+
"std": std,
|
|
210
|
+
"size_x": self.size_x,
|
|
211
|
+
"size_y": self.size_y,
|
|
212
|
+
"axes": axes,
|
|
213
|
+
"batchsize": self.batchsize,
|
|
214
|
+
"num_workers": self.num_workers,
|
|
215
|
+
"activation": self.get_activation_function(self.activation),
|
|
216
|
+
"labels": self.labelset.get_labels_in_order(), # pylint: disable=no-member
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
ic(f"ModelMeta - get_inference_dataset_config: {config}")
|
|
220
|
+
|
|
221
|
+
return config
|
|
222
|
+
|
|
223
|
+
def natural_key(self):
|
|
224
|
+
"""Return the natural key for this model"""
|
|
225
|
+
return (self.name, self.version)
|
|
226
|
+
|
|
227
|
+
def __str__(self):
|
|
228
|
+
return f"{self.name} (v: {self.version})"
|
|
229
|
+
|
|
230
|
+
def get_config_dict(self) -> dict:
|
|
231
|
+
"""Return the configuration as a dictionary"""
|
|
232
|
+
conf_dict = {
|
|
233
|
+
"mean": list(map(float, str(self.mean).split(","))),
|
|
234
|
+
"std": list(map(float, str(self.std).split(","))),
|
|
235
|
+
"size_x": self.size_x,
|
|
236
|
+
"size_y": self.size_y,
|
|
237
|
+
"axes": list(map(int, str(self.axes).split(","))),
|
|
238
|
+
"batchsize": self.batchsize,
|
|
239
|
+
"num_workers": self.num_workers,
|
|
240
|
+
"activation": self.activation,
|
|
241
|
+
"labels": self.labelset.get_labels_in_order(), # pylint: disable=no-member
|
|
242
|
+
}
|
|
243
|
+
return conf_dict
|
|
244
|
+
|
|
245
|
+
@classmethod
|
|
246
|
+
def get_by_name(cls, name: str, version: Optional[int]) -> "ModelMeta":
|
|
247
|
+
"""Get the model by its name and version"""
|
|
248
|
+
if version is None:
|
|
249
|
+
version = cls.get_latest_version(name)
|
|
250
|
+
return cls.objects.get(name=name, version=version)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
from django.core import serializers
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ModelTypeManager(models.Manager):
|
|
6
|
+
"""
|
|
7
|
+
Custom manager for ModelType with additional query methods.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
def get_by_natural_key(self, name: str) -> "ModelType":
|
|
11
|
+
"""Get the model type by its natural key"""
|
|
12
|
+
return self.get(name=name)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ModelType(models.Model):
|
|
16
|
+
"""
|
|
17
|
+
A class representing a model type.
|
|
18
|
+
|
|
19
|
+
Attributes:
|
|
20
|
+
name (str): The name of the model type.
|
|
21
|
+
description (str): A description of the model type.
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
name = models.CharField(max_length=255)
|
|
26
|
+
description = models.TextField(blank=True, null=True)
|
|
27
|
+
|
|
28
|
+
objects = ModelTypeManager()
|
|
29
|
+
|
|
30
|
+
def natural_key(self):
|
|
31
|
+
"""Return the natural key for this model type"""
|
|
32
|
+
return (self.name,)
|
|
33
|
+
|
|
34
|
+
def __str__(self):
|
|
35
|
+
"""Return the name of the model type"""
|
|
36
|
+
return str(self.name)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from .model_meta import ModelMeta
|
|
2
|
+
|
|
3
|
+
# get latest model meta by model name
|
|
4
|
+
|
|
5
|
+
# TODO MOVE THIS TO A QUERY FILE
|
|
6
|
+
def get_latest_model_meta_by_model_name(model_name):
|
|
7
|
+
model_meta = ModelMeta.objects.filter(name=model_name).order_by('-version').first()
|
|
8
|
+
return model_meta
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Module for annotation models"""
|
|
2
|
+
|
|
3
|
+
from .image_classification import ImageClassificationAnnotation
|
|
4
|
+
from .binary_classification_annotation_task import (
|
|
5
|
+
BinaryClassificationAnnotationTask,
|
|
6
|
+
)
|
|
7
|
+
from .anonymized_image_annotation import (
|
|
8
|
+
AnonymousImageAnnotation,
|
|
9
|
+
DroppedName,
|
|
10
|
+
AnonymizedImageLabel,
|
|
11
|
+
AnonymizedFile,
|
|
12
|
+
UploadedFile,
|
|
13
|
+
)
|
|
14
|
+
from .video_segmentation_annotation import (
|
|
15
|
+
VideoSegmentationLabel,
|
|
16
|
+
VideoSegmentationAnnotation,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
from .video_segmentation_labelset import VideoSegmentationLabelSet
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"ImageClassificationAnnotation",
|
|
23
|
+
"BinaryClassificationAnnotationTask",
|
|
24
|
+
"AnonymousImageAnnotation",
|
|
25
|
+
"DroppedName",
|
|
26
|
+
"AnonymizedImageLabel",
|
|
27
|
+
"AnonymizedFile",
|
|
28
|
+
"UploadedFile",
|
|
29
|
+
"VideoSegmentationLabel",
|
|
30
|
+
"VideoSegmentationLabelSet",
|
|
31
|
+
"VideoSegmentationAnnotation",
|
|
32
|
+
]
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
from django.utils.text import slugify
|
|
3
|
+
from django.utils import timezone
|
|
4
|
+
|
|
5
|
+
class AnonymizedImageLabel(models.Model):
|
|
6
|
+
"""
|
|
7
|
+
Represents a label for anonymized image annotations.
|
|
8
|
+
|
|
9
|
+
Attributes:
|
|
10
|
+
name (str): Unique name of the label.
|
|
11
|
+
description (str): Optional description for the label.
|
|
12
|
+
"""
|
|
13
|
+
name = models.CharField(max_length=255, unique=True)
|
|
14
|
+
description = models.TextField(blank=True, null=True)
|
|
15
|
+
|
|
16
|
+
def __str__(self) -> str:
|
|
17
|
+
return self.name
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AnonymousImageAnnotation(models.Model):
|
|
21
|
+
"""
|
|
22
|
+
Represents an annotation for anonymized images.
|
|
23
|
+
|
|
24
|
+
Attributes:
|
|
25
|
+
label (ForeignKey): Associated label for the image.
|
|
26
|
+
image_name (str): Name of the image file.
|
|
27
|
+
original_image_url (str): URL of the original image.
|
|
28
|
+
slug (str): Unique identifier for the annotation.
|
|
29
|
+
polyp_count (int): Number of polyps identified in the image.
|
|
30
|
+
comments (str): Additional comments about the annotation.
|
|
31
|
+
gender (str): Gender associated with the annotation (if applicable).
|
|
32
|
+
name_image_url (str): URL of the name image.
|
|
33
|
+
date_created (datetime): Date when the annotation was created.
|
|
34
|
+
processed (bool): Indicates if the annotation has been processed.
|
|
35
|
+
"""
|
|
36
|
+
label = models.ForeignKey(AnonymizedImageLabel, on_delete=models.CASCADE)
|
|
37
|
+
image_name = models.CharField(max_length=255)
|
|
38
|
+
original_image_url = models.CharField(max_length=255, default='https://example.com/placeholder.jpg')
|
|
39
|
+
slug = models.SlugField(unique=True, blank=True, null=True)
|
|
40
|
+
polyp_count = models.IntegerField()
|
|
41
|
+
comments = models.TextField(blank=True, null=True)
|
|
42
|
+
gender = models.CharField(max_length=255)
|
|
43
|
+
name_image_url = models.CharField(max_length=255)
|
|
44
|
+
date_created = models.DateTimeField(auto_now_add=True)
|
|
45
|
+
processed = models.BooleanField(default=False)
|
|
46
|
+
|
|
47
|
+
def save(self, *args, **kwargs):
|
|
48
|
+
"""
|
|
49
|
+
Overrides the save method to generate a slug if not already set.
|
|
50
|
+
"""
|
|
51
|
+
if not self.slug:
|
|
52
|
+
self.slug = slugify(f"{self.label}-{self.image_name}")
|
|
53
|
+
super().save(*args, **kwargs)
|
|
54
|
+
|
|
55
|
+
def __str__(self) -> str:
|
|
56
|
+
return f"{self.image_name} - {self.label}"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class DroppedName(models.Model):
|
|
60
|
+
"""
|
|
61
|
+
Represents a dropped name in the annotation process.
|
|
62
|
+
|
|
63
|
+
Attributes:
|
|
64
|
+
annotation (ForeignKey): Associated annotation.
|
|
65
|
+
name (str): Dropped name.
|
|
66
|
+
gender (str): Gender associated with the name.
|
|
67
|
+
x (float): X-coordinate of the name.
|
|
68
|
+
y (float): Y-coordinate of the name.
|
|
69
|
+
name_image_url (str): URL of the name image.
|
|
70
|
+
box_coordinates (str): Optional coordinates of the bounding box.
|
|
71
|
+
"""
|
|
72
|
+
annotation = models.ForeignKey(AnonymousImageAnnotation, related_name='dropped_names', on_delete=models.CASCADE)
|
|
73
|
+
name = models.CharField(max_length=255)
|
|
74
|
+
gender = models.CharField(max_length=255)
|
|
75
|
+
x = models.FloatField()
|
|
76
|
+
y = models.FloatField()
|
|
77
|
+
name_image_url = models.CharField(max_length=255)
|
|
78
|
+
box_coordinates = models.CharField(max_length=255, blank=True, null=True)
|
|
79
|
+
|
|
80
|
+
def __str__(self) -> str:
|
|
81
|
+
return f"{self.name} ({self.gender}) at ({self.x}, {self.y})"
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class UploadedFile(models.Model):
|
|
85
|
+
"""
|
|
86
|
+
Represents a file uploaded to the system.
|
|
87
|
+
|
|
88
|
+
Attributes:
|
|
89
|
+
original_file (FileField): The uploaded original file.
|
|
90
|
+
upload_date (datetime): Date when the file was uploaded.
|
|
91
|
+
description (str): Optional description of the file.
|
|
92
|
+
"""
|
|
93
|
+
original_file = models.FileField(upload_to='uploads/original/')
|
|
94
|
+
upload_date = models.DateTimeField(default=timezone.now)
|
|
95
|
+
description = models.TextField(blank=True, null=True)
|
|
96
|
+
|
|
97
|
+
def __str__(self) -> str:
|
|
98
|
+
return self.original_file.name
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class AnonymizedFile(models.Model):
|
|
102
|
+
"""
|
|
103
|
+
Represents an anonymized version of an uploaded file.
|
|
104
|
+
|
|
105
|
+
Attributes:
|
|
106
|
+
original_file (OneToOneField): The original uploaded file.
|
|
107
|
+
anonymized_file (FileField): The anonymized file.
|
|
108
|
+
anonymization_date (datetime): Date when the file was anonymized.
|
|
109
|
+
"""
|
|
110
|
+
original_file = models.OneToOneField(UploadedFile, on_delete=models.CASCADE, related_name='anonymized_file')
|
|
111
|
+
anonymized_file = models.FileField(upload_to='uploads/anonymized/')
|
|
112
|
+
anonymization_date = models.DateTimeField(default=timezone.now)
|
|
113
|
+
|
|
114
|
+
def __str__(self) -> str:
|
|
115
|
+
return f"Anonymized version of {self.original_file.original_file.name}"
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
# from rest_framework import serializers
|
|
3
|
+
# from ..label import Label
|
|
4
|
+
# from .image_classification import ImageClassificationAnnotation
|
|
5
|
+
|
|
6
|
+
ANNOTATION_PER_S_THRESHOLD = 2
|
|
7
|
+
|
|
8
|
+
# TODO Migrate
|
|
9
|
+
# def clear_finished_legacy_tasks():
|
|
10
|
+
# """
|
|
11
|
+
# Deletes all finished LegacyBinaryClassificationAnnotationTask entries.
|
|
12
|
+
# """
|
|
13
|
+
# tasks = LegacyBinaryClassificationAnnotationTask.objects.filter(is_finished=True)
|
|
14
|
+
# tasks.delete()
|
|
15
|
+
|
|
16
|
+
# def get_legacy_binary_classification_annotation_tasks_by_label(label:Label, n:int=100, legacy=False):
|
|
17
|
+
# clear_finished_legacy_tasks()
|
|
18
|
+
# """
|
|
19
|
+
# Retrieves legacy binary classification annotation tasks for a specific label.
|
|
20
|
+
|
|
21
|
+
# Args:
|
|
22
|
+
# label (Label): The label to filter tasks by.
|
|
23
|
+
# n (int): Maximum number of tasks to retrieve. Defaults to 100.
|
|
24
|
+
# legacy (bool): If True, includes legacy tasks. Defaults to False.
|
|
25
|
+
# """
|
|
26
|
+
# if legacy:
|
|
27
|
+
# # fetch all LegacyLabelVideoSegments with the given label
|
|
28
|
+
# _segments = LegacyLabelVideoSegment.objects.filter(label=label)
|
|
29
|
+
# frames_for_tasks = []
|
|
30
|
+
|
|
31
|
+
# for segment in _segments:
|
|
32
|
+
# # check if the segment has already been annotated
|
|
33
|
+
# annotations = list(ImageClassificationAnnotation.objects.filter(legacy_frame__in=segment.get_frames(), label=label))
|
|
34
|
+
# segment_len_in_s = segment.get_segment_len_in_s()
|
|
35
|
+
|
|
36
|
+
# target_annotation_number = segment_len_in_s * ANNOTATION_PER_S_THRESHOLD
|
|
37
|
+
|
|
38
|
+
# if len(annotations) < target_annotation_number:
|
|
39
|
+
# get_frame_number = int(target_annotation_number - len(annotations))
|
|
40
|
+
# frames = segment.get_frames_without_annotation(get_frame_number)
|
|
41
|
+
# frames_for_tasks.extend(frames)
|
|
42
|
+
|
|
43
|
+
# if len(frames_for_tasks) >= n:
|
|
44
|
+
# break
|
|
45
|
+
|
|
46
|
+
# # create tasks
|
|
47
|
+
# tasks = []
|
|
48
|
+
# for frame in frames_for_tasks:
|
|
49
|
+
|
|
50
|
+
# # get_or_create task
|
|
51
|
+
# task, created = LegacyBinaryClassificationAnnotationTask.objects.get_or_create(
|
|
52
|
+
# label=label,
|
|
53
|
+
# image_path=frame.image.path,
|
|
54
|
+
# frame_id=frame.pk,
|
|
55
|
+
# )
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class AbstractBinaryClassificationAnnotationTask(models.Model):
|
|
59
|
+
"""
|
|
60
|
+
Abstract base class for binary classification annotation tasks.
|
|
61
|
+
|
|
62
|
+
Attributes:
|
|
63
|
+
label (ForeignKey): The associated label.
|
|
64
|
+
is_finished (bool): Indicates if the task is completed.
|
|
65
|
+
date_created (datetime): The creation date of the task.
|
|
66
|
+
date_finished (datetime): The completion date of the task.
|
|
67
|
+
image_path (str): Path to the associated image.
|
|
68
|
+
image_type (str): The type of the image (e.g., "frame" or "legacy").
|
|
69
|
+
frame_id (int): Identifier of the associated frame.
|
|
70
|
+
labelstudio_project_id (int): The Label Studio project ID.
|
|
71
|
+
labelstudio_task_id (int): The Label Studio task ID.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
label = models.ForeignKey("Label", on_delete=models.CASCADE)
|
|
75
|
+
is_finished = models.BooleanField(default=False)
|
|
76
|
+
date_created = models.DateTimeField(auto_now_add=True)
|
|
77
|
+
date_finished = models.DateTimeField(blank=True, null=True)
|
|
78
|
+
image_path = models.CharField(max_length=255, blank=True, null=True)
|
|
79
|
+
image_type = models.CharField(max_length=255, blank=True, null=True)
|
|
80
|
+
frame_id = models.IntegerField(blank=True, null=True)
|
|
81
|
+
labelstudio_project_id = models.IntegerField(blank=True, null=True)
|
|
82
|
+
labelstudio_task_id = models.IntegerField(blank=True, null=True)
|
|
83
|
+
|
|
84
|
+
class Meta:
|
|
85
|
+
abstract = True
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class BinaryClassificationAnnotationTask(AbstractBinaryClassificationAnnotationTask):
|
|
89
|
+
"""
|
|
90
|
+
Represents a binary classification task for a frame.
|
|
91
|
+
|
|
92
|
+
Attributes:
|
|
93
|
+
frame (ForeignKey): The associated frame for this task.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
frame = models.ForeignKey(
|
|
97
|
+
"Frame",
|
|
98
|
+
on_delete=models.CASCADE,
|
|
99
|
+
related_name="binary_classification_annotation_tasks",
|
|
100
|
+
)
|
|
101
|
+
image_type = models.CharField(
|
|
102
|
+
max_length=255, default="frame"
|
|
103
|
+
) # Default image type for non-legacy tasks
|
|
104
|
+
|
|
105
|
+
def get_frame(self):
|
|
106
|
+
"""
|
|
107
|
+
Retrieves the frame associated with this task.
|
|
108
|
+
"""
|
|
109
|
+
from endoreg_db.models.data_file.frame import Frame
|
|
110
|
+
|
|
111
|
+
frame = self.frame
|
|
112
|
+
if not frame:
|
|
113
|
+
return None
|
|
114
|
+
else:
|
|
115
|
+
assert isinstance(frame, Frame)
|
|
116
|
+
|
|
117
|
+
return frame
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Union
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from endoreg_db.models import Frame, RawFrame, Label
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ImageClassificationAnnotation(models.Model):
|
|
10
|
+
"""
|
|
11
|
+
Represents an image classification annotation.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
frame (ForeignKey): The frame associated with the annotation.
|
|
15
|
+
legacy_frame (ForeignKey): The legacy frame associated with the annotation.
|
|
16
|
+
legacy_image (ForeignKey): The legacy image associated with the annotation.
|
|
17
|
+
label (ForeignKey): The label assigned to the annotation.
|
|
18
|
+
value (bool): Indicates if the classification is valid.
|
|
19
|
+
annotator (str): The user who created the annotation.
|
|
20
|
+
date_created (datetime): The creation date of the annotation.
|
|
21
|
+
date_modified (datetime): The last modification date of the annotation.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
# Foreign keys to Frame, LegacyFrame, and LegacyImage (only one of these should be set)
|
|
25
|
+
frame = models.ForeignKey(
|
|
26
|
+
"Frame",
|
|
27
|
+
on_delete=models.CASCADE,
|
|
28
|
+
blank=True,
|
|
29
|
+
null=True,
|
|
30
|
+
related_name="image_classification_annotations",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
raw_frame = models.ForeignKey(
|
|
34
|
+
"RawFrame",
|
|
35
|
+
on_delete=models.CASCADE,
|
|
36
|
+
blank=True,
|
|
37
|
+
null=True,
|
|
38
|
+
related_name="image_classification_annotations",
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
label = models.ForeignKey(
|
|
42
|
+
"Label",
|
|
43
|
+
on_delete=models.CASCADE,
|
|
44
|
+
related_name="image_classification_annotations",
|
|
45
|
+
)
|
|
46
|
+
value = models.BooleanField()
|
|
47
|
+
float_value = models.FloatField(blank=True, null=True)
|
|
48
|
+
annotator = models.CharField(max_length=255, blank=True, null=True)
|
|
49
|
+
model_meta = models.ForeignKey(
|
|
50
|
+
"ModelMeta",
|
|
51
|
+
on_delete=models.SET_NULL,
|
|
52
|
+
related_name="image_classification_annotations",
|
|
53
|
+
default=None,
|
|
54
|
+
null=True,
|
|
55
|
+
blank=True,
|
|
56
|
+
)
|
|
57
|
+
date_created = models.DateTimeField(auto_now_add=True)
|
|
58
|
+
date_modified = models.DateTimeField(auto_now=True)
|
|
59
|
+
information_source = models.ForeignKey(
|
|
60
|
+
"InformationSource",
|
|
61
|
+
on_delete=models.SET_NULL,
|
|
62
|
+
related_name="image_classification_annotations",
|
|
63
|
+
default=None,
|
|
64
|
+
null=True,
|
|
65
|
+
blank=True,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
if TYPE_CHECKING:
|
|
69
|
+
frame: "Frame"
|
|
70
|
+
raw_frame: "RawFrame"
|
|
71
|
+
label: "Label"
|
|
72
|
+
|
|
73
|
+
def __str__(self) -> str:
|
|
74
|
+
"""
|
|
75
|
+
String representation of the annotation.
|
|
76
|
+
"""
|
|
77
|
+
return f"{self.label.name} - {self.value}"
|
|
78
|
+
|
|
79
|
+
def get_frame(self):
|
|
80
|
+
"""
|
|
81
|
+
Get the frame associated with the annotation.
|
|
82
|
+
"""
|
|
83
|
+
if self.frame:
|
|
84
|
+
return self.frame
|
|
85
|
+
else:
|
|
86
|
+
return self.raw_frame
|