diff --git a/README.md b/README.md
index 8020df36..2b855069 100644
--- a/README.md
+++ b/README.md
@@ -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.4-runnable.jar
+java -jar coda-calibration/calibration-standalone/target/calibration-standalone-1.0.5-runnable.jar
```
#### **GUI alone**
```shell
-java -jar coda-calibration/calibration-gui/target/calibration-gui-1.0.4-runnable.jar
+java -jar coda-calibration/calibration-gui/target/calibration-gui-1.0.5-runnable.jar
```
#### **Calibration REST service alone**
```shell
-java -jar coda-calibration/calibration-service/application/target/application-1.0.4-runnable.jar
+java -jar coda-calibration/calibration-service/application/target/application-1.0.5-runnable.jar
```
#### A note about HTTPS
diff --git a/calibration-gui/pom.xml b/calibration-gui/pom.xml
index 590270ec..bc74794c 100644
--- a/calibration-gui/pom.xml
+++ b/calibration-gui/pom.xml
@@ -7,7 +7,7 @@
gov.llnl.gnem.apps.coda.calibrationcoda-calibration
- 1.0.4-SNAPSHOT
+ 1.0.5calibration-gui
diff --git a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/plotting/CodaWaveformPlot.java b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/plotting/CodaWaveformPlot.java
index 4b496a91..a3a30cb5 100644
--- a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/plotting/CodaWaveformPlot.java
+++ b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/plotting/CodaWaveformPlot.java
@@ -2,11 +2,11 @@
* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
-* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
-*
+* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
+*
* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the license.
*
* This work was performed under the auspices of the U.S. Department of Energy
@@ -150,7 +150,7 @@ public void setWaveform(Waveform waveform, SyntheticCoda synth) {
// waveform so we need to check that
for (WaveformPick pick : picks) {
double pickTime;
- //"'Bad' pick, plot it at begin time
+ //"'Bad' pick, plot it at begin time
if (pick.getPickTimeSecFromOrigin() < 0) {
pickTime = new TimeT(waveform.getBeginTime()).getEpochTime();
} else {
@@ -271,17 +271,20 @@ private void plotSynthetic(Waveform waveform, SyntheticCoda synth, final TimeT b
if (startTime.lt(endTime)) {
interpolatedSeries.cut(startTime, endTime);
synthSeriesBeforeEndMarker.cut(startTime, endTime);
- synthSeriesRemaining.cutBefore(endTime);
TimeSeries diffSeis = interpolatedSeries.subtract(synthSeriesBeforeEndMarker);
int synthStartTimeShift = (int) (startTime.subtractD(beginTime) + 0.5);
- int remainingStartTimeShift = (int) (endTime.subtractD(beginTime) + 0.5);
double median = diffSeis.getMedian();
subplot.DeletePlotObject(legendRef);
subplot.AddPlotObject(createLegend(labelText + "Shift: " + dfmt4.format(median)));
subplot.AddPlotObject(createLine(synthStartTimeShift, median, synthSeriesBeforeEndMarker, Color.GREEN), PLOT_ORDERING.MODEL_FIT.getZOrder());
- subplot.AddPlotObject(createLine(remainingStartTimeShift, median, synthSeriesRemaining, Color.GREEN, 3, PenStyle.DASH), PLOT_ORDERING.MODEL_FIT.getZOrder());
+
+ if (endTime.lt(synthSeriesRemaining.getEndtime())) {
+ synthSeriesRemaining.cutBefore(endTime);
+ int remainingStartTimeShift = (int) (endTime.subtractD(beginTime) + 0.5);
+ subplot.AddPlotObject(createLine(remainingStartTimeShift, median, synthSeriesRemaining, Color.GREEN, 3, PenStyle.DASH), PLOT_ORDERING.MODEL_FIT.getZOrder());
+ }
repaint();
}
}
@@ -336,7 +339,7 @@ private PlotObject createRectangle(int timeStart, int timeEnd, int heightMin, in
/*
* (non-Javadoc)
- *
+ *
* @see
* llnl.gnem.core.gui.waveform.WaveformPlot#handlePickMovedState(java.lang.
* Object)T
diff --git a/calibration-service/calibration-application/pom.xml b/calibration-service/calibration-application/pom.xml
index 2d524d6d..5b7cbf57 100644
--- a/calibration-service/calibration-application/pom.xml
+++ b/calibration-service/calibration-application/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.calibrationcalibration-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/calibration-service/calibration-integration/pom.xml b/calibration-service/calibration-integration/pom.xml
index 486fb261..91c47cc0 100644
--- a/calibration-service/calibration-integration/pom.xml
+++ b/calibration-service/calibration-integration/pom.xml
@@ -4,7 +4,7 @@
gov.llnl.gnem.apps.coda.calibrationcalibration-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/calibration-service/calibration-model/pom.xml b/calibration-service/calibration-model/pom.xml
index f26c0701..c3b28761 100644
--- a/calibration-service/calibration-model/pom.xml
+++ b/calibration-service/calibration-model/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.calibrationcalibration-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/calibration-service/calibration-repository/pom.xml b/calibration-service/calibration-repository/pom.xml
index 530c276c..394535ce 100644
--- a/calibration-service/calibration-repository/pom.xml
+++ b/calibration-service/calibration-repository/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.calibrationcalibration-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/calibration-service/calibration-service-api/pom.xml b/calibration-service/calibration-service-api/pom.xml
index 31775d3f..c1cff6a2 100644
--- a/calibration-service/calibration-service-api/pom.xml
+++ b/calibration-service/calibration-service-api/pom.xml
@@ -4,7 +4,7 @@
gov.llnl.gnem.apps.coda.calibrationcalibration-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/calibration-service/calibration-service-impl/pom.xml b/calibration-service/calibration-service-impl/pom.xml
index 24ae9c97..6cc6bae5 100644
--- a/calibration-service/calibration-service-impl/pom.xml
+++ b/calibration-service/calibration-service-impl/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.calibrationcalibration-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/Joint1DPathCorrection.java b/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/Joint1DPathCorrection.java
index 121635f8..d1be3b10 100644
--- a/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/Joint1DPathCorrection.java
+++ b/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/Joint1DPathCorrection.java
@@ -24,7 +24,6 @@
import java.util.Set;
import java.util.stream.IntStream;
-import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.math3.analysis.MultivariateFunction;
import org.apache.commons.math3.exception.TooManyEvaluationsException;
import org.apache.commons.math3.optim.ConvergenceChecker;
@@ -37,7 +36,7 @@
import org.apache.commons.math3.optim.nonlinear.scalar.ObjectiveFunction;
import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.CMAESOptimizer;
import org.apache.commons.math3.random.MersenneTwister;
-import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
+import org.eclipse.collections.impl.list.mutable.primitive.DoubleArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -348,7 +347,7 @@ public double costFunction(Map> evidStaD
Event evid = evidEntry.getKey();
Map stationMapData = evidEntry.getValue();
- List dataVec = new ArrayList<>(optimizationParams.length);
+ DoubleArrayList dataVec = new DoubleArrayList(stationMapData.size());
for (Entry entry : stationMapData.entrySet()) {
double del = distanceMap.get(evid).get(entry.getKey());
double site = optimizationParams[stationIdxMap.get(entry.getKey())];
@@ -367,7 +366,7 @@ public double costFunction(Map> evidStaD
if (dataVec.size() > 1) {
double huberDel = .5d;
- double median = new DescriptiveStatistics(ArrayUtils.toPrimitive(dataVec.toArray(new Double[0]))).getPercentile(50d);
+ double median = dataVec.median();
for (Entry entry1 : stationMapData.entrySet()) {
double diff = Math.abs(localDataMap.get(evid).get(entry1.getKey()) - median);
cost = cost + (Math.pow(huberDel, 2.0) + (Math.sqrt(1d + Math.pow(diff / huberDel, 2.0)) - 1d));
diff --git a/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/processing/CalibrationCurveFitter.java b/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/processing/CalibrationCurveFitter.java
index 8a1052bb..4465ce51 100755
--- a/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/processing/CalibrationCurveFitter.java
+++ b/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/processing/CalibrationCurveFitter.java
@@ -19,6 +19,7 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ThreadLocalRandom;
+import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -159,6 +160,14 @@ public EnvelopeFit fitCodaCMAES(final float[] segment) {
return fit;
}
+ private PointValuePair bestByFunction(MultivariateFunction prediction, Function mapper) {
+ return IntStream.range(0, 1 + ITER_COUNT)
+ .parallel()
+ .mapToObj(mapper::apply)
+ .reduce((left, right) -> left.getValue() < right.getValue() ? left : right)
+ .orElseGet(() -> new PointValuePair(new double[4], Double.MAX_VALUE));
+ }
+
public double[] gridSearchCodaVApacheCMAES(List> velocityDistancePairs) {
return gridSearchCodaVApacheCMAES(velocityDistancePairs, YVV_MIN, YVV_MAX, 0, V_DIST_MAX);
}
@@ -192,23 +201,14 @@ public double[] gridSearchCodaVApacheCMAES(final List> vel
return sum;
};
- PointValuePair bestResult = optimizeCMAES(
+ Function mapper = (i) -> optimizeCMAES(
prediction,
new InitialGuess(new double[] { ThreadLocalRandom.current().nextDouble(minP1, maxP1), ThreadLocalRandom.current().nextDouble(minP2, maxP2),
ThreadLocalRandom.current().nextDouble(minP3, maxP3) }),
new CMAESOptimizer.Sigma(new double[] { 1, 75, 100 }),
new SimpleBounds(new double[] { minP1, minP2, minP3 }, new double[] { maxP1, maxP2, maxP3 }));
- for (int i = 1; i < ITER_COUNT; i++) {
- PointValuePair result = optimizeCMAES(
- prediction,
- new InitialGuess(new double[] { ThreadLocalRandom.current().nextDouble(minP1, maxP1), ThreadLocalRandom.current().nextDouble(minP2, maxP2),
- ThreadLocalRandom.current().nextDouble(minP3, maxP3) }),
- new CMAESOptimizer.Sigma(new double[] { 1, 75, 100 }),
- new SimpleBounds(new double[] { minP1, minP2, minP3 }, new double[] { maxP1, maxP2, maxP3 }));
- if (result.getValue() < bestResult.getValue()) {
- bestResult = result;
- }
- }
+
+ PointValuePair bestResult = bestByFunction(prediction, mapper);
double[] curve = new double[4];
curve[0] = bestResult.getPoint()[0] / V0_REG;
@@ -256,25 +256,15 @@ public double[] gridSearchCodaBApacheCMAES(final List> bet
return sum;
};
- PointValuePair bestResult = optimizeCMAES(
+ Function mapper = (i) -> optimizeCMAES(
prediction,
new InitialGuess(new double[] { ThreadLocalRandom.current().nextDouble(minP1, maxP1), ThreadLocalRandom.current().nextDouble(minP2, maxP2),
ThreadLocalRandom.current().nextDouble(minP3, maxP3) }),
new CMAESOptimizer.Sigma(new double[] { .05, 0.5, 750 }),
50,
new SimpleBounds(new double[] { minP1, minP2, minP3 }, new double[] { maxP1, maxP2, maxP3 }));
- for (int i = 1; i < ITER_COUNT; i++) {
- PointValuePair result = optimizeCMAES(
- prediction,
- new InitialGuess(new double[] { ThreadLocalRandom.current().nextDouble(minP1, maxP1), ThreadLocalRandom.current().nextDouble(minP2, maxP2),
- ThreadLocalRandom.current().nextDouble(minP3, maxP3) }),
- new CMAESOptimizer.Sigma(new double[] { .05, 0.5, 750 }),
- 50,
- new SimpleBounds(new double[] { minP1, minP2, minP3 }, new double[] { maxP1, maxP2, maxP3 }));
- if (result.getValue() < bestResult.getValue()) {
- bestResult = result;
- }
- }
+
+ PointValuePair bestResult = bestByFunction(prediction, mapper);
double[] curve = new double[4];
curve[0] = bestResult.getPoint()[0] / B0_REG;
@@ -338,27 +328,15 @@ public double[] gridSearchCodaGApacheCMAES(final List> gam
ConvergenceChecker convergenceChecker = new SimplePointChecker<>(0.005, 0.005, 100000);
- PointValuePair bestResult = optimizeCMAES(
+ Function mapper = (i) -> optimizeCMAES(
prediction,
new InitialGuess(new double[] { ThreadLocalRandom.current().nextDouble(minP1, maxP1), minP2, minP3 }),
new CMAESOptimizer.Sigma(new double[] { 1, 50, 50 }),
convergenceChecker,
50,
new SimpleBounds(new double[] { minP1, minP2, minP3 }, new double[] { maxP1, maxP2, maxP3 }));
- for (int i = 1; i < ITER_COUNT; i++) {
-
- PointValuePair result = optimizeCMAES(
- prediction,
- new InitialGuess(new double[] { ThreadLocalRandom.current().nextDouble(minP1, maxP1), ThreadLocalRandom.current().nextDouble(minP2, maxP2),
- ThreadLocalRandom.current().nextDouble(minP3, maxP3) }),
- new CMAESOptimizer.Sigma(new double[] { 1, 50, 50 }),
- convergenceChecker,
- 50,
- new SimpleBounds(new double[] { minP1, minP2, minP3 }, new double[] { maxP1, maxP2, maxP3 }));
- if (result.getValue() < bestResult.getValue()) {
- bestResult = result;
- }
- }
+
+ PointValuePair bestResult = bestByFunction(prediction, mapper);
double[] curve = new double[4];
curve[0] = bestResult.getPoint()[0] / G0_REG;
diff --git a/calibration-service/pom.xml b/calibration-service/pom.xml
index 4486245b..cae26073 100644
--- a/calibration-service/pom.xml
+++ b/calibration-service/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.calibrationcoda-calibration
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/calibration-standalone/pom.xml b/calibration-standalone/pom.xml
index 5e7cedf7..8cea825a 100644
--- a/calibration-standalone/pom.xml
+++ b/calibration-standalone/pom.xml
@@ -6,7 +6,7 @@
gov.llnl.gnem.apps.coda.calibrationcoda-calibration
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/common-gui/pom.xml b/common-gui/pom.xml
index 667c47c7..a8e2a5f4 100644
--- a/common-gui/pom.xml
+++ b/common-gui/pom.xml
@@ -7,7 +7,7 @@
gov.llnl.gnem.apps.coda.calibrationcoda-calibration
- 1.0.4-SNAPSHOT
+ 1.0.5gov.llnl.gnem.apps.coda.common
diff --git a/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacExporter.java b/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacExporter.java
index d0efda1d..9a293a83 100644
--- a/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacExporter.java
+++ b/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacExporter.java
@@ -2,11 +2,11 @@
* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
-* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
-*
+* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
+*
* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the license.
*
* This work was performed under the auspices of the U.S. Department of Energy
@@ -42,8 +42,6 @@
@Component
public class SacExporter {
private static final String SEP = "_";
- private final NumberFormat dfmt4 = NumberFormatFactory.fourDecimalOneLeadingZero();
-
private static final Logger log = LoggerFactory.getLogger(SacExporter.class);
public Result writeWaveformToDirectory(File exportDirectory, Waveform w) {
@@ -104,24 +102,23 @@ public Result writeWaveformToDirectory(File exportDirectory, Waveform w)
}
os.flush();
- return new Result(true, filename);
+ return new Result<>(true, filename);
}
} catch (IOException e) {
log.error(e.getMessage(), e);
- return new Result(false, e.toString()).setErrors(Collections.singletonList(e));
+ return new Result<>(false, e.toString()).setErrors(Collections.singletonList(e));
}
}
String message = "Waveform is missing required information or is malformed; waveform: " + w;
log.error(message);
- return new Result(false, message);
+ return new Result<>(false, message);
}
private boolean waveformFullySpecified(Waveform w) {
return w != null
&& w.getLowFrequency() != null
&& w.getHighFrequency() != null
- && present(w.getSegmentType())
&& w.getSampleRate() != null
&& w.getBeginTime() != null
&& w.getEndTime() != null
@@ -136,6 +133,7 @@ && present(w.getStream().getChannelName())
public String getFileName(Waveform w) {
if (waveformFullySpecified(w)) {
+ NumberFormat dfmt4 = NumberFormatFactory.fourDecimalOneLeadingZero();
Stream stream = w.getStream();
Event ev = w.getEvent();
diff --git a/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacLoader.java b/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacLoader.java
index 7e794b59..8b0efa4a 100644
--- a/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacLoader.java
+++ b/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacLoader.java
@@ -2,11 +2,11 @@
* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
-* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
-*
+* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
+*
* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the license.
*
* This work was performed under the auspices of the U.S. Department of Energy
@@ -209,7 +209,7 @@ public Result convertSacFileToWaveform(File file) {
double[] segment = new double[rawVals.length];
try {
IntStream.range(0, rawVals.length).forEach(index -> {
- segment[index] = Double.valueOf(rawVals[index]);
+ segment[index] = rawVals[index];
if (!Double.isFinite(segment[index])) {
throw new LightweightIllegalStateException("Invalid data in segment for file: " + fileName);
}
diff --git a/common-service/common-application/pom.xml b/common-service/common-application/pom.xml
index e0f4d910..c342d9f6 100644
--- a/common-service/common-application/pom.xml
+++ b/common-service/common-application/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.commoncommon-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/common-service/common-application/src/main/java/gov/llnl/gnem/apps/coda/common/application/web/WaveformsCollectionJsonController.java b/common-service/common-application/src/main/java/gov/llnl/gnem/apps/coda/common/application/web/WaveformsCollectionJsonController.java
index b7125e82..519b4f4b 100644
--- a/common-service/common-application/src/main/java/gov/llnl/gnem/apps/coda/common/application/web/WaveformsCollectionJsonController.java
+++ b/common-service/common-application/src/main/java/gov/llnl/gnem/apps/coda/common/application/web/WaveformsCollectionJsonController.java
@@ -2,11 +2,11 @@
* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
-* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
-*
+* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
+*
* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the license.
*
* This work was performed under the auspices of the U.S. Department of Energy
@@ -14,8 +14,10 @@
*/
package gov.llnl.gnem.apps.coda.common.application.web;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Set;
import javax.validation.Valid;
@@ -41,7 +43,7 @@
public class WaveformsCollectionJsonController {
/**
- *
+ *
* @param waveformService
*/
@Autowired
@@ -50,7 +52,7 @@ public WaveformsCollectionJsonController(WaveformService waveformService) {
}
/**
- *
+ *
* @param waveform
* @param result
* @return ResponseEntity
@@ -106,7 +108,7 @@ public ResponseEntity> setActiveFlagByStationName(@PathVariable Boolean active
}
/**
- *
+ *
* @param ids
* @return ResponseEntity
*/
@@ -121,7 +123,7 @@ public ResponseEntity> getBatchMetadata(@PathVariable("ids") List ids) {
}
/**
- *
+ *
* @param ids
* @return ResponseEntity
*/
@@ -136,37 +138,37 @@ public ResponseEntity> getBatch(@PathVariable("ids") Collection ids) {
}
/**
- *
+ *
* @param waveforms
* @param result
* @return ResponseEntity
*/
@PostMapping(value = "/batch/{sessionId}", name = "createBatch")
- public ResponseEntity> createBatch(@PathVariable Long sessionId, @Valid @RequestBody List waveforms, BindingResult result) {
+ public ResponseEntity> createBatch(@PathVariable Long sessionId, @Valid @RequestBody Set waveforms, BindingResult result) {
if (result.hasErrors()) {
return ResponseEntity.status(HttpStatus.CONFLICT).body(result);
}
- getWaveformService().update(sessionId, waveforms);
+ getWaveformService().update(sessionId, new ArrayList<>(waveforms));
return ResponseEntity.ok().build();
}
/**
- *
+ *
* @param waveforms
* @param result
* @return ResponseEntity
*/
@PutMapping(value = "/batch/{sessionId}", name = "updateBatch")
- public ResponseEntity> updateBatch(@PathVariable Long sessionId, @Valid @RequestBody List waveforms, BindingResult result) {
+ public ResponseEntity> updateBatch(@PathVariable Long sessionId, @Valid @RequestBody Set waveforms, BindingResult result) {
if (result.hasErrors()) {
return ResponseEntity.status(HttpStatus.CONFLICT).body(result);
}
- getWaveformService().update(sessionId, waveforms);
+ getWaveformService().update(sessionId, new ArrayList<>(waveforms));
return ResponseEntity.ok().build();
}
/**
- *
+ *
* @param ids
* @return ResponseEntity
*/
@@ -177,12 +179,12 @@ public ResponseEntity> deleteBatch(@PathVariable("ids") Collection ids)
}
/**
- *
+ *
*/
private WaveformService waveformService;
/**
- *
+ *
* @return WaveformService
*/
public WaveformService getWaveformService() {
diff --git a/common-service/common-model/pom.xml b/common-service/common-model/pom.xml
index 2716ffa2..a3f4c3a4 100644
--- a/common-service/common-model/pom.xml
+++ b/common-service/common-model/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.commoncommon-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/common-service/common-model/src/main/java/gov/llnl/gnem/apps/coda/common/model/domain/Station.java b/common-service/common-model/src/main/java/gov/llnl/gnem/apps/coda/common/model/domain/Station.java
index cc066cde..3b585baf 100644
--- a/common-service/common-model/src/main/java/gov/llnl/gnem/apps/coda/common/model/domain/Station.java
+++ b/common-service/common-model/src/main/java/gov/llnl/gnem/apps/coda/common/model/domain/Station.java
@@ -20,6 +20,8 @@
import javax.persistence.Embeddable;
import javax.validation.constraints.NotNull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.format.annotation.NumberFormat;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
@@ -29,6 +31,7 @@
@JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class)
public class Station implements Serializable {
+ private static final Logger log = LoggerFactory.getLogger(Station.class);
private static final long serialVersionUID = 1L;
@Column(name = "network_name")
@@ -107,9 +110,11 @@ public boolean equals(Object obj) {
Station other = (Station) obj;
if (networkName == null) {
if (other.networkName != null) {
+ log.trace("Mismatched network names {} and {}", networkName, other.networkName);
return false;
}
} else if (!networkName.equalsIgnoreCase(other.networkName)) {
+ log.trace("Mismatched network names {} and {}", networkName, other.networkName);
return false;
}
if (stationName == null) {
diff --git a/common-service/common-repository/pom.xml b/common-service/common-repository/pom.xml
index 4a388f6a..f357fb15 100644
--- a/common-service/common-repository/pom.xml
+++ b/common-service/common-repository/pom.xml
@@ -4,7 +4,7 @@
gov.llnl.gnem.apps.coda.commoncommon-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/common-service/common-service-api/pom.xml b/common-service/common-service-api/pom.xml
index 28fe6ff6..7789385b 100644
--- a/common-service/common-service-api/pom.xml
+++ b/common-service/common-service-api/pom.xml
@@ -4,7 +4,7 @@
gov.llnl.gnem.apps.coda.commoncommon-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/common-service/common-service-impl/pom.xml b/common-service/common-service-impl/pom.xml
index fce7ce87..4a4dc903 100644
--- a/common-service/common-service-impl/pom.xml
+++ b/common-service/common-service-impl/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.commoncommon-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/common-service/pom.xml b/common-service/pom.xml
index d5d9a68a..9203f8f1 100644
--- a/common-service/pom.xml
+++ b/common-service/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.calibrationcoda-calibration
- 1.0.4-SNAPSHOT
+ 1.0.5gov.llnl.gnem.apps.coda.common
diff --git a/envelope-gui/pom.xml b/envelope-gui/pom.xml
index c03074fc..0dd9da2f 100644
--- a/envelope-gui/pom.xml
+++ b/envelope-gui/pom.xml
@@ -7,7 +7,7 @@
gov.llnl.gnem.apps.coda.calibrationcoda-calibration
- 1.0.4-SNAPSHOT
+ 1.0.5envelope-gui
diff --git a/envelope-gui/src/main/java/gov/llnl/gnem/apps/coda/envelope/gui/controllers/WaveformLoadingController.java b/envelope-gui/src/main/java/gov/llnl/gnem/apps/coda/envelope/gui/controllers/WaveformLoadingController.java
index d1ad6975..81c19f51 100644
--- a/envelope-gui/src/main/java/gov/llnl/gnem/apps/coda/envelope/gui/controllers/WaveformLoadingController.java
+++ b/envelope-gui/src/main/java/gov/llnl/gnem/apps/coda/envelope/gui/controllers/WaveformLoadingController.java
@@ -2,11 +2,11 @@
* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
-* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
-*
+* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
+*
* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the license.
*
* This work was performed under the auspices of the U.S. Department of Energy
@@ -20,10 +20,14 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -40,7 +44,11 @@
import gov.llnl.gnem.apps.coda.common.gui.converters.api.StackInfo;
import gov.llnl.gnem.apps.coda.common.gui.converters.sac.SacExporter;
import gov.llnl.gnem.apps.coda.common.gui.converters.sac.SacLoader;
+import gov.llnl.gnem.apps.coda.common.gui.util.ProgressEventProgressListener;
+import gov.llnl.gnem.apps.coda.common.gui.util.ProgressMonitor;
import gov.llnl.gnem.apps.coda.common.model.domain.Waveform;
+import gov.llnl.gnem.apps.coda.common.model.messaging.Progress;
+import gov.llnl.gnem.apps.coda.common.model.messaging.ProgressEvent;
import gov.llnl.gnem.apps.coda.common.model.messaging.Result;
import gov.llnl.gnem.apps.coda.envelope.gui.data.api.EnvelopeClient;
import llnl.gnem.core.io.SAC.SACHeader;
@@ -60,6 +68,12 @@ public class WaveformLoadingController extends AbstractSeismogramSaveLoadControl
private CodaFilenameParser filenameParser;
+ private ProgressMonitor progressMonitor;
+
+ private ProgressEvent progressEvent;
+
+ private Progress progress;
+
@Autowired
public WaveformLoadingController(List fileConverters, EnvelopeClient client, EnvelopeParamsController params, EventBus bus, SacExporter sacExporter, SacLoader sacLoader,
CodaFilenameParser filenameParser) {
@@ -67,12 +81,16 @@ public WaveformLoadingController(List fileConverters, E
this.sacLoader = sacLoader;
this.filenameParser = filenameParser;
this.loadClient = (id, waveforms) -> client.postEnvelopes(id, waveforms).doOnNext(w -> {
- this.sacExporter.writeWaveformToDirectory(getExportPath(w).toFile(), w);
+ CompletableFuture.runAsync(() -> this.sacExporter.writeWaveformToDirectory(getExportPath(w).toFile(), w));
});
this.setCompletionCallback(() -> {
stackEnvelopes(createEnvelopeMapping(getSacFiles(getExportPath())));
});
this.setMaxBatching(50);
+
+ progress = new Progress(-1l, 0l);
+ progressEvent = new ProgressEvent(idCounter.getAndIncrement(), progress);
+ progressMonitor = new ProgressMonitor("Saving Event-Sta-Freq pairs", new ProgressEventProgressListener(bus, progressEvent));
}
private List getSacFiles(Path path) {
@@ -91,7 +109,7 @@ private List getSacFiles(Path path) {
public void loadFiles(List inputFiles) {
try {
Files.createDirectories(getExportPath());
- super.loadFiles(inputFiles);
+ super.loadFiles(inputFiles, this.getCompletionCallback(), progressMonitor);
} catch (IOException ex) {
// TODO: bus.post(new DisplayableExceptionEvent("Unable to create directory for envelopes.", ex));
log.error(ex.getMessage(), ex);
@@ -99,7 +117,7 @@ public void loadFiles(List inputFiles) {
}
public TreeMap> createEnvelopeMapping(List files) {
- TreeMap> evidStaFreqMap = new TreeMap>();
+ TreeMap> evidStaFreqMap = new TreeMap<>();
for (int ii = 0; ii < files.size(); ii++) {
try {
File file = files.get(ii);
@@ -142,100 +160,113 @@ private boolean isValidStationName(SACHeader header) {
}
public void stackEnvelopes(TreeMap> evidStaFreqMap) {
+ final AtomicLong count = new AtomicLong(0);
+ progress.setTotal((long) evidStaFreqMap.size());
+ progress.setCurrent(count.get());
+ progressEvent.setProgress(progress);
+ bus.post(progressEvent);
+
evidStaFreqMap.entrySet().parallelStream().forEach(entry -> {
if (entry.getValue().size() > 1) {
List files = entry.getValue();
- TimeSeries stackedSeries = null;
- Waveform stackedWaveform = null;
- int nseismograms = 0;
+ Map> waveformsByFreqAndSta = new HashMap<>();
for (int i = 0; i < files.size(); i++) {
- Result result = sacLoader.convertSacFileToWaveform(files.get(i));
- if (result.isSuccess() && result.getResultPayload().isPresent()) {
- Waveform rawWaveform = result.getResultPayload().get();
- if (rawWaveform != null && rawWaveform.getSegment() != null && rawWaveform.getSegment().length > 0) {
- float[] fData = new float[rawWaveform.getSegment().length];
- for (int j = 0; j < fData.length; ++j) {
- fData[j] = (float) rawWaveform.getSegment()[j];
- }
- TimeSeries seis = new TimeSeries(fData, rawWaveform.getSampleRate(), new TimeT(rawWaveform.getBeginTime()));
- if (stackedSeries == null) {
- stackedSeries = seis;
- stackedWaveform = rawWaveform;
- nseismograms = 1;
+ Result res = filenameParser.parse(files.get(i).getName().toUpperCase(Locale.ENGLISH));
+ if (res != null && res.isSuccess() && res.getResultPayload().isPresent()) {
+ StackInfo stackInfo = res.getResultPayload().get();
+ Result result = sacLoader.convertSacFileToWaveform(files.get(i));
+
+ if (result.isSuccess() && result.getResultPayload().isPresent()) {
+ Waveform rawWaveform = result.getResultPayload().get();
+ rawWaveform.setLowFrequency(stackInfo.getLowFrequency());
+ rawWaveform.setHighFrequency(stackInfo.getHighFrequency());
+ if (rawWaveform != null
+ && rawWaveform.getSegment() != null
+ && rawWaveform.getSegment().length > 0
+ && rawWaveform.getStream() != null
+ && rawWaveform.getStream().getStation() != null) {
+ waveformsByFreqAndSta.computeIfAbsent(entry.getKey() + " " + rawWaveform.getStream().getStation().hashCode(), k -> new ArrayList<>()).add(rawWaveform);
} else {
- try {
- if (seis.getTime().gt(stackedSeries.getTime())) {
- stackedSeries.cutBefore(seis.getTime());
- } else {
- seis.cutBefore(stackedSeries.getTime());
- }
-
- if (seis.getEndtime().lt(stackedSeries.getEndtime())) {
- stackedSeries.cutAfter(seis.getEndtime());
- } else {
- seis.cutAfter(stackedSeries.getEndtime());
- }
-
- if (stackedSeries.AddSeismogram(seis)) {
- nseismograms++;
- } else {
- log.warn("{}. Unabled to stack series {} and {}; sample rate or timing mismatch.", entry.getKey(), stackedSeries, seis);
- }
- } catch (IllegalArgumentException e) {
- log.warn("{}. Unabled to stack series {} and {}; {}", entry.getKey(), stackedSeries, seis, e.getMessage());
- }
- }
- if (stackedWaveform != null && (stackedWaveform.getLowFrequency() == null || stackedWaveform.getHighFrequency() == null)) {
- Result res = filenameParser.parse(files.get(i).getName().toUpperCase(Locale.ENGLISH));
- if (res.isSuccess() && res.getResultPayload().isPresent()) {
- StackInfo info = res.getResultPayload().get();
- stackedWaveform.setLowFrequency(info.getLowFrequency());
- stackedWaveform.setHighFrequency(info.getHighFrequency());
- }
+ log.warn("No data or bad station specification for waveform {}.", rawWaveform);
}
+ } else {
+ log.warn("Unable to read envelope file {}. {}", files.get(i), result.getErrors());
}
} else {
- log.warn("Unabled to read envelope file {}. {}", files.get(i), result.getErrors());
+ log.warn("Unable to parse envelope filename for frequency band {}. {}", files.get(i), res.getErrors());
}
-
- // TODO: Implement array processing
- // TODO: Profile to improve perf
- // TODO: Progress bars for stacking
- // TODO: Export envelopes and stacks to separate dirs
- // TODO: Create folder hierarchy for output (Year->Month->Evid->Sta)
-
- // 1. For each element envelope, find record begin and end of each
- // trace ( b and e may have changed because of time shifting)
- // 2. Keep the largest begin and smallest end times of all elements
- // 3. Form an average envelope by summing each trace and then
- // dividing by the total number of envelopes used
- // 4. TODO ? Decimate the averaged envelopes using interp d 0.5
- // where d is the inverse of the number of samples per second TODO
- // == didn't we already do this?
- // 5. Change station header location lat and lon to the reference
- // (array center?) and re-compute hypocentral distance
- // 6. Store the envelope for coda amplitude measurement
}
- if (nseismograms > 1) {
- stackedSeries.MultiplyScalar(1 / ((double) nseismograms));
- float[] stackedData = stackedSeries.getData();
- double[] data = new double[stackedData.length];
- for (int i = 0; i < data.length; ++i) {
- data[i] = stackedData[i];
- }
- stackedWaveform.setSegment(data);
- stackedWaveform.getStream().setChannelName("STACK");
+ List stackedWaveforms = waveformsByFreqAndSta.entrySet().stream().map(e -> stackEnvelopes(e.getValue())).collect(Collectors.toList());
+ // TODO: Export envelopes and stacks to separate dirs
+ for (Waveform stackedWaveform : stackedWaveforms) {
File stackFolder = getExportPath(stackedWaveform).toFile();
sacExporter.writeWaveformToDirectory(stackFolder, stackedWaveform);
- } else {
- log.warn("No valid seismograms available to stack for inputs: {}", files);
}
+ }
+ long currentCount = count.getAndIncrement();
+ if (currentCount % this.getMaxBatching() == 0) {
+ progress.setCurrent(currentCount);
+ progressEvent.setProgress(progress);
+ bus.post(progressEvent);
}
});
+
+ progress.setCurrent(progress.getTotal());
+ progressEvent.setProgress(progress);
+ bus.post(progressEvent);
+ }
+
+ private Waveform stackEnvelopes(List waves) {
+ // FIXME: Duplicate of the one in service.
+ // Need a common-utils because this pulls in stuff from Externals for TimeSeries etc so I can't cheat and slam it into the common model.
+ Waveform base = null;
+ if (waves != null && waves.size() > 1) {
+ try {
+ base = waves.get(0);
+ TimeSeries seis = convertToTimeSeries(base);
+
+ // int nseismograms = 0;
+ for (int i = 1; i < waves.size(); i++) {
+ TimeSeries seis2 = convertToTimeSeries(waves.get(i));
+ seis = seis.add(seis2);
+ }
+ seis.MultiplyScalar(1d / waves.size());
+
+ double[] data = new double[seis.getData().length];
+ for (int j = 0; j < data.length; ++j) {
+ data[j] = seis.getData()[j];
+ }
+ base.setSegment(data);
+ if (base.getSegment() == null || base.getSegment().length == 0) {
+ return null;
+ }
+
+ base.setSampleRate(seis.getSamprate());
+ base.setBeginTime(seis.getTime().getDate());
+ base.setEndTime(seis.getEndtime().getDate());
+ if (base.getStream() != null) {
+ base.getStream().setChannelName("STACK");
+ }
+ } catch (Exception e) {
+ log.info(e.getMessage(), e);
+ }
+ } else {
+ log.info("Waveform with only one channel found for list {}, skipping stacking", waves);
+ }
+ return base;
+ }
+
+ private TimeSeries convertToTimeSeries(Waveform base) {
+ float[] fData = new float[base.getSegment().length];
+ for (int j = 0; j < fData.length; ++j) {
+ fData[j] = (float) base.getSegment()[j];
+ }
+ TimeSeries seis = new TimeSeries(fData, base.getSampleRate(), new TimeT(base.getBeginTime()));
+ return seis;
}
public Path getExportPath() {
diff --git a/envelope-service/envelope-application/pom.xml b/envelope-service/envelope-application/pom.xml
index 17426746..1997d774 100644
--- a/envelope-service/envelope-application/pom.xml
+++ b/envelope-service/envelope-application/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.envelopeenvelope-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/envelope-service/envelope-application/src/main/java/gov/llnl/gnem/apps/coda/envelope/application/web/EnvelopeJsonController.java b/envelope-service/envelope-application/src/main/java/gov/llnl/gnem/apps/coda/envelope/application/web/EnvelopeJsonController.java
index a55359da..f8be0077 100644
--- a/envelope-service/envelope-application/src/main/java/gov/llnl/gnem/apps/coda/envelope/application/web/EnvelopeJsonController.java
+++ b/envelope-service/envelope-application/src/main/java/gov/llnl/gnem/apps/coda/envelope/application/web/EnvelopeJsonController.java
@@ -2,11 +2,11 @@
* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
-* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
-*
+* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
+*
* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the license.
*
* This work was performed under the auspices of the U.S. Department of Energy
@@ -52,7 +52,24 @@ public ResponseEntity> createBatch(@PathVariable Long sessionId, @Valid @Reque
return ResponseEntity.badRequest().body(bindResult);
}
- Result> result = service.createEnvelopes(sessionId, job.getData(), job.getJobConfig());
+ Result> result = service.createEnvelopes(sessionId, job.getData(), job.getJobConfig(), false);
+
+ BodyBuilder response;
+ if (result.isSuccess()) {
+ response = ResponseEntity.ok();
+ } else {
+ response = ResponseEntity.badRequest();
+ }
+ return response.body(result);
+ }
+
+ @PostMapping(value = "/batch-stacks-only/{sessionId}", name = "createBatchStacks")
+ public ResponseEntity> createBatchStacks(@PathVariable Long sessionId, @Valid @RequestBody EnvelopeJob job, BindingResult bindResult) {
+ if (bindResult.hasErrors()) {
+ return ResponseEntity.badRequest().body(bindResult);
+ }
+
+ Result> result = service.createEnvelopes(sessionId, job.getData(), job.getJobConfig(), true);
BodyBuilder response;
if (result.isSuccess()) {
diff --git a/envelope-service/envelope-model/pom.xml b/envelope-service/envelope-model/pom.xml
index 5f01b047..fa70beab 100644
--- a/envelope-service/envelope-model/pom.xml
+++ b/envelope-service/envelope-model/pom.xml
@@ -4,7 +4,7 @@
gov.llnl.gnem.apps.coda.envelopeenvelope-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/envelope-service/envelope-repository/pom.xml b/envelope-service/envelope-repository/pom.xml
index f6d232bf..3b906548 100644
--- a/envelope-service/envelope-repository/pom.xml
+++ b/envelope-service/envelope-repository/pom.xml
@@ -4,7 +4,7 @@
gov.llnl.gnem.apps.coda.envelopeenvelope-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/envelope-service/envelope-service-api/pom.xml b/envelope-service/envelope-service-api/pom.xml
index 6fc6b03a..12810d14 100644
--- a/envelope-service/envelope-service-api/pom.xml
+++ b/envelope-service/envelope-service-api/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.envelopeenvelope-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/envelope-service/envelope-service-api/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/api/EnvelopeCreationService.java b/envelope-service/envelope-service-api/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/api/EnvelopeCreationService.java
index 947f281c..3000f18c 100644
--- a/envelope-service/envelope-service-api/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/api/EnvelopeCreationService.java
+++ b/envelope-service/envelope-service-api/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/api/EnvelopeCreationService.java
@@ -2,11 +2,11 @@
* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
-* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
-*
+* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
+*
* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the license.
*
* This work was performed under the auspices of the U.S. Department of Energy
@@ -23,6 +23,6 @@
public interface EnvelopeCreationService {
- public Result> createEnvelopes(Long sessionId, Collection waveforms, EnvelopeJobConfiguration envConf);
+ public Result> createEnvelopes(Long sessionId, Collection waveforms, EnvelopeJobConfiguration envConf, boolean shouldReturnStacks);
}
diff --git a/envelope-service/envelope-service-api/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/api/WaveformStacker.java b/envelope-service/envelope-service-api/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/api/WaveformStacker.java
new file mode 100644
index 00000000..5a353362
--- /dev/null
+++ b/envelope-service/envelope-service-api/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/api/WaveformStacker.java
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2019, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* CODE-743439.
+* All rights reserved.
+* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
+*
+* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and limitations under the license.
+*
+* This work was performed under the auspices of the U.S. Department of Energy
+* by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.
+*/
+package gov.llnl.gnem.apps.coda.envelope.service.api;
+
+import java.util.List;
+
+import gov.llnl.gnem.apps.coda.common.model.domain.Waveform;
+
+public interface WaveformStacker {
+ public Waveform stackEnvelopes(List waves);
+}
diff --git a/envelope-service/envelope-service-impl/pom.xml b/envelope-service/envelope-service-impl/pom.xml
index 86243aef..abd813e2 100644
--- a/envelope-service/envelope-service-impl/pom.xml
+++ b/envelope-service/envelope-service-impl/pom.xml
@@ -6,7 +6,7 @@
gov.llnl.gnem.apps.coda.envelopeenvelope-service
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/envelope-service/envelope-service-impl/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/impl/EnvelopeCreationServiceImpl.java b/envelope-service/envelope-service-impl/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/impl/EnvelopeCreationServiceImpl.java
index a98b1032..223e52c8 100644
--- a/envelope-service/envelope-service-impl/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/impl/EnvelopeCreationServiceImpl.java
+++ b/envelope-service/envelope-service-impl/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/impl/EnvelopeCreationServiceImpl.java
@@ -16,8 +16,10 @@
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -31,9 +33,11 @@
import gov.llnl.gnem.apps.coda.common.model.util.LightweightIllegalStateException;
import gov.llnl.gnem.apps.coda.common.service.util.WaveformToTimeSeriesConverter;
import gov.llnl.gnem.apps.coda.common.service.util.WaveformUtils;
+import gov.llnl.gnem.apps.coda.envelope.model.domain.EnvelopeBandParameters;
import gov.llnl.gnem.apps.coda.envelope.model.domain.EnvelopeJobConfiguration;
import gov.llnl.gnem.apps.coda.envelope.service.api.EnvelopeCreationService;
import gov.llnl.gnem.apps.coda.envelope.service.api.EnvelopeParamsService;
+import gov.llnl.gnem.apps.coda.envelope.service.api.WaveformStacker;
import llnl.gnem.core.util.Passband;
import llnl.gnem.core.waveform.seismogram.TimeSeries;
@@ -46,14 +50,17 @@ public class EnvelopeCreationServiceImpl implements EnvelopeCreationService {
private EnvelopeParamsService params;
+ private WaveformStacker stacker;
+
@Autowired
- public EnvelopeCreationServiceImpl(WaveformToTimeSeriesConverter converter, EnvelopeParamsService params) {
+ public EnvelopeCreationServiceImpl(WaveformToTimeSeriesConverter converter, EnvelopeParamsService params, WaveformStacker stacker) {
this.converter = converter;
this.params = params;
+ this.stacker = stacker;
}
@Override
- public Result> createEnvelopes(Long sessionId, Collection waveforms, EnvelopeJobConfiguration envConf) {
+ public Result> createEnvelopes(Long sessionId, Collection waveforms, EnvelopeJobConfiguration envConf, boolean shouldReturnStacks) {
if (waveforms == null || waveforms.isEmpty()) {
// TODO: Propagate warning to the status API
return new Result<>(false, Collections.singletonList(new LightweightIllegalStateException("No waveforms provided; unable to compute envelopes.")), Collections.emptyList());
@@ -70,62 +77,85 @@ public Result> createEnvelopes(Long sessionId, Collection results = generateEnvelopesForBands(waveforms.stream().filter(Objects::nonNull).collect(Collectors.toList()), envConf);
- // CompletableFuture.runAsync(() -> waveformSvc.saveAll(results));
+ Set distinctWaveforms = new HashSet<>(waveforms);
+ List results = generateEnvelopesForBands(distinctWaveforms.stream().filter(Objects::nonNull).collect(Collectors.toList()), envConf);
+ if (shouldReturnStacks) {
+ results = results.stream()
+ .filter(w -> w.getEvent() != null && w.getLowFrequency() != null && w.getStream() != null && w.getStream().getStation() != null)
+ .collect(Collectors.groupingBy(w -> w.getEvent().getEventId() + w.getLowFrequency() + w.getStream().getStation().hashCode()))
+ .values()
+ .stream()
+ .map(waves -> {
+ return stacker.stackEnvelopes(waves);
+ })
+ .collect(Collectors.toList());
+ }
return new Result<>(true, results);
}
private List generateEnvelopesForBands(List rawWaveforms, EnvelopeJobConfiguration envConf) {
return rawWaveforms.parallelStream().map(wave -> {
-
return envConf.getFrequencyBandConfiguration().parallelStream().map(bandConfig -> {
- try {
- Waveform seisWave = new Waveform().mergeNonNullOrEmptyFields(wave);
-
- Double sampRate = seisWave.getSampleRate();
- if (sampRate != null && bandConfig.getHighFrequency() > (sampRate / 2.0)) {
- log.info("Asked to generate a frequency band {}-{} above nyquist for waveform {}.", bandConfig.getLowFrequency(), bandConfig.getHighFrequency(), seisWave);
- return null;
- }
-
- TimeSeries seis = converter.convert(wave);
- //Note these mutate the series
- seis.RemoveMean();
- seis.removeTrend();
- seis.Taper(1);
-
- seis.filter(4, Passband.BAND_PASS, bandConfig.getLowFrequency(), bandConfig.getHighFrequency(), true);
-
- seis.Envelope();
- seis.Log10();
-
- int smoothing = bandConfig.getSmoothing();
- seis.interpolate(bandConfig.getInterpolation());
-
- //Convert it to samples
- smoothing = (int) (smoothing * seis.getSamprate());
- seis.Smooth(smoothing);
-
- // final cut to eliminate smoothing edge effects
- double trimlength = 2 * smoothing / seis.getSamprate();
- seis.cut(seis.getTime().add(trimlength), seis.getEndtime().add(-1 * trimlength));
-
- seisWave.setSampleRate(seis.getSamprate());
- seisWave.setSegment(WaveformUtils.floatsToDoubles(seis.getData()));
- seisWave.setLowFrequency(bandConfig.getLowFrequency());
- seisWave.setHighFrequency(bandConfig.getHighFrequency());
- seisWave.setBeginTime(seis.getTime().getDate());
- seisWave.setEndTime(seis.getEndtime().getDate());
- if (seisWave.getStream() != null) {
- seisWave.getStream().setChannelName("STACK");
- }
-
- return seisWave;
- } catch (Exception e) {
- log.info(e.getMessage(), e);
- return null;
- }
+ return createEnvelopeForBand(wave, bandConfig);
}).filter(Objects::nonNull);
}).flatMap(Function.identity()).collect(Collectors.toList());
}
+
+ private Waveform createEnvelopeForBand(Waveform wave, EnvelopeBandParameters bandConfig) {
+ try {
+ Waveform seisWave = new Waveform().mergeNonNullOrEmptyFields(wave);
+
+ Double sampRate = seisWave.getSampleRate();
+ if (sampRate != null && bandConfig.getHighFrequency() > (sampRate / 2.0)) {
+ log.info("Asked to generate a frequency band {}-{} outside nyquist for waveform {}.", bandConfig.getLowFrequency(), bandConfig.getHighFrequency(), seisWave);
+ return null;
+ }
+
+ TimeSeries seis = converter.convert(wave);
+
+ //Note these mutate the series
+ double maxNeededRate = sampRate;
+ if (maxNeededRate > bandConfig.getHighFrequency() * 2.0) {
+ maxNeededRate = (int) (bandConfig.getHighFrequency() * 2.0 + 0.5);
+ }
+ if (maxNeededRate < 1.0) {
+ maxNeededRate = 1.0;
+ }
+ if (maxNeededRate < bandConfig.getInterpolation()) {
+ maxNeededRate = bandConfig.getInterpolation();
+ }
+ seis.interpolate(maxNeededRate);
+
+ seis.RemoveMean();
+ seis.removeTrend();
+ seis.Taper(1);
+
+ seis.filter(4, Passband.BAND_PASS, bandConfig.getLowFrequency(), bandConfig.getHighFrequency(), true);
+
+ seis.Envelope();
+ seis.Log10();
+
+ int smoothing = bandConfig.getSmoothing();
+
+ //Convert it to samples
+ smoothing = (int) (smoothing * seis.getSamprate());
+ seis.Smooth(smoothing);
+
+ // final cut to eliminate smoothing edge effects
+ double trimlength = 2 * smoothing / seis.getSamprate();
+ seis.cut(seis.getTime().add(trimlength), seis.getEndtime().add(-1 * trimlength));
+
+ seisWave.setSampleRate(seis.getSamprate());
+ seisWave.setSegment(WaveformUtils.floatsToDoubles(seis.getData()));
+ seisWave.setLowFrequency(bandConfig.getLowFrequency());
+ seisWave.setHighFrequency(bandConfig.getHighFrequency());
+ seisWave.setBeginTime(seis.getTime().getDate());
+ seisWave.setEndTime(seis.getEndtime().getDate());
+
+ return seisWave;
+ } catch (Exception e) {
+ log.info(e.getMessage(), e);
+ return null;
+ }
+ }
}
diff --git a/envelope-service/envelope-service-impl/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/impl/EnvelopeStacker.java b/envelope-service/envelope-service-impl/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/impl/EnvelopeStacker.java
new file mode 100644
index 00000000..438c977c
--- /dev/null
+++ b/envelope-service/envelope-service-impl/src/main/java/gov/llnl/gnem/apps/coda/envelope/service/impl/EnvelopeStacker.java
@@ -0,0 +1,90 @@
+/*
+* Copyright (c) 2019, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* CODE-743439.
+* All rights reserved.
+* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
+*
+* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and limitations under the license.
+*
+* This work was performed under the auspices of the U.S. Department of Energy
+* by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.
+*/
+package gov.llnl.gnem.apps.coda.envelope.service.impl;
+
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import gov.llnl.gnem.apps.coda.common.model.domain.Waveform;
+import gov.llnl.gnem.apps.coda.common.service.util.WaveformToTimeSeriesConverter;
+import gov.llnl.gnem.apps.coda.common.service.util.WaveformUtils;
+import gov.llnl.gnem.apps.coda.envelope.service.api.WaveformStacker;
+import llnl.gnem.core.waveform.seismogram.TimeSeries;
+
+@Component
+public class EnvelopeStacker implements WaveformStacker {
+
+ private final Logger log = LoggerFactory.getLogger(this.getClass());
+
+ private WaveformToTimeSeriesConverter converter;
+
+ @Autowired
+ public EnvelopeStacker(WaveformToTimeSeriesConverter converter) {
+ this.converter = converter;
+ }
+
+ @Override
+ public Waveform stackEnvelopes(List waves) {
+ // TODO: Implement array processing
+ // TODO: Profile to improve perf
+ // TODO: Progress notification for stacking
+
+ //TODO: Thoughts on array stacks
+ // 1. Compare all the elements in the array to look for outliers in measurements (bad channels).
+ // Needs some kind of hypothesis testing probably to try and figure out 'bad' in this context (majority rules?).
+ // 2. For each element envelope, find record begin and end of each
+ // trace ( b and e may have changed because of time shifting)
+ // 3. Keep the largest begin and smallest end times of all elements
+ // 4. Form an average envelope by summing each trace and then
+ // dividing by the total number of envelopes used
+ // 5. Change station header location lat and lon to the reference
+ // (array element closest to centroid of hull maybe?) and re-compute hypocentral distance
+ // 6. Store the envelope for coda amplitude measurement
+
+ Waveform base = null;
+ if (waves != null && waves.size() > 1) {
+ try {
+ base = waves.get(0);
+ TimeSeries seis = converter.convert(base);
+ for (int i = 1; i < waves.size(); i++) {
+ TimeSeries seis2 = converter.convert(waves.get(i));
+ seis = seis.add(seis2);
+ }
+ seis.MultiplyScalar(1d / (waves.size()));
+ base.setSegment(WaveformUtils.floatsToDoubles(seis.getData()));
+
+ if (base.getSegment() == null || base.getSegment().length == 0) {
+ return null;
+ }
+
+ base.setSampleRate(seis.getSamprate());
+ base.setBeginTime(seis.getTime().getDate());
+ base.setEndTime(seis.getEndtime().getDate());
+ if (base.getStream() != null) {
+ base.getStream().setChannelName("STACK");
+ }
+ } catch (Exception e) {
+ log.info(e.getMessage(), e);
+ }
+ } else {
+ log.info("Waveform with only one channel found for list {}, skipping stacking", waves);
+ }
+ return base;
+ }
+}
diff --git a/envelope-service/envelope-service-impl/src/test/java/gov/llnl/gnem/apps/coda/envelope/service/impl/EnvelopeCreationServiceImplTest.java b/envelope-service/envelope-service-impl/src/test/java/gov/llnl/gnem/apps/coda/envelope/service/impl/EnvelopeCreationServiceImplTest.java
new file mode 100644
index 00000000..710ff4b1
--- /dev/null
+++ b/envelope-service/envelope-service-impl/src/test/java/gov/llnl/gnem/apps/coda/envelope/service/impl/EnvelopeCreationServiceImplTest.java
@@ -0,0 +1,173 @@
+/*
+* Copyright (c) 2019, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* CODE-743439.
+* All rights reserved.
+* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
+*
+* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and limitations under the license.
+*
+* This work was performed under the auspices of the U.S. Department of Energy
+* by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.
+*/
+package gov.llnl.gnem.apps.coda.envelope.service.impl;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import gov.llnl.gnem.apps.coda.common.model.domain.Event;
+import gov.llnl.gnem.apps.coda.common.model.domain.Station;
+import gov.llnl.gnem.apps.coda.common.model.domain.Stream;
+import gov.llnl.gnem.apps.coda.common.model.domain.Waveform;
+import gov.llnl.gnem.apps.coda.common.model.messaging.Result;
+import gov.llnl.gnem.apps.coda.common.service.util.WaveformToTimeSeriesConverter;
+import gov.llnl.gnem.apps.coda.envelope.model.domain.Default14BandEnvelopeJobConfiguration;
+import gov.llnl.gnem.apps.coda.envelope.service.api.EnvelopeParamsService;
+
+@ExtendWith(MockitoExtension.class)
+public class EnvelopeCreationServiceImplTest {
+
+ private final Logger log = LoggerFactory.getLogger(this.getClass());
+
+ @Mock
+ private EnvelopeParamsService params;
+
+ private EnvelopeCreationServiceImpl envelopeCreationService;
+
+ @BeforeAll
+ protected static void setUpBeforeClass() throws Exception {
+ }
+
+ @AfterAll
+ protected static void tearDownAfterClass() throws Exception {
+ }
+
+ @BeforeEach
+ protected void setUp() throws Exception {
+ WaveformToTimeSeriesConverter converter = new WaveformToTimeSeriesConverter();
+ envelopeCreationService = new EnvelopeCreationServiceImpl(converter, params, new EnvelopeStacker(converter));
+ }
+
+ @AfterEach
+ protected void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testCreateEnvelopesDefault14Bands() throws Exception {
+ Mockito.when(params.getConfiguration()).thenReturn(Default14BandEnvelopeJobConfiguration.getConfiguration());
+ List waveforms = new ArrayList<>();
+
+ waveforms = generateWaveforms();
+
+ Result> stacks = envelopeCreationService.createEnvelopes(1l, waveforms, null, false);
+ assertTrue(stacks.isSuccess());
+ assertTrue(stacks.getResultPayload().isPresent());
+ long eventCount = waveforms.stream().map(w -> w.getEvent().getEventId()).distinct().count();
+ long bandCount = params.getConfiguration().getFrequencyBandConfiguration().size();
+ long channelCount = waveforms.stream().map(w -> w.getStream().getChannelName()).distinct().count();
+ assertEquals(bandCount * eventCount * channelCount, stacks.getResultPayload().get().stream().distinct().count());
+ }
+
+ @Test
+ public void testCreateStacksDefault14Bands() throws Exception {
+ Mockito.when(params.getConfiguration()).thenReturn(Default14BandEnvelopeJobConfiguration.getConfiguration());
+ List waveforms = new ArrayList<>();
+
+ waveforms = generateWaveforms();
+
+ Result> stacks = envelopeCreationService.createEnvelopes(1l, waveforms, null, true);
+ assertTrue(stacks.isSuccess());
+ assertTrue(stacks.getResultPayload().isPresent());
+
+ long eventCount = waveforms.stream().map(w -> w.getEvent().getEventId()).distinct().count();
+ long bandCount = params.getConfiguration().getFrequencyBandConfiguration().size();
+ assertEquals(bandCount * eventCount, stacks.getResultPayload().get().stream().distinct().count());
+ }
+
+ private List generateWaveforms() {
+ Date startTime = Date.from(Instant.now());
+ Date endTime = Date.from(startTime.toInstant().plusSeconds(1l));
+
+ Event event = new Event();
+ event.setEventId("1234");
+ event.setLatitude(1.0);
+ event.setLongitude(1.0);
+
+ Event event2 = new Event();
+ event2.setEventId("2345");
+ event2.setLatitude(1.0);
+ event2.setLongitude(1.0);
+
+ Station station = new Station();
+ station.setLatitude(1.0);
+ station.setLongitude(1.0);
+ station.setStationName("TEST");
+ station.setNetworkName(null);
+
+ Stream s1 = new Stream();
+ s1.setChannelName("BHE");
+ s1.setStation(station);
+
+ Stream s2 = new Stream();
+ s2.setChannelName("BHN");
+ s2.setStation(station);
+
+ double[] data = new double[400];
+ Arrays.fill(data, 0, 200, 1000.0);
+ Arrays.fill(data, 2, 400, 2000.0);
+ Waveform w1 = new Waveform();
+ w1.setEvent(event);
+ w1.setStream(s1);
+ w1.setSegment(data);
+ w1.setBeginTime(startTime);
+ w1.setEndTime(endTime);
+ w1.setSampleRate(16d);
+
+ Arrays.fill(data, 0, 200, 1000.0);
+ Arrays.fill(data, 2, 400, 2000.0);
+ Waveform w2 = new Waveform();
+ w2.setEvent(event);
+ w2.setStream(s2);
+ w2.setSegment(data);
+ w2.setBeginTime(startTime);
+ w2.setEndTime(endTime);
+ w2.setSampleRate(16d);
+
+ Waveform w3 = Waveform.mergeNonNullOrEmptyFields(w1, new Waveform());
+ w3.setEvent(event2);
+ Waveform w4 = Waveform.mergeNonNullOrEmptyFields(w2, new Waveform());
+ w4.setEvent(event2);
+
+ List waveforms = new ArrayList<>(2);
+ waveforms.add(w1);
+ waveforms.add(w2);
+
+ //Toss some duplicates in just to see
+ waveforms.add(w1);
+ waveforms.add(w2);
+
+ waveforms.add(w3);
+ waveforms.add(w4);
+ return waveforms;
+ }
+}
diff --git a/envelope-service/pom.xml b/envelope-service/pom.xml
index b104396e..9a15b512 100644
--- a/envelope-service/pom.xml
+++ b/envelope-service/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.calibrationcoda-calibration
- 1.0.4-SNAPSHOT
+ 1.0.5gov.llnl.gnem.apps.coda.envelope
diff --git a/envelope-standalone/pom.xml b/envelope-standalone/pom.xml
index cb5a6bcb..00ccc054 100644
--- a/envelope-standalone/pom.xml
+++ b/envelope-standalone/pom.xml
@@ -6,7 +6,7 @@
gov.llnl.gnem.apps.coda.calibrationcoda-calibration
- 1.0.4-SNAPSHOT
+ 1.0.54.0.0
diff --git a/envelope-standalone/src/main/java/gov/llnl/gnem/apps/coda/envelope/standalone/data/client/EnvelopeLocalClient.java b/envelope-standalone/src/main/java/gov/llnl/gnem/apps/coda/envelope/standalone/data/client/EnvelopeLocalClient.java
index a42fb584..47c76b5f 100644
--- a/envelope-standalone/src/main/java/gov/llnl/gnem/apps/coda/envelope/standalone/data/client/EnvelopeLocalClient.java
+++ b/envelope-standalone/src/main/java/gov/llnl/gnem/apps/coda/envelope/standalone/data/client/EnvelopeLocalClient.java
@@ -2,11 +2,11 @@
* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
-* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
-*
+* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
+*
* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the license.
*
* This work was performed under the auspices of the U.S. Department of Energy
@@ -69,7 +69,7 @@ public Flux postEnvelopes(Long sessionId, List segments) {
@Override
public Flux postEnvelopes(Long sessionId, List segments, EnvelopeJobConfiguration conf) {
- return Flux.fromIterable(service.createEnvelopes(sessionId, segments, conf).getResultPayload().orElseGet(() -> new ArrayList()));
+ return Flux.fromIterable(service.createEnvelopes(sessionId, segments, conf, false).getResultPayload().orElseGet(() -> new ArrayList<>()));
}
}
diff --git a/example-notebooks/measure-mws/Mw-From-FDSN-waveforms.ipynb b/example-notebooks/measure-mws/Mw-From-FDSN-waveforms.ipynb
index 3ab6eb2e..0e2477c9 100644
--- a/example-notebooks/measure-mws/Mw-From-FDSN-waveforms.ipynb
+++ b/example-notebooks/measure-mws/Mw-From-FDSN-waveforms.ipynb
@@ -12,7 +12,7 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
@@ -21,7 +21,6 @@
"import json\n",
"\n",
"from obspy import read\n",
- "from obspy.signal.trigger import recursive_sta_lta_py\n",
"import matplotlib.pyplot as plt"
]
},
@@ -34,7 +33,7 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
@@ -95,7 +94,7 @@
},
{
"cell_type": "code",
- "execution_count": 4,
+ "execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
@@ -114,7 +113,7 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 4,
"metadata": {
"scrolled": true
},
@@ -138,7 +137,7 @@
},
{
"cell_type": "code",
- "execution_count": 6,
+ "execution_count": 5,
"metadata": {
"scrolled": true
},
@@ -193,7 +192,7 @@
},
{
"cell_type": "code",
- "execution_count": 7,
+ "execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
@@ -211,7 +210,7 @@
},
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
@@ -227,7 +226,7 @@
},
{
"cell_type": "code",
- "execution_count": 9,
+ "execution_count": 8,
"metadata": {},
"outputs": [
{
@@ -256,7 +255,7 @@
},
{
"cell_type": "code",
- "execution_count": 10,
+ "execution_count": 9,
"metadata": {},
"outputs": [
{
@@ -283,7 +282,7 @@
},
{
"cell_type": "code",
- "execution_count": 11,
+ "execution_count": 10,
"metadata": {
"scrolled": false
},
@@ -297,41 +296,11 @@
}
],
"source": [
- "r = requests.post('https://127.0.0.1:53922/api/v1/envelopes/create/batch/10000', json=waveData, verify=False)\n",
+ "r = requests.post('https://127.0.0.1:53922/api/v1/envelopes/create/batch-stacks-only/10000', json=waveData, verify=False)\n",
"print(r.status_code)\n",
"envData = json.loads(r.text)[\"resultPayload\"]"
]
},
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We can look at the envelopes to see if anything looks odd."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": [
- "