📄 waveform.java
字号:
package org.trinet.waveserver.rt;
import java.util.*;
import org.trinet.jasi.WFSegment;
import org.trinet.jasi.seed.SeedReader;
import org.trinet.jasi.seed.SeedReaderException;
/** Implemenation of the TRINET WaveClient/Server Waveform class.
* This class is a container for the time series data of a waveform belonging to a specific seismic station channel.
* The seismic channel data attributes are described by the Channel data member associated with this object.
* The time-series is contained in DataSegment objects as a collection of timestamped contiguous time-series packets.
* The sample rate for the associated time-series is assumed uniform and is set as data member in the associated Channel object.
* This class is used by a WaveClient object when processing a getData(...) or getPacketData(...) message request.
*/
public class Waveform implements Cloneable, MiniSeedDataTypes {
/** Fraction of a period jitter allowed is sampling. */
public static final double TIME_EPSILON = 0.10;
/** MiniSEED Data type defined by NCEDC Waveform schema */
public static final int MINISEED_TYPE = 2; // as defined by NCEDC Waveform schema
/** Estimated minimum samples in a miniSEED packet. */
public static final int MINISEED_MIN_PACKET_SAMPLES = 128;
/** List of DataSegment objects containing summary data and SEED packets. */
Collection dataSegmentList;
/** Channel descriptor object for this Waveform. */
Channel chan;
/** Size of data sample buffer (frame) comprising packet. */
int recordSize; // Supports MINISEED_REC_512
/** Time-series data format type */
int dataFormat; // Supports MINISEED_TYPE;
/** SEED packet reader used to parse data in data segment collection.*/
private SeedReader seedReader;
/** Internal pointer used by next() method as starting offset of next contiguous Waveform time series */
private int nextSegmentIndex;
/** Default constructor no data member initialization == null data members. */
public Waveform() { }
/** Constructor aliases data members with references same data as that of the input Waveform.
* @exception java.lang.NullPointerException null input parameter
*/
public Waveform(Waveform wave) {
chan = wave.chan;
dataSegmentList = wave.dataSegmentList;
recordSize = wave.recordSize;
dataFormat = wave.dataFormat;
}
/** Constructor initializes data members by parsing data from the first DataSegment in the List.
* Verifies data integrity/consistency by scanning data list elements.
* @exception java.lang.NullPointerException if input collection is null.
* @exception java.lang.WaveformDataException error occurred verifying collection data.
*/
Waveform(Collection dataSegmentList) throws WaveformDataException {
this(dataSegmentList, true);
}
/** Constructor initializes data members by parsing data from the first DataSegment in the List.
* If verifyData == true, verifies data integrity/consistency by scanning all list elements.
* else no checking is done and initialization is complete.
* @exception java.lang.NullPointerException input data collection is null.
* @exception java.lang.WaveformDataException error occurred verifying collection data.
*/
Waveform(Collection dataSegmentList, boolean verifyData) throws WaveformDataException {
if (dataSegmentList == null) {
throw new NullPointerException("Waveform(List) null input argument.");
}
if (dataSegmentList.isEmpty()) {
System.err.println("Waveform(Collection, boolean) Warning - collection is empty no data.");
}
setData(dataSegmentList, verifyData);
}
/** Makes a shallow copy of this object */
public Object clone() {
Waveform waveform = null;
try {
waveform = (Waveform) super.clone();
// waveform.chan = (Channel) chan.clone(); // optional, do you really need a new copy?
}
catch (CloneNotSupportedException ex) {
ex.printStackTrace();
}
return waveform;
}
/** Set the trace data DataSegmentList for this Waveform with verification of data integrity/consistency.
* @exception java.lang.NullPointerException if input collection is null.
*/
void setData(Collection dataSegmentList) throws WaveformDataException {
setData(dataSegmentList, true);
}
/** Set the trace data DataSegmentList for this Waveform.
* If verify == true, verifies data integrity/consistency by scanning all list elements.
* else no checking is done and initialization is complete.
* @exception java.lang.NullPointerException if input data collection is null.
* @exception WaveformDataException error occurred initializing data members.
*/
void setData(Collection dataSegmentList, boolean verify) throws WaveformDataException {
if (dataSegmentList == null) {
throw new NullPointerException("Waveform.setData() null data segment list input parameter.");
}
nextSegmentIndex = 0;
this.dataSegmentList = dataSegmentList; // assumes data is in sorted order
if (dataSegmentList.isEmpty()) return;
WFSegment wfSegment = null;
DataSegment dataSegment = null;
// Set the channel data declared in the input data
try {
//Obtain first data segment from list and check data samples, treat no samples as fatal error
Iterator iter = dataSegmentList.iterator();
dataSegment = (DataSegment) iter.next();
if (dataSegment.numberOfSamples <= 0) throw new WaveformDataException("No samples declared for first data segment.");
if (seedReader == null) seedReader = new SeedReader();
// Extract the data from the DataSegment
wfSegment = seedReader.createWFSegment(dataSegment.dataContent);
// Initialize Waveform data members with the data extracted from first DataSegment data Packet
chan = makeChannel(wfSegment);
dataFormat = initDataFormat(wfSegment.fmt);
recordSize = initRecordSize(dataSegment.numberOfDataBytes);
// VERIFY == FALSE ASSUMES ALL REMAINING DATA SEGMENTS CONFORMING +++++++++++++++++++++++++++++++++++++++++
if ( verify ) verifyDataConsistency(iter, dataSegment);
}
catch (WaveformDataException ex) {
System.err.println("Error Waveform.setData() failure processing DataSegment collection");
if (dataSegment != null) System.err.println(toString(nextSegmentIndex, dataSegment));
if (wfSegment != null) System.err.println("\tDump of First WFSegment:\n" + wfSegment.dumpToString());
System.err.println(ex.toString());
ex.printStackTrace();
throw new WaveformDataException("Waveform.setData(): " + ex.getMessage());
}
catch (Exception ex) {
System.err.println("Error Waveform.setData() caught exception processing DataSegment collection");
if (dataSegment != null) System.err.println(toString(nextSegmentIndex, dataSegment));
if (wfSegment != null) System.err.println("\tDump of First WFSegment:\n" + wfSegment.dumpToString());
System.err.println(ex.toString());
ex.printStackTrace();
throw new WaveformDataException("Waveform.setData() caught exception " + ex.getMessage());
}
}
/** Checks consecutive DataSegment in input collection for collective data consistency.
*/
private void verifyDataConsistency(Iterator iter, DataSegment dataSegment) throws WaveformVerificationException {
DataSegment dataSegmentPrevious = dataSegment;
int currentSegmentIndex = 0;
WFSegment wfSegment = null;
try {
while (iter.hasNext()) {
currentSegmentIndex++;
dataSegment = (DataSegment) iter.next();
// Verify that there are data declared in this segment
if (dataSegment.numberOfSamples <= 0)
throw new WaveformDataException("No samples declared for data segment, index = " + currentSegmentIndex);
//Extract channel data from SEED header
wfSegment = seedReader.createWFSegment(dataSegment.dataContent);
if (wfSegment == null)
throw new WaveformDataException("Unable to decode SEED header, index = " + currentSegmentIndex);
//Set the comparison data for this segment
Channel currentChan = makeChannel(wfSegment);
int currentDataFormat = initDataFormat(wfSegment.fmt);
int currentRecordSize = initRecordSize(dataSegment.numberOfDataBytes);
// Verify the channel identifier data are the same as the first segment
if (! isEqualChannelData(currentChan))
throw new WaveformDataException("Channel id/samplerate mismatch in data, index = " + currentSegmentIndex);
// Verify the data byte count is the same as the first segment
if (currentRecordSize != recordSize)
throw new WaveformDataException("RecordSize mismatch in data, index = " + currentSegmentIndex);
// Verify the data format type is the same as that of the first data segment
if (currentDataFormat != dataFormat)
throw new WaveformDataException("Format mismatch in data, index = " + currentSegmentIndex);
// If this packet and last overlap, display a warning, gaps between packets are OK.
// Looks like a bug to me. - DDG 6/20/01
// if (isOverlapping(dataSegment, dataSegmentPrevious)) {
if (isOverlapping(dataSegmentPrevious, dataSegment)) {
printOverlapWarning(dataSegmentPrevious, dataSegment, currentSegmentIndex);
// Overlapping but don't erase remaining dataSegments in list
// dataSegmentList.subList(currentIndex, dataSegmentList.size()).clear();
}
if (hasGap(dataSegmentPrevious, dataSegment)) {
printGapWarning(dataSegmentPrevious, dataSegment, currentSegmentIndex);
// Overlapping but don't erase remaining dataSegments in list
// dataSegmentList.subList(currentIndex, dataSegmentList.size()).clear();
}
dataSegmentPrevious = dataSegment;
}
}
catch (WaveformDataException ex) {
System.err.println("Error Waveform.verifyDataConsistency() failure processing DataSegment collection at index: "
+ currentSegmentIndex);
if (dataSegment != null) System.err.println(toString(currentSegmentIndex, dataSegment));
if (wfSegment != null) System.err.println("\tDump of equivalent WFSegment:\n" + wfSegment.dumpToString());
System.err.println(ex.toString());
ex.printStackTrace();
throw new WaveformVerificationException("Waveform.verifyDataConsistency(): " + ex.getMessage());
}
catch (Exception ex) {
System.err.println("Error Waveform.verifyDataConsistency() caught exception DataSegment collection at index: "
+ currentSegmentIndex);
if (dataSegment != null) System.err.println(toString(currentSegmentIndex, dataSegment));
if (wfSegment != null) System.err.println("\tDump of equivalent WFSegment:\n" + wfSegment.dumpToString());
System.err.println(ex.toString());
ex.printStackTrace();
throw new WaveformVerificationException("Waveform.verifyDataConsistency() " + ex.getMessage());
}
}
/** Returns true if the input channel identifier and sample rate are equivalent to those of this waveform.*/
private boolean isEqualChannelData(Channel newChan) {
return (chan.equalsId(newChan) && ( Math.rint(chan.sampleRate) == Math.rint(newChan.sampleRate)) );
}
/** Creates a new org.trinet.rt.seisimc.Channel object from the data in the WFSegment object. */
private static Channel makeChannel(WFSegment wfSegment) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -