Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 42 additions & 4 deletions cdm/core/src/main/java/ucar/nc2/dataset/VariableDS.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2018 John Caron and University Corporation for Atmospheric Research/Unidata
* Copyright (c) 1998-2025 John Caron and University Corporation for Atmospheric Research/Unidata
* See LICENSE for license information.
*/
package ucar.nc2.dataset;
Expand Down Expand Up @@ -494,9 +494,28 @@ protected Array _read(Section section) throws IOException, InvalidRangeException
// do not call directly
@Override
public Array reallyRead(Variable client, CancelTask cancelTask) throws IOException {
if (orgVar == null)
if (orgVar == null) {
// possible aggregation
if (this.proxyReader != null && this.proxyReader instanceof ucar.nc2.ncml.Aggregation) {
return this.proxyReader.reallyRead(client, cancelTask);
}
return getMissingDataArray(shape);
}

if (client instanceof CoordinateAxis) {
// If orgVar is a VariableDS (orgVar of a CoordinateAxis using the non-builder
// API, for example), call reallyRead on it, otherwise, enhancements will get
// applied twice in a second _read() call triggered by calling read() on the
// VariableDS.
if (orgVar instanceof VariableDS && !orgVar.hasCachedData()) {
return orgVar.reallyRead(client, cancelTask);
}
// Some aggregations use a DatasetProxyReader for reading a coordinate axis
// variable, so check to see if that's what we have and, if so, use it.
if (ucar.nc2.ncml.Aggregation.instanceOfDatasetProxyReader(this.proxyReader)) {
return this.proxyReader.reallyRead(client, cancelTask);
}
}
return orgVar.read();
}

Expand All @@ -508,9 +527,28 @@ public Array reallyRead(Variable client, Section section, CancelTask cancelTask)
if ((null == section) || section.computeSize() == getSize())
return reallyRead(client, cancelTask);

if (orgVar == null)
return getMissingDataArray(section.getShape());
if (orgVar == null) {
// possible aggregation
if (this.proxyReader != null && this.proxyReader instanceof ucar.nc2.ncml.Aggregation) {
return this.proxyReader.reallyRead(client, section, cancelTask);
}
return getMissingDataArray(shape);
}

if (client instanceof CoordinateAxis) {
// If orgVar is a VariableDS (orgVar of a CoordinateAxis using the non-builder
// API, for example), call reallyRead on it, otherwise, enhancements will get
// applied twice in a second _read() call triggered by calling read() on the
// VariableDS.
if (orgVar instanceof VariableDS && !orgVar.hasCachedData()) {
return orgVar.reallyRead(client, section, cancelTask);
}
// Some aggregations use a DatasetProxyReader for reading a coordinate axis
// variable, so check to see if that's what we have and, if so, use it.
if (ucar.nc2.ncml.Aggregation.instanceOfDatasetProxyReader(this.proxyReader)) {
return this.proxyReader.reallyRead(client, section, cancelTask);
}
}
return orgVar.read(section);
}

Expand Down
7 changes: 6 additions & 1 deletion cdm/core/src/main/java/ucar/nc2/ncml/Aggregation.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2020 John Caron and University Corporation for Atmospheric Research/Unidata
* Copyright (c) 1998-2025 John Caron and University Corporation for Atmospheric Research/Unidata
* See LICENSE.txt for license information.
*/
package ucar.nc2.ncml;
Expand Down Expand Up @@ -777,6 +777,11 @@ protected void setDatasetAcquireProxy(DatasetProxyReader proxy, Group g) throws
}
}

public static boolean instanceOfDatasetProxyReader(Object obj) {
if (obj == null)
return false;
return obj instanceof DatasetProxyReader;
}

protected class DatasetProxyReader implements ProxyReader {
Dataset dataset;
Expand Down
Binary file added cdm/core/src/test/data/scaledCoordAxis1D.nc4
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2025 University Corporation for Atmospheric Research/Unidata
* See LICENSE.txt for license information.
*/
package ucar.nc2.dataset;

import java.io.IOException;
import java.util.Objects;
import org.junit.Test;
import ucar.ma2.Array;
import ucar.nc2.Attribute;
import ucar.nc2.NetcdfFile;
import ucar.nc2.NetcdfFiles;
import ucar.nc2.Variable;
import ucar.nc2.constants.AxisType;
import ucar.unidata.util.test.TestDir;
import static com.google.common.truth.Truth.assertThat;

public class TestScaledCoordAxis1D {

@Test
public void testEnhancedOnce() throws IOException {
String testfile = TestDir.cdmLocalTestDataDir + "scaledCoordAxis1D.nc4";
try (NetcdfFile ncf = NetcdfFile.open(testfile, null); NetcdfDataset ncd = NetcdfDataset.openDataset(testfile)) {
checkAxis(ncf, ncd, "x", AxisType.GeoX);
checkAxis(ncf, ncd, "y", AxisType.GeoY);
}
}

@Test
public void testEnhancedOnceBuilders() throws IOException {
String testfile = TestDir.cdmLocalTestDataDir + "scaledCoordAxis1D.nc4";
try (NetcdfFile ncf = NetcdfFiles.open(testfile, null); NetcdfDataset ncd = NetcdfDatasets.openDataset(testfile)) {
checkAxis(ncf, ncd, "x", AxisType.GeoX);
checkAxis(ncf, ncd, "y", AxisType.GeoY);
}
}

public void checkAxis(NetcdfFile ncf, NetcdfDataset ncd, String axisName, AxisType axisType) throws IOException {
Variable var = ncf.findVariable(axisName);
assertThat(var != null).isTrue();
Array vals = var.read();
Attribute scaleAttr = var.findAttribute("scale_factor");
assertThat(scaleAttr).isNotNull();
float scale = Objects.requireNonNull(scaleAttr.getNumericValue()).floatValue();
Attribute offsetAttr = var.findAttribute("add_offset");
assertThat(offsetAttr).isNotNull();
float offset = Objects.requireNonNull(offsetAttr.getNumericValue()).floatValue();
assertThat(vals.getShape().length).isEqualTo(1);
int len = vals.getShape()[0];
final float[] valsEnhanced = new float[len];
for (int i = 0; i < len; i++) {
valsEnhanced[i] = vals.getShort(i) * scale + offset;
}
// vals have a scale and offset.
assertThat(vals).isNotNull();
CoordinateAxis coodAxis = ncd.findCoordinateAxis(axisType);
Array coordVals = coodAxis.read();
for (int i = 0; i < len; i++) {
assertThat(coordVals.getFloat(i)).isWithin(1e-6f).of(valsEnhanced[i]);
}
}
}