📄 wfviewlist.java
字号:
package org.trinet.jiggle;
import java.util.*;
//import java.sql.*;
import javax.swing.event.*;
import org.trinet.util.gazetteer.LatLonZ;
import org.trinet.util.*;
import org.trinet.jdbc.*;
import org.trinet.jasi.*;
import org.trinet.jasi.coda.*;
/**
* A List of WFViews. This also provides sort capabilities and waveform caching.
* This extends ActiveArraylist so changes to this list fire change events to
* notify any listeners of changes to this list.<p>
*
* Via its own change event listener it keeps the private reading list of each
* WFView up-to-date with
*/
public class WFViewList extends ChannelableList {
// boolean debug = true;
boolean debug = false;
/** Optional one-shot background Waveform loading thread. Seldom used
* because it tends to run the process out of memory for large events.*/
WFLoaderThread wfLoaderThread;
/** Optional Waveform cache manager */
WFCacheManager cacheMgr;
boolean cachingEnabled = false; // default
/** Used to control and synchronize waveform loading thread. */
Object loaderLock = new Object();
boolean stopLoader = false;
/** Comparitor for distance/channel sort. */
ChannelSorter distanceSorter = new ChannelSorter();
/** Comparitor for componentsort. */
// ComponentSorter componentSorter = new ComponentSorter(); Channelable
public WFViewList() {}
public WFViewList(int initialCapacity) {
super(initialCapacity);
}
public WFViewList(Collection col) {
super(col);
}
/**
* Return WFView for the given Channel. Returns null if none found.
*/
public WFView get(Channel chan) {
return (WFView) getByChannel(chan);
}
/**
* Simplify the conversion of this ArrayList to an array.
*/
public WFView[] getArray () {
WFView wfv [] = new WFView[this.size()];
this.toArray(wfv);
return wfv;
}
/**
* Return array of WFViews sorted by increasing distance from a point (most
* likely an epicenter) but do NOT sort the actual WFViewList. Note that
* further manipulation of the WFViewList will make this array obsolete. */
public WFView[] getNewSortedArray(LatLonZ loc)
{
calcDistances(loc);
WFView wfv[] = getArray();
double distArray[] = new double[wfv.length]; // array for distances
for ( int i = 0; i < wfv.length; i++) // copy the distance array
{
distArray[i] = wfv[i].getDistance();
}
IndexSort indexSort = new IndexSort();
int idx[] = indexSort.getSortedIndexes(distArray); // sort by distance
// create new sorted WFView array
WFView sortedwfv[] = new WFView[wfv.length]; // empty array, same size
for (int i = 0; i < wfv.length; i++)
{
sortedwfv[i] = wfv[idx[i]];
}
return sortedwfv;
}
/**
* Calculate the distance from location in the argument for each site in the
* list. */
public void calcDistances (LatLonZ loc) {
WFView wfv [] = this.getArray();
double dist;
for ( int i=0; i < wfv.length; i++) {
wfv[i].chan.calcDistance(loc);
/* if (wfv[i].getChannel().latlonz == null ||
wfv[i].getChannel().latlonz.isNull() ) { // lat/lon unknown
wfv[i].dist = 9999.9; // so they'll be at END of a sorted list
} else {
// wfv[i].dist = wfv[i].getChannel().latlonz.distanceFrom(loc);
wfv[i].dist = wfv[i].getChannel().latlonz.horizontalDistanceFrom(loc);
}
*/
}
}
/**
* Calculate the distance from this Solution for each site in the
* list. */
public void calcDistances (Solution sol) {
calcDistances(sol.getLatLonZ());
}
/** Return the ealiest view start time in the WFViewList. Returns 0.0 if no views. */
public double getEarliestViewTime () {
WFView wfv [] = getArray();
double earliest = 0.0;
for ( int i=0; i < wfv.length; i++) {
earliest = Math.max(earliest, wfv[i].getViewSpan().getStart());
}
return earliest;
}
/** Return the ealiest data sample time in the WFViewList. Returns 0.0 if no views. */
public double getEarliestSampleTime () {
WFView wfv [] = getArray();
double earliest = 0.0;
for ( int i=0; i < wfv.length; i++) {
earliest = Math.max(earliest, wfv[i].getDataBox().getStartTime());
}
return earliest;
}
/**
* Load all the waveforms for WFViews in this list. This can be a time consuming
* task and caller will block until this is done.
* Use loadWaveformsInBackground() to do in a separate thread and not block.
*/
public void loadWaveformsNow() {
WFView wfv[] = getArray();
for (int i = 0; i<wfv.length; i++) {
wfv[i].loadTimeSeries();
}
}
// ****** WOULD THERE BE A COLLISION IF OTHER DBASE ACTIVITY WAS DONE? *********
/** Begin loading waveforms in a background thread. Each waveform object will
fire a change event after it is loaded so components can do something, like repaint,
when each waveform load is done.*/
public void loadWaveformsInBackground() {
wfLoaderThread = new WFLoaderThread(this);
}
/** Stop the waveforms loader thread. Thread will stop after the next waveform
load is done. */
public void stopLoadWaveformsInBackground() {
synchronized (loaderLock) {
stopLoader = true;
loaderLock.notifyAll();
}
}
//////// INNER CLASS
/** This is a one-shot thread that loads ALL waveforms in background when
* it runs. Not to be confused with
* WFCacheManager which dynamically loads and unloads waveforms. */
class WFLoaderThread implements Runnable {
WFViewList wfvList;
public Thread thread;
// constructor - also starts thread
public WFLoaderThread (WFViewList wfvList) {
this.wfvList = wfvList;
thread = new Thread(this);
stopLoader = false;
thread.start();
}
public void run () {
WFView wfv[] = wfvList.getArray();
for (int i = 0; i<wfv.length; i++) {
if (wfv[i].loadTimeSeries()) {
if (debug) System.out.println ("loaded: "+ wfv[i].wf.toString());
}
synchronized (loaderLock) {
if (stopLoader) return;
}
}
} // end of run()
} // end of WFLoaderThread class
////////
/** Dump the whole list. */
public void dump () {
WFView wfv [] = getArray();
for ( int i=0; i < wfv.length; i++) {
wfv[i].dump();
}
}
// //////////////////////////////////////////////////////////////////
// Waveform cache methods
/** Enable/disable waveform caching with default parameters. This does not start
the cache manager, that is done by a call to setCacheIndex(int index). */
public void setCachingEnabled (boolean tf) {
cachingEnabled = tf;
if (tf) {
cacheMgr = new WFCacheManager(this);
} else {
stopCacheManager();
}
}
public void stopCacheManager() {
if (cacheMgr != null) {
cacheMgr.stopCacheMgr();
cacheMgr = null;
}
}
/** Returns 'true' if waveform caching is enabled */
public boolean getCachingEnabled () {
return cachingEnabled;
}
/** Returns the WFCacheManager. Returns 'null' if waveform caching is not enabled. */
public WFCacheManager getWFCacheManager() {
return cacheMgr;
}
/** Pass-thru method. Specify the size of the cache by setting the number of
* panels above and below the index. The current index is considered part of the
* below value so that the Cache size = above + below. */
public void setCacheSize (int above, int below) {
if (getCachingEnabled()) {
cacheMgr.setCacheSize(above, below);
}
}
/** Move the logical index of the waveform cache to the new position. */
public void setCacheIndex(int index) {
if (debug) System.out.println ("setCacheIndex= "+index+
" getCachingEnabled()= "+ getCachingEnabled() );
if (getCachingEnabled()) {
cacheMgr.setIndex(index);
}
}
public void loadWaveformsInCache() {
setCacheIndex(0);
}
//////////////////////////////////////////////////////
/** INNER CLASS: Handle changes to the JasiObject lists. */
/*
class JasiReadingChangeListener implements ChangeListener {
WFView wfv;
JasiReading jr;
public void stateChanged (ChangeEvent changeEvent) {
// 'arg' will be either a JasiReading or a JasiReadingList
Object arg = changeEvent.getSource();
if (arg instanceof JasiReading) {
jr = (JasiReading) arg;
wfv = get(jr.getChannel());
if (wfv != null) updateOneReadingList (wfv, jr);
return;
} else if (arg instanceof JasiReadingList) {
updateAllReadingLists( (JasiReadingList)arg );
}
} // end of stateChanged
protected void updateOneReadingList (WFView wfv, JasiReading jr) {
if (jr instanceof Phase) {
wfv.updatePhaseList();
} else if (jr instanceof Coda) {
wfv.updateCodaList();
} else if (jr instanceof Amplitude) {
wfv.updateAmpList();
}
}
protected void updateAllReadingLists (JasiReadingList jrl) {
WFView wfv [] = getArray();
if (jrl instanceof PhaseList) {
for ( int i=0; i < wfv.length; i++) { wfv[i].updatePhaseList(); }
} else if (jrl instanceof CodaList) {
for ( int i=0; i < wfv.length; i++) { wfv[i].updateCodaList(); }
} else if (jrl instanceof AmpList) {
for ( int i=0; i < wfv.length; i++) { wfv[i].updateAmpList(); }
}
}
} // end of JasiReadingChangeListener
*/
/**
* Main for testing.
*/
public static void main (String args[]) {
int evid;
if (args.length <= 0) {
System.out.println ("Usage: java WFViewList [evid])");
evid = 9526852;
System.out.println ("Using evid "+ evid+" as a test...");
} else {
Integer val = Integer.valueOf(args[0]); // convert arg String to 'double'
evid = (int) val.intValue();
}
System.out.println ("Making connection...");
DataSource init = new TestDataSource(); // make connection
// NOTE: this demonstrates making a static Channel list.
// System.out.println ("Reading in station list...");
// Channel.setList (Channel.getAllList());
System.out.println ("Making MasterView for evid = "+evid);
MasterView mv = new MasterView();
// test limit
// mv.setWaveformLoadLimit(200);
mv.defineByDataSource(evid);
// mv.loadChannelData();
mv.dump();
// mv.phaseList.dump();
Solution sol[] = mv.solList.getArray();
PhaseList pl = (PhaseList) mv.getSelectedSolution().phaseList.getAssociated(sol[0]);
pl.dump();
int k = 1;
while (mv.wfvList.wfLoaderThread.thread.isAlive()) {
System.out.println("Waiting for wfloader to finish..."+ k++);
try{
Thread.sleep(1000);
} catch (InterruptedException e){}
// test killing loader thread
System.out.println("### Killing loader thread...");
mv.wfvList.stopLoadWaveformsInBackground();
}
}
} // end of class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -