📄 wfsegment.java
字号:
seg1.digClipped |= seg2.digClipped;
seg1.spikes |= seg2.spikes;
seg1.glitches |= seg2.glitches;
seg1.badTimeTag |= seg2.badTimeTag;
// precision problems if (seg1.lenSecs != seg1.sampleCount*seg1.dt)
return seg1;
}
/** Return a sub-segment of this segment as defined by the start/stop times.
* If either the start or end time is beyond what is available in the WFSegment
* the returned WFSegment will be limited by the available data. If the
* time window does not overlap the time of this WFSegment an empty WFSegment
* is returned.
*/
public WFSegment getSubSegment(double startTime, double endTime) {
WFSegment newWFseg = new WFSegment(this);
newWFseg.trim(startTime, endTime);
return newWFseg;
}
/** Trim the time in this WFSegment to this range of samples.
* If the lastSample is beyond what is available in the WFSegment
* the trim will be limited by the available data.
*/
public boolean trim (int firstSample, int lastSample) {
int lastData = size() - 1;
if (lastSample > lastData) lastSample = lastData;
int arrayLen = lastSample - firstSample + 1;
float newSample[] = new float[arrayLen] ;
System.arraycopy(ts, firstSample, newSample, 0, arrayLen);
ts = newSample;
scanTimeSeries();
return true;
}
/** Trim the time in this WFSegment to this time window.
* If either the start or end time is beyond what is available in the WFSegment
* the trim will be limited by the available data. If the
* time window does not overlap the time of this WFSegment the WFSegment is
* left unchanged and 'false' is returned.
*/
public boolean trim (double startTime, double endTime) {
// no overlap
if (startTime > getEpochEnd() || endTime < getEpochStart()) return false;
int firstSamp = sampleIndexAtTime(startTime);
int lastSamp = sampleIndexAtTime(endTime);
if (firstSamp == -1) {
firstSamp = 0;
} else {
setStart(startTime);
}
if (lastSamp == -1) {
lastSamp = ts.length;
} else {
setEnd(endTime);
}
return trim(firstSamp, lastSamp);
}
/**
* Convert a Collection of WFSegments to an Array.
*/
public static WFSegment[] getArray(Collection segList)
{
if (segList.size() == 0) return (null); // no segments
WFSegment segArray[] = new WFSegment[segList.size()];
return (WFSegment[]) segList.toArray(segArray);
}
/**
* Return the Sample with the maximum amplitude in the waveform segment.
* "Maximum" value could be
* the largest excursion downward. Bias is NOT removed because segments may be
* short.
* Because of large biases even "positive" peak
* would be a negative number. Returns 'null' if no time-series.
*/
public Sample getPeakSample () {
return getPeakSample(getEpochStart(), getEpochEnd());
}
/**
* Return the Sample with the maximum amplitude in the waveform segment.
* "Maximum" value could be the largest excursion downward. Bias is NOT
* removed because segments may beshort.
* Because of large biases even "positive" peak
* would be a negative number. Returns 'null' if no time-series, time period is
* not in this segment or the time bounds are inverted (start > end).
*/
public Sample getPeakSample (double startTime, double endTime) {
if (startTime > endTime || // inverted time
!hasTimeSeries() || // no time series
!getTimeSpan().overlaps(startTime, endTime)) return null;
// determine start & end sample indexes with sanitiy checks
int startSample = sampleIndexAtTime(startTime);
if (startSample < 0) startSample = 0;
int endSample = sampleIndexAtTime(endTime);
if (endSample < 0 || endSample > (size()-1)) endSample = size()-1;
if (startSample == endSample) return sampleAtIndex(startSample);
float comp = Math.abs(ts[startSample]);
int sampNo = startSample;
for (int i = startSample + 1; i <= endSample; i++) {
if ( Math.abs(ts[i]) > comp) {
sampNo = i;
comp = Math.abs(ts[i]);
}
}
return sampleAtIndex(sampNo);
}
/**
* Return the Sample with the largest absolute amplitude in the waveform segment.
* Because of large biases even "positive" peak would be a negative number.
* Returns 'null' if no time-series.
*/
public Sample getMaxSample () {
if (!hasTimeSeries()) return (null); // no time series
if (maxSample == null) { // only calculate on 1st request
int sampNo = 0;
double comp = ts[0];
for (int i = 1; i < size(); i++) {
if ( ts[i] > comp) {
sampNo = i;
comp = ts[i];
}
}
// maxSample = new Sample (getEpochStart() + (sampNo * dt), ts[sampNo]);
maxSample = sampleAtIndex(sampNo);
}
return maxSample;
} // end of getMaxAmp
/**
* Return the Sample with the smallest absolute amplitude in the waveform segment.
*/
public Sample getMinSample () {
if (!hasTimeSeries()) return null; // no time series
if (minSample == null) { // only calculate on 1st request
int sampNo = 0;
double comp = ts[0];
for (int i = 1; i < size(); i++) {
if ( ts[i] < comp) {
sampNo = i;
comp = ts[i];
}
}
// minSample = new Sample (tstart + (sampNo * dt), ts[sampNo]);
minSample = sampleAtIndex(sampNo);
}
return minSample;
} // end of getMinAmp
/**
* Calculate the background noise level. It is
* the median of the peaks between zero-crossings for a rectified time-series
* with the bias removed for the whole time-series.
* Returns Float.NaN if it cannot be calculated.
*/
public float scanForNoiseLevel () {
return scanForNoiseLevel(getEpochStart(), getEpochEnd());
}
/**
* Calculate the background noise level. Sets value of 'noiseLevel'. It is
* the median of the peaks between zero-crossings for a rectified time-series
* with the bias removed for the time window given.
* Returns Float.NaN if it cannot be calculated.
*/
public float scanForNoiseLevel (double startTime, double endTime) {
if (!hasTimeSeries() || // no time series
!getTimeSpan().overlaps(startTime, endTime)) return Float.NaN;
int startSample = sampleIndexAtTime(startTime);
if (startSample == -1) startSample = 0;
int endSample = sampleIndexAtTime(endTime);
if (endSample == -1) endSample = size()-1;
float bias = getBias();
float samp;
float lastSamp = ts[startSample]-bias;
float peak = Math.abs(lastSamp);
double sumPeak = peak;
int npeak = 1;
for (int i = startSample + 1; i <= endSample; i++) {
// remove bias
samp = ts[i]-bias;
// same sign :. not a zero crossing, search for peak
if ( (lastSamp>0.0f) == (samp>0.0f) ) {
peak = Math.max(peak, Math.abs(samp));
// sign changed :. a zero crossing!
} else {
sumPeak += peak;
npeak++;
peak = Math.abs(samp);
}
lastSamp = samp;
}
noiseLevel = (float) (sumPeak/npeak);
// System.out.println ( "scan noise: noiseLevel npeak "+ noiseLevel +" "+npeak);
return noiseLevel;
}
/** Filter this time series in place. */
public void filter(FilterIF filter) {
if (!hasTimeSeries()) return;
filter.filter(ts); // pass float[] of timeseries
scanTimeSeries(); // recalc max, min, bias
}
/** Scan for bias, max and min. This should be done after any operation
* that modifies the timeseries. */
public void scanTimeSeries () {
biasVal = NULL;
maxSample = null;
minSample = null;
getBias();
getMaxSample();
getMinSample();
}
/**
* Return the bias of the waveform segment
*/
public float getBias () {
if (!hasTimeSeries()) { return 0; } // no time series
if (biasVal == NULL) { // only calculate on 1st request
double sum = 0.0;
for (int i = 0; i < size(); i++) {
sum += ts[i];
}
biasVal = (float) (sum / size());
}
return biasVal;
} // end of bias
/**
* Dump some WFSegment info for debugging
*/
public void dump ()
{
System.out.println (
" rec = " + rec + " " +
" source = " + source + " " +
" nsamps = " + size() + " " +
" secs = " + getDuration() + " " +
" fmt = " + fmt );
System.out.println ( " filename = " + filename );
System.out.println ( " timespan = " + getTimeSpan().toString());
}
/**
* Dump some WFSegment info for debugging
*/
public String dumpToString ()
{
return toString();
}
/**
* Dump some WFSegment info for debugging
*/
public String toString ()
{
String str = "chan = "+ getChannelObj().toString() +
" rec = " + rec + " " +
" source = " + source + " " +
// " sampleCount = " + sampleCount + " " +
" size = " + size() + " " +
" lenSecs = " + getDuration() + " " +
" dt = " + getSampleInterval() +
" fmt = " + fmt + "\n";
str += " filename = " + filename +
" bytesPerSample = "+ bytesPerSample+"\n";
if (maxSample != null) str += " maxAmp = " + maxSample.value;
if (minSample != null) str += " minAmp = " + minSample.value;
str += " clockLocked = "+ clockLocked +
" ampSaturated = " + ampSaturated +
" digClipped = " + digClipped +
" spikes = " + spikes +
" glitches = " + glitches +
" badTimeTag = " + badTimeTag +
" timeQual = "+ getTimeQuality()+"\n";
str += " timespan = " + getTimeSpan().toString() + "\n";
return str;
}
} // end of WFSegment class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -