📄 trinetmagnitudemethod.java
字号:
package org.trinet.util.magnitudeengines;
import java.util.*;
import org.trinet.filters.*;
import org.trinet.util.*;
import java.io.*;
import org.trinet.jasi.*;
/**
* Abstract class from which all other Magnitude calculation methods
* are derived.<p>
*
* Known subclasses:<br>
* @see: ML
* @See: SoCalML
*
* @author Doug Given
* @version
*/
public abstract class TrinetMagnitudeMethod extends MagnitudeMethod
{
// Amp rejection criteria ============================================
/** If value is non-zero trim amps with residuals greater then this value and
* recalc the median. */
double trimResidual = Double.MAX_VALUE;
/** Do not calculate magnitudes for stations farther than this. This value
* imposes a maximum limit on the distance calculated by getDistanceCutoff()*/
double maxDistance = Double.MAX_VALUE;
/** Always calculate magnitudes for stations closer than this. This value
* imposes a minimum limit on the distance calculated by getDistanceCutoff()*/
double minDistance = Double.MIN_VALUE;
/** Do not calculate magnitudes for more than this many channels (not stations).*/
int maxChannels = Integer.MAX_VALUE;
/** Set true to require a channel-magnitude correction for he channel to be used.
* The default is 'false'. */
boolean requireCorrection = false;
/** Set true to low gain channels in the mag. (SEED '_L_')
* The default is 'false'. */
boolean useLowGains = false;
/** Set true to broad band channels in the mag. (SEED 'B__')
* The default is 'false'. */
boolean useBroadBands = false;
/** Minimum signal-to-noise (SNR) ratio for an amplitude to be used.
* For example, if this value is set to 1.5 a peak amplitude must be 150% of
* background noise level to be used. */
double minSNR = Double.MIN_VALUE;
/** If 'true' only that part of a waveform that is likely to contain seismic
* energy will be scanned. If 'false' the whole available waveform is scanned.<p>
*
* If 'true' window scanned begins 1 sec before expected P-wave onset and
* ends at P-wave onset plus 2x the S-P time.
*
*/
boolean scanEnergyWindow = true;
boolean debug = true;
//boolean debug = false;
public TrinetMagnitudeMethod() {
}
/** Set the Waveform filter. */
public TrinetMagnitudeMethod(GenericFilter filter) {
setWaveformFilter(filter);
}
/**
* Return the Magnitude given the epicentral distance (km) and the amplitude
* for this mag method.
*/
public abstract double getValue (Amplitude amp) throws WrongAmpTypeException ;
/**
* Return the Magnitude given the epicentral distance (km) and the amplitude value
* as required by the mag method.
*/
public abstract double getValue (double distance, double value) ;
/**
* Return the Magnitude given the epicentral distance (km), the amplitude value and
* a static correction value as required by the mag method.
*/
public abstract double getValue (double distance,
double value,
double staticCorrection) ;
/** Set a global correction that is added to all magnitudes calculated
* by this method. Default is 0.0 */
public void setGlobalCorrection (double correction) {
globalCorrection = correction;
}
/** Return the global correction that is added to all magnitudes calculated
* by this method. */
public double getGlobalCorrection () {
return globalCorrection;
}
/**
* Return the distance correction appropriate for the method.
*/
public abstract double distanceCorrection (double distance) ;
/**
* 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. Override to impose a different
* distance cutoff criterion.
*/
public double getDistanceCutoff (double magnitude) {
return Math.max( getMinDistance(), getMaxDistance() );
}
/** Set the Waveform filter */
public void setWaveformFilter(GenericFilter filter) {
this.wfFilter = filter;
}
/** Return 'true' if the object is withing the cutoff distance.
* @See: Channelable */
public boolean isWithinCutoffDistance (Channelable obj, double magnitude) {
return (obj.getDistance() <= getDistanceCutoff(magnitude));
}
/** Return 'true' if component is to be included in the magnitude.
* Currently only responds getUseLowGains() value. */
public boolean isIncludedComponent (Channel chan) {
if (!getUseLowGains() && chan.isLowGain() ||
!getUseBroadBands() && chan.isBroadBand() ) {
return false;
} else {
return true;
}
}
/** Return 'true' if component is to be included in the magnitude.
* Currently only responds getUseLowGains() value. */
public boolean isIncludedComponent (Channelable obj) {
return isIncludedComponent(obj.getChannelObj());
}
/** Return the Waveform filter */
public GenericFilter getWaveformFilter () {
return wfFilter;
}
/** Return 'true' if this mag method has a Waveform filter */
public boolean hasWaveformFilter () {
return (wfFilter != null);
}
/** Return a filter COPY of one Waveform.
* Returns original Waveform if no filter is set.
* Returns empty Waveform if filtering fails. For example, filter
* will fail if the waveform does not have a channel gain. */
public Waveform filter (Waveform wfIn) {
if (wfFilter == null) return wfIn;
return getWaveformFilter().filter(wfIn);
}
/**
* Set values for certain essential properties so the program will work in the absence of
* a default 'properties' file.
*/
public void setDefaultProperties() {
// setReuseOldAmps(false) ;
setUseLowGains(false) ;
setScanEnergyWindow (true) ;
setMaxDistance (600.0) ;
setMaxChannels (999999 );
// setMinSNR (3.0) ;
setMinSNR (8.0) ; // changed per Kate Hutton's observations 4/2002
setTrimResidual( 1.0) ;
setRequireCorrection ( false) ;
}
/** */
public boolean loadProperties(String propertyFileName) {
GenericPropertyList props = new GenericPropertyList();
try {
FileInputStream in = new FileInputStream(propertyFileName);
props.load(in);
in.close();
} catch (Exception e) {
System.out.println ("Warning: no such properties file: "+
propertyFileName);
return false;
}
return loadProperties (props);
}
/** */
public boolean loadProperties(GenericPropertyList props) {
// setReuseOldAmps(props.getBoolean("reuseOldAmps")) ;
setUseLowGains(props.getBoolean("useLowGains"));
setUseBroadbands(props.getBoolean("useBroadBands"));
setScanEnergyWindow(props.getBoolean("scanEnergyWindow"));
setMaxDistance(props.getDouble("maxDistance"));
setMaxChannels(props.getInt("maxChannels"));
setMinSNR(props.getDouble("minSNR"));
setTrimResidual(props.getDouble("trimResidual"));
setRequireCorrection(props.getBoolean("requireCorrection"));
return true;
}
/** Return a property list that has all values set as the params of this
* TrinetMagnitudeMethod. */
public GenericPropertyList getPropertyList () {
GenericPropertyList props = new GenericPropertyList();
// props.setProperty("reuseOldAmps", ""+tf);
props.setProperty("useLowGains", useLowGains);
props.setProperty("useBroadBands", useBroadBands);
props.setProperty("scanEnergyWindow", scanEnergyWindow);
props.setProperty("maxDistance", maxDistance);
props.setProperty("maxChannels", maxChannels);
props.setProperty("minSNR", minSNR);
props.setProperty("trimResidual", trimResidual);
props.setProperty("requireCorrection", requireCorrection);
return props;
}
/** Don't calculate amps greater then this far away (in km).*/
public void setMaxDistance (double distKm ) {
maxDistance = distKm;
}
/** Return the maximum distance value. Returns Double.MAX_VALUE if it
* was not explicitly set, so it is safe to use.*/
public double getMaxDistance () {
return maxDistance;
}
/** Calculate amps less then this far away (in km).*/
public void setMinDistance (double distKm ) {
minDistance = distKm;
}
/** Return the minimum distance value. Returns Double.MIN_VALUE if it
* was not explicitly set, so it is safe to use.*/
public double getMinDistance () {
return minDistance;
}
/** Return the maximum distance value. Returns Int.MAX_VALUE if it
* was not explicitly set, so it is safe to use.*/
public int getMaxChannels () {
return maxChannels;
}
/** Don't calculate amps greater then this far away (in km).*/
public void setMaxChannels (int maxChannels ) {
this.maxChannels = maxChannels;
}
/** Set true to use low gain channels. */
public void setUseLowGains(boolean tf) {
useLowGains = tf;
}
/**Returns true if low gain channels will contribute to the magnitude. */
public boolean getUseLowGains() {
return useLowGains;
}
/** Set true to use Broad Band (SEED 'BH_') channels. */
public void setUseBroadbands(boolean tf) {
useBroadBands = tf;
}
/**Returns true if Broad Band (SEED 'BH_') channels will contribute to the magnitude. */
public boolean getUseBroadBands() {
return useBroadBands;
}
/** Set true to scan a limited window for seismic energy. */
public void setScanEnergyWindow(boolean tf) {
scanEnergyWindow = tf;
}
/**Returns true if a limited window will be scanned for seismic energy. */
public boolean getScanEnergyWindow() {
return scanEnergyWindow;
}
/** Return the minimum SNR value for which amplitudes will contribute to the
* magnitude. Returns Double.NaN if not set.
* Returns Double.MIN_VALUE if not set.*/
public double getMinSNR () {
return minSNR;
}
/** Set the minimum SNR value for which amplitudes will contribute to the
* magnitude.*/
public void setMinSNR (double value ) {
this.minSNR = value;
}
/** If value is non-zero trim amps with residuals greater then this value and
* recalc the median.*/
public void setTrimResidual( double value ) {
trimResidual = value;
}
/** Return the value of the trimResidual. Returns Double.MAX_VALUE if not set. */
public double getTrimResidual () {
return trimResidual;
}
/** Set the value of requireCorrections. */
public void setRequireCorrection ( boolean tf ) {
requireCorrection = tf;
}
/** Return the value of requireCorrections. */
public boolean getRequireCorrection() {
return requireCorrection;
}
/** 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.
* Returns 'true' if the list is changed by the scan. */
public abstract boolean preScanAmpList (Magnitude mag) ;
/** Examine the Amp list AFTER the waveforms are scanned and throw out any
* channels you don't what to keep. Any you do keep will be written to the
* dbase and will contribute to future calibrations.
* Returns 'true' if the list is changed by the scan. */
public abstract boolean postScanAmpList (Magnitude mag) ;
/** Trim Amps that are farther then either the magnitude method's distanceCutoff
* value or the distance cutoff for this MagnitudeEngine.
* Amplitudes beyond the cutoff distance will have their weights set
* to 0.0. <br>
* Note that getDistanceCutoff() depends on magnitude so you can't trim until
* AFTER the magnitude has been calculated.
*
* @see: setMaxDistance
* @see: getDistanceCutoff */
public boolean trimByDistance (Magnitude mag) {
double cutoff;
// find the min distance cutoff
if (mag.value.isNull()) {
cutoff = getMaxDistance();
} else {
cutoff = getDistanceCutoff(mag.value.doubleValue());
}
return trimByDistance(mag, cutoff);
}
public boolean trimByDistance (Magnitude mag, double cutoff) {
// short cut if no cutoff
if (cutoff == Double.MAX_VALUE) return false;
boolean changed = false;
Amplitude amp[] = mag.ampList.getArray();
for (int i=0; i<amp.length; i++) {
if (amp[i].getChannelObj().getDistance() > cutoff) {
changed = true;
amp[i].channelMag.weight.setValue(0.0);
mag.removeAmp(amp[i]);
if (debug) System.out.println ("REJECT D: too far > " +
(int) cutoff + " km "+
amp[i].getChannelObj().toDelimitedSeedString()+
" dist = "+amp[i].getDistance());
}
}
return changed;
}
/** Return the magnitude type subscript string.
* For example: for "Ml" this would return "l". */
public String getSubScript() { return subScript; }
/**
* Return the long name of the magnitude method
*/
public String getName() { return name; }
/**
* Java does not provide a function for log(base10). This is how you
* do it. (see Que, Using Java 1.1, pg. 506).
*/
// moved to org.trinet.util.MathTN
/*
public static double log10 (double val) {
final double logOf10 = Math.log(10.0);
if (val > 0) {
return Math.log(val) / logOf10;
} else {
return 0.0; // should throw exception? or NaN?
}
}
*/
/**
* Convenience method to throw WrongAmpTypeException.
*/
public void throwWrongAmpTypeException (String str) throws WrongAmpTypeException{
WrongAmpTypeException ex = new WrongAmpTypeException(str);
throw ex;
}
} // ML
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -