Crop
Goal¶
Wrap the crop step as a Common Workflow Language CommandLineTool and execute it with a CWL runner.
Lab¶
This step has a dedicated lab at practice-labs/3-CWL-CommandLineTools/crop.ipynb.
How to wrap a step as a CWL CommandLineTool¶
The CWL document below shows the crop step wrapped as a CWL CommandLineTool:
Let's break down the key components of this CWL document:
cwlVersion: v1.2: Specifies the version of the CWL specification that this document follows.class: CommandLineTool: Indicates that this CWL document defines a command-line tool.id: crop: Provides a unique identifier for this tool, which can be used to reference it in workflows.requirements: Specifies the requirements and dependencies of the tool. In this case, it defines the following:InlineJavascriptRequirement: This requirement allows the use of inline JavaScript expressions in the tool.EnvVarRequirement: It sets environment variables. In this case, it adds/app/venv/bintoPATHso the installed commands can be found.ResourceRequirement: Specifies resource requirements for running the tool, including the maximum number of CPU cores and maximum RAM.DockerRequirement: This requirement specifies the Docker container to be used. It indicates that the tool should be executed in a Docker container with the imagelocalhost/crop:latest.
baseCommand: Defines the base command to be executed in the container. In this case, it runs the installedcropcommand.arguments: This section is empty, meaning there are no additional command-line arguments specified here. The tool is expected to receive its arguments via the input parameters.inputs: Describes the input parameters for the tool, including their types and how they are bound to command-line arguments. The tool expects the following inputs:item: A URI record containing avaluefield with the STAC item URL;valueFrom: $(self.value)passes that URL, bound to the--input-itemargument.aoi: A GeoJSON Polygon record withcoordinatesandbbox;valueFrom: $(JSON.stringify(self))serializes the full Polygon, bound to the--aoiargument.epsg: A string representing the EPSG code for the coordinate system, bound to the--epsgargument.band: A string representing the name of the band to be extracted, bound to the--bandargument.
outputs: Specifies the tool's output. It defines an output parameter namedcropped, which is of typeFile. The outputBinding section specifies that the tool is expected to produce one or more TIFF files (glob: '*.tif') as output.
Steps¶
Clean-up the /workspace/mastering-app-package/runs folder:
Run the CWL document using the cwltool CWL runner to execute the crop step with the green band with:
export WORKSPACE=${WORKSPACE:-/workspace/mastering-app-package}
mkdir -p "${WORKSPACE}/runs"
cwltool \
--podman \
--outdir "${WORKSPACE}/runs" \
"${WORKSPACE}/cwl-cli/crop.cwl" \
"${WORKSPACE}/cwl-cli/crop-green-params.yaml"
Run the CWL document using the cwltool CWL runner to execute the crop step with the nir band with:
export WORKSPACE=${WORKSPACE:-/workspace/mastering-app-package}
mkdir -p "${WORKSPACE}/runs"
cwltool \
--podman \
--outdir "${WORKSPACE}/runs" \
"${WORKSPACE}/cwl-cli/crop.cwl" \
"${WORKSPACE}/cwl-cli/crop-params.yaml"
Expected outcome¶
The folder /workspace/mastering-app-package/runs contains:
(base) jovyan@coder-mrossi:~/runs$ tree .
.
├── crop_green.tif
└── crop_nir.tif
0 directories, 2 files
Extra¶
The CWL runner cwltool allows you to do a YAML file with the parameters:
item:
value: https://earth-search.aws.element84.com/v0/collections/sentinel-s2-l2a-cogs/items/S2B_10TFK_20210713_0_L2A
aoi:
type: Polygon
coordinates:
- - - -121.399
- 39.834
- - -120.74
- 39.834
- - -120.74
- 40.472
- - -121.399
- 40.472
- - -121.399
- 39.834
bbox:
- -121.399
- 39.834
- -120.74
- 40.472
epsg: EPSG:4326
band: nir
and run it with:
cwltool \
--podman \
--outdir /workspace/mastering-app-package/runs \
${WORKSPACE}/cwl-cli/crop.cwl \
${WORKSPACE}/cwl-cli/crop-params.yaml
SchemaDefRequirement imports the EOAP GeoJSON and URI record schemas. Use the YAML job above to supply structured inputs. The standalone crop tool retains string epsg and band inputs; the workflows constrain these through enums. The binding passes the full Polygon as JSON, and the application masks pixels outside it.