pathology/transformation_pipeline/ingest_flags.py (586 lines of code) (raw):

# Copyright 2023 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== """Flags used in transformation pipeline. Flags annotated with: * 'oof' are applicable for OOF mode * 'default' are applicable for default mode * 'required' must be populated for the pipeline to work * 'optional' pipeline will work without populating them """ import enum import json import os import sys from typing import Any, List, Optional, Union from absl import flags from pathology.shared_libs.flags import secret_flag_utils from pathology.transformation_pipeline.ingestion_lib import ingest_const def _load_multi_string(val: Optional[str]) -> Optional[Union[List[str], str]]: if val is None: return None try: return json.loads(val) except json.decoder.JSONDecodeError: return val def get_value( env_var: str, test_default_value: Optional[Any] = None, default_value: Any = None, ) -> Any: """Returns applicable value for flag. Prioritizes env_var if available, then test value, then default value. Args: env_var: Environment variable name to use. test_default_value: Default value to use when running tests. default_value: Default value to use. """ if test_default_value and ( 'UNITTEST_ON_FORGE' in os.environ or 'unittest' in sys.modules ): default_value = test_default_value return secret_flag_utils.get_secret_or_env(env_var, default_value) class MetadataUidValidation(enum.Enum): NONE = 1 LOG_WARNING = 2 ERROR = 3 class MetadataTagLengthValidation(enum.Enum): NONE = 1 LOG_WARNING = 2 LOG_WARNING_AND_CLIP = 3 ERROR = 4 class UidSource(enum.Enum): DICOM = 1 METADATA = 2 class Wsi2DcmCompression(enum.Enum): JPEG = 'jpeg' JPEG2000 = 'jpeg2000' RAW = 'raw' class Wsi2DcmFirstLevelCompression(enum.Enum): NONE = None JPEG = Wsi2DcmCompression.JPEG.value JPEG2000 = Wsi2DcmCompression.JPEG2000.value RAW = Wsi2DcmCompression.RAW.value class Wsi2DcmJpegCompressionSubsample(enum.Enum): SUBSAMPLE_444 = '444' SUBSAMPLE_440 = '440' SUBSAMPLE_442 = '442' SUBSAMPLE_420 = '420' class Wsi2DcmPixelEquivalentTransform(enum.Enum): DISABLED = None HIGHEST_MAGNIFICATION = 'SVSImportPreferScannerTileingForLargestLevel' ALL_LEVELS = 'SVSImportPreferScannerTileingForAllLevels' class WsiDicomExtendedDepthOfFieldDefault(enum.Enum): YES = 'YES' NO = 'NO' class WsiDicomFocusMethod(enum.Enum): AUTO = 'AUTO' MANUAL = 'MANUAL' TRANSFORMATION_PIPELINE_FLG = flags.DEFINE_string( 'transformation_pipeline', secret_flag_utils.get_secret_or_env('TRANSFORMATION_PIPELINE', 'default'), '[optional|default,oof] Defines transformation pipeline to run. Must be one' ' of {default, oof}.', ) EMBED_ICC_PROFILE_FLG = flags.DEFINE_boolean( 'embed_icc_profile', secret_flag_utils.get_bool_secret_or_env('EMBED_ICC_PROFILE', True), '[optional|default] embed icc profile into dicom', ) METADATA_BUCKET_FLG = flags.DEFINE_string( 'metadata_bucket', secret_flag_utils.get_secret_or_env('METADATA_BUCKET', ''), '[required|default] Name of bucket non-imaging metadata is pushed to.', ) BIG_QUERY_METADATA_TABLE_FLG = flags.DEFINE_string( 'big_query_metadata_table', secret_flag_utils.get_secret_or_env('BIG_QUERY_METADATA_TABLE', ''), 'Id of BigQuery table to ingest metadata from ' 'ex.project_id.dataset_id.table_name.', ) DICOM_GUID_PREFIX_FLG = flags.DEFINE_string( 'dicom_guid_prefix', secret_flag_utils.get_secret_or_env( 'DICOM_GUID_PREFIX', ingest_const.DPAS_UID_PREFIX ), '[optional|default] Prefix for generated DICOM GUIDs.', ) VIEWER_DEBUG_URL_FLG = flags.DEFINE_string( 'viewer_debug_url', secret_flag_utils.get_secret_or_env('VIEWER_DEBUG_URL', ''), '[optional|default,oof] If defined, a debug url is logged at the end of' ' ingestion.', ) DICOM_QUOTA_ERROR_RETRY_FLG = flags.DEFINE_integer( 'dicom_quota_error_retry_sec', secret_flag_utils.get_secret_or_env('DICOM_QUOTA_ERROR_RETRY', '600'), '[optional|default,oof] Seconds to wait before retying DICOM Store' ' upload due to quota failure.', ) COPY_DICOM_TO_BUCKET_URI_FLG = flags.DEFINE_string( 'copy_dicom_to_bucket_uri', secret_flag_utils.get_secret_or_env('COPY_DICOM_TO_BUCKET_URI', ''), '[optional|default/oof] The bucket to copy generated DICOM to. If empty, ' 'the generated DICOM will not be copied.', ) # Pub/Sub flags PROJECT_ID_FLG = flags.DEFINE_string( 'project_id', secret_flag_utils.get_secret_or_env('PROJECT_ID', ''), '[required|default,oof] GCP project id to listen on.', ) GCS_SUBSCRIPTION_FLG = flags.DEFINE_string( 'gcs_subscription', secret_flag_utils.get_secret_or_env('GCS_SUBSCRIPTION', None), '[required|default] Pub/Sub GCS subscription id to listen on. Used in' ' regular (default) transformation pipeline only.', ) DICOM_STORE_SUBSCRIPTION_FLG = flags.DEFINE_string( 'dicom_store_subscription', secret_flag_utils.get_secret_or_env('DICOM_STORE_SUBSCRIPTION', None), '[optional|default] Pub/Sub DICOM store subscription id to listen on. Used' 'in regular (default) transformation pipeline only.', ) OOF_SUBSCRIPTION_FLG = flags.DEFINE_string( 'oof_subscription', secret_flag_utils.get_secret_or_env('OOF_SUBSCRIPTION', None), '[required|oof] Pub/Sub Dataflow subscription id to listen on. Used in OOF' ' transformation pipeline only.', ) INGEST_COMPLETE_OOF_TRIGGER_PUBSUB_TOPIC_FLG = flags.DEFINE_string( 'ingest_complete_oof_trigger_pubsub_topic', secret_flag_utils.get_secret_or_env( ingest_const.EnvVarNames.INGEST_COMPLETE_OOF_TRIGGER_PUBSUB_TOPIC, '' ), '[required|oof] Pub/Sub topic to publish to at completion of ingestion to' ' trigger OOF.', ) # GCS ingestion flags INGEST_SUCCEEDED_URI_FLG = flags.DEFINE_string( 'ingest_succeeded_uri', secret_flag_utils.get_secret_or_env('INGEST_SUCCEEDED_URI', ''), '[required|default] Bucket/path to move input to if ingest succeeds.', ) INGEST_FAILED_URI_FLG = flags.DEFINE_string( 'ingest_failed_uri', secret_flag_utils.get_secret_or_env('INGEST_FAILED_URI', ''), '[required|default] Bucket/path to move input to if an error occurs.', ) GCS_INGEST_STUDY_INSTANCE_UID_SOURCE_FLG = flags.DEFINE_enum_class( 'gcs_ingest_study_instance_uid_source', get_value(env_var='GCS_INGEST_STUDY_INSTANCE_UID_SOURCE'), UidSource, '[required|default] Which StudyInstanceUID source to use in GCS ingestion.', ) INGEST_IGNORE_ROOT_DIR_FLG = flags.DEFINE_multi_string( 'ingest_ignore_root_dirs', _load_multi_string( secret_flag_utils.get_secret_or_env( 'INGEST_IGNORE_ROOT_DIR', '["cloud-ingest", "storage-transfer"]' ) ), '[optional|default] Root folders ignored in ingestion.', ) GCS_FILE_INGEST_LIST_FLG = flags.DEFINE_multi_string( 'gcs_file_to_ingest_list', _load_multi_string( secret_flag_utils.get_secret_or_env('GCS_FILE_INGEST_LIST', None) ), '[optional|default] Fixed list of GCS files to ingest. Client will' 'terminate at end of ingestion.', ) GCS_UPLOAD_IGNORE_FILE_EXTS_FLG = flags.DEFINE_list( 'gcs_upload_ignore_file_exts', secret_flag_utils.get_secret_or_env( ingest_const.EnvVarNames.GCS_UPLOAD_IGNORE_FILE_EXT, '' ), '[optional|default] Comma-separated list of file extensions (e.g., ".json")' ' which will be ignored by ingestion if uploaded to GCS. Files without' ' extensions can be defined as " ".', ) GCS_IGNORE_FILE_REGEXS_FLG = flags.DEFINE_multi_string( 'gcs_ignore_file_regexs', _load_multi_string( secret_flag_utils.get_secret_or_env( ingest_const.EnvVarNames.GCS_IGNORE_FILE_REGEXS, None ) ), '[optional|default] List of regular expression used to identify file names ' 'to ignore. The file will will be ingored if any of the regex match.', ) GCS_IGNORE_FILE_BUCKET_FLG = flags.DEFINE_string( 'gcs_ignore_file_bucket', secret_flag_utils.get_secret_or_env( ingest_const.EnvVarNames.GCS_IGNORE_FILE_BUCKET, '' ), '[optional|default] Optional name of bucket to move files which are ignored' ' by the transformation pipeline.', ) FILENAME_SLIDEID_REGEX_FLG = flags.DEFINE_string( 'wsi2dcm_filename_slideid_regex', secret_flag_utils.get_secret_or_env( 'SLIDEID_REGEX', secret_flag_utils.get_secret_or_env( 'METADATA_PRIMARY_KEY_REGEX', '^[a-zA-Z0-9]+-[a-zA-Z0-9]+(-[a-zA-Z0-9]+)+', ), ), '[optional|default] Regular expression used to identify candidate metadata' ' primary key in filename. Default value matches 3 or more hyphen separated' ' alpha-numeric blocks, e.g. SR-21-2 and SR-21-2-B1-5.', ) FILENAME_SLIDEID_SPLIT_STR_FLG = flags.DEFINE_string( 'filename_slideid_split_str', secret_flag_utils.get_secret_or_env( 'FILENAME_SLIDEID_SPLIT_STR', secret_flag_utils.get_secret_or_env( 'FILENAME_METADATA_PRIMARY_KEY_SPLIT_STR', '_' ), ), '[optional|default] Character or string to split GCS filename to find' ' metadata primary key using regex defined in FILENAME_SLIDEID_REGEX_FLG.', ) TEST_WHOLE_FILENAME_AS_SLIDEID_FLG = flags.DEFINE_boolean( 'test_whole_filename_as_slideid', secret_flag_utils.get_bool_secret_or_env( 'TEST_WHOLE_FILENAME_AS_SLIDEID', secret_flag_utils.get_bool_secret_or_env( 'TEST_WHOLE_FILENAME_AS_METADATA_PRIMARY_KEY', ), ), '[optional|default] Include slide whole filename excluding file extension' ' as a candidate metadata primary key.', ) INCLUDE_UPLOAD_BUCKET_PATH_IN_WHOLE_FILENAME_SLIDEID_FLG = flags.DEFINE_boolean( 'include_upload_bucket_path_in_whole_filename_slideid', secret_flag_utils.get_bool_secret_or_env( 'INCLUDE_UPLOAD_BUCKET_PATH_IN_WHOLE_FILENAME_SLIDEID', secret_flag_utils.get_bool_secret_or_env( 'INCLUDE_UPLOAD_BUCKET_PATH_IN_WHOLE_FILENAME_METADATA_PRIMARY_KEY' ), ), '[optional|default] Include bucket upload path in whole filename metadata ' 'primary key. If enabled and file upload to gs://mybucket/foo/bar.svs then ' 'whole filename metadata primary key will be foo/bar. If False (default), ' 'then whole filename metadata primary key will be bar.', ) ENABLE_CREATE_MISSING_STUDY_INSTANCE_UID_FLG = flags.DEFINE_boolean( 'enable_create_missing_study_instance_uid', secret_flag_utils.get_bool_secret_or_env( 'ENABLE_CREATE_MISSING_STUDY_INSTANCE_UID' ), '[optional|default] If True pipeline will create instance Study Instance ' 'UID if its missing. Requires metadata to define accession number.', ) ENABLE_METADATA_FREE_INGESTION_FLG = flags.DEFINE_boolean( 'enable_metadata_free_ingestion', secret_flag_utils.get_bool_secret_or_env('ENABLE_METADATA_FREE_INGESTION'), '[optional|default] If True pipeline will ingest images without requiring ' 'metadata. Each image will be ingested into unique study and series ' 'instance uid. The PatientID will be set to the ingested file name.', ) METADATA_UID_VALIDATION_FLG = flags.DEFINE_enum_class( 'metadata_uid_validation', get_value( env_var='METADATA_UID_VALIDATION', default_value=MetadataUidValidation.LOG_WARNING.name, ), MetadataUidValidation, '[optional|default] How to report errors in metadata UID formating.', ) METADATA_TAG_LENGTH_VALIDATION_FLG = flags.DEFINE_enum_class( 'metadata_tag_length_validation', get_value( env_var='METADATA_TAG_LENGTH_VALIDATION', default_value=MetadataTagLengthValidation.LOG_WARNING.name, ), MetadataTagLengthValidation, '[optional|default] How to handles DICOM tags which exceed the length/size ' 'limits that are defined by the DICOM standard for the tags VR code.', ) DELETE_FILE_FROM_INGEST_AT_BUCKET_AT_INGEST_SUCCESS_OR_FAILURE_FLG = flags.DEFINE_boolean( 'delete_file_from_ingest_or_bucket', secret_flag_utils.get_bool_secret_or_env( 'DELETE_FILE_FROM_INGEST_BUCKET_AT_INGEST_SUCCESS_OR_FAILURE', undefined_value=True, ), '[optional|default] Set flag to False to disable file deletion from the ' 'ingestion bucket. If disabled, file will be copied to the success/failure ' 'bucket at the end of ingestion but not removed from the ingestion bucket ' 'to help de-duplicate uploads.', ) REDIS_SERVER_IP_FLG = flags.DEFINE_string( 'redis_server_ip', secret_flag_utils.get_secret_or_env('REDIS_SERVER_IP', None), '[optional|default] IP address of cloud memory store for redis. Used to ' 'back cross GKE redis locks.', ) REDIS_SERVER_PORT_FLG = flags.DEFINE_integer( 'redis_server_port', int(secret_flag_utils.get_secret_or_env('REDIS_SERVER_PORT', '6379')), '[optional|default] Port of cloud memory store for redis. Used to back ' 'cross GKE redis locks.', ) REDIS_DB_FLG = flags.DEFINE_integer( 'redis_db', int(secret_flag_utils.get_secret_or_env('REDIS_DB', '0')), 'Redis database', ) REDIS_USERNAME_FLG = flags.DEFINE_string( 'redis_auth_username', secret_flag_utils.get_secret_or_env('REDIS_USERNAME', None), 'Redis auth username.', ) REDIS_AUTH_PASSWORD_FLG = flags.DEFINE_string( 'redis_auth_password', secret_flag_utils.get_secret_or_env('REDIS_AUTH_PASSWORD', None), 'Redis auth password.', ) TRANSFORM_POD_UID_FLG = flags.DEFINE_string( 'transform_pod_uid', secret_flag_utils.get_secret_or_env('MY_POD_UID', None), 'UID of GKE pod. Do not set unless in test.', ) TRANSFORMATION_LOCK_RETRY_FLG = flags.DEFINE_integer( 'transformation_lock_retry', int( secret_flag_utils.get_secret_or_env('TRANSFORMATION_LOCK_RETRY', '300') ), '[optional|default] Amount of time in seconds that pipeline should wait ' 'before retrying image ingestion when an image cannot be ingested due to ' 'another instance of the pipleine holding an transformation lock.', ) OOF_INFERENCE_CONFIG_PATH_FLG = flags.DEFINE_string( 'oof_inference_config_path', secret_flag_utils.get_secret_or_env( ingest_const.EnvVarNames.OOF_INFERENCE_CONFIG_PATH, '' ), '[optional|default] Path to OOF inference config to be included in Pub/Sub ' 'messages generated at the end of ingestion to trigger inference pipeline.', ) OOF_LEGACY_INFERENCE_PIPELINE_FLG = flags.DEFINE_boolean( 'oof_legacy_inference_pipeline', secret_flag_utils.get_bool_secret_or_env( 'OOF_LEGACY_INFERENCE_PIPELINE', undefined_value=True, ), '[private|default,oof] Whether to use legacy OOF inference pipeline. Used ' 'both to trigger inference pipeline in default ingestion mode and process ' 'inference pipeline output in OOF ingestion mode.', ) # DICOM Metadata Schema flags REQUIRE_TYPE1_DICOM_TAG_METADATA_IS_DEFINED_FLG = flags.DEFINE_boolean( 'require_type1_dicom_tag_metadata_is_defined', secret_flag_utils.get_bool_secret_or_env( 'REQUIRE_TYPE1_DICOM_TAG_METADATA_IS_DEFINED' ), '[optional|default] Require all type one tags defined in the metadata' ' schema have defined values; if not raise' ' MissingRequiredMetadataValueError exception and fail ingestion.', ) CREATE_NULL_TYPE2C_DICOM_TAG_IF_METADATA_IS_UNDEFINED_FLG = flags.DEFINE_boolean( 'create_null_type2c_dicom_tag_if_metadata_if_undefined', secret_flag_utils.get_bool_secret_or_env( 'CREATE_NULL_TYPE2C_DICOM_TAG_IF_METADATA_IS_UNDEFINED' ), '[optional|default] Undefined mandatory type2 tags are always initalized to' ' None. Flag enables automatic initialization of undefined type2c DICOM ' ' tags to None.', ) METADATA_PRIMARY_KEY_COLUMN_NAME_FLG = flags.DEFINE_string( 'metadata_primary_key_column_name', secret_flag_utils.get_secret_or_env( 'METADATA_PRIMARY_KEY_COLUMN_NAME', 'Bar Code Value' ), '[optional|default] Defines column name used as primary key for joining ' 'candidate imaging with BigQuery or CSV metadata.', ) # Undefined Metadata default values DEFAULT_ICC_PROFILE_FLG = flags.DEFINE_string( 'default_iccprofile', get_value( env_var='DEFAULT_ICCPROFILE', default_value=ingest_const.ICCProfile.SRGB, ), '[optional|default] ICC Profile to embedd in wsi imaging that does not ' 'provide an ICCColor profile.', ) THIRD_PARTY_ICC_PROFILE_DICRECTORY_FLG = flags.DEFINE_string( 'third_party_icc_profile_directory', secret_flag_utils.get_secret_or_env( 'THIRD_PARTY_ICC_PROFILE_DIRECTORY', '' ), 'Directory that contains third party icc profiles.', ) WSI_DICOM_EXTENDED_DEPTH_OF_FIELD_DEFAULT_VALUE_FLG = flags.DEFINE_enum_class( 'wsi_dicom_extended_depth_of_field_default_value', get_value( env_var='WSI_DICOM_EXTENDED_DEPTH_OF_FIELD_DEFAULT_VALUE', default_value=WsiDicomExtendedDepthOfFieldDefault.NO.name, ), WsiDicomExtendedDepthOfFieldDefault, '[optional|default] Default metadata value for extended depth of field' ' DICOM tag metadata in VL Whole Slide Microscopy Images.', ) WSI_DICOM_FOCUS_METHOD_DEFAULT_VALUE_FLG = flags.DEFINE_enum_class( 'wsi_dicom_focus_method_default_value', get_value( env_var='WSI_DICOM_FOCUS_METHOD_DEFAULT_VALUE', default_value=WsiDicomFocusMethod.AUTO.name, ), WsiDicomFocusMethod, '[optional|default] Default metadata value for focus method DICOM tag' ' metadata in VL Whole Slide Microscopy Images.', ) WSI_DICOM_SLICE_THICKNESS_DEFAULT_VALUE_FLG = flags.DEFINE_float( 'wsi_dicom_slice_thickness_default_value', float( get_value( env_var='WSI_DICOM_SLICE_THICKNESS_DEFAULT_VALUE', default_value=12.0, ) ), '[optional|default] Default metadata value for slice thickness (micrometer)' ' DICOM tag metadata in VL Whole Slide Microscopy Images. ', ) # DICOM Store ingestion flags DICOM_STORE_INGEST_GCS_URI_FLG = flags.DEFINE_string( 'dicom_store_ingest_gcs_uri', secret_flag_utils.get_secret_or_env('DICOM_STORE_INGEST_GCS_URI', ''), '[optional|default] GCS URI for temporarily storing DICOM files when' ' ingesting from DICOM Store. Files are stored as backup before deletion' ' from DICOM Store.', ) # Openslide metadata flags ADD_OPENSLIDE_BACKGROUND_COLOR_METADATA_FLG = flags.DEFINE_boolean( 'add_openslide_background_color_metadata', secret_flag_utils.get_bool_secret_or_env( 'ADD_OPENSLIDE_BACKGROUND_COLOR_METADATA' ), '[optional|default] OpenSlide provides hooks to return WSI background color' ' however metadata retrieval and embedding is experimental and disabled by ' 'default. At time of writing none of the available openslide supported WSI ' 'imaging encoded this metadata.', ) ADD_OPENSLIDE_TOTAL_PIXEL_MATRIX_ORIGIN_SEQ_FLG = flags.DEFINE_boolean( 'add_openslide_total_pixel_matrix_origin_seq', secret_flag_utils.get_bool_secret_or_env( 'ADD_OPENSLIDE_TOTAL_PIXEL_MATRIX_ORIGIN_SEQ' ), '[optional|default] Openslide provides hooks to return the slide ' 'coordinates of the imaged region however metadata retrieval and embedding ' 'is experimental and disabled by default. At time of writing none of the ' 'available openslide supported WSI imaging encoded this metadata.', ) # WSI specific flags INGESTION_PYRAMID_LAYER_GENERATION_CONFIG_PATH_FLG = flags.DEFINE_string( 'ingestion_pyramid_layer_generation_config_path', secret_flag_utils.get_secret_or_env( 'INGESTION_PYRAMID_LAYER_GENERATION_CONFIG_PATH', '' ), '[optional|default] Path to *.YAML or *.JSON file which defines WSI' ' downsampling pyramid layers to generate.', ) WSI2DCM_DICOM_FRAME_HEIGHT_FLG = flags.DEFINE_integer( 'wsi2dcm_dicom_frame_height', secret_flag_utils.get_secret_or_env('WSI2DCM_DICOM_FRAME_HEIGHT', '256'), '[optional|default] wsi2dcm dicom frame height.', ) WSI2DCM_DICOM_FRAME_WIDTH_FLG = flags.DEFINE_integer( 'wsi2dcm_dicom_frame_width', secret_flag_utils.get_secret_or_env('WSI2DCM_DICOM_FRAME_WIDTH', '256'), '[optional|default] wsi2dcm dicom frame width.', ) WSI2DCM_COMPRESSION_FLG = flags.DEFINE_enum_class( 'wsi2dcm_compression', get_value( env_var='WSI2DCM_COMPRESSION', default_value=Wsi2DcmCompression.JPEG.name, ), Wsi2DcmCompression, '[optional|default] wsi2dcm compression param used across all levels; ' 'Can be overridden at highest magnification by using the ' '--first_level_compression flag.', ) WSI2DCM_FIRST_LEVEL_COMPRESSION_FLG = flags.DEFINE_enum_class( 'wsi2dcm_first_level_compression', get_value( env_var='WSI2DCM_FIRST_LEVEL_COMPRESSION', default_value=Wsi2DcmFirstLevelCompression.NONE.name, ), Wsi2DcmFirstLevelCompression, '[optional|default] wsi2dcm compression param to use at highest ' 'magnification level.', ) WSI2DCM_JPEG_COMPRESSION_QUALITY_FLG = flags.DEFINE_integer( 'wsi2dcm_jpeg_compression_quality', secret_flag_utils.get_secret_or_env( 'WSI2DCM_JPEG_COMPRESSION_QUALITY', '95' ), '[optional|default] wsi2dcm jpeg compression quality range 1 - 100.', ) WSI2DCM_JPEG_COMPRESSION_SUBSAMPLING_FLG = flags.DEFINE_enum_class( 'wsi2dcm_jpeg_compression_subsampling', get_value( env_var='WSI2DCM_JPEG_COMPRESSION_SUBSAMPLING', default_value=Wsi2DcmJpegCompressionSubsample.SUBSAMPLE_444.name, ), Wsi2DcmJpegCompressionSubsample, '[optional|default] wsi2dcm jpeg compression subsampling.', ) WSI2DCM_PIXEL_EQUIVALENT_TRANSFORM_FLG = flags.DEFINE_enum_class( 'wsi2dcm_pixel_equivalent_transform', get_value( env_var='WSI2DCM_PIXEL_EQUIVALENT_TRANSFORM', default_value=Wsi2DcmPixelEquivalentTransform.HIGHEST_MAGNIFICATION.name, ), Wsi2DcmPixelEquivalentTransform, '[optional|default] Defines input image magnifications that wsi2dcm will ' 'use to perform pixel equivalent transform on.', ) INIT_SERIES_INSTANCE_UID_FROM_METADATA_FLG = flags.DEFINE_boolean( 'init_series_instance_uid_from_metadata', secret_flag_utils.get_bool_secret_or_env( 'INIT_SERIES_INSTANCE_UID_FROM_METADATA' ), '[optional|default] Initialize series instance UID from metadata.' ' Recommended setting = False. If true disables auto-reingestion of rescans' ' into new series and correct handling of rescans would need to be handled' ' outside of DPAS ingestion.', ) # Flat image specific flags FLAT_IMAGES_VL_MICROSCOPIC_IMAGE_IOD_FLG = flags.DEFINE_boolean( 'flat_images_vl_microscopic_image_iod', secret_flag_utils.get_bool_secret_or_env( 'FLAT_IMAGES_VL_MICROSCOPIC_IMAGE_IOD' ), '[optional|default] Whether to use VL Microscopic Image IOD for ingestion' ' of flat images without slide coordinates. If unset, all images will use' ' VL Slide-Coordinates Microscopic Image IOD.', ) # DICOM Store URL flags DICOMWEB_URL_FLG = flags.DEFINE_string( 'dicomweb_url', secret_flag_utils.get_secret_or_env( ingest_const.EnvVarNames.DICOMWEB_URL, '' ), '[required|default,oof] DICOM Store to upload primary imaging into.', ) OOF_DICOMWEB_BASE_URL_FLG = flags.DEFINE_string( 'oof_dicomweb_base_url', secret_flag_utils.get_secret_or_env( ingest_const.EnvVarNames.OOF_DICOMWEB_BASE_URL, '' ), '[required|oof] DICOM Store to upload OOF imaging into.', ) DICOM_STORE_TO_CLEAN_FLG = flags.DEFINE_string( 'dicom_store_to_clean', secret_flag_utils.get_secret_or_env( ingest_const.EnvVarNames.DICOM_STORE_TO_CLEAN, '' ), '[optional|oof] DICOM Store to cleanup instances used for OOF pipeline' ' after it completes.', ) # Barcode flags ZXING_CLI_FLG = flags.DEFINE_string( 'zxing_cli', secret_flag_utils.get_secret_or_env('ZXING_CLI', '/zxing/cpp/build/zxing'), '[optional|default] Path to zxing command line tool.', ) DISABLE_CLOUD_VISION_BARCODE_SEG_FLG = flags.DEFINE_boolean( 'testing_disable_cloudvision', secret_flag_utils.get_bool_secret_or_env( 'DISABLE_CLOUD_VISION_BARCODE_SEG', not ( secret_flag_utils.get_bool_secret_or_env( 'ENABLE_CLOUD_VISION_BARCODE_SEGMENTATION', True ) ), ), '[private] Unit testing flag. Disables cloud vision.', ) DISABLE_BARCODE_DECODER_FLG = flags.DEFINE_boolean( 'disable_barcode_decoder', secret_flag_utils.get_bool_secret_or_env( 'DISABLE_BARCODE_DECODER', not ( secret_flag_utils.get_bool_secret_or_env( 'ENABLE_BARCODE_DECODER', True ) ), ), '[optional|default] Disable barcode decoder.', )