endoreg-db 0.8.6.1__py3-none-any.whl → 0.8.8.9__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/authz/auth.py +74 -0
- endoreg_db/authz/backends.py +168 -0
- endoreg_db/authz/management/commands/list_routes.py +18 -0
- endoreg_db/authz/middleware.py +83 -0
- endoreg_db/authz/permissions.py +127 -0
- endoreg_db/authz/policy.py +218 -0
- endoreg_db/authz/views_auth.py +66 -0
- endoreg_db/config/env.py +13 -8
- endoreg_db/data/__init__.py +2 -11
- endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +3 -3
- endoreg_db/data/event_classification/data.yaml +4 -0
- endoreg_db/data/event_classification_choice/data.yaml +9 -0
- endoreg_db/data/examination/examinations/data.yaml +114 -14
- endoreg_db/data/examination/time-type/data.yaml +0 -3
- endoreg_db/data/examination_indication/endoscopy.yaml +108 -173
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +0 -70
- endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +33 -37
- endoreg_db/data/finding/00_generic.yaml +35 -0
- endoreg_db/data/finding/00_generic_complication.yaml +9 -0
- endoreg_db/data/finding/01_gastroscopy_baseline.yaml +88 -0
- endoreg_db/data/finding/01_gastroscopy_observation.yaml +113 -0
- endoreg_db/data/finding/02_colonoscopy_baseline.yaml +53 -0
- endoreg_db/data/finding/02_colonoscopy_hidden.yaml +119 -0
- endoreg_db/data/finding/02_colonoscopy_observation.yaml +152 -0
- endoreg_db/data/finding_classification/00_generic.yaml +44 -0
- endoreg_db/data/finding_classification/00_generic_histology.yaml +28 -0
- endoreg_db/data/finding_classification/00_generic_lesion.yaml +52 -0
- endoreg_db/data/finding_classification/02_colonoscopy_baseline.yaml +83 -0
- endoreg_db/data/finding_classification/02_colonoscopy_histology.yaml +13 -0
- endoreg_db/data/finding_classification/02_colonoscopy_other.yaml +12 -0
- endoreg_db/data/finding_classification/02_colonoscopy_polyp.yaml +101 -0
- endoreg_db/data/finding_classification_choice/{yes_no_na.yaml → 00_generic.yaml} +5 -1
- endoreg_db/data/finding_classification_choice/{examination_setting_generic_types.yaml → 00_generic_baseline.yaml} +10 -2
- endoreg_db/data/finding_classification_choice/{complication_generic_types.yaml → 00_generic_complication.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{histology.yaml → 00_generic_histology.yaml} +1 -4
- endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
- endoreg_db/data/finding_classification_choice/{bowel_preparation.yaml → 02_colonoscopy_bowel_preparation.yaml} +1 -30
- endoreg_db/data/finding_classification_choice/{colonoscopy_not_complete_reason.yaml → 02_colonoscopy_generic.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{histology_polyp.yaml → 02_colonoscopy_histology.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{colonoscopy_location.yaml → 02_colonoscopy_location.yaml} +23 -4
- endoreg_db/data/finding_classification_choice/02_colonoscopy_other.yaml +34 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_polyp_advanced_imaging.yaml +76 -0
- endoreg_db/data/finding_classification_choice/{colon_lesion_paris.yaml → 02_colonoscopy_polyp_morphology.yaml} +26 -8
- endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
- endoreg_db/data/finding_classification_type/{colonoscopy_basic.yaml → 00_generic.yaml} +18 -13
- endoreg_db/data/finding_classification_type/02_colonoscopy.yaml +9 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy.yaml +59 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_ablation.yaml +44 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_bleeding.yaml +55 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_resection.yaml +85 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_stenosis.yaml +17 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_stent.yaml +9 -0
- endoreg_db/data/finding_intervention/01_gastroscopy.yaml +19 -0
- endoreg_db/data/finding_intervention/04_eus.yaml +39 -0
- endoreg_db/data/finding_intervention/05_ercp.yaml +3 -0
- endoreg_db/data/finding_type/data.yaml +8 -12
- endoreg_db/data/requirement/01_patient_data.yaml +93 -0
- endoreg_db/data/requirement/old/colon_polyp_intervention.yaml +49 -0
- endoreg_db/data/requirement/old/coloreg_colon_polyp.yaml +49 -0
- endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +29 -12
- endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
- endoreg_db/data/requirement_set/{endoscopy_bleeding_risk.yaml → 02_endoscopy_bleeding_risk.yaml} +0 -6
- endoreg_db/data/requirement_set/90_coloreg.yaml +190 -0
- endoreg_db/data/requirement_set/_old_ +109 -0
- endoreg_db/data/requirement_set_type/data.yaml +21 -0
- endoreg_db/data/setup_config.yaml +4 -4
- endoreg_db/data/tag/requirement_set_tags.yaml +21 -0
- endoreg_db/exceptions.py +4 -2
- endoreg_db/forms/examination_form.py +1 -1
- endoreg_db/helpers/data_loader.py +125 -53
- endoreg_db/helpers/default_objects.py +116 -81
- endoreg_db/import_files/__init__.py +27 -0
- endoreg_db/import_files/context/__init__.py +7 -0
- endoreg_db/import_files/context/default_sensitive_meta.py +81 -0
- endoreg_db/import_files/context/ensure_center.py +17 -0
- endoreg_db/import_files/context/file_lock.py +66 -0
- endoreg_db/import_files/context/import_context.py +43 -0
- endoreg_db/import_files/context/validate_directories.py +56 -0
- endoreg_db/import_files/file_storage/__init__.py +15 -0
- endoreg_db/import_files/file_storage/create_report_file.py +76 -0
- endoreg_db/import_files/file_storage/create_video_file.py +75 -0
- endoreg_db/import_files/file_storage/sensitive_meta_storage.py +39 -0
- endoreg_db/import_files/file_storage/state_management.py +400 -0
- endoreg_db/import_files/file_storage/storage.py +36 -0
- endoreg_db/import_files/import_service.md +26 -0
- endoreg_db/import_files/processing/__init__.py +11 -0
- endoreg_db/import_files/processing/report_processing/report_anonymization.py +94 -0
- endoreg_db/import_files/processing/sensitive_meta_adapter.py +51 -0
- endoreg_db/import_files/processing/video_processing/video_anonymization.py +107 -0
- endoreg_db/import_files/processing/video_processing/video_cleanup_on_error.py +119 -0
- endoreg_db/import_files/pseudonymization/fake.py +52 -0
- endoreg_db/import_files/pseudonymization/k_anonymity.py +182 -0
- endoreg_db/import_files/pseudonymization/k_pseudonymity.py +128 -0
- endoreg_db/import_files/report_import_service.py +141 -0
- endoreg_db/import_files/video_import_service.py +150 -0
- endoreg_db/management/commands/create_model_meta_from_huggingface.py +21 -10
- endoreg_db/management/commands/create_multilabel_model_meta.py +299 -129
- endoreg_db/management/commands/import_report.py +130 -65
- endoreg_db/management/commands/import_video.py +9 -10
- endoreg_db/management/commands/import_video_with_classification.py +2 -2
- endoreg_db/management/commands/list_routes.py +18 -0
- endoreg_db/management/commands/load_ai_model_data.py +5 -5
- endoreg_db/management/commands/load_ai_model_label_data.py +9 -7
- endoreg_db/management/commands/load_base_db_data.py +5 -134
- endoreg_db/management/commands/load_center_data.py +12 -12
- endoreg_db/management/commands/load_contraindication_data.py +14 -16
- endoreg_db/management/commands/load_disease_classification_choices_data.py +15 -18
- endoreg_db/management/commands/load_disease_classification_data.py +15 -18
- endoreg_db/management/commands/load_disease_data.py +25 -28
- endoreg_db/management/commands/load_endoscope_data.py +20 -27
- endoreg_db/management/commands/load_event_data.py +14 -16
- endoreg_db/management/commands/load_examination_data.py +31 -44
- endoreg_db/management/commands/load_examination_indication_data.py +20 -21
- endoreg_db/management/commands/load_finding_data.py +52 -80
- endoreg_db/management/commands/load_information_source.py +21 -23
- endoreg_db/management/commands/load_lab_value_data.py +17 -26
- endoreg_db/management/commands/load_medication_data.py +13 -12
- endoreg_db/management/commands/load_organ_data.py +15 -19
- endoreg_db/management/commands/load_pdf_type_data.py +19 -18
- endoreg_db/management/commands/load_profession_data.py +14 -17
- endoreg_db/management/commands/load_qualification_data.py +20 -23
- endoreg_db/management/commands/load_report_reader_flag_data.py +17 -19
- endoreg_db/management/commands/load_requirement_data.py +62 -39
- endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
- endoreg_db/management/commands/load_risk_data.py +7 -6
- endoreg_db/management/commands/load_shift_data.py +20 -23
- endoreg_db/management/commands/load_tag_data.py +8 -11
- endoreg_db/management/commands/load_unit_data.py +17 -19
- endoreg_db/management/commands/setup_endoreg_db.py +3 -3
- endoreg_db/management/commands/start_filewatcher.py +46 -37
- endoreg_db/management/commands/storage_management.py +271 -203
- endoreg_db/management/commands/validate_video_files.py +1 -5
- endoreg_db/migrations/0001_initial.py +297 -250
- endoreg_db/models/__init__.py +78 -123
- endoreg_db/models/administration/__init__.py +21 -42
- endoreg_db/models/administration/ai/active_model.py +2 -2
- endoreg_db/models/administration/ai/ai_model.py +7 -6
- endoreg_db/models/administration/case/__init__.py +1 -15
- endoreg_db/models/administration/case/case.py +3 -3
- endoreg_db/models/administration/case/case_template/__init__.py +2 -14
- endoreg_db/models/administration/case/case_template/case_template.py +2 -124
- endoreg_db/models/administration/case/case_template/case_template_rule.py +2 -268
- endoreg_db/models/administration/case/case_template/case_template_rule_value.py +2 -85
- endoreg_db/models/administration/case/case_template/case_template_type.py +2 -25
- endoreg_db/models/administration/center/center.py +33 -19
- endoreg_db/models/administration/center/center_product.py +12 -9
- endoreg_db/models/administration/center/center_resource.py +25 -19
- endoreg_db/models/administration/center/center_shift.py +21 -17
- endoreg_db/models/administration/center/center_waste.py +16 -8
- endoreg_db/models/administration/person/__init__.py +2 -0
- endoreg_db/models/administration/person/employee/employee.py +10 -5
- endoreg_db/models/administration/person/employee/employee_qualification.py +9 -4
- endoreg_db/models/administration/person/employee/employee_type.py +12 -6
- endoreg_db/models/administration/person/examiner/examiner.py +13 -11
- endoreg_db/models/administration/person/patient/__init__.py +2 -0
- endoreg_db/models/administration/person/patient/patient.py +129 -100
- endoreg_db/models/administration/person/patient/patient_external_id.py +37 -0
- endoreg_db/models/administration/person/person.py +4 -0
- endoreg_db/models/administration/person/profession/__init__.py +8 -4
- endoreg_db/models/administration/person/user/portal_user_information.py +11 -7
- endoreg_db/models/administration/product/product.py +20 -15
- endoreg_db/models/administration/product/product_material.py +17 -18
- endoreg_db/models/administration/product/product_weight.py +12 -8
- endoreg_db/models/administration/product/reference_product.py +23 -55
- endoreg_db/models/administration/qualification/qualification.py +7 -3
- endoreg_db/models/administration/qualification/qualification_type.py +7 -3
- endoreg_db/models/administration/shift/scheduled_days.py +8 -5
- endoreg_db/models/administration/shift/shift.py +16 -12
- endoreg_db/models/administration/shift/shift_type.py +23 -31
- endoreg_db/models/label/__init__.py +8 -9
- endoreg_db/models/label/annotation/image_classification.py +10 -9
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +23 -28
- endoreg_db/models/label/label.py +15 -15
- endoreg_db/models/label/label_set.py +19 -6
- endoreg_db/models/label/label_type.py +1 -1
- endoreg_db/models/label/label_video_segment/_create_from_video.py +5 -8
- endoreg_db/models/label/label_video_segment/label_video_segment.py +98 -102
- endoreg_db/models/label/video_segmentation_label.py +4 -0
- endoreg_db/models/label/video_segmentation_labelset.py +4 -3
- endoreg_db/models/media/frame/frame.py +22 -22
- endoreg_db/models/media/pdf/raw_pdf.py +194 -194
- endoreg_db/models/media/pdf/report_file.py +25 -29
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +55 -47
- endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +23 -7
- endoreg_db/models/media/processing_history/__init__.py +5 -0
- endoreg_db/models/media/processing_history/processing_history.py +96 -0
- endoreg_db/models/media/video/__init__.py +1 -0
- endoreg_db/models/media/video/create_from_file.py +139 -77
- endoreg_db/models/media/video/pipe_2.py +8 -9
- endoreg_db/models/media/video/video_file.py +174 -112
- endoreg_db/models/media/video/video_file_ai.py +288 -74
- endoreg_db/models/media/video/video_file_anonymize.py +38 -38
- endoreg_db/models/media/video/video_file_frames/__init__.py +3 -1
- endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +7 -9
- endoreg_db/models/media/video/video_file_frames/_delete_frames.py +9 -8
- endoreg_db/models/media/video/video_file_frames/_extract_frames.py +38 -45
- endoreg_db/models/media/video/video_file_frames/_get_frame.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +4 -18
- endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +4 -3
- endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +7 -6
- endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_get_frames.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +15 -25
- endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +26 -23
- endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +23 -14
- endoreg_db/models/media/video/video_file_io.py +113 -61
- endoreg_db/models/media/video/video_file_meta/get_crop_template.py +3 -3
- endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +5 -3
- endoreg_db/models/media/video/video_file_meta/get_fps.py +37 -34
- endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +19 -25
- endoreg_db/models/media/video/video_file_meta/text_meta.py +41 -38
- endoreg_db/models/media/video/video_file_meta/video_meta.py +14 -7
- endoreg_db/models/media/video/video_file_segments.py +24 -17
- endoreg_db/models/media/video/video_metadata.py +19 -35
- endoreg_db/models/media/video/video_processing.py +96 -95
- endoreg_db/models/medical/contraindication/README.md +1 -0
- endoreg_db/models/medical/contraindication/__init__.py +13 -3
- endoreg_db/models/medical/disease.py +22 -16
- endoreg_db/models/medical/event.py +31 -18
- endoreg_db/models/medical/examination/__init__.py +13 -6
- endoreg_db/models/medical/examination/examination.py +39 -20
- endoreg_db/models/medical/examination/examination_indication.py +30 -95
- endoreg_db/models/medical/examination/examination_time.py +23 -8
- endoreg_db/models/medical/examination/examination_time_type.py +9 -6
- endoreg_db/models/medical/examination/examination_type.py +3 -4
- endoreg_db/models/medical/finding/finding.py +32 -40
- endoreg_db/models/medical/finding/finding_classification.py +42 -72
- endoreg_db/models/medical/finding/finding_intervention.py +25 -22
- endoreg_db/models/medical/finding/finding_type.py +13 -12
- endoreg_db/models/medical/hardware/endoscope.py +26 -26
- endoreg_db/models/medical/hardware/endoscopy_processor.py +2 -2
- endoreg_db/models/medical/laboratory/lab_value.py +62 -91
- endoreg_db/models/medical/medication/medication.py +22 -10
- endoreg_db/models/medical/medication/medication_indication.py +29 -3
- endoreg_db/models/medical/medication/medication_indication_type.py +25 -14
- endoreg_db/models/medical/medication/medication_intake_time.py +31 -19
- endoreg_db/models/medical/medication/medication_schedule.py +27 -16
- endoreg_db/models/medical/organ/__init__.py +15 -12
- endoreg_db/models/medical/patient/medication_examples.py +6 -6
- endoreg_db/models/medical/patient/patient_disease.py +20 -23
- endoreg_db/models/medical/patient/patient_event.py +19 -22
- endoreg_db/models/medical/patient/patient_examination.py +48 -54
- endoreg_db/models/medical/patient/patient_examination_indication.py +16 -14
- endoreg_db/models/medical/patient/patient_finding.py +122 -139
- endoreg_db/models/medical/patient/patient_finding_classification.py +44 -49
- endoreg_db/models/medical/patient/patient_finding_intervention.py +8 -19
- endoreg_db/models/medical/patient/patient_lab_sample.py +28 -23
- endoreg_db/models/medical/patient/patient_lab_value.py +82 -89
- endoreg_db/models/medical/patient/patient_medication.py +27 -38
- endoreg_db/models/medical/patient/patient_medication_schedule.py +28 -36
- endoreg_db/models/medical/risk/risk.py +7 -6
- endoreg_db/models/medical/risk/risk_type.py +8 -5
- endoreg_db/models/metadata/model_meta.py +60 -29
- endoreg_db/models/metadata/model_meta_logic.py +125 -18
- endoreg_db/models/metadata/pdf_meta.py +31 -24
- endoreg_db/models/metadata/sensitive_meta.py +105 -85
- endoreg_db/models/metadata/sensitive_meta_logic.py +198 -103
- endoreg_db/models/metadata/video_meta.py +51 -31
- endoreg_db/models/metadata/video_prediction_logic.py +16 -23
- endoreg_db/models/metadata/video_prediction_meta.py +29 -33
- endoreg_db/models/other/distribution/date_value_distribution.py +89 -29
- endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +21 -5
- endoreg_db/models/other/distribution/numeric_value_distribution.py +114 -53
- endoreg_db/models/other/distribution/single_categorical_value_distribution.py +4 -3
- endoreg_db/models/other/emission/emission_factor.py +18 -8
- endoreg_db/models/other/gender.py +10 -5
- endoreg_db/models/other/information_source.py +50 -29
- endoreg_db/models/other/material.py +9 -5
- endoreg_db/models/other/resource.py +6 -4
- endoreg_db/models/other/tag.py +10 -5
- endoreg_db/models/other/transport_route.py +13 -8
- endoreg_db/models/other/unit.py +10 -6
- endoreg_db/models/other/waste.py +6 -5
- endoreg_db/models/report/report.py +6 -0
- endoreg_db/models/requirement/requirement.py +329 -361
- endoreg_db/models/requirement/requirement_error.py +85 -0
- endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
- endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +3 -6
- endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +90 -64
- endoreg_db/models/requirement/requirement_operator.py +103 -112
- endoreg_db/models/requirement/requirement_set.py +74 -57
- endoreg_db/models/state/__init__.py +4 -4
- endoreg_db/models/state/abstract.py +2 -2
- endoreg_db/models/state/anonymization.py +12 -0
- endoreg_db/models/state/audit_ledger.py +49 -51
- endoreg_db/models/state/label_video_segment.py +9 -0
- endoreg_db/models/state/raw_pdf.py +101 -68
- endoreg_db/models/state/sensitive_meta.py +6 -2
- endoreg_db/models/state/video.py +110 -90
- endoreg_db/models/upload_job.py +35 -34
- endoreg_db/models/utils.py +28 -25
- endoreg_db/queries/__init__.py +3 -1
- endoreg_db/root_urls.py +21 -2
- endoreg_db/schemas/examination_evaluation.py +1 -1
- endoreg_db/serializers/__init__.py +2 -10
- endoreg_db/serializers/anonymization.py +18 -10
- endoreg_db/serializers/label_video_segment/label_video_segment.py +2 -29
- endoreg_db/serializers/meta/__init__.py +1 -6
- endoreg_db/serializers/meta/sensitive_meta_detail.py +63 -118
- endoreg_db/serializers/misc/file_overview.py +11 -99
- endoreg_db/serializers/misc/sensitive_patient_data.py +50 -26
- endoreg_db/serializers/patient_examination/patient_examination.py +3 -3
- endoreg_db/serializers/pdf/anony_text_validation.py +39 -23
- endoreg_db/serializers/requirements/requirement_sets.py +92 -22
- endoreg_db/serializers/video/segmentation.py +2 -1
- endoreg_db/serializers/video/video_file_list.py +65 -34
- endoreg_db/serializers/video/video_processing_history.py +20 -5
- endoreg_db/services/__old/pdf_import.py +1487 -0
- endoreg_db/services/__old/video_import.py +1306 -0
- endoreg_db/services/anonymization.py +128 -89
- endoreg_db/services/lookup_service.py +65 -52
- endoreg_db/services/lookup_store.py +2 -2
- endoreg_db/services/pdf_import.py +0 -1382
- endoreg_db/services/report_import.py +10 -0
- endoreg_db/services/video_import.py +6 -1255
- endoreg_db/tasks/upload_tasks.py +79 -70
- endoreg_db/tasks/video_ingest.py +8 -4
- endoreg_db/urls/__init__.py +5 -32
- endoreg_db/urls/ai.py +32 -0
- endoreg_db/urls/media.py +121 -83
- endoreg_db/urls/root_urls.py +29 -0
- endoreg_db/utils/__init__.py +15 -5
- endoreg_db/utils/ai/multilabel_classification_net.py +116 -20
- endoreg_db/utils/case_generator/__init__.py +3 -0
- endoreg_db/utils/dataloader.py +142 -40
- endoreg_db/utils/defaults/set_default_center.py +32 -0
- endoreg_db/utils/names.py +22 -16
- endoreg_db/utils/paths.py +110 -46
- endoreg_db/utils/permissions.py +2 -1
- endoreg_db/utils/pipelines/Readme.md +1 -1
- endoreg_db/utils/pipelines/process_video_dir.py +1 -1
- endoreg_db/utils/requirement_operator_logic/_old/model_evaluators.py +655 -0
- endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +97 -0
- endoreg_db/utils/setup_config.py +8 -5
- endoreg_db/utils/storage.py +115 -0
- endoreg_db/utils/validate_endo_roi.py +8 -2
- endoreg_db/utils/video/ffmpeg_wrapper.py +184 -188
- endoreg_db/views/__init__.py +85 -183
- endoreg_db/views/ai/__init__.py +8 -0
- endoreg_db/views/ai/label.py +155 -0
- endoreg_db/views/anonymization/media_management.py +202 -166
- endoreg_db/views/anonymization/overview.py +99 -67
- endoreg_db/views/anonymization/validate.py +182 -44
- endoreg_db/views/media/__init__.py +7 -20
- endoreg_db/views/media/pdf_media.py +197 -174
- endoreg_db/views/media/sensitive_metadata.py +193 -138
- endoreg_db/views/media/video_media.py +89 -82
- endoreg_db/views/meta/__init__.py +0 -8
- endoreg_db/views/misc/__init__.py +1 -7
- endoreg_db/views/misc/upload_views.py +94 -93
- endoreg_db/views/patient/patient.py +5 -4
- endoreg_db/views/report/__init__.py +5 -7
- endoreg_db/views/{pdf → report}/reimport.py +22 -22
- endoreg_db/views/{pdf/pdf_stream.py → report/report_stream.py} +46 -39
- endoreg_db/views/requirement/evaluate.py +188 -187
- endoreg_db/views/requirement/lookup.py +17 -3
- endoreg_db/views/requirement/lookup_store.py +22 -90
- endoreg_db/views/requirement/requirement_utils.py +89 -0
- endoreg_db/views/video/__init__.py +23 -24
- endoreg_db/views/video/correction.py +201 -172
- endoreg_db/views/video/reimport.py +1 -1
- endoreg_db/views/{media/video_segments.py → video/segments_crud.py} +77 -40
- endoreg_db/views/video/{video_meta.py → video_meta_stats.py} +2 -2
- endoreg_db/views/video/video_stream.py +7 -8
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/METADATA +7 -3
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/RECORD +391 -413
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/WHEEL +1 -1
- endoreg_db/data/finding/anatomy_colon.yaml +0 -128
- endoreg_db/data/finding/colonoscopy.yaml +0 -40
- endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +0 -56
- endoreg_db/data/finding/complication.yaml +0 -16
- endoreg_db/data/finding/data.yaml +0 -105
- endoreg_db/data/finding/examination_setting.yaml +0 -16
- endoreg_db/data/finding/medication_related.yaml +0 -18
- endoreg_db/data/finding/outcome.yaml +0 -12
- endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +0 -95
- endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +0 -22
- endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +0 -25
- endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
- endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +0 -68
- endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_location.yaml +0 -80
- endoreg_db/data/finding_classification/colonoscopy_lst.yaml +0 -21
- endoreg_db/data/finding_classification/colonoscopy_nice.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_paris.yaml +0 -26
- endoreg_db/data/finding_classification/colonoscopy_sano.yaml +0 -22
- endoreg_db/data/finding_classification/colonoscopy_summary.yaml +0 -53
- endoreg_db/data/finding_classification/complication_generic.yaml +0 -25
- endoreg_db/data/finding_classification/examination_setting_generic.yaml +0 -40
- endoreg_db/data/finding_classification/histology_colo.yaml +0 -51
- endoreg_db/data/finding_classification/intervention_required.yaml +0 -26
- endoreg_db/data/finding_classification/medication_related.yaml +0 -23
- endoreg_db/data/finding_classification/visualized.yaml +0 -33
- endoreg_db/data/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
- endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
- endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
- endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +0 -15
- endoreg_db/data/finding_classification_choice/colon_lesion_nice.yaml +0 -17
- endoreg_db/data/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
- endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +0 -14
- endoreg_db/data/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
- endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +0 -82
- endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
- endoreg_db/data/finding_classification_choice/outcome.yaml +0 -19
- endoreg_db/data/finding_intervention/endoscopy.yaml +0 -43
- endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
- endoreg_db/data/finding_intervention/endoscopy_egd.yaml +0 -128
- endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +0 -32
- endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +0 -9
- endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +0 -36
- endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +0 -79
- endoreg_db/data/requirement/age.yaml +0 -26
- endoreg_db/data/requirement/gender.yaml +0 -25
- endoreg_db/management/commands/init_default_ai_model.py +0 -112
- endoreg_db/management/commands/reset_celery_schedule.py +0 -9
- endoreg_db/management/commands/validate_video.py +0 -204
- endoreg_db/migrations/0002_add_video_correction_models.py +0 -52
- endoreg_db/migrations/0003_add_center_display_name.py +0 -30
- endoreg_db/models/administration/permissions/__init__.py +0 -44
- endoreg_db/models/rule/__init__.py +0 -13
- endoreg_db/models/rule/rule.py +0 -27
- endoreg_db/models/rule/rule_applicator.py +0 -224
- endoreg_db/models/rule/rule_attribute_dtype.py +0 -17
- endoreg_db/models/rule/rule_type.py +0 -20
- endoreg_db/models/rule/ruleset.py +0 -17
- endoreg_db/renames.yml +0 -8
- endoreg_db/serializers/_old/raw_pdf_meta_validation.py +0 -223
- endoreg_db/serializers/_old/raw_video_meta_validation.py +0 -179
- endoreg_db/serializers/_old/video.py +0 -71
- endoreg_db/serializers/meta/pdf_file_meta_extraction.py +0 -115
- endoreg_db/serializers/meta/report_meta.py +0 -53
- endoreg_db/serializers/report/__init__.py +0 -9
- endoreg_db/serializers/report/mixins.py +0 -45
- endoreg_db/serializers/report/report.py +0 -105
- endoreg_db/serializers/report/report_list.py +0 -22
- endoreg_db/serializers/report/secure_file_url.py +0 -26
- endoreg_db/serializers/video/video_metadata.py +0 -105
- endoreg_db/services/requirements_object.py +0 -147
- endoreg_db/services/storage_aware_video_processor.py +0 -344
- endoreg_db/urls/files.py +0 -6
- endoreg_db/urls/label_video_segment_validate.py +0 -33
- endoreg_db/urls/label_video_segments.py +0 -46
- endoreg_db/urls/report.py +0 -48
- endoreg_db/urls/video.py +0 -61
- endoreg_db/utils/case_generator/case_generator.py +0 -159
- endoreg_db/utils/case_generator/utils.py +0 -30
- endoreg_db/utils/requirement_operator_logic/model_evaluators.py +0 -368
- endoreg_db/views/label/__init__.py +0 -5
- endoreg_db/views/label/label.py +0 -15
- endoreg_db/views/label_video_segment/__init__.py +0 -16
- endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +0 -44
- endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +0 -50
- endoreg_db/views/label_video_segment/label_video_segment.py +0 -77
- endoreg_db/views/label_video_segment/label_video_segment_by_label.py +0 -174
- endoreg_db/views/label_video_segment/label_video_segment_detail.py +0 -73
- endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +0 -46
- endoreg_db/views/label_video_segment/validate.py +0 -226
- endoreg_db/views/media/segments.py +0 -71
- endoreg_db/views/meta/available_files_list.py +0 -146
- endoreg_db/views/meta/report_meta.py +0 -53
- endoreg_db/views/meta/sensitive_meta_detail.py +0 -148
- endoreg_db/views/misc/secure_file_serving_view.py +0 -80
- endoreg_db/views/misc/secure_file_url_view.py +0 -84
- endoreg_db/views/misc/secure_url_validate.py +0 -79
- endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +0 -164
- endoreg_db/views/patient_finding_location/__init__.py +0 -5
- endoreg_db/views/patient_finding_location/pfl_create.py +0 -70
- endoreg_db/views/patient_finding_morphology/__init__.py +0 -5
- endoreg_db/views/patient_finding_morphology/pfm_create.py +0 -70
- endoreg_db/views/pdf/__init__.py +0 -8
- endoreg_db/views/report/report_list.py +0 -112
- endoreg_db/views/report/report_with_secure_url.py +0 -28
- endoreg_db/views/report/start_examination.py +0 -7
- endoreg_db/views/video/segmentation.py +0 -274
- endoreg_db/views/video/task_status.py +0 -49
- endoreg_db/views/video/timeline.py +0 -46
- endoreg_db/views/video/video_analyze.py +0 -52
- endoreg_db/views.py +0 -0
- /endoreg_db/data/requirement/{colonoscopy_baseline_austria.yaml → old/colonoscopy_baseline_austria.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_cardiovascular.yaml → old/disease_cardiovascular.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_classification_choice_cardiovascular.yaml → old/disease_classification_choice_cardiovascular.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_hepatology.yaml → old/disease_hepatology.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_misc.yaml → old/disease_misc.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_renal.yaml → old/disease_renal.yaml} +0 -0
- /endoreg_db/data/requirement/{endoscopy_bleeding_risk.yaml → old/endoscopy_bleeding_risk.yaml} +0 -0
- /endoreg_db/data/requirement/{event_cardiology.yaml → old/event_cardiology.yaml} +0 -0
- /endoreg_db/data/requirement/{event_requirements.yaml → old/event_requirements.yaml} +0 -0
- /endoreg_db/data/requirement/{finding_colon_polyp.yaml → old/finding_colon_polyp.yaml} +0 -0
- /endoreg_db/{migrations/__init__.py → data/requirement/old/gender.yaml} +0 -0
- /endoreg_db/data/requirement/{lab_value.yaml → old/lab_value.yaml} +0 -0
- /endoreg_db/data/requirement/{medication.yaml → old/medication.yaml} +0 -0
- /endoreg_db/data/requirement_operator/{age.yaml → _old/age.yaml} +0 -0
- /endoreg_db/data/requirement_operator/{lab_operators.yaml → _old/lab_operators.yaml} +0 -0
- /endoreg_db/data/requirement_operator/{model_operators.yaml → _old/model_operators.yaml} +0 -0
- /endoreg_db/{models/media/video/refactor_plan.md → import_files/pseudonymization/__init__.py} +0 -0
- /endoreg_db/{models/media/video/video_file_frames.py → import_files/pseudonymization/pseudonymize.py} +0 -0
- /endoreg_db/models/{metadata/frame_ocr_result.py → report/__init__.py} +0 -0
- /endoreg_db/{urls/sensitive_meta.py → models/report/images.py} +0 -0
- /endoreg_db/utils/requirement_operator_logic/{lab_value_operators.py → _old/lab_value_operators.py} +0 -0
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,50 +1,40 @@
|
|
|
1
|
-
from django.db import models
|
|
2
|
-
from typing import TYPE_CHECKING, Dict
|
|
3
1
|
import random
|
|
4
|
-
import
|
|
2
|
+
from typing import TYPE_CHECKING, Dict
|
|
5
3
|
|
|
4
|
+
import numpy as np
|
|
5
|
+
from django.db import models
|
|
6
6
|
|
|
7
7
|
# Corrected imports for type hints
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
9
|
from ..finding import (
|
|
10
|
-
FindingClassification,
|
|
11
|
-
FindingClassificationChoice,
|
|
10
|
+
FindingClassification,
|
|
11
|
+
FindingClassificationChoice,
|
|
12
12
|
)
|
|
13
13
|
from .patient_finding import PatientFinding
|
|
14
14
|
|
|
15
|
+
|
|
15
16
|
class PatientFindingClassification(models.Model):
|
|
16
17
|
"""Represents basic classifications for specific findings in a patient context.
|
|
17
18
|
Links a PatientFinding to a specific classification and choice, with optional subcategory values.
|
|
18
19
|
"""
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
)
|
|
24
|
-
classification = models.ForeignKey( # type: ignore[assignment]
|
|
25
|
-
"FindingClassification",
|
|
26
|
-
on_delete=models.CASCADE,
|
|
27
|
-
related_name="patient_finding_classifications"
|
|
28
|
-
)
|
|
29
|
-
classification_choice = models.ForeignKey( # type: ignore[assignment]
|
|
30
|
-
"FindingClassificationChoice",
|
|
31
|
-
on_delete=models.CASCADE,
|
|
32
|
-
related_name="patient_finding_classifications"
|
|
33
|
-
)
|
|
20
|
+
|
|
21
|
+
finding = models.ForeignKey("PatientFinding", on_delete=models.CASCADE, related_name="classifications")
|
|
22
|
+
classification = models.ForeignKey("FindingClassification", on_delete=models.CASCADE, related_name="patient_finding_classifications")
|
|
23
|
+
classification_choice = models.ForeignKey("FindingClassificationChoice", on_delete=models.CASCADE, related_name="patient_finding_classifications")
|
|
34
24
|
|
|
35
25
|
is_active = models.BooleanField(default=True, help_text="Indicates if the classification is currently active.")
|
|
36
26
|
subcategories = models.JSONField(blank=True, null=True)
|
|
37
27
|
numerical_descriptors = models.JSONField(blank=True, null=True)
|
|
38
28
|
|
|
39
29
|
if TYPE_CHECKING:
|
|
40
|
-
finding: "PatientFinding"
|
|
41
|
-
classification: "FindingClassification"
|
|
42
|
-
classification_choice: "FindingClassificationChoice"
|
|
30
|
+
finding: models.ForeignKey["PatientFinding"]
|
|
31
|
+
classification: models.ForeignKey["FindingClassification"]
|
|
32
|
+
classification_choice: models.ForeignKey["FindingClassificationChoice"]
|
|
43
33
|
|
|
44
34
|
class Meta:
|
|
45
|
-
verbose_name =
|
|
46
|
-
verbose_name_plural =
|
|
47
|
-
ordering = [
|
|
35
|
+
verbose_name = "Patient Finding Classification"
|
|
36
|
+
verbose_name_plural = "Patient Finding Classifications"
|
|
37
|
+
ordering = ["finding", "classification", "classification_choice"]
|
|
48
38
|
|
|
49
39
|
def __str__(self):
|
|
50
40
|
"""
|
|
@@ -55,7 +45,7 @@ class PatientFindingClassification(models.Model):
|
|
|
55
45
|
def save(self, *args, **kwargs):
|
|
56
46
|
"""
|
|
57
47
|
Saves the model instance after validating and initializing classification-related fields.
|
|
58
|
-
|
|
48
|
+
|
|
59
49
|
Ensures that the selected classification choice is valid for the associated classification. If subcategories or numerical descriptors are unset, initializes them from the classification choice before saving.
|
|
60
50
|
"""
|
|
61
51
|
if self.classification_choice not in self.classification.choices.all():
|
|
@@ -72,7 +62,7 @@ class PatientFindingClassification(models.Model):
|
|
|
72
62
|
def initialize_and_get_subcategories(self):
|
|
73
63
|
"""
|
|
74
64
|
Ensure the subcategories field is initialized and return its dictionary.
|
|
75
|
-
|
|
65
|
+
|
|
76
66
|
Returns:
|
|
77
67
|
dict: The subcategories associated with this classification.
|
|
78
68
|
"""
|
|
@@ -83,43 +73,46 @@ class PatientFindingClassification(models.Model):
|
|
|
83
73
|
def initialize_and_get_descriptors(self):
|
|
84
74
|
"""
|
|
85
75
|
Return the numerical descriptors dictionary, initializing it if necessary.
|
|
86
|
-
|
|
76
|
+
|
|
87
77
|
If the `numerical_descriptors` field is empty or uninitialized, the method triggers model initialization and returns the resulting dictionary.
|
|
88
78
|
"""
|
|
89
79
|
if not self.numerical_descriptors:
|
|
90
80
|
self.save()
|
|
91
81
|
return self.numerical_descriptors
|
|
92
82
|
|
|
93
|
-
def set_subcategory(self, subcategory_name: str, subcategory_value: Dict):
|
|
83
|
+
def set_subcategory(self, subcategory_name: str, subcategory_value: Dict[str, dict]):
|
|
94
84
|
"""
|
|
95
85
|
Update the value of a specified subcategory and save the classification.
|
|
96
|
-
|
|
86
|
+
|
|
97
87
|
Parameters:
|
|
98
88
|
subcategory_name (str): The name of the subcategory to update.
|
|
99
89
|
subcategory_value (dict): The value to assign to the subcategory.
|
|
100
|
-
|
|
90
|
+
|
|
101
91
|
Returns:
|
|
102
92
|
dict: The updated subcategory dictionary.
|
|
103
93
|
"""
|
|
94
|
+
assert self.subcategories, "Subcategories must be initialized."
|
|
104
95
|
assert subcategory_name in self.subcategories, "Subcategory must be in subcategories."
|
|
105
96
|
self.subcategories[subcategory_name]["value"] = subcategory_value
|
|
106
97
|
self.save()
|
|
107
98
|
|
|
108
99
|
return self.subcategories[subcategory_name]
|
|
109
|
-
|
|
100
|
+
|
|
110
101
|
def set_random_subcategories(self):
|
|
111
102
|
"""
|
|
112
103
|
Assign random values to all required subcategories that do not already have a value.
|
|
113
|
-
|
|
104
|
+
|
|
114
105
|
For each required subcategory without a value, selects a random option from its available choices, updates the subcategory, saves the model, and returns the updated subcategories dictionary.
|
|
115
|
-
|
|
106
|
+
|
|
116
107
|
Returns:
|
|
117
108
|
dict: The updated subcategories with random values assigned where needed.
|
|
118
109
|
"""
|
|
110
|
+
|
|
119
111
|
if not self.subcategories or not self.numerical_descriptors:
|
|
120
112
|
self.save()
|
|
121
|
-
|
|
113
|
+
|
|
122
114
|
self.refresh_from_db()
|
|
115
|
+
assert self.subcategories is not None, "Subcategories must be initialized."
|
|
123
116
|
|
|
124
117
|
for subcategory_name, subcategory_dict in self.subcategories.items():
|
|
125
118
|
if subcategory_dict["required"] and not subcategory_dict.get("value", None):
|
|
@@ -129,21 +122,21 @@ class PatientFindingClassification(models.Model):
|
|
|
129
122
|
self.save()
|
|
130
123
|
|
|
131
124
|
return self.subcategories
|
|
132
|
-
|
|
133
|
-
def get_random_value_for_numerical_descriptor(self, descriptor_name):
|
|
134
125
|
|
|
126
|
+
def get_random_value_for_numerical_descriptor(self, descriptor_name):
|
|
135
127
|
"""
|
|
136
128
|
Generate a random value for the specified numerical descriptor using its defined distribution parameters.
|
|
137
|
-
|
|
129
|
+
|
|
138
130
|
Parameters:
|
|
139
131
|
descriptor_name (str): The name of the numerical descriptor to generate a value for.
|
|
140
|
-
|
|
132
|
+
|
|
141
133
|
Returns:
|
|
142
134
|
float: A randomly generated value based on the descriptor's distribution, clipped to its min and max range.
|
|
143
|
-
|
|
135
|
+
|
|
144
136
|
Raises:
|
|
145
137
|
ValueError: If the descriptor's distribution type is not supported.
|
|
146
|
-
"""
|
|
138
|
+
"""
|
|
139
|
+
assert self.numerical_descriptors is not None, "Numerical descriptors must be initialized."
|
|
147
140
|
assert descriptor_name in self.numerical_descriptors, "Descriptor must be in numerical descriptors."
|
|
148
141
|
descriptor = self.numerical_descriptors[descriptor_name]
|
|
149
142
|
min_val = descriptor.get("min", 0)
|
|
@@ -159,20 +152,20 @@ class PatientFindingClassification(models.Model):
|
|
|
159
152
|
value = np.random.uniform(min_val, max_val)
|
|
160
153
|
else:
|
|
161
154
|
raise ValueError("Distribution not supported")
|
|
162
|
-
|
|
155
|
+
|
|
163
156
|
return value
|
|
164
157
|
|
|
165
158
|
def set_random_numerical_descriptor(self, descriptor_name, save=True):
|
|
166
159
|
"""
|
|
167
160
|
Assigns a random value to the specified numerical descriptor and optionally saves the model.
|
|
168
|
-
|
|
161
|
+
|
|
169
162
|
Parameters:
|
|
170
163
|
descriptor_name (str): The name of the numerical descriptor to update.
|
|
171
164
|
save (bool): If True, saves the model after updating the descriptor. Defaults to True.
|
|
172
|
-
|
|
165
|
+
|
|
173
166
|
Returns:
|
|
174
167
|
dict: The updated numerical descriptor dictionary with the new random value.
|
|
175
|
-
|
|
168
|
+
|
|
176
169
|
Raises:
|
|
177
170
|
ValueError: If the descriptor name is not present in the numerical descriptors.
|
|
178
171
|
"""
|
|
@@ -180,23 +173,25 @@ class PatientFindingClassification(models.Model):
|
|
|
180
173
|
raise ValueError("Descriptor name must be in numerical descriptors.")
|
|
181
174
|
|
|
182
175
|
value = self.get_random_value_for_numerical_descriptor(descriptor_name)
|
|
183
|
-
|
|
176
|
+
assert self.numerical_descriptors is not None, "Numerical descriptors must be initialized."
|
|
184
177
|
self.numerical_descriptors[descriptor_name]["value"] = value
|
|
185
178
|
if save:
|
|
186
179
|
self.save()
|
|
187
180
|
|
|
188
181
|
return self.numerical_descriptors[descriptor_name]
|
|
189
|
-
|
|
182
|
+
|
|
190
183
|
def set_random_numerical_descriptors(self):
|
|
191
184
|
"""
|
|
192
185
|
Assigns random values to all numerical descriptors and saves the model.
|
|
193
|
-
|
|
186
|
+
|
|
194
187
|
Returns:
|
|
195
188
|
dict: The updated numerical_descriptors dictionary with assigned random values.
|
|
196
189
|
"""
|
|
197
190
|
if not self.subcategories or not self.numerical_descriptors:
|
|
198
191
|
self.save()
|
|
199
192
|
|
|
193
|
+
assert self.numerical_descriptors is not None, "Numerical descriptors must be initialized."
|
|
194
|
+
|
|
200
195
|
numerical_descriptors = self.numerical_descriptors
|
|
201
196
|
|
|
202
197
|
for numerical_descriptor_name, _numerical_descriptor_dict in numerical_descriptors.items():
|
|
@@ -1,40 +1,29 @@
|
|
|
1
|
-
from operator import is_
|
|
2
|
-
from django.db import models
|
|
3
1
|
from typing import TYPE_CHECKING
|
|
4
2
|
|
|
3
|
+
from django.db import models
|
|
4
|
+
|
|
5
5
|
if TYPE_CHECKING:
|
|
6
6
|
from ..finding import FindingIntervention
|
|
7
7
|
from .patient_finding import PatientFinding
|
|
8
8
|
|
|
9
|
+
|
|
9
10
|
class PatientFindingIntervention(models.Model):
|
|
10
|
-
finding = models.ForeignKey(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
related_name='interventions'
|
|
14
|
-
)
|
|
15
|
-
intervention = models.ForeignKey(
|
|
16
|
-
'FindingIntervention',
|
|
17
|
-
on_delete=models.CASCADE,
|
|
18
|
-
related_name='patient_finding_interventions'
|
|
19
|
-
)
|
|
20
|
-
is_active = models.BooleanField(
|
|
21
|
-
default=True,
|
|
22
|
-
help_text="Indicates if the intervention is currently active."
|
|
23
|
-
)
|
|
11
|
+
finding = models.ForeignKey("PatientFinding", on_delete=models.CASCADE, related_name="interventions")
|
|
12
|
+
intervention = models.ForeignKey("FindingIntervention", on_delete=models.CASCADE, related_name="patient_finding_interventions")
|
|
13
|
+
is_active = models.BooleanField(default=True, help_text="Indicates if the intervention is currently active.")
|
|
24
14
|
state = models.CharField(max_length=100, blank=True, null=True)
|
|
25
15
|
time_start = models.DateTimeField(blank=True, null=True)
|
|
26
16
|
time_end = models.DateTimeField(blank=True, null=True)
|
|
27
17
|
date = models.DateField(blank=True, null=True)
|
|
28
18
|
|
|
29
19
|
if TYPE_CHECKING:
|
|
30
|
-
finding: "PatientFinding"
|
|
31
|
-
intervention: "FindingIntervention"
|
|
20
|
+
finding: models.ForeignKey["PatientFinding"]
|
|
21
|
+
intervention: models.ForeignKey["FindingIntervention"]
|
|
32
22
|
|
|
33
23
|
def __str__(self):
|
|
34
24
|
return self.intervention.name
|
|
35
25
|
|
|
36
26
|
def natural_key(self):
|
|
37
27
|
return (self.intervention.name,)
|
|
38
|
-
|
|
39
28
|
|
|
40
29
|
objects = models.Manager()
|
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
from
|
|
1
|
+
from datetime import datetime as dt
|
|
2
|
+
from datetime import timezone
|
|
2
3
|
from typing import TYPE_CHECKING
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
from django.db import models
|
|
4
6
|
|
|
5
7
|
if TYPE_CHECKING:
|
|
6
|
-
from endoreg_db.models import
|
|
7
|
-
from endoreg_db.utils.links.requirement_link import RequirementLinks
|
|
8
|
+
from endoreg_db.models import LabValue, Patient, PatientLabValue
|
|
9
|
+
from endoreg_db.utils.links.requirement_link import RequirementLinks # Added import
|
|
8
10
|
|
|
9
11
|
DEFAULT_PATIENT_LAB_SAMPLE_TYPE_NAME = "generic"
|
|
10
12
|
|
|
13
|
+
|
|
11
14
|
class PatientLabSampleTypeManager(models.Manager):
|
|
12
15
|
"""Manager for PatientLabSampleType with natural key support."""
|
|
16
|
+
|
|
13
17
|
def get_by_natural_key(self, name):
|
|
14
18
|
"""Retrieves a PatientLabSampleType instance by its natural key (name)."""
|
|
15
19
|
return self.get(name=name)
|
|
16
20
|
|
|
21
|
+
|
|
17
22
|
class PatientLabSampleType(models.Model):
|
|
18
23
|
"""
|
|
19
24
|
Represents the type of a patient lab sample (e.g., Blood, Urine).
|
|
@@ -22,6 +27,7 @@ class PatientLabSampleType(models.Model):
|
|
|
22
27
|
name (str): The name of the patient lab sample type.
|
|
23
28
|
description (str): A description of the patient lab sample type.
|
|
24
29
|
"""
|
|
30
|
+
|
|
25
31
|
name = models.CharField(max_length=255)
|
|
26
32
|
description = models.TextField(blank=True, null=True)
|
|
27
33
|
|
|
@@ -34,12 +40,13 @@ class PatientLabSampleType(models.Model):
|
|
|
34
40
|
def __str__(self):
|
|
35
41
|
"""Returns the name of the sample type."""
|
|
36
42
|
return str(self.name)
|
|
37
|
-
|
|
43
|
+
|
|
38
44
|
@classmethod
|
|
39
45
|
def get_default_sample_type(cls):
|
|
40
46
|
"""Gets or creates the default patient lab sample type ('default')."""
|
|
41
47
|
return cls.objects.get_or_create(name="default")[0]
|
|
42
48
|
|
|
49
|
+
|
|
43
50
|
class PatientLabSample(models.Model):
|
|
44
51
|
"""
|
|
45
52
|
Represents a specific lab sample taken from a patient at a certain date and time.
|
|
@@ -52,24 +59,27 @@ class PatientLabSample(models.Model):
|
|
|
52
59
|
date (datetime): The date of the lab sample.
|
|
53
60
|
values (PatientLabValue; One2Many): The value of the lab sample.
|
|
54
61
|
"""
|
|
62
|
+
|
|
55
63
|
patient = models.ForeignKey("Patient", on_delete=models.CASCADE, related_name="lab_samples")
|
|
56
64
|
sample_type = models.ForeignKey("PatientLabSampleType", on_delete=models.CASCADE)
|
|
57
65
|
date = models.DateTimeField()
|
|
58
66
|
|
|
59
67
|
if TYPE_CHECKING:
|
|
60
|
-
patient: "Patient"
|
|
61
|
-
sample_type: "PatientLabSampleType"
|
|
62
|
-
|
|
68
|
+
patient: models.ForeignKey["Patient"]
|
|
69
|
+
sample_type: models.ForeignKey["PatientLabSampleType"]
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def values(self) -> models.manager.RelatedManager["PatientLabValue"]: ...
|
|
63
73
|
|
|
64
74
|
def __str__(self):
|
|
65
75
|
"""Returns a string representation including patient, type, and date."""
|
|
66
|
-
formatted_datetime = self.date.strftime(
|
|
76
|
+
formatted_datetime = self.date.strftime("%Y-%m-%d %H:%M")
|
|
67
77
|
return f"{self.patient} - {self.sample_type} - {formatted_datetime} ()"
|
|
68
|
-
|
|
78
|
+
|
|
69
79
|
def get_values(self):
|
|
70
80
|
"""Returns all PatientLabValue instances associated with this sample."""
|
|
71
81
|
return self.values.all()
|
|
72
|
-
|
|
82
|
+
|
|
73
83
|
@property
|
|
74
84
|
def links(self) -> "RequirementLinks":
|
|
75
85
|
"""
|
|
@@ -84,11 +94,11 @@ class PatientLabSample(models.Model):
|
|
|
84
94
|
|
|
85
95
|
return RequirementLinks(
|
|
86
96
|
patient_lab_values=patient_lab_values,
|
|
87
|
-
patient_lab_samples=[self]
|
|
97
|
+
patient_lab_samples=[self], # Include the sample itself
|
|
88
98
|
)
|
|
89
99
|
|
|
90
100
|
@classmethod
|
|
91
|
-
def create_by_patient(cls, patient=None, sample_type=None, date=None, save
|
|
101
|
+
def create_by_patient(cls, patient=None, sample_type=None, date=None, save=True):
|
|
92
102
|
"""
|
|
93
103
|
Creates a new patient lab sample for a given patient.
|
|
94
104
|
|
|
@@ -115,26 +125,22 @@ class PatientLabSample(models.Model):
|
|
|
115
125
|
if not date:
|
|
116
126
|
date = dt.now(timezone.utc)
|
|
117
127
|
|
|
118
|
-
patient_lab_sample = cls.objects.create(
|
|
119
|
-
patient=patient,
|
|
120
|
-
sample_type=sample_type,
|
|
121
|
-
date=date
|
|
122
|
-
)
|
|
128
|
+
patient_lab_sample = cls.objects.create(patient=patient, sample_type=sample_type, date=date)
|
|
123
129
|
|
|
124
130
|
if save:
|
|
125
131
|
patient_lab_sample.save()
|
|
126
132
|
|
|
127
133
|
return patient_lab_sample
|
|
128
134
|
|
|
129
|
-
|
|
130
|
-
def add_empty_value(self, lab_value:"LabValue"):
|
|
135
|
+
def add_empty_value(self, lab_value: "LabValue"):
|
|
131
136
|
"""
|
|
132
137
|
Adds an empty PatientLabValue for the given lab value to this sample.
|
|
133
138
|
|
|
134
139
|
Args:
|
|
135
140
|
lab_value (LabValue): The lab value to add.
|
|
136
141
|
"""
|
|
137
|
-
from endoreg_db.models import
|
|
142
|
+
from endoreg_db.models import LabValue, PatientLabValue
|
|
143
|
+
|
|
138
144
|
if not isinstance(lab_value, LabValue):
|
|
139
145
|
raise ValueError("lab_value must be an instance of LabValue.")
|
|
140
146
|
patient_lab_value = PatientLabValue.create_lab_value_by_sample(
|
|
@@ -142,7 +148,6 @@ class PatientLabSample(models.Model):
|
|
|
142
148
|
lab_value_name=lab_value.name,
|
|
143
149
|
value=None, # Empty value
|
|
144
150
|
value_str=None, # Empty string
|
|
145
|
-
unit=lab_value.default_unit # Use the unit from the lab value
|
|
151
|
+
unit=lab_value.default_unit, # Use the unit from the lab value
|
|
146
152
|
)
|
|
147
153
|
return patient_lab_value
|
|
148
|
-
|