Skip to content

Commit 2ec0a2b

Browse files
committed
fetch updates
Merge branch 'master' into TB_Noaa_Buoy
2 parents ad1396f + 2397d6f commit 2ec0a2b

File tree

79 files changed

+1220
-421
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+1220
-421
lines changed

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
### Updates from version 1.5.7 to 1.5.8
22
* added support for Windsat Coriolis data
3+
* added conda environment
4+
* extended workflow to run without scheduler on plain console
5+
* Added option to use different name for matchup dimension in post processing
36

47
### Updates from version 1.5.6 to 1.5.7
58
* added support for SMOS L1C daily aggregated products

cems/src/main/python/monitor.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from pmonitor import PMonitor
22

33
class Monitor:
4-
def __init__(self, preconditions, usecase, hosts, types, log_dir, simulation):
4+
def __init__(self, preconditions, usecase, hosts, types, log_dir, simulation, synchronous=False):
55
"""
66
77
:type preconditions: list
@@ -10,8 +10,12 @@ def __init__(self, preconditions, usecase, hosts, types, log_dir, simulation):
1010
:type calls: list
1111
:type log_dir: str
1212
:type simulation: bool
13+
:type synchronous: bool
1314
"""
14-
self.pm = PMonitor(preconditions, usecase, hosts, types, logdir=log_dir, simulation=simulation, polling="job_status_callback.sh")
15+
if synchronous:
16+
self.pm = PMonitor(preconditions, usecase, hosts, types, logdir=log_dir, simulation=simulation)
17+
else:
18+
self.pm = PMonitor(preconditions, usecase, hosts, types, logdir=log_dir, simulation=simulation, polling="job_status_callback.sh")
1519

1620
def execute(self, job):
1721
"""

cems/src/main/python/workflow.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,14 @@ def _add_post_processing_preconditions(self, preconditions):
244244

245245
return preconditions
246246

247-
def _get_monitor(self, hosts, calls, log_dir, simulation):
247+
def _get_monitor(self, hosts, calls, log_dir, simulation, synchronous=False):
248248
"""
249249
250250
:type hosts: list
251251
:type calls: list
252252
:type log_dir: str
253253
:type simulation: bool
254+
:type synchronous: bool
254255
:rtype : Monitor
255256
"""
256257
preconditions = list()
@@ -262,7 +263,7 @@ def _get_monitor(self, hosts, calls, log_dir, simulation):
262263
# @todo 2 tb/tb do we need this 2016-03-29
263264
# self._add_obs_preconditions(preconditions)
264265
# self._add_smp_preconditions(preconditions)
265-
return Monitor(preconditions, self.get_usecase(), hosts, calls, log_dir, simulation)
266+
return Monitor(preconditions, self.get_usecase(), hosts, calls, log_dir, simulation, synchronous)
266267

267268
def _next_year_start(self, date):
268269
"""
@@ -366,16 +367,22 @@ def run_test_job(self, hosts, simulation=False, logdir='trace'):
366367

367368
monitor.wait_for_completion()
368369

369-
def run_matchup(self, hosts, num_parallel_tasks, simulation=False, logdir='trace'):
370+
def run_matchup(self, hosts, num_parallel_tasks, simulation=False, logdir='trace', synchronous=False):
370371
"""
371372
372373
:param hosts: list
373374
:param num_parallel_tasks: int
374375
:param simulation: bool
375376
:param logdir: str
377+
:param synchronous: bool
376378
:return:
377379
"""
378-
monitor = self._get_monitor(hosts, [('matchup_start.sh', num_parallel_tasks)], logdir, simulation)
380+
if synchronous:
381+
runs_script = 'matchup_run.sh'
382+
else:
383+
runs_script = 'matchup_start.sh'
384+
385+
monitor = self._get_monitor(hosts, [(runs_script, num_parallel_tasks)], logdir, simulation, synchronous)
379386

380387
sensors = self._get_sensor_pairs()
381388
for sensor_pair in sensors:
@@ -393,7 +400,7 @@ def run_matchup(self, hosts, num_parallel_tasks, simulation=False, logdir='trace
393400
pre_condition = 'ingest-' + primary_name + '-' + start_string + '-' + end_string
394401
post_condition = 'matchup-' + name + '-' + start_string + '-' + end_string + '-' + self.usecase_config
395402

396-
job = Job(job_name, 'matchup_start.sh', [pre_condition], [post_condition],
403+
job = Job(job_name, runs_script, [pre_condition], [post_condition],
397404
[start_string, end_string, self._get_config_dir(), self.usecase_config])
398405
monitor.execute(job)
399406

core/src/main/java/com/bc/fiduceo/geometry/s2/BcS2GeometryFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public BcS2GeometryFactory() {
4242
public Geometry parse(String wkt) {
4343
final Object geometry = s2WKTReader.read(wkt);
4444
if (geometry instanceof S2Polygon) {
45+
//normalizePolygon((S2Polygon) geometry);
4546
return new BcS2Polygon(geometry);
4647
} else if (geometry instanceof S2Polyline) {
4748
return new BcS2LineString((S2Polyline) geometry);
@@ -53,6 +54,7 @@ public Geometry parse(String wkt) {
5354
final ArrayList<Polygon> polygonList = new ArrayList<>();
5455
final List<S2Polygon> googlePolygonList = (List<S2Polygon>) geometry;
5556
for (S2Polygon googlePolygon : googlePolygonList) {
57+
//normalizePolygon(googlePolygon);
5658
polygonList.add(new BcS2Polygon(googlePolygon));
5759
}
5860
return new BcS2MultiPolygon(polygonList);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.bc.fiduceo.qc;
2+
3+
import java.util.ArrayList;
4+
import java.util.HashMap;
5+
import java.util.List;
6+
7+
class FileMessages {
8+
9+
private final HashMap<String, List<String>> messagesMap;
10+
11+
FileMessages() {
12+
messagesMap = new HashMap<>();
13+
}
14+
15+
HashMap<String, List<String>> getMessageMap() {
16+
return messagesMap;
17+
}
18+
19+
public void add(String fileName, String message) {
20+
final List<String> messages = messagesMap.computeIfAbsent(fileName, k -> new ArrayList<>());
21+
messages.add(message);
22+
}
23+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.bc.fiduceo.qc;
2+
3+
import com.bc.fiduceo.util.TimeUtils;
4+
5+
import java.util.Calendar;
6+
import java.util.Date;
7+
import java.util.HashMap;
8+
9+
class MatchupAccumulator {
10+
11+
private final Calendar utcCalendar;
12+
private final HashMap<String, Integer> daysMap;
13+
private int matchupSum;
14+
private int fileCount;
15+
16+
public MatchupAccumulator() {
17+
utcCalendar = TimeUtils.getUTCCalendar();
18+
daysMap = new HashMap<>();
19+
matchupSum = 0;
20+
fileCount = 0;
21+
}
22+
23+
HashMap<String, Integer> getDaysMap() {
24+
return daysMap;
25+
}
26+
27+
public int getSummaryCount() {
28+
return matchupSum;
29+
}
30+
31+
public void add(int timeStamp) {
32+
utcCalendar.setTimeInMillis(timeStamp * 1000L);
33+
final Date time = utcCalendar.getTime();
34+
final String dayString = TimeUtils.format(time, "yyyy-MM-dd");
35+
36+
Integer count = daysMap.get(dayString);
37+
if (count == null) {
38+
count = 1;
39+
daysMap.put(dayString, count);
40+
} else {
41+
++count;
42+
daysMap.replace(dayString, count);
43+
}
44+
45+
matchupSum++;
46+
}
47+
48+
int getFileCount() {
49+
return fileCount;
50+
}
51+
52+
void countFile() {
53+
++fileCount;
54+
}
55+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package com.bc.fiduceo.qc;
2+
3+
import com.bc.fiduceo.FiduceoConstants;
4+
import com.bc.fiduceo.log.FiduceoLogger;
5+
import com.bc.fiduceo.util.NetCDFUtils;
6+
import org.apache.commons.cli.CommandLine;
7+
import org.apache.commons.cli.HelpFormatter;
8+
import org.apache.commons.cli.Option;
9+
import org.apache.commons.cli.Options;
10+
import ucar.ma2.Array;
11+
import ucar.ma2.IndexIterator;
12+
import ucar.ma2.InvalidRangeException;
13+
import ucar.nc2.NetcdfFile;
14+
15+
import java.io.File;
16+
import java.io.IOException;
17+
import java.io.OutputStream;
18+
import java.io.PrintWriter;
19+
import java.nio.file.Files;
20+
import java.nio.file.Path;
21+
import java.util.*;
22+
import java.util.logging.Logger;
23+
import java.util.regex.Pattern;
24+
import java.util.stream.Collectors;
25+
import java.util.stream.Stream;
26+
27+
import static com.bc.fiduceo.FiduceoConstants.VERSION_NUMBER;
28+
import static com.bc.fiduceo.util.MMDUtil.getMMDFileNamePattern;
29+
30+
class MmdQCTool {
31+
32+
private final static Logger logger = FiduceoLogger.getLogger();
33+
34+
private FileMessages fileMessages;
35+
private MatchupAccumulator matchupAccumulator;
36+
37+
// package access for testing only tb 2023-02-14
38+
static Options getOptions() {
39+
final Options options = new Options();
40+
41+
final Option helpOption = new Option("h", "help", false, "Prints the tool usage.");
42+
options.addOption(helpOption);
43+
44+
final Option inputOption = new Option("i", "input", true, "Defines the MMD input directory.");
45+
inputOption.setRequired(true);
46+
options.addOption(inputOption);
47+
48+
final Option timeOption = new Option("t", "time", true, "Defines matchup time variable name.");
49+
timeOption.setRequired(true);
50+
options.addOption(timeOption);
51+
52+
return options;
53+
}
54+
55+
// package access for testing only tb 2023-02-14
56+
static void writeReport(OutputStream outputStream, MatchupAccumulator accumulator, FileMessages fileMessages) {
57+
final PrintWriter writer = new PrintWriter(outputStream);
58+
59+
final int fileCount = accumulator.getFileCount();
60+
writer.println("Analysed " + fileCount + " file(s)");
61+
if (fileCount == 0) {
62+
writer.flush();
63+
return;
64+
}
65+
66+
writer.println();
67+
final HashMap<String, List<String>> messageMap = fileMessages.getMessageMap();
68+
final int size = messageMap.size();
69+
writer.println(size + " file(s) with errors");
70+
if (size > 0) {
71+
// @todo 1 tb/tb add error messages per file here
72+
}
73+
74+
writer.println();
75+
writer.println("Total number of matchups: " + accumulator.getSummaryCount());
76+
writer.println("Daily distribution:");
77+
78+
final TreeMap<String, Integer> treeMap = new TreeMap<>(accumulator.getDaysMap());
79+
final Set<Map.Entry<String, Integer>> entries = treeMap.entrySet();
80+
for (final Map.Entry<String, Integer> entry : entries) {
81+
writer.println(entry.getKey() + ": " + entry.getValue());
82+
}
83+
84+
writer.flush();
85+
}
86+
87+
void run(CommandLine commandLine) throws IOException {
88+
final String inputDirOption = commandLine.getOptionValue("i");
89+
final List<Path> mmdFiles = getInputFiles(inputDirOption);
90+
logger.info("Found " + mmdFiles.size() + " input file(s) to analyze.");
91+
92+
fileMessages = new FileMessages();
93+
matchupAccumulator = new MatchupAccumulator();
94+
95+
// loop over files
96+
for (final Path mmdFile : mmdFiles) {
97+
98+
try (final NetcdfFile netcdfFile = NetCDFUtils.openReadOnly(mmdFile.toAbsolutePath().toString())) {
99+
100+
// read time variable center pixel
101+
final String timeVariableName = commandLine.getOptionValue("t");
102+
final Array timeArray = NetCDFUtils.getCenterPosArrayFromMMDFile(netcdfFile, timeVariableName, null,
103+
null, FiduceoConstants.MATCHUP_COUNT);
104+
final IndexIterator iterator = timeArray.getIndexIterator();
105+
while (iterator.hasNext()) {
106+
final int time = iterator.getIntNext();
107+
matchupAccumulator.add(time);
108+
}
109+
} catch (IOException | InvalidRangeException ioException) {
110+
fileMessages.add(mmdFile.getFileName().toString(), ioException.getMessage());
111+
}
112+
}
113+
114+
// write report
115+
final TreeMap<String, Integer> treeMap = new TreeMap<>(matchupAccumulator.getDaysMap());
116+
final Set<Map.Entry<String, Integer>> entries = treeMap.entrySet();
117+
for (final Map.Entry<String, Integer> entry : entries) {
118+
System.out.println(entry.getKey() + ": " + entry.getValue());
119+
}
120+
}
121+
122+
private List<Path> getInputFiles(String inputDirOption) throws IOException {
123+
final File inputDir = new File(inputDirOption);
124+
if (!inputDir.isDirectory()) {
125+
throw new IOException("Not a valid directory: " + inputDir.getAbsolutePath());
126+
}
127+
128+
final Pattern pattern = getMMDFileNamePattern();
129+
try (Stream<Path> pathStream = Files.walk(inputDir.toPath())) {
130+
final Stream<Path> regularFiles = pathStream.filter(Files::isRegularFile);
131+
final Stream<Path> mmdFileStream = regularFiles.filter(path -> pattern.matcher(path.getFileName().toString()).matches());
132+
return mmdFileStream.collect(Collectors.toList());
133+
}
134+
}
135+
136+
static void printUsageTo(OutputStream outputStream) {
137+
final String ls = System.lineSeparator();
138+
final PrintWriter writer = new PrintWriter(outputStream);
139+
writer.write("mmd-qc-tool version " + VERSION_NUMBER);
140+
writer.write(ls + ls);
141+
142+
final HelpFormatter helpFormatter = new HelpFormatter();
143+
helpFormatter.printHelp(writer, 120, "matchup-tool <options>", "Valid options are:",
144+
getOptions(), 3, 3, "");
145+
146+
writer.flush();
147+
}
148+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.bc.fiduceo.qc;
2+
3+
import com.bc.fiduceo.log.FiduceoLogger;
4+
import org.apache.commons.cli.CommandLine;
5+
import org.apache.commons.cli.CommandLineParser;
6+
import org.apache.commons.cli.ParseException;
7+
import org.apache.commons.cli.PosixParser;
8+
9+
public class MmdQCToolMain {
10+
11+
public static void main(String[] args) throws ParseException {
12+
final MmdQCTool mmdQCTool = new MmdQCTool();
13+
14+
if (args.length == 0) {
15+
MmdQCTool.printUsageTo(System.err);
16+
return;
17+
}
18+
19+
final CommandLineParser parser = new PosixParser();
20+
final CommandLine commandLine = parser.parse(MmdQCTool.getOptions(), args);
21+
if (commandLine.hasOption("h") || commandLine.hasOption("--help")) {
22+
MmdQCTool.printUsageTo(System.err);
23+
return;
24+
}
25+
26+
try {
27+
mmdQCTool.run(commandLine);
28+
} catch (Throwable e) {
29+
FiduceoLogger.getLogger().severe(e.getMessage());
30+
e.printStackTrace();
31+
System.exit(-1);
32+
}
33+
}
34+
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ public ArrayCache(NetcdfFile netcdfFile) {
4848
variableFinder = netcdfFile::findVariable;
4949
}
5050

51+
public void clear() {
52+
cache.clear();
53+
scaledCache.clear();
54+
injectedVariables.clear();
55+
}
56+
5157
// package access for testing only tb 2016-04-14
5258
static String createGroupedName(String groupName, String variableName) {
5359
return groupName + "_" + variableName;

core/src/main/java/com/bc/fiduceo/reader/insitu/sic_cci/AMSR2SectionParser.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.bc.fiduceo.reader.insitu.sic_cci;
22

3+
import com.bc.fiduceo.reader.netcdf.StringVariable;
34
import com.bc.fiduceo.util.NetCDFUtils;
45
import com.bc.fiduceo.util.VariableProxy;
56
import ucar.ma2.DataType;
@@ -52,7 +53,7 @@ List<Variable> getVariables() {
5253
variables.add(new VariableProxy("AMSR2_scanpos", DataType.SHORT, attributes));
5354

5455
attributes = new ArrayList<>();
55-
variables.add(new VariableProxy("AMSR2_upstreamfile", DataType.CHAR, attributes));
56+
variables.add(new StringVariable(new VariableProxy("AMSR2_upstreamfile", DataType.STRING, attributes), 48));
5657

5758
attributes = new ArrayList<>();
5859
attributes.add(new Attribute(CF_FILL_VALUE_NAME, NetCDFUtils.getDefaultFillValue(short.class)));

0 commit comments

Comments
 (0)