@@ -23,11 +23,14 @@ import com.google.privacy.differentialprivacy.pipelinedp4j.core.DpEngine
2323import com.google.privacy.differentialprivacy.pipelinedp4j.core.DpEngineBudgetSpec
2424import com.google.privacy.differentialprivacy.pipelinedp4j.core.Encoder
2525import com.google.privacy.differentialprivacy.pipelinedp4j.core.EncoderFactory
26+ import com.google.privacy.differentialprivacy.pipelinedp4j.core.FeatureSpec
2627import com.google.privacy.differentialprivacy.pipelinedp4j.core.FeatureValuesExtractor
2728import com.google.privacy.differentialprivacy.pipelinedp4j.core.FrameworkCollection
2829import com.google.privacy.differentialprivacy.pipelinedp4j.core.FrameworkTable
2930import com.google.privacy.differentialprivacy.pipelinedp4j.core.MetricType
31+ import com.google.privacy.differentialprivacy.pipelinedp4j.core.ScalarFeatureSpec
3032import com.google.privacy.differentialprivacy.pipelinedp4j.core.SelectPartitionsParams
33+ import com.google.privacy.differentialprivacy.pipelinedp4j.core.VectorFeatureSpec
3134import com.google.privacy.differentialprivacy.pipelinedp4j.proto.DpAggregates
3235import com.google.privacy.differentialprivacy.pipelinedp4j.proto.PerFeature
3336import com.google.privacy.differentialprivacy.pipelinedp4j.proto.copy
@@ -494,22 +497,53 @@ protected constructor(
494497 valueAggregations : ValueAggregations <* >? ,
495498 vectorAggregations : VectorAggregations <* >? ,
496499 ): AggregationParams {
497- val valueContributionBounds = valueAggregations?.contributionBounds
498- val vectorContributionBounds = vectorAggregations?.vectorContributionBounds
500+ val nonFeatureMetrics =
501+ aggregationSpecs
502+ .filter { it is Count || it is PrivacyIdCount }
503+ .map { it.toNonFeatureMetricDefinition() }
504+ val features =
505+ buildList<FeatureSpec > {
506+ if (valueAggregations != null ) {
507+ val valueContributionBounds = valueAggregations.contributionBounds
508+ add(
509+ ScalarFeatureSpec (
510+ featureId = valueAggregations.getFeatureId(),
511+ metrics =
512+ valueAggregations.valueAggregationSpecs
513+ .map { it.toMetricDefinition() }
514+ .toImmutableList(),
515+ minValue = valueContributionBounds.valueBounds?.minValue,
516+ maxValue = valueContributionBounds.valueBounds?.maxValue,
517+ minTotalValue = valueContributionBounds.totalValueBounds?.minValue,
518+ maxTotalValue = valueContributionBounds.totalValueBounds?.maxValue,
519+ )
520+ )
521+ }
522+ if (vectorAggregations != null ) {
523+ val vectorContributionBounds = vectorAggregations.vectorContributionBounds
524+ add(
525+ VectorFeatureSpec (
526+ featureId = vectorAggregations.getFeatureId(),
527+ metrics =
528+ vectorAggregations.vectorAggregationSpecs
529+ .map { it.toMetricDefinition() }
530+ .toImmutableList(),
531+ vectorSize = vectorAggregations.vectorSize,
532+ normKind = vectorContributionBounds.maxVectorTotalNorm.normKind.toInternalNormKind(),
533+ vectorMaxTotalNorm = vectorContributionBounds.maxVectorTotalNorm.value,
534+ )
535+ )
536+ }
537+ }
538+
499539 return AggregationParams (
500- metrics = ImmutableList .copyOf(aggregationSpecs.metrics()),
540+ nonFeatureMetrics = nonFeatureMetrics.toImmutableList(),
541+ features = features.toImmutableList(),
501542 noiseKind =
502543 checkNotNull(noiseKind) { " noiseKind cannot be null if there are aggregations." }
503544 .toInternalNoiseKind(),
504545 maxPartitionsContributed = contributionBoundingLevel.getMaxPartitionsContributed(),
505546 maxContributionsPerPartition = contributionBoundingLevel.getMaxContributionsPerPartition(),
506- minValue = valueContributionBounds?.valueBounds?.minValue,
507- maxValue = valueContributionBounds?.valueBounds?.maxValue,
508- minTotalValue = valueContributionBounds?.totalValueBounds?.minValue,
509- maxTotalValue = valueContributionBounds?.totalValueBounds?.maxValue,
510- vectorNormKind = vectorContributionBounds?.maxVectorTotalNorm?.normKind?.toInternalNormKind(),
511- vectorMaxTotalNorm = vectorContributionBounds?.maxVectorTotalNorm?.value,
512- vectorSize = vectorAggregations?.vectorSize,
513547 partitionSelectionBudget = groupsType.getBudget()?.toInternalBudgetPerOpSpec(),
514548 preThreshold = groupsType.getPreThreshold(),
515549 contributionBoundingLevel = contributionBoundingLevel.toInternalContributionBoundingLevel(),
@@ -534,3 +568,5 @@ protected constructor(
534568 }
535569 }
536570}
571+
572+ private fun <T : Any > Iterable<T>.toImmutableList (): ImmutableList <T > = ImmutableList .copyOf(this )
0 commit comments