datamint 2.40.0__tar.gz → 2.41.0__tar.gz
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.
- {datamint-2.40.0 → datamint-2.41.0}/PKG-INFO +1 -1
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/dto/annotation_dto.py +4 -1
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/endpoints/annotations_api.py +240 -2
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/endpoints/deploy_model_api.py +0 -19
- {datamint-2.40.0 → datamint-2.41.0}/datamint/client_cmd_tools/datamint_init.py +2 -2
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/__init__.py +16 -3
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/annotation.py +1 -1
- datamint-2.40.0/datamint/entities/annotations/image_classification.py → datamint-2.41.0/datamint/entities/annotations/category_annotation.py +5 -1
- datamint-2.41.0/datamint/entities/annotations/image_classification.py +3 -0
- datamint-2.41.0/datamint/entities/annotations/label_annotation.py +37 -0
- datamint-2.41.0/datamint/entities/annotations/text_annotation.py +40 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/types.py +3 -1
- {datamint-2.40.0 → datamint-2.41.0}/datamint/examples/fracatlas_dataset.py +2 -2
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/lightning_modules/classification_module.py +3 -3
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/flavors/model.py +2 -2
- {datamint-2.40.0 → datamint-2.41.0}/pyproject.toml +1 -1
- {datamint-2.40.0 → datamint-2.41.0}/README.md +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/__main__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/_repr_utils.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/base_api.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/client.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/dto/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/dto/inference_prompts.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/dto/save_results_options.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/endpoints/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/endpoints/annotationsets_api.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/endpoints/datasetsinfo_api.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/endpoints/inference_api.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/endpoints/model_types.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/endpoints/models_api.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/endpoints/pod_logs_api.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/endpoints/projects_api.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/endpoints/resources_api.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/endpoints/users_api.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/endpoints/validation_studies_api.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/api/entity_base_api.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/client_cmd_tools/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/client_cmd_tools/datamint_config.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/client_cmd_tools/datamint_download.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/client_cmd_tools/datamint_example.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/client_cmd_tools/datamint_import.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/client_cmd_tools/datamint_inference.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/client_cmd_tools/datamint_train.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/client_cmd_tools/datamint_upload.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/configs.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/dataset/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/dataset/annotation_processor.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/dataset/base.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/dataset/factory.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/dataset/image_dataset.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/dataset/multiframe_dataset.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/dataset/sliced_dataset.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/dataset/sliced_video_dataset.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/dataset/split_result.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/dataset/video_dataset.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/dataset/volume_dataset.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/default_project.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotation_worklist.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/annotation_spec.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/base_geometry.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/base_segmentation.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/box_annotation.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/geometry.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/image_segmentation.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/line_annotation.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/numeric_annotation.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/point_annotation.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/region_annotation.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/annotations/volume_segmentation.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/base_entity.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/buildlog.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/cache_manager.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/channel.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/datasetinfo.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/deployjob.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/inferencejob.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/pod.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/project.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/project_resource_split.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/resource.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/resources/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/resources/dicom_resource.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/resources/image_resource.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/resources/nifti_resource.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/resources/video_resource.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/resources/volume_resource.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/sliced_resource.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/sliced_resource_base.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/sliced_video_resource.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/user.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/entities/validation_study.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/evaluate/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/evaluate/evaluator.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/evaluate/metrics/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/evaluate/metrics/classification.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/evaluate/metrics/detection.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/evaluate/metrics/segmentation.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/examples/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/examples/_common.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/examples/_download.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/examples/bccd_dataset.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/examples/busi_dataset.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/examples/example_projects.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/examples/synapse_dataset.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/exceptions.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/importers/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/importers/_common.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/importers/_detect.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/importers/coco.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/importers/pascal_voc.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/importers/yolo.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/benchmark.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/datamodule.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/base_trainer.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/classification_trainer.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/detection_trainer.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/lightning_modules/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/lightning_modules/base.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/lightning_modules/detection_modules/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/lightning_modules/detection_modules/yolox_module.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/lightning_modules/segmentation_module.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/lightning_modules/segmentation_modules/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/lightning_modules/segmentation_modules/deeplabv3plus.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/lightning_modules/segmentation_modules/smp_module.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/lightning_modules/segmentation_modules/transunet.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/lightning_modules/segmentation_modules/unetpp.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/lightning_modules/segmentation_modules/unetrpp.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/seg2d_trainer.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/seg3d_trainer.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/segmentation_trainer.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/specialized/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/specialized/deeplabv3plus.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/specialized/efficientnetv2.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/specialized/nnunet/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/specialized/nnunet/_nnunet_trainer_bridge.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/specialized/nnunet/data_export.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/specialized/nnunet/data_import.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/specialized/nnunet/inference_model.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/specialized/nnunet/trainer.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/specialized/transunet.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/specialized/unetpp.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/specialized/unetrpp.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/specialized/yolox.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/lightning/trainers/vol_seg_trainer.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/logging.yaml +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/artifact/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/artifact/datamint_artifacts_repo.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/data/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/data/datamint_dataset.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/env_utils.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/env_vars.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/flavors/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/flavors/annotation_specs.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/flavors/datamint_flavor.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/flavors/model_loader.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/flavors/model_parser.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/flavors/prediction_modes.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/flavors/prediction_router.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/flavors/task_type.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/flavors/validation.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/lightning/callbacks/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/lightning/callbacks/modelcheckpoint.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/models/Dockerfile.template +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/models/__init__.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/models/datamint_model_store.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/models/docker_build.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/models/local_inference.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/models/serve.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/models/tags.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/store_utils.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/tracking/datamint_store.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/tracking/default_experiment.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/tracking/fluent.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/mlflow/tracking/offline_buffer.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/types.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/utils/annotation_agreement.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/utils/collection_utils.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/utils/env.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/utils/logging_utils.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/utils/nifti_utils.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/utils/torchmetrics.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/utils/uncertainty.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/utils/urls.py +0 -0
- {datamint-2.40.0 → datamint-2.41.0}/datamint/utils/visualization.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datamint
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.41.0
|
|
4
4
|
Summary: A library for interacting with the Datamint API, designed for efficient data management, processing and Deep Learning workflows.
|
|
5
5
|
Keywords: medical-imaging,dicom,nifti,pytorch,mlflow,lightning,datasets,annotation
|
|
6
6
|
Author: SonanceAI
|
|
@@ -39,7 +39,8 @@ class CreateAnnotationDto:
|
|
|
39
39
|
model_id: str | None = None,
|
|
40
40
|
geometry: 'Geometry | None' = None,
|
|
41
41
|
units: str | None = None,
|
|
42
|
-
source: str | None = None
|
|
42
|
+
source: str | None = None,
|
|
43
|
+
frame_range: tuple[int, int] | None = None):
|
|
43
44
|
self.type = type if isinstance(type, AnnotationType) else AnnotationType(type)
|
|
44
45
|
self.value = value
|
|
45
46
|
self.identifier = identifier
|
|
@@ -48,6 +49,7 @@ class CreateAnnotationDto:
|
|
|
48
49
|
self.imported_from = imported_from
|
|
49
50
|
self.import_author = import_author
|
|
50
51
|
self.frame_index = frame_index
|
|
52
|
+
self.frame_range = frame_range # inclusive [start, end], as the server expects
|
|
51
53
|
self.units = units
|
|
52
54
|
self.model_id = model_id
|
|
53
55
|
if model_id is not None:
|
|
@@ -70,6 +72,7 @@ class CreateAnnotationDto:
|
|
|
70
72
|
"identifier": self.identifier,
|
|
71
73
|
"scope": self.scope,
|
|
72
74
|
'frame_index': self.frame_index,
|
|
75
|
+
'frame_range': list(self.frame_range) if self.frame_range is not None else None,
|
|
73
76
|
'annotation_worklist_id': self.annotation_worklist_id,
|
|
74
77
|
'imported_from': self.imported_from,
|
|
75
78
|
'import_author': self.import_author,
|
|
@@ -21,13 +21,14 @@ from PIL import Image
|
|
|
21
21
|
from tqdm.auto import tqdm
|
|
22
22
|
|
|
23
23
|
from datamint.api.dto import CreateAnnotationDto
|
|
24
|
+
from datamint.api.dto.annotation_dto import _remove_none
|
|
24
25
|
from datamint.entities import Resource
|
|
25
26
|
from datamint.entities.annotations import (
|
|
26
27
|
Annotation,
|
|
27
28
|
AnnotationType,
|
|
28
29
|
BoxAnnotation,
|
|
30
|
+
CategoryAnnotation,
|
|
29
31
|
CoordinateSystem,
|
|
30
|
-
ImageClassification,
|
|
31
32
|
LineAnnotation,
|
|
32
33
|
NumericAnnotation,
|
|
33
34
|
PointAnnotation,
|
|
@@ -1124,6 +1125,8 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
1124
1125
|
"""
|
|
1125
1126
|
Create an image-level classification annotation.
|
|
1126
1127
|
|
|
1128
|
+
Same as :meth:`add_category_annotation` without frames.
|
|
1129
|
+
|
|
1127
1130
|
Args:
|
|
1128
1131
|
resource: The resource unique id or Resource instance.
|
|
1129
1132
|
identifier: The annotation identifier/label.
|
|
@@ -1139,7 +1142,7 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
1139
1142
|
Returns:
|
|
1140
1143
|
The id of the created annotation.
|
|
1141
1144
|
"""
|
|
1142
|
-
annotation =
|
|
1145
|
+
annotation = CategoryAnnotation(
|
|
1143
1146
|
name=identifier,
|
|
1144
1147
|
value=value,
|
|
1145
1148
|
worklist_id=worklist_id,
|
|
@@ -1201,6 +1204,241 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
1201
1204
|
raise TypeError('Expected a single annotation id for numeric annotation creation.')
|
|
1202
1205
|
return created
|
|
1203
1206
|
|
|
1207
|
+
@staticmethod
|
|
1208
|
+
def _resolve_frame_scope(frame_index: int | None,
|
|
1209
|
+
frame_range: tuple[int, int] | None,
|
|
1210
|
+
) -> tuple[str, tuple[int, int] | None]:
|
|
1211
|
+
"""Return the scope and the inclusive frame range expected by the server."""
|
|
1212
|
+
if frame_index is not None and frame_range is not None:
|
|
1213
|
+
raise ValueError('Pass either frame_index or frame_range, not both.')
|
|
1214
|
+
if frame_range is None:
|
|
1215
|
+
return ('image' if frame_index is None else 'frame'), None
|
|
1216
|
+
start, end = frame_range
|
|
1217
|
+
if start < 0 or end <= start:
|
|
1218
|
+
raise ValueError(f'Invalid frame_range {frame_range}. Expected half-open (start, end) with 0 <= start < end.')
|
|
1219
|
+
return 'frame', (start, end - 1)
|
|
1220
|
+
|
|
1221
|
+
def _add_value_annotation(self,
|
|
1222
|
+
annotation_type: AnnotationType,
|
|
1223
|
+
resource: str | Resource,
|
|
1224
|
+
identifier: str,
|
|
1225
|
+
value: str | None,
|
|
1226
|
+
frame_index: int | None,
|
|
1227
|
+
frame_range: tuple[int, int] | None,
|
|
1228
|
+
worklist_id: str | None,
|
|
1229
|
+
author_email: str | None,
|
|
1230
|
+
imported_from: str | None,
|
|
1231
|
+
model_id: str | None,
|
|
1232
|
+
source: str | None) -> str:
|
|
1233
|
+
scope, inclusive_range = self._resolve_frame_scope(frame_index, frame_range)
|
|
1234
|
+
dto = CreateAnnotationDto(
|
|
1235
|
+
type=annotation_type,
|
|
1236
|
+
identifier=identifier,
|
|
1237
|
+
scope=scope,
|
|
1238
|
+
value=value,
|
|
1239
|
+
frame_index=frame_index,
|
|
1240
|
+
frame_range=inclusive_range,
|
|
1241
|
+
annotation_worklist_id=worklist_id,
|
|
1242
|
+
import_author=author_email,
|
|
1243
|
+
imported_from=imported_from,
|
|
1244
|
+
model_id=model_id,
|
|
1245
|
+
source=source,
|
|
1246
|
+
)
|
|
1247
|
+
created = self.create(resource, dto)
|
|
1248
|
+
if not isinstance(created, str):
|
|
1249
|
+
raise TypeError(f'Expected a single annotation id for {annotation_type.value} annotation creation.')
|
|
1250
|
+
return created
|
|
1251
|
+
|
|
1252
|
+
def add_text_annotation(self,
|
|
1253
|
+
resource: str | Resource,
|
|
1254
|
+
identifier: str,
|
|
1255
|
+
value: str,
|
|
1256
|
+
frame_index: int | None = None,
|
|
1257
|
+
frame_range: tuple[int, int] | None = None,
|
|
1258
|
+
worklist_id: str | None = None,
|
|
1259
|
+
author_email: str | None = None,
|
|
1260
|
+
imported_from: str | None = None,
|
|
1261
|
+
model_id: str | None = None,
|
|
1262
|
+
source: str | None = 'imported') -> str:
|
|
1263
|
+
"""
|
|
1264
|
+
Add a free-text annotation to a resource, for the whole image or for frames.
|
|
1265
|
+
|
|
1266
|
+
Args:
|
|
1267
|
+
resource: The resource unique id or Resource instance.
|
|
1268
|
+
identifier: The annotation identifier.
|
|
1269
|
+
value: Any free text.
|
|
1270
|
+
frame_index: A single frame (0-based). Makes the annotation frame-scoped.
|
|
1271
|
+
frame_range: Half-open ``(start, end)`` frame range, 0-based, ``end`` not included.
|
|
1272
|
+
Makes the annotation frame-scoped. Mutually exclusive with `frame_index`.
|
|
1273
|
+
worklist_id: The annotation worklist unique id.
|
|
1274
|
+
author_email: The email to consider as the author of the annotation.
|
|
1275
|
+
If None, use the customer of the api key.
|
|
1276
|
+
imported_from: The imported from source value.
|
|
1277
|
+
model_id: The model unique id.
|
|
1278
|
+
source: Annotation source tag.
|
|
1279
|
+
|
|
1280
|
+
Returns:
|
|
1281
|
+
The id of the created annotation.
|
|
1282
|
+
|
|
1283
|
+
Example:
|
|
1284
|
+
.. code-block:: python
|
|
1285
|
+
|
|
1286
|
+
api.annotations.add_text_annotation(resource, 'findings', 'small fracture line')
|
|
1287
|
+
api.annotations.add_text_annotation(resource, 'findings', 'motion blur', frame_range=(10, 20))
|
|
1288
|
+
"""
|
|
1289
|
+
return self._add_value_annotation(AnnotationType.TEXT, resource, identifier, value,
|
|
1290
|
+
frame_index, frame_range, worklist_id, author_email,
|
|
1291
|
+
imported_from, model_id, source)
|
|
1292
|
+
|
|
1293
|
+
def add_category_annotation(self,
|
|
1294
|
+
resource: str | Resource,
|
|
1295
|
+
identifier: str,
|
|
1296
|
+
value: str,
|
|
1297
|
+
frame_index: int | None = None,
|
|
1298
|
+
frame_range: tuple[int, int] | None = None,
|
|
1299
|
+
worklist_id: str | None = None,
|
|
1300
|
+
author_email: str | None = None,
|
|
1301
|
+
imported_from: str | None = None,
|
|
1302
|
+
model_id: str | None = None,
|
|
1303
|
+
source: str | None = 'imported') -> str:
|
|
1304
|
+
"""
|
|
1305
|
+
Add a category annotation to a resource, for the whole image or for frames.
|
|
1306
|
+
|
|
1307
|
+
Args:
|
|
1308
|
+
resource: The resource unique id or Resource instance.
|
|
1309
|
+
identifier: The annotation identifier.
|
|
1310
|
+
value: One of the category values set up in the project (e.g. 'Displaced').
|
|
1311
|
+
frame_index: A single frame (0-based). Makes the annotation frame-scoped.
|
|
1312
|
+
frame_range: Half-open ``(start, end)`` frame range, 0-based, ``end`` not included.
|
|
1313
|
+
Makes the annotation frame-scoped. Mutually exclusive with `frame_index`.
|
|
1314
|
+
worklist_id: The annotation worklist unique id.
|
|
1315
|
+
author_email: The email to consider as the author of the annotation.
|
|
1316
|
+
If None, use the customer of the api key.
|
|
1317
|
+
imported_from: The imported from source value.
|
|
1318
|
+
model_id: The model unique id.
|
|
1319
|
+
source: Annotation source tag.
|
|
1320
|
+
|
|
1321
|
+
Returns:
|
|
1322
|
+
The id of the created annotation.
|
|
1323
|
+
"""
|
|
1324
|
+
return self._add_value_annotation(AnnotationType.CATEGORY, resource, identifier, value,
|
|
1325
|
+
frame_index, frame_range, worklist_id, author_email,
|
|
1326
|
+
imported_from, model_id, source)
|
|
1327
|
+
|
|
1328
|
+
def add_label_annotation(self,
|
|
1329
|
+
resource: str | Resource,
|
|
1330
|
+
identifier: str,
|
|
1331
|
+
frame_index: int | None = None,
|
|
1332
|
+
frame_range: tuple[int, int] | None = None,
|
|
1333
|
+
worklist_id: str | None = None,
|
|
1334
|
+
author_email: str | None = None,
|
|
1335
|
+
imported_from: str | None = None,
|
|
1336
|
+
model_id: str | None = None,
|
|
1337
|
+
source: str | None = 'imported') -> str:
|
|
1338
|
+
"""
|
|
1339
|
+
Add a label annotation to a resource, for the whole image or for frames.
|
|
1340
|
+
A label marks that something is present and carries no value.
|
|
1341
|
+
|
|
1342
|
+
Args:
|
|
1343
|
+
resource: The resource unique id or Resource instance.
|
|
1344
|
+
identifier: The label name (e.g. 'Fracture').
|
|
1345
|
+
frame_index: A single frame (0-based). Makes the annotation frame-scoped.
|
|
1346
|
+
frame_range: Half-open ``(start, end)`` frame range, 0-based, ``end`` not included.
|
|
1347
|
+
Makes the annotation frame-scoped. Mutually exclusive with `frame_index`.
|
|
1348
|
+
worklist_id: The annotation worklist unique id.
|
|
1349
|
+
author_email: The email to consider as the author of the annotation.
|
|
1350
|
+
If None, use the customer of the api key.
|
|
1351
|
+
imported_from: The imported from source value.
|
|
1352
|
+
model_id: The model unique id.
|
|
1353
|
+
source: Annotation source tag.
|
|
1354
|
+
|
|
1355
|
+
Returns:
|
|
1356
|
+
The id of the created annotation.
|
|
1357
|
+
"""
|
|
1358
|
+
return self._add_value_annotation(AnnotationType.LABEL, resource, identifier, None,
|
|
1359
|
+
frame_index, frame_range, worklist_id, author_email,
|
|
1360
|
+
imported_from, model_id, source)
|
|
1361
|
+
|
|
1362
|
+
def set_frame_ranges(self,
|
|
1363
|
+
resource: str | Resource,
|
|
1364
|
+
identifier: str,
|
|
1365
|
+
type: AnnotationType | str,
|
|
1366
|
+
values: dict[str | float | None, Sequence[tuple[int, int]]],
|
|
1367
|
+
worklist_id: str | None = None,
|
|
1368
|
+
model_id: str | None = None,
|
|
1369
|
+
source: str | None = None) -> dict[str, Any]:
|
|
1370
|
+
"""
|
|
1371
|
+
Replace all frame ranges of one track (resource + identifier + type + author + worklist).
|
|
1372
|
+
|
|
1373
|
+
Anything not in `values` is removed, so passing an empty dict clears the track.
|
|
1374
|
+
|
|
1375
|
+
Args:
|
|
1376
|
+
resource: The resource unique id or Resource instance.
|
|
1377
|
+
identifier: The annotation identifier.
|
|
1378
|
+
type: One of 'text', 'category', 'integer', 'float' or 'label'.
|
|
1379
|
+
values: Maps each value to its half-open ``(start, end)`` frame ranges, 0-based.
|
|
1380
|
+
Use ``None`` as the key for a label, which carries no value.
|
|
1381
|
+
worklist_id: The annotation worklist unique id. Omit for project-level tracks.
|
|
1382
|
+
model_id: Registered model name. Only allowed for API keys.
|
|
1383
|
+
source: Annotation source tag. Defaults from the auth context when omitted.
|
|
1384
|
+
|
|
1385
|
+
Returns:
|
|
1386
|
+
The server response, with the ``created`` and ``deleted`` rows.
|
|
1387
|
+
|
|
1388
|
+
Example:
|
|
1389
|
+
.. code-block:: python
|
|
1390
|
+
|
|
1391
|
+
api.annotations.set_frame_ranges(resource, 'position', 'category',
|
|
1392
|
+
{'Displaced': [(0, 10), (20, 31)],
|
|
1393
|
+
'Normal': [(10, 20)]})
|
|
1394
|
+
"""
|
|
1395
|
+
type = type if isinstance(type, AnnotationType) else AnnotationType(type)
|
|
1396
|
+
payload_values = []
|
|
1397
|
+
for value, ranges in values.items():
|
|
1398
|
+
item: dict[str, Any] = {'frame_ranges': [{'start': start, 'end': end} for start, end in ranges]}
|
|
1399
|
+
if value is not None:
|
|
1400
|
+
item['value'] = value
|
|
1401
|
+
payload_values.append(item)
|
|
1402
|
+
|
|
1403
|
+
payload = _remove_none({
|
|
1404
|
+
'identifier': identifier,
|
|
1405
|
+
'type': type.value,
|
|
1406
|
+
'annotation_worklist_id': worklist_id,
|
|
1407
|
+
'values': payload_values,
|
|
1408
|
+
'source': source,
|
|
1409
|
+
'model_id': model_id,
|
|
1410
|
+
})
|
|
1411
|
+
resource_id = self._entid(resource)
|
|
1412
|
+
resp = self._make_request('PUT',
|
|
1413
|
+
f'{self.endpoint_base}/{resource_id}/frame-ranges',
|
|
1414
|
+
json=payload)
|
|
1415
|
+
return resp.json()
|
|
1416
|
+
|
|
1417
|
+
def get_frame_ranges(self,
|
|
1418
|
+
resource: str | Resource,
|
|
1419
|
+
worklist_id: str | None = None,
|
|
1420
|
+
created_by: str | None = None) -> list[dict[str, Any]]:
|
|
1421
|
+
"""
|
|
1422
|
+
Get the frame-scoped classifications (text, category, integer, float, label) of a resource,
|
|
1423
|
+
one record per identifier + value + author.
|
|
1424
|
+
|
|
1425
|
+
Args:
|
|
1426
|
+
resource: The resource unique id or Resource instance.
|
|
1427
|
+
worklist_id: Restrict to a worklist. Omit for project-level tracks.
|
|
1428
|
+
created_by: Restrict to a single author (email).
|
|
1429
|
+
|
|
1430
|
+
Returns:
|
|
1431
|
+
The server records, with ``frame_ranges`` as a list of half-open ``(start, end)`` tuples.
|
|
1432
|
+
"""
|
|
1433
|
+
params = _remove_none({'annotation_worklist_id': worklist_id, 'created_by': created_by})
|
|
1434
|
+
resource_id = self._entid(resource)
|
|
1435
|
+
records = self._make_request('GET',
|
|
1436
|
+
f'{self.endpoint_base}/{resource_id}/frame-ranges',
|
|
1437
|
+
params=params).json()
|
|
1438
|
+
for rec in records:
|
|
1439
|
+
rec['frame_ranges'] = [(r['start'], r['end']) for r in rec.get('frame_ranges') or []]
|
|
1440
|
+
return records
|
|
1441
|
+
|
|
1204
1442
|
def upload_predictions(
|
|
1205
1443
|
self,
|
|
1206
1444
|
resource: str | Resource,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""API handler for model deployment endpoints."""
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
|
-
import re
|
|
5
4
|
import threading
|
|
6
5
|
import time
|
|
7
6
|
from collections.abc import Callable, Generator
|
|
@@ -20,22 +19,6 @@ logger = logging.getLogger(__name__)
|
|
|
20
19
|
|
|
21
20
|
_TERMINAL_STATUSES = frozenset({'completed', 'failed', 'cancelled', 'error'})
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
def _model_name_to_image_name(model_name: str) -> str:
|
|
25
|
-
"""Lowercase and clean a model name to match the Docker image name it was deployed as."""
|
|
26
|
-
|
|
27
|
-
parts = [p for p in model_name.split("/") if p]
|
|
28
|
-
if not parts:
|
|
29
|
-
return "image"
|
|
30
|
-
cleaned = []
|
|
31
|
-
for part in parts:
|
|
32
|
-
part = part.strip().lower()
|
|
33
|
-
part = re.sub(r"\s+", "_", part)
|
|
34
|
-
part = re.sub(r"[^a-z0-9._-]", "-", part)
|
|
35
|
-
part = part.strip("._-")
|
|
36
|
-
cleaned.append(part or "image")
|
|
37
|
-
return "/".join(cleaned)
|
|
38
|
-
|
|
39
22
|
#: SSE event name carrying a single new build-log line
|
|
40
23
|
_LOG_EVENT = 'log'
|
|
41
24
|
#: SSE event name signalling that the log stream was closed by the server
|
|
@@ -231,7 +214,6 @@ class DeployModelApi(EntityBaseApi[DeployJob]):
|
|
|
231
214
|
|
|
232
215
|
def remove_image(self, model_name: str, tag: str | None = None) -> dict:
|
|
233
216
|
"""Remove a deployed model image."""
|
|
234
|
-
model_name = _model_name_to_image_name(model_name)
|
|
235
217
|
params = {}
|
|
236
218
|
if tag:
|
|
237
219
|
params['tag'] = tag
|
|
@@ -240,7 +222,6 @@ class DeployModelApi(EntityBaseApi[DeployJob]):
|
|
|
240
222
|
|
|
241
223
|
def image_exists(self, model_name: str, tag: str = DEFAULT_DEPLOY_MODEL_ALIAS) -> bool:
|
|
242
224
|
"""Check if a model image exists."""
|
|
243
|
-
model_name = _model_name_to_image_name(model_name)
|
|
244
225
|
params = {'tag': tag}
|
|
245
226
|
response = self._make_request('GET', f'/{self.endpoint_base}/image/{model_name}/exists', params=params)
|
|
246
227
|
return response.json().get('exists', False)
|
|
@@ -541,7 +541,7 @@ for class_dir in class_dirs:
|
|
|
541
541
|
print(f" '{class_name}': uploaded {len(uploaded)} images.")
|
|
542
542
|
|
|
543
543
|
for res in uploaded:
|
|
544
|
-
api.annotations.
|
|
544
|
+
api.annotations.add_category_annotation(
|
|
545
545
|
resource=res,
|
|
546
546
|
identifier=LABEL_NAME,
|
|
547
547
|
value=class_name,
|
|
@@ -800,7 +800,7 @@ for resource in test_resources:
|
|
|
800
800
|
pred_anns = predictions[0] if predictions else []
|
|
801
801
|
|
|
802
802
|
for ann in pred_anns:
|
|
803
|
-
api.annotations.
|
|
803
|
+
api.annotations.add_category_annotation(
|
|
804
804
|
resource=resource,
|
|
805
805
|
identifier=LABEL_NAME,
|
|
806
806
|
value=ann.value,
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
from .annotation import Annotation, _normalize_annotation_data
|
|
2
2
|
from .box_annotation import BoxAnnotation
|
|
3
|
+
from .category_annotation import CategoryAnnotation, ImageClassification
|
|
3
4
|
from .geometry import BoxGeometry, CoordinateSystem, Geometry, LineGeometry, PointGeometry, RegionGeometry
|
|
4
|
-
from .image_classification import ImageClassification
|
|
5
5
|
from .image_segmentation import ImageSegmentation
|
|
6
|
+
from .label_annotation import LabelAnnotation
|
|
6
7
|
from .line_annotation import LineAnnotation
|
|
7
8
|
from .numeric_annotation import NumericAnnotation
|
|
8
9
|
from .point_annotation import PointAnnotation
|
|
9
10
|
from .region_annotation import RegionAnnotation
|
|
11
|
+
from .text_annotation import TextAnnotation
|
|
10
12
|
from .types import AnnotationType
|
|
11
13
|
from .volume_segmentation import VolumeSegmentation
|
|
12
14
|
|
|
@@ -18,7 +20,9 @@ def annotation_from_dict(data: dict) -> Annotation:
|
|
|
18
20
|
|
|
19
21
|
* ``'segmentation'`` with a ``class_map`` → :class:`VolumeSegmentation`
|
|
20
22
|
* ``'segmentation'`` without ``class_map`` → :class:`ImageSegmentation`
|
|
21
|
-
* ``'category'`` → :class:`
|
|
23
|
+
* ``'category'`` → :class:`CategoryAnnotation`
|
|
24
|
+
* ``'text'`` → :class:`TextAnnotation`
|
|
25
|
+
* ``'label'`` → :class:`LabelAnnotation`
|
|
22
26
|
* ``'integer'``/``'float'`` → :class:`NumericAnnotation`
|
|
23
27
|
* ``'line'`` → :class:`LineAnnotation`
|
|
24
28
|
* ``'square'`` → :class:`BoxAnnotation`
|
|
@@ -47,7 +51,13 @@ def annotation_from_dict(data: dict) -> Annotation:
|
|
|
47
51
|
return ImageSegmentation(**normalized_data)
|
|
48
52
|
|
|
49
53
|
if annotation_type in (AnnotationType.CATEGORY, AnnotationType.CATEGORY.value):
|
|
50
|
-
return
|
|
54
|
+
return CategoryAnnotation(**normalized_data)
|
|
55
|
+
|
|
56
|
+
if annotation_type in (AnnotationType.TEXT, AnnotationType.TEXT.value):
|
|
57
|
+
return TextAnnotation(**normalized_data)
|
|
58
|
+
|
|
59
|
+
if annotation_type in (AnnotationType.LABEL, AnnotationType.LABEL.value):
|
|
60
|
+
return LabelAnnotation(**normalized_data)
|
|
51
61
|
|
|
52
62
|
if annotation_type in (AnnotationType.INTEGER, AnnotationType.FLOAT):
|
|
53
63
|
return NumericAnnotation(**normalized_data)
|
|
@@ -72,10 +82,12 @@ __all__ = [
|
|
|
72
82
|
"AnnotationType",
|
|
73
83
|
"BoxAnnotation",
|
|
74
84
|
"BoxGeometry",
|
|
85
|
+
"CategoryAnnotation",
|
|
75
86
|
"CoordinateSystem",
|
|
76
87
|
"Geometry",
|
|
77
88
|
"ImageClassification",
|
|
78
89
|
"ImageSegmentation",
|
|
90
|
+
"LabelAnnotation",
|
|
79
91
|
"LineAnnotation",
|
|
80
92
|
"LineGeometry",
|
|
81
93
|
"NumericAnnotation",
|
|
@@ -83,6 +95,7 @@ __all__ = [
|
|
|
83
95
|
"PointGeometry",
|
|
84
96
|
"RegionAnnotation",
|
|
85
97
|
"RegionGeometry",
|
|
98
|
+
"TextAnnotation",
|
|
86
99
|
"VolumeSegmentation",
|
|
87
100
|
"annotation_from_dict",
|
|
88
101
|
]
|
|
@@ -60,7 +60,7 @@ class AnnotationBase(BaseEntity):
|
|
|
60
60
|
"""Minimal base class for creating annotations.
|
|
61
61
|
|
|
62
62
|
This class contains only the essential fields needed to create annotations.
|
|
63
|
-
Use this for creating specific annotation types like
|
|
63
|
+
Use this for creating specific annotation types like CategoryAnnotation.
|
|
64
64
|
"""
|
|
65
65
|
|
|
66
66
|
model_config = ConfigDict(populate_by_name=True)
|
|
@@ -5,7 +5,7 @@ from typing import Any
|
|
|
5
5
|
from .annotation import Annotation
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class
|
|
8
|
+
class CategoryAnnotation(Annotation):
|
|
9
9
|
def __init__(
|
|
10
10
|
self,
|
|
11
11
|
name: str | None = None,
|
|
@@ -37,3 +37,7 @@ class ImageClassification(Annotation):
|
|
|
37
37
|
kwargs.setdefault('scope', 'image')
|
|
38
38
|
kwargs.setdefault('annotation_type', 'category')
|
|
39
39
|
super().__init__(**kwargs)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# Backwards compatible name. Same class, not a subclass.
|
|
43
|
+
ImageClassification = CategoryAnnotation
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from .annotation import Annotation
|
|
6
|
+
from .types import AnnotationType
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class LabelAnnotation(Annotation):
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
name: str | None = None,
|
|
13
|
+
confiability: float = 1.0,
|
|
14
|
+
worklist_id: str | None = None,
|
|
15
|
+
author_email: str | None = None,
|
|
16
|
+
imported_from: str | None = None,
|
|
17
|
+
model_id: str | None = None,
|
|
18
|
+
source: str | None = None,
|
|
19
|
+
**kwargs: Any,
|
|
20
|
+
) -> None:
|
|
21
|
+
if name is not None:
|
|
22
|
+
kwargs.setdefault('identifier', name)
|
|
23
|
+
if worklist_id is not None:
|
|
24
|
+
kwargs.setdefault('annotation_worklist_id', worklist_id)
|
|
25
|
+
if author_email is not None:
|
|
26
|
+
kwargs.setdefault('import_author', author_email)
|
|
27
|
+
if imported_from is not None:
|
|
28
|
+
kwargs.setdefault('imported_from', imported_from)
|
|
29
|
+
if model_id is not None:
|
|
30
|
+
kwargs.setdefault('model_id', model_id)
|
|
31
|
+
if source is not None:
|
|
32
|
+
kwargs.setdefault('source', source)
|
|
33
|
+
|
|
34
|
+
kwargs.setdefault('confiability', confiability)
|
|
35
|
+
kwargs.setdefault('scope', 'image')
|
|
36
|
+
kwargs.setdefault('annotation_type', AnnotationType.LABEL)
|
|
37
|
+
super().__init__(**kwargs)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from .annotation import Annotation
|
|
6
|
+
from .types import AnnotationType
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TextAnnotation(Annotation):
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
name: str | None = None,
|
|
13
|
+
value: str | None = None,
|
|
14
|
+
confiability: float = 1.0,
|
|
15
|
+
worklist_id: str | None = None,
|
|
16
|
+
author_email: str | None = None,
|
|
17
|
+
imported_from: str | None = None,
|
|
18
|
+
model_id: str | None = None,
|
|
19
|
+
source: str | None = None,
|
|
20
|
+
**kwargs: Any,
|
|
21
|
+
) -> None:
|
|
22
|
+
if name is not None:
|
|
23
|
+
kwargs.setdefault('identifier', name)
|
|
24
|
+
if value is not None:
|
|
25
|
+
kwargs.setdefault('text_value', value)
|
|
26
|
+
if worklist_id is not None:
|
|
27
|
+
kwargs.setdefault('annotation_worklist_id', worklist_id)
|
|
28
|
+
if author_email is not None:
|
|
29
|
+
kwargs.setdefault('import_author', author_email)
|
|
30
|
+
if imported_from is not None:
|
|
31
|
+
kwargs.setdefault('imported_from', imported_from)
|
|
32
|
+
if model_id is not None:
|
|
33
|
+
kwargs.setdefault('model_id', model_id)
|
|
34
|
+
if source is not None:
|
|
35
|
+
kwargs.setdefault('source', source)
|
|
36
|
+
|
|
37
|
+
kwargs.setdefault('confiability', confiability)
|
|
38
|
+
kwargs.setdefault('scope', 'image')
|
|
39
|
+
kwargs.setdefault('annotation_type', AnnotationType.TEXT)
|
|
40
|
+
super().__init__(**kwargs)
|
|
@@ -62,13 +62,13 @@ def create(project_name: str = _DATASET_NAME, api: Api | None = None) -> Project
|
|
|
62
62
|
)
|
|
63
63
|
|
|
64
64
|
for resource_id in tqdm(non_fractured_ids, desc='Uploading annotations'):
|
|
65
|
-
api.annotations.
|
|
65
|
+
api.annotations.add_category_annotation(
|
|
66
66
|
resource=resource_id,
|
|
67
67
|
identifier=_LABEL_IDENTIFIER,
|
|
68
68
|
value='no',
|
|
69
69
|
)
|
|
70
70
|
for resource_id in tqdm(fractured_ids, desc='Uploading annotations'):
|
|
71
|
-
api.annotations.
|
|
71
|
+
api.annotations.add_category_annotation(
|
|
72
72
|
resource=resource_id,
|
|
73
73
|
identifier=_LABEL_IDENTIFIER,
|
|
74
74
|
value='yes',
|
|
@@ -13,7 +13,7 @@ from albumentations.pytorch import ToTensorV2
|
|
|
13
13
|
from torch import Tensor, nn
|
|
14
14
|
from torchmetrics import MetricCollection
|
|
15
15
|
|
|
16
|
-
from datamint.entities.annotations import
|
|
16
|
+
from datamint.entities.annotations import CategoryAnnotation
|
|
17
17
|
from datamint.mlflow.flavors.task_type import TaskType
|
|
18
18
|
|
|
19
19
|
from .base import DatamintLightningModule
|
|
@@ -158,7 +158,7 @@ class ClassificationModule(DatamintLightningModule):
|
|
|
158
158
|
compute_uncertainty: bool = False,
|
|
159
159
|
**kwargs: Any,
|
|
160
160
|
):
|
|
161
|
-
"""Run classification inference, returning :class:`~datamint.entities.annotations.
|
|
161
|
+
"""Run classification inference, returning :class:`~datamint.entities.annotations.CategoryAnnotation` per resource.
|
|
162
162
|
|
|
163
163
|
Args:
|
|
164
164
|
compute_uncertainty: If ``True``, also compute a predictive-entropy
|
|
@@ -193,7 +193,7 @@ class ClassificationModule(DatamintLightningModule):
|
|
|
193
193
|
extra = {}
|
|
194
194
|
if compute_uncertainty:
|
|
195
195
|
extra['uncertainty'] = categorical_entropy(probs)[0].item()
|
|
196
|
-
all_preds.append([
|
|
196
|
+
all_preds.append([CategoryAnnotation(
|
|
197
197
|
name=identifier, value=value,
|
|
198
198
|
confiability=confidence,
|
|
199
199
|
**extra,
|
|
@@ -15,7 +15,7 @@ from typing_extensions import override
|
|
|
15
15
|
|
|
16
16
|
from datamint.entities.annotations import (
|
|
17
17
|
Annotation,
|
|
18
|
-
|
|
18
|
+
CategoryAnnotation,
|
|
19
19
|
ImageSegmentation,
|
|
20
20
|
)
|
|
21
21
|
from datamint.entities.annotations.annotation_spec import AnnotationSpec
|
|
@@ -34,7 +34,7 @@ logger = logging.getLogger(__name__)
|
|
|
34
34
|
|
|
35
35
|
# Type aliases
|
|
36
36
|
PredictionResult: TypeAlias = list[list[Annotation]]
|
|
37
|
-
PredictionImageResult: TypeAlias = Sequence[Sequence[ImageSegmentation |
|
|
37
|
+
PredictionImageResult: TypeAlias = Sequence[Sequence[ImageSegmentation | CategoryAnnotation]]
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
def _move_torch_modules_to_device(obj: Any, device: str, _seen: set[int] | None = None) -> None:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "datamint"
|
|
3
3
|
description = "A library for interacting with the Datamint API, designed for efficient data management, processing and Deep Learning workflows."
|
|
4
|
-
version = "2.
|
|
4
|
+
version = "2.41.0"
|
|
5
5
|
dynamic = ["dependencies"]
|
|
6
6
|
requires-python = ">=3.10"
|
|
7
7
|
readme = "README.md"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|