/**
   * Compiles the list of keys for the Covariates table and uses the shared parsing utility to
   * produce the actual table
   *
   * @param reportTable the GATKReport table containing data for this table
   * @param recalibrationTables the recalibration tables \
   */
  private void parseAllCovariatesTable(
      final GATKReportTable reportTable, final RecalibrationTables recalibrationTables) {
    for (int i = 0; i < reportTable.getNumRows(); i++) {
      final Object rg = reportTable.get(i, RecalUtils.READGROUP_COLUMN_NAME);
      tempCOVarray[0] = requestedCovariates[0].keyFromValue(rg);
      final Object qual = reportTable.get(i, RecalUtils.QUALITY_SCORE_COLUMN_NAME);
      tempCOVarray[1] = requestedCovariates[1].keyFromValue(qual);

      final String covName = (String) reportTable.get(i, RecalUtils.COVARIATE_NAME_COLUMN_NAME);
      final int covIndex = optionalCovariateIndexes.get(covName);
      final Object covValue = reportTable.get(i, RecalUtils.COVARIATE_VALUE_COLUMN_NAME);
      tempCOVarray[2] =
          requestedCovariates[
              RecalibrationTables.TableType.OPTIONAL_COVARIATE_TABLES_START.ordinal() + covIndex]
              .keyFromValue(covValue);

      final EventType event =
          EventType.eventFrom((String) reportTable.get(i, RecalUtils.EVENT_TYPE_COLUMN_NAME));
      tempCOVarray[3] = event.ordinal();

      recalibrationTables
          .getTable(
              RecalibrationTables.TableType.OPTIONAL_COVARIATE_TABLES_START.ordinal() + covIndex)
          .put(getRecalDatum(reportTable, i, false), tempCOVarray);
    }
  }
  /**
   * Update the recalibration statistics using the information in recalInfo
   *
   * @param recalInfo data structure holding information about the recalibration values for a single
   *     read
   */
  @Requires("recalInfo != null")
  public void updateDataForRead(final ReadRecalibrationInfo recalInfo) {
    final GATKSAMRecord read = recalInfo.getRead();
    final ReadCovariates readCovariates = recalInfo.getCovariatesValues();
    final RecalibrationTables tables = getUpdatableRecalibrationTables();
    final NestedIntegerArray<RecalDatum> qualityScoreTable = tables.getQualityScoreTable();

    for (int offset = 0; offset < read.getReadBases().length; offset++) {
      if (!recalInfo.skip(offset)) {

        for (final EventType eventType : EventType.values()) {
          final int[] keys = readCovariates.getKeySet(offset, eventType);
          final int eventIndex = eventType.ordinal();
          final byte qual = recalInfo.getQual(eventType, offset);
          final double isError = recalInfo.getErrorFraction(eventType, offset);

          RecalUtils.incrementDatumOrPutIfNecessary(
              qualityScoreTable, qual, isError, keys[0], keys[1], eventIndex);

          for (int i = 2; i < covariates.length; i++) {
            if (keys[i] < 0) continue;

            RecalUtils.incrementDatumOrPutIfNecessary(
                tables.getTable(i), qual, isError, keys[0], keys[1], keys[i], eventIndex);
          }
        }
      }
    }
  }
  /**
   * Compiles the list of keys for the ReadGroup table and uses the shared parsing utility to
   * produce the actual table
   *
   * @param reportTable the GATKReport table containing data for this table
   * @param rgTable the map representing this table
   */
  private void parseReadGroupTable(
      final GATKReportTable reportTable, final NestedIntegerArray<RecalDatum> rgTable) {
    for (int i = 0; i < reportTable.getNumRows(); i++) {
      final Object rg = reportTable.get(i, RecalUtils.READGROUP_COLUMN_NAME);
      tempRGarray[0] = requestedCovariates[0].keyFromValue(rg);
      final EventType event =
          EventType.eventFrom((String) reportTable.get(i, RecalUtils.EVENT_TYPE_COLUMN_NAME));
      tempRGarray[1] = event.ordinal();

      rgTable.put(getRecalDatum(reportTable, i, true), tempRGarray);
    }
  }
  /**
   * Compiles the list of keys for the QualityScore table and uses the shared parsing utility to
   * produce the actual table
   *
   * @param reportTable the GATKReport table containing data for this table
   * @param qualTable the map representing this table
   */
  private void parseQualityScoreTable(
      final GATKReportTable reportTable, final NestedIntegerArray<RecalDatum> qualTable) {
    for (int i = 0; i < reportTable.getNumRows(); i++) {
      final Object rg = reportTable.get(i, RecalUtils.READGROUP_COLUMN_NAME);
      tempQUALarray[0] = requestedCovariates[0].keyFromValue(rg);
      final Object qual = reportTable.get(i, RecalUtils.QUALITY_SCORE_COLUMN_NAME);
      tempQUALarray[1] = requestedCovariates[1].keyFromValue(qual);
      final EventType event =
          EventType.eventFrom((String) reportTable.get(i, RecalUtils.EVENT_TYPE_COLUMN_NAME));
      tempQUALarray[2] = event.ordinal();

      qualTable.put(getRecalDatum(reportTable, i, false), tempQUALarray);
    }
  }