syntax = "proto3";
package pulse.cdm.bind;
option java_package = "com.kitware.pulse.cdm.bind";
option csharp_namespace = "pulse.cdm.bind";
option optimize_for = SPEED;

/////////////////////////
// Curve/Segments Data //
/////////////////////////

message SegmentConstantData
{
  ScalarVolumeData                 BeginVolume            = 1; /**<< @brief Blahb.*/
  ScalarVolumeData                 EndVolume              = 2; /**<< @brief Blahb.*/
  ScalarVolumePerPressureData      Compliance             = 3; /**<< @brief Blahb.*/
}

message SegmentLinearData
{
  ScalarVolumeData                 BeginVolume            = 1; /**<< @brief Blahb.*/
  ScalarVolumeData                 EndVolume              = 2; /**<< @brief Blahb.*/
  ScalarPressurePerVolumeData      Slope                  = 3; /**<< @brief Blahb.*/
  ScalarPressureData               YIntercept             = 4; /**<< @brief Blahb.*/
}

message SegmentParabolicData
{
  ScalarVolumeData                 BeginVolume            = 1; /**<< @brief Blahb.*/
  ScalarVolumeData                 EndVolume              = 2; /**<< @brief Blahb.*/
  ScalarData                       Coefficient1           = 3; /**<< @brief Blahb.*/
  ScalarData                       Coefficient2           = 4; /**<< @brief Blahb.*/
  ScalarData                       Coefficient3           = 5; /**<< @brief Blahb.*/
  ScalarData                       Coefficient4           = 6; /**<< @brief Blahb.*/
}

message SegmentSigmoidalData
{
  ScalarVolumeData                 BeginVolume            = 1; /**<< @brief Blahb.*/
  ScalarVolumeData                 EndVolume              = 2; /**<< @brief Blahb.*/
  ScalarPressureData               LowerCorner            = 3; /**<< @brief Blahb.*/
  ScalarPressureData               UpperCorner            = 4; /**<< @brief Blahb.*/
  ScalarVolumePerPressureData      BaselineCompliance     = 5; /**<< @brief Blahb.*/
}

message AnySegmentData
{
  oneof Action
  {
    SegmentConstantData            ConstantSegment        = 1; /**<< @brief Blahb.*/
    SegmentLinearData              LinearSegment          = 2; /**<< @brief Blahb.*/
    SegmentParabolicData           ParabolicSegment       = 3; /**<< @brief Blahb.*/
    SegmentSigmoidalData           SigmoidalSegment       = 4; /**<< @brief Blahb.*/
  }
}

message CurveData
{
  repeated AnySegmentData          Segment                = 1;
}

//////////////////
// Average Data //
//////////////////

message RunningAverageData
{
  double Sum         = 1;
  uint32 NumSamples  = 2;
}

message TemporalInterpolatorData
{
  bool   Complete           = 1;
  bool   PositiveTransition = 2;
  double Period_s           = 3;
  double Current            = 4;
  double Target             = 5;
  double Initial            = 6;
}

////////////////
// Scalar Data //

/** @brief A unitless scalar. */
message ScalarData
{
  double Value       = 1;
  string Unit        = 2;
  bool   ReadOnly    = 3;
}

/** Various Scalar Types */

/** @brief A unitless scalar greater or equal to 0 and less that or equal to 1. */
message Scalar0To1Data
{
  ScalarData Scalar0To1 = 1;
}

/** @brief A unitless scalar greater or equal to -1 and less that or equal to 1. */
message ScalarNegative1To1Data
{
  ScalarData ScalarNegative1To1 = 1;
}

/** @brief An unsigned scalar greater or equal to 0. */
message ScalarUnsignedData 
{
  ScalarData ScalarUnsigned = 1;
}

/** @brief A scalar for holding amount quantities (ex. ct, mol) */
message ScalarAmountData
{
  ScalarData ScalarAmount = 1;
}

/** @brief A scalar for holding amount per mass quantities (ex. mol/g) */
message ScalarAmountPerMassData
{
  ScalarData ScalarAmountPerMass = 1;
}

/** @brief A scalar for holding amount per time quantities (ex. mol/min) */
message ScalarAmountPerTimeData
{
  ScalarData ScalarAmountPerTime = 1;
}

/** @brief A scalar for holding amount per volume quantities (ex. mol/L) */
message ScalarAmountPerVolumeData
{
  ScalarData ScalarAmountPerVolume = 1;
}

/** @brief A scalar for holding area quantities (ex. m^2) */
message ScalarAreaData
{
  ScalarData ScalarArea = 1;
}

/** @brief A scalar for holding area per time quantities (ex. m^2/s) */
message ScalarAreaPerTimePressureData
{
  ScalarData ScalarAreaPerTimePressure = 1;
}

/** @brief A scalar for holding electric capacitance quantities (ex. F) */
message ScalarElectricCapacitanceData
{
  ScalarData ScalarElectricCapacitance = 1;
}

/** @brief A scalar for holding electric charge quantities (ex. C) */
message ScalarElectricChargeData
{
  ScalarData ScalarElectricCharge = 1;
}

/** @brief A scalar for holding electric current quantities (ex. A) */
message ScalarElectricCurrentData
{
  ScalarData ScalarElectricCurrent = 1;
}

/** @brief A scalar for holding electric potential quantities (ex. V) */
message ScalarElectricPotentialData
{
  ScalarData ScalarElectricPotential = 1;
}

/** @brief A scalar for holding electric inductance quantities (ex. H) */
message ScalarElectricInductanceData
{
  ScalarData ScalarElectricInductance = 1;
}

/** @brief A scalar for holding electric resistance quantities (ex. ohm) */
message ScalarElectricResistanceData
{
  ScalarData ScalarElectricResistance = 1;
}

/** @brief A scalar for holding energy quantities (ex. J) */
message ScalarEnergyData
{
  ScalarData ScalarEnergy = 1;
}

/** @brief A scalar for holding energy per amount quantities (ex. J/mol) */
message ScalarEnergyPerAmountData
{
  ScalarData ScalarEnergyPerAmount = 1;
}

/** @brief A scalar for holding energy per mass quantities (ex. J/kg) */
message ScalarEnergyPerMassData
{
  ScalarData ScalarEnergyPerMass = 1;
}

/** @brief A scalar for holding equivalent weight(mass / substance atomic weight * valence) per volume (ex. mEq/L) */
message ScalarEquivalentWeightPerVolumeData
{
  ScalarData ScalarEquivalentWeightPerVolume = 1;
}

/** @brief A scalar for holding force quantities (ex. N) */
message ScalarForceData
{
  ScalarData ScalarForce = 1;
}

/** @brief A scalar for holding frequency quantities (ex. 1/s) */
message ScalarFrequencyData
{
  ScalarData ScalarFrequency = 1;
}

/** @brief A scalar for holding heat capacitance quantities (ex. J/K) */
message ScalarHeatCapacitanceData
{
  ScalarData ScalarHeatCapacitance = 1;
}

/** @brief A scalar for holding heat capacitance per amount quantities (ex. J/K mol) */
message ScalarHeatCapacitancePerAmountData
{
  ScalarData ScalarHeatCapacitancePerAmount = 1;
}

/** @brief A scalar for holding heat capacitance per mass quantities (ex. J/K kg) */
message ScalarHeatCapacitancePerMassData
{
  ScalarData ScalarHeatCapacitancePerMass = 1;
}

/** @brief A scalar for holding heat conductance quantities (ex. W/K) */
message ScalarHeatConductanceData
{
  ScalarData ScalarHeatConductance = 1;
}

/** @brief A scalar for holding heat conductance per area quantities (ex. W/m^2 K) */
message ScalarHeatConductancePerAreaData
{
  ScalarData ScalarHeatConductancePerArea = 1;
}

/** @brief A scalar for holding heat inductance quantities (ex. K s/W) */
message ScalarHeatInductanceData
{
  ScalarData ScalarHeatInductance = 1;
}

/** @brief A scalar for holding heat resistance quantities (ex. K/W) */
message ScalarHeatResistanceData
{
  ScalarData ScalarHeatResistance = 1;
}

/** @brief A scalar for holding heat resistance area quantities (ex. rsi) */
message ScalarHeatResistanceAreaData
{
  ScalarData ScalarHeatResistanceArea = 1;
}

/** @brief A scalar for holding inverse pressure quantities (ex. 1/Pa) */
message ScalarInversePressureData
{
  ScalarData ScalarInversePressure = 1;
}

/** @brief A scalar for holding inverse volume quantities (ex. 1/L) */
message ScalarInverseVolumeData
{
  ScalarData ScalarInverseVolume = 1;
}

/** @brief A scalar for holding length quantities (ex. ft) */
message ScalarLengthData
{
  ScalarData ScalarLength = 1;
}

/** @brief A scalar for holding length per time quantities (ex. ft/s) */
message ScalarLengthPerTimeData
{
  ScalarData ScalarLengthPerTime = 1;
}

/** @brief A scalar for holding length per time per pressure quantities (ex. m/s mmHg) */
message ScalarLengthPerTimePressureData
{
  ScalarData ScalarLengthPerTimePressure = 1;
}

/** @brief A scalar for holding mass quantities (ex. g) */
message ScalarMassData
{
  ScalarData ScalarMass = 1;
}

/** @brief A scalar for holding mass per amount quantities (ex. g/mol) */
message ScalarMassPerAmountData
{
  ScalarData ScalarMassPerAmount = 1;
}

/** @brief A scalar for holding mass per time quantities (ex. ug/s) */
message ScalarMassPerAreaTimeData
{
  ScalarData ScalarMassPerAreaTime = 1;
}

/** @brief A scalar for holding mass per mass quantities (ex. ug/kg) */
message ScalarMassPerMassData
{
  ScalarData ScalarMassPerMass = 1;
}

/** @brief A scalar for holding mass per time quantities (ex. ug/s) */
message ScalarMassPerTimeData
{
  ScalarData ScalarMassPerTime = 1;
}

/** @brief  A scalar for holding mass per volume quantities (ex. ug/mL) */
message ScalarMassPerVolumeData
{
  ScalarData ScalarMassPerVolume = 1;
}

/** @brief A scalar for holding osmolality quantities (ex. Osm/kg) */
message ScalarOsmolalityData
{
  ScalarData ScalarOsmolality = 1;
}

/** @brief A scalar for holding osmolarity quantities (ex. Osm/L) */
message ScalarOsmolarityData
{
  ScalarData ScalarOsmolarity = 1;
}

/** A scalar for holding power quantities (ex. W) */
message ScalarPowerData
{
  ScalarData ScalarPower = 1;
}

/** @brief A scalar for holding Radiative Heat Transfer Powers such as Stefan Boltzman quantities (ex. W / m^2 K^4) */
message ScalarPowerPerAreaTemperatureToTheFourthData
{
  ScalarData ScalarPowerPerAreaTemperatureToTheFourth = 1;
}

/** @brief A scalar for holding pressure quantities (ex. mmHg) */
message ScalarPressureData
{
  ScalarData ScalarPressure = 1;
}

/** @brief A scalar for holding pressure per volume quantities (ex. mmHg/mL) */
message ScalarPressurePerVolumeData
{
  ScalarData ScalarPressurePerVolume = 1;
}

/** @brief A scalar for holding pressure time area per volume quantities (ex. dyn s /cm^5 m^2) */
message ScalarPressureTimePerVolumeAreaData
{
  ScalarData ScalarPressureTimePerVolumeArea = 1;
}

/** @brief A scalar for holding pressure time per area quantities (ex. mmHg s/m2) */
message ScalarPressureTimePerAreaData
{
  ScalarData ScalarPressureTimePerArea = 1;
}

/** @brief A scalar for holding pressure time per volume quantities (ex. Pa s/m^3) */
message ScalarPressureTimePerVolumeData
{
  ScalarData ScalarPressureTimePerVolume = 1;
}

/** @brief A scalar for holding pressure time squared per volume quantities (ex. mmHg s^2/mL) */
message ScalarPressureTimeSquaredPerVolumeData
{
  ScalarData ScalarPressureTimeSquaredPerVolume = 1;
}

/** @brief A scalar for holding time quantities (ex. s) */
message ScalarTimeData
{
  ScalarData ScalarTime = 1;
}

/** @brief A scalar for holding temperature quantities (ex. degC) */
message ScalarTemperatureData
{
  ScalarData ScalarTemperature = 1;
}

/** @brief A scalar for holding volume quantities (ex. mL) */
message ScalarVolumeData
{
  ScalarData ScalarVolume = 1;
}

/** @brief A scalar for holding volume per time quantities (ex. mL/s) */
message ScalarVolumePerTimeData
{
  ScalarData ScalarVolumePerTime = 1;
}

/** @brief A scalar for holding volume per pressure quantities (ex. mL/cmH2O) */
message ScalarVolumePerPressureData
{
  ScalarData ScalarVolumePerPressure = 1;
}

/** @brief A scalar for holding volume per time per area quantities (ex. mL/s cm2 g) */
message ScalarVolumePerTimeAreaData
{
  ScalarData ScalarVolumePerTimeArea = 1;
}

/** @brief A scalar for holding volume per time per mass quantities (ex. mL/s g) */
message ScalarVolumePerTimeMassData
{
  ScalarData ScalarVolumePerTimeMass = 1;
}

/** @brief A scalar for holding volume per time per pressure quantities (ex. "mL/s mmHg) */
message ScalarVolumePerTimePressureData
{
  ScalarData ScalarVolumePerTimePressure = 1;
}

/** @brief A scalar for holding volume per time per pressure per are quantities (ex. "mL/s mmHg cm2) */
message ScalarVolumePerTimePressureAreaData
{
  ScalarData ScalarVolumePerTimePressureArea = 1;
}

message DoubleArrayData
{
  repeated double Value = 1 [packed=true];
}
message IntegerArrayData
{
  repeated int32 Value = 1 [packed=true];
}

message ArrayData
{
  DoubleArrayData Value = 1;
  string          Unit  = 2;
}

message ArrayElectricPotentialData
{
  ArrayData       ArrayElectricPotential = 1;
}

message ArrayTimeData
{
  ArrayData       ArrayTime = 1;
}

message FunctionData
{
  DoubleArrayData Dependent   = 1;
  DoubleArrayData Independent = 2;
  string DependentUnit        = 3;
  string IndependentUnit      = 4;
}

/** @brief Volumes as a function of time */
message FunctionVolumeVsTimeData
{
  FunctionData FunctionVolumeVsTime = 1;
}

/** @brief Electric potential as a function of time */
message FunctionElectricPotentialVsTimeData
{
  FunctionData FunctionElectricPotentialVsTime = 1;
}

/** @brief Two arrays paired where the independent list is 1 + the length of the dependent list, for bins */
message HistogramData
{
  FunctionData Histogram = 1;
}

/** @brief Two arrays paired where the length list is 1 + the length of the fraction list, for bins*/
message HistogramFractionVsLengthData
{
  HistogramData HistogramFractionVsLength = 1;
}

message RangeData
{
  double                                                Minimum                         = 1;
  double                                                Maximum                         = 2;
}
