📄 channeltimewindowmodel.java
字号:
package org.trinet.jasi;
import java.util.*;
import org.trinet.util.*;
/**
Abstract model that determines and returns a Collection of channel/time-windows
that characterize a seismic event, i.e. the windows should
have seismic energy for the specified Solution. Specific algorithms for
arriving at this list extend this class. There are two parts to the model:<p>
1) Deciding which channels to include <br>
2) Deciding the start-time and duration of the time windowfor each channel. Each
channel may have a different window.<p>
Most models (algorythms) require a Solution. The origin time is needed to set
time window starts and the magnitude is often used to set window durations.<p>
This abstract class has a default algorithm (method getTimeWindow()) based on
the coda duration curve for southern California. Override it if it is not
appropriate for your application.
*/
public abstract class ChannelTimeWindowModel {
/** The solution for which the model is calculated. */
Solution sol = null;
/** Model name string. */
String modelName = "Default";
/** A string with an brief explanation of the model. For help and tooltips. */
String explanation = "";
/** A ChannelList from which channel time windows will be selected. */
ChannelableList channelSet = null;
/** Minimum window duration (secs). Some algorythms may need an minimum amount of data.*/
double minWindow = 30.0;
/** Minimum window duration (secs).*/
double maxWindow = 600.0;
/** Time added to start of time window calculated by the model algorythm (secs).*/
double preEvent = 10.0;
/** Time added to duration of time window calculated by the model algorythm (secs).*/
double postEvent = 10.0;
/** The maximum distance allowed by the getDistanceCutoff() method. All channel
* beyond this distance will be excluded from the Channel set.
*/
double maxDistance = Double.MAX_VALUE;
/** The minimum distance allowed by the getDistanceCutoff() method. All channel
* within this distance will be included in the Channel set. Default = Double.MAX_VALUE
*/
double minDistance = 0.0;
/** The maximum number of channels that will be allowed to belong to
* this Channel set. Default = 0.
*/
int maxChannels = Integer.MAX_VALUE;
public ChannelTimeWindowModel() {
}
/** Sets the Solution and the list of channels from which the algorythm can select channels.*/
public ChannelTimeWindowModel(Solution sol, ChannelableList inputChannelSet ) {
setSolution(sol);
setChannelList(inputChannelSet);
}
/** Sets the list of channels from which the algorythm can select channels.*/
public ChannelTimeWindowModel(ChannelableList inputChannelSet ) {
setChannelList(inputChannelSet);
}
/** Sets the Solution.*/
public ChannelTimeWindowModel(Solution sol ) {
setSolution(sol);
setChannelList(MasterChannelList.get());
}
/** Set the descriptive name for the model. */
public void setModelName (String name) {
modelName = name;
}
/** Get the descriptive name for the model. */
public String getModelName () {
return modelName;
}
/** Get the Class name for the model. */
public String getClassname () {
return this.getClass().getName();
}
/** Set the longer description of the model. This may be used in help,
* error messages, etc.*/
public void setExplanation (String str) {
explanation = str;
}
/** Get the longer description of the model. This may be used in help,
* error messages, etc.*/
public String getExplanation () {
return explanation;
}
/** 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 the Solution to use in the model.*/
public void setSolution (Solution sol) {
this.sol = sol;
}
/** Return the Solution used in the model.*/
public Solution getSolution () {
return sol;
}
/** Set a ChannelList from which the model will select channels to include.
* If there is a channelList channel/timewindows will only be created for
* channels in the list. If this is not set ALL channels are permissible.*/
public void setChannelList (ChannelableList channelSet) {
this.channelSet = channelSet;
}
/** Return the ChannelableList from which the model will select channels to include. */
public ChannelableList getChannelList() {
return channelSet;
}
/** Set the minimum and maximum window size (seconds) that can be returned.*/
public void setWindowLimits (double minSize, double maxSize) {
minWindow = minSize;
maxWindow = maxSize;
}
/** Set the value of the amount of time to save before onset of energy. */
public void setPreEventSize (double seconds) {
preEvent = seconds;
}
/** Set the value of the amount of time to save after the decay of energy. */
public void setPostEventSize (double seconds) {
postEvent = seconds;
}
/** Given a distance, return the TimeSpan (time window) at this distance.
* The window start time is: OriginTime + P_travetime - preEvent <br>
* The window end time is: OriginTime + P_travetime + magCoda_time + postEvent*/
public TimeSpan getTimeWindow (double dist) {
//TravelTime ttModel = new TravelTime();
TravelTime tt = TravelTime.getInstance();
tt.setSource(sol);
double start = 0.0;
double end = 0.0;
double ot = sol.datetime.doubleValue();
double pTime = ot + tt.getTTp(dist);
start = pTime - preEvent;
end = pTime + getCodaDuration() + postEvent;
double duration = end - start;
// check extremes
if (duration > maxWindow) {
end = start+maxWindow;
} else if (duration < minWindow) {
end = start+minWindow;
}
return new TimeSpan(start, end);
}
/** Return the coda duration for an event of this magnitude.
* This is based on the straight line fit of a plot of
* ML vs log duration (tau). The equation is:<p>
* <tt>
10 ^ ((mag - intercept) / slope)
Emperical data from southern california yields values of:
intercept = -0.95
slope = 2.15
* </tt>*/
protected double getCodaDuration(double mag) {
double magIntercept = -0.95;
double slope = 2.15;
return Math.pow(10.0, ((mag - magIntercept)/slope));
}
protected double getCodaDuration() {
return getCodaDuration(sol.magnitude.value.doubleValue());
}
/** Return a Collection of Channel objects selected by the model. Note that
* TimeSpans are not part of a Channel object so time windows will not be
* calculated.
*
* @see: Channel */
// public abstract Collection getChannelList();
/** Return a Collection of Waveform objects selected by the model.
* The Waveforms will not contain time-series yet. To load time-series you must set
* the loader mode with a call to Waveform.setWaveSource(Object) then load them
* with Waveform.loadTimeSeries().<p>
*
* @see: Waveform
*/
public abstract Collection getWaveformList();
/** Return a Collection of Waveform objects selected by the model.
* The Waveforms will not contain time-series yet. To load time-series you must set
* the loader mode with a call to Waveform.setWaveSource(Object) then load them
* with Waveform.loadTimeSeries().<p>
*
* @see: Waveform
*/
public Collection getWaveformList(Solution sol, ChannelableList list) {
this.setChannelList(list);
this.setSolution(sol);
return getWaveformList();
}
/** Return a Collection of Waveform objects selected by the model.
* The will not contain time-series yet. To load time-series you must set
* the loader mode with a call to Waveform.setWaveSource(Object) then load them
* with Waveform.loadTimeSeries().<p>
*
* @see: Waveform
*/
public Collection getWaveformList(Solution sol) {
this.setSolution(sol);
return getWaveformList();
}
/** Return true if the passed Channelable is in the channel set.
* Also eturns true if no channelset was defined.
* @See: setChannelLigs() */
protected boolean include(Channelable cbl) {
if (getChannelList() == null || getChannelList().isEmpty()) return true; // if no set assume all are OK
// does the list contain this channel?
for (int i =0; i<getChannelList().size(); i++) {
if (cbl.getChannelObj().equals(getChannelList().get(i))) return true;
}
return false;
}
/** Return the subset of 'waveformlist' that matches the list set by
* setChannelList(). This enforces the rule that returned waveforms
* must be in the given channel list.
* @see: setChannelList() */
protected Collection filterWfListByChannelList(Collection waveformlist) {
if (getChannelList() == null ||
getChannelList().isEmpty()) return waveformlist;
ArrayList newWfList = new ArrayList();
Waveform wf[] = new Waveform[waveformlist.size()];
wf = (Waveform[]) waveformlist.toArray(wf);
for (int i=0; i< wf.length; i++) {
if (include(wf[i])) newWfList.add(wf[i]);
}
return newWfList;
}
/** Return an instance of the named ChannelTimeWindowModel class. Returns
* null if instance cannot be created or is not an extension of
* ChannelTimeWindowModel.*/
public static ChannelTimeWindowModel getInstance(String className) {
try {
Object obj = Class.forName(className).newInstance();
if (obj instanceof ChannelTimeWindowModel) {
return (ChannelTimeWindowModel) obj;
} else {
return null;
}
} catch (Exception ex) {
return null;
}
}
/** Return a Collection of String objects based on the contents
* of the property string. The string is a series of fully qualified class
* names and has the form:<p>
*
* "org.trinet.jasi.ThisIsaModel, org.trinet.otherstuff.AnotherModel"
*
* The actual class objects are instantiated with
* ChannelTimeWindowModel.getInstance(String).
* */
public static AbstractCollection parsePropertyString(String string) {
if (string == null) return null;
ActiveList list = new ActiveList();
String delList = ",:;" ; // delimiter list
StringTokenizer strTok = new StringTokenizer(string, delList);
try {
while (strTok.hasMoreTokens()) {
// list.add(Class.forName(strTok.nextToken()));
list.add(strTok.nextToken().trim());
}
} catch (Exception ex) {
ex.printStackTrace();
System.err.println("Bad syntax in property string:" +string);
return null;
}
return (AbstractCollection) list;
}
/** Returns ChannelTimeWindowModel's name. This is used produce a string to
* be displayed in a JComboBox, for instance. */
public String toString () {
return getModelName();
}
/** Given a Collection of Strings that are fully qualified class names of
* ChannelTimeWindowModels produce a string is a delimited concatinatation
* with the form:<p>
*
* "org.trinet.jasi.ThisIsaModel, org.trinet.otherstuff.AnotherModel"
*
* Note the input Collection is a Collection of strings not ChannelTimeWindowModels/
* */
public static String toPropertyString(Collection list) {
final String delim = ", ";
String str = "";
String lstr[] = (String[]) list.toArray(new String[list.size()]);
for (int i = 0; i< lstr.length; i++) {
if (i > 0) str += delim;
str += lstr[i];
}
return str;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -