Hey Jonathan, while looking into your inquiry, we do actually have workflows to manually process the L0B data to L1 in our NISAR environments faster than the 1-3 days, but while reviewing them we realized that without access to lot of NISAR S3 buckets, these workflows don't work out of the box and need tweaks to be able to use them on mirrors like ASF.
I'll try to briefly go over the process of turning an L0B RSSD file into an L1 RSLC, which is the hard part, starting with the expected processing time (your mileage may vary). This requires installing ISCE3 with the GPU CUDA libraries compiled. I believe this is available over conda forge, but alternatively you can look at
https://github.com/isce-framework/isce3.git.
This conversion is through ISCE3's nisar.workflows.focus module (
https://github.com/isce-framework/isce3/blob/static-layers-wip/python/packages/nisar/workflows/focus.py) and it requires a GPU:
- With double precision floating point cores on the GPU: ~1-2 hours per RSLC
- Without double precision cores: ~8 hours per RSLC
The cheapest GPU that has double precision cores is a V100. If you are planning to process this on the cloud like AWS, be aware that they don't offer these cheap GPUs anymore (p3.2xlarge), and all the newer GPUs that have this quality (H100's -> p5 instances) are being monopolized for AI training, so getting the instance itself will be a challenge.
The second challenge software-wise is that you need to obtain the DEM and the Watermask ancillary files. On the NISAR data system, we use these two scripts from ISCE3:
- nisar.workflows.stage_dem ->
https://github.com/isce-framework/isce3/blob/develop/python/packages/nisar/workflows/stage_dem.py
- nisar.workflows.stage_watermask ->
https://github.com/isce-framework/isce3/blob/develop/python/packages/nisar/workflows/stage_watermask.py
These scripts require access to the nisar-dem S3 bucket, which can't be granted publicly, so these scripts need to be modified to point to a mirror on ASF instead (see:
https://nisar-docs.asf.alaska.edu/nisar-dem/). An AI could help with this modification, like Claude Code or Gemini.
The final challenge is to fill out the correct runconfig and obtain the remaining ancillary files. You can do this by starting from an .rc.yaml file from the same frame you want to process for, that was taken at a different time, and modify the ancillary files and the start/end_time fields to the new time window (usually in about 12 day increments since it is a cycle). The remaining ancillary files:
- external_calibration: This is a static file per release ID, it won't change by frame or time
- internal_calibration: This is a static file per release ID, it won't change by frame or time
- antenna_pattern: This is a static file per release ID, it won't change by frame or time
- corner_reflector_file: This is a static file per release ID, it won't change by frame or time
And here are the last 2 ancillary files, which you may change:
- orbit: example is NISAR_ANC_J_PR_MOE_20260121T132557_20260119T205942_20260121T025942.xml
- pointing: example is NISAR_ANC_L_PR_NRP_20260121T210333_20260120T125942_20260121T185942.xml
These files will need to cover the time period you are processing for. For the orbit file, the example is a MOE file and you'd use the forecasted version (FOE) if you need it available sooner. All these files should be available on the ASF.
Before I continue discussing this topic any further, I think it's first worth asking whether the approach I've described thus far makes sense for your use case and/or processing constraints.