📄 wfview.java
字号:
Channel ch[] = new Channel[chanList.size()];
chanList.toArray(ch);
return copyChannel(ch);
}
/**
* Given an array of Channels (i.e. a station list), find the one that matches
* this WFViews's current Channel. Replace the WFView's Channel object with the
* "found" Channel which has complete Channel location & response info. This is
* necessary for distance calcs, sorting, magnitudes, etc. Return 'true' if
* match was found, else return 'false'. */
public boolean copyChannel(Channel[] ch)
{
// VH_/EH_ kludge
String origChan = getChannelObj().getChannel();
Channel chan = getChannelObj();
// No efficient way to do this unless we put Channel list in hash table
for (int i = 0; i<ch.length; i++)
{
if (chan.equalsIgnoreCase(ch[i])) {
setChannelObj(ch[i]); // substitute
// rest of the VH_/EH_ kludge
// System.out.println ("1) "+chan.toString());
chan.setChannel(origChan);
// System.out.println ("2) "+chan.toString());
return true;
}
}
return false;
}
/** Update the local phaseList by scanning the one in the MasterView. This
* local list is used to more efficiently plot the phases. Returns the
* number of phases in the phaselist for this WFView. */
public int updatePhaseList() {
return updatePhaseList(mv.getAllPhases());
}
/** Update the local phaseList by scanning the one passed. This
* local list is used to more efficiently plot the phases. Returns the
* number of phases in the phaselist for this WFView. */
public int updatePhaseList(PhaseList list) {
phaseList.clear();
phaseList.addAll(list.getAssociated(getChannelObj()));
return phaseList.size();
}
/** Update the local ampList by scanning the one in the MasterView. This
* local list is used to more efficiently plotting. Returns the
* number of amps in the list for this WFView. */
public int updateAmpList() {
return updateAmpList(mv.getAllAmps());
}
/** Update the local ampList by scanning the one in the MasterView. This
* local list is used to more efficiently plotting. Returns the
* number of amps in the list for this WFView. */
public int updateAmpList(AmpList list) {
ampList.clear();
ampList.addAll(list.getAssociated(getChannelObj()));
return ampList.size();
}
/** Update the local codaList by scanning the one in the MasterView. This
* local list is used to more efficiently plotting. Returns the
* number of codas in the list for this WFView. */
public int updateCodaList() {
return updateCodaList(mv.getAllCodas());
}
/** Update the local codaList by scanning the one in the MasterView. This
* local list is used to more efficiently plotting. Returns the
* number of codas in the list for this WFView. */
public int updateCodaList(CodaList list) {
codaList.clear();
codaList.addAll(list.getAssociated(getChannelObj()));
return codaList.size();
}
/** Update the local codaList by scanning the one in the MasterView. This
* local list is used to more efficiently plotting. Returns the
* number of codas in the list for this WFView. */
/* public int updateJasiReadingList(JasiReadingList list) {
list = (JasiReadingList) list.getAssociatedByChannel(chan);
return list.size();
}
*/
/** Return true if there are phases */
public boolean hasPhases() {
return !phaseList.isEmpty();
}
/** Return true if there are amps */
public boolean hasAmps() {
return !ampList.isEmpty();
}
/** Return true if there are codas */
public boolean hasCodas() {
return !codaList.isEmpty();
}
/**
* Returns a partial Phase description for this WFView.
* Only populates the Channel part of the Phase.
* Leaves specific variables null, e.g. datetime, iphase, etc.
*/
public Phase getEmptyPhase() {
Phase ph = Phase.create();
ph.setChannelObj((Channel) chan.clone());
return ph;
}
/**
* Takes its best shot at describing the phase pick at the given time.
* This first hack is very crude.
*/
//TODO: add estimate of quality, and phase (based on ttime to selected origin)
public Phase describePickAt (double dtime, Solution selSol) {
Phase ph = getEmptyPhase();
ph.datetime.setValue(dtime);
// ph.description.fm = "..";
double diff = 0.0;
// figure first motion it there's a waveform
if (wf != null) {
Sample samp1 = wf.closestSample(dtime);
// Sample samp2 = wf.closestSample(dtime + getSampleInterval() );
Sample samp2 =
wf.closestSample(dtime + wf.getSampleInterval());
diff = samp1.value - samp2.value;
// <> First motion
if (diff < 0.0) {
ph.description.fm = "c.";
} else if (diff > 0.0) {
ph.description.fm = "d.";
} else {
ph.description.fm = "..";
}
}
// <> Phase type, could be clever and check traveltimes
double ttP = tt.getTTp(getHorizontalDistance(), mv.getSelectedSolution().getLatLonZ().getZ());
double ttS = ttP*tt.getPSRatio();
double sMinusP = ttS - ttP;
if (selSol == null) {
ph.description.iphase = "P"; // guess P if no solution
} else {
double ot = selSol.datetime.doubleValue();
double ttObs = dtime - ot;
// Guess "S" if time is closer to expected S than expected P
// i.e. if time is greater then P-time + 1/2 S-P
if (ttObs >= (ttP+ (0.5 *sMinusP) ) ) {
ph.description.iphase = "S";
} else {
ph.description.iphase = "P";
}
}
// <> "qual" (aka onset) i, e, w
// "i" if first diff is 10% of the full range, "e" if 5% (this is a kludge)
// but looks reasonable upon inspection.
//TODO: refine this
double firstDiffRatio =
(double) Math.abs(diff) /(double) wf.rangeAmp();
if (firstDiffRatio >= 0.10) { ph.description.ei = "i";
} else if (firstDiffRatio >= 0.05) { ph.description.ei = "e";
} else { ph.description.ei = "w"; }
/*
System.out.println ("firstDiffRatio = "+ firstDiffRatio +
" Math.abs(diff)= "+ Math.abs(diff) +
" wf.rangeAmp()= "+wf.rangeAmp());
*/
// <> "quality" (aka weight)
ph.description.setQuality(1.0);
// <> association, could be clever and check traveltimes
// if (selSol != null) ph.associate(selSol);
return ph;
}
/**
* Return a WFSelectionBox the is based on the extremes of the data, including
* waveforms and phases. If there is no waveform max/min amps cannot be set
* based on the data so arbitrary values of +- 100 will be usex1d. */
public WFSelectionBox getViewBox () {
if (wf != null && wf.hasTimeSeries()) {
return new WFSelectionBox(viewSpan, wf.getMaxAmp(), wf.getMinAmp());
} else {
// box must have non-zero dimension else /0 error happen elsewhere
return new WFSelectionBox(viewSpan, 1, 0);
}
}
/** Return the TimeSpan of the view. */
public TimeSpan getViewSpan () {
return viewSpan;
}
/**
* Return a WFSelectionBox the is based on the extremes of the data, including
* waveforms and phases. If there is no waveform max/min amps cannot be set
* based on the data so arbitrary values of +- 100 will be used. */
public WFSelectionBox getDataBox () {
if (wf != null && wf.hasTimeSeries()) {
return new WFSelectionBox(dataSpan, wf.getMaxAmp(), wf.getMinAmp());
} else {
// box must have non-zero dimension else /0 error happens elsewhere
// can't use dataSpan because it depends on wf bounds
return new WFSelectionBox(viewSpan, 1, 0);
}
}
/**
* Set the WFView's 'dataSpan' value to match the actual data in the Waveform.
*/
public void autoSetDataSpan() {
dataSpan = wf.getTimeSpan();
}
/**
* Dump some info about the view for debugging
*/
public void dump ()
{
System.out.println (dumpToString());
}
/**
* Dump some info about the view for debugging
*/
public String dumpToString ()
{
String str = "WFView: "+ getChannelObj().toString() +
" dist = "+ getDistance();
if (wf != null) {
str +=
" nsegs = " + wf.getSegmentList().size() +"\n"+
" nsamples = "+ wf.samplesInMemory() +
" maxamp = " + wf.getMaxAmp() +
" minamp = " + wf.getMinAmp() +
" nphases= "+ phaseList.size()+"\n";
} else {
str += " -- no waveform available --";
}
str += "\n viewSpan = " + viewSpan.toString() + "\n";
str += " dataSpan = " + dataSpan.toString() + "\n";
// str += wf.toString();
// dump info about all the segments
/* WFSegment seg[] = WFSegment.getArray(segVector);
for (int i = 0; i< segmentCount(); i ++)
{
str += "....\n";
str += seg[i].dumpToString();
}
*/
return str;
}
} // end of class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -