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
|
@@ -5,33 +5,41 @@ from django.utils.timezone import is_aware, make_naive
|
|
|
5
5
|
import datetime
|
|
6
6
|
import os
|
|
7
7
|
from openpyxl import Workbook
|
|
8
|
-
from django.conf import settings
|
|
9
8
|
import csv
|
|
10
9
|
|
|
10
|
+
|
|
11
11
|
class Command(BaseCommand):
|
|
12
|
-
help =
|
|
12
|
+
help = "Generates a structured report summarizing the database content of custom endoreg_db models and saves it to Excel and CSV files, excluding models with zero records from the files." # Updated help text
|
|
13
13
|
|
|
14
14
|
def handle(self, *args, **options):
|
|
15
15
|
"""
|
|
16
16
|
Generates a summary report of all models in the 'endoreg_db' app and exports the results to Excel and CSV files.
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
For each model, counts the total number of records and includes only models with at least one record in the output files. For models with records, attempts to display the range of values for common date or datetime fields and provides value counts for up to three categorical or ForeignKey fields, using heuristics based on field type and name. Handles missing app configuration, file saving errors, and aggregation exceptions gracefully, outputting progress and warnings to the console. Creates a 'data' directory within the app if it does not exist and saves the reports there.
|
|
19
19
|
"""
|
|
20
|
-
self.stdout.write(
|
|
20
|
+
self.stdout.write(
|
|
21
|
+
self.style.SUCCESS(
|
|
22
|
+
"Starting database content summarization for endoreg_db models..."
|
|
23
|
+
)
|
|
24
|
+
)
|
|
21
25
|
|
|
22
26
|
try:
|
|
23
|
-
app_config = apps.get_app_config(
|
|
27
|
+
app_config = apps.get_app_config("endoreg_db")
|
|
24
28
|
except LookupError:
|
|
25
|
-
self.stdout.write(
|
|
29
|
+
self.stdout.write(
|
|
30
|
+
self.style.ERROR(
|
|
31
|
+
"Could not find the 'endoreg_db' app. Make sure it's correctly installed and configured."
|
|
32
|
+
)
|
|
33
|
+
)
|
|
26
34
|
return
|
|
27
35
|
|
|
28
|
-
data_dir = os.path.join(app_config.path,
|
|
36
|
+
data_dir = os.path.join(app_config.path, "data")
|
|
29
37
|
if not os.path.exists(data_dir):
|
|
30
38
|
os.makedirs(data_dir)
|
|
31
39
|
self.stdout.write(self.style.SUCCESS(f"Created directory: {data_dir}"))
|
|
32
|
-
|
|
33
|
-
excel_file_path = os.path.join(data_dir,
|
|
34
|
-
csv_file_path = os.path.join(data_dir,
|
|
40
|
+
|
|
41
|
+
excel_file_path = os.path.join(data_dir, "db_summary.xlsx")
|
|
42
|
+
csv_file_path = os.path.join(data_dir, "db_summary.csv")
|
|
35
43
|
|
|
36
44
|
# --- Excel Setup ---
|
|
37
45
|
wb = Workbook()
|
|
@@ -42,20 +50,32 @@ class Command(BaseCommand):
|
|
|
42
50
|
# --- End Excel Setup ---
|
|
43
51
|
|
|
44
52
|
# --- CSV Setup ---
|
|
45
|
-
csv_data_for_file = [
|
|
53
|
+
csv_data_for_file = [
|
|
54
|
+
excel_headers
|
|
55
|
+
] # Initialize with headers for CSV, will only store rows with count > 0
|
|
46
56
|
# --- End CSV Setup ---
|
|
47
|
-
|
|
57
|
+
|
|
48
58
|
models = app_config.get_models()
|
|
49
59
|
|
|
50
60
|
if not models:
|
|
51
|
-
self.stdout.write(
|
|
61
|
+
self.stdout.write(
|
|
62
|
+
self.style.WARNING("No models found in the 'endoreg_db' app.")
|
|
63
|
+
)
|
|
52
64
|
try:
|
|
53
|
-
wb.save(excel_file_path)
|
|
54
|
-
self.stdout.write(
|
|
55
|
-
|
|
65
|
+
wb.save(excel_file_path) # wb will only have headers
|
|
66
|
+
self.stdout.write(
|
|
67
|
+
self.style.SUCCESS(
|
|
68
|
+
f"Empty summary report saved to {excel_file_path}"
|
|
69
|
+
)
|
|
70
|
+
)
|
|
71
|
+
with open(csv_file_path, "w", newline="") as f:
|
|
56
72
|
writer = csv.writer(f)
|
|
57
|
-
writer.writerows(
|
|
58
|
-
|
|
73
|
+
writer.writerows(
|
|
74
|
+
csv_data_for_file
|
|
75
|
+
) # csv_data_for_file will only contain headers
|
|
76
|
+
self.stdout.write(
|
|
77
|
+
self.style.SUCCESS(f"Empty summary report saved to {csv_file_path}")
|
|
78
|
+
)
|
|
59
79
|
except Exception as e:
|
|
60
80
|
self.stdout.write(self.style.ERROR(f"Error saving files: {e}"))
|
|
61
81
|
return
|
|
@@ -69,8 +89,12 @@ class Command(BaseCommand):
|
|
|
69
89
|
self.stdout.write(f" Total records: {count}")
|
|
70
90
|
|
|
71
91
|
if count == 0:
|
|
72
|
-
self.stdout.write(
|
|
73
|
-
|
|
92
|
+
self.stdout.write(
|
|
93
|
+
self.style.NOTICE(
|
|
94
|
+
" No records found for this model. Skipping from file output."
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
continue # Skip further processing for this model if count is 0 for file output
|
|
74
98
|
|
|
75
99
|
# --- Add to Excel (only if count > 0) ---
|
|
76
100
|
ws.append([model_name, count])
|
|
@@ -79,36 +103,63 @@ class Command(BaseCommand):
|
|
|
79
103
|
# --- Add to CSV data list (only if count > 0) ---
|
|
80
104
|
csv_data_for_file.append([model_name, count])
|
|
81
105
|
# --- End Add to CSV data list ---
|
|
82
|
-
|
|
106
|
+
|
|
83
107
|
# Attempt to get date ranges for common date/datetime fields
|
|
84
|
-
date_fields_to_check = [
|
|
85
|
-
|
|
86
|
-
|
|
108
|
+
date_fields_to_check = [
|
|
109
|
+
"created_at",
|
|
110
|
+
"updated_at",
|
|
111
|
+
"timestamp",
|
|
112
|
+
"date",
|
|
113
|
+
"start_time",
|
|
114
|
+
"end_time",
|
|
115
|
+
"examination_date",
|
|
116
|
+
"birth_date",
|
|
117
|
+
"record_date",
|
|
118
|
+
]
|
|
87
119
|
processed_date_field = False
|
|
88
120
|
for field_obj in model._meta.get_fields():
|
|
89
|
-
if field_obj.name in date_fields_to_check and isinstance(
|
|
121
|
+
if field_obj.name in date_fields_to_check and isinstance(
|
|
122
|
+
field_obj, (fields.DateField, fields.DateTimeField)
|
|
123
|
+
):
|
|
90
124
|
try:
|
|
91
|
-
aggregation = model.objects.aggregate(
|
|
92
|
-
|
|
93
|
-
|
|
125
|
+
aggregation = model.objects.aggregate(
|
|
126
|
+
min_date=Min(field_obj.name),
|
|
127
|
+
max_date=Max(field_obj.name),
|
|
128
|
+
)
|
|
129
|
+
min_val = aggregation.get("min_date")
|
|
130
|
+
max_val = aggregation.get("max_date")
|
|
94
131
|
|
|
95
132
|
if min_val is not None and max_val is not None:
|
|
96
|
-
if isinstance(min_val, datetime.datetime) and is_aware(
|
|
97
|
-
min_val
|
|
133
|
+
if isinstance(min_val, datetime.datetime) and is_aware(
|
|
134
|
+
min_val
|
|
135
|
+
):
|
|
136
|
+
min_val = make_naive(min_val).strftime(
|
|
137
|
+
"%Y-%m-%d %H:%M:%S"
|
|
138
|
+
)
|
|
98
139
|
elif isinstance(min_val, datetime.date):
|
|
99
|
-
min_val = min_val.strftime(
|
|
100
|
-
|
|
101
|
-
if isinstance(max_val, datetime.datetime) and is_aware(
|
|
102
|
-
max_val
|
|
140
|
+
min_val = min_val.strftime("%Y-%m-%d")
|
|
141
|
+
|
|
142
|
+
if isinstance(max_val, datetime.datetime) and is_aware(
|
|
143
|
+
max_val
|
|
144
|
+
):
|
|
145
|
+
max_val = make_naive(max_val).strftime(
|
|
146
|
+
"%Y-%m-%d %H:%M:%S"
|
|
147
|
+
)
|
|
103
148
|
elif isinstance(max_val, datetime.date):
|
|
104
|
-
max_val = max_val.strftime(
|
|
149
|
+
max_val = max_val.strftime("%Y-%m-%d")
|
|
105
150
|
|
|
106
|
-
self.stdout.write(
|
|
151
|
+
self.stdout.write(
|
|
152
|
+
f" {field_obj.verbose_name.capitalize()} range: {min_val} to {max_val}"
|
|
153
|
+
)
|
|
107
154
|
processed_date_field = True
|
|
108
|
-
break
|
|
155
|
+
break # Process only the first found relevant date field for brevity
|
|
109
156
|
except Exception as e:
|
|
110
|
-
self.stdout.write(
|
|
111
|
-
|
|
157
|
+
self.stdout.write(
|
|
158
|
+
self.style.WARNING(
|
|
159
|
+
f" Could not aggregate date range for '{field_obj.name}': {e}"
|
|
160
|
+
)
|
|
161
|
+
)
|
|
162
|
+
|
|
112
163
|
# Attempt to get value counts for potential categorical/ForeignKey fields
|
|
113
164
|
categorical_fields_found = 0
|
|
114
165
|
MAX_CATEGORICAL_FIELDS_TO_ANALYZE = 3
|
|
@@ -121,69 +172,109 @@ class Command(BaseCommand):
|
|
|
121
172
|
is_potential_categorical = False
|
|
122
173
|
field_name_lower = field.name.lower()
|
|
123
174
|
|
|
124
|
-
if
|
|
175
|
+
if (
|
|
176
|
+
field.many_to_one or field.one_to_one
|
|
177
|
+
): # ForeignKey or OneToOneField
|
|
125
178
|
if field.related_model:
|
|
126
179
|
is_potential_categorical = True
|
|
127
|
-
elif isinstance(
|
|
180
|
+
elif isinstance(
|
|
181
|
+
field,
|
|
182
|
+
(
|
|
183
|
+
fields.CharField,
|
|
184
|
+
fields.IntegerField,
|
|
185
|
+
fields.BooleanField,
|
|
186
|
+
fields.TextField,
|
|
187
|
+
),
|
|
188
|
+
):
|
|
128
189
|
# Heuristic for common categorical fields by name or type
|
|
129
|
-
if
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
190
|
+
if (
|
|
191
|
+
"type" in field_name_lower
|
|
192
|
+
or "status" in field_name_lower
|
|
193
|
+
or "gender" in field_name_lower
|
|
194
|
+
or "category" in field_name_lower
|
|
195
|
+
or isinstance(field, fields.BooleanField)
|
|
196
|
+
):
|
|
197
|
+
is_potential_categorical = True
|
|
135
198
|
# For CharField/TextField, also consider if it has few distinct values (expensive to check upfront for all)
|
|
136
199
|
# We'll rely on the naming heuristic primarily or if it's a boolean.
|
|
137
200
|
|
|
138
201
|
if is_potential_categorical:
|
|
139
202
|
try:
|
|
140
|
-
self.stdout.write(
|
|
141
|
-
|
|
203
|
+
self.stdout.write(
|
|
204
|
+
f" Value counts for '{field.verbose_name.capitalize() if hasattr(field, 'verbose_name') else field.name}':"
|
|
205
|
+
)
|
|
206
|
+
|
|
142
207
|
# QuerySet for distinct values and their counts
|
|
143
|
-
values_qs =
|
|
144
|
-
|
|
208
|
+
values_qs = (
|
|
209
|
+
model.objects.values(field.name)
|
|
210
|
+
.annotate(count=Count(field.name))
|
|
211
|
+
.order_by("-count")
|
|
212
|
+
)
|
|
213
|
+
|
|
145
214
|
distinct_values_count = values_qs.count()
|
|
146
215
|
|
|
147
216
|
if distinct_values_count == 0:
|
|
148
|
-
self.stdout.write(
|
|
217
|
+
self.stdout.write(
|
|
218
|
+
" No distinct values found or field is often NULL."
|
|
219
|
+
)
|
|
149
220
|
continue
|
|
150
221
|
|
|
151
222
|
for i, item in enumerate(values_qs):
|
|
152
223
|
if i >= MAX_DISTINCT_VALUES_TO_SHOW:
|
|
153
|
-
self.stdout.write(
|
|
224
|
+
self.stdout.write(
|
|
225
|
+
f" ... and {distinct_values_count - MAX_DISTINCT_VALUES_TO_SHOW} more distinct values."
|
|
226
|
+
)
|
|
154
227
|
break
|
|
155
228
|
val = item[field.name]
|
|
156
|
-
val_display =
|
|
229
|
+
val_display = (
|
|
230
|
+
str(val) if val is not None else "None/NULL"
|
|
231
|
+
)
|
|
157
232
|
# Truncate long string values for display
|
|
158
233
|
if isinstance(val, str) and len(val_display) > 50:
|
|
159
234
|
val_display = val_display[:47] + "..."
|
|
160
|
-
self.stdout.write(
|
|
161
|
-
|
|
235
|
+
self.stdout.write(
|
|
236
|
+
f" - {val_display}: {item['count']}"
|
|
237
|
+
)
|
|
238
|
+
|
|
162
239
|
categorical_fields_found += 1
|
|
163
240
|
|
|
164
241
|
except Exception as e:
|
|
165
242
|
# Some fields (like generic relations or complex custom fields) might not support this directly
|
|
166
|
-
self.stdout.write(
|
|
167
|
-
|
|
243
|
+
self.stdout.write(
|
|
244
|
+
self.style.WARNING(
|
|
245
|
+
f" Could not get value counts for '{field.name}': {e}"
|
|
246
|
+
)
|
|
247
|
+
)
|
|
248
|
+
|
|
168
249
|
except Exception as e:
|
|
169
|
-
self.stdout.write(
|
|
250
|
+
self.stdout.write(
|
|
251
|
+
self.style.ERROR(f" Error processing model {model_name}: {e}")
|
|
252
|
+
)
|
|
170
253
|
|
|
171
254
|
# --- Save Excel File ---
|
|
172
255
|
try:
|
|
173
256
|
wb.save(excel_file_path)
|
|
174
|
-
self.stdout.write(
|
|
257
|
+
self.stdout.write(
|
|
258
|
+
self.style.SUCCESS(
|
|
259
|
+
f"\nDatabase summary report saved to {excel_file_path}"
|
|
260
|
+
)
|
|
261
|
+
)
|
|
175
262
|
except Exception as e:
|
|
176
263
|
self.stdout.write(self.style.ERROR(f"\nError saving Excel file: {e}"))
|
|
177
264
|
# --- End Save Excel File ---
|
|
178
265
|
|
|
179
266
|
# --- Save CSV File ---
|
|
180
267
|
try:
|
|
181
|
-
with open(csv_file_path,
|
|
268
|
+
with open(csv_file_path, "w", newline="") as f:
|
|
182
269
|
writer = csv.writer(f)
|
|
183
270
|
writer.writerows(csv_data_for_file)
|
|
184
|
-
self.stdout.write(
|
|
271
|
+
self.stdout.write(
|
|
272
|
+
self.style.SUCCESS(f"Database summary report saved to {csv_file_path}")
|
|
273
|
+
)
|
|
185
274
|
except Exception as e:
|
|
186
275
|
self.stdout.write(self.style.ERROR(f"Error saving CSV file: {e}"))
|
|
187
276
|
# --- End Save CSV File ---
|
|
188
277
|
|
|
189
|
-
self.stdout.write(
|
|
278
|
+
self.stdout.write(
|
|
279
|
+
self.style.SUCCESS("\nDatabase content summarization finished.")
|
|
280
|
+
)
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# endoreg_db/management/commands/train_image_multilabel_model.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from django.core.management.base import BaseCommand, CommandError
|
|
6
|
+
|
|
7
|
+
from endoreg_db.models import AIDataSet
|
|
8
|
+
from endoreg_db.utils.ai.data_loader_for_model_training import (
|
|
9
|
+
build_dataset_for_training,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Command(BaseCommand):
|
|
14
|
+
help = (
|
|
15
|
+
"Train / fine-tune the image multi-label model on a given AIDataSet.\n"
|
|
16
|
+
"\n"
|
|
17
|
+
"This command is fully dynamic:\n"
|
|
18
|
+
"- It uses the AIDataSet row (id) to decide which annotations to use.\n"
|
|
19
|
+
"- It *infers* the LabelSet from the labels in those annotations.\n"
|
|
20
|
+
"- It builds image_paths, label_vectors, and label_masks for training.\n"
|
|
21
|
+
"- It prints detailed debug information about the chosen LabelSet and samples.\n"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
def add_arguments(self, parser):
|
|
25
|
+
parser.add_argument(
|
|
26
|
+
"--dataset-id",
|
|
27
|
+
type=int,
|
|
28
|
+
required=True,
|
|
29
|
+
help="Primary key of the AIDataSet to use for training.",
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def handle(self, *args, **options):
|
|
33
|
+
dataset_id = options["dataset_id"]
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
dataset = AIDataSet.objects.get(id=dataset_id)
|
|
37
|
+
except AIDataSet.DoesNotExist:
|
|
38
|
+
raise CommandError(f"AIDataSet with id={dataset_id} does not exist.")
|
|
39
|
+
|
|
40
|
+
# ------------------------------------------------------------------
|
|
41
|
+
# Basic dataset info (AIDataSet row)
|
|
42
|
+
# ------------------------------------------------------------------
|
|
43
|
+
self.stdout.write(
|
|
44
|
+
self.style.NOTICE(
|
|
45
|
+
f"Using AIDataSet id={dataset.id}, "
|
|
46
|
+
f"name={dataset.name!r}, "
|
|
47
|
+
f"dataset_type={dataset.dataset_type!r}, "
|
|
48
|
+
f"ai_model_type={dataset.ai_model_type!r}"
|
|
49
|
+
)
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Build in-memory dataset (completely dynamic, labelset inferred automatically)
|
|
53
|
+
data = build_dataset_for_training(dataset)
|
|
54
|
+
|
|
55
|
+
image_paths = data["image_paths"]
|
|
56
|
+
label_vectors = data["label_vectors"]
|
|
57
|
+
label_masks = data["label_masks"]
|
|
58
|
+
labels = data["labels"]
|
|
59
|
+
labelset = data["labelset"]
|
|
60
|
+
|
|
61
|
+
# Optional: additional meta info, if present
|
|
62
|
+
frame_ids = data.get("frame_ids", [])
|
|
63
|
+
old_examination_ids = data.get("old_examination_ids", [])
|
|
64
|
+
|
|
65
|
+
# ------------------------------------------------------------------
|
|
66
|
+
# Debug: show which LabelSet was picked and its labels
|
|
67
|
+
# ------------------------------------------------------------------
|
|
68
|
+
self.stdout.write(self.style.NOTICE("Inferred LabelSet for this AIDataSet:"))
|
|
69
|
+
self.stdout.write(
|
|
70
|
+
f" LabelSet id={labelset.id}, "
|
|
71
|
+
f"name={labelset.name!r}, "
|
|
72
|
+
f"version={labelset.version}"
|
|
73
|
+
)
|
|
74
|
+
self.stdout.write(" Labels (index, id, name):")
|
|
75
|
+
for idx, lbl in enumerate(labels):
|
|
76
|
+
self.stdout.write(f" [{idx}] id={lbl.id}, name={lbl.name!r}")
|
|
77
|
+
|
|
78
|
+
# ------------------------------------------------------------------
|
|
79
|
+
# Summary of constructed dataset
|
|
80
|
+
# ------------------------------------------------------------------
|
|
81
|
+
self.stdout.write(
|
|
82
|
+
self.style.SUCCESS(
|
|
83
|
+
f"\nBuilt training dataset from AIDataSet id={dataset.id}:\n"
|
|
84
|
+
f"- #samples: {len(image_paths)}\n"
|
|
85
|
+
f"- #labels: {len(labels)}"
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# ------------------------------------------------------------------
|
|
90
|
+
# Debug: print each frame's path, label vector and mask
|
|
91
|
+
# NOTE: If your dataset is very large, this will spam the console.
|
|
92
|
+
# For now you want full transparency, so we print all.
|
|
93
|
+
# ------------------------------------------------------------------
|
|
94
|
+
MAX_PRINT = 50
|
|
95
|
+
self.stdout.write(self.style.NOTICE("\nPer-sample debug output:"))
|
|
96
|
+
for i, (path, vec, mask) in enumerate(
|
|
97
|
+
zip(image_paths, label_vectors, label_masks)
|
|
98
|
+
):
|
|
99
|
+
if i >= MAX_PRINT:
|
|
100
|
+
self.stdout.write(
|
|
101
|
+
self.style.WARNING(
|
|
102
|
+
f"... ({len(image_paths) - MAX_PRINT} more samples not shown)"
|
|
103
|
+
)
|
|
104
|
+
)
|
|
105
|
+
break
|
|
106
|
+
|
|
107
|
+
frame_id = frame_ids[i] if i < len(frame_ids) else None
|
|
108
|
+
old_exam = old_examination_ids[i] if i < len(old_examination_ids) else None
|
|
109
|
+
|
|
110
|
+
self.stdout.write(
|
|
111
|
+
f" Sample {i}:"
|
|
112
|
+
f"\n path = {path!r}"
|
|
113
|
+
f"\n frame_id = {frame_id}"
|
|
114
|
+
f"\n old_examination_id = {old_exam}"
|
|
115
|
+
f"\n vector (1/0/None) = {vec}"
|
|
116
|
+
f"\n mask (1=use, 0=ignore) = {mask}"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
# ------------------------------------------------------------------
|
|
120
|
+
# TODO: Insert your actual training loop here
|
|
121
|
+
# ------------------------------------------------------------------
|
|
122
|
+
# Example (pseudo-code):
|
|
123
|
+
#
|
|
124
|
+
# import torch
|
|
125
|
+
# from torch.utils.data import Dataset, DataLoader
|
|
126
|
+
#
|
|
127
|
+
# class EndoDataset(Dataset):
|
|
128
|
+
# def __init__(self, image_paths, label_vectors, label_masks):
|
|
129
|
+
# ...
|
|
130
|
+
#
|
|
131
|
+
# ds = EndoDataset(image_paths, label_vectors, label_masks)
|
|
132
|
+
# loader = DataLoader(ds, batch_size=32, shuffle=True)
|
|
133
|
+
#
|
|
134
|
+
# for batch in loader:
|
|
135
|
+
# # forward, compute loss using mask, backward, step, ...
|
|
136
|
+
#
|
|
137
|
+
# ------------------------------------------------------------------
|
|
138
|
+
|
|
139
|
+
self.stdout.write(
|
|
140
|
+
self.style.SUCCESS(
|
|
141
|
+
"\nDataset construction finished. "
|
|
142
|
+
"You can now plug this into your model training code."
|
|
143
|
+
)
|
|
144
|
+
)
|