Skip to content

Commit 6e681fb

Browse files
committed
finished NCDB reader
1 parent bd9a789 commit 6e681fb

File tree

7 files changed

+499
-57
lines changed

7 files changed

+499
-57
lines changed

core/src/main/java/com/bc/fiduceo/reader/insitu/ndbc/NdbcCWReader.java

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import com.bc.fiduceo.util.TimeUtils;
1313
import com.bc.fiduceo.util.VariableProxy;
1414
import org.esa.snap.core.util.StringUtils;
15-
import org.esa.snap.core.util.io.FileUtils;
1615
import ucar.ma2.Array;
1716
import ucar.ma2.ArrayInt;
1817
import ucar.ma2.DataType;
@@ -42,24 +41,14 @@ class NdbcCWReader extends NdbcReader {
4241

4342
private ArrayList<CwRecord> records;
4443
private TimeLocator timeLocator;
45-
private Station station;
4644

4745
@Override
4846
public void open(File file) throws IOException {
4947
ensureStationDatabase();
50-
loadStation(file);
48+
loadStation(file, stationDatabase);
5149
parseFile(file);
5250
}
5351

54-
private void loadStation(File file) {
55-
final String fileName = FileUtils.getFilenameWithoutExtension(file);
56-
final String stationId = fileName.substring(0, 5);
57-
station = stationDatabase.get(stationId);
58-
if (station == null) {
59-
throw new IllegalArgumentException("unsupported station, id = " + stationId);
60-
}
61-
}
62-
6352
private void parseFile(File file) throws IOException {
6453
records = new ArrayList<>();
6554
try (final FileReader fileReader = new FileReader(file)) {
@@ -86,6 +75,7 @@ public void close() throws IOException {
8675
}
8776

8877
timeLocator = null;
78+
station = null;
8979
}
9080

9181
@Override
@@ -147,17 +137,6 @@ private void createTimeLocator() {
147137
timeLocator = new TimeLocator_MillisSince1970(timeArray);
148138
}
149139

150-
@Override
151-
public int[] extractYearMonthDayFromFilename(String fileName) {
152-
int[] ymd = new int[3];
153-
final int dotIndex = fileName.indexOf('.');
154-
final String yearString = fileName.substring(dotIndex - 4, dotIndex);
155-
ymd[0] = Integer.parseInt(yearString);
156-
ymd[1] = 1;
157-
ymd[2] = 1;
158-
return ymd;
159-
}
160-
161140
@Override
162141
public Array readRaw(int centerX, int centerY, Interval interval, String variableName) throws IOException, InvalidRangeException {
163142
final CwRecord record = records.get(centerY);
@@ -244,16 +223,6 @@ public Dimension getProductSize() throws IOException {
244223
return new Dimension("product_size", 1, records.size());
245224
}
246225

247-
@Override
248-
public String getLongitudeVariableName() {
249-
return LONGITUDE;
250-
}
251-
252-
@Override
253-
public String getLatitudeVariableName() {
254-
return LATITUDE;
255-
}
256-
257226
private void ensureStationDatabase() throws IOException {
258227
if (stationDatabase == null) {
259228
stationDatabase = parseStationDatabase("buoy_locations_cw.txt");

core/src/main/java/com/bc/fiduceo/reader/insitu/ndbc/NdbcReader.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,19 @@
44
import com.bc.fiduceo.reader.Reader;
55
import com.bc.fiduceo.util.NetCDFUtils;
66
import com.bc.fiduceo.util.VariableProxy;
7+
import org.esa.snap.core.util.io.FileUtils;
78
import ucar.ma2.Array;
89
import ucar.ma2.DataType;
910
import ucar.nc2.Attribute;
1011
import ucar.nc2.Variable;
1112

13+
import java.io.File;
1214
import java.io.IOException;
1315
import java.io.InputStream;
1416
import java.util.ArrayList;
1517
import java.util.List;
1618

1719
import static com.bc.fiduceo.util.NetCDFUtils.*;
18-
import static com.bc.fiduceo.util.NetCDFUtils.CF_LONG_NAME;
1920

2021
abstract class NdbcReader implements Reader {
2122

@@ -34,6 +35,29 @@ abstract class NdbcReader implements Reader {
3435
static final String WSPD = "WSPD";
3536
static final String GST = "GST";
3637

38+
protected Station station;
39+
40+
@Override
41+
public int[] extractYearMonthDayFromFilename(String fileName) {
42+
int[] ymd = new int[3];
43+
final int dotIndex = fileName.indexOf('.');
44+
final String yearString = fileName.substring(dotIndex - 4, dotIndex);
45+
ymd[0] = Integer.parseInt(yearString);
46+
ymd[1] = 1;
47+
ymd[2] = 1;
48+
return ymd;
49+
}
50+
51+
@Override
52+
public String getLongitudeVariableName() {
53+
return LONGITUDE;
54+
}
55+
56+
@Override
57+
public String getLatitudeVariableName() {
58+
return LATITUDE;
59+
}
60+
3761
StationDatabase parseStationDatabase(String resourceName) throws IOException {
3862
final InputStream is = getClass().getResourceAsStream(resourceName);
3963
if (is == null) {
@@ -48,6 +72,15 @@ StationDatabase parseStationDatabase(String resourceName) throws IOException {
4872
return sdb;
4973
}
5074

75+
void loadStation(File file, StationDatabase stationDatabase) {
76+
final String fileName = FileUtils.getFilenameWithoutExtension(file);
77+
final String stationId = fileName.substring(0, 5);
78+
station = stationDatabase.get(stationId);
79+
if (station == null) {
80+
throw new IllegalArgumentException("unsupported station, id = " + stationId);
81+
}
82+
}
83+
5184
static byte toByte(StationType stationType) {
5285
switch (stationType) {
5386
case OCEAN_BUOY:

core/src/main/java/com/bc/fiduceo/reader/insitu/ndbc/NdbcSMReader.java

Lines changed: 130 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
import com.bc.fiduceo.core.Dimension;
44
import com.bc.fiduceo.core.Interval;
5+
import com.bc.fiduceo.core.NodeType;
56
import com.bc.fiduceo.geometry.Polygon;
67
import com.bc.fiduceo.location.PixelLocator;
78
import com.bc.fiduceo.reader.AcquisitionInfo;
89
import com.bc.fiduceo.reader.time.TimeLocator;
10+
import com.bc.fiduceo.reader.time.TimeLocator_MillisSince1970;
11+
import com.bc.fiduceo.util.NetCDFUtils;
12+
import com.bc.fiduceo.util.TimeUtils;
913
import com.bc.fiduceo.util.VariableProxy;
1014
import org.esa.snap.core.util.StringUtils;
1115
import ucar.ma2.Array;
@@ -15,10 +19,13 @@
1519
import ucar.nc2.Attribute;
1620
import ucar.nc2.Variable;
1721

22+
import java.io.BufferedReader;
1823
import java.io.File;
24+
import java.io.FileReader;
1925
import java.io.IOException;
2026
import java.util.ArrayList;
2127
import java.util.Calendar;
28+
import java.util.Date;
2229
import java.util.List;
2330

2431
import static com.bc.fiduceo.util.NetCDFUtils.*;
@@ -39,18 +46,47 @@ class NdbcSMReader extends NdbcReader {
3946

4047
private static StationDatabase stationDatabase;
4148

49+
private ArrayList<SmRecord> records;
50+
private TimeLocator timeLocator;
51+
4252
@Override
4353
public void open(File file) throws IOException {
4454
ensureStationDatabase();
55+
loadStation(file, stationDatabase);
56+
parseFile(file);
4557
}
4658

4759
@Override
4860
public void close() throws IOException {
61+
if (records != null) {
62+
records.clear();
63+
records = null;
64+
}
65+
66+
station = null;
4967
}
5068

5169
@Override
5270
public AcquisitionInfo read() throws IOException {
53-
throw new RuntimeException("not implemented");
71+
final AcquisitionInfo acquisitionInfo = new AcquisitionInfo();
72+
73+
int minTime = Integer.MAX_VALUE;
74+
int maxTime = Integer.MIN_VALUE;
75+
for (final SmRecord record : records) {
76+
if (record.utc < minTime) {
77+
minTime = record.utc;
78+
}
79+
if (record.utc > maxTime) {
80+
maxTime = record.utc;
81+
}
82+
}
83+
84+
acquisitionInfo.setSensingStart(new Date(minTime * 1000L));
85+
acquisitionInfo.setSensingStop(new Date(maxTime * 1000L));
86+
87+
acquisitionInfo.setNodeType(NodeType.UNDEFINED);
88+
89+
return acquisitionInfo;
5490
}
5591

5692
@Override
@@ -70,27 +106,81 @@ public PixelLocator getSubScenePixelLocator(Polygon sceneGeometry) throws IOExce
70106

71107
@Override
72108
public TimeLocator getTimeLocator() throws IOException {
73-
throw new RuntimeException("not implemented");
74-
}
109+
if (timeLocator == null) {
110+
createTimeLocator();
111+
}
75112

76-
@Override
77-
public int[] extractYearMonthDayFromFilename(String fileName) {
78-
throw new RuntimeException("not implemented");
113+
return timeLocator;
79114
}
80115

81116
@Override
82117
public Array readRaw(int centerX, int centerY, Interval interval, String variableName) throws IOException, InvalidRangeException {
83-
throw new RuntimeException("not implemented");
118+
final SmRecord record = records.get(centerY);
119+
120+
switch (variableName) {
121+
case STATION_ID:
122+
final Array resultArray = Array.factory(DataType.STRING, new int[]{1, 1});
123+
resultArray.setObject(0, station.getId());
124+
return resultArray;
125+
case STATION_TYPE:
126+
final StationType type = station.getType();
127+
return createResultArray(toByte(type), -1, DataType.BYTE, interval);
128+
case MEASUREMENT_TYPE:
129+
final MeasurementType measurementType = station.getMeasurementType();
130+
return createResultArray(toByte(measurementType), -1, DataType.BYTE, interval);
131+
case LONGITUDE:
132+
return createResultArray(station.getLon(), Float.NaN, DataType.FLOAT, interval);
133+
case LATITUDE:
134+
return createResultArray(station.getLat(), Float.NaN, DataType.FLOAT, interval);
135+
case ANEMOMETER_HEIGHT:
136+
return createResultArray(station.getAnemometerHeight(), Float.NaN, DataType.FLOAT, interval);
137+
case AIR_TEMP_HEIGHT:
138+
return createResultArray(station.getAirTemperatureHeight(), Float.NaN, DataType.FLOAT, interval);
139+
case BAROMETER_HEIGHT:
140+
return createResultArray(station.getBarometerHeight(), Float.NaN, DataType.FLOAT, interval);
141+
case SST_DEPTH:
142+
return createResultArray(station.getSSTDepth(), Float.NaN, DataType.FLOAT, interval);
143+
case TIME:
144+
return createResultArray(record.utc, NetCDFUtils.getDefaultFillValue(int.class), DataType.INT, interval);
145+
case WDIR:
146+
return createResultArray(record.windDir, 999, DataType.SHORT, interval);
147+
case WSPD:
148+
return createResultArray(record.windSpeed, 99.f, DataType.FLOAT, interval);
149+
case GST:
150+
return createResultArray(record.gustSpeed, 99.f, DataType.FLOAT, interval);
151+
case WVHT:
152+
return createResultArray(record.waveHeight, 99.f, DataType.FLOAT, interval);
153+
case DPD:
154+
return createResultArray(record.domWavePeriod, 99.f, DataType.FLOAT, interval);
155+
case APD:
156+
return createResultArray(record.avgWavePeriod, 99.f, DataType.FLOAT, interval);
157+
case MWD:
158+
return createResultArray(record.waveDir, 999, DataType.SHORT, interval);
159+
case PRES:
160+
return createResultArray(record.seaLevelPressure, 9999.f, DataType.FLOAT, interval);
161+
case ATMP:
162+
return createResultArray(record.airTemp, 999.f, DataType.FLOAT, interval);
163+
case DEWP:
164+
return createResultArray(record.dewPointTemp, 999.f, DataType.FLOAT, interval);
165+
case VIS:
166+
return createResultArray(record.visibility, 99.f, DataType.FLOAT, interval);
167+
case TIDE:
168+
return createResultArray(record.tideLevel, 99.f, DataType.FLOAT, interval);
169+
}
170+
171+
return null;
84172
}
85173

86174
@Override
87175
public Array readScaled(int centerX, int centerY, Interval interval, String variableName) throws IOException, InvalidRangeException {
88-
throw new RuntimeException("not implemented");
176+
return readRaw(centerX, centerY, interval, variableName);
89177
}
90178

91179
@Override
92180
public ArrayInt.D2 readAcquisitionTime(int x, int y, Interval interval) throws IOException, InvalidRangeException {
93-
throw new RuntimeException("not implemented");
181+
final Array timeArray = readRaw(x, y, interval, TIME);
182+
183+
return (ArrayInt.D2) timeArray;
94184
}
95185

96186
@Override
@@ -190,17 +280,7 @@ public List<Variable> getVariables() throws InvalidRangeException, IOException {
190280

191281
@Override
192282
public Dimension getProductSize() throws IOException {
193-
throw new RuntimeException("not implemented");
194-
}
195-
196-
@Override
197-
public String getLongitudeVariableName() {
198-
throw new RuntimeException("not implemented");
199-
}
200-
201-
@Override
202-
public String getLatitudeVariableName() {
203-
throw new RuntimeException("not implemented");
283+
return new Dimension("product_size", 1, records.size());
204284
}
205285

206286
private void ensureStationDatabase() throws IOException {
@@ -239,4 +319,34 @@ SmRecord parseLine(String line, Calendar calendar) {
239319

240320
return record;
241321
}
322+
323+
private void parseFile(File file) throws IOException {
324+
records = new ArrayList<>();
325+
try (final FileReader fileReader = new FileReader(file)) {
326+
final Calendar calendar = TimeUtils.getUTCCalendar();
327+
final BufferedReader bufferedReader = new BufferedReader(fileReader);
328+
String line;
329+
while ((line = bufferedReader.readLine()) != null) {
330+
if (line.startsWith("#")) {
331+
// skip comment lines tb 2023-02-27
332+
continue;
333+
}
334+
335+
final SmRecord smRecord = parseLine(line, calendar);
336+
records.add(smRecord);
337+
}
338+
}
339+
}
340+
341+
private void createTimeLocator() {
342+
long[] timeArray = new long[records.size()];
343+
344+
int i = 0;
345+
for (final SmRecord record : records) {
346+
timeArray[i] = record.utc * 1000L;
347+
i++;
348+
}
349+
350+
timeLocator = new TimeLocator_MillisSince1970(timeArray);
351+
}
242352
}

core/src/main/java/com/bc/fiduceo/reader/insitu/ndbc/StationDatabase.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ private static ArrayList<String> readInputLines(InputStream inputStream) throws
8282
String line;
8383
while ((line = reader.readLine()) != null) {
8484
if (line.startsWith("#")) {
85-
// skip comment lines tb 2022-11-03
85+
// skip comment lines tb 2023-03-02
8686
continue;
8787
}
8888
lineList.add(line);
@@ -91,6 +91,6 @@ private static ArrayList<String> readInputLines(InputStream inputStream) throws
9191
}
9292

9393
Station get(String id) {
94-
return stationMap.get(id);
94+
return stationMap.get(id.toUpperCase());
9595
}
9696
}

0 commit comments

Comments
 (0)