Skip to content

Commit e25ce0a

Browse files
committed
implemented acquisition time reading, corrected time conversion
1 parent e755712 commit e25ce0a

File tree

7 files changed

+132
-96
lines changed

7 files changed

+132
-96
lines changed

core/src/main/java/com/bc/fiduceo/reader/ReaderUtils.java

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,18 @@
2020

2121
package com.bc.fiduceo.reader;
2222

23+
import com.bc.fiduceo.core.Dimension;
24+
import com.bc.fiduceo.core.Interval;
2325
import com.bc.fiduceo.geometry.*;
2426
import com.bc.fiduceo.math.TimeInterval;
27+
import com.bc.fiduceo.reader.time.TimeLocator;
2528
import com.bc.fiduceo.util.NetCDFUtils;
2629
import org.esa.snap.core.datamodel.ProductData;
2730
import org.esa.snap.core.util.io.FileUtils;
31+
import ucar.ma2.Array;
32+
import ucar.ma2.ArrayInt;
2833
import ucar.ma2.DataType;
34+
import ucar.ma2.Index;
2935

3036
import java.io.*;
3137
import java.util.Date;
@@ -111,7 +117,7 @@ public static int getChannelIndex(String variableName) {
111117

112118
public static boolean isCompressed(File file) {
113119
final String extension = FileUtils.getExtension(file);
114-
return extension.equalsIgnoreCase(".gz") || extension.equalsIgnoreCase(".tgz")|| extension.equalsIgnoreCase(".zip");
120+
return extension.equalsIgnoreCase(".gz") || extension.equalsIgnoreCase(".tgz") || extension.equalsIgnoreCase(".zip");
115121
}
116122

117123
/**
@@ -132,4 +138,44 @@ public static void decompress(File gzipFile, File tmpFile) throws IOException {
132138
}
133139
}
134140
}
141+
142+
public static ArrayInt.D2 readAcquisitionTimeFromTimeLocator(int x, int y, Interval interval, Dimension productSize, TimeLocator timeLocator) {
143+
final int height = interval.getY();
144+
final int width = interval.getX();
145+
final int x_offset = x - width / 2;
146+
final int y_offset = y - height / 2;
147+
int[] shape = new int[]{height, width};
148+
149+
final int pWidth = productSize.getNx();
150+
final int pHeight = productSize.getNy();
151+
152+
final int acquisitionTimeFillValue = getDefaultFillValue(ProductData.TYPE_INT32).intValue();
153+
154+
final ArrayInt.D2 acquisitionTime = (ArrayInt.D2) Array.factory(DataType.INT, shape);
155+
final Index index = acquisitionTime.getIndex();
156+
157+
for (int ya = 0; ya < height; ya++) {
158+
final int yRead = y_offset + ya;
159+
160+
for (int xa = 0; xa < width; xa++) {
161+
final int xRead = x_offset + xa;
162+
163+
int acTime;
164+
if (xRead < 0 || xRead >= pWidth || yRead < 0 || yRead >= pHeight) {
165+
acTime = acquisitionTimeFillValue;
166+
} else {
167+
final long pxTime = timeLocator.getTimeFor(xRead, yRead);
168+
if (pxTime < 0) {
169+
acTime = acquisitionTimeFillValue;
170+
} else {
171+
acTime = (int) (pxTime / 1000);
172+
}
173+
}
174+
index.set(ya, xa);
175+
acquisitionTime.setInt(index, acTime);
176+
}
177+
}
178+
179+
return acquisitionTime;
180+
}
135181
}

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

Lines changed: 47 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333

3434
import static com.bc.fiduceo.reader.smos.GeolocationHandler.LATITUDE;
3535
import static com.bc.fiduceo.reader.smos.GeolocationHandler.LONGITUDE;
36-
import static com.bc.fiduceo.util.NetCDFUtils.getDefaultFillValue;
3736

3837
class SmosL1CDailyGriddedReader extends NetCDFReader {
3938

@@ -65,6 +64,52 @@ class SmosL1CDailyGriddedReader extends NetCDFReader {
6564
layerExtension = new SmosAngleExtension();
6665
}
6766

67+
/**
68+
* extract minimal and maximal value of geolocation arrays passed in.
69+
* the resulting array is ordered:
70+
* [0] lonMin
71+
* [1] lonMax
72+
* [2] latMin
73+
* [3] latMax
74+
* package access for testing only tb 2022-09-26
75+
*
76+
* @param longitudes longitude data
77+
* @param latitudes latitude data
78+
* @return array with the extreme values
79+
*/
80+
static double[] extractMinMax(Array longitudes, Array latitudes) {
81+
final double[] minMax = new double[4];
82+
83+
int size = (int) longitudes.getSize();
84+
minMax[0] = longitudes.getDouble(0);
85+
minMax[1] = longitudes.getDouble(size - 1);
86+
87+
size = (int) latitudes.getSize();
88+
minMax[2] = latitudes.getDouble(0);
89+
minMax[3] = latitudes.getDouble(size - 1);
90+
91+
return minMax;
92+
}
93+
94+
// package access for testing only tb 2022-09-29
95+
static Date cfiDateToUtc(int days, long seconds, long microseconds) {
96+
final Calendar calendar = TimeUtils.getUTCCalendar();
97+
98+
calendar.set(Calendar.YEAR, 2000);
99+
calendar.set(Calendar.MONTH, 0);
100+
calendar.set(Calendar.DAY_OF_MONTH, 1);
101+
calendar.set(Calendar.HOUR_OF_DAY, 0);
102+
calendar.set(Calendar.MINUTE, 0);
103+
calendar.set(Calendar.SECOND, 0);
104+
calendar.set(Calendar.MILLISECOND, 0);
105+
106+
calendar.add(Calendar.DATE, days);
107+
calendar.add(Calendar.SECOND, (int) seconds);
108+
calendar.add(Calendar.MILLISECOND, (int) (microseconds * 0.001));
109+
110+
return calendar.getTime();
111+
}
112+
68113
@Override
69114
public void open(File file) throws IOException {
70115
if (ReaderUtils.isCompressed(file)) {
@@ -246,45 +291,9 @@ public Array readScaled(int centerX, int centerY, Interval interval, String vari
246291

247292
@Override
248293
public ArrayInt.D2 readAcquisitionTime(int x, int y, Interval interval) throws IOException, InvalidRangeException {
249-
final int height = interval.getY();
250-
final int width = interval.getX();
251-
final int x_offset = x - width / 2;
252-
final int y_offset = y - height / 2;
253-
int[] shape = new int[]{height, width};
254-
255294
final Dimension productSize = getProductSize();
256-
final int pWidth = productSize.getNx();
257-
final int pHeight = productSize.getNy();
258-
259295
final TimeLocator timeLocator = getTimeLocator();
260-
final int acquisitionTimeFillValue = getDefaultFillValue(int.class).intValue();
261-
262-
final ArrayInt.D2 acquisitionTime = (ArrayInt.D2) Array.factory(DataType.INT, shape);
263-
final Index index = acquisitionTime.getIndex();
264-
265-
for (int ya = 0; ya < height; ya++) {
266-
final int yRead = y_offset + ya;
267-
268-
for (int xa = 0; xa < width; xa++) {
269-
final int xRead = x_offset + xa;
270-
271-
int acTime;
272-
if (xRead < 0 || xRead >= pWidth || yRead < 0 || yRead >= pHeight) {
273-
acTime = acquisitionTimeFillValue;
274-
} else {
275-
final long pxTime = timeLocator.getTimeFor(xRead, yRead);
276-
if (pxTime < 0) {
277-
acTime = acquisitionTimeFillValue;
278-
} else {
279-
acTime = (int) (pxTime / 1000);
280-
}
281-
}
282-
index.set(ya, xa);
283-
acquisitionTime.setInt(index, acTime);
284-
}
285-
}
286-
287-
return acquisitionTime;
296+
return ReaderUtils.readAcquisitionTimeFromTimeLocator(x, y, interval, productSize, timeLocator);
288297
}
289298

290299
@Override
@@ -402,50 +411,4 @@ private void setSensingTimes(AcquisitionInfo acquisitionInfo) {
402411

403412
acquisitionInfo.setSensingStop(utcCalendar.getTime());
404413
}
405-
406-
/**
407-
* extract minimal and maximal value of geolocation arrays passed in.
408-
* the resulting array is ordered:
409-
* [0] lonMin
410-
* [1] lonMax
411-
* [2] latMin
412-
* [3] latMax
413-
* package access for testing only tb 2022-09-26
414-
*
415-
* @param longitudes longitude data
416-
* @param latitudes latitude data
417-
* @return array with the extreme values
418-
*/
419-
static double[] extractMinMax(Array longitudes, Array latitudes) {
420-
final double[] minMax = new double[4];
421-
422-
int size = (int) longitudes.getSize();
423-
minMax[0] = longitudes.getDouble(0);
424-
minMax[1] = longitudes.getDouble(size - 1);
425-
426-
size = (int) latitudes.getSize();
427-
minMax[2] = latitudes.getDouble(0);
428-
minMax[3] = latitudes.getDouble(size - 1);
429-
430-
return minMax;
431-
}
432-
433-
// package access for testing only tb 2022-09-29
434-
static Date cfiDateToUtc(int days, long seconds, long microseconds) {
435-
final Calendar calendar = TimeUtils.getUTCCalendar();
436-
437-
calendar.set(Calendar.YEAR, 2000);
438-
calendar.set(Calendar.MONTH, 0);
439-
calendar.set(Calendar.DAY_OF_MONTH, 1);
440-
calendar.set(Calendar.HOUR_OF_DAY, 0);
441-
calendar.set(Calendar.MINUTE, 0);
442-
calendar.set(Calendar.SECOND, 0);
443-
calendar.set(Calendar.MILLISECOND, 0);
444-
445-
calendar.add(Calendar.DATE, days);
446-
calendar.add(Calendar.SECOND, (int) seconds);
447-
calendar.add(Calendar.MILLISECOND, (int) (microseconds * 0.001));
448-
449-
return calendar.getTime();
450-
}
451414
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.bc.fiduceo.location.PixelLocator;
88
import com.bc.fiduceo.reader.AcquisitionInfo;
99
import com.bc.fiduceo.reader.ReaderContext;
10+
import com.bc.fiduceo.reader.ReaderUtils;
1011
import com.bc.fiduceo.reader.netcdf.NetCDFReader;
1112
import com.bc.fiduceo.reader.time.TimeLocator;
1213
import com.bc.fiduceo.reader.time.TimeLocator_SecondsSince2000;
@@ -141,7 +142,9 @@ public Array readScaled(int centerX, int centerY, Interval interval, String vari
141142

142143
@Override
143144
public ArrayInt.D2 readAcquisitionTime(int x, int y, Interval interval) throws IOException, InvalidRangeException {
144-
throw new RuntimeException("not implmented");
145+
final Dimension productSize = getProductSize();
146+
final TimeLocator timeLocator = getTimeLocator();
147+
return ReaderUtils.readAcquisitionTimeFromTimeLocator(x, y, interval, productSize, timeLocator);
145148
}
146149

147150
@Override

core/src/main/java/com/bc/fiduceo/util/TimeUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ public static long millisSince2000ToUnixEpoch(double timeStampMillis2000) {
177177

178178
public static long secondsSince2000ToUnixEpoch(double timeStampSecs2000) {
179179
long timeStamp = Math.round(timeStampSecs2000);
180-
return secondsSince2000 + timeStamp;
180+
return (secondsSince2000 + timeStamp) * 1000;
181181
}
182182

183183
public static Date tai1993ToUtc(double taiSeconds) {

core/src/test/java/com/bc/fiduceo/reader/time/TimeLocator_SecondsSince2000Test.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ public void setUp() {
2424

2525
@Test
2626
public void testGetTimes() {
27-
assertEquals(1525023896, timeLocator.getTimeFor(0, 1));
28-
assertEquals(1525023893, timeLocator.getTimeFor(1, 2));
29-
assertEquals(1525023898, timeLocator.getTimeFor(2, 0));
27+
assertEquals(1525023896000L, timeLocator.getTimeFor(0, 1));
28+
assertEquals(1525023893000L, timeLocator.getTimeFor(1, 2));
29+
assertEquals(1525023898000L, timeLocator.getTimeFor(2, 0));
3030
}
3131

3232
@Test

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

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33

44
import com.bc.fiduceo.IOTestRunner;
5+
import com.bc.fiduceo.NCTestUtils;
56
import com.bc.fiduceo.TestUtil;
67
import com.bc.fiduceo.core.Dimension;
8+
import com.bc.fiduceo.core.Interval;
79
import com.bc.fiduceo.core.NodeType;
810
import com.bc.fiduceo.geometry.*;
911
import com.bc.fiduceo.location.PixelLocator;
@@ -13,6 +15,7 @@
1315
import org.junit.Before;
1416
import org.junit.Test;
1517
import org.junit.runner.RunWith;
18+
import ucar.ma2.ArrayInt;
1619
import ucar.ma2.DataType;
1720
import ucar.ma2.InvalidRangeException;
1821
import ucar.nc2.Attribute;
@@ -184,9 +187,30 @@ public void testGetTimeLocator() throws IOException {
184187
assertEquals(-1, timeLocator.getTimeFor(2405, 1387));
185188

186189
// check data areas
187-
assertEquals(1525029953, timeLocator.getTimeFor(3016, 29));
188-
assertEquals(1525028428, timeLocator.getTimeFor(2237, 730));
189-
assertEquals(1525024084, timeLocator.getTimeFor(274, 153));
190+
assertEquals(1525029953000L, timeLocator.getTimeFor(3016, 29));
191+
assertEquals(1525028428000L, timeLocator.getTimeFor(2237, 730));
192+
assertEquals(1525024084000L, timeLocator.getTimeFor(274, 153));
193+
} finally {
194+
reader.close();
195+
}
196+
}
197+
198+
@Test
199+
public void testReadAcquisitionTime() throws IOException, InvalidRangeException {
200+
final File file = getWindsatFile();
201+
202+
try {
203+
reader.open(file);
204+
205+
// read a section that covers a swath border tb 2022-11-28
206+
final ArrayInt.D2 acquisitionTime = reader.readAcquisitionTime(810, 737, new Interval(5, 3));
207+
assertEquals(15, acquisitionTime.getSize());
208+
209+
NCTestUtils.assertValueAt(1525025479, 0, 1, acquisitionTime);
210+
NCTestUtils.assertValueAt(1525025482, 1, 1, acquisitionTime);
211+
NCTestUtils.assertValueAt(1525025484, 2, 1, acquisitionTime);
212+
NCTestUtils.assertValueAt(-2147483647, 3, 1, acquisitionTime);
213+
NCTestUtils.assertValueAt(-2147483647, 4, 1, acquisitionTime);
190214
} finally {
191215
reader.close();
192216
}

core/src/test/java/com/bc/fiduceo/util/TimeUtilsTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,9 @@ public void testMillisSince2000ToUnixEpoch() {
182182

183183
@Test
184184
public void testSecondsSince2000ToUnixEpoch() {
185-
assertEquals(946684800L, TimeUtils.secondsSince2000ToUnixEpoch(0));
186-
assertEquals(946771200L, TimeUtils.secondsSince2000ToUnixEpoch(86400));
187-
assertEquals(956684800L, TimeUtils.secondsSince2000ToUnixEpoch(10000000L));
185+
assertEquals(946684800000L, TimeUtils.secondsSince2000ToUnixEpoch(0));
186+
assertEquals(946771200000L, TimeUtils.secondsSince2000ToUnixEpoch(86400));
187+
assertEquals(956684800000L, TimeUtils.secondsSince2000ToUnixEpoch(10000000L));
188188
}
189189

190190
@Test

0 commit comments

Comments
 (0)