Skip to content

Commit

Permalink
Merge pull request #295 from NOAA-OWP/issue36
Browse files Browse the repository at this point in the history
Issue36
  • Loading branch information
james-d-brown authored Aug 29, 2024
2 parents 0d7eafb + 27f236d commit bc99397
Show file tree
Hide file tree
Showing 38 changed files with 813 additions and 202 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import java.time.ZoneId
/* Used by gradle plugins outside the official gradle plugins repository */
buildscript {

// Work around for missing transitive dependency for plugin org.kordamp.gradle.markdown
// Workaround for missing transitive dependency for plugin org.kordamp.gradle.markdown
// https://github.com/kordamp/markdown-gradle-plugin/issues/36
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute module("com.overzealous:remark:1.1.0") using module( 'com.wavefront:remark:2023-07.07' ) because "not available on maven central anymore"
substitute module( 'com.overzealous:remark:1.1.0' ) using module( 'com.wavefront:remark:2023-07.07' ) because "not available on maven central anymore"
}
}
repositories {
Expand Down
283 changes: 231 additions & 52 deletions src/wres/pipeline/pooling/PoolFactory.java

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion test/wres/pipeline/EvaluationUtilitiesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import wres.config.yaml.components.EvaluationDeclaration;
import wres.config.yaml.components.EvaluationDeclarationBuilder;
import wres.config.yaml.components.FeatureGroups;
import wres.config.yaml.components.FeatureGroupsBuilder;
import wres.config.yaml.components.LeadTimeInterval;
import wres.config.yaml.components.ThresholdBuilder;
import wres.config.yaml.components.ThresholdType;
Expand Down Expand Up @@ -268,7 +269,9 @@ void testGetSummaryStatisticsCalculatorsWithTwoTimeWindowsAcrossFeatureGroups()

Set<GeometryGroup> geometryGroups = Set.of( firstGroup, secondGroup );

FeatureGroups featureGroups = new FeatureGroups( geometryGroups );
FeatureGroups featureGroups = FeatureGroupsBuilder.builder()
.geometryGroups( geometryGroups )
.build();

EvaluationDeclaration evaluation = EvaluationDeclarationBuilder.builder()
.leadTimes( leadTimeInterval )
Expand Down

This file was deleted.

33 changes: 19 additions & 14 deletions wres-config/nonsrc/schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -566,9 +566,9 @@ definitions:
cross-pairing chosen."
anyOf:
- "$ref": "#/definitions/CrossPairEnum"
- "$ref": "#/definitions/CrossPairFull"
- "$ref": "#/definitions/CrossPairWithParameters"

CrossPairFull:
CrossPairWithParameters:
type: object
additionalProperties: false
properties:
Expand Down Expand Up @@ -665,25 +665,25 @@ definitions:
properties:
observed:
anyOf:
- "$ref": "#/definitions/FeatureTupleFull"
- "$ref": "#/definitions/FeatureWithParameters"
- type: string
minLength: 1
maxLength: 32
predicted:
anyOf:
- "$ref": "#/definitions/FeatureTupleFull"
- "$ref": "#/definitions/FeatureWithParameters"
- type: string
minLength: 1
maxLength: 32
baseline:
anyOf:
- "$ref": "#/definitions/FeatureTupleFull"
- "$ref": "#/definitions/FeatureWithParameters"
- type: string
minLength: 1
maxLength: 32

FeatureTupleFull:
title: A feature tuple with additional properties
FeatureWithParameters:
title: A feature with additional properties
type: object
additionalProperties: false
properties:
Expand All @@ -695,6 +695,8 @@ definitions:
type: string
minLength: 1
maxLength: 2083
offset:
type: number
required:
- name

Expand Down Expand Up @@ -1487,13 +1489,16 @@ definitions:
is present, evaluates common events by reference time and valid time. If
absent, retains all events of each type. With fuzzy matching, each time-
series is matched with its nearest, corresponding, time-series according to
the total duration between all reference times of a corresponding type. In
other words, if there is an exact match, that will be used, else the time-
series whose reference times are nearest overall. Once a time-series has
been matched, it cannot be re-used. Always uses exact matching for valid
times. The scope of the cross-pairing always includes the predicted and
baseline datasets, where defined, and may be further controlled using the
'scope' parameter."
the total duration between all reference times across the candidate time-
series. In other words, if there is an exact match, that will be used, else
the time-series whose reference times are nearest overall. With exact
matching, both the type of reference time and the time itself must
correspond. With fuzzy matching, all types of reference time are considered
equal and hence used to calculate the total duration between all reference
times of the candidate series. Once a time-series has been matched, it
cannot be re-used. Always uses exact matching for valid times. The scope of
the cross-pairing always includes the predicted and baseline datasets, where
defined, and may be further controlled using the 'scope' parameter."
type: string
enum:
- exact
Expand Down
4 changes: 2 additions & 2 deletions wres-config/src/wres/config/yaml/DeclarationFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,11 @@ public class DeclarationFactory
.enable( DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY )
.enable( DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY )
.enable( JsonParser.Feature.STRICT_DUPLICATE_DETECTION )
.disable( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES )
.build()
.registerModule( new ProtobufModule() )
.registerModule( new JavaTimeModule() )
.configure( DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES,
true );
.enable( DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES );

/** Mapper for serialization. */
private static final ObjectMapper SERIALIZER =
Expand Down
8 changes: 6 additions & 2 deletions wres-config/src/wres/config/yaml/DeclarationInterpolator.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import wres.config.yaml.components.EvaluationDeclarationBuilder;
import wres.config.yaml.components.FeatureAuthority;
import wres.config.yaml.components.FeatureGroups;
import wres.config.yaml.components.FeatureGroupsBuilder;
import wres.config.yaml.components.Features;
import wres.config.yaml.components.FeaturesBuilder;
import wres.config.yaml.components.Formats;
Expand Down Expand Up @@ -486,7 +487,8 @@ private static void interpolateSparseFeatures( EvaluationDeclarationBuilder buil
.geometries();
Set<GeometryTuple> denseFeatures = DeclarationInterpolator.interpolateSparseFeatures( features,
hasBaseline );
Features adjustedFeatures = new Features( denseFeatures );
Features adjustedFeatures = new Features( denseFeatures, builder.features()
.offsets() );
builder.features( adjustedFeatures );
}

Expand All @@ -512,7 +514,9 @@ private static void interpolateSparseFeatures( EvaluationDeclarationBuilder buil
.build();
adjustedGeoGroups.add( nextAdjustedGroup );
}
FeatureGroups adjustedFeatureGroups = new FeatureGroups( adjustedGeoGroups );
FeatureGroups adjustedFeatureGroups = FeatureGroupsBuilder.builder()
.geometryGroups( adjustedGeoGroups )
.build();
builder.featureGroups( adjustedFeatureGroups );
}
}
Expand Down
10 changes: 8 additions & 2 deletions wres-config/src/wres/config/yaml/DeclarationMigrator.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,12 @@
import wres.config.yaml.components.EvaluationDeclarationBuilder;
import wres.config.yaml.components.FeatureAuthority;
import wres.config.yaml.components.FeatureGroups;
import wres.config.yaml.components.FeatureGroupsBuilder;
import wres.config.yaml.components.FeatureService;
import wres.config.yaml.components.FeatureServiceBuilder;
import wres.config.yaml.components.FeatureServiceGroup;
import wres.config.yaml.components.Features;
import wres.config.yaml.components.FeaturesBuilder;
import wres.config.yaml.components.Format;
import wres.config.yaml.components.Formats;
import wres.config.yaml.components.GeneratedBaseline;
Expand Down Expand Up @@ -293,7 +295,9 @@ private static void migrateFeatures( List<NamedFeature> features, EvaluationDecl
if ( !features.isEmpty() )
{
Set<GeometryTuple> geometries = DeclarationMigrator.migrateFeatures( features );
Features wrappedFeatures = new Features( geometries );
Features wrappedFeatures = FeaturesBuilder.builder()
.geometries( geometries )
.build();
builder.features( wrappedFeatures );
}
}
Expand All @@ -312,7 +316,9 @@ private static void migrateFeatureGroups( List<FeaturePool> featureGroups, Evalu
featureGroups.stream()
.map( DeclarationMigrator::migrateFeatureGroup )
.collect( Collectors.toSet() );
FeatureGroups wrappedGroups = new FeatureGroups( geometryGroups );
FeatureGroups wrappedGroups = FeatureGroupsBuilder.builder()
.geometryGroups( geometryGroups )
.build();
builder.featureGroups( wrappedGroups );
}
}
Expand Down
8 changes: 6 additions & 2 deletions wres-config/src/wres/config/yaml/DeclarationUtilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import wres.config.yaml.components.EvaluationDeclarationBuilder;
import wres.config.yaml.components.FeatureAuthority;
import wres.config.yaml.components.FeatureGroups;
import wres.config.yaml.components.FeatureGroupsBuilder;
import wres.config.yaml.components.FeatureServiceGroup;
import wres.config.yaml.components.Features;
import wres.config.yaml.components.LeadTimeInterval;
Expand Down Expand Up @@ -2243,7 +2244,8 @@ private static EvaluationDeclaration removeFeaturesWithoutThresholds( Evaluation
.collect( Collectors.toSet() );

// Set the new features
Features filteredFeatures = new Features( filtered );
Features filteredFeatures = new Features( filtered, declaration.features()
.offsets() );
builder.features( filteredFeatures );

if ( LOGGER.isWarnEnabled()
Expand Down Expand Up @@ -2305,7 +2307,9 @@ private static EvaluationDeclaration removeFeaturesWithoutThresholds( Evaluation
.toList() );
}

FeatureGroups finalFeatureGroups = new FeatureGroups( adjustedGroups );
FeatureGroups finalFeatureGroups = FeatureGroupsBuilder.builder()
.geometryGroups( adjustedGroups )
.build();
builder.featureGroups( finalFeatureGroups );
}

Expand Down
1 change: 0 additions & 1 deletion wres-config/src/wres/config/yaml/DeclarationValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,6 @@ private static List<EvaluationStatusEvent> validateDatasets( EvaluationDeclarati
// Data types are valid
List<EvaluationStatusEvent> typesValid = DeclarationValidator.typesAreValid( declaration );
events.addAll( typesValid );

// Ensembles cannot be present on both left and right sides
List<EvaluationStatusEvent> ensembles = DeclarationValidator.ensembleOnOneSideOnly( declaration );
events.addAll( ensembles );
Expand Down
19 changes: 17 additions & 2 deletions wres-config/src/wres/config/yaml/components/FeatureGroups.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package wres.config.yaml.components;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.StringJoiner;
Expand All @@ -14,15 +16,18 @@
import wres.config.yaml.deserializers.FeatureGroupsDeserializer;
import wres.config.yaml.serializers.FeatureGroupsSerializer;
import wres.statistics.generated.GeometryGroup;
import wres.statistics.generated.GeometryTuple;

/**
* Geographic feature groups.
* Geographic feature groups and associated offset values (e.g., datum offsets). Absence of an offset for a given
* feature with a group implies no/zero offset.
* @param geometryGroups the feature groups
* @param offsets the offset values associated with features in the group, such as a datum offset, if any
*/
@RecordBuilder
@JsonSerialize( using = FeatureGroupsSerializer.class )
@JsonDeserialize( using = FeatureGroupsDeserializer.class )
public record FeatureGroups( Set<GeometryGroup> geometryGroups )
public record FeatureGroups( Set<GeometryGroup> geometryGroups, Map<GeometryTuple, Offset> offsets )
{
/**
* Sets the default values.
Expand All @@ -40,6 +45,16 @@ public record FeatureGroups( Set<GeometryGroup> geometryGroups )
// Immutable copy, preserving insertion order
geometryGroups = Collections.unmodifiableSet( new LinkedHashSet<>( geometryGroups ) );
}

if ( Objects.isNull( offsets ) )
{
offsets = Collections.emptyMap();
}
else
{
// Immutable copy, preserving insertion order
offsets = Collections.unmodifiableMap( new LinkedHashMap<>( offsets ) );
}
}

@Override
Expand Down
18 changes: 16 additions & 2 deletions wres-config/src/wres/config/yaml/components/Features.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package wres.config.yaml.components;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.StringJoiner;
Expand All @@ -16,13 +18,15 @@
import wres.statistics.generated.GeometryTuple;

/**
* Geographic features.
* Geographic features and associated offset values (e.g., datum offsets). Absence of an offset for a given feature
* implies no/zero offset.
* @param geometries the features
* @param offsets the offset values, such as a datum offset, if any
*/
@RecordBuilder
@JsonSerialize( using = FeaturesSerializer.class )
@JsonDeserialize( using = FeaturesDeserializer.class )
public record Features( Set<GeometryTuple> geometries )
public record Features( Set<GeometryTuple> geometries, Map<GeometryTuple,Offset> offsets )
{
/**
* Sets the default values.
Expand All @@ -39,6 +43,16 @@ public record Features( Set<GeometryTuple> geometries )
// Immutable copy, preserving insertion order
geometries = Collections.unmodifiableSet( new LinkedHashSet<>( geometries ) );
}

if ( Objects.isNull( offsets ) )
{
offsets = Collections.emptyMap();
}
else
{
// Immutable copy, preserving insertion order
offsets = Collections.unmodifiableMap( new LinkedHashMap<>( offsets ) );
}
}

@Override
Expand Down
11 changes: 11 additions & 0 deletions wres-config/src/wres/config/yaml/components/Offset.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package wres.config.yaml.components;

/**
* The offset value to apply to each dataset orientation. For example, a datum offset.
* @param left the left-oriented offset
* @param right the right-oriented offset
* @param baseline the baseline-oriented offset
*/
public record Offset( double left, double right, double baseline )
{
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package wres.config.yaml.deserializers;

import java.io.IOException;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

Expand All @@ -16,7 +17,9 @@
import org.slf4j.LoggerFactory;

import wres.config.yaml.components.FeatureGroups;
import wres.config.yaml.components.FeatureGroupsBuilder;
import wres.config.yaml.components.Features;
import wres.config.yaml.components.Offset;
import wres.statistics.generated.GeometryGroup;
import wres.statistics.generated.GeometryTuple;

Expand Down Expand Up @@ -71,14 +74,15 @@ private FeatureGroups getFeatureGroupsFromArray( ObjectReader reader,
{
// Preserve insertion order
Set<GeometryGroup> featureGroups = new LinkedHashSet<>();
Map<GeometryTuple, Offset> featureOffsets = new LinkedHashMap<>();

int nodeCount = featureGroupsNode.size();

for ( int i = 0; i < nodeCount; i++ )
{
JsonNode nextNode = featureGroupsNode.get( i );
String groupName = "";
Set<GeometryTuple> geometries = null;

// Group name
if ( nextNode.has( "name" ) )
{
Expand All @@ -95,8 +99,9 @@ private FeatureGroups getFeatureGroupsFromArray( ObjectReader reader,
parser.setCodec( reader );
Features features = FEATURES_DESERIALIZER.deserialize( parser, context );
geometries = features.geometries();
featureOffsets.putAll( features.offsets() );
LOGGER.debug( "Discovered the following collection of geometries associated with a feature group "
+ "named '{}': {}.", groupName, new Features( geometries ) );
+ "named '{}': {}.", groupName, features );
}

// Create the group
Expand All @@ -110,6 +115,9 @@ private FeatureGroups getFeatureGroupsFromArray( ObjectReader reader,
}
}

return new FeatureGroups( Collections.unmodifiableSet( featureGroups ) );
return FeatureGroupsBuilder.builder()
.geometryGroups( featureGroups )
.offsets( featureOffsets )
.build();
}
}
Loading

0 comments on commit bc99397

Please sign in to comment.