?? ml.java
字號:
package org.trinet.util.magnitudeengines;
import java.util.*;
import org.trinet.util.*;
import org.trinet.filters.*;
import org.trinet.jasi.*;
/**
* Methods for ML (local magnitude) calculation.<p>
*
* Formula is defined by Richter in Elementry Seismology, pg. 340: <p>
*
* ML = log A + Cd + Cs<p>
* Where:<br>
* A = half amp, in mm from a 2,800x Wood-Anderson torsion seismometer<br>
* Cd = Richter distance correction<br>
* Cs = emperical station correction<p>
*
* The method can use either corrected or uncorrected Wood-Anderson amplitudes
* (types WAC and WAU)
* @see AmpType()
*
* @author Doug Given
* @version
*/
public class ML extends TrinetMagnitudeMethod {
/** The amplitude being used. */
Amplitude amp;
static boolean debug = true;
public ML() {
// Magnitude type subscript. For example: for "Ml" this would equal "l".
subScript = "l";
// String describing the magnitude method
name = "Local Ml";
// set the waveform filter to Synthetic Wood-Anderson
setWaveformFilter(new WAFilter());
// cutoff dist
setMinDistance(20.0);
setMaxDistance(600.0);
}
/**
* Return the Local Magnitude (ML) as defined by Richter in Elementry
* Seismology, pg. 340. Epicentral distance is given in km, amplitude is
* half peak-to-peak amplitude of a Wood-Anderson torsion seismomemter with
* 2,800 magnification measured in mm. */
public double getValue (Amplitude amp) throws WrongAmpTypeException {
double magCorr = 0.0;
// reject clipped amps
if (amp.isClipped()) {
throwWrongAmpTypeException("ML: Amplitude is clipped: "+ amp.isClipped() );
}
// check that amp is of correct type
if (amp.type == AmpType.WAU) { //Wood-Anderson Uncorrected
// set magnitude correction if there is one and amp not already corrected
if (amp.hasCorrection() && !amp.isCorrected())
magCorr = amp.getChannelObj().mlCorr.doubleValue();
} else if (amp.type == AmpType.WAC) { //Wood-Anderson Corrected
// no correction
} else {
throwWrongAmpTypeException("ML: Wrong amplitude type: "+
AmpType.getString(amp.type));
}
// make sure units are mm
double ampval = 0.0;
if (amp.units == Units.MM) {
ampval = amp.value.doubleValue();
} else if (amp.units == Units.CM) {
ampval = amp.value.doubleValue() * 10.0; // cm -> mm
} else if (amp.units == Units.M) {
ampval = amp.value.doubleValue() * 100.0; // m -> mm
} else {
throwWrongAmpTypeException("ML: Wrong amplitude units: "+
Units.getString(amp.units));
}
// make sure is half-amp
if (!amp.halfAmp) ampval /= 2.0;
return getValue(amp.getDistance(), ampval, magCorr);
}
/**
* Return the Local Magnitude (ML) as defined by Richter in Elementry
* Seismology, pg. 340. Epicentral distance is given in km, amplitude is
* half peak-to-peak amplitude of a Wood-Anderson torsion seismometer with
* 2,800 magnification measured in positive mm's.
* The station correction given as the third
* argument will be added to the magnitude. */
public double getValue (double distance,
double mmHalfAmp,
double staticCorrection) {
/*
if (debug) System.out.println ("mmHalfAmp, ML.log10(mmHalfAmp), distanceCorrection(distance), staticCorrection:\n "+
mmHalfAmp+ " "+
ML.log10(mmHalfAmp) +" " +
distanceCorrection(distance) +" " +
staticCorrection);
*/
// make sure its +positive
mmHalfAmp = Math.abs(mmHalfAmp);
return MathTN.log10 (mmHalfAmp) + // calculated mag
distanceCorrection(distance) + // distance correction
staticCorrection + // channel correction
getGlobalCorrection() ; // global correction
}
/**
* Return the Local Magnitude (ML) as defined by Richter in Elementry
* Seismology, pg. 340. Epicentral distance is given in km, amplitude is
* half peak-to-peak amplitude of a Wood-Anderson torsion seismomemter with
* 2,800 magnification measured in mm. */
public double getValue (double distance,
double mmHalfAmp) {
return getValue (distance, mmHalfAmp, 0.0);
}
/**
* Return the Richter distance correction. (from Richter, Table 22-1, pg. 342)
* Correction should be added to magnitude calculated by ML.value().
*/
public double distanceCorrection (double distance) {
double dist[] = { 10, 15, 20, 22.5, 25, 27.5, 30, 32.5, 35,
40, 45, 50, 55, 60, 80, 90, 110, 130,
150, 170, 190, 210, 220, 230, 250, 270, 290,
310, 330, 350, 380, 400, 430, 470, 510, 560,
601};
double corr[] = {1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2,
2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.1,
3.2, 3.3, 3.4, 3.5, 3.6, 3.65,3.7, 3.8, 3.9,
4.0, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8,
4.9};
for (int i = 0; i < dist.length; i++) {
if (distance < dist[i]) {
// if (debug) System.out.println ("ML dist. Corr= "+corr[i]);
return corr[i];
}
}
// out of allowed range
return 0.0;
}
/**
* Return the distance cutoff appropriate for the method. Amplitudes from
* stations father then this will not be included in the summary magnitude.
* Because it depends on the magnitude the cutoff can only be applied in a
* second pass through the amplitude readings. In the
* local (Richter) magnitude scheme the distance cutoff is simply 600 km.
*/
public double getDistanceCutoff (double magnitude) {
double dist = Math.max( getMinDistance(), 600.0 );
return Math.min(dist, getMaxDistance() );
}
/** Examine the Amp list BEFORE the waveforms are scanned and throw out any
* channels you don't what scanned. This will save time in scanning. These include
* channels that will not contribute to future calibrations.
* Returns 'true' if the list is changed by the scan. */
public boolean preScanAmpList (Magnitude mag) {
boolean changed = false;
// first trim by absolute cutoff distance
changed = trimByDistance(mag, getMaxDistance());
// Amplitude amp[] = mag.ampList.getArray();
Amplitude amp[] = mag.ampList.getGood(); // don't get zero wt'ed amps
for (int i=0; i<amp.length; i++) {
// NOTE: 2 type of rejection:
// 1) amps we want to save for future calibration (weight = 0)
// 2) amps we do NOT want to save for future calibration (delete)
// HERE we reject type #2 amps to save time and work in the wf scanning
if (amp[i].isDeleted()) {
if (debug) System.out.println ("DELETE: isDeleted " +
amp[i].getChannelObj().toDelimitedSeedString());
amp[i].delete();
changed = true;
} else if (!isIncludedComponent(amp[i])) {
if (debug) System.out.println ("DELETE: not included component " +
amp[i].getChannelObj().toDelimitedSeedString());
amp[i].delete();
changed = true;
}
/* } else if (!amp[i].isOnScale() ) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -