endoreg-db 0.8.8.9__py3-none-any.whl → 0.8.9.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of endoreg-db might be problematic. Click here for more details.
- endoreg_db/admin.py +10 -5
- endoreg_db/apps.py +4 -7
- endoreg_db/authz/auth.py +1 -0
- endoreg_db/authz/backends.py +1 -1
- endoreg_db/authz/management/commands/list_routes.py +2 -0
- endoreg_db/authz/middleware.py +8 -7
- endoreg_db/authz/permissions.py +21 -10
- endoreg_db/authz/policy.py +14 -19
- endoreg_db/authz/views_auth.py +14 -10
- endoreg_db/codemods/rename_datetime_fields.py +8 -1
- endoreg_db/exceptions.py +5 -2
- endoreg_db/forms/__init__.py +0 -1
- endoreg_db/forms/examination_form.py +4 -3
- endoreg_db/forms/patient_finding_intervention_form.py +30 -8
- endoreg_db/forms/patient_form.py +9 -13
- endoreg_db/forms/questionnaires/__init__.py +1 -1
- endoreg_db/forms/settings/__init__.py +4 -1
- endoreg_db/forms/unit.py +2 -1
- endoreg_db/helpers/count_db.py +17 -14
- endoreg_db/helpers/default_objects.py +2 -1
- endoreg_db/helpers/download_segmentation_model.py +4 -3
- endoreg_db/helpers/interact.py +0 -5
- endoreg_db/helpers/test_video_helper.py +33 -25
- endoreg_db/import_files/__init__.py +1 -1
- endoreg_db/import_files/context/__init__.py +1 -1
- endoreg_db/import_files/context/default_sensitive_meta.py +11 -9
- endoreg_db/import_files/context/ensure_center.py +4 -4
- endoreg_db/import_files/context/file_lock.py +3 -3
- endoreg_db/import_files/context/import_context.py +11 -12
- endoreg_db/import_files/context/validate_directories.py +1 -0
- endoreg_db/import_files/file_storage/create_report_file.py +57 -34
- endoreg_db/import_files/file_storage/create_video_file.py +64 -35
- endoreg_db/import_files/file_storage/sensitive_meta_storage.py +5 -2
- endoreg_db/import_files/file_storage/state_management.py +146 -83
- endoreg_db/import_files/file_storage/storage.py +5 -1
- endoreg_db/import_files/processing/report_processing/report_anonymization.py +24 -19
- endoreg_db/import_files/processing/sensitive_meta_adapter.py +3 -3
- endoreg_db/import_files/processing/video_processing/video_anonymization.py +18 -18
- endoreg_db/import_files/pseudonymization/k_anonymity.py +8 -9
- endoreg_db/import_files/pseudonymization/k_pseudonymity.py +16 -5
- endoreg_db/import_files/report_import_service.py +36 -30
- endoreg_db/import_files/video_import_service.py +27 -23
- endoreg_db/logger_conf.py +56 -40
- endoreg_db/management/__init__.py +1 -1
- endoreg_db/management/commands/__init__.py +1 -1
- endoreg_db/management/commands/check_auth.py +45 -38
- endoreg_db/management/commands/create_model_meta_from_huggingface.py +53 -2
- endoreg_db/management/commands/create_multilabel_model_meta.py +54 -19
- endoreg_db/management/commands/fix_missing_patient_data.py +105 -71
- endoreg_db/management/commands/fix_video_paths.py +75 -54
- endoreg_db/management/commands/import_report.py +1 -3
- endoreg_db/management/commands/list_routes.py +2 -0
- endoreg_db/management/commands/load_ai_model_data.py +8 -2
- endoreg_db/management/commands/load_ai_model_label_data.py +0 -1
- endoreg_db/management/commands/load_center_data.py +3 -3
- endoreg_db/management/commands/load_distribution_data.py +35 -38
- endoreg_db/management/commands/load_endoscope_data.py +0 -3
- endoreg_db/management/commands/load_examination_data.py +20 -4
- endoreg_db/management/commands/load_finding_data.py +18 -3
- endoreg_db/management/commands/load_gender_data.py +17 -24
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +95 -85
- endoreg_db/management/commands/load_information_source.py +0 -3
- endoreg_db/management/commands/load_lab_value_data.py +14 -3
- endoreg_db/management/commands/load_legacy_data.py +303 -0
- endoreg_db/management/commands/load_name_data.py +1 -2
- endoreg_db/management/commands/load_pdf_type_data.py +4 -8
- endoreg_db/management/commands/load_profession_data.py +0 -1
- endoreg_db/management/commands/load_report_reader_flag_data.py +0 -4
- endoreg_db/management/commands/load_requirement_data.py +6 -2
- endoreg_db/management/commands/load_unit_data.py +0 -4
- endoreg_db/management/commands/load_user_groups.py +5 -7
- endoreg_db/management/commands/model_input.py +169 -0
- endoreg_db/management/commands/register_ai_model.py +22 -16
- endoreg_db/management/commands/setup_endoreg_db.py +110 -32
- endoreg_db/management/commands/storage_management.py +14 -8
- endoreg_db/management/commands/summarize_db_content.py +154 -63
- endoreg_db/management/commands/train_image_multilabel_model.py +144 -0
- endoreg_db/management/commands/validate_video_files.py +82 -50
- endoreg_db/management/commands/video_validation.py +4 -6
- endoreg_db/migrations/0001_initial.py +112 -63
- endoreg_db/migrations/__init__.py +0 -0
- endoreg_db/models/__init__.py +8 -0
- endoreg_db/models/administration/ai/active_model.py +5 -5
- endoreg_db/models/administration/ai/ai_model.py +41 -18
- endoreg_db/models/administration/ai/model_type.py +1 -0
- endoreg_db/models/administration/case/case.py +22 -22
- endoreg_db/models/administration/center/__init__.py +5 -5
- endoreg_db/models/administration/center/center.py +6 -2
- endoreg_db/models/administration/center/center_resource.py +18 -4
- endoreg_db/models/administration/center/center_shift.py +3 -1
- endoreg_db/models/administration/center/center_waste.py +6 -2
- endoreg_db/models/administration/person/__init__.py +1 -1
- endoreg_db/models/administration/person/employee/__init__.py +1 -1
- endoreg_db/models/administration/person/employee/employee_type.py +3 -1
- endoreg_db/models/administration/person/examiner/__init__.py +1 -1
- endoreg_db/models/administration/person/examiner/examiner.py +10 -2
- endoreg_db/models/administration/person/names/first_name.py +6 -4
- endoreg_db/models/administration/person/names/last_name.py +4 -3
- endoreg_db/models/administration/person/patient/__init__.py +1 -1
- endoreg_db/models/administration/person/patient/patient.py +0 -1
- endoreg_db/models/administration/person/patient/patient_external_id.py +0 -1
- endoreg_db/models/administration/person/person.py +1 -1
- endoreg_db/models/administration/product/__init__.py +7 -6
- endoreg_db/models/administration/product/product.py +6 -2
- endoreg_db/models/administration/product/product_group.py +9 -7
- endoreg_db/models/administration/product/product_material.py +9 -2
- endoreg_db/models/administration/product/reference_product.py +64 -15
- endoreg_db/models/administration/qualification/qualification.py +3 -1
- endoreg_db/models/administration/shift/shift.py +3 -1
- endoreg_db/models/administration/shift/shift_type.py +12 -4
- endoreg_db/models/aidataset/__init__.py +5 -0
- endoreg_db/models/aidataset/aidataset.py +193 -0
- endoreg_db/models/label/__init__.py +1 -1
- endoreg_db/models/label/label.py +10 -2
- endoreg_db/models/label/label_set.py +3 -1
- endoreg_db/models/label/label_video_segment/_create_from_video.py +6 -2
- endoreg_db/models/label/label_video_segment/label_video_segment.py +148 -44
- endoreg_db/models/media/__init__.py +12 -5
- endoreg_db/models/media/frame/__init__.py +1 -1
- endoreg_db/models/media/frame/frame.py +34 -8
- endoreg_db/models/media/pdf/__init__.py +2 -1
- endoreg_db/models/media/pdf/raw_pdf.py +11 -4
- endoreg_db/models/media/pdf/report_file.py +6 -2
- endoreg_db/models/media/pdf/report_reader/__init__.py +3 -3
- endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +15 -5
- endoreg_db/models/media/video/create_from_file.py +20 -41
- endoreg_db/models/media/video/pipe_1.py +75 -30
- endoreg_db/models/media/video/pipe_2.py +37 -12
- endoreg_db/models/media/video/video_file.py +36 -24
- endoreg_db/models/media/video/video_file_ai.py +235 -70
- endoreg_db/models/media/video/video_file_anonymize.py +240 -65
- endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +6 -1
- endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +3 -1
- endoreg_db/models/media/video/video_file_frames/_delete_frames.py +30 -9
- endoreg_db/models/media/video/video_file_frames/_extract_frames.py +95 -29
- endoreg_db/models/media/video/video_file_frames/_get_frame.py +13 -3
- endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +4 -1
- endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +15 -3
- endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +15 -3
- endoreg_db/models/media/video/video_file_frames/_get_frames.py +7 -2
- endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +109 -23
- endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +111 -27
- endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +46 -13
- endoreg_db/models/media/video/video_file_io.py +85 -33
- endoreg_db/models/media/video/video_file_meta/__init__.py +6 -6
- endoreg_db/models/media/video/video_file_meta/get_crop_template.py +17 -4
- endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +28 -7
- endoreg_db/models/media/video/video_file_meta/get_fps.py +46 -13
- endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +81 -20
- endoreg_db/models/media/video/video_file_meta/text_meta.py +61 -20
- endoreg_db/models/media/video/video_file_meta/video_meta.py +40 -12
- endoreg_db/models/media/video/video_file_segments.py +118 -27
- endoreg_db/models/media/video/video_metadata.py +25 -6
- endoreg_db/models/media/video/video_processing.py +54 -15
- endoreg_db/models/medical/__init__.py +3 -13
- endoreg_db/models/medical/contraindication/__init__.py +3 -1
- endoreg_db/models/medical/disease.py +18 -6
- endoreg_db/models/medical/event.py +6 -2
- endoreg_db/models/medical/examination/__init__.py +5 -1
- endoreg_db/models/medical/examination/examination.py +22 -6
- endoreg_db/models/medical/examination/examination_indication.py +23 -7
- endoreg_db/models/medical/examination/examination_time.py +6 -2
- endoreg_db/models/medical/finding/__init__.py +3 -1
- endoreg_db/models/medical/finding/finding.py +37 -12
- endoreg_db/models/medical/finding/finding_classification.py +27 -8
- endoreg_db/models/medical/finding/finding_intervention.py +19 -6
- endoreg_db/models/medical/finding/finding_type.py +3 -1
- endoreg_db/models/medical/hardware/__init__.py +1 -1
- endoreg_db/models/medical/hardware/endoscope.py +14 -2
- endoreg_db/models/medical/laboratory/__init__.py +1 -1
- endoreg_db/models/medical/laboratory/lab_value.py +139 -39
- endoreg_db/models/medical/medication/__init__.py +7 -3
- endoreg_db/models/medical/medication/medication.py +3 -1
- endoreg_db/models/medical/medication/medication_indication.py +3 -1
- endoreg_db/models/medical/medication/medication_indication_type.py +11 -3
- endoreg_db/models/medical/medication/medication_intake_time.py +3 -1
- endoreg_db/models/medical/medication/medication_schedule.py +3 -1
- endoreg_db/models/medical/patient/__init__.py +2 -10
- endoreg_db/models/medical/patient/medication_examples.py +3 -14
- endoreg_db/models/medical/patient/patient_disease.py +17 -5
- endoreg_db/models/medical/patient/patient_event.py +12 -4
- endoreg_db/models/medical/patient/patient_examination.py +52 -15
- endoreg_db/models/medical/patient/patient_examination_indication.py +15 -4
- endoreg_db/models/medical/patient/patient_finding.py +105 -29
- endoreg_db/models/medical/patient/patient_finding_classification.py +41 -12
- endoreg_db/models/medical/patient/patient_finding_intervention.py +11 -3
- endoreg_db/models/medical/patient/patient_lab_sample.py +6 -2
- endoreg_db/models/medical/patient/patient_lab_value.py +42 -10
- endoreg_db/models/medical/patient/patient_medication.py +25 -7
- endoreg_db/models/medical/patient/patient_medication_schedule.py +34 -10
- endoreg_db/models/metadata/model_meta.py +40 -12
- endoreg_db/models/metadata/model_meta_logic.py +51 -16
- endoreg_db/models/metadata/sensitive_meta.py +65 -28
- endoreg_db/models/metadata/sensitive_meta_logic.py +28 -26
- endoreg_db/models/metadata/video_meta.py +146 -39
- endoreg_db/models/metadata/video_prediction_logic.py +70 -21
- endoreg_db/models/metadata/video_prediction_meta.py +80 -27
- endoreg_db/models/operation_log.py +63 -0
- endoreg_db/models/other/__init__.py +10 -10
- endoreg_db/models/other/distribution/__init__.py +9 -7
- endoreg_db/models/other/distribution/base_value_distribution.py +3 -1
- endoreg_db/models/other/distribution/date_value_distribution.py +19 -5
- endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +3 -1
- endoreg_db/models/other/distribution/numeric_value_distribution.py +34 -9
- endoreg_db/models/other/emission/__init__.py +1 -1
- endoreg_db/models/other/emission/emission_factor.py +9 -3
- endoreg_db/models/other/information_source.py +15 -5
- endoreg_db/models/other/material.py +3 -1
- endoreg_db/models/other/transport_route.py +3 -1
- endoreg_db/models/other/unit.py +6 -2
- endoreg_db/models/report/report.py +0 -1
- endoreg_db/models/requirement/requirement.py +84 -27
- endoreg_db/models/requirement/requirement_error.py +5 -6
- endoreg_db/models/requirement/requirement_evaluation/__init__.py +1 -1
- endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +8 -8
- endoreg_db/models/requirement/requirement_evaluation/get_values.py +3 -3
- endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +24 -8
- endoreg_db/models/requirement/requirement_operator.py +28 -8
- endoreg_db/models/requirement/requirement_set.py +34 -11
- endoreg_db/models/state/__init__.py +1 -0
- endoreg_db/models/state/audit_ledger.py +9 -2
- endoreg_db/models/{media → state}/processing_history/__init__.py +1 -3
- endoreg_db/models/state/processing_history/processing_history.py +136 -0
- endoreg_db/models/state/raw_pdf.py +0 -1
- endoreg_db/models/state/video.py +2 -3
- endoreg_db/models/utils.py +4 -2
- endoreg_db/queries/__init__.py +2 -6
- endoreg_db/queries/annotations/__init__.py +1 -3
- endoreg_db/queries/annotations/legacy.py +37 -26
- endoreg_db/root_urls.py +3 -4
- endoreg_db/schemas/examination_evaluation.py +3 -0
- endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +249 -163
- endoreg_db/serializers/__init__.py +2 -8
- endoreg_db/serializers/administration/__init__.py +1 -2
- endoreg_db/serializers/administration/ai/__init__.py +0 -1
- endoreg_db/serializers/administration/ai/active_model.py +3 -1
- endoreg_db/serializers/administration/ai/ai_model.py +5 -3
- endoreg_db/serializers/administration/ai/model_type.py +3 -1
- endoreg_db/serializers/administration/center.py +7 -2
- endoreg_db/serializers/administration/gender.py +4 -2
- endoreg_db/serializers/anonymization.py +13 -13
- endoreg_db/serializers/evaluation/examination_evaluation.py +0 -1
- endoreg_db/serializers/examination/__init__.py +1 -1
- endoreg_db/serializers/examination/base.py +12 -13
- endoreg_db/serializers/examination/dropdown.py +6 -7
- endoreg_db/serializers/examination_serializer.py +3 -6
- endoreg_db/serializers/finding/__init__.py +1 -1
- endoreg_db/serializers/finding/finding.py +14 -7
- endoreg_db/serializers/finding_classification/__init__.py +3 -3
- endoreg_db/serializers/finding_classification/choice.py +3 -3
- endoreg_db/serializers/finding_classification/classification.py +2 -4
- endoreg_db/serializers/label_video_segment/__init__.py +5 -3
- endoreg_db/serializers/{label → label_video_segment}/image_classification_annotation.py +5 -5
- endoreg_db/serializers/label_video_segment/label/__init__.py +6 -0
- endoreg_db/serializers/{label → label_video_segment/label}/label.py +1 -1
- endoreg_db/serializers/label_video_segment/label_video_segment.py +338 -228
- endoreg_db/serializers/meta/__init__.py +1 -2
- endoreg_db/serializers/meta/sensitive_meta_detail.py +28 -13
- endoreg_db/serializers/meta/sensitive_meta_update.py +51 -46
- endoreg_db/serializers/meta/sensitive_meta_verification.py +19 -16
- endoreg_db/serializers/misc/__init__.py +2 -2
- endoreg_db/serializers/misc/file_overview.py +11 -7
- endoreg_db/serializers/misc/stats.py +10 -8
- endoreg_db/serializers/misc/translatable_field_mix_in.py +6 -6
- endoreg_db/serializers/misc/upload_job.py +32 -29
- endoreg_db/serializers/patient/__init__.py +2 -1
- endoreg_db/serializers/patient/patient.py +32 -15
- endoreg_db/serializers/patient/patient_dropdown.py +11 -3
- endoreg_db/serializers/patient_examination/__init__.py +1 -1
- endoreg_db/serializers/patient_examination/patient_examination.py +67 -40
- endoreg_db/serializers/patient_finding/__init__.py +1 -1
- endoreg_db/serializers/patient_finding/patient_finding.py +2 -1
- endoreg_db/serializers/patient_finding/patient_finding_classification.py +17 -9
- endoreg_db/serializers/patient_finding/patient_finding_detail.py +26 -17
- endoreg_db/serializers/patient_finding/patient_finding_intervention.py +7 -5
- endoreg_db/serializers/patient_finding/patient_finding_list.py +10 -11
- endoreg_db/serializers/patient_finding/patient_finding_write.py +36 -27
- endoreg_db/serializers/pdf/__init__.py +1 -3
- endoreg_db/serializers/requirements/requirement_schema.py +1 -6
- endoreg_db/serializers/sensitive_meta_serializer.py +100 -81
- endoreg_db/serializers/video/__init__.py +2 -2
- endoreg_db/serializers/video/{segmentation.py → video_file.py} +66 -47
- endoreg_db/serializers/video/video_file_brief.py +6 -2
- endoreg_db/serializers/video/video_file_detail.py +36 -23
- endoreg_db/serializers/video/video_file_list.py +4 -2
- endoreg_db/serializers/video/video_processing_history.py +54 -50
- endoreg_db/services/__init__.py +1 -1
- endoreg_db/services/anonymization.py +2 -2
- endoreg_db/services/examination_evaluation.py +40 -17
- endoreg_db/services/model_meta_from_hf.py +76 -0
- endoreg_db/services/polling_coordinator.py +101 -70
- endoreg_db/services/pseudonym_service.py +27 -22
- endoreg_db/services/report_import.py +6 -3
- endoreg_db/services/segment_sync.py +75 -59
- endoreg_db/services/video_import.py +6 -7
- endoreg_db/urls/__init__.py +2 -2
- endoreg_db/urls/ai.py +7 -25
- endoreg_db/urls/anonymization.py +61 -15
- endoreg_db/urls/auth.py +4 -4
- endoreg_db/urls/classification.py +4 -9
- endoreg_db/urls/examination.py +27 -18
- endoreg_db/urls/media.py +27 -34
- endoreg_db/urls/patient.py +11 -7
- endoreg_db/urls/requirements.py +3 -1
- endoreg_db/urls/root_urls.py +2 -3
- endoreg_db/urls/stats.py +24 -16
- endoreg_db/urls/upload.py +3 -11
- endoreg_db/utils/__init__.py +14 -15
- endoreg_db/utils/ai/__init__.py +1 -1
- endoreg_db/utils/ai/data_loader_for_model_input.py +262 -0
- endoreg_db/utils/ai/data_loader_for_model_training.py +262 -0
- endoreg_db/utils/ai/get.py +2 -1
- endoreg_db/utils/ai/inference_dataset.py +14 -15
- endoreg_db/utils/ai/model_training/config.py +117 -0
- endoreg_db/utils/ai/model_training/dataset.py +74 -0
- endoreg_db/utils/ai/model_training/losses.py +68 -0
- endoreg_db/utils/ai/model_training/metrics.py +78 -0
- endoreg_db/utils/ai/model_training/model_backbones.py +155 -0
- endoreg_db/utils/ai/model_training/model_gastronet_resnet.py +118 -0
- endoreg_db/utils/ai/model_training/trainer_gastronet_multilabel.py +771 -0
- endoreg_db/utils/ai/multilabel_classification_net.py +21 -6
- endoreg_db/utils/ai/predict.py +4 -4
- endoreg_db/utils/ai/preprocess.py +19 -11
- endoreg_db/utils/calc_duration_seconds.py +4 -4
- endoreg_db/utils/case_generator/lab_sample_factory.py +3 -4
- endoreg_db/utils/check_video_files.py +74 -47
- endoreg_db/utils/cropping.py +10 -9
- endoreg_db/utils/dataloader.py +11 -3
- endoreg_db/utils/dates.py +3 -4
- endoreg_db/utils/defaults/set_default_center.py +7 -6
- endoreg_db/utils/env.py +6 -2
- endoreg_db/utils/extract_specific_frames.py +24 -9
- endoreg_db/utils/file_operations.py +30 -18
- endoreg_db/utils/fix_video_path_direct.py +57 -41
- endoreg_db/utils/frame_anonymization_utils.py +157 -157
- endoreg_db/utils/hashs.py +3 -18
- endoreg_db/utils/links/requirement_link.py +96 -52
- endoreg_db/utils/ocr.py +30 -25
- endoreg_db/utils/operation_log.py +61 -0
- endoreg_db/utils/parse_and_generate_yaml.py +12 -13
- endoreg_db/utils/paths.py +6 -6
- endoreg_db/utils/permissions.py +40 -24
- endoreg_db/utils/pipelines/process_video_dir.py +50 -26
- endoreg_db/utils/product/sum_emissions.py +5 -3
- endoreg_db/utils/product/sum_weights.py +4 -2
- endoreg_db/utils/pydantic_models/__init__.py +3 -4
- endoreg_db/utils/requirement_operator_logic/_old/lab_value_operators.py +207 -107
- endoreg_db/utils/requirement_operator_logic/_old/model_evaluators.py +252 -65
- endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +27 -10
- endoreg_db/utils/setup_config.py +21 -5
- endoreg_db/utils/storage.py +3 -1
- endoreg_db/utils/translation.py +19 -15
- endoreg_db/utils/uuid.py +1 -0
- endoreg_db/utils/validate_endo_roi.py +12 -4
- endoreg_db/utils/validate_subcategory_dict.py +26 -24
- endoreg_db/utils/validate_video_detailed.py +207 -149
- endoreg_db/utils/video/__init__.py +7 -3
- endoreg_db/utils/video/extract_frames.py +30 -18
- endoreg_db/utils/video/ffmpeg_wrapper.py +217 -52
- endoreg_db/utils/video/names.py +11 -6
- endoreg_db/utils/video/streaming_processor.py +175 -101
- endoreg_db/utils/video/video_splitter.py +30 -19
- endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +59 -50
- endoreg_db/views/__init__.py +0 -20
- endoreg_db/views/anonymization/__init__.py +6 -2
- endoreg_db/views/anonymization/media_management.py +2 -6
- endoreg_db/views/anonymization/overview.py +34 -1
- endoreg_db/views/anonymization/validate.py +79 -18
- endoreg_db/views/auth/__init__.py +1 -1
- endoreg_db/views/auth/keycloak.py +16 -14
- endoreg_db/views/examination/__init__.py +12 -15
- endoreg_db/views/examination/examination.py +5 -5
- endoreg_db/views/examination/examination_manifest_cache.py +5 -5
- endoreg_db/views/examination/get_finding_classification_choices.py +8 -5
- endoreg_db/views/examination/get_finding_classifications.py +9 -7
- endoreg_db/views/examination/get_findings.py +8 -10
- endoreg_db/views/examination/get_instruments.py +3 -2
- endoreg_db/views/examination/get_interventions.py +1 -1
- endoreg_db/views/finding/__init__.py +2 -2
- endoreg_db/views/finding/finding.py +58 -54
- endoreg_db/views/finding/get_classifications.py +1 -1
- endoreg_db/views/finding/get_interventions.py +1 -1
- endoreg_db/views/finding_classification/__init__.py +5 -5
- endoreg_db/views/finding_classification/finding_classification.py +5 -6
- endoreg_db/views/finding_classification/get_classification_choices.py +3 -4
- endoreg_db/views/media/__init__.py +13 -13
- endoreg_db/views/media/pdf_media.py +9 -9
- endoreg_db/views/media/sensitive_metadata.py +10 -7
- endoreg_db/views/media/video_media.py +4 -4
- endoreg_db/views/meta/__init__.py +1 -1
- endoreg_db/views/meta/sensitive_meta_list.py +20 -22
- endoreg_db/views/meta/sensitive_meta_verification.py +14 -11
- endoreg_db/views/misc/__init__.py +6 -34
- endoreg_db/views/misc/center.py +2 -1
- endoreg_db/views/misc/csrf.py +2 -1
- endoreg_db/views/misc/gender.py +2 -1
- endoreg_db/views/misc/stats.py +141 -106
- endoreg_db/views/patient/__init__.py +1 -3
- endoreg_db/views/patient/patient.py +141 -99
- endoreg_db/views/patient_examination/__init__.py +5 -5
- endoreg_db/views/patient_examination/patient_examination.py +43 -42
- endoreg_db/views/patient_examination/patient_examination_create.py +10 -15
- endoreg_db/views/patient_examination/patient_examination_detail.py +12 -15
- endoreg_db/views/patient_examination/patient_examination_list.py +21 -17
- endoreg_db/views/patient_examination/video.py +114 -80
- endoreg_db/views/patient_finding/__init__.py +1 -1
- endoreg_db/views/patient_finding/patient_finding.py +17 -10
- endoreg_db/views/patient_finding/patient_finding_optimized.py +127 -95
- endoreg_db/views/patient_finding_classification/__init__.py +1 -1
- endoreg_db/views/patient_finding_classification/pfc_create.py +35 -27
- endoreg_db/views/report/reimport.py +1 -1
- endoreg_db/views/report/report_stream.py +5 -8
- endoreg_db/views/requirement/__init__.py +2 -1
- endoreg_db/views/requirement/evaluate.py +7 -9
- endoreg_db/views/requirement/lookup.py +2 -3
- endoreg_db/views/requirement/lookup_store.py +0 -1
- endoreg_db/views/requirement/requirement_utils.py +2 -4
- endoreg_db/views/stats/__init__.py +4 -4
- endoreg_db/views/stats/stats_views.py +152 -115
- endoreg_db/views/video/__init__.py +18 -27
- endoreg_db/views/{ai → video/ai}/__init__.py +2 -2
- endoreg_db/views/{ai → video/ai}/label.py +20 -16
- endoreg_db/views/video/correction.py +5 -6
- endoreg_db/views/video/reimport.py +134 -99
- endoreg_db/views/video/segments_crud.py +134 -44
- endoreg_db/views/video/video_apply_mask.py +13 -12
- endoreg_db/views/video/video_correction.py +2 -1
- endoreg_db/views/video/video_download_processed.py +15 -15
- endoreg_db/views/video/video_meta_stats.py +7 -6
- endoreg_db/views/video/video_processing_history.py +3 -2
- endoreg_db/views/video/video_remove_frames.py +13 -12
- endoreg_db/views/video/video_stream.py +110 -82
- {endoreg_db-0.8.8.9.dist-info → endoreg_db-0.8.9.10.dist-info}/METADATA +9 -3
- {endoreg_db-0.8.8.9.dist-info → endoreg_db-0.8.9.10.dist-info}/RECORD +436 -433
- endoreg_db/import_files/processing/video_processing/video_cleanup_on_error.py +0 -119
- endoreg_db/management/commands/import_fallback_video.py +0 -203
- endoreg_db/management/commands/import_video.py +0 -422
- endoreg_db/management/commands/import_video_with_classification.py +0 -367
- endoreg_db/models/media/processing_history/processing_history.py +0 -96
- endoreg_db/serializers/label/__init__.py +0 -7
- endoreg_db/serializers/label_video_segment/_lvs_create.py +0 -149
- endoreg_db/serializers/label_video_segment/_lvs_update.py +0 -138
- endoreg_db/serializers/label_video_segment/_lvs_validate.py +0 -149
- endoreg_db/serializers/label_video_segment/label_video_segment_annotation.py +0 -99
- endoreg_db/serializers/label_video_segment/label_video_segment_update.py +0 -163
- endoreg_db/services/__old/pdf_import.py +0 -1487
- endoreg_db/services/__old/video_import.py +0 -1306
- endoreg_db/tasks/upload_tasks.py +0 -216
- endoreg_db/tasks/video_ingest.py +0 -161
- endoreg_db/tasks/video_processing_tasks.py +0 -327
- endoreg_db/views/misc/translation.py +0 -182
- {endoreg_db-0.8.8.9.dist-info → endoreg_db-0.8.9.10.dist-info}/WHEEL +0 -0
- {endoreg_db-0.8.8.9.dist-info → endoreg_db-0.8.9.10.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Django model for AI models.
|
|
3
3
|
"""
|
|
4
|
+
|
|
4
5
|
from django.db import models
|
|
5
6
|
from icecream import ic
|
|
6
7
|
from typing import TYPE_CHECKING
|
|
8
|
+
from logging import getLogger
|
|
9
|
+
|
|
10
|
+
logger = getLogger(__name__)
|
|
7
11
|
|
|
8
12
|
if TYPE_CHECKING:
|
|
9
13
|
from .model_type import ModelType
|
|
10
|
-
from ...metadata import ModelMeta
|
|
14
|
+
from ...metadata import ModelMeta
|
|
11
15
|
from ...label import VideoSegmentationLabelSet
|
|
16
|
+
|
|
12
17
|
# Forward reference AiModel for use in type hints within the class itself
|
|
13
18
|
from typing import ForwardRef
|
|
19
|
+
|
|
14
20
|
AiModelRef = ForwardRef("'AiModel'")
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
|
|
17
23
|
class AiModelManager(models.Manager):
|
|
18
24
|
"""
|
|
19
25
|
Manager for AI models with custom query methods.
|
|
@@ -22,13 +28,13 @@ class AiModelManager(models.Manager):
|
|
|
22
28
|
def get_by_natural_key(self, name: str):
|
|
23
29
|
"""
|
|
24
30
|
Retrieves the AiModel instance with the specified unique name.
|
|
25
|
-
|
|
31
|
+
|
|
26
32
|
Args:
|
|
27
33
|
name: The unique identifier of the AiModel to retrieve.
|
|
28
|
-
|
|
34
|
+
|
|
29
35
|
Returns:
|
|
30
36
|
The AiModel instance matching the given name.
|
|
31
|
-
|
|
37
|
+
|
|
32
38
|
Raises:
|
|
33
39
|
AiModel.DoesNotExist: If no AiModel with the specified name exists.
|
|
34
40
|
"""
|
|
@@ -48,6 +54,7 @@ class AiModel(models.Model):
|
|
|
48
54
|
video_segmentation_labelset (VideoSegmentationLabelSet): Optional associated label set for video segmentation tasks.
|
|
49
55
|
active_meta (ModelMeta): Optional reference to the currently active ModelMeta instance associated with the model.
|
|
50
56
|
"""
|
|
57
|
+
|
|
51
58
|
objects = AiModelManager()
|
|
52
59
|
|
|
53
60
|
name = models.CharField(max_length=255, unique=True)
|
|
@@ -71,29 +78,29 @@ class AiModel(models.Model):
|
|
|
71
78
|
active_meta = models.ForeignKey(
|
|
72
79
|
"ModelMeta",
|
|
73
80
|
on_delete=models.SET_NULL,
|
|
74
|
-
related_name="active_model",
|
|
81
|
+
related_name="active_model",
|
|
75
82
|
blank=True,
|
|
76
83
|
null=True,
|
|
77
84
|
)
|
|
78
85
|
|
|
79
86
|
if TYPE_CHECKING:
|
|
80
87
|
metadata_versions: models.QuerySet["ModelMeta"]
|
|
81
|
-
model_type:models.ForeignKey["ModelType|None"]
|
|
82
|
-
active_meta:models.ForeignKey["ModelMeta|None"]
|
|
83
|
-
video_segmentation_labelset:models.ForeignKey["VideoSegmentationLabelSet|None"]
|
|
88
|
+
model_type: models.ForeignKey["ModelType|None"]
|
|
89
|
+
active_meta: models.ForeignKey["ModelMeta|None"]
|
|
90
|
+
video_segmentation_labelset: models.ForeignKey["VideoSegmentationLabelSet|None"]
|
|
84
91
|
|
|
85
92
|
def get_version(self, version: int) -> "ModelMeta":
|
|
86
93
|
"""
|
|
87
94
|
Retrieves the ModelMeta instance for the specified version.
|
|
88
|
-
|
|
95
|
+
|
|
89
96
|
If the active_meta matches the requested version, it is returned. Otherwise, searches related metadata_versions for a matching version. Raises ValueError if no matching metadata is found.
|
|
90
|
-
|
|
97
|
+
|
|
91
98
|
Args:
|
|
92
99
|
version: The version number of the desired ModelMeta.
|
|
93
|
-
|
|
100
|
+
|
|
94
101
|
Returns:
|
|
95
102
|
The ModelMeta instance corresponding to the specified version.
|
|
96
|
-
|
|
103
|
+
|
|
97
104
|
Raises:
|
|
98
105
|
ValueError: If no ModelMeta with the given version exists.
|
|
99
106
|
"""
|
|
@@ -108,24 +115,40 @@ class AiModel(models.Model):
|
|
|
108
115
|
raise ValueError(f"No model metadata found for version {version}.")
|
|
109
116
|
|
|
110
117
|
def get_latest_version(self) -> "ModelMeta":
|
|
111
|
-
"""
|
|
112
|
-
Get the model_metadata object from metadata_versions with the highest version number.
|
|
113
|
-
"""
|
|
114
118
|
if self.active_meta is not None:
|
|
115
119
|
return self.active_meta
|
|
116
120
|
|
|
117
|
-
# Get the latest version of the model metadata
|
|
118
121
|
latest_version = self.metadata_versions.order_by("-version").first()
|
|
119
122
|
if latest_version is not None:
|
|
120
123
|
return latest_version
|
|
121
124
|
|
|
125
|
+
# Only in environments where auto-download is acceptable:
|
|
126
|
+
try:
|
|
127
|
+
logger.info(
|
|
128
|
+
"Locally, no segmentation model was available. We are using colo_segmentation_RegNetX800MF_base."
|
|
129
|
+
)
|
|
130
|
+
from endoreg_db.services.model_meta_from_hf import ensure_model_meta_from_hf
|
|
131
|
+
|
|
132
|
+
model_meta = ensure_model_meta_from_hf(
|
|
133
|
+
model_id="wg-lux/colo_segmentation_RegNetX800MF_base",
|
|
134
|
+
model_name="image_multilabel_classification_colonoscopy_default",
|
|
135
|
+
labelset_name="multilabel_classification_colonoscopy_default",
|
|
136
|
+
meta_version="1",
|
|
137
|
+
)
|
|
138
|
+
return model_meta
|
|
139
|
+
except Exception:
|
|
140
|
+
logger.exception(
|
|
141
|
+
"Failed to ensure ModelMeta from Hugging Face for AiModel '%s'",
|
|
142
|
+
self.name,
|
|
143
|
+
)
|
|
144
|
+
|
|
122
145
|
raise ValueError("No model metadata found for this model.")
|
|
123
146
|
|
|
124
147
|
@classmethod
|
|
125
148
|
def set_active_model_meta(cls, model_name: str, meta_name: str, meta_version: int):
|
|
126
149
|
"""
|
|
127
150
|
Sets the active metadata version for the specified AI model.
|
|
128
|
-
|
|
151
|
+
|
|
129
152
|
Updates the `active_meta` field of the AiModel identified by `model_name` to the ModelMeta instance matching `meta_name` and `meta_version`.
|
|
130
153
|
"""
|
|
131
154
|
from ...metadata import ModelMeta
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
from django.db import models
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
4
5
|
if TYPE_CHECKING:
|
|
5
6
|
from ..person import Patient
|
|
6
7
|
from ...medical.patient.patient_examination import PatientExamination
|
|
7
8
|
from django.utils import timezone
|
|
8
9
|
|
|
10
|
+
|
|
9
11
|
class Case(models.Model):
|
|
10
12
|
"""
|
|
11
13
|
Represents a clinical case, linking a patient to one or more examinations over a specific period.
|
|
@@ -22,64 +24,62 @@ class Case(models.Model):
|
|
|
22
24
|
created_at (datetime): Timestamp of case creation.
|
|
23
25
|
updated_at (datetime): Timestamp of last case update.
|
|
24
26
|
"""
|
|
27
|
+
|
|
25
28
|
patient = models.ForeignKey(
|
|
26
|
-
|
|
29
|
+
"Patient",
|
|
27
30
|
on_delete=models.CASCADE,
|
|
28
|
-
related_name=
|
|
31
|
+
related_name="cases",
|
|
29
32
|
help_text="The patient associated with this case.",
|
|
30
|
-
db_index=True
|
|
33
|
+
db_index=True,
|
|
31
34
|
)
|
|
32
35
|
patient_examinations = models.ManyToManyField(
|
|
33
|
-
|
|
34
|
-
related_name=
|
|
35
|
-
help_text="The examinations included in this case."
|
|
36
|
+
"PatientExamination",
|
|
37
|
+
related_name="cases",
|
|
38
|
+
help_text="The examinations included in this case.",
|
|
36
39
|
)
|
|
37
40
|
hash = models.CharField(
|
|
38
41
|
max_length=255,
|
|
39
42
|
blank=True,
|
|
40
43
|
null=True,
|
|
41
|
-
help_text="An optional hash value associated with the case."
|
|
44
|
+
help_text="An optional hash value associated with the case.",
|
|
42
45
|
)
|
|
43
46
|
|
|
44
47
|
start_date = models.DateTimeField(
|
|
45
|
-
help_text="The start date and time of the case.",
|
|
46
|
-
db_index=True
|
|
48
|
+
help_text="The start date and time of the case.", db_index=True
|
|
47
49
|
)
|
|
48
50
|
end_date = models.DateTimeField(
|
|
49
|
-
null=True,
|
|
50
|
-
blank=True,
|
|
51
|
-
help_text="The end date and time of the case (optional)."
|
|
51
|
+
null=True, blank=True, help_text="The end date and time of the case (optional)."
|
|
52
52
|
)
|
|
53
53
|
is_active = models.BooleanField(
|
|
54
54
|
default=True,
|
|
55
55
|
help_text="Flag indicating if the case is currently active.",
|
|
56
|
-
db_index=True
|
|
56
|
+
db_index=True,
|
|
57
57
|
)
|
|
58
58
|
is_closed = models.BooleanField(
|
|
59
59
|
default=False,
|
|
60
60
|
help_text="Flag indicating if the case has been closed.",
|
|
61
|
-
db_index=True
|
|
61
|
+
db_index=True,
|
|
62
62
|
)
|
|
63
63
|
is_deleted = models.BooleanField(
|
|
64
64
|
default=False,
|
|
65
65
|
help_text="Flag indicating if the case is marked as deleted.",
|
|
66
|
-
db_index=True
|
|
66
|
+
db_index=True,
|
|
67
67
|
)
|
|
68
68
|
created_at = models.DateTimeField(
|
|
69
|
-
auto_now_add=True,
|
|
70
|
-
help_text="The date and time the case was created."
|
|
69
|
+
auto_now_add=True, help_text="The date and time the case was created."
|
|
71
70
|
)
|
|
72
71
|
updated_at = models.DateTimeField(
|
|
73
|
-
auto_now=True,
|
|
74
|
-
help_text="The date and time the case was last updated."
|
|
72
|
+
auto_now=True, help_text="The date and time the case was last updated."
|
|
75
73
|
)
|
|
76
74
|
|
|
77
75
|
if TYPE_CHECKING:
|
|
78
76
|
patient: models.ForeignKey["Patient"]
|
|
79
|
-
patient_examinations: models.ManyToManyField[
|
|
80
|
-
|
|
77
|
+
patient_examinations: models.ManyToManyField[
|
|
78
|
+
"PatientExamination", "PatientExamination"
|
|
79
|
+
]
|
|
80
|
+
|
|
81
81
|
class Meta:
|
|
82
|
-
ordering = [
|
|
82
|
+
ordering = ["-start_date", "patient"]
|
|
83
83
|
verbose_name = "Case"
|
|
84
84
|
verbose_name_plural = "Cases"
|
|
85
85
|
|
|
@@ -5,9 +5,9 @@ from .center_waste import CenterWaste
|
|
|
5
5
|
from .center_shift import CenterShift
|
|
6
6
|
|
|
7
7
|
__all__ = [
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
"Center",
|
|
9
|
+
"CenterProduct",
|
|
10
|
+
"CenterResource",
|
|
11
|
+
"CenterWaste",
|
|
12
|
+
"CenterShift",
|
|
13
13
|
]
|
|
@@ -48,10 +48,14 @@ class Center(models.Model):
|
|
|
48
48
|
def endoscopes(self) -> RelatedManager[Endoscope]: ...
|
|
49
49
|
|
|
50
50
|
@property
|
|
51
|
-
def anonymexaminationreport_set(
|
|
51
|
+
def anonymexaminationreport_set(
|
|
52
|
+
self,
|
|
53
|
+
) -> RelatedManager[AnonymExaminationReport]: ...
|
|
52
54
|
|
|
53
55
|
@property
|
|
54
|
-
def anonymhistologyreport_set(
|
|
56
|
+
def anonymhistologyreport_set(
|
|
57
|
+
self,
|
|
58
|
+
) -> RelatedManager[AnonymHistologyReport]: ...
|
|
55
59
|
|
|
56
60
|
@classmethod
|
|
57
61
|
def get_by_name(cls, name):
|
|
@@ -19,9 +19,17 @@ class CenterResource(models.Model):
|
|
|
19
19
|
quantity = models.FloatField()
|
|
20
20
|
resource = models.ForeignKey("Resource", on_delete=models.CASCADE)
|
|
21
21
|
transport_emission_factor = models.ForeignKey(
|
|
22
|
-
"EmissionFactor",
|
|
22
|
+
"EmissionFactor",
|
|
23
|
+
on_delete=models.SET_NULL,
|
|
24
|
+
null=True,
|
|
25
|
+
related_name="center_resource_transport_emission_factor",
|
|
26
|
+
)
|
|
27
|
+
use_emission_factor = models.ForeignKey(
|
|
28
|
+
"EmissionFactor",
|
|
29
|
+
on_delete=models.SET_NULL,
|
|
30
|
+
null=True,
|
|
31
|
+
related_name="center_resource_use_emission_factor",
|
|
23
32
|
)
|
|
24
|
-
use_emission_factor = models.ForeignKey("EmissionFactor", on_delete=models.SET_NULL, null=True, related_name="center_resource_use_emission_factor")
|
|
25
33
|
year = models.IntegerField()
|
|
26
34
|
unit = models.ForeignKey("Unit", on_delete=models.SET_NULL, null=True)
|
|
27
35
|
|
|
@@ -46,9 +54,15 @@ class CenterResource(models.Model):
|
|
|
46
54
|
result_string += "\tUnit\t-\t" + str(self.unit) + "\n"
|
|
47
55
|
|
|
48
56
|
if self.transport_emission_factor is not None:
|
|
49
|
-
result_string +=
|
|
57
|
+
result_string += (
|
|
58
|
+
"\tTransport Emission Factor\t-\t"
|
|
59
|
+
+ str(self.transport_emission_factor)
|
|
60
|
+
+ "\n"
|
|
61
|
+
)
|
|
50
62
|
|
|
51
|
-
result_string +=
|
|
63
|
+
result_string += (
|
|
64
|
+
"\tUse Emission Factor\t-\t" + str(self.use_emission_factor) + "\n"
|
|
65
|
+
)
|
|
52
66
|
|
|
53
67
|
result_string += "\n"
|
|
54
68
|
|
|
@@ -61,7 +61,9 @@ class CenterShift(models.Model):
|
|
|
61
61
|
if TYPE_CHECKING:
|
|
62
62
|
center: models.ForeignKey["Center"]
|
|
63
63
|
shift: models.ForeignKey["Shift"]
|
|
64
|
-
scheduled_days = cast(
|
|
64
|
+
scheduled_days = cast(
|
|
65
|
+
models.manager.RelatedManager["ScheduledDays"], scheduled_days
|
|
66
|
+
)
|
|
65
67
|
|
|
66
68
|
def __str__(self):
|
|
67
69
|
"""
|
|
@@ -16,10 +16,14 @@ class CenterWaste(models.Model):
|
|
|
16
16
|
related_name="center_wastes",
|
|
17
17
|
)
|
|
18
18
|
year = models.IntegerField()
|
|
19
|
-
waste: models.ForeignKey["Waste"] = models.ForeignKey(
|
|
19
|
+
waste: models.ForeignKey["Waste"] = models.ForeignKey(
|
|
20
|
+
"Waste", on_delete=models.CASCADE
|
|
21
|
+
)
|
|
20
22
|
quantity = models.FloatField()
|
|
21
23
|
unit = models.ForeignKey("Unit", on_delete=models.SET_NULL, null=True)
|
|
22
|
-
emission_factor = models.ForeignKey(
|
|
24
|
+
emission_factor = models.ForeignKey(
|
|
25
|
+
"EmissionFactor", on_delete=models.SET_NULL, null=True
|
|
26
|
+
)
|
|
23
27
|
|
|
24
28
|
if TYPE_CHECKING:
|
|
25
29
|
center: models.ForeignKey["Center"]
|
|
@@ -34,7 +34,9 @@ class EmployeeType(models.Model):
|
|
|
34
34
|
)
|
|
35
35
|
|
|
36
36
|
if TYPE_CHECKING:
|
|
37
|
-
qualifications = cast(
|
|
37
|
+
qualifications = cast(
|
|
38
|
+
models.manager.RelatedManager["Qualification"], qualifications
|
|
39
|
+
)
|
|
38
40
|
|
|
39
41
|
@property
|
|
40
42
|
def employees(self) -> models.QuerySet["Employee"]: ...
|
|
@@ -12,7 +12,9 @@ if TYPE_CHECKING:
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class Examiner(Person):
|
|
15
|
-
center = models.ForeignKey(
|
|
15
|
+
center = models.ForeignKey(
|
|
16
|
+
"Center", on_delete=models.CASCADE, blank=True, null=True
|
|
17
|
+
)
|
|
16
18
|
hash = models.CharField(max_length=255, unique=True)
|
|
17
19
|
|
|
18
20
|
if TYPE_CHECKING:
|
|
@@ -23,7 +25,13 @@ class Examiner(Person):
|
|
|
23
25
|
return self.first_name + " " + self.last_name
|
|
24
26
|
|
|
25
27
|
@classmethod
|
|
26
|
-
def custom_get_or_create(
|
|
28
|
+
def custom_get_or_create(
|
|
29
|
+
cls,
|
|
30
|
+
first_name: str,
|
|
31
|
+
last_name: str,
|
|
32
|
+
center: "administration.Center",
|
|
33
|
+
substitute_names: bool = True,
|
|
34
|
+
):
|
|
27
35
|
from endoreg_db.models import (
|
|
28
36
|
FirstName,
|
|
29
37
|
LastName,
|
|
@@ -3,16 +3,18 @@
|
|
|
3
3
|
|
|
4
4
|
from django.db import models
|
|
5
5
|
|
|
6
|
+
|
|
6
7
|
class FirstNameManager(models.Manager):
|
|
7
8
|
def get_by_natural_key(self, name):
|
|
8
9
|
return self.get(name=name)
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
|
|
10
12
|
class FirstName(models.Model):
|
|
11
13
|
objects = FirstNameManager()
|
|
12
14
|
name = models.CharField(max_length=255, unique=True)
|
|
13
|
-
|
|
15
|
+
|
|
14
16
|
def natural_key(self):
|
|
15
17
|
return (self.name,)
|
|
16
|
-
|
|
18
|
+
|
|
17
19
|
def __str__(self):
|
|
18
|
-
return str(self.name)
|
|
20
|
+
return str(self.name)
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
2
1
|
from django.db import models
|
|
3
2
|
|
|
3
|
+
|
|
4
4
|
class LastNameManager(models.Manager):
|
|
5
5
|
def get_by_natural_key(self, name):
|
|
6
6
|
return self.get(name=name)
|
|
7
7
|
|
|
8
|
+
|
|
8
9
|
class LastName(models.Model):
|
|
9
10
|
objects = LastNameManager()
|
|
10
11
|
name = models.CharField(max_length=255, unique=True)
|
|
@@ -14,6 +15,6 @@ class LastName(models.Model):
|
|
|
14
15
|
|
|
15
16
|
def __str__(self):
|
|
16
17
|
return str(self.name)
|
|
17
|
-
|
|
18
|
+
|
|
19
|
+
|
|
18
20
|
# Path: endoreg_db/models/persons/first_name.py
|
|
19
|
-
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
"""Module for product models"""
|
|
2
|
+
|
|
2
3
|
from .product import Product
|
|
3
4
|
from .product_material import ProductMaterial
|
|
4
5
|
from .product_group import ProductGroup
|
|
@@ -6,9 +7,9 @@ from .reference_product import ReferenceProduct
|
|
|
6
7
|
from .product_weight import ProductWeight
|
|
7
8
|
|
|
8
9
|
__all__ = [
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
"Product",
|
|
11
|
+
"ProductMaterial",
|
|
12
|
+
"ProductGroup",
|
|
13
|
+
"ReferenceProduct",
|
|
14
|
+
"ProductWeight",
|
|
14
15
|
]
|
|
@@ -23,7 +23,9 @@ class Product(models.Model):
|
|
|
23
23
|
|
|
24
24
|
name = models.CharField(max_length=255)
|
|
25
25
|
|
|
26
|
-
transport_route = models.ForeignKey(
|
|
26
|
+
transport_route = models.ForeignKey(
|
|
27
|
+
"TransportRoute", on_delete=models.SET_NULL, null=True
|
|
28
|
+
)
|
|
27
29
|
product_group = models.ForeignKey(
|
|
28
30
|
"ProductGroup",
|
|
29
31
|
on_delete=models.SET_NULL,
|
|
@@ -56,7 +58,9 @@ class Product(models.Model):
|
|
|
56
58
|
|
|
57
59
|
def _calculate_material_metric(self, component: str, calculation_func):
|
|
58
60
|
"""Helper method to calculate weight or emission for materials of a specific component."""
|
|
59
|
-
from .product_material import
|
|
61
|
+
from .product_material import (
|
|
62
|
+
ProductMaterial,
|
|
63
|
+
) # Import locally to avoid circular dependency issues at module level
|
|
60
64
|
|
|
61
65
|
materials = ProductMaterial.objects.filter(product=self, component=component)
|
|
62
66
|
return calculation_func(materials)
|
|
@@ -7,33 +7,35 @@ if TYPE_CHECKING:
|
|
|
7
7
|
ReferenceProduct,
|
|
8
8
|
)
|
|
9
9
|
|
|
10
|
+
|
|
10
11
|
class ProductGroupManager(models.Manager):
|
|
11
12
|
def get_by_natural_key(self, name):
|
|
12
13
|
return self.get(name=name)
|
|
13
|
-
|
|
14
|
+
|
|
15
|
+
|
|
14
16
|
class ProductGroup(models.Model):
|
|
15
17
|
objects = ProductGroupManager()
|
|
16
18
|
|
|
17
19
|
name = models.CharField(max_length=255)
|
|
18
|
-
|
|
20
|
+
|
|
19
21
|
if TYPE_CHECKING:
|
|
20
22
|
reference_product: "ReferenceProduct"
|
|
21
23
|
products: models.QuerySet["Product"]
|
|
22
24
|
|
|
23
25
|
def natural_key(self):
|
|
24
26
|
return (self.name,)
|
|
25
|
-
|
|
27
|
+
|
|
26
28
|
def __str__(self):
|
|
27
29
|
return str(self.name)
|
|
28
|
-
|
|
30
|
+
|
|
29
31
|
def get_products(self) -> models.QuerySet["Product"]:
|
|
30
32
|
from .product import Product
|
|
33
|
+
|
|
31
34
|
products = self.products.all()
|
|
32
35
|
if products:
|
|
33
36
|
return products
|
|
34
37
|
else:
|
|
35
38
|
return Product.objects.none()
|
|
36
|
-
|
|
37
|
-
def get_reference_product(self) -> "None | ReferenceProduct":
|
|
38
|
-
return self.reference_product
|
|
39
39
|
|
|
40
|
+
def get_reference_product(self) -> "None | ReferenceProduct":
|
|
41
|
+
return self.reference_product
|
|
@@ -37,12 +37,19 @@ class ProductMaterial(models.Model):
|
|
|
37
37
|
def get_emission(self) -> tuple[float, Unit]:
|
|
38
38
|
emission_factor = self.material.emission_factor
|
|
39
39
|
if emission_factor is None:
|
|
40
|
-
raise Exception(
|
|
40
|
+
raise Exception(
|
|
41
|
+
"No emission factor for material " + self.material.name + " found."
|
|
42
|
+
)
|
|
41
43
|
|
|
42
44
|
# make sure product_material.unit is the same as emission_factor.unit
|
|
43
45
|
if self.unit is not None and emission_factor.unit is not None:
|
|
44
46
|
if self.unit != emission_factor.unit:
|
|
45
|
-
raise Exception(
|
|
47
|
+
raise Exception(
|
|
48
|
+
"Unit mismatch: "
|
|
49
|
+
+ self.unit.name
|
|
50
|
+
+ " != "
|
|
51
|
+
+ emission_factor.unit.name
|
|
52
|
+
)
|
|
46
53
|
|
|
47
54
|
emmision_value = emission_factor.value * self.quantity
|
|
48
55
|
assert isinstance(emission_factor.unit, Unit)
|