calculateShortTermVariability method

void calculateShortTermVariability()

Short-term variability (STV) (calculated in ms and bpm)

  1. discard all deaccelerations + more than 50% signal loss
  2. 1 minute mean of difference between FHR of consecutive samples
  3. take mean of 1 minute means

TODO: How to consider parallel scanning of signal for deaccelerations and processing? Are we loosing some part of signal here?

Implementation

void calculateShortTermVariability() {
  try {
    List<int?> epoch = cleanMillisecondsEpoch(millisecondsEpoch);
    int size = epoch.length;
    int minMeanLength = (size / NO_OF_SAMPLES_PER_MINUTE).truncate();
    List<double?> meanIatPerMinute =
        List.filled((size / NO_OF_SAMPLES_PER_MINUTE).truncate(), null, growable: false);
    List<double?> meanEpochPerMinute =
        List.filled((size / NO_OF_SAMPLES_PER_MINUTE).truncate(), null, growable: false);
    List<double?> iatBeats = List.filled(size - 1, null, growable: false);
    List<int?> epochBeats = List.filled(size - 1, null, growable: false);
    double shortTermVariation = 0;
    double shortTermEpochVariation = 0;
    int counter = 0, meanIatCounter = 0;

    /** first calculate iat of beats **/
    for (int i = 0; i < size - 1; i++) {
      iatBeats[i] = (epoch[i + 1]! - epoch[i]!).toDouble().abs();
      epochBeats[i] = (((SIXTY_THOUSAND_MS / epoch[i + 1]!) -
                  (SIXTY_THOUSAND_MS / epoch[i]!))
              .truncate())
          .abs();
    }

    for (int i = 0; i < minMeanLength; i++) {
      meanIatPerMinute[i] = 0;
      meanEpochPerMinute[i] = 0;
    }

    /** processing only parts of signal which contain no deacceleration **/
    for (int i = 0; i < minMeanLength - 1; i++) {
      for (int j = 0; j < NO_OF_SAMPLES_PER_MINUTE; j++) {
        meanIatPerMinute[i] = meanIatPerMinute[i]! + iatBeats[i * NO_OF_SAMPLES_PER_MINUTE + j]!;
        meanEpochPerMinute[i] = meanEpochPerMinute[i]! + epochBeats[i * NO_OF_SAMPLES_PER_MINUTE + j]!;

        /** first criteria **/ /*
              if (millisecondsEpoch[i * NO_OF_SAMPLES_PER_MINUTE + j] - baselineFHRDR[i * NO_OF_SAMPLES_PER_MINUTE + j] <= 6000) {
                  counter++;
                  if (counter >= 16) { // 60 seconds = 16 samples
                      // deacceleration is occuring here
                  }
              } else {
                  counter = 0;
                  meanIatPerMinute[i] += iatBeats[i * NO_OF_SAMPLES_PER_MINUTE + j];
                  meanIatCounter++;
              }

              */ /** second criteria **/ /*
              if (millisecondsEpoch[i * NO_OF_SAMPLES_PER_MINUTE + j] - baselineFHRDR[i * NO_OF_SAMPLES_PER_MINUTE + j] <= 3000) {
                  counter++;
                  if (counter >= 8 && counter < 16) { // 30 seconds = 8 samples
                      // deacceleration is occuring here
                  }
              } else {
                  counter = 0;
                  meanIatPerMinute[i] += iatBeats[i * NO_OF_SAMPLES_PER_MINUTE + j];
                  meanIatCounter++;
              }*/
      }
      meanIatPerMinute[i] = meanIatPerMinute[i]!/ NO_OF_SAMPLES_PER_MINUTE;
      meanEpochPerMinute[i] = meanEpochPerMinute[i]!/ NO_OF_SAMPLES_PER_MINUTE;

      /*if (meanIatCounter != 0)
              meanIatPerMinute[i] = meanIatPerMinute[i] / meanIatCounter;*/
    }

    for (int i = 0; i < minMeanLength; i++) {
      shortTermVariation += meanIatPerMinute[i]!;
      shortTermEpochVariation += meanEpochPerMinute[i]!;
    }
    shortTermVariabilityMs = shortTermVariation / (minMeanLength - 1);
    shortTermVariabilityBpm = shortTermEpochVariation / (minMeanLength - 1);

    //shortTermVariabilityMs = shortTermVariation * NO_OF_SAMPLES_PER_MINUTE / size;

    //if (shortTermVariabilityMs != 0)
    //    shortTermVariabilityBpm = SIXTY_THOUSAND_MS / shortTermVariation;

    print("STV   $shortTermVariabilityMs  $shortTermVariabilityBpm");
    //return shortTermVariabilityBpm;
  } catch (exception) {
    print(exception);
  }
}