/**
  * Checks whether all targets in the input target collection have a designated name.
  *
  * @param result the query target collection.
  * @throws UserException if there are some targets with no name in {@code result}.
  */
 private void checkAllTargetsHaveName(TargetCollection<Target> result) {
   if (result.targets().stream().anyMatch(t -> t.getName() == null || t.getName().equals(""))) {
     throw new UserException(
         String.format(
             "Target output info requested '%s' requires that each target has a designated unique name/id but there are some with no names: %s",
             targetOutInfo.name(),
             result
                 .targets()
                 .stream()
                 .filter(t -> t.getName() == null || t.getName().equals(""))
                 .limit(10)
                 .map(e -> result.location(e).toString())
                 .collect(Collectors.joining(", "))));
   }
 }
 /**
  * Composes the main output header.
  *
  * @param commandLine the tool command line.
  * @param groupBy the group-by argument used.
  * @param countColumnNames the column names.
  * @return never {@code null}.
  */
 private static String composeMatrixOutputHeader(
     final String commandLine,
     final TargetOutInfo targetOutInfo,
     final GroupBy groupBy,
     final List<String> countColumnNames) {
   final String countColumnHeaderString =
       String.join(COLUMN_SEPARATOR, countColumnNames).replace("%", "%%");
   final String formatString =
       String.join(
           LINE_SEPARATOR,
           "##fileFormat  = tsv",
           "##commandLine = %s",
           "##title       = Read counts per target and %s",
           String.join(COLUMN_SEPARATOR, targetOutInfo.headerString(), countColumnHeaderString));
   return String.format(formatString, commandLine, groupBy.toString());
 }
  /**
   * Builds the target collection given the values of user arguments.
   *
   * @throws UserException if there is some inconsistency in user arguments and inputs.
   * @throws GATKException if there was any problem parsing the content of the targets file.
   * @return never {@code null}.
   */
  private TargetCollection<Target> resolveTargetCollection() {
    final TargetCollection<Target> result;
    if (targetsFile != null) {
      result = resolveTargetsFromFile();
    } else if (hasIntervals()) {
      final SAMSequenceDictionary sequenceDictionary = getBestAvailableSequenceDictionary();
      final List<SimpleInterval> intervals =
          intervalArgumentCollection.getIntervals(sequenceDictionary);

      // this constructor automatically generates target names from the intervals
      final List<Target> targets = intervals.stream().map(Target::new).collect(Collectors.toList());
      result = new HashedListTargetCollection<>(targets);
    } else {
      throw new UserException(
          String.format(
              "You must indicate the set of target as input intervals (e.g. -L target-intervals.list) or a target feature file (e.g. -%s my-targets.tsv) ",
              TARGET_FILE_SHORT_NAME));
    }
    if (targetOutInfo.requiresUniqueTargetName()) {
      checkAllTargetsHaveName(result);
    }
    return result;
  }
 /**
  * Composes the row summary output header.
  *
  * @param commandLine the execution command line.
  * @param groupBy the value of the group-by argument used.
  * @param columnCount number of count-column involved in the analysis.
  * @return never {@code null}.
  */
 private static String composeRowOutputHeader(
     final String commandLine,
     final TargetOutInfo targetOutInfo,
     final GroupBy groupBy,
     final int columnCount) {
   return String.format(
       String.join(
           LINE_SEPARATOR,
           "##fileFormat  = tsv",
           "##commandLine = %s",
           "##title       = Summary counts per target",
           "##metaData = {",
           "##    groupBy     = %s,",
           "##    columnCount = %d",
           "##}",
           String.join(
               COLUMN_SEPARATOR,
               targetOutInfo.headerString(),
               SUM_COLUMN_NAME,
               AVG_COL_BP_COLUMN_NAME)),
       commandLine,
       groupBy,
       columnCount);
 }
  /**
   * Writes the row in the main matrix output file for a target and, if requested, the corresponding
   * row in the row summary output file.
   *
   * @param countBuffer the counts for the target.
   * @param index the index of target within the target collection.
   */
  private void writeOutputRows(
      final int[] countBuffer, final long[] columnTotals, final int index) {
    final String countString =
        IntStream.range(0, countBuffer.length)
            .mapToObj(i -> transform.apply(countBuffer[i], columnTotals[i]))
            .collect(Collectors.joining(COLUMN_SEPARATOR));
    final String targetInfoString =
        targetOutInfo.composeTargetOutInfoString(index, targetCollection);

    outputWriter.println(String.join(COLUMN_SEPARATOR, targetInfoString, countString));

    if (rowSummaryOutputWriter != null) {
      final long sum = MathUtils.sum(countBuffer);
      final SimpleInterval location = targetCollection.location(index);
      final int targetSize = location.size();
      rowSummaryOutputWriter.println(
          String.join(
              COLUMN_SEPARATOR,
              targetInfoString,
              Long.toString(sum),
              String.format(
                  AVERAGE_DOUBLE_FORMAT, sum / ((float) countColumns.columnCount() * targetSize))));
    }
  }