Skip to content

Commit

Permalink
CCT 1.0.10 Release Notes
Browse files Browse the repository at this point in the history
Features and improvements

This is a smaller release focused around creating and using bounding polygons in the CCT map.

Mapping

* Includes the Leaflet Geoman library to support drawing and editing bounding boxes and arbitrary polygons on the map
* Support for importing and exporting polygons is now included as a field in the calibration JSON definition as a GeoJSON formatted block
* Include/exclude options to toggle activation status on event/station pairs based on if they are bounded by a polygon
  * Excludes require that both the station and the event meet the criteria, that is inside or outside the polygon, to be selected for disabling
  * Includes require that **either** the station and the event meet the criteria, that is inside or outside the polygon, to be selected for enabling
* Added REST endpoints for managing polygon related tasks via service calls as well

Plotting

* Site/Measurement now plot the estimated corner frequency (~Fc) line on spectral plots when a fit is available.
  • Loading branch information
justinbarno committed Sep 14, 2020
1 parent df2a6a0 commit 10a36d0
Show file tree
Hide file tree
Showing 103 changed files with 1,682 additions and 271 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,18 @@ We don't presently deploy versioned artifacts into a public repository like the
#### **As a single runnable JAR**

```shell
java -jar coda-calibration/calibration-standalone/target/calibration-standalone-1.0.9-runnable.jar
java -jar coda-calibration/calibration-standalone/target/calibration-standalone-1.0.10-runnable.jar
```

#### **GUI alone**

```shell
java -jar coda-calibration/calibration-gui/target/calibration-gui-1.0.9-runnable.jar
java -jar coda-calibration/calibration-gui/target/calibration-gui-1.0.10-runnable.jar
```
#### **Calibration REST service alone**

```shell
java -jar coda-calibration/calibration-service/application/target/application-1.0.9-runnable.jar
java -jar coda-calibration/calibration-service/application/target/application-1.0.10-runnable.jar
```

#### A note about HTTPS
Expand Down
8 changes: 2 additions & 6 deletions calibration-gui/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>gov.llnl.gnem.apps.coda.calibration</groupId>
<artifactId>coda-calibration</artifactId>
<version>1.0.9</version>
<version>1.0.10</version>
</parent>

<artifactId>calibration-gui</artifactId>
Expand Down Expand Up @@ -102,10 +102,6 @@
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
Expand Down Expand Up @@ -177,7 +173,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
</dependency>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@
import gov.llnl.gnem.apps.coda.calibration.gui.controllers.SiteController;
import gov.llnl.gnem.apps.coda.calibration.gui.controllers.parameters.ParametersController;
import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.CalibrationClient;
import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.ParameterClient;
import gov.llnl.gnem.apps.coda.calibration.gui.data.exporters.ParamExporter;
import gov.llnl.gnem.apps.coda.calibration.gui.events.CalibrationStageShownEvent;
import gov.llnl.gnem.apps.coda.calibration.gui.events.MapIconActivationCallback;
import gov.llnl.gnem.apps.coda.calibration.gui.events.MapPolygonChangeHandler;
import gov.llnl.gnem.apps.coda.calibration.gui.events.UpdateMapPolygonEvent;
import gov.llnl.gnem.apps.coda.calibration.gui.plotting.WaveformGui;
import gov.llnl.gnem.apps.coda.calibration.gui.util.CalibrationProgressListener;
import gov.llnl.gnem.apps.coda.calibration.gui.util.FileDialogs;
Expand Down Expand Up @@ -139,6 +142,8 @@ public class CodaGuiController {
private GeoMap mapController;

private WaveformClient waveformClient;

private ParameterClient configClient;

private EnvelopeLoadingController envelopeLoadingController;

Expand Down Expand Up @@ -179,7 +184,7 @@ public class CodaGuiController {
@Autowired
public CodaGuiController(GeoMap mapController, WaveformClient waveformClient, EnvelopeLoadingController waveformLoadingController, CodaParamLoadingController codaParamLoadingController,
ReferenceEventLoadingController refEventLoadingController, CalibrationClient calibrationClient, ParamExporter paramExporter, WaveformGui waveformGui, DataController data,
ParametersController param, ShapeController shape, PathController path, SiteController site, MeasuredMwsController measuredMws, EventBus bus) {
ParametersController param, ShapeController shape, PathController path, SiteController site, MeasuredMwsController measuredMws, ParameterClient configClient, EventBus bus) {
super();
this.mapController = mapController;
this.waveformClient = waveformClient;
Expand All @@ -195,6 +200,7 @@ public CodaGuiController(GeoMap mapController, WaveformClient waveformClient, En
this.path = path;
this.site = site;
this.measuredMws = measuredMws;
this.configClient = configClient;
this.bus = bus;
bus.register(this);

Expand Down Expand Up @@ -335,6 +341,7 @@ public void initialize() {
waveformFocus.selectedProperty().bindBidirectional(waveformGui.focusProperty());

mapController.registerEventCallback(new MapIconActivationCallback(waveformClient));
mapController.registerEventCallback(new MapPolygonChangeHandler(configClient));

activeMapIcon = makeMapLabel();
showMapIcon = makeMapLabel();
Expand Down Expand Up @@ -450,6 +457,13 @@ private Label makeSnapshotLabel() {
return label;
}

@Subscribe
private void listener(UpdateMapPolygonEvent event) {
if (mapController != null && event != null && event.getGeoJSON() != null && !event.getGeoJSON().isEmpty()) {
mapController.setPolygonGeoJSON(event.getGeoJSON());
}
}

//TODO: Move this to a controller
@Subscribe
private void listener(CalibrationStatusEvent event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
package gov.llnl.gnem.apps.coda.calibration.gui.controllers;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
Expand Down Expand Up @@ -52,8 +54,8 @@
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.ParameterClient;
import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.EventClient;
import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.ParameterClient;
import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.SpectraClient;
import gov.llnl.gnem.apps.coda.calibration.gui.plotting.MapPlottingUtilities;
import gov.llnl.gnem.apps.coda.calibration.gui.plotting.SpectralPlot;
Expand Down Expand Up @@ -397,11 +399,19 @@ public void initialize() {
.asObject());

iconCol.setCellValueFactory(x -> Bindings.createObjectBinding(() -> Optional.ofNullable(x).map(CellDataFeatures::getValue).map(pp -> {
ImageView imView = new ImageView(SwingFXUtils.toFXImage(SymbolFactory.createSymbol(pp.getStyle(), 0, 0, 2, pp.getColor(), pp.getColor(), pp.getColor(), "", true, false, 10.0)
.getBufferedImage(256),
null));
imView.setFitHeight(12);
imView.setFitWidth(12);
BufferedImage iconLayer = SymbolFactory.createSymbol(pp.getStyle(), 0, 0, 2.0, pp.getColor(), Color.BLACK, pp.getColor(), "", true, false, 10.0).getBufferedImage(216);
BufferedImage backgroundLayer = SymbolFactory.createSymbol(pp.getStyle(), 0, 0, 2.0, Color.BLACK, Color.BLACK, Color.BLACK, "", true, false, 10.0).getBufferedImage(256);

BufferedImage combined = new BufferedImage(backgroundLayer.getWidth(), backgroundLayer.getHeight(), BufferedImage.TYPE_INT_ARGB);

Graphics g = combined.getGraphics();
g.drawImage(backgroundLayer, 0, 0, null);
g.drawImage(iconLayer, 20, 20, null);
g.dispose();

ImageView imView = new ImageView(SwingFXUtils.toFXImage(combined, null));
imView.setFitHeight(16);
imView.setFitWidth(16);
return imView;
}).orElseGet(() -> new ImageView())));

Expand Down Expand Up @@ -466,7 +476,7 @@ private void plotSpectra() {

spectraControllers.forEach(spc -> {
if (fittingSpectra != null) {
spc.getSpectralPlot().plotXYdata(toPlotPoints(filteredMeasurements, spc.getDataFunc()), SHOW_LEGEND, fittingSpectra);
spc.getSpectralPlot().plotXYdata(toPlotPoints(filteredMeasurements, spc.getDataFunc()), SHOW_LEGEND, fittingSpectra);
} else {
spc.getSpectralPlot().plotXYdata(toPlotPoints(filteredMeasurements, spc.getDataFunc()), HIDE_LEGEND);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
import com.google.common.eventbus.EventBus;

import gov.llnl.gnem.apps.coda.calibration.gui.converters.api.FileToParameterConverter;
import gov.llnl.gnem.apps.coda.calibration.gui.converters.param.RawGeoJSON;
import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.ParameterClient;
import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.EventClient;
import gov.llnl.gnem.apps.coda.calibration.gui.events.ParametersLoadedEvent;
import gov.llnl.gnem.apps.coda.calibration.gui.events.UpdateMapPolygonEvent;
import gov.llnl.gnem.apps.coda.calibration.model.domain.MdacParametersFI;
import gov.llnl.gnem.apps.coda.calibration.model.domain.MdacParametersPS;
import gov.llnl.gnem.apps.coda.calibration.model.domain.ReferenceMwParameters;
Expand Down Expand Up @@ -182,6 +184,9 @@ protected void convertFiles(List<File> validFiles) {
} else {
log.error("Returned a null request from the parameter client while posting ShapeFitterConstraints {}", entry);
}
} else if (res.get() instanceof RawGeoJSON) {
RawGeoJSON entry = (RawGeoJSON) res.get();
bus.post(new UpdateMapPolygonEvent(entry.getRawGeoJSON()));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public class DataController implements MapListeningController, RefreshableContro

@FXML
private ScrollPane scrollPane;

@FXML
private TableView<Waveform> tableView;

Expand All @@ -101,7 +101,7 @@ public class DataController implements MapListeningController, RefreshableContro

@FXML
private TableColumn<Waveform, String> highFreqCol;

@FXML
private TableColumn<Waveform, String> depthCol;

Expand Down Expand Up @@ -210,20 +210,21 @@ private void reloadTable(ActionEvent e) {
@FXML
public void initialize() {
tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
eventCol.setCellValueFactory(
x -> Bindings.createStringBinding(() -> Optional.ofNullable(x).map(CellDataFeatures::getValue).map(Waveform::getEvent).map(Event::getEventId).orElseGet(String::new)));
eventCol.setCellValueFactory(x -> Bindings.createStringBinding(() -> Optional.ofNullable(x)
.map(CellDataFeatures::getValue)
.map(Waveform::getEvent)
.map(Event::getEventId)
.orElseGet(String::new)));
eventCol.comparatorProperty().set(new MaybeNumericStringComparator());

CellBindingUtils.attachTextCellFactories(lowFreqCol, Waveform::getLowFrequency, dfmt2);
CellBindingUtils.attachTextCellFactories(highFreqCol, Waveform::getHighFrequency, dfmt2);

depthCol.setCellValueFactory(
x -> Bindings.createStringBinding(
() ->
dfmt2.format(
Optional.ofNullable(x).map(CellDataFeatures::getValue)
.map(Waveform::getEvent)
.map(ev->Double.toString(ev.getDepth())).orElseGet(String::new))));

depthCol.setCellValueFactory(x -> Bindings.createStringBinding(() -> Optional.ofNullable(x)
.map(CellDataFeatures::getValue)
.map(Waveform::getEvent)
.map(ev -> dfmt2.format(ev.getDepth()))
.orElseGet(String::new)));
depthCol.comparatorProperty().set(new MaybeNumericStringComparator());

usedCol.setCellValueFactory(x -> Bindings.createObjectBinding(() -> Optional.ofNullable(x).map(CellDataFeatures::getValue).map(waveform -> {
Expand All @@ -243,9 +244,12 @@ public void initialize() {
}).orElseGet(CheckBox::new)));
usedCol.comparatorProperty().set((c1, c2) -> Boolean.compare(c1.isSelected(), c2.isSelected()));

stationCol.setCellValueFactory(
x -> Bindings.createStringBinding(
() -> Optional.ofNullable(x).map(CellDataFeatures::getValue).map(Waveform::getStream).map(Stream::getStation).map(Station::getStationName).orElseGet(String::new)));
stationCol.setCellValueFactory(x -> Bindings.createStringBinding(() -> Optional.ofNullable(x)
.map(CellDataFeatures::getValue)
.map(Waveform::getStream)
.map(Stream::getStation)
.map(Station::getStationName)
.orElseGet(String::new)));

tableView.getSelectionModel().getSelectedItems().addListener(tableChangeListener);
//Workaround for https://bugs.openjdk.java.net/browse/JDK-8095943, for now we just clear the selection to avoid dumping a stack trace in the logs and mucking up event bubbling
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ public double getProgress() {
plot.addPlotObjectObserver(getPlotpointObserver(() -> spectra.getSymbolMap()));
plot.setLabels("Moment Rate Spectra", X_AXIS_LABEL, "log10(dyne-cm)");
plot.setYaxisVisibility(true);
spectra.setShowCornerFrequencies(true);
spectra.setYAxisResizable(true);
spectraPlotSwingNode.setContent(plot);

Expand Down Expand Up @@ -172,7 +173,7 @@ protected void preloadData() {
List<MeasuredMwDetails> refEvs = referenceEventClient.getMeasuredEventDetails()
.filter(ev -> ev.getEventId() != null)
.collect(Collectors.toList())
.subscribeOn(Schedulers.elastic())
.subscribeOn(Schedulers.boundedElastic())
.block(Duration.ofSeconds(10l));
Collection<MeasuredMwDetails> measMws = mfs.getMeasuredMwDetails().values();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@

import javax.swing.SwingUtilities;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

Expand All @@ -52,8 +50,6 @@
@Component
public class SiteController extends AbstractMeasurementController {

private static final Logger log = LoggerFactory.getLogger(SiteController.class);

private static final String X_AXIS_LABEL = "center freq";

private static final String displayName = "Site";
Expand Down Expand Up @@ -108,6 +104,7 @@ public void initialize() {
plot.addPlotObjectObserver(getPlotpointObserver(() -> site.getSymbolMap()));
plot.setLabels("Moment Rate Spectra", X_AXIS_LABEL, "log10(dyne-cm)");
plot.setYaxisVisibility(true);
site.setShowCornerFrequencies(true);
site.setYAxisResizable(true);
sitePlotSwingNode.setContent(plot);

Expand Down Expand Up @@ -155,7 +152,7 @@ protected List<MeasuredMwDetails> getEvents() {
return referenceEventClient.getMeasuredEventDetails()
.filter(ev -> ev.getEventId() != null)
.collect(Collectors.toList())
.subscribeOn(Schedulers.elastic())
.subscribeOn(Schedulers.boundedElastic())
.block(Duration.ofSeconds(10l));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,11 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import gov.llnl.gnem.apps.coda.calibration.gui.plotting.SpectralPlot;
import gov.llnl.gnem.apps.coda.calibration.model.domain.SpectraMeasurement;

public class SpectraPlotController {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private SpectralPlot spectraPlot = new SpectralPlot();;
private SpectralPlot spectraPlot = new SpectralPlot();
private Map<Point2D.Double, SpectraMeasurement> spectraSymbolMap = new ConcurrentHashMap<>();
private boolean isYaxisResizble = false;
private Function<SpectraMeasurement, Double> dataFunction;
Expand Down Expand Up @@ -61,4 +57,8 @@ public void setYAxisResizable(boolean isYaxisResizble) {
public Function<SpectraMeasurement, Double> getDataFunc() {
return dataFunction;
}

public void setShowCornerFrequencies(boolean showCornerFrequencies) {
this.spectraPlot.showCornerFrequency(showCornerFrequencies);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ protected void requestData() {
.filter(Objects::nonNull)
.filter(value -> null != value.getId())
.doOnComplete(() -> Optional.ofNullable(codaSharedTableView).ifPresent(TableView::sort))
.subscribe(value -> sharedFbData.add(value), err -> log.trace(err.getMessage(), err));
.subscribe(value -> sharedFbData.add(value), err -> log.error(err.getMessage(), err));
Optional.ofNullable(codaSharedTableView).ifPresent(v -> v.refresh());
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import static gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.CalibrationJsonConstants.TYPE_VALUE;
import static gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.CalibrationJsonConstants.VALIDATION_EVENTS_FIELD;
import static gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.CalibrationJsonConstants.VELOCITY_CONFIGURATION;
import static gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.CalibrationJsonConstants.POLYGON_FIELD;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -114,6 +115,7 @@ public List<Result<Object>> convertJsonParamFile(File file) {
results.addAll(convertJsonFields(node, VALIDATION_EVENTS_FIELD, x -> valEventsFromJsonNode(x)));
results.addAll(convertJsonFields(node, VELOCITY_CONFIGURATION, x -> velocityConfigurationFromJsonNode(x)));
results.addAll(convertJsonFields(node, SHAPE_CONSTRAINTS, x -> shapeConstraintsFromJsonNode(x)));
results.addAll(convertJsonFields(node, POLYGON_FIELD, x -> polygonFromJsonNode(x)));
} else if (node.has(ENVELOPE_JOB_NODE)) {
results.addAll(convertJsonFields(node, ENVELOPE_JOB_NODE, x -> envelopeJobBandsToSharedBands(x)));
}
Expand All @@ -124,6 +126,10 @@ public List<Result<Object>> convertJsonParamFile(File file) {
return results;
}

private Result<Object> polygonFromJsonNode(JsonNode polygon) {
return new Result<>(true, new RawGeoJSON(polygon.toString()));
}

protected List<Result<Object>> convertJsonFields(JsonNode node, String field, Function<JsonNode, Result<Object>> func) {
List<Result<Object>> results = new ArrayList<>();
List<JsonNode> nodes = node.findValues(field);
Expand Down
Loading

0 comments on commit 10a36d0

Please sign in to comment.