use of org.geotoolkit.processing.science.drift.Output in project geotoolkit by Geomatys.
the class Predictor method compute.
private List<Output> compute(final Instant startTime, final Instant endTime, final PredictionContext ctx, final MeteoDataset.TimeSet meteo) throws ProcessException {
final double totalSeconds = startTime.until(endTime, ChronoUnit.SECONDS);
boolean newDay = false;
Instant nextDay = startTime.plus(1, ChronoUnit.DAYS);
Instant stepTime = startTime;
// TODO : We should think about a better way of managing output grid, because here we waste a lot of space.
final double[] globalProba = new double[ctx.grid.width * ctx.grid.height];
final double[] dayProba = new double[globalProba.length];
final List<Output> outputs = new ArrayList<>();
// When computing point drift, we'll add a point for each weight available. As we don't want this amount to grow
// past a configured maximum, we have to purge available points before each computing pass.
final int maxAllowedPoints = ctx.points.maxPts / (ctx.weights.length + 1);
do {
final long timePassed = startTime.until(stepTime, ChronoUnit.SECONDS);
fireProgressing("Drifting: " + stepTime, (float) (timePassed / totalSeconds) * 100f, false);
MeteoDataset.Snapshot snapshot = meteo.setTime(stepTime).map(calibration -> calibration.setHorizontalComponent(ctx.grid.model.getEnvelope())).orElse(null);
if (snapshot == null)
break;
ctx.points.removeLeastProbable(maxAllowedPoints);
final double[] stepProba = advance(ctx, snapshot);
if (stepProba == null)
break;
// TODO : add abstraction here : we could reduce loop by iterating only over a rectangle where probabilities
// have really been updated.
IntStream.range(0, dayProba.length).parallel().forEach(i -> {
dayProba[i] += stepProba[i];
globalProba[i] += stepProba[i];
});
newDay = stepTime.isAfter(nextDay);
if (newDay) {
nextDay = nextDay.plus(1, ChronoUnit.DAYS);
outputs.add(new Output(dayProba, ctx.grid.width, ctx.grid.height));
Arrays.fill(dayProba, 0);
}
} while ((stepTime = ctx.step(stepTime)).isBefore(endTime));
if (stepTime.equals(startTime)) {
throw new ProcessException("No data available for time: " + stepTime, this);
}
if (!newDay) {
outputs.add(new Output(dayProba, ctx.grid.width, ctx.grid.height));
}
outputs.add(new Output(globalProba, ctx.grid.width, ctx.grid.height));
outputParameters.getOrCreate(ACTUAL_END_TIMESTAMP).setValue(stepTime.toEpochMilli());
return outputs;
}
use of org.geotoolkit.processing.science.drift.Output in project geotoolkit by Geomatys.
the class Predictor method execute.
@Override
protected void execute() throws ProcessException {
// // TODO: move in prediction context
final Instant startTime = Instant.ofEpochMilli(inputParameters.getMandatoryValue(START_TIMESTAMP));
final Instant endTime = Instant.ofEpochMilli(inputParameters.getMandatoryValue(END_TIMESTAMP));
final MeteoDataset meteo = initData();
final Origin origin;
try {
DirectPosition tmpOrigin = inputParameters.getMandatoryValue(START_POINT);
tmpOrigin = setTime(tmpOrigin, startTime);
origin = new Origin(tmpOrigin);
} catch (FactoryException | TransformException ex) {
throw new ProcessException("Cannot align start position with meteo coordinate system", this, ex);
}
final MeteoDataset.TimeSet initedMeteo = init(meteo, origin.getSource());
final PredictionContext ctx = initContext(origin.getOrigin2d());
// // END TODO
/* Note: we should create it at the end, BUT: If this fails, we cannot store processing results, so it's useless
* to start any heavy computing before being sure we will be able to store them. Doing tmp file creation
* beforehand allows to ensure we can write on disk.
*/
final Path outputFile;
try {
outputFile = Files.createTempFile("drift", ".nc");
} catch (IOException ex) {
throw new ProcessException("Cannot create a temporary file for result storage", this, ex);
}
try {
// TODO: stream all this sh*t
List<Output> outputs = compute(startTime, endTime, ctx, initedMeteo);
write(outputs, ctx.grid.model, startTime, outputFile);
} catch (Exception ex) {
try {
Files.delete(outputFile);
} catch (Exception bis) {
ex.addSuppressed(bis);
}
if (ex instanceof ProcessException) {
throw (ProcessException) ex;
}
throw new ProcessException("Error while computing", this, ex);
}
outputParameters.getOrCreate(OUTPUT_DATA).setValue(outputFile);
}
Aggregations