Skip to content

Commit 1177347

Browse files
committed
added extraction of multi-dimensional variables
1 parent ae081de commit 1177347

File tree

6 files changed

+247
-13
lines changed

6 files changed

+247
-13
lines changed

core/src/main/java/com/bc/fiduceo/reader/smos/SmosL1CDailyGriddedReader.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,8 @@ public Array readScaled(int centerX, int centerY, Interval interval, String vari
279279
final int extensionIdx = variableName.lastIndexOf("_");
280280
ncVariableName = variableName.substring(0, extensionIdx);
281281
}
282-
double scaleFactor = arrayCache.getNumberAttributeValue("scale_factor", ncVariableName).doubleValue();
283-
double offset = arrayCache.getNumberAttributeValue("add_offset", ncVariableName).doubleValue();
282+
final double scaleFactor = arrayCache.getNumberAttributeValue("scale_factor", ncVariableName).doubleValue();
283+
final double offset = arrayCache.getNumberAttributeValue("add_offset", ncVariableName).doubleValue();
284284
if (ReaderUtils.mustScale(scaleFactor, offset)) {
285285
final MAMath.ScaleOffset scaleOffset = new MAMath.ScaleOffset(scaleFactor, offset);
286286
return MAMath.convert2Unpacked(rawArray, scaleOffset);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.bc.fiduceo.reader.windsat;
2+
3+
class ArrayInfo {
4+
5+
String ncVarName;
6+
int lookIdx;
7+
int polIdx;
8+
int freqIdx;
9+
10+
public ArrayInfo() {
11+
lookIdx = -1;
12+
polIdx = -1;
13+
freqIdx = -1;
14+
}
15+
}

core/src/main/java/com/bc/fiduceo/reader/windsat/WindsatReader.java

Lines changed: 94 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@
1515
import com.bc.fiduceo.util.NetCDFUtils;
1616
import com.bc.fiduceo.util.TimeUtils;
1717
import com.bc.fiduceo.util.VariableProxy;
18-
import ucar.ma2.Array;
19-
import ucar.ma2.ArrayInt;
20-
import ucar.ma2.DataType;
21-
import ucar.ma2.InvalidRangeException;
18+
import ucar.ma2.*;
2219
import ucar.nc2.Variable;
2320

2421
import java.io.File;
@@ -48,6 +45,32 @@ class WindsatReader extends NetCDFReader {
4845
variables2D.add("land_fraction_10");
4946
}
5047

48+
static ArrayInfo extractArrayInfo(String mmsVariableName) {
49+
final ArrayInfo arrayInfo = new ArrayInfo();
50+
51+
final int viewIdx = mmsVariableName.lastIndexOf("_");
52+
final String view = mmsVariableName.substring(viewIdx + 1);
53+
arrayInfo.lookIdx = getIndex(view, LOOKS);
54+
55+
final int extIdx = mmsVariableName.lastIndexOf("_", viewIdx - 1);
56+
final String ext = mmsVariableName.substring(extIdx + 1, viewIdx);
57+
arrayInfo.polIdx = getIndex(ext, POLARIZATIONS);
58+
arrayInfo.freqIdx = getIndex(ext, FREQ_BANDS);
59+
60+
arrayInfo.ncVarName = mmsVariableName.substring(0, extIdx);
61+
62+
return arrayInfo;
63+
}
64+
65+
static int getIndex(String value, String[] strings) {
66+
for (int i = 0; i < strings.length; i++) {
67+
if (strings[i].equals(value)) {
68+
return i;
69+
}
70+
}
71+
return -1;
72+
}
73+
5174
@Override
5275
public void open(File file) throws IOException {
5376
super.open(file);
@@ -141,23 +164,83 @@ public int[] extractYearMonthDayFromFilename(String fileName) {
141164
public Array readRaw(int centerX, int centerY, Interval interval, String variableName) throws IOException, InvalidRangeException {
142165
if (variableName.equals("fractional_orbit")) {
143166
// read x section and fill in y-direction
167+
final Array array = arrayCache.get(variableName);
168+
final int[] shape = array.getShape();
169+
final Number fillValue = NetCDFUtils.getDefaultFillValue(DataType.DOUBLE, true);
170+
171+
final int sectionWidth = interval.getX();
172+
final int sectionHeight = interval.getY();
173+
final Array resultArray = Array.factory(DataType.DOUBLE, new int[]{sectionWidth, sectionHeight});
174+
final Index index = resultArray.getIndex();
175+
176+
final int offsetX = centerX - sectionWidth / 2;
177+
178+
int writeX = 0;
179+
for (int x = offsetX; x < offsetX + sectionWidth; x++) {
180+
final double value;
181+
if (x >= 0 && x < shape[0]) {
182+
value = array.getDouble(x);
183+
} else {
184+
value = fillValue.doubleValue();
185+
}
186+
187+
for (int y = 0; y < sectionHeight; y++) {
188+
index.set(y, writeX);
189+
resultArray.setDouble(index, value);
190+
}
191+
writeX++;
192+
}
193+
194+
return resultArray;
144195
} else if (variables2D.contains(variableName)) {
145196
final Array array = arrayCache.get(variableName);
146197
final Number fillValue = arrayCache.getNumberAttributeValue(NetCDFUtils.CF_FILL_VALUE_NAME, variableName);
147198
return RawDataReader.read(centerX, centerY, interval, fillValue, array, getProductSize());
148199
} else {
149-
// - extract layer indices from variable name
150-
// - extract NetCDF file variable name
151-
// - read from ArrayCache
152-
// - create section
153-
}
200+
// extract layer indices and NetCDF file variable name from variable name
201+
final ArrayInfo arrayInfo = extractArrayInfo(variableName);
202+
203+
final Array array = arrayCache.get(arrayInfo.ncVarName);
204+
final Number fillValue = arrayCache.getNumberAttributeValue(NetCDFUtils.CF_FILL_VALUE_NAME, arrayInfo.ncVarName);
205+
206+
final int[] origin;
207+
final int[] shape;
208+
if (arrayInfo.freqIdx >= 0) {
209+
origin = new int[4];
210+
origin[2] = arrayInfo.lookIdx;
211+
origin[3] = arrayInfo.freqIdx;
212+
213+
shape = array.getShape();
214+
shape[2] = 1;
215+
shape[3] = 1;
216+
} else {
217+
origin = new int[4];
218+
origin[0] = arrayInfo.polIdx;
219+
origin[1] = arrayInfo.lookIdx;
220+
221+
shape = array.getShape();
222+
shape[0] = 1;
223+
shape[1] = 1;
224+
}
154225

155-
throw new RuntimeException("not implmented");
226+
final Array section = array.section(origin, shape).copy();
227+
return RawDataReader.read(centerX, centerY, interval, fillValue, section, getProductSize());
228+
}
156229
}
157230

158231
@Override
159232
public Array readScaled(int centerX, int centerY, Interval interval, String variableName) throws IOException, InvalidRangeException {
160-
throw new RuntimeException("not implmented");
233+
final Array rawArray = readRaw(centerX, centerY, interval, variableName);
234+
if (!variableName.startsWith("tb_")) {
235+
// everything except for the brightness temperatures is already scaled tb 2023-01-05
236+
return rawArray;
237+
}
238+
239+
final ArrayInfo arrayInfo = extractArrayInfo(variableName);
240+
final double scaleFactor = arrayCache.getNumberAttributeValue("scale_factor", arrayInfo.ncVarName).doubleValue();
241+
final double offset = arrayCache.getNumberAttributeValue("add_offset", arrayInfo.ncVarName).doubleValue();
242+
final MAMath.ScaleOffset scaleOffset = new MAMath.ScaleOffset(scaleFactor, offset);
243+
return MAMath.convert2Unpacked(rawArray, scaleOffset);
161244
}
162245

163246
@Override
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.bc.fiduceo.reader.windsat;
2+
3+
import org.junit.Test;
4+
5+
import static org.junit.Assert.assertEquals;
6+
import static org.junit.Assert.assertNull;
7+
8+
public class ArrayInfoTest {
9+
10+
@Test
11+
public void testConstruction() {
12+
final ArrayInfo arrayInfo = new ArrayInfo();
13+
14+
assertNull(arrayInfo.ncVarName);
15+
assertEquals(-1, arrayInfo.freqIdx);
16+
assertEquals(-1, arrayInfo.lookIdx);
17+
assertEquals(-1, arrayInfo.polIdx);
18+
}
19+
}

core/src/test/java/com/bc/fiduceo/reader/windsat/WindsatReaderTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,25 @@ public void testExtractYearMonthDayFromFilename() {
5858
ymd = reader.extractYearMonthDayFromFilename("RSS_WindSat_TB_L1C_r80689_20180806T174232_2018218_V08.0.nc");
5959
assertArrayEquals(new int[]{2018, 8, 6}, ymd);
6060
}
61+
62+
@Test
63+
public void testExtractArrayInfo() {
64+
ArrayInfo info = WindsatReader.extractArrayInfo("scan_angle_068_fore");
65+
assertEquals("scan_angle", info.ncVarName);
66+
assertEquals(0, info.freqIdx);
67+
assertEquals(-1, info.polIdx);
68+
assertEquals(0, info.lookIdx);
69+
70+
info = WindsatReader.extractArrayInfo("earth_azimuth_angle_107_aft");
71+
assertEquals("earth_azimuth_angle", info.ncVarName);
72+
assertEquals(1, info.freqIdx);
73+
assertEquals(-1, info.polIdx);
74+
assertEquals(1, info.lookIdx);
75+
76+
info = WindsatReader.extractArrayInfo("tb_37_H_aft");
77+
assertEquals("tb_37", info.ncVarName);
78+
assertEquals(-1, info.freqIdx);
79+
assertEquals(1, info.polIdx);
80+
assertEquals(1, info.lookIdx);
81+
}
6182
}

core/src/test/java/com/bc/fiduceo/reader/windsat/WindsatReader_IO_Test.java

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,102 @@ public void testReadRaw() throws IOException, InvalidRangeException {
319319
}
320320
}
321321

322+
@Test
323+
public void testReadRaw_vector_data() throws IOException, InvalidRangeException {
324+
final File file = getWindsatFile();
325+
326+
try {
327+
reader.open(file);
328+
329+
Array array = reader.readRaw(1328, 384, new Interval(3, 3), "fractional_orbit");
330+
NCTestUtils.assertValueAt(0.48804149876781366, 0, 0, array);
331+
NCTestUtils.assertValueAt(0.4881054987676521, 1, 1, array);
332+
NCTestUtils.assertValueAt(0.4881694987674905, 2, 2, array); // rounding issues in assertion code
333+
} finally {
334+
reader.close();
335+
}
336+
}
337+
338+
@Test
339+
public void testReadRaw_vector_data_outside() throws IOException, InvalidRangeException {
340+
final File file = getWindsatFile();
341+
342+
try {
343+
reader.open(file);
344+
345+
Array array = reader.readRaw(0, 385, new Interval(3, 3), "fractional_orbit");
346+
NCTestUtils.assertValueAt(9.969209968386869E36, 0, 0, array);
347+
NCTestUtils.assertValueAt(2.599999993435631E-5, 1, 1, array);
348+
NCTestUtils.assertValueAt(7.799999980306893E-5, 2, 2, array); // rounding issues in assertion code
349+
} finally {
350+
reader.close();
351+
}
352+
}
353+
354+
@Test
355+
public void testReadRaw_frequency_dependent() throws IOException, InvalidRangeException {
356+
final File file = getWindsatFile();
357+
358+
try {
359+
reader.open(file);
360+
361+
Array array = reader.readRaw(1329, 1306, new Interval(3, 3), "earth_azimuth_angle_187_fore");
362+
NCTestUtils.assertValueAt(-9999.0, 0, 0, array);
363+
NCTestUtils.assertValueAt(244.25, 1, 1, array);
364+
NCTestUtils.assertValueAt(245.239990234375, 2, 2, array);
365+
366+
array = reader.readRaw(765, 848, new Interval(3, 3), "fra_238_aft");
367+
NCTestUtils.assertValueAt(0.048, 0, 1, array);
368+
NCTestUtils.assertValueAt(0.049, 1, 1, array);
369+
NCTestUtils.assertValueAt(0.049, 2, 1, array);
370+
} finally {
371+
reader.close();
372+
}
373+
}
374+
375+
@Test
376+
public void testReadRaw_polarisation_dependent() throws IOException, InvalidRangeException {
377+
final File file = getWindsatFile();
378+
379+
try {
380+
reader.open(file);
381+
382+
Array array = reader.readRaw(665, 234, new Interval(3, 3), "tb_06_V_aft");
383+
NCTestUtils.assertValueAt(-32768, 0, 1, array);
384+
NCTestUtils.assertValueAt(10172, 1, 1, array);
385+
NCTestUtils.assertValueAt(10176, 2, 1, array);
386+
387+
array = reader.readRaw(2964, 17, new Interval(3, 3), "tb_37_M_fore");
388+
NCTestUtils.assertValueAt(12197, 0, 1, array);
389+
NCTestUtils.assertValueAt(-32768, 1, 1, array);
390+
NCTestUtils.assertValueAt(12199, 2, 1, array);
391+
} finally {
392+
reader.close();
393+
}
394+
}
395+
396+
@Test
397+
public void testReadScaled() throws IOException, InvalidRangeException {
398+
final File file = getWindsatFile();
399+
400+
try {
401+
reader.open(file);
402+
403+
// only need to check the brightness temperatures, the remainder of the variables is stored as floats/is flag data
404+
Array array = reader.readScaled(665, 234, new Interval(3, 3), "tb_06_V_aft");
405+
NCTestUtils.assertValueAt(-277.67999267578125, 0, 1, array);
406+
NCTestUtils.assertValueAt(151.71999772638083, 1, 1, array);
407+
NCTestUtils.assertValueAt(151.75999772548676, 2, 1, array);
408+
409+
array = reader.readScaled(2964, 17, new Interval(3, 3), "tb_37_M_fore");
410+
NCTestUtils.assertValueAt(171.96999727375805, 0, 1, array);
411+
NCTestUtils.assertValueAt(-277.67999267578125, 1, 1, array);
412+
NCTestUtils.assertValueAt(171.98999727331102, 2, 1, array);
413+
} finally {
414+
reader.close();
415+
}
416+
}
417+
322418
private File getWindsatFile() throws IOException {
323419
final String testFilePath = TestUtil.assembleFileSystemPath(new String[]{"windsat-coriolis", "v1.0", "2018", "04", "29", "RSS_WindSat_TB_L1C_r79285_20180429T174238_2018119_V08.0.nc"}, false);
324420
return TestUtil.getTestDataFileAsserted(testFilePath);

0 commit comments

Comments
 (0)