Skip to content

Commit ca5dfb7

Browse files
committed
GNS/Geonet Local Magnitude plugin (Beta)
1 parent 1165807 commit ca5dfb7

File tree

9 files changed

+359
-0
lines changed

9 files changed

+359
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@
139139
!/src/ipgp/
140140
!/src/nettab/
141141
!/src/sed/
142+
!/src/gns/
142143
!/src/seedlink/
143144
!/src/system/
144145
!/src/trunk/

src/gns/CMakeLists.txt

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
SC_BEGIN_PACKAGE(GNS)
2+
3+
SET(Boost_DETAILED_FAILURE_MSG ON)
4+
FIND_PACKAGE(Boost REQUIRED COMPONENTS program_options thread filesystem iostreams regex)
5+
IF (WIN32)
6+
ADD_DEFINITIONS("-DBOOST_ALL_NO_LIB")
7+
ADD_DEFINITIONS("-DBOOST_LIB_DIAGNOSTIC")
8+
ENDIF (WIN32)
9+
10+
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
11+
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
12+
13+
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/libs)
14+
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/libs)
15+
16+
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../system/libs)
17+
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/../system/libs)
18+
19+
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../trunk/libs)
20+
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/../trunk/libs)
21+
22+
SUBDIRS(plugins)

src/gns/plugins/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SUBDIRS(magnitudes)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SUBDIRS(MLR)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
SET(PLUGIN_TARGET mlr)
2+
3+
SET(
4+
PLUGIN_SOURCES
5+
mlr.cpp
6+
)
7+
8+
SC_ADD_PLUGIN_LIBRARY(PLUGIN ${PLUGIN_TARGET} "")
9+
SC_LINK_LIBRARIES_INTERNAL(${PLUGIN_TARGET} client)
10+
11+
FILE(GLOB descs "${CMAKE_CURRENT_SOURCE_DIR}/descriptions/*.xml")
12+
INSTALL(FILES ${descs} DESTINATION ${SC3_PACKAGE_APP_DESC_DIR})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Amplitude
2+
---------
3+
The MLr amplitude calculation is that of the Mlv amplitude computation
4+
5+
Station Magnitude
6+
-----------------
7+
8+
The MLr plugin calculates the individual station local magnitude using the following formula:
9+
10+
.. math::
11+
12+
//based on sed MLh magnitude: mag = \log10(waamp1) + A \times hypdistkm + B
13+
mag = log10(waampl)-log10(waamplRef)
14+
log10(waamplRef)= 0.2869 - 1.272*1e-3*(hypdistkm) -(1.493 * log10 (hypdistkm)) + (StationCorrection)
15+
// A(station) Station correction - given by module.trunk.NZ.WEL.MLR.params, A ;
16+
// Sation Correction is set to be distance dependent;
17+
// Option nomag disable the station magnitude.
18+
19+
20+
waampl is the amplitude produced by the MLr plugin. Hypdistkm is the distance
21+
from the sensor to the hypocenter in kilometers.
22+
23+
Overall Event Magnitude
24+
-----------------------
25+
26+
The GNS/Geonet Mlr local magnitude is using the default Sc3 behaviour for the automatic network magnitudes.
27+
Hard coded range are 0-20 degrees maximum distance, and 800 km max depth.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<seiscomp>
3+
<plugin name="MLr">
4+
<extends>global</extends>
5+
<description>
6+
The MLr plugin is designed to use the MLv station amplitudes
7+
and provides a GNS/Geonet local magnitude (Jristau this study: - REF-).
8+
The magnitude uses a station correction term and the hypocentral distance
9+
Hard coded range are 0-20 degrees maximum distance, and 800 km max depth.
10+
</description>
11+
</plugin>
12+
<binding name="MLr" module="global">
13+
<description>
14+
The MLr plugin is designed to use MLv station amplitudes
15+
and a GNS/Geonet local magnitude (Jristau study - REF-).
16+
It is a modified version of the gempa ML plugin developed
17+
at the Liverpool developer meeting (Gempa).
18+
It is a modified version of the SED MLh plugin (J.Becker Gempa + S. Heimers SED)
19+
</description>
20+
<configuration>
21+
<group name="MLr">
22+
<parameter name="params" type="string">
23+
<description>
24+
Defines Stations Corrections parameters for MLr.
25+
Format: &quot;UpToKilometers A ; UpToNextKilometers A ;&quot;.
26+
Example: &quot;30 nomag; 60 0.018 ; 700 0.0038 &quot;.
27+
The first parameter set &quot;30 nomag&quot; means that up to 30km
28+
from the sensor the magnitude should not be calculated.
29+
A is used as Station Correction
30+
"nomag" is used to disable station magnitudes
31+
</description>
32+
</parameter>
33+
</group>
34+
</configuration>
35+
</binding>
36+
</seiscomp>
+235
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
/***************************************************************************
2+
* Copyright (C) 2009 by gempa GmbH
3+
*
4+
* Author: Jan Becker
5+
6+
*
7+
* Modifications 2010 - 2011 by Stefan Heimers <[email protected]>
8+
* Modifications 2014 - 2015 by JeromeSalichon
9+
*
10+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
12+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
14+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
15+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
16+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
17+
* OTHER DEALINGS IN THE SOFTWARE.
18+
***************************************************************************/
19+
20+
#define SEISCOMP_COMPONENT MLR
21+
22+
#include "mlr.h"
23+
#include <seiscomp3/logging/log.h>
24+
#include <seiscomp3/core/strings.h>
25+
#include <seiscomp3/processing/magnitudeprocessor.h>
26+
#include <seiscomp3/math/geo.h>
27+
28+
#include <iostream>
29+
30+
#include <boost/bind.hpp>
31+
#include <unistd.h>
32+
33+
// Only valid within 0-20 degrees
34+
#define DELTA_MIN 0.
35+
#define DELTA_MAX 20
36+
37+
// Only valid for depths up to 800 km
38+
#define DEPTH_MAX 800
39+
40+
#define MAG_TYPE "MLr"
41+
42+
using namespace std;
43+
44+
45+
using namespace Seiscomp;
46+
using namespace Seiscomp::Processing;
47+
48+
49+
ADD_SC_PLUGIN(
50+
"MLr GNS magnitude, J. Ristau method",
51+
"Derived from MLh magnitude & Sc3 Tutorial methods, J.Salichon, GNS Science New Zealand, J.Becker, Gempa",
52+
0, 0, 1
53+
);
54+
55+
56+
class Magnitude_MLR : public Processing::MagnitudeProcessor {
57+
public:
58+
struct param_struct {
59+
double dist;
60+
double A;
61+
bool nomag;
62+
};
63+
64+
list<param_struct> list_of_parametersets;
65+
param_struct selected_parameterset;
66+
67+
Magnitude_MLR() : Processing::MagnitudeProcessor(MAG_TYPE) {}
68+
69+
//Same amplitude measurement as MLv (ML Sc3 amplitude on vertical)
70+
std::string amplitudeType() const {
71+
return "MLv" ;
72+
}
73+
74+
// Do not need to compute another amplitude.
75+
76+
bool setup(const Settings &settings) {
77+
// Reset the configuration
78+
list_of_parametersets.clear();
79+
try {
80+
// Read the settings variable MLr.params. This can be found in the applications
81+
// configuration file at:
82+
// module.trunk.global.MLr.params
83+
// or per station (highest priority)
84+
// module.trunk.NZ.WEL.MLr.params
85+
if ( !initParameters(list_of_parametersets, settings.getString("MLr.params")) )
86+
return false;
87+
}
88+
catch ( ... ) {}
89+
90+
return true;
91+
}
92+
93+
MagnitudeProcessor::Status computeMagnitude(
94+
double amplitude, // in milimeters
95+
double period, // in seconds
96+
double delta, // in degrees
97+
double depth, // in kilometers
98+
double &value)
99+
{
100+
if ( delta < DELTA_MIN || delta > DELTA_MAX )
101+
return DistanceOutOfRange;
102+
103+
if ( depth > DEPTH_MAX )
104+
return DepthOutOfRange;
105+
106+
return compute_ML(amplitude, delta, depth, &value);
107+
}
108+
109+
private:
110+
// create a C++ list of structs containing all configured
111+
// parameter sets.
112+
// run this once at program start
113+
bool initParameters(list<param_struct> &paramlist, const string &params) {
114+
string paramset, range_str, minrange_str;
115+
string A_str;
116+
117+
// for each parameter set
118+
istringstream iss_params(params);
119+
while ( getline(iss_params,paramset,';') ) {
120+
// extract the parameters from this parameter set
121+
istringstream iss_paramset(paramset);
122+
iss_paramset >> range_str;
123+
iss_paramset >> A_str;
124+
125+
param_struct new_paramset;
126+
if ( !Core::fromString(new_paramset.dist, range_str) ) {
127+
SEISCOMP_ERROR("MLr: %s: range is not a numeric value",
128+
params.c_str());
129+
return false;
130+
}
131+
132+
if ( A_str == "nomag" ) {
133+
new_paramset.A = 0;
134+
new_paramset.nomag = true;
135+
}
136+
else {
137+
if ( !Core::fromString(new_paramset.A, A_str) ) {
138+
SEISCOMP_ERROR("MLr: %s: not a numeric value",
139+
A_str.c_str());
140+
return false;
141+
}
142+
143+
new_paramset.nomag = false;
144+
}
145+
146+
paramlist.push_back(new_paramset);
147+
}
148+
149+
return true;
150+
}
151+
152+
153+
// select the right parameter set for a given distance. init_parameters() must
154+
// have been called before using this function.
155+
param_struct selectParameters(double distance, const list<param_struct> &paramlist) {
156+
double last_dist = 1000000; // arbitrary number larger than any expected distance;
157+
param_struct selected_parameters;
158+
159+
// defaults in case the distance is out of the definded ranges
160+
selected_parameters.nomag = true;
161+
selected_parameters.dist = 0;
162+
selected_parameters.A = 0;
163+
164+
list<param_struct>::const_iterator paramit;
165+
for ( paramit = paramlist.begin(); paramit != paramlist.end(); ++paramit ) {
166+
if ( (paramit->dist < last_dist) && (paramit->dist >= distance) ) {
167+
selected_parameters = *paramit;
168+
last_dist = paramit->dist;
169+
}
170+
}
171+
172+
return selected_parameters;
173+
}
174+
175+
MagnitudeProcessor::Status compute_ML(
176+
double amplitude, // in micrometers
177+
double delta, // in degrees
178+
double depth, // in kilometers
179+
double *mag) {
180+
float epdistkm,hypdistkm;
181+
float LogAmpREF; //MLr parameters
182+
float magTemp ; //MLr parameters
183+
184+
if ( amplitude <= 0. ) {
185+
*mag = 0;
186+
return Error;
187+
}
188+
189+
// examples:
190+
// epdistkm <= 60 km => mag=log10(waampl) + 0.018 *epdistkm+1.77 ;
191+
// 60 < epdistkm <= 700 => mag=log10(waampl) + 0.0038*epdistkm+2.62 ;
192+
// more generic: mag = log10(waampl) + A * epdistkm
193+
//
194+
// a list of distance ranges and corresponding values for A
195+
// is read from a config file.
196+
197+
// calculate the distance in kilometers from the distance in degrees
198+
epdistkm = Math::Geo::deg2km(delta);
199+
hypdistkm = sqrt(epdistkm*epdistkm + depth * depth);
200+
201+
// read the values for A and epdistkm from the config file and
202+
// select the right set depending on the distance
203+
selected_parameterset = selectParameters(hypdistkm, list_of_parametersets);
204+
205+
SEISCOMP_DEBUG("epdistkm: %f\n",epdistkm);
206+
SEISCOMP_DEBUG("hypdistkm: %f\n",hypdistkm);
207+
208+
if ( selected_parameterset.nomag ) {
209+
SEISCOMP_DEBUG( "epicenter distance out of configured range, no magnitude");
210+
return DistanceOutOfRange;
211+
}
212+
else {
213+
SEISCOMP_DEBUG("The selected range is: %f", selected_parameterset.dist);
214+
SEISCOMP_DEBUG("A: %f", selected_parameterset.A);
215+
//SEISCOMP_DEBUG("MLr: station %s.%s: %s",settings.networkCode.c_str(), settings.stationCode.c_str(),s.c_str());
216+
217+
// ORI(sed): *mag = log10(amplitude) + selected_parameterset.A * hypdistkm + selected_parameterset.B;
218+
// JRistau: *mag = log10(amplitude) - Log(Amp(hypdistkm)) + Selected_parameterset.A ;
219+
//
220+
// Computing terms of magnitude
221+
LogAmpREF = 0.2869 - (1.272 * 1e-3) * hypdistkm - (1.493 * log10(hypdistkm) ) ;
222+
223+
// magTemp = log10(amplitude) - LogAmpREF + StatCorr ;
224+
// A is defined as STATION dependent ie. module.trunk.NZ.WEL.MLr.params ;
225+
// Not corrected stations: Default is 0. Use nomag option to disable;
226+
magTemp = log10(amplitude) - LogAmpREF + selected_parameterset.A ;
227+
*mag = magTemp ;
228+
229+
SEISCOMP_DEBUG("Mlr: %f", *mag);
230+
return OK;
231+
}
232+
}
233+
};
234+
235+
REGISTER_MAGNITUDEPROCESSOR(Magnitude_MLR, MAG_TYPE);

src/gns/plugins/magnitudes/MLR/mlr.h

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/***************************************************************************
2+
* Copyright (C) 2009 by gempa GmbH
3+
*
4+
* Author: Jan Becker
5+
6+
*
7+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
8+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
9+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
10+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
11+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
12+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
13+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
14+
* OTHER DEALINGS IN THE SOFTWARE.
15+
***************************************************************************/
16+
17+
#ifndef __MLR_PLUGIN_H__
18+
#define __MLR_PLUGIN_H__
19+
20+
21+
#include <seiscomp3/core/plugin.h>
22+
23+
24+
#endif

0 commit comments

Comments
 (0)