---
# System prepended metadata

title: Operational Processor

---

# SwarmPAL Operational Processor

## Goal

- Allow SwarmPAL to be used to generate on-demand "products"* for FAC (and other processors in the future) across different spacecraft and processing chains (e.g. OPER/FAST)
- The SwarmPAL processor should be portable (easy to run on different machines)
- We also need to run it continually to generate a set of FAC files (just keep a rolling recent archive) to be put on some TBD file server (e.g. FTP access)
    - these may be a running archive of only the past $N$ days (e.g. for space weather use)

*"products": referring to outputs from the processor that are comparable to the products already delivered
(e.g. FAC → [SW_FACxTMS_2F](https://swarmhandbook.earth.esa.int/catalogue/SW_FACxTMS_2F))

FAC on-demand "products" to be produced from the spacecraft/grades available 
```mermaid
graph TD
    subgraph "Swarm"
        SwarmA[Swarm-A]
        SwarmB[Swarm-B]
        SwarmC[Swarm-C]
    end
    subgraph "Other"
        Cryosat[Cryosat]
        GRACEA[GRACE-A]
        GRACEB[GRACE-B]
        GRACEFO1[GRACE-FO-1]
        GRACEFO2[GRACE-FO-2]
        GOCE[GOCE]
    end

    subgraph "Swarm-A"
        SwarmAFAST[Swarm-A FAST]
        SwarmAOPER[Swarm-A OPER]
        SwarmAFAC["FAC<br>Swarm-A"]
        SwarmAFACFAST["FAC<br>Swarm-A<br>FAST"]
    end

    subgraph "Swarm-B"
        SwarmBFAST[Swarm-B FAST]
        SwarmBOPER[Swarm-B OPER]
        SwarmBFAC["FAC<br>Swarm-B"]
        SwarmBFACFAST["FAC<br>Swarm-B<br>FAST"]
    end

    subgraph "Swarm-C"
        SwarmCFAST[Swarm-C FAST]
        SwarmCOPER[Swarm-C OPER]
        SwarmCFAC["FAC<br>Swarm-C"]
        SwarmCFACFAST["FAC<br>Swarm-C<br>FAST"]
    end

    Cryosat -->|CS_MAG| CryosatFAC["FAC<br>Cryosat"]
    GRACEA -->|GRACE_x_MAG| GRACEAFAC["FAC<br>GRACE-A"]
    GRACEB -->|GRACE_x_MAG| GRACEBFAC["FAC<br>GRACE-B"]
    GRACEFO1 -->|GFx_FGM_ACAL_CORR| GRACEFO1FAC["FAC<br>GRACE-FO-1"]
    GRACEFO2 -->|GFx_FGM_ACAL_CORR| GRACEFO2FAC["FAC<br>GRACE-FO-2"]
    GOCE -->|GO_MAG_ACAL_CORR| GOCEFAC["FAC<br>GOCE"]

    SwarmA --> SwarmAFAST
    SwarmA --> SwarmAOPER
    SwarmAFAST -->|SW_MAGx_LR_1B<br>FAST| SwarmAFACFAST
    SwarmAOPER -->|SW_MAGx_LR_1B| SwarmAFAC

    SwarmB --> SwarmBFAST
    SwarmB --> SwarmBOPER
    SwarmBFAST -->|SW_MAGx_LR_1B<br>FAST| SwarmBFACFAST
    SwarmBOPER -->|SW_MAGx_LR_1B| SwarmBFAC

    SwarmC --> SwarmCFAST
    SwarmC --> SwarmCOPER
    SwarmCFAST -->|SW_MAGx_LR_1B<br>FAST| SwarmCFACFAST
    SwarmCOPER -->|SW_MAGx_LR_1B| SwarmCFAC
```

## Approach

- SwarmPAL will be run from within a versioned container (lock the reproducibility) - WIP
    - the host just requires Docker or Podman
  - can also be run by directly installing the package
- The logic to orchestrate the runner will be within a (bash) script
    - Some tooling should be within the SwarmPAL package
      e.g. `swarmpal poll-availability "SW_FAST_MAGx...."` to identify new times over which to run the process

```mermaid

graph LR

package[SwarmPAL<br>installed just as a package] -.-> script

    container[SwarmPAL Container:<br> e.g. ghcr.io/Swarm-DISC/<br>SwarmPAL]

    subgraph "Execution Environment<i> - needs Docker/Podman</i>"
    
    script[Execution script *<br><i>run on schedule/trigger</i>]
    envvars[Environment variables:<br>VIRES_TOKEN<br>file server auth]
    options[Choose spacecraft] --> script
    end
    
     
     
    file-place[File server<br>e.g. webdav/FTP]
    container & envvars --> script
    script -- upload --> file-place
    
   
```

***Execution script:**

Every 15 minutes, for each spacecraft:
1. Check `t_new`: newest product availability on VirES
2. Check `t_latest`: latest time already processed
3. If `t_new > t_latest`:
   - Run process for period `t_latest` to `t_new`
     ```
     swarmpal fac-single-sat --spacecraft="Swarm-A" --grade="FAST" \
         --time_start=t_latest --time_end=t_new \
         --output=<UNIQUE-FILENAME.CDF>
     ```
4. Upload file
5. Delete files older than 1 month


```mermaid
gantt
    title Files delivered by SwarmPAL
    dateFormat  HH
    axisFormat %H
    section FAC<br>spacecraft X
    X1.CDF     : 00, 1h
    X2.CDF     : 01, 2h
    X3.CDF     : 03, 1h
    
    section FAC<br>spacecraft Y
    Y1.CDF     : 00, 2h
    Y2.CDF     : 02, 1h
    Y3.CDF     : 03, 2h
    
    section FAC<br>spacecraft Z
    _ : _
```

### Naming scheme

- Emulate the product naming scheme?
    - `SW_FAST_FACxTMS_2F_<start>_<end>_0401.CDF`
      Replace `FAST`->`SPAL`
      Needs adjusting for multimission data
      Cause confusion because the product is not the same
- Define a SwarmPAL format?
    - `SwarmPAL_FAC-single-satellite_<spacecraft>_FAST_<start>_<end>_<VERSION>.CDF`
- DSECS (and other) data better suit NetCDF

## Questions / problems

1. Without a trigger to run the task, data can be 30 minutes late:
   - VirES syncs to PDGS every 15 minutes
   - and we add another delay here (15 minutes as above)
2. Must decide on naming scheme for files
3. Where, how, who:
   1. where do we run the code?
   2. where do we host the data?
   3. who is responsible for monitoring/fixing it?
