📄 waveform.java
字号:
public double getSampleRate() {
if (chan == null) return -1.;
return chan.sampleRate;
}
/** Returns true if time series data contains time gaps.
* Returns false if no time gaps or no data.
*/
public boolean hasTimeGaps() {
int offset = offsetToFirstTimeGap(dataSegmentList);
return ( (offset > 0) && (offset < dataSegmentList.size()) );
}
/** Returns index offset to first time tear in data segment list for this Waveform.
* Returns size of the list if the list has no gaps.
* Returns 0 if the segment list is empty.
* @exception java.lang.NullPointerException input Collection parameter null
*/
int offsetToFirstTimeGap(Collection dataSegmentList) {
if (dataSegmentList == null)
throw new NullPointerException("Waveform.offsetToFirstTimeGap null time-series collection parameter");
if (dataSegmentList.isEmpty()) return 0;
Iterator iter = dataSegmentList.iterator();
DataSegment dataSegment = (DataSegment) iter.next();
int offset = 0;
while (iter.hasNext()) {
DataSegment dataSegmentNext = (DataSegment) iter.next();
offset++;
if (absTimeGapSeconds(dataSegment, dataSegmentNext) > getEpsilon()) break;
dataSegment = dataSegmentNext;
}
return offset;
}
/** Number of contiguous time-series segments comprised this waveform. */
public int numberOfSegments() {
if (dataSegmentList == null || dataSegmentList.isEmpty()) return 0;
Iterator iter = dataSegmentList.iterator();
DataSegment dataSegment = (DataSegment) iter.next();
int numberOfSegments = 1;
while (iter.hasNext()) {
DataSegment dataSegmentNext = (DataSegment) iter.next();
if (absTimeGapSeconds(dataSegment, dataSegmentNext) > getEpsilon()) { numberOfSegments++; }
dataSegment = dataSegmentNext;
}
return numberOfSegments;
}
/** Erases all waveform trace data beyond the first time gap */
void trimAtFirstGap() {
// Comment out List specific implementation
// int offset = offsetToFirstTimeGap(this.dataSegmentList);
// dataSegmentList.subList(offset, dataSegmentList.size()).clear();
Iterator iter = dataSegmentList.iterator();
DataSegment dataSegment = (DataSegment) iter.next();
while (iter.hasNext()) {
DataSegment dataSegmentNext = (DataSegment) iter.next();
if (absTimeGapSeconds(dataSegment, dataSegmentNext) > getEpsilon()) {
iter.remove();
while (iter.hasNext()) {
iter.next();
iter.remove();
}
}
break;
}
}
/** Create new collection for DataSegment objects.*/
private Collection createDataSegmentCollection(int size) {
return new ArrayList(size);
}
/** Creates a new Waveform whose data copy the next contiguous time series segment within this Waveform.
* If this Waveform has no time gaps, a complete copy of this Waveform. An internal pointer is advanced with
* each invocation, so after returning the last contiguous segment, subsequent invocations return null.
* Returns null if this Waveform time-series data collection has no more time-series segments.
* @exception java.lang.NullPointerException null member time-series collection
*/
public Waveform next() {
if (dataSegmentList == null) throw new NullPointerException("Waveform.next() data segment List is null");
if (dataSegmentList.isEmpty() || (nextSegmentIndex >= dataSegmentList.size()) ) return null;
// Create view of list starting with next data segment to end of list
Iterator iter = dataSegmentList.iterator();
Collection newDataSegmentList = createDataSegmentCollection(dataSegmentList.size() - nextSegmentIndex);
// Find the first and last packet of the next contiguous time segment
int lastSegmentIndex = 0;
Outer:
while(iter.hasNext()) {
lastSegmentIndex++;
DataSegment dataSegment = (DataSegment) iter.next();
if (lastSegmentIndex < nextSegmentIndex) continue;
newDataSegmentList.add(dataSegment);
while (iter.hasNext()) {
lastSegmentIndex++;
DataSegment dataSegmentNext = (DataSegment) iter.next();
if (absTimeGapSeconds(dataSegment, dataSegmentNext) > getEpsilon()) break Outer; // time gap, quit
newDataSegmentList.add(dataSegmentNext);
dataSegment = dataSegmentNext;
}
}
Waveform wave = (Waveform) clone(); // new Waveform(this); // alias new waveform to this object's references
wave.dataSegmentList = newDataSegmentList; // replace time series data for new waveform
nextSegmentIndex = lastSegmentIndex; // reset offset into this object's time-series data
return wave;
}
/** Returns a Waveform containing the specified sublist of the dataSegments (includes first, excludes last index).
* @exception java.lang.IllegalArgumentException firstIndex > lastIndex
* @exception java.lang.IndexOutOfBoundsException (lastIndex <= firstIndex || lastIndex > size() || firstIndex < 0)
*/
Waveform copyData(int firstIndex, int lastIndex) {
if (lastIndex <= firstIndex || lastIndex > dataSegmentList.size() || firstIndex < 0)
throw new IndexOutOfBoundsException("Error Waveform.copyData input indices: " + firstIndex + " : " + lastIndex);
// Comment out List specific implementation
/*
// Add selected objects of the contiguous subrange as elements of new list
Waveform wave = (Waveform) this.clone();
wave.nextSegmentIndex = 0;
wave.dataSegmentList.clear();
subList = dataSegmentList.subList(firstIndex, lastIndex));
wave.dataSegmentList.addAll(subList);
*/
Waveform wave = (Waveform) clone(); // new Waveform(this);
wave.dataSegmentList = createDataSegmentCollection(lastIndex - firstIndex);
Iterator iter = dataSegmentList.iterator();
int index = -1;
while(iter.hasNext()) {
index++;
Object dataSegment = iter.next();
if (index < firstIndex) continue;
else if (index == lastIndex) break;
wave.dataSegmentList.add(dataSegment);
}
return wave;
}
/** Returns the exclusive allowable seconds between data segments before a data overlap/gap is declared.
*/
double getEpsilon() {
return (1.0 + TIME_EPSILON)/chan.sampleRate;
}
/** Removes all time series data segments found outside of the time bounds found in the specified TimeWindow.
* @exception java.lang.NullPointerException input parameter null
* @exception WaveformDataException null member time-series segment collection
*/
public boolean trim(TimeWindow tw) {
if (tw == null) throw new NullPointerException("Waveform.trim() null input TimeWindow parameter");
if (dataSegmentList == null) throw new WaveformDataException("Waveform.trim() time-series DataSegment collection null");
Iterator iter = dataSegmentList.iterator();
DataSegment dataSegmentPrevious = null;
while (iter.hasNext()) {
DataSegment dataSegment = (DataSegment) iter.next();
Date endtime = endTime(dataSegment); // Endtime is the time of the last sample in the packet
if (tw.excludes(dataSegment.startTimestamp, endtime)) { // Case 1: Packet completely outside of time window
iter.remove();
}
else if (tw.overlaps(dataSegment.startTimestamp, endtime)) { // Case 2: Packet overlaps with time window
// Need the previous packet to unpack the current packet properly, but ignore it if a time tear exists.
if (dataSegmentPrevious == null || absTimeGapSeconds(dataSegmentPrevious, dataSegment) > getEpsilon())
dataSegmentPrevious = dataSegment;
if ( ! trimPacket(dataSegment, dataSegmentPrevious, tw) ) {
System.err.println( "INFO Waveform.trim(): data segment overlaps time window, continuing to next segment.");
// return false; // disabled packet trimming so don't treat is as error just continue - aww
}
if (dataSegment.numberOfSamples == 0) iter.remove(); // delete current packet from collection if no samples
}
dataSegmentPrevious = dataSegment; // save a reference to last processed data segment
}
return true;
}
/** Return starting time declared for input data segment. */
private static Date startTime(DataSegment dataSegment) {
return new Date((long) dataSegment.getStartTimeSecs());
}
/** Return starting time declared for first data segment of this Waveform.
* @exception NullPointerException null member time-series segment collection
*/
public Date startTime() {
if (dataSegmentList == null) throw new NullPointerException("Waveform.startTime() null DataSegment collection");
return (dataSegmentList.size() > 0) ? startTime((DataSegment) dataSegmentList.iterator().next()) : new Date(0l);
}
/** Return ending time declared for input data segment. */
private Date endTime(DataSegment dataSegment) {
return new Date((long)(1000.*(dataSegment.getStartTimeSecs() + (double)(dataSegment.numberOfSamples - 1)/chan.sampleRate)));
}
/** Return ending time declared for last data segment of this Waveform.
* @exception NullPointerException null member time-series segment collection
*/
public Date endTime() {
if (dataSegmentList == null) throw new NullPointerException("Waveform.endTime() null DataSegment collection");
if (dataSegmentList.size() <= 0) return new Date(0l);
Iterator iter = dataSegmentList.iterator();
Object object = null;
while(iter.hasNext()) {
object = iter.next();
}
return endTime((DataSegment) object);
}
/** Appends specified index and DataSegment.toString() to this.toString() */
private String toString(int index, DataSegment dataSegment) {
StringBuffer sb = new StringBuffer(256);
sb.append(toString());
sb.append("index: ");
sb.append(index);
sb.append(" dataSegment: ");
if (dataSegment == null) sb.append("null");
else sb.append(dataSegment.toString());
return sb.toString();
}
/** Returns String summarizing data member information for the instance. */
public String toString() {
StringBuffer sb = new StringBuffer(128);
sb.append("Waveform channel: ");
if (chan != null) sb.append(chan.toIdString());
else sb.append("null");
sb.append(" recordSize: ");
sb.append(recordSize);
sb.append(" dataFormat: ");
sb.append(dataFormat);
sb.append(" nextSegmentIndex: ");
sb.append(nextSegmentIndex);
sb.append(" #segments: ");
if (dataSegmentList == null) sb.append("null");
else sb.append(dataSegmentList.size());
return sb.toString();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -