

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Usando trabalhos de processamento para workloads geoespaciais personalizadas
<a name="geospatial-custom-operations"></a>

Com o [Amazon SageMaker Processing](processing-job.md), você pode usar uma experiência simplificada e gerenciada em SageMaker IA para executar suas cargas de trabalho de processamento de dados com o contêiner geoespacial criado especificamente.

 A infraestrutura subjacente para um trabalho SageMaker de processamento da Amazon é totalmente gerenciada pela SageMaker IA. Durante um trabalho de processamento, os recursos do cluster são provisionados para a duração do seu trabalho e limpos quando um trabalho é concluído.

![\[Execução de um trabalho de processamento.\]](http://docs.aws.amazon.com/pt_br/sagemaker/latest/dg/images/Processing-1.png)


O diagrama anterior mostra como a SageMaker IA acelera um trabalho de processamento geoespacial. SageMaker A IA pega seu script de carga de trabalho geoespacial, copia seus dados geoespaciais do Amazon Simple Storage Service (Amazon S3) e, em seguida, extrai o contêiner geoespacial especificado. A infraestrutura subjacente para o trabalho de processamento é totalmente gerenciada pela SageMaker IA. Os recursos do cluster são provisionados para a duração do seu trabalho e limpos quando um trabalho é concluído. A saída do trabalho de processamento é armazenada no bucket que você especificar. 

**Restrições de nomenclatura de path**  
Os caminhos locais dentro de um contêiner de trabalhos de processamento devem começar com **/opt/ml/processing/**.

SageMaker geospatial fornece um contêiner criado especificamente, `081189585635.dkr.ecr.us-west-2.amazonaws.com/sagemaker-geospatial-v1-0:latest` que pode ser especificado ao executar um trabalho de processamento.

**Topics**
+ [Visão geral: Execute trabalhos de processamento usando `ScriptProcessor` um SageMaker contêiner geoespacial](geospatial-custom-operations-overview.md)
+ [Usando `ScriptProcessor` para calcular o Índice de Vegetação por Diferença Normalizada (NDVI) usando dados do satélite Sentinel-2](geospatial-custom-operations-procedure.md)

# Visão geral: Execute trabalhos de processamento usando `ScriptProcessor` um SageMaker contêiner geoespacial
<a name="geospatial-custom-operations-overview"></a>

SageMaker geospatial fornece um contêiner de processamento específico,. `081189585635.dkr.ecr.us-west-2.amazonaws.com/sagemaker-geospatial-v1-0:latest` Você pode usar esse contêiner ao executar um trabalho com o Amazon SageMaker Processing. Ao criar uma instância da [https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ScriptProcessor](https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ScriptProcessor)classe que está disponível por meio do *Amazon SageMaker Python SDK for Processing*, especifique isso. `image_uri`

**nota**  
Se você receber um ResourceLimitExceedederro ao tentar iniciar um trabalho de processamento, precisará solicitar um aumento de cota. Para iniciar uma solicitação de aumento da cota Service Quotas, consulte [Solicitar um aumento de cota](https://docs.aws.amazon.com/servicequotas/latest/userguide/request-quota-increase.html) no *Guia do usuário do Service Quotas* 

**Pré-requisitos para usar o `ScriptProcessor`**

1. Você criou um script Python que especifica sua workload geoespacial de ML.

1. Você concedeu à função de execução de SageMaker IA acesso a todos os buckets do Amazon S3 necessários.

1. Prepare seus dados para importação no contêiner. Os trabalhos SageMaker de processamento da Amazon oferecem suporte à definição de `s3_data_type` igual `"ManifestFile"` ou igual a`"S3Prefix"`.

O procedimento a seguir mostra como criar uma instância `ScriptProcessor` e enviar um trabalho de SageMaker processamento da Amazon usando o contêiner SageMaker geoespacial.

**Para criar uma `ScriptProcessor` instância e enviar um trabalho de SageMaker processamento da Amazon usando um contêiner SageMaker geoespacial**

1. Instancie uma instância da `ScriptProcessor` classe usando a imagem SageMaker geoespacial:

   ```
   from sagemaker.processing import ScriptProcessor, ProcessingInput, ProcessingOutput
   	
   sm_session = sagemaker.session.Session()
   execution_role_arn = sagemaker.get_execution_role()
   
   # purpose-built geospatial container
   image_uri = '081189585635.dkr.ecr.us-west-2.amazonaws.com/sagemaker-geospatial-v1-0:latest'
   
   script_processor = ScriptProcessor(
   	command=['python3'],
   	image_uri=image_uri,
   	role=execution_role_arn,
   	instance_count=4,
   	instance_type='ml.m5.4xlarge',
   	sagemaker_session=sm_session
   )
   ```

   *execution\$1role\$1arn*Substitua pelo ARN da função de execução de SageMaker IA que tem acesso aos dados de entrada armazenados no Amazon S3 e em qualquer AWS outro serviço que você queira chamar em seu trabalho de processamento. Você pode atualizar o `instance_count` e o `instance_type` para atender aos requisitos do seu trabalho de processamento.

1. Para iniciar um trabalho de processamento, use o método `.run()`:

   ```
   # Can be replaced with any S3 compliant string for the name of the folder.
   s3_folder = geospatial-data-analysis
   
   # Use .default_bucket() to get the name of the S3 bucket associated with your current SageMaker session
   s3_bucket = sm_session.default_bucket()
   					
   s3_manifest_uri = f's3://{s3_bucket}/{s3_folder}/manifest.json'
   s3_prefix_uri =  f's3://{s3_bucket}/{s3_folder}/image-prefix
   
   script_processor.run(
   	code='preprocessing.py',
   	inputs=[
   		ProcessingInput(
   			source=s3_manifest_uri | s3_prefix_uri ,
   			destination='/opt/ml/processing/input_data/',
   			s3_data_type= "ManifestFile" | "S3Prefix",
   			s3_data_distribution_type= "ShardedByS3Key" | "FullyReplicated"
   		)
   	],
   	outputs=[
           ProcessingOutput(
               source='/opt/ml/processing/output_data/',
               destination=s3_output_prefix_url
           )
       ]
   )
   ```
   + *preprocessing.py*Substitua pelo nome do seu próprio script de processamento de dados em Python.
   + Um trabalho de processamento oferece apoio a dois métodos para formatar seus dados de entrada. Você pode criar um arquivo manifesto que aponte para todos os dados de entrada do seu trabalho de processamento ou usar um prefixo comum em cada entrada de dados individual. Se você criou um conjunto de arquivos de manifesto `s3_manifest_uri` igual a `"ManifestFile"`. Se você usou um prefixo do arquivo definido `s3_manifest_uri` igual a `"S3Prefix"`. Você especifica o caminho para seus dados usando `source`.
   + Você pode distribuir os dados da tarefa de processamento de duas maneiras:
     + Distribua seus dados para todas as instâncias de processamento definindo `s3_data_distribution_type` igual a `FullyReplicated`.
     + Distribua seus dados em fragmentos com base na chave Amazon S3 definindo `s3_data_distribution_type` igual a `ShardedByS3Key`. Quando você usa `ShardedByS3Key`, um fragmento de dados é enviado para cada instância de processamento.

    Você pode usar um script para processar dados SageMaker geoespaciais. Esse script pode ser encontrado na [Etapa 3: Escrevendo um script que possa calcular o NDVI](geospatial-custom-operations-procedure.md#geospatial-custom-operations-script-mode). Para saber mais sobre a operação da `.run()` API, consulte [https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ScriptProcessor.run](https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ScriptProcessor.run)o *Amazon SageMaker Python SDK* for Processing.

Para monitorar o progresso do seu trabalho de processamento, a classe `ProcessingJobs` oferece apoio a um método [https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ProcessingJob.describe](https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ProcessingJob.describe). Esse método retorna uma resposta da chamada de API `DescribeProcessingJob`. Para saber mais, consulte [`DescribeProcessingJob`a *Amazon SageMaker AI API Reference*](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_DescribeProcessingJob.html).

O próximo tópico mostra como criar uma instância da `ScriptProcessor` classe usando o contêiner SageMaker geoespacial e, em seguida, como usá-lo para calcular o Índice de Vegetação por Diferença Normalizada (NDVI) com imagens. Sentinel-2



# Usando `ScriptProcessor` para calcular o Índice de Vegetação por Diferença Normalizada (NDVI) usando dados do satélite Sentinel-2
<a name="geospatial-custom-operations-procedure"></a>

Os exemplos de código a seguir mostram como calcular o índice de vegetação de diferença normalizada de uma área geográfica específica usando a imagem geoespacial criada especificamente em um notebook Studio Classic e executar uma carga de trabalho em grande escala com o Amazon Processing SageMaker usando o SDK AI Python. [https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ScriptProcessor](https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ScriptProcessor) SageMaker 

Essa demonstração também usa uma instância de notebook Amazon SageMaker Studio Classic que usa o kernel geoespacial e o tipo de instância. Para saber como criar uma instância de cadernos geoespaciais do Studio Classic, consulte [Crie um notebook Amazon SageMaker Studio Classic usando a imagem geoespacial](geospatial-launch-notebook.md).

Você pode acompanhar essa demonstração em sua própria instância de caderno copiando e colando os seguintes trechos de código:

1. [Use `search_raster_data_collection` para consultar uma área específica de interesse (AOI) em um determinado intervalo de tempo usando uma coleção de dados raster específica, Sentinel-2.](#geospatial-custom-operations-procedure-search)

1. [Crie um arquivo manifesto que especifique quais dados serão processados durante o trabalho de processamento.](#geospatial-custom-operations-procedure-manifest)

1. [Escreva um script Python de processamento de dados calculando o NDVI.](#geospatial-custom-operations-script-mode)

1. [Crie uma `ScriptProcessor` instância e inicie o trabalho SageMaker de processamento da Amazon](#geospatial-custom-operations-create).

1. [Visualizando os resultados do seu trabalho de processamento.](#geospatial-custom-operations-visual)

## Consultar a coleta de dados raster Sentinel-2 usando `SearchRasterDataCollection`
<a name="geospatial-custom-operations-procedure-search"></a>

Com `search_raster_data_collection` você pode consultar coleções de dados raster compatíveis. Este exemplo usa dados extraídos dos satélites Sentinel-2. A área de interesse (`AreaOfInterest`) especificada é a zona rural do norte de Iowa, e o intervalo de tempo (`TimeRangeFilter`) é de 1º de janeiro de 2022 a 30 de dezembro de 2022. Para ver as coleções de dados raster disponíveis em seu Região da AWS use `list_raster_data_collections`. Para ver um exemplo de código usando essa API, consulte [`ListRasterDataCollections`](geospatial-data-collections.md)o *Amazon SageMaker AI Developer Guide*.

Nos exemplos de código a seguir, você usa o ARN associado à coleta de dados raster do Sentinel-2, `arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8`.

Uma solicitação de API `search_raster_data_collection` requer dois parâmetros:
+ Você precisa especificar um parâmetro `Arn` que corresponda à coleção de dados raster que você deseja consultar.
+ Você também precisa especificar um parâmetro `RasterDataCollectionQuery`, que usa um dicionário Python.

O exemplo de código a seguir contém os pares de valores-chave necessários para o parâmetro `RasterDataCollectionQuery` salvo na variável `search_rdc_query`.

```
search_rdc_query = {
    "AreaOfInterest": {
        "AreaOfInterestGeometry": {
            "PolygonGeometry": {
                "Coordinates": [[
                    [
              -94.50938680498298,
              43.22487436936203
            ],
            [
              -94.50938680498298,
              42.843474642037194
            ],
            [
              -93.86520004156142,
              42.843474642037194
            ],
            [
              -93.86520004156142,
              43.22487436936203
            ],
            [
              -94.50938680498298,
              43.22487436936203
            ]
               ]]
            }
        }
    },
    "TimeRangeFilter": {"StartTime": "2022-01-01T00:00:00Z", "EndTime": "2022-12-30T23:59:59Z"}
}
```

Para fazer a solicitação `search_raster_data_collection`, você deve especificar o ARN da coleção de dados raster Sentinel-2: `arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8`. Você também precisa passar o dicionário Python que foi definido anteriormente, que especifica os parâmetros de consulta. 

```
## Creates a SageMaker Geospatial client instance 
sm_geo_client= session.create_client(service_name="sagemaker-geospatial")

search_rdc_response1 = sm_geo_client.search_raster_data_collection(
    Arn='arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8',
    RasterDataCollectionQuery=search_rdc_query
)
```

Os resultados dessa API não podem ser paginados. Para coletar todas as imagens de satélite retornadas pela operação `search_raster_data_collection`, você pode implementar um loop `while`. Isso é verificado para `NextToken` na resposta da API:

```
## Holds the list of API responses from search_raster_data_collection
items_list = []
while search_rdc_response1.get('NextToken') and search_rdc_response1['NextToken'] != None:
    items_list.extend(search_rdc_response1['Items'])
    
    search_rdc_response1 = sm_geo_client.search_raster_data_collection(
    	Arn='arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8',
        RasterDataCollectionQuery=search_rdc_query, 
        NextToken=search_rdc_response1['NextToken']
    )
```

A resposta da API retorna uma lista URLs abaixo da `Assets` chave correspondente a faixas de imagem específicas. Veja a seguir uma versão truncada da resposta da API. Algumas das faixas da imagem foram removidas para maior clareza.

```
{
	'Assets': {
        'aot': {
            'Href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/15/T/UH/2022/12/S2A_15TUH_20221230_0_L2A/AOT.tif'
        },
        'blue': {
            'Href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/15/T/UH/2022/12/S2A_15TUH_20221230_0_L2A/B02.tif'
        },
        'swir22-jp2': {
            'Href': 's3://sentinel-s2-l2a/tiles/15/T/UH/2022/12/30/0/B12.jp2'
        },
        'visual-jp2': {
            'Href': 's3://sentinel-s2-l2a/tiles/15/T/UH/2022/12/30/0/TCI.jp2'
        },
        'wvp-jp2': {
            'Href': 's3://sentinel-s2-l2a/tiles/15/T/UH/2022/12/30/0/WVP.jp2'
        }
    },
    'DateTime': datetime.datetime(2022, 12, 30, 17, 21, 52, 469000, tzinfo = tzlocal()),
    'Geometry': {
        'Coordinates': [
            [
                [-95.46676936182894, 43.32623760511659],
                [-94.11293433656887, 43.347431265475954],
                [-94.09532154452742, 42.35884880571144],
                [-95.42776890002203, 42.3383710796791],
                [-95.46676936182894, 43.32623760511659]
            ]
        ],
        'Type': 'Polygon'
    },
    'Id': 'S2A_15TUH_20221230_0_L2A',
    'Properties': {
        'EoCloudCover': 62.384969,
        'Platform': 'sentinel-2a'
    }
}
```

Na [próxima seção](#geospatial-custom-operations-procedure-manifest), você cria um arquivo manifesto usando a chave `'Id'` da resposta da API.

## Crie um arquivo manifesto de entrada usando a chave `Id` da resposta da API `search_raster_data_collection`
<a name="geospatial-custom-operations-procedure-manifest"></a>

Ao executar um trabalho de processamento, você deve especificar uma entrada de dados do Amazon S3. O tipo de dados de entrada pode ser um arquivo manifesto, que então aponta para os arquivos de dados individuais. Você também pode adicionar um prefixo a cada arquivo que você deseja processar. O exemplo de código a seguir define a pasta na qual seus arquivos manifesto serão gerados.

Use o SDK for Python (Boto3) para obter o bucket padrão e o ARN da função de execução associada à sua instância de caderno Studio:

```
sm_session = sagemaker.session.Session()
s3 = boto3.resource('s3')
# Gets the default excution role associated with the notebook
execution_role_arn = sagemaker.get_execution_role() 

# Gets the default bucket associated with the notebook
s3_bucket = sm_session.default_bucket() 

# Can be replaced with any name
s3_folder = "script-processor-input-manifest"
```

Em seguida, você cria um arquivo manifesto. Ele conterá as imagens URLs de satélite que você deseja processar ao executar seu trabalho de processamento posteriormente na etapa 4.

```
# Format of a manifest file
manifest_prefix = {}
manifest_prefix['prefix'] = 's3://' + s3_bucket + '/' + s3_folder + '/'
manifest = [manifest_prefix]

print(manifest)
```

O exemplo de código a seguir retorna o URI do S3 em que seus arquivos manifesto serão criados.

```
[{'prefix': 's3://sagemaker-us-west-2-111122223333/script-processor-input-manifest/'}]
```

Todos os elementos de resposta da resposta search\$1raster\$1data\$1collection não são necessários para executar a tarefa de processamento. 

O trecho de código a seguir remove os elementos desnecessários `'Properties'`, `'Geometry'` e `'DateTime'`. O par de valores-chave `'Id'`, `'Id': 'S2A_15TUH_20221230_0_L2A'`, contém o ano e o mês. O exemplo de código a seguir analisa esses dados para criar novas chaves no dicionário Python **dict\$1month\$1items**. Os valores são os ativos retornados da consulta `SearchRasterDataCollection`. 

```
# For each response get the month and year, and then remove the metadata not related to the satelite images.
dict_month_items = {}
for item in items_list:
    # Example ID being split: 'S2A_15TUH_20221230_0_L2A' 
    yyyymm = item['Id'].split("_")[2][:6]
    if yyyymm not in dict_month_items:
        dict_month_items[yyyymm] = []
    
    # Removes uneeded metadata elements for this demo 
    item.pop('Properties', None)
    item.pop('Geometry', None)
    item.pop('DateTime', None)

    # Appends the response from search_raster_data_collection to newly created key above
    dict_month_items[yyyymm].append(item)
```

Este exemplo de código  carrega o `dict_month_items` para o Amazon S3 como um objeto JSON usando a operação de API [https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3/client/upload_file.html](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3/client/upload_file.html):

```
## key_ is the yyyymm timestamp formatted above
## value_ is the reference to all the satellite images collected via our searchRDC query 
for key_, value_ in dict_month_items.items():
    filename = f'manifest_{key_}.json'
    with open(filename, 'w') as fp:
        json.dump(value_, fp)
    s3.meta.client.upload_file(filename, s3_bucket, s3_folder + '/' + filename)
    manifest.append(filename)
    os.remove(filename)
```

Esse exemplo de código carrega um arquivo principal `manifest.json` que aponta para todos os outros manifestos enviados para o Amazon S3. Também salva o caminho para uma variável local: **s3\$1manifest\$1uri**. Você usará essa variável novamente para especificar a origem dos dados de entrada ao executar o trabalho de processamento na etapa 4.

```
with open('manifest.json', 'w') as fp:
    json.dump(manifest, fp)
s3.meta.client.upload_file('manifest.json', s3_bucket, s3_folder + '/' + 'manifest.json')
os.remove('manifest.json')

s3_manifest_uri = f's3://{s3_bucket}/{s3_folder}/manifest.json'
```

Agora que você criou os arquivos manifesto de entrada e os carregou, você pode escrever um script que processe seus dados na tarefa de processamento. Ele processa os dados das imagens de satélite, calcula o NDVI e, em seguida, retorna os resultados para um local diferente do Amazon S3.

## Escreva um script que calcule o NDVI
<a name="geospatial-custom-operations-script-mode"></a>

O Amazon SageMaker Studio Classic suporta o uso do comando `%%writefile` cell magic. Depois de executar uma célula com esse comando, seu conteúdo será salvo no diretório local do Studio Classic. Esse é um código específico para calcular o NDVI. No entanto, o seguinte pode ser útil quando você escreve seu próprio script para uma tarefa de processamento:
+ Em seu contêiner de trabalho de processamento, os caminhos locais dentro do contêiner devem começar com `/opt/ml/processing/`. Neste exemplo, **input\$1data\$1path = '/opt/ml/processing/input\$1data/' ** e **processed\$1data\$1path = '/opt/ml/processing/output\$1data/'** são especificados dessa forma.
+ Com o Amazon SageMaker Processing, um  script executado por uma tarefa de processamento pode carregar seus dados processados diretamente para o Amazon S3. Para fazer isso, certifique-se de que o perfil de execução associada à sua instância `ScriptProcessor` tenha os requisitos necessários para acessar o bucket do S3. Você também pode especificar um parâmetro de saídas ao executar seu trabalho de processamento. Para saber mais, consulte a [operação da `.run()` API](https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ScriptProcessor.run) no SDK do *Amazon SageMaker Python*. Neste exemplo de código, os resultados do processamento de dados são carregados diretamente para o Amazon S3.
+ Para gerenciar o tamanho da Amazon EBScontainer anexada ao seu processamento, use o `volume_size_in_gb` parâmetro. O tamanho padrão dos contêineres é 30 GB. Opcionalmente, você também pode usar [Coleta de resíduos](https://docs.python.org/3/library/gc.html) da biblioteca Python para gerenciar o armazenamento em seu contêiner do Amazon EBS.

  O exemplo de código a seguir carrega as matrizes no contêiner do trabalho de processamento. Quando as matrizes se acumulam e preenchem a memória, a tarefa de processamento falha. Para evitar essa falha, o exemplo a seguir contém comandos que removem as matrizes do contêiner do trabalho de processamento.

```
%%writefile compute_ndvi.py

import os
import pickle
import sys
import subprocess
import json
import rioxarray

if __name__ == "__main__":
    print("Starting processing")
    
    input_data_path = '/opt/ml/processing/input_data/'
    input_files = []
    
    for current_path, sub_dirs, files in os.walk(input_data_path):
        for file in files:
            if file.endswith(".json"):
                input_files.append(os.path.join(current_path, file))
    
    print("Received {} input_files: {}".format(len(input_files), input_files))

    items = []
    for input_file in input_files:
        full_file_path = os.path.join(input_data_path, input_file)
        print(full_file_path)
        with open(full_file_path, 'r') as f:
            items.append(json.load(f))
            
    items = [item for sub_items in items for item in sub_items]

    for item in items:
        red_uri = item["Assets"]["red"]["Href"]
        nir_uri = item["Assets"]["nir"]["Href"]

        red = rioxarray.open_rasterio(red_uri, masked=True)
        nir = rioxarray.open_rasterio(nir_uri, masked=True)

        ndvi = (nir - red)/ (nir + red)
        
        file_name = 'ndvi_' + item["Id"] + '.tif'
        output_path = '/opt/ml/processing/output_data'
        output_file_path = f"{output_path}/{file_name}"
        
        ndvi.rio.to_raster(output_file_path)
        print("Written output:", output_file_path)
```

Agora você tem um script que pode calcular o NDVI. Em seguida, você pode criar uma instância do ScriptProcessor e executar sua tarefa de processamento.

## Criando uma instância da classe `ScriptProcessor`
<a name="geospatial-custom-operations-create"></a>

Esta demonstração usa a [ScriptProcessor](https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ScriptProcessor)classe que está disponível por meio do SDK do Amazon SageMaker Python. Primeiro, você precisa criar uma instância da classe e, em seguida, iniciar seu trabalho de processamento usando o método `.run()`.

```
from sagemaker.processing import ScriptProcessor, ProcessingInput, ProcessingOutput

image_uri = '081189585635.dkr.ecr.us-west-2.amazonaws.com/sagemaker-geospatial-v1-0:latest'

processor = ScriptProcessor(
	command=['python3'],
	image_uri=image_uri,
	role=execution_role_arn,
	instance_count=4,
	instance_type='ml.m5.4xlarge',
	sagemaker_session=sm_session
)

print('Starting processing job.')
```

Ao iniciar seu trabalho de processamento, você precisa especificar um objeto [https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ProcessingInput](https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ProcessingInput). Nesse objeto, você especifica o seguinte:
+ O caminho para o arquivo manifesto que você criou na etapa 2, **s3\$1manifest\$1uri**. Essa é a fonte dos dados de entrada para o contêiner.
+ O caminho para onde você deseja que os dados de entrada sejam salvos no contêiner. Isso deve corresponder ao caminho que você especificou em seu script.
+ Use o parâmetro `s3_data_type` para especificar a entrada como `"ManifestFile"`.

```
s3_output_prefix_url = f"s3://{s3_bucket}/{s3_folder}/output"

processor.run(
    code='compute_ndvi.py',
    inputs=[
        ProcessingInput(
            source=s3_manifest_uri,
            destination='/opt/ml/processing/input_data/',
            s3_data_type="ManifestFile",
            s3_data_distribution_type="ShardedByS3Key"
        ),
    ],
    outputs=[
        ProcessingOutput(
            source='/opt/ml/processing/output_data/',
            destination=s3_output_prefix_url,
            s3_upload_mode="Continuous"
        )
    ]
)
```

O exemplo de código a seguir usa o [método `.describe()`](https://sagemaker.readthedocs.io/en/stable/api/training/processing.html#sagemaker.processing.ProcessingJob.describe) para obter detalhes do seu trabalho de processamento.

```
preprocessing_job_descriptor = processor.jobs[-1].describe()
s3_output_uri = preprocessing_job_descriptor["ProcessingOutputConfig"]["Outputs"][0]["S3Output"]["S3Uri"]
print(s3_output_uri)
```

## Visualizando seus resultados usando `matplotlib`
<a name="geospatial-custom-operations-visual"></a>

Com a biblioteca [Matplotlib](https://matplotlib.org/stable/index.html) Python, você pode traçar dados raster. Antes de traçar os dados, você precisa calcular o NDVI usando imagens de amostra dos satélites Sentinel-2. O exemplo de código a seguir abre as matrizes de imagens usando a operação de API `.open_rasterio()` e, em seguida, calcula o NDVI usando as bandas de imagem `nir` e `red` dos dados do satélite Sentinel-2. 

```
# Opens the python arrays 
import rioxarray

red_uri = items[25]["Assets"]["red"]["Href"]
nir_uri = items[25]["Assets"]["nir"]["Href"]

red = rioxarray.open_rasterio(red_uri, masked=True)
nir = rioxarray.open_rasterio(nir_uri, masked=True)

# Calculates the NDVI
ndvi = (nir - red)/ (nir + red)

# Common plotting library in Python 
import matplotlib.pyplot as plt

f, ax = plt.subplots(figsize=(18, 18))
ndvi.plot(cmap='viridis', ax=ax)
ax.set_title("NDVI for {}".format(items[25]["Id"]))
ax.set_axis_off()
plt.show()
```

A saída do exemplo de código anterior é uma imagem de satélite com os valores de NDVI sobrepostos nela. Um valor de NDVI próximo a 1 indica que muita vegetação está presente e valores próximos a 0 indicam que nenhuma vegetação está presente.

![\[Uma imagem de satélite do norte de Iowa com o NDVI sobreposto na parte superior\]](http://docs.aws.amazon.com/pt_br/sagemaker/latest/dg/images/ndvi-iowa.png)


Isso conclui a demonstração do uso de `ScriptProcessor`.