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,12 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
import numbers
|
|
2
2
|
from typing import TYPE_CHECKING, Optional
|
|
3
3
|
|
|
4
|
+
from django.db import models
|
|
5
|
+
|
|
4
6
|
if TYPE_CHECKING:
|
|
7
|
+
from endoreg_db.utils.links.requirement_link import RequirementLinks # Added import
|
|
8
|
+
|
|
5
9
|
from ...administration.person.patient import Patient
|
|
6
|
-
from ..laboratory import LabValue
|
|
7
10
|
from ...other.unit import Unit
|
|
11
|
+
from ..laboratory import LabValue
|
|
8
12
|
from .patient_lab_sample import PatientLabSample
|
|
9
|
-
|
|
13
|
+
|
|
10
14
|
|
|
11
15
|
class PatientLabValue(models.Model):
|
|
12
16
|
"""
|
|
@@ -18,50 +22,55 @@ class PatientLabValue(models.Model):
|
|
|
18
22
|
value (float): The value of the lab value.
|
|
19
23
|
date (datetime): The date of the lab value.
|
|
20
24
|
"""
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
)
|
|
24
|
-
lab_value = models.ForeignKey('LabValue', on_delete=models.CASCADE)
|
|
25
|
+
|
|
26
|
+
patient = models.ForeignKey("Patient", on_delete=models.CASCADE, related_name="lab_values", blank=True, null=True)
|
|
27
|
+
lab_value = models.ForeignKey("LabValue", on_delete=models.CASCADE)
|
|
25
28
|
value = models.FloatField(blank=True, null=True)
|
|
26
29
|
value_str = models.CharField(max_length=255, blank=True, null=True)
|
|
27
|
-
sample
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
related_name='values'
|
|
31
|
-
)
|
|
32
|
-
datetime = models.DateTimeField(# if not set, use now
|
|
33
|
-
auto_now_add=True
|
|
30
|
+
sample = models.ForeignKey("PatientLabSample", on_delete=models.CASCADE, blank=True, null=True, related_name="values")
|
|
31
|
+
datetime = models.DateTimeField( # if not set, use now
|
|
32
|
+
auto_now_add=True
|
|
34
33
|
)
|
|
35
|
-
normal_range = models.JSONField(
|
|
36
|
-
|
|
37
|
-
)
|
|
38
|
-
unit = models.ForeignKey('Unit', on_delete=models.CASCADE, blank=True, null=True)
|
|
34
|
+
normal_range = models.JSONField(default=dict)
|
|
35
|
+
unit = models.ForeignKey("Unit", on_delete=models.CASCADE, blank=True, null=True)
|
|
39
36
|
|
|
40
|
-
|
|
37
|
+
@property
|
|
38
|
+
def lab_value_safe(self) -> "LabValue":
|
|
39
|
+
"""Returns the lab value, raises error if not set."""
|
|
40
|
+
if not self.lab_value:
|
|
41
|
+
raise ValueError("Lab value is not set.")
|
|
42
|
+
return self.lab_value
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def patient_safe(self) -> "Patient":
|
|
46
|
+
"""Returns the patient, raises error if not set."""
|
|
47
|
+
if not self.patient:
|
|
48
|
+
raise ValueError("Patient is not set.")
|
|
49
|
+
return self.patient
|
|
41
50
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
51
|
+
if TYPE_CHECKING:
|
|
52
|
+
patient: models.ForeignKey["Patient|None"]
|
|
53
|
+
lab_value: models.ForeignKey["LabValue"]
|
|
54
|
+
unit: models.ForeignKey["Unit|None"]
|
|
55
|
+
sample: models.ForeignKey["PatientLabSample|None"]
|
|
56
|
+
normal_range: models.JSONField[dict]
|
|
46
57
|
|
|
47
58
|
@classmethod
|
|
48
59
|
def create_lab_value_by_sample(
|
|
49
|
-
cls, sample:"PatientLabSample", lab_value_name:str,
|
|
50
|
-
value:Optional[float]=None, value_str:Optional[str]=None,
|
|
51
|
-
unit:Optional["Unit"]=None
|
|
60
|
+
cls, sample: "PatientLabSample", lab_value_name: str, value: Optional[float] = None, value_str: Optional[str] = None, unit: Optional["Unit"] = None
|
|
52
61
|
):
|
|
53
62
|
from ..laboratory import LabValue
|
|
63
|
+
|
|
54
64
|
patient = sample.patient
|
|
55
65
|
lab_value = LabValue.objects.get(name=lab_value_name)
|
|
56
66
|
|
|
57
|
-
|
|
58
67
|
pat_lab_val = cls.objects.create(
|
|
59
|
-
patient
|
|
60
|
-
lab_value
|
|
61
|
-
value
|
|
62
|
-
value_str
|
|
63
|
-
sample
|
|
64
|
-
unit
|
|
68
|
+
patient=patient,
|
|
69
|
+
lab_value=lab_value,
|
|
70
|
+
value=value,
|
|
71
|
+
value_str=value_str,
|
|
72
|
+
sample=sample,
|
|
73
|
+
unit=unit,
|
|
65
74
|
)
|
|
66
75
|
|
|
67
76
|
pat_lab_val.save()
|
|
@@ -69,44 +78,41 @@ class PatientLabValue(models.Model):
|
|
|
69
78
|
return pat_lab_val
|
|
70
79
|
|
|
71
80
|
def __str__(self):
|
|
72
|
-
formatted_datetime = self.datetime.strftime(
|
|
81
|
+
formatted_datetime = self.datetime.strftime("%Y-%m-%d %H:%M")
|
|
73
82
|
# normal_range = self.get_normal_range()
|
|
74
|
-
norm_range_string = f
|
|
75
|
-
_str = f
|
|
83
|
+
norm_range_string = f"[{self.normal_range.get('min', '')} - {self.normal_range.get('max', '')}]"
|
|
84
|
+
_str = f"{self.lab_value} - {self.value} {self.unit} - {norm_range_string} ({formatted_datetime})"
|
|
76
85
|
return _str
|
|
77
|
-
|
|
86
|
+
|
|
78
87
|
def get_normal_range(self):
|
|
79
|
-
lab_value = self.
|
|
80
|
-
patient = self.
|
|
88
|
+
lab_value = self.lab_value_safe
|
|
89
|
+
patient = self.patient_safe
|
|
81
90
|
|
|
82
|
-
age = patient.
|
|
91
|
+
age = patient.age_safe
|
|
83
92
|
gender = patient.gender
|
|
84
93
|
|
|
85
|
-
normal_range_dict = lab_value.get_normal_range(
|
|
86
|
-
age,gender
|
|
87
|
-
)
|
|
94
|
+
normal_range_dict = lab_value.get_normal_range(age, gender)
|
|
88
95
|
return normal_range_dict
|
|
89
96
|
|
|
90
|
-
|
|
91
|
-
def set_min_norm_value(self, value, save = True):
|
|
97
|
+
def set_min_norm_value(self, value, save=True):
|
|
92
98
|
self.normal_range["min"] = value
|
|
93
99
|
if save:
|
|
94
100
|
self.save()
|
|
95
101
|
|
|
96
|
-
def set_max_norm_value(self, value, save
|
|
102
|
+
def set_max_norm_value(self, value, save=True):
|
|
97
103
|
self.normal_range["max"] = value
|
|
98
104
|
if save:
|
|
99
105
|
self.save()
|
|
100
106
|
|
|
101
107
|
def set_norm_values_from_default(self):
|
|
102
|
-
|
|
103
108
|
normal_range_dict = self.get_normal_range()
|
|
104
|
-
self.set_min_norm_value(normal_range_dict["min"], save
|
|
105
|
-
self.set_max_norm_value(normal_range_dict["max"], save
|
|
109
|
+
self.set_min_norm_value(normal_range_dict["min"], save=False)
|
|
110
|
+
self.set_max_norm_value(normal_range_dict["max"], save=False)
|
|
106
111
|
self.save()
|
|
107
112
|
|
|
108
113
|
def set_unit_from_default(self):
|
|
109
|
-
|
|
114
|
+
_default_unit = self.lab_value_safe.default_unit
|
|
115
|
+
self.unit = _default_unit
|
|
110
116
|
self.save()
|
|
111
117
|
|
|
112
118
|
def get_value(self):
|
|
@@ -114,65 +120,57 @@ class PatientLabValue(models.Model):
|
|
|
114
120
|
return self.value
|
|
115
121
|
else:
|
|
116
122
|
return self.value_str
|
|
117
|
-
|
|
123
|
+
|
|
118
124
|
def get_value_field_name(self):
|
|
119
125
|
if self.value:
|
|
120
126
|
return "value"
|
|
121
127
|
else:
|
|
122
128
|
return "value_str"
|
|
123
|
-
|
|
129
|
+
|
|
124
130
|
# customize save method so that if a numeric value exists, we round it to the precision of the lab value
|
|
125
131
|
def save(self, *args, **kwargs):
|
|
126
|
-
if self.value:
|
|
127
|
-
|
|
128
|
-
|
|
132
|
+
if self.value is not None:
|
|
133
|
+
# only attempt rounding for real numeric types (ints/floats/compatible)
|
|
134
|
+
|
|
135
|
+
precision = getattr(self.lab_value_safe, "numeric_precision", None)
|
|
136
|
+
if isinstance(self.value, numbers.Real) and precision is not None:
|
|
137
|
+
# ensure a plain float is passed to built-in round to satisfy type checkers
|
|
138
|
+
self.value = round(float(self.value), int(precision))
|
|
129
139
|
super().save(*args, **kwargs)
|
|
130
140
|
|
|
131
|
-
def set_value_by_distribution(self, distribution=None, save
|
|
132
|
-
|
|
133
|
-
|
|
141
|
+
def set_value_by_distribution(self, distribution=None, save=True):
|
|
142
|
+
import warnings
|
|
143
|
+
|
|
134
144
|
from ...other.distribution import (
|
|
135
145
|
DateValueDistribution,
|
|
136
|
-
SingleCategoricalValueDistribution,
|
|
137
|
-
NumericValueDistribution,
|
|
138
146
|
MultipleCategoricalValueDistribution,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
patient:Patient = self.patient
|
|
147
|
+
NumericValueDistribution,
|
|
148
|
+
SingleCategoricalValueDistribution,
|
|
149
|
+
)
|
|
143
150
|
|
|
144
|
-
|
|
151
|
+
patient = self.patient_safe
|
|
152
|
+
lab_value = self.lab_value_safe
|
|
145
153
|
|
|
146
|
-
|
|
147
|
-
self.unit = self.lab_value.default_unit
|
|
154
|
+
self.unit = self.lab_value_safe.default_unit
|
|
148
155
|
|
|
149
156
|
if not distribution:
|
|
150
157
|
distribution = lab_value.get_default_default_distribution()
|
|
151
158
|
|
|
152
159
|
if not distribution:
|
|
153
|
-
warnings.warn(
|
|
154
|
-
f"No distribution set for lab value {lab_value}, assuming uniform numeric distribution based on normal values"
|
|
155
|
-
)
|
|
160
|
+
warnings.warn(f"No distribution set for lab value {lab_value}, assuming uniform numeric distribution based on normal values")
|
|
156
161
|
|
|
157
162
|
if not self.normal_range.get("min", None) or not self.normal_range.get("max", None):
|
|
158
163
|
self.set_norm_values_from_default()
|
|
159
|
-
|
|
160
|
-
self.normal_range:dict
|
|
161
164
|
_min = self.normal_range.get("min", 0.0001)
|
|
162
165
|
_max = self.normal_range.get("max", 100)
|
|
163
|
-
_name = "auto-" + self.
|
|
164
|
-
distribution = NumericValueDistribution(
|
|
165
|
-
name = _name,
|
|
166
|
-
min_descriptor = _min,
|
|
167
|
-
max_max_desciptor = _max,
|
|
168
|
-
distribution_type = "uniform"
|
|
169
|
-
)
|
|
166
|
+
_name = "auto-" + self.lab_value_safe.name + "-distribution-default-uniform"
|
|
167
|
+
distribution = NumericValueDistribution(name=_name, min_descriptor=_min, max_max_desciptor=_max, distribution_type="uniform")
|
|
170
168
|
|
|
171
169
|
value = distribution.generate_value(lab_value=lab_value, patient=patient)
|
|
172
170
|
self.value = value
|
|
173
171
|
if save:
|
|
174
172
|
self.save()
|
|
175
|
-
|
|
173
|
+
|
|
176
174
|
return value
|
|
177
175
|
|
|
178
176
|
if isinstance(distribution, SingleCategoricalValueDistribution):
|
|
@@ -181,17 +179,14 @@ class PatientLabValue(models.Model):
|
|
|
181
179
|
if save:
|
|
182
180
|
self.save()
|
|
183
181
|
return value
|
|
184
|
-
|
|
182
|
+
|
|
185
183
|
elif isinstance(distribution, NumericValueDistribution):
|
|
186
|
-
value = distribution.generate_value(
|
|
187
|
-
lab_value=lab_value,
|
|
188
|
-
patient=patient
|
|
189
|
-
)
|
|
184
|
+
value = distribution.generate_value(lab_value=lab_value, patient=patient)
|
|
190
185
|
self.value = value
|
|
191
186
|
if save:
|
|
192
187
|
self.save()
|
|
193
188
|
return value
|
|
194
|
-
|
|
189
|
+
|
|
195
190
|
elif isinstance(distribution, MultipleCategoricalValueDistribution):
|
|
196
191
|
value = distribution.generate_value()
|
|
197
192
|
self.value_str = value
|
|
@@ -216,7 +211,5 @@ class PatientLabValue(models.Model):
|
|
|
216
211
|
from endoreg_db.utils.links.requirement_link import RequirementLinks
|
|
217
212
|
|
|
218
213
|
return RequirementLinks(
|
|
219
|
-
patient_lab_values=[self]
|
|
214
|
+
patient_lab_values=[self] # Include the lab value itself
|
|
220
215
|
)
|
|
221
|
-
|
|
222
|
-
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, List, Optional, cast # Added List
|
|
2
|
+
|
|
1
3
|
from django.db import models
|
|
2
|
-
from typing import TYPE_CHECKING, Optional, List # Added List
|
|
3
4
|
|
|
4
5
|
# Added imports for type hints
|
|
5
6
|
if TYPE_CHECKING:
|
|
7
|
+
from ....utils.links.requirement_link import RequirementLinks # Added RequirementLinks
|
|
6
8
|
from ...administration.person.patient import Patient
|
|
7
|
-
from ..medication import MedicationIndication, Medication, MedicationIntakeTime
|
|
8
9
|
from ...other.unit import Unit
|
|
9
|
-
from
|
|
10
|
+
from ..medication import Medication, MedicationIndication, MedicationIntakeTime
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
class PatientMedication(models.Model):
|
|
12
14
|
"""
|
|
@@ -14,42 +16,32 @@ class PatientMedication(models.Model):
|
|
|
14
16
|
|
|
15
17
|
Links a patient to a medication, its indication, dosage, intake times, and unit.
|
|
16
18
|
"""
|
|
19
|
+
|
|
17
20
|
patient = models.ForeignKey("Patient", on_delete=models.CASCADE)
|
|
18
|
-
medication_indication = models.ForeignKey(
|
|
19
|
-
"MedicationIndication", on_delete=models.CASCADE,
|
|
20
|
-
related_name="indication_patient_medications", null=True
|
|
21
|
-
)
|
|
21
|
+
medication_indication = models.ForeignKey("MedicationIndication", on_delete=models.CASCADE, related_name="indication_patient_medications", null=True)
|
|
22
22
|
|
|
23
|
-
medication = models.ForeignKey(
|
|
24
|
-
'Medication', on_delete=models.CASCADE,
|
|
25
|
-
blank=True,
|
|
26
|
-
related_name='medication_patient_medications'
|
|
27
|
-
)
|
|
23
|
+
medication = models.ForeignKey("Medication", on_delete=models.CASCADE, blank=True, related_name="medication_patient_medications")
|
|
28
24
|
|
|
29
25
|
intake_times = models.ManyToManyField(
|
|
30
|
-
|
|
31
|
-
related_name=
|
|
26
|
+
"MedicationIntakeTime",
|
|
27
|
+
related_name="intake_time_patient_medications",
|
|
32
28
|
blank=True,
|
|
33
29
|
)
|
|
34
30
|
|
|
35
|
-
unit = models.ForeignKey(
|
|
36
|
-
|
|
37
|
-
null=True, blank=True
|
|
38
|
-
)
|
|
39
|
-
dosage = models.JSONField(
|
|
40
|
-
null=True, blank=True
|
|
41
|
-
)
|
|
31
|
+
unit = models.ForeignKey("Unit", on_delete=models.CASCADE, null=True, blank=True)
|
|
32
|
+
dosage = models.JSONField(null=True, blank=True)
|
|
42
33
|
active = models.BooleanField(default=True)
|
|
43
34
|
|
|
44
35
|
objects = models.Manager()
|
|
45
36
|
|
|
46
37
|
if TYPE_CHECKING: # Added type hints block
|
|
47
|
-
patient: "Patient"
|
|
48
|
-
medication_indication:
|
|
49
|
-
medication:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
38
|
+
patient: models.ForeignKey["Patient"]
|
|
39
|
+
medication_indication: models.ForeignKey["MedicationIndication|None"]
|
|
40
|
+
medication: models.ForeignKey["Medication|None"]
|
|
41
|
+
|
|
42
|
+
intake_times = cast(models.manager.RelatedManager["MedicationIntakeTime"], intake_times)
|
|
43
|
+
unit: models.ForeignKey["Unit|None"]
|
|
44
|
+
dosage = cast(models.JSONField, dosage)
|
|
53
45
|
|
|
54
46
|
@property
|
|
55
47
|
def links(self) -> "RequirementLinks":
|
|
@@ -58,11 +50,11 @@ class PatientMedication(models.Model):
|
|
|
58
50
|
This is used during requirement evaluation.
|
|
59
51
|
"""
|
|
60
52
|
from ....utils.links.requirement_link import RequirementLinks
|
|
61
|
-
|
|
53
|
+
|
|
62
54
|
meds: List["Medication"] = []
|
|
63
55
|
if self.medication:
|
|
64
56
|
meds.append(self.medication)
|
|
65
|
-
|
|
57
|
+
|
|
66
58
|
indications: List["MedicationIndication"] = []
|
|
67
59
|
if self.medication_indication:
|
|
68
60
|
indications.append(self.medication_indication)
|
|
@@ -73,23 +65,21 @@ class PatientMedication(models.Model):
|
|
|
73
65
|
medications=meds,
|
|
74
66
|
medication_indications=indications,
|
|
75
67
|
medication_intake_times=intake_times_list,
|
|
76
|
-
patient_medications=[self]
|
|
68
|
+
patient_medications=[self], # Include self in patient_medications
|
|
77
69
|
)
|
|
78
70
|
|
|
79
71
|
class Meta:
|
|
80
|
-
verbose_name =
|
|
81
|
-
verbose_name_plural =
|
|
72
|
+
verbose_name = "Patient Medication"
|
|
73
|
+
verbose_name_plural = "Patient Medications"
|
|
82
74
|
|
|
83
75
|
@classmethod
|
|
84
|
-
def create_by_patient_and_indication(cls, patient, medication_indication):
|
|
76
|
+
def create_by_patient_and_indication(cls, patient, medication_indication: "MedicationIndication"):
|
|
85
77
|
"""Creates a PatientMedication instance linking a patient and an indication."""
|
|
86
|
-
|
|
87
|
-
medication_indication: MedicationIndication
|
|
78
|
+
|
|
88
79
|
patient_medication = cls.objects.create(patient=patient, medication_indication=medication_indication)
|
|
89
80
|
patient_medication.save()
|
|
90
|
-
|
|
91
|
-
return patient_medication
|
|
92
81
|
|
|
82
|
+
return patient_medication
|
|
93
83
|
|
|
94
84
|
def __str__(self):
|
|
95
85
|
"""Returns a string representation including medication, indication, dosage, and intake times."""
|
|
@@ -101,4 +91,3 @@ class PatientMedication(models.Model):
|
|
|
101
91
|
out += f"{intake_time} - "
|
|
102
92
|
|
|
103
93
|
return out
|
|
104
|
-
|
|
@@ -1,32 +1,30 @@
|
|
|
1
1
|
from django.db import models
|
|
2
|
-
from typing import TYPE_CHECKING, List # Added List
|
|
2
|
+
from typing import TYPE_CHECKING, List, cast # Added List
|
|
3
3
|
from datetime import datetime as dt
|
|
4
4
|
|
|
5
5
|
if TYPE_CHECKING:
|
|
6
6
|
from ...administration.person.patient import Patient
|
|
7
7
|
from .patient_medication import PatientMedication
|
|
8
8
|
from ..medication import MedicationSchedule
|
|
9
|
-
from ....utils.links.requirement_link import RequirementLinks
|
|
10
|
-
from ..medication import Medication, MedicationIndication, MedicationIntakeTime
|
|
9
|
+
from ....utils.links.requirement_link import RequirementLinks # Added
|
|
10
|
+
from ..medication import Medication, MedicationIndication, MedicationIntakeTime # Added
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class PatientMedicationSchedule(models.Model):
|
|
14
14
|
"""
|
|
15
15
|
Represents a collection of medications associated with a patient, forming their schedule.
|
|
16
16
|
"""
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
related_name='patient_medication_schedules',
|
|
21
|
-
blank=True
|
|
22
|
-
)
|
|
17
|
+
|
|
18
|
+
patient = models.ForeignKey("Patient", on_delete=models.CASCADE)
|
|
19
|
+
medication = models.ManyToManyField("PatientMedication", related_name="patient_medication_schedules", blank=True)
|
|
23
20
|
|
|
24
21
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
25
22
|
updated_at = models.DateTimeField(auto_now=True)
|
|
26
23
|
|
|
27
24
|
if TYPE_CHECKING:
|
|
28
|
-
patient: "Patient"
|
|
29
|
-
|
|
25
|
+
patient: models.ForeignKey["Patient"]
|
|
26
|
+
|
|
27
|
+
medication = cast(models.manager.RelatedManager["PatientMedication"], medication)
|
|
30
28
|
|
|
31
29
|
@property
|
|
32
30
|
def links(self) -> "RequirementLinks":
|
|
@@ -38,12 +36,12 @@ class PatientMedicationSchedule(models.Model):
|
|
|
38
36
|
aggregated_medications: List["Medication"] = []
|
|
39
37
|
aggregated_medication_indications: List["MedicationIndication"] = []
|
|
40
38
|
aggregated_medication_intake_times: List["MedicationIntakeTime"] = []
|
|
41
|
-
|
|
39
|
+
|
|
42
40
|
patient_meds_in_schedule: List["PatientMedication"] = list(self.medication.all())
|
|
43
41
|
|
|
44
42
|
for pm_instance in patient_meds_in_schedule:
|
|
45
|
-
pm_links_obj = pm_instance.links
|
|
46
|
-
|
|
43
|
+
pm_links_obj = pm_instance.links
|
|
44
|
+
|
|
47
45
|
aggregated_medications.extend(pm_links_obj.medications)
|
|
48
46
|
aggregated_medication_indications.extend(pm_links_obj.medication_indications)
|
|
49
47
|
aggregated_medication_intake_times.extend(pm_links_obj.medication_intake_times)
|
|
@@ -53,13 +51,13 @@ class PatientMedicationSchedule(models.Model):
|
|
|
53
51
|
medication_indications=list(set(aggregated_medication_indications)),
|
|
54
52
|
medication_intake_times=list(set(aggregated_medication_intake_times)),
|
|
55
53
|
patient_medications=patient_meds_in_schedule,
|
|
56
|
-
patient_medication_schedules=[self]
|
|
54
|
+
patient_medication_schedules=[self],
|
|
57
55
|
)
|
|
58
56
|
|
|
59
57
|
def __str__(self):
|
|
60
58
|
"""Returns a string representation including the patient and associated medications."""
|
|
61
|
-
return f
|
|
62
|
-
|
|
59
|
+
return f"{self.patient} - {self.medication.all()}"
|
|
60
|
+
|
|
63
61
|
@classmethod
|
|
64
62
|
def create_by_patient_and_indication_type(cls, patient, indication_type):
|
|
65
63
|
"""Creates a schedule and adds a medication based on a random indication of a given type."""
|
|
@@ -76,7 +74,7 @@ class PatientMedicationSchedule(models.Model):
|
|
|
76
74
|
patient_medication_schedule.save()
|
|
77
75
|
|
|
78
76
|
return patient_medication_schedule
|
|
79
|
-
|
|
77
|
+
|
|
80
78
|
@classmethod
|
|
81
79
|
def create_by_patient_and_indication(cls, patient, medication_indication):
|
|
82
80
|
"""Creates a schedule and adds a medication based on a specific indication."""
|
|
@@ -84,7 +82,6 @@ class PatientMedicationSchedule(models.Model):
|
|
|
84
82
|
from .patient_medication import PatientMedication
|
|
85
83
|
from ...administration.person.patient import Patient
|
|
86
84
|
|
|
87
|
-
|
|
88
85
|
assert isinstance(medication_indication, MedicationIndication)
|
|
89
86
|
assert isinstance(patient, Patient)
|
|
90
87
|
patient_medication_schedule = cls.objects.create(patient=patient)
|
|
@@ -95,17 +92,17 @@ class PatientMedicationSchedule(models.Model):
|
|
|
95
92
|
patient_medication_schedule.save()
|
|
96
93
|
|
|
97
94
|
return patient_medication_schedule
|
|
98
|
-
|
|
95
|
+
|
|
99
96
|
def create_patient_medication_from_medication_schedule(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
97
|
+
self,
|
|
98
|
+
medication_schedule: "MedicationSchedule",
|
|
99
|
+
medication_indication=None,
|
|
100
|
+
start_date=None,
|
|
101
|
+
):
|
|
105
102
|
"""Creates and adds a PatientMedication based on a generic MedicationSchedule template."""
|
|
106
|
-
|
|
103
|
+
|
|
107
104
|
from .patient_medication import PatientMedication
|
|
108
|
-
|
|
105
|
+
|
|
109
106
|
if not start_date:
|
|
110
107
|
start_date = dt.now()
|
|
111
108
|
|
|
@@ -115,22 +112,17 @@ class PatientMedicationSchedule(models.Model):
|
|
|
115
112
|
intake_times = medication_schedule.get_intake_times()
|
|
116
113
|
|
|
117
114
|
patient_medication = PatientMedication.objects.create(
|
|
118
|
-
patient=self.patient,
|
|
119
|
-
medication=drug,
|
|
120
|
-
medication_indication=medication_indication,
|
|
121
|
-
unit=unit,
|
|
122
|
-
dosage=dosage
|
|
115
|
+
patient=self.patient, medication=drug, medication_indication=medication_indication, unit=unit, dosage=dosage
|
|
123
116
|
)
|
|
124
117
|
|
|
125
118
|
patient_medication.intake_times.set(intake_times)
|
|
126
119
|
patient_medication.save()
|
|
127
120
|
|
|
128
121
|
self.medication.add(patient_medication)
|
|
129
|
-
self.save()
|
|
122
|
+
self.save()
|
|
130
123
|
|
|
131
124
|
return patient_medication
|
|
132
|
-
|
|
133
|
-
|
|
125
|
+
|
|
134
126
|
def get_patient_medication(self):
|
|
135
127
|
"""Returns all PatientMedication instances associated with this schedule."""
|
|
136
|
-
return self.medication.all()
|
|
128
|
+
return self.medication.all()
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
1
3
|
from django.db import models
|
|
2
|
-
from typing import List, TYPE_CHECKING
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
class RiskManager(models.Manager):
|
|
6
7
|
def get_by_natural_key(self, name):
|
|
7
8
|
"""
|
|
8
9
|
Retrieve a risk instance using its natural key.
|
|
9
|
-
|
|
10
|
+
|
|
10
11
|
Args:
|
|
11
12
|
name: The unique name identifying the risk instance.
|
|
12
|
-
|
|
13
|
+
|
|
13
14
|
Returns:
|
|
14
15
|
The risk instance with the matching name.
|
|
15
16
|
"""
|
|
@@ -49,14 +50,14 @@ class Risk(models.Model):
|
|
|
49
50
|
objects = RiskManager()
|
|
50
51
|
|
|
51
52
|
if TYPE_CHECKING:
|
|
52
|
-
from endoreg_db.models
|
|
53
|
+
from endoreg_db.models import RiskType
|
|
53
54
|
|
|
54
55
|
risk_types: RiskType
|
|
55
56
|
|
|
56
57
|
def natural_key(self):
|
|
57
58
|
"""
|
|
58
59
|
Return a tuple containing the natural key of the risk instance.
|
|
59
|
-
|
|
60
|
+
|
|
60
61
|
The tuple consists of the unique 'name' attribute, which enables natural key lookups
|
|
61
62
|
and serialization within Django.
|
|
62
63
|
"""
|
|
@@ -65,7 +66,7 @@ class Risk(models.Model):
|
|
|
65
66
|
def __str__(self):
|
|
66
67
|
"""
|
|
67
68
|
Return the string representation of the risk.
|
|
68
|
-
|
|
69
|
+
|
|
69
70
|
Returns:
|
|
70
71
|
str: The risk's name.
|
|
71
72
|
"""
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
from django.db import models
|
|
2
1
|
from typing import TYPE_CHECKING
|
|
3
2
|
|
|
3
|
+
from django.db import models
|
|
4
|
+
|
|
5
|
+
# Deorecate ?
|
|
6
|
+
|
|
4
7
|
|
|
5
8
|
class RiskTypeManager(models.Manager):
|
|
6
9
|
def get_by_natural_key(self, name):
|
|
7
10
|
"""
|
|
8
11
|
Retrieves a RiskType instance using its natural key.
|
|
9
|
-
|
|
12
|
+
|
|
10
13
|
Args:
|
|
11
14
|
name (str): The unique name identifying the RiskType instance.
|
|
12
|
-
|
|
15
|
+
|
|
13
16
|
Returns:
|
|
14
17
|
RiskType: The matching instance with the provided name.
|
|
15
18
|
"""
|
|
@@ -31,14 +34,14 @@ class RiskType(models.Model):
|
|
|
31
34
|
objects = RiskTypeManager()
|
|
32
35
|
|
|
33
36
|
if TYPE_CHECKING:
|
|
34
|
-
from endoreg_db.models
|
|
37
|
+
from endoreg_db.models import Risk
|
|
35
38
|
|
|
36
39
|
risks: models.QuerySet[Risk]
|
|
37
40
|
|
|
38
41
|
def natural_key(self):
|
|
39
42
|
"""
|
|
40
43
|
Return the natural key for this risk type.
|
|
41
|
-
|
|
44
|
+
|
|
42
45
|
This method returns a tuple containing only the risk type's unique name, which is used
|
|
43
46
|
to identify the instance naturally.
|
|
44
47
|
"""
|