openapi: 3.0.0
info:
  title: Simulation Service
  description: The shared interface for the SciML and PyCIEMSS services. Differences in APIs should be contained to the `extra` argument.
  version: 0.1.0
components:
  schemas:
    ModelConfigurations:
      type: array
      description: "List of model configurations to use. The sum of the weights should be 1."
      items:
        $ref: '#/components/schemas/ModelConfiguration'
      example:
        - id: "ba8da8d4-047d-11ee-be56"
          solution_mappings: 
            S: "Susceptible"
            I: "SymptomaticAndAsymptomatic"
            R: "Healthy"
          weight: 0.4
        - id: "c1cd941a-047d-11ee-be56"
          solution_mappings: 
            S: "S"
            I: "IandDandAandRandT"
            R: "HandE"
          weight: 0.1
        - id: "c4b9f88a-047d-11ee-be56"
          solution_mappings:
            S: "scaleS"
            I: "scaleI"
            R: "scaleR"
          weight: 0.5
    Dataset:
      type: object
      description: "Information to retrieve and match data to the model"
      properties:
        id:
          type: string
          description: "The ID of the dataset in the Terarium Data Service"
          example: "cd339570-047d-11ee-be55"
        filename:
          type: string
          description: "The filename to use from the dataset"
          example: "dataset.csv"
        mappings:
          type: object
          description: "
            A key-value pair representing the column to map from (key) to the
            new name (value). Note that we currently expect the unmapped columns
            to still be used in the model. There is currently no dropping.
            NOTE - we may eventually change this so that only mapped columns
            are the ones that are used."
    Interventions:
      type: array
      description: "A list of all interventions where each variable at each timestep is separated"
      items:
        $ref: '#/components/schemas/Intervention'
    OptimizeInterventions:
      type: array
      description: "A list of all interventions where each variable at each timestep is separated"
      items:
        $ref: '#/components/schemas/OptimizeIntervention'
    ModelConfiguration:
      type: object
      properties:
        model_config_id:
          type: string
        solution_mappings: 
          type: object
          description: "
            A key-value pair that indicates how the observables will be used in
            map to the ensembled model. The key is the name of the state in the
            ensembled model and the value is the observable in the individual
            model that will be used to map to the ensembled state."
        weight:
          type: number
          description: "How much the model should affect the final result. Must be between 0 and 1."
    Intervention:
      type: object
      description: "A change in a variables value at a specific timestep."
      properties:
          timestep:
            type: number
            example: 2
          name:
            type: string
            example: "beta"
          value:
            type: number
            example: 0.4
    OptimizeIntervention:
      type: object
      description: "A in a variables at a specific timestep without a value provided."
      properties:
          timestep:
            type: number
            example: 2
          name:
            type: string
            example: "beta"
    Timespan:
      type: object
      properties:
        start:
          type: integer
          example: 0
        end:
          type: integer
          example: 90
      description: "Timesteps to start and stop the simulation"
    Engine:
      type: string
      enum: [sciml, ciemss]
      example: sciml
      description: "Choice of which simulation service to use"
paths:
  /simulate:
    post:
      summary: Perform a simulation
      operationId: simulateModel
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                engine:
                  $ref: '#/components/schemas/Engine'
                model_config_id:
                  type: string
                  example: "ba8da8d4-047d-11ee-be56"
                timespan:
                    $ref: '#/components/schemas/Timespan'
                interventions:
                   $ref: '#/components/schemas/Interventions'                  
                extra:
                  description: optional extra system specific arguments for advanced use cases
                  type: object
              required:
                - engine
                - model_config_id
                - timespan
      responses:
        '200':
          description: Simulation created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  simulation_id:
                    type: string
                    example: fc5d80e4-0483-11ee-be56

  /calibrate:
    post:
      summary: Calibrate a model to data
      description: Calibrate a model and perform a "fitting" simulation over the time range of the calibration dataset and a simulation of a time range specified in `timespan` if `timespan` is specified. NOTICE - This will be changed soon to NOT perform a simulation after calibration
      operationId: calibratesimulateModel
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                engine:
                  $ref: '#/components/schemas/Engine'
                model_config_id:
                  type: string
                  example: "c1cd941a-047d-11ee-be56"
                dataset:
                  $ref: '#/components/schemas/Dataset'
                timespan:
                    $ref: '#/components/schemas/Timespan'
                extra:
                  description: optional extra system specific arguments for advanced use cases
                  type: object
              required:
                - engine
                - model_config_id
                - dataset
      responses:
        '200':
          description: Calibration created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  simulation_id:
                    type: string
                    example: fc5d80e4-0483-11ee-be56
  /optimize:
    post:
      summary: Find optimization for given interventions
      operationId: operate_optimize_post
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                engine:
                  $ref: '#/components/schemas/Engine'
                model_config_id:
                  type: string
                  example: "c1cd941a-047d-11ee-be56"
                timespan:
                    $ref: '#/components/schemas/Timespan'
                interventions:
                   $ref: '#/components/schemas/OptimizeInterventions'                  
                step_size:
                  title: Step Size
                  type: number
                  default: 1
                qoi:
                  title: Quantities of Interest
                  description: "Compartments to optimize"
                  type: array
                  items:
                    type: string
                risk_bound:
                  title: Risk Bound
                  type: number
                initial_guess_interventions:
                  title: Initial Guess Interventions
                  type: array
                  items:
                    type: number
                bounds_interventions:
                  title: Bounds Interventions
                  type: array
                  items:
                    type: array
                    items:
                      type: number
                extra:
                  description: optional extra system specific arguments for advanced use cases
                  type: object
              required:
                - engine
                - model_config_id
                - qoi
                - risk_bound
                - initial_guess_interventions
                - bounds_interventions
      responses:
        '200':
          description: Optimization created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  simulation_id:
                    type: string
                    example: fc5d80e4-0483-11ee-be56
  /ensemble-simulate:
    post:
      summary: Perform an ensemble simulation
      operationId: createEnsemble
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                engine:
                  $ref: '#/components/schemas/Engine'
                model_configs:
                  $ref: '#/components/schemas/ModelConfigurations'
                timespan:
                    $ref: '#/components/schemas/Timespan'

                extra:
                  description: optional extra system specific arguments for advanced use cases
                  type: object                   
              required:
                - engine
                - model_config_id
                - timespan
      responses:
        '200':
          description: Ensemble created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  simulation_id:
                    type: string
                    example: fc5d80e4-0483-11ee-be56
  
  /ensemble-calibrate:
    post:
      summary: Calibrate an ensemble of models
      operationId: calibrateEnsemble
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                engine:
                  $ref: '#/components/schemas/Engine'
                model_configs:
                  $ref: '#/components/schemas/ModelConfigurations'
                dataset:
                  $ref: '#/components/schemas/Dataset'
                timespan:
                    $ref: '#/components/schemas/Timespan'
                extra:
                  description: optional extra system specific arguments for advanced use cases
                  type: object
              required:
                - engine
                - model_config_ids
                - timespan
      responses:
        '200':
          description: Ensemble created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  simulation_id:
                    type: string
                    example: fc5d80e4-0483-11ee-be56

  /status/{simulation_id}:
    get:
      summary: Retrieve the status of a simulation
      operationId: getStatus
      parameters:
        - name: simulation_id
          in: path
          required: true
          schema:
            type: string
            example: fc5d80e4-0483-11ee-be56
      responses:
        '200':
          description: Status retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum: [queued, running, complete, error, failure]