/**
  * Do the full tangent normalization process given proportional coverage data.
  *
  * <p>This includes:
  *
  * <ul>
  *   <li>normalization by target factors
  *   <li>projection of the normalized coverage profile into the hyperplane from the PoN
  * </ul>
  *
  * @param pon -- never {@code null}
  * @param pcov -- never {@code null}. Must contain data for at least one sample.
  * @param ctx spark context. Use {@code null} if no context is available
  * @return never {@code null}
  */
 public static TangentNormalizationResult tangentNormalizePcov(
     final PoN pon, final ReadCountCollection pcov, final JavaSparkContext ctx) {
   Utils.nonNull(pon, "PoN cannot be null.");
   Utils.nonNull(pcov, "input pcov read counts cannot be null when creating a coverage profile.");
   ParamUtils.isPositive(
       pcov.columnNames().size(), "input cov profile column names cannot be an empty list.");
   final ReadCountCollection coverageProfile = createCoverageProfile(pon, pcov);
   return TangentNormalizer.tangentNormalize(pon, coverageProfile, ctx);
 }
  /**
   * Project all of the normals used to create the PoN into the reduced panel.
   *
   * @param pon Not {@code null}.
   * @param ctx Spark context, {@code null} indicates no spark context available, which is
   *     supported.
   * @return never {@code null}. Result will contain multiple columns in each of the
   *     ReadCountCollection attributes.
   */
  public static TangentNormalizationResult tangentNormalizeNormalsInPoN(
      final PoN pon, final JavaSparkContext ctx) {
    // Get the list of sample names in a modifiable List
    final List<String> sampleNamesCopy = new ArrayList<>(pon.getSampleNames());

    logger.info("Loading normalized counts...");
    final ReadCountCollection coverageProfile =
        new ReadCountCollection(
            SetUniqueList.setUniqueList(pon.getTargets()),
            SetUniqueList.setUniqueList(sampleNamesCopy),
            pon.getNormalizedCounts());

    logger.info("Tangent normalizing the normals (normalized by target factors) ...");

    // For each sample in the PoN, tangent normalize against the qc reduced PoN.
    return TangentNormalizer.tangentNormalize(pon, coverageProfile, ctx);
  }
 /**
  * {@link TangentNormalizer :: tangentNormalizePcov} with no spark context
  *
  * @param pon never {@code null}. Must contain data for at least one sample.
  * @param pcov never {@code null}. Must contain data for at least one sample.
  * @return never {@code null}
  */
 public static TangentNormalizationResult tangentNormalizePcov(
     final PoN pon, final ReadCountCollection pcov) {
   return TangentNormalizer.tangentNormalizePcov(pon, pcov, null);
 }