Importar y exportar datos de DICOM con Cloud Storage

En esta página, se explica cómo exportar instancias de DICOM y cómo importar objetos de DICOM desde Cloud Storage. Una instancia de DICOM suele ser una imagen, pero puede ser otro tipo de datos persistentes, como un informe estructurado. Un objeto de Cloud Storage es una instancia de DICOM que reside en Cloud Storage.

Puedes importar y exportar un enorme cantidad de datos entre un bucket de Cloud Storage y una tienda de DICOM. Por ejemplo, es posible que tengas muchos archivos de instancia de DICOM que quieras importar a una tienda de DICOM. En lugar de almacenar los datos de manera programática, almacena los datos en un bucket de Cloud Storage y, luego, importa los archivos a un almacén DICOM mediante una sola operación de importación. Para obtener más información, consulta Cloud Storage.

Para almacenar una instancia de DICOM directamente, como desde la máquina local, almacena los datos de DICOM mediante el servicio web de REST Transacción de almacenamiento como se implementó. en la API de Cloud Healthcare. Para recuperar una sola instancia o estudio de un almacén de DICOM, recupera datos de DICOM mediante el servicio web RESTful Transaction Fetch como se implementó. en la API de Cloud Healthcare.

Configura permisos de Cloud Storage

Antes de importar y exportar datos de DICOM desde y hacia Cloud Storage, debes otorgar permisos adicionales a la cuenta de servicio del agente de servicios de Cloud Healthcare. Para obtener más información, consulta Permisos de Cloud Storage de la tienda de DICOM.

Importa objetos de DICOM

En las siguientes muestras, se demuestra cómo importar objetos de DICOM desde un bucket de Cloud Storage.

Console

Para importar objetos de DICOM desde un bucket de Cloud Storage, completa los siguientes pasos:

  1. En Cloud Console, ve a la página Conjuntos de datos.
    Ir a la página Conjuntos de datos
  2. Haz clic en el conjunto de datos que contiene el almacén de DICOM al que deseas importar objetos de DICOM.
  3. En la lista de almacenes de datos, eligeImportación de laAcciones para el almacén de DICOM.

    LaImporta datos al almacén de DICOM.
  4. En la lista Proyecto, selecciona un proyecto de Cloud Storage.
  5. En la lista Ubicación, selecciona un depósito de Cloud Storage.
  6. Si deseas establecer una ubicación específica para importar archivos, haz lo siguiente:
    1. Expande Opciones avanzadas.
    2. Selecciona Anular ruta de Cloud Storage.
    3. Si quieres establecer una fuente específica para importar archivos, define la ruta con las siguientes variables en el cuadro de texto Location:
      • *: hace coincidir caracteres sin separadores.
      • **: hace coincidir caracteres, incluidos los separadores. Esto se puede usar con una extensión de nombre de archivo para que todos los archivos del mismo tipo coincidan.
      • ?: hace coincidir 1 carácter.
  7. Haz clic en Importar para importar objetos de DICOM desde la fuente definida.
  8. Para hacer un seguimiento del estado de la operación, haz clic en la pestaña Operaciones. Una vez que se completa la operación, aparecerán las siguientes indicaciones:
    • En la sección Estado de la operación de larga duración, hay una marca de verificación verde debajo del encabezado Aceptar.
    • La sección Descripción general tiene una marca de verificación verde y un indicador de aceptar en la misma fila que el ID de operación.
    Si encuentras algún error, haz clic en Acciones y, luego, en Ver detalles en Cloud Logging.

gcloud

Para importar objetos de DICOM desde un depósito de Cloud Storage, usa el comando gcloud healthcare dicom-stores import gcs. Especifica el nombre del conjunto de datos superior, el nombre de la tienda de DICOM y la ubicación del objeto en un bucket de Cloud Storage.

  • La ubicación de los archivos dentro del bucket es arbitraria y no necesita adherirse exactamente al formato especificado en el siguiente ejemplo.
  • Cuando especificas la ubicación de los objetos de DICOM en Cloud Storage, puedes usar comodines para importar varios archivos desde uno o más directorios. Se admiten los siguientes comodines:
    • Usa * para hacer coincidir 0 o más caracteres sin separadores. Por ejemplo, gs://BUCKET/DIRECTORY/Example*.dcm hace coincidir Example.dcm y Example22.dcm en DIRECTORY.
    • Usa ** para hacer coincidir 0 o más caracteres (con separadores). Se debe usar al final de una ruta y no debe haber otros comodines en la ruta. También se puede usar con una extensión de nombre de archivo (como .dcm), que importa todos los archivos con la extensión de nombre de archivo en el directorio especificado y en sus subdirectorios. Por ejemplo, gs://BUCKET/DIRECTORY/**.dcm importa todos los archivos con la extensión de nombre de archivo .dcm en DIRECTORY y en sus subdirectorios.
    • Usa ? para hacer coincidir 1 carácter. Por ejemplo, gs://BUCKET/DIRECTORY/Example?.dcm hace coincidir Example1.dcm, pero no Example.dcm ni Example01.dcm.

En la siguiente muestra, se demuestra cómo importar objetos de DICOM desde un bucket de Cloud Storage.

gcloud healthcare dicom-stores import gcs DICOM_STORE_ID \
  --dataset=DATASET_ID \
  --location=LOCATION \
  --gcs-uri=gs://BUCKET/DIRECTORY/DICOM_INSTANCE.dcm

La línea de comandos muestra el ID de la operación:

name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID

Para ver el estado de la operación, ejecuta el comando gcloud healthcare operations describe y proporciona OPERATION_ID a partir de la respuesta:

gcloud healthcare operations describe OPERATION_ID \
  --location=LOCATION \
  --dataset=DATASET_ID

Una vez que se completa el comando, se incluirá done: true en la respuesta.

done: true
metadata:
'@type': type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata
apiMethodName: google.cloud.healthcare.v1.dicom.DicomService.ImportDicomData
counter:
  success: SUCCESSFUL_INSTANCES
  failure: FAILED_INSTANCES
createTime: "CREATE_TIME"
endTime: "END_TIME"
name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID
response:
'@type': "..."

API

Para importar objetos de DICOM desde un depósito de Cloud Storage, usa el método projects.locations.datasets.dicomStores.import.

  • La ubicación de los archivos dentro del bucket es arbitraria y no necesita adherirse exactamente al formato especificado en los siguientes ejemplos.
  • Cuando especifiques la ubicación de los objetos DICOM en Cloud Storage, usa comodines para importar varios archivos desde uno o más directorios. Se admiten los siguientes comodines:
    • Usa * para hacer coincidir 0 o más caracteres sin separadores. Por ejemplo, gs://BUCKET/DIRECTORY/Example*.dcm hace coincidir Example.dcm y Example22.dcm en DIRECTORY.
    • Usa ** para hacer coincidir 0 o más caracteres (con separadores). Se debe usar al final de una ruta y no debe haber otros comodines en la ruta. También se puede usar con una extensión de nombre de archivo (como .dcm), que importa todos los archivos con la extensión de nombre de archivo en el directorio especificado y en sus subdirectorios. Por ejemplo, gs://BUCKET/DIRECTORY/**.dcm importa todos los archivos con la extensión de nombre de archivo .dcm en DIRECTORY y en sus subdirectorios.
    • Usa ? para hacer coincidir 1 carácter. Por ejemplo, gs://BUCKET/DIRECTORY/Example?.dcm hace coincidir Example1.dcm, pero no Example.dcm ni Example01.dcm.

curl

Para importar objetos DICOM, haz una solicitud POST y proporciona la siguiente información:

  • El nombre y la ubicación del conjunto de datos superior
  • El nombre del almacén de DICOM
  • La ubicación de los objetos en un bucket de Cloud Storage

En el siguiente ejemplo, se muestra una solicitud POST mediante curl.

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    --data "{
      'gcsSource': {
        'uri': 'gs://BUCKET/*.dcm'
      }
    }" "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:import"

Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

La respuesta contiene un nombre de operación. Para realizar un seguimiento del estado de la operación, usa el método get de operación:

curl -X GET \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

Si la solicitud es exitosa, el servidor mostrará una respuesta con el estado de la operación en formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1.dicom.DicomService.ImportDicomData",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/viewer/CLOUD_LOGGING_URL",
    "counter": {
       "success": SUCCESSFUL_INSTANCES
       "failure": FAILED_INSTANCES
    },
  },
  "done": true,
  "response": {
    "@type": "..."
  }
}

PowerShell

Para importar objetos DICOM, haz una solicitud POST y proporciona la siguiente información:

  • El nombre y la ubicación del conjunto de datos superior
  • El nombre del almacén de DICOM
  • La ubicación de los objetos en un bucket de Cloud Storage

En el siguiente ejemplo, se muestra una solicitud POST mediante Windows PowerShell.

$cred = gcloud auth application-default print-access-token
$headers = @{ Authorization = "Bearer $cred" }

Invoke-WebRequest `
  -Method Post `
  -Headers $headers `
  -ContentType: "application/json; charset=utf-8" `
  -Body "{
    'gcsSource': {
      'uri': 'gs://BUCKET/*.dcm'
    }
  }" `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:import" | Select-Object -Expand Content

Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

La respuesta contiene un nombre de operación. Para realizar un seguimiento del estado de la operación, usa el método get de operación:

$cred = gcloud auth application-default print-access-token
$headers = @{ Authorization = "Bearer $cred" }

Invoke-WebRequest `
  -Method Get `
  -Headers $headers `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID" | Select-Object -Expand Content

Si la solicitud es exitosa, el servidor mostrará una respuesta con el estado de la operación en formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1.dicom.DicomService.ImportDicomData",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/viewer/CLOUD_LOGGING_URL",
    "counter":{
       "success": SUCCESSFUL_INSTANCES
       "failure": FAILED_INSTANCES
    }
  },
  "done": true,
  "response": {
    "@type": "..."
  }
}

Comienza a usarlo

import (
	"context"
	"fmt"
	"io"

	healthcare "google.golang.org/api/healthcare/v1"
)

// importDICOMInstance imports DICOM objects from GCS.
func importDICOMInstance(w io.Writer, projectID, location, datasetID, dicomStoreID, contentURI string) error {
	ctx := context.Background()

	healthcareService, err := healthcare.NewService(ctx)
	if err != nil {
		return fmt.Errorf("healthcare.NewService: %v", err)
	}

	storesService := healthcareService.Projects.Locations.Datasets.DicomStores

	req := &healthcare.ImportDicomDataRequest{
		GcsSource: &healthcare.GoogleCloudHealthcareV1DicomGcsSource{
			Uri: contentURI,
		},
	}
	name := fmt.Sprintf("projects/%s/locations/%s/datasets/%s/dicomStores/%s", projectID, location, datasetID, dicomStoreID)

	lro, err := storesService.Import(name, req).Do()
	if err != nil {
		return fmt.Errorf("Import: %v", err)
	}

	fmt.Fprintf(w, "Import to DICOM store started. Operation: %q\n", lro.Name)
	return nil
}

Java

import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.healthcare.v1.CloudHealthcare;
import com.google.api.services.healthcare.v1.CloudHealthcare.Projects.Locations.Datasets.DicomStores;
import com.google.api.services.healthcare.v1.CloudHealthcareScopes;
import com.google.api.services.healthcare.v1.model.GoogleCloudHealthcareV1DicomGcsSource;
import com.google.api.services.healthcare.v1.model.ImportDicomDataRequest;
import com.google.api.services.healthcare.v1.model.Operation;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Collections;

public class DicomStoreImport {
  private static final String DICOM_NAME = "projects/%s/locations/%s/datasets/%s/dicomStores/%s";
  private static final JsonFactory JSON_FACTORY = new JacksonFactory();
  private static final NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();

  public static void dicomStoreImport(String dicomStoreName, String gcsUri) throws IOException {
    // String dicomStoreName =
    //    String.format(
    //        DICOM_NAME, "your-project-id", "your-region-id", "your-dataset-id", "your-dicom-id");
    // String gcsUri = "gs://your-bucket-id/path/to/destination/dir"

    // Initialize the client, which will be used to interact with the service.
    CloudHealthcare client = createClient();

    // Configure where the store should be imported from.
    GoogleCloudHealthcareV1DicomGcsSource gcsSource =
        new GoogleCloudHealthcareV1DicomGcsSource().setUri(gcsUri);
    ImportDicomDataRequest importRequest = new ImportDicomDataRequest().setGcsSource(gcsSource);

    // Create request and configure any parameters.
    DicomStores.CloudHealthcareImport request =
        client
            .projects()
            .locations()
            .datasets()
            .dicomStores()
            .healthcareImport(dicomStoreName, importRequest);

    // Execute the request, wait for the operation to complete, and process the results.
    try {
      Operation operation = request.execute();
      while (operation.getDone() == null || !operation.getDone()) {
        // Update the status of the operation with another request.
        Thread.sleep(500); // Pause for 500ms between requests.
        operation =
            client
                .projects()
                .locations()
                .datasets()
                .operations()
                .get(operation.getName())
                .execute();
      }
      System.out.println("DICOM store import complete." + operation.getResponse());
    } catch (Exception ex) {
      System.out.printf("Error during request execution: %s", ex.toString());
      ex.printStackTrace(System.out);
    }
  }

  private static CloudHealthcare createClient() throws IOException {
    // Use Application Default Credentials (ADC) to authenticate the requests
    // For more information see https://cloud.google.com/docs/authentication/production
    GoogleCredentials credential =
        GoogleCredentials.getApplicationDefault()
            .createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));

    // Create a HttpRequestInitializer, which will provide a baseline configuration to all requests.
    HttpRequestInitializer requestInitializer =
        request -> {
          new HttpCredentialsAdapter(credential).initialize(request);
          request.setConnectTimeout(60000); // 1 minute connect timeout
          request.setReadTimeout(60000); // 1 minute read timeout
        };

    // Build the client for interacting with the service.
    return new CloudHealthcare.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer)
        .setApplicationName("your-application-name")
        .build();
  }
}

Node.js

const google = require('@googleapis/healthcare');
const healthcare = google.healthcare({
  version: 'v1',
  auth: new google.auth.GoogleAuth({
    scopes: ['https://www.googleapis.com/auth/cloud-platform'],
  }),
});
const sleep = ms => {
  return new Promise(resolve => setTimeout(resolve, ms));
};

const importDicomInstance = async () => {
  // TODO(developer): uncomment these lines before running the sample
  // const cloudRegion = 'us-central1';
  // const projectId = 'adjective-noun-123';
  // const datasetId = 'my-dataset';
  // const dicomStoreId = 'my-dicom-store';
  // const gcsUri = 'my-bucket/my-directory/*.dcm'
  const name = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/dicomStores/${dicomStoreId}`;
  const request = {
    name,
    resource: {
      // The location of the DICOM instances in Cloud Storage
      gcsSource: {
        uri: `gs://${gcsUri}`,
      },
    },
  };

  const operation =
    await healthcare.projects.locations.datasets.dicomStores.import(request);
  const operationName = operation.data.name;

  const operationRequest = {name: operationName};

  // Wait fifteen seconds for the LRO to finish.
  await sleep(15000);

  // Check the LRO's status
  const operationStatus =
    await healthcare.projects.locations.datasets.operations.get(
      operationRequest
    );

  const {data} = operationStatus;

  if (data.error === undefined) {
    console.log('Successfully imported DICOM instances');
  } else {
    console.log('Encountered errors. Sample error:');
    console.log(
      'Resource on which error occured:',
      data.error.details[0]['sampleErrors'][0]['resource']
    );
    console.log(
      'Error code:',
      data.error.details[0]['sampleErrors'][0]['error']['code']
    );
    console.log(
      'Error message:',
      data.error.details[0]['sampleErrors'][0]['error']['message']
    );
  }
};

importDicomInstance();

Python

def import_dicom_instance(
    project_id, location, dataset_id, dicom_store_id, content_uri
):
    """Imports data into the DICOM store by copying it from the specified
    source.

    See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/healthcare/api-client/v1/dicom
    before running the sample."""
    # Imports the Google API Discovery Service.
    from googleapiclient import discovery

    api_version = "v1"
    service_name = "healthcare"
    # Returns an authorized API client by discovering the Healthcare API
    # and using GOOGLE_APPLICATION_CREDENTIALS environment variable.
    client = discovery.build(service_name, api_version)

    # TODO(developer): Uncomment these lines and replace with your values.
    # project_id = 'my-project'  # replace with your GCP project ID
    # location = 'us-central1'  # replace with the parent dataset's location
    # dataset_id = 'my-dataset'  # replace with the DICOM store's parent dataset ID
    # dicom_store_id = 'my-dicom-store'  # replace with the DICOM store's ID
    # content_uri = 'my-bucket/*.dcm'  # replace with a Cloud Storage bucket and DCM files
    dicom_store_parent = "projects/{}/locations/{}/datasets/{}".format(
        project_id, location, dataset_id
    )
    dicom_store_name = "{}/dicomStores/{}".format(dicom_store_parent, dicom_store_id)

    body = {"gcsSource": {"uri": "gs://{}".format(content_uri)}}

    # Escape "import()" method keyword because "import"
    # is a reserved keyword in Python
    request = (
        client.projects()
        .locations()
        .datasets()
        .dicomStores()
        .import_(name=dicom_store_name, body=body)
    )

    response = request.execute()
    print("Imported DICOM instance: {}".format(content_uri))

    return response

Soluciona problemas de solicitudes de importación de DICOM

Si se producen errores durante una solicitud de importación de DICOM, estos se registrarán en Cloud Logging. Para obtener más información, consulta Visualiza los registros de errores en Cloud Logging.

Exporta instancias de DICOM

En las siguientes muestras, se demuestra cómo exportar instancias de DICOM a un bucket de Cloud Storage. Cuando exportas instancias de DICOM desde una tienda de DICOM, se exportarán todas las instancias de la tienda.

Console

Para exportar instancias de DICOM a Cloud Storage, completa los siguientes pasos:

  1. En Cloud Console, ve a la página Conjuntos de datos.
    Ir a la página Conjuntos de datos
  2. Haz clic en el conjunto de datos que contiene el almacén DICOM desde el que exportas las instancias de DICOM.
  3. En la lista de almacenes de datos, elige Exportar en la lista Acciones del almacén DICOM.
  4. En la página Exportar almacén de DICOM que aparece, selecciona Bucket de Google Cloud Storage.
  5. En la lista Proyecto, selecciona un proyecto de Cloud Storage.
  6. En la lista Ubicación, selecciona un depósito de Cloud Storage.
  7. En Configuración de exportación de DICOM, selecciona el tipo de archivo que se usa para exportar las instancias de DICOM. Están disponibles los siguientes tipos:
    • Archivo de DICOM (.dcm)
    • octet-stream
    • Imagen (.jpg, .png)
  8. Para definir la sintaxis de transferencia adicional, elige la sintaxis de la lista Sintaxis de transferencia.
  9. Haz clic en Exportar para exportar instancias de DICOM a la ubicación definida en Cloud Storage.
  10. Para hacer un seguimiento del estado de la operación, haz clic en la pestaña Operaciones. Una vez que se completa la operación, aparecerán las siguientes indicaciones:
    • En la sección Estado de la operación de larga duración, hay una marca de verificación verde debajo del encabezado Aceptar.
    • La sección Descripción general tiene una marca de verificación verde y un indicador de aceptar en la misma fila que el ID de operación.
    Si encuentras algún error, haz clic en Acciones y, luego, en Ver detalles en Cloud Logging.

gcloud

Para exportar instancias de DICOM a un depósito de Cloud Storage, usa el comando gcloud healthcare dicom-stores export gcs.

  • Proporciona el nombre del conjunto de datos superior, el nombre de la tienda de DICOM y el bucket de Cloud Storage de destino.
  • Escribe en un depósito o un directorio de Cloud Storage, en lugar de en un objeto, ya que la API de Cloud Healthcare crea un archivo .dcm para cada objeto.
  • Si el comando especifica un directorio que no existe, este se creará.

En el siguiente ejemplo, se muestra el comando gcloud healthcare dicom-stores export gcs.

gcloud healthcare dicom-stores export gcs DICOM_STORE_ID \
  --dataset=DATASET_ID \
  --location=LOCATION \
  --gcs-uri-prefix=gs://BUCKET/DIRECTORY

La línea de comandos muestra el ID de la operación:

name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID

Para ver el estado de la operación, ejecuta el comando gcloud healthcare operations describe y proporciona OPERATION_ID a partir de la respuesta:

gcloud healthcare operations describe OPERATION_ID \
  --location=LOCATION \
  --dataset=DATASET_ID

Una vez que se completa el comando, se incluirá done: true en la respuesta.

done: true
metadata:
'@type': type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata
apiMethodName: google.cloud.healthcare.v1.dicom.DicomService.ExportDicomData
counter:
  success: SUCCESSFUL_INSTANCES
  failure: FAILED_INSTANCES
createTime: "CREATE_TIME"
endTime: "END_TIME"
name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID
response:
'@type': "..."

API

Para exportar instancias de DICOM a un depósito de Cloud Storage, usa el método projects.locations.datasets.dicomStores.export.

  • Escribe en un depósito o un directorio de Cloud Storage, en lugar de en un objeto, ya que la API de Cloud Healthcare crea un archivo .dcm para cada objeto de DICOM.
  • Si el comando especifica un directorio que no existe, este se creará.

curl

Para exportar instancias de DICOM, realiza una solicitud POST y proporciona la siguiente información:

  • El nombre y la ubicación del conjunto de datos superior
  • El nombre del almacén de DICOM
  • El bucket de destino de Cloud Storage

En el siguiente ejemplo, se muestra una solicitud POST mediante curl.

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    --data "{
      'gcsDestination': {
        'uriPrefix': 'gs://BUCKET/DIRECTORY'
      }
    }" "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:export"

Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

La respuesta contiene un nombre de operación. Para realizar un seguimiento del estado de la operación, usa el método get de operación:

curl -X GET \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

Si la solicitud es exitosa, el servidor mostrará una respuesta con el estado de la operación en formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1.dicom.DicomService.ExportDicomData",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/viewer/CLOUD_LOGGING_URL",
    "counter":{
       "success": SUCCESSFUL_INSTANCES
       "failure": FAILED_INSTANCES
    }
  },
  "done": true,
  "response": {
    "@type": "..."
  }
}

PowerShell

Para exportar instancias de DICOM, realiza una solicitud POST y proporciona la siguiente información:

  • El nombre y la ubicación del conjunto de datos superior
  • El nombre del almacén de DICOM
  • El bucket de destino de Cloud Storage

En el siguiente ejemplo, se muestra una solicitud POST mediante Windows PowerShell.

$cred = gcloud auth application-default print-access-token
$headers = @{ Authorization = "Bearer $cred" }

Invoke-WebRequest `
  -Method Post `
  -Headers $headers `
  -ContentType: "application/json; charset=utf-8" `
  -Body "{
    'gcsDestination': {
      'uriPrefix': 'gs://BUCKET/DIRECTORY'
    }
  }" `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:export" | Select-Object -Expand Content

Si la solicitud tiene éxito, se mostrará la respuesta en formato JSON en el servidor:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

La respuesta contiene un nombre de operación. Para realizar un seguimiento del estado de la operación, usa el método get de operación:

$cred = gcloud auth application-default print-access-token
$headers = @{ Authorization = "Bearer $cred" }

Invoke-WebRequest `
  -Method Get `
  -Headers $headers `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID" | Select-Object -Expand Content

Si la solicitud es exitosa, el servidor mostrará una respuesta con el estado de la operación en formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1.dicom.DicomService.ExportDicomData",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/viewer/CLOUD_LOGGING_URL",
    "counter":{
       "success": SUCCESSFUL_INSTANCES
       "failure": FAILED_INSTANCES
    },
  },
  "done": true,
  "response": {
    "@type": "..."
  }
}

Go

import (
	"context"
	"fmt"
	"io"

	healthcare "google.golang.org/api/healthcare/v1"
)

// exportDICOMInstance exports DICOM objects to GCS.
func exportDICOMInstance(w io.Writer, projectID, location, datasetID, dicomStoreID, destination string) error {
	ctx := context.Background()

	healthcareService, err := healthcare.NewService(ctx)
	if err != nil {
		return fmt.Errorf("healthcare.NewService: %v", err)
	}

	storesService := healthcareService.Projects.Locations.Datasets.DicomStores

	req := &healthcare.ExportDicomDataRequest{
		GcsDestination: &healthcare.GoogleCloudHealthcareV1DicomGcsDestination{
			UriPrefix: destination, // "gs://my-bucket/path/to/prefix/"
		},
	}
	name := fmt.Sprintf("projects/%s/locations/%s/datasets/%s/dicomStores/%s", projectID, location, datasetID, dicomStoreID)

	lro, err := storesService.Export(name, req).Do()
	if err != nil {
		return fmt.Errorf("Export: %v", err)
	}

	fmt.Fprintf(w, "Export to DICOM store started. Operation: %q\n", lro.Name)
	return nil
}

Java

import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.healthcare.v1.CloudHealthcare;
import com.google.api.services.healthcare.v1.CloudHealthcare.Projects.Locations.Datasets.DicomStores;
import com.google.api.services.healthcare.v1.CloudHealthcareScopes;
import com.google.api.services.healthcare.v1.model.ExportDicomDataRequest;
import com.google.api.services.healthcare.v1.model.GoogleCloudHealthcareV1DicomGcsDestination;
import com.google.api.services.healthcare.v1.model.Operation;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Collections;

public class DicomStoreExport {
  private static final String DICOM_NAME = "projects/%s/locations/%s/datasets/%s/dicomStores/%s";
  private static final JsonFactory JSON_FACTORY = new JacksonFactory();
  private static final NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();

  public static void dicomStoreExport(String dicomStoreName, String gcsUri) throws IOException {
    // String dicomStoreName =
    //    String.format(
    //        DICOM_NAME, "your-project-id", "your-region-id", "your-dataset-id", "your-dicom-id");
    // String gcsUri = "gs://your-bucket-id/path/to/destination/dir"

    // Initialize the client, which will be used to interact with the service.
    CloudHealthcare client = createClient();

    // Configure where the store will be exported too.
    GoogleCloudHealthcareV1DicomGcsDestination gcsDestination =
        new GoogleCloudHealthcareV1DicomGcsDestination().setUriPrefix(gcsUri);
    ExportDicomDataRequest exportRequest =
        new ExportDicomDataRequest().setGcsDestination(gcsDestination);

    // Create request and configure any parameters.
    DicomStores.Export request =
        client
            .projects()
            .locations()
            .datasets()
            .dicomStores()
            .export(dicomStoreName, exportRequest);

    // Execute the request, wait for the operation to complete, and process the results.
    try {
      Operation operation = request.execute();
      while (operation.getDone() == null || !operation.getDone()) {
        // Update the status of the operation with another request.
        Thread.sleep(500); // Pause for 500ms between requests.
        operation =
            client
                .projects()
                .locations()
                .datasets()
                .operations()
                .get(operation.getName())
                .execute();
      }
      System.out.println("DICOM store export complete." + operation.getResponse());
    } catch (Exception ex) {
      System.out.printf("Error during request execution: %s", ex.toString());
      ex.printStackTrace(System.out);
    }
  }

  private static CloudHealthcare createClient() throws IOException {
    // Use Application Default Credentials (ADC) to authenticate the requests
    // For more information see https://cloud.google.com/docs/authentication/production
    GoogleCredentials credential =
        GoogleCredentials.getApplicationDefault()
            .createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));

    // Create a HttpRequestInitializer, which will provide a baseline configuration to all requests.
    HttpRequestInitializer requestInitializer =
        request -> {
          new HttpCredentialsAdapter(credential).initialize(request);
          request.setConnectTimeout(60000); // 1 minute connect timeout
          request.setReadTimeout(60000); // 1 minute read timeout
        };

    // Build the client for interacting with the service.
    return new CloudHealthcare.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer)
        .setApplicationName("your-application-name")
        .build();
  }
}

Node.js

const google = require('@googleapis/healthcare');
const healthcare = google.healthcare({
  version: 'v1',
  auth: new google.auth.GoogleAuth({
    scopes: ['https://www.googleapis.com/auth/cloud-platform'],
  }),
});

const exportDicomInstanceGcs = async () => {
  // TODO(developer): uncomment these lines before running the sample
  // const cloudRegion = 'us-central1';
  // const projectId = 'adjective-noun-123';
  // const datasetId = 'my-dataset';
  // const dicomStoreId = 'my-dicom-store';
  // const gcsUri = 'my-bucket/my-directory'
  const name = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/dicomStores/${dicomStoreId}`;
  const request = {
    name,
    resource: {
      gcsDestination: {
        // The destination location of the DICOM instances in Cloud Storage
        uriPrefix: `gs://${gcsUri}`,
        // The format to use for the output files, per the MIME types supported in the DICOM spec
        mimeType: 'application/dicom',
      },
    },
  };

  await healthcare.projects.locations.datasets.dicomStores.export(request);
  console.log(`Exported DICOM instances to ${gcsUri}`);
};

exportDicomInstanceGcs();

Python

def export_dicom_instance(project_id, location, dataset_id, dicom_store_id, uri_prefix):
    """Export data to a Google Cloud Storage bucket by copying
    it from the DICOM store.

    See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/healthcare/api-client/v1/dicom
    before running the sample."""
    # Imports the Google API Discovery Service.
    from googleapiclient import discovery

    api_version = "v1"
    service_name = "healthcare"
    # Returns an authorized API client by discovering the Healthcare API
    # and using GOOGLE_APPLICATION_CREDENTIALS environment variable.
    client = discovery.build(service_name, api_version)

    # TODO(developer): Uncomment these lines and replace with your values.
    # project_id = 'my-project'  # replace with your GCP project ID
    # location = 'us-central1'  # replace with the parent dataset's location
    # dataset_id = 'my-dataset'  # replace with the DICOM store's parent dataset ID
    # dicom_store_id = 'my-dicom-store'  # replace with the DICOM store's ID
    # uri_prefix = 'my-bucket'  # replace with a Cloud Storage bucket
    dicom_store_parent = "projects/{}/locations/{}/datasets/{}".format(
        project_id, location, dataset_id
    )
    dicom_store_name = "{}/dicomStores/{}".format(dicom_store_parent, dicom_store_id)

    body = {"gcsDestination": {"uriPrefix": "gs://{}".format(uri_prefix)}}

    request = (
        client.projects()
        .locations()
        .datasets()
        .dicomStores()
        .export(name=dicom_store_name, body=body)
    )

    response = request.execute()
    print("Exported DICOM instances to bucket: gs://{}".format(uri_prefix))

    return response

Exporta instancias de DICOM mediante filtros

De forma predeterminada, cuando exportas archivos de DICOM a Cloud Storage, se exportan todos los archivos DICOM del almacén de DICOM especificado. Del mismo modo, cuando exportas metadatos de DICOM a BigQuery, se exportan los metadatos para todos los datos de DICOM en el almacén DICOM.

Puedes exportar un subconjunto de datos o metadatos de DICOM mediante un filtro. Debes definir el filtro en un archivo de filtro.

Configura archivos de filtro

Un archivo de filtro define qué archivos DICOM se exportarán a Cloud Storage o BigQuery. Puedes configurar archivos de filtro en los siguientes niveles:

  • A nivel del estudio
  • En el nivel de la serie
  • En el nivel de la instancia

El archivo de filtro consta de varias líneas y cada una de ellas define el estudio, la serie o la instancia que deseas exportar. Cada línea usa el formato /studies/STUDY_UID[/series/SERIES_UID[/instances/INSTANCE_UID]].

Si no se especifica un estudio, una serie o una instancia en el archivo de filtro cuando pasas el archivo de filtro, ese estudio, serie o instancia no se exportarán.

Solo se requiere la parte /studies/STUDY_UID de la ruta de acceso. Puedes exportar un estudio completo si especificas /studies/STUDY_UID o puedes exportar una serie completa si especificas /studies/STUDY_UID/series/SERIES_UID.

Considera el siguiente archivo de filtro. El archivo de filtro tendrá como resultado la exportación de un estudio, dos series y tres instancias individuales:

/studies/1.123.456.789
/studies/1.666.333.111/series/123.456
/studies/1.666.333.111/series/567.890
/studies/1.888.999.222/series/123.456/instances/111
/studies/1.888.999.222/series/123.456/instances/222
/studies/1.888.999.222/series/123.456/instances/333

Crea un archivo de filtro con BigQuery

Por lo general, para crear un archivo de filtro, primero debes exportar los metadatos de un almacén DICOM a BigQuery. Esto te permite usar BigQuery para ver los UID del estudio, serie y de las instancias de los datos de DICOM en tu almacén de DICOM. Luego, puedes completar los siguientes pasos:

  1. Realiza consultas para los UID del estudio, la serie y la instancia que te interesa. Por ejemplo, después de exportar metadatos de DICOM a BigQuery, puedes ejecutar la siguiente consulta para concatenar los UID de estudio, serie y instancia a un formato compatible con los requisitos de archivos de filtro:
    SELECT CONCAT
        ('/studies/', StudyInstanceUID, '/series/', SeriesInstanceUID, '/instances/', SOPInstanceUID)
    FROM
        [PROJECT_ID:BIGQUERY_DATASET.BIGQUERY_TABLE]
    
  2. Si la consulta muestra un conjunto de resultados grande, puedes materializar una tabla nueva si guardas los resultados de las consultas en una tabla de destino en BigQuery.
  3. Si guardaste los resultados de la consulta en una tabla de destino, puedes guardar los contenidos de la tabla de destino en un archivo y exportarlo a Cloud Storage. Si quieres obtener los pasos para hacerlo, consulta Exporta datos de tablas. El archivo exportado es tu archivo de filtro. Usa la ubicación del archivo de filtro en Cloud Storage cuando especifiques el filtro en la operación de exportación.

Crea un archivo de filtro de forma manual

Puedes crear un archivo de filtro con contenido personalizado y subirlo a un depósito de Cloud Storage. Usa la ubicación del archivo de filtro en Cloud Storage cuando especifiques el filtro en la operación de exportación. En el siguiente ejemplo, se muestra cómo subir un archivo de filtro a un depósito de Cloud Storage con el comando gsutil cp:
gsutil cp PATH/TO/FILTER_FILE gs://BUCKET/DIRECTORY

Pasa el archivo de filtro

Después de crear un archivo de filtro, llama a la operación de exportación de DICOM y pasa el archivo de filtro mediante la API de REST. En los siguientes ejemplos, se muestra cómo exportar datos de DICOM mediante un filtro.

gcloud

Para exportar metadatos de DICOM a Cloud Storage mediante un filtro, usa el comando gcloud beta healthcare dicom-stores export gcs:

gcloud beta healthcare dicom-stores export gcs DICOM_STORE_ID \
  --dataset=DATASET_ID \
  --location=LOCATION \
  --gcs-uri-prefix=gs://DESTINATION_BUCKET/DIRECTORY \
  --filter-config-gcs-uri=gs://BUCKET/DIRECTORY/FILTER_FILE

Reemplaza lo siguiente:

  • DICOM_STORE_ID: El identificador del almacén DICOM
  • DATASET_ID: Es el nombre del conjunto de datos superior del almacén de DICOM.
  • LOCATION: Es la ubicación del conjunto de datos superior del almacén de DICOM.
  • DESTINATION_BUCKET/DIRECTORY: el bucket de destino de Cloud Storage
  • BUCKET/DIRECTORY/FILTER_FILE: Es la ubicación del archivo de filtro en un depósito de Cloud Storage.

Este es el resultado:

Request issued for: [DICOM_STORE_ID]
Waiting for operation [projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID] to complete...done.
name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID

Para ver el estado de la operación, ejecuta el comando gcloud healthcare operations describe y proporciona OPERATION_ID a partir de la respuesta:

gcloud healthcare operations describe OPERATION_ID \
  --location=LOCATION \
  --dataset=DATASET_ID

Reemplaza lo siguiente:

  • OPERATION_ID: El número de ID que se muestra en la respuesta anterior
  • DATASET_ID: Es el nombre del conjunto de datos superior del almacén de DICOM.
  • LOCATION: Es la ubicación del conjunto de datos superior del almacén de DICOM.

Este es el resultado:

done: true
metadata:
'@type': type.googleapis.com/google.cloud.healthcare.v1beta1.OperationMetadata
apiMethodName: google.cloud.healthcare.v1beta1.dicom.DicomService.ExportDicomData
counter:
  success: SUCCESSFUL_INSTANCES
  failure: FAILED_INSTANCES
createTime: 'CREATE_TIME'
endTime: 'END_TIME'
logsUrl: 'https://console.cloud.google.com/logs/viewer/CLOUD_LOGGING_URL'
name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID
response:
'@type': '...'

API

Para exportar datos de DICOM mediante un filtro, usa el método projects.locations.datasets.dicomStores.export.

curl

Para exportar datos de DICOM mediante un archivo de filtro, realiza una solicitud POST y proporciona la siguiente información:

  • El nombre y la ubicación del conjunto de datos superior
  • El nombre del almacén de DICOM
  • El bucket de destino de Cloud Storage
  • La ubicación del archivo de filtro en un bucket de Cloud Storage

En el siguiente ejemplo, se muestra una solicitud POST mediante curl.

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    --data "{
      'gcsDestination': {
        'uriPrefix': 'gs://BUCKET/DIRECTORY'
      },
      'filterConfig': {
        'resourcePathsGcsUri': 'gs://BUCKET/DIRECTORY/FILTER_FILE'
      }
    }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:export"

Si la solicitud tiene éxito, se mostrará la siguiente respuesta en formato JSON en el servidor:

{
  "name": "projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/operations/OPERATION_ID"
}

La respuesta contiene un nombre de operación. Usa el método get de operación para realizar un seguimiento del estado de la operación:

curl -X GET \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/operations/OPERATION_NAME"

Si la solicitud se realiza de forma correcta, el servidor muestra la siguiente respuesta en formato JSON:

{
  "name": "projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1beta1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1beta1.dicom.DicomService.ExportDicomData",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME"
  },
  "done": true,
  "response": {
    "@type": "..."
  }
}

PowerShell

Para exportar datos de DICOM mediante un archivo de filtro, realiza una solicitud POST y proporciona la siguiente información:

  • El nombre y la ubicación del conjunto de datos superior
  • El nombre del almacén de DICOM
  • El bucket de destino de Cloud Storage
  • La ubicación del archivo de filtro en un bucket de Cloud Storage

En el siguiente ejemplo, se muestra una solicitud POST mediante Windows PowerShell.

$cred = gcloud auth application-default print-access-token
$headers = @{ Authorization = "Bearer $cred" }

Invoke-WebRequest `
  -Method Post `
  -Headers $headers `
  -ContentType: "application/json; charset=utf-8" `
  -Body "{
    'gcsDestination': {
      'uriPrefix': 'gs://BUCKET/DIRECTORY'
    },
    'filterConfig': {
      'resourcePathsGcsUri': 'gs://BUCKET/DIRECTORY/FILTER_FILE'
  }" `
  -Uri "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID:export" | Select-Object -Expand Content

Si la solicitud tiene éxito, se mostrará la siguiente respuesta en formato JSON en el servidor:

{
  "name": "projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/operations/OPERATION_ID"
}

La respuesta contiene un nombre de operación. Usa el método get de operación para realizar un seguimiento del estado de la operación:

$cred = gcloud auth application-default print-access-token
$headers = @{ Authorization = "Bearer $cred" }

Invoke-WebRequest `
  -Method Get `
  -Headers $headers `
  -Uri "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/operations/OPERATION_NAME" | Select-Object -Expand Content

Si la solicitud se realiza de forma correcta, el servidor muestra la siguiente respuesta con el estado de la operación en formato JSON:

{
  "name": "projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1beta1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1beta1.dicom.DicomService.ExportDicomData",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME"
  },
  "done": true,
  "response": {
    "@type": "..."
  }
}

Soluciona problemas de solicitudes de exportación de DICOM

Si se producen errores durante una solicitud de exportación de DICOM, estos se registrarán en Cloud Logging. Para obtener más información, consulta Visualiza los registros de errores en Cloud Logging.