-
Notifications
You must be signed in to change notification settings - Fork 10
Open
Description
If the time window is small and gaps are long, a real-time display will crush.
I think it would be better to allow merging of segments, or even merge when adding a new segment.
Here are two functions that might be used for that. I'm not using the pull request since it's in Javascript and I'm not familiar with typescript.
Merging when adding a new segment
function appendSegment(seismogram, newSegment) {
if (!seismogram.segments || seismogram.segments.length === 0) {
seismogram._segmentArray = [newSegment];
return seismogram;
}
const lastSegment = seismogram.segments[seismogram.segments.length - 1];
const sampleInterval = 1000 / lastSegment.sampleRate; // in milliseconds
// Calculate end time of last segment
const lastEndTime = lastSegment.startTime.valueOf() + (lastSegment.y.length - 1) * sampleInterval;
const newStartTime = newSegment.startTime.valueOf();
// Calculate gap
const gap = newStartTime - lastEndTime - sampleInterval;
// If gap is less than half a sample interval, append to last segment
if (gap < sampleInterval / 2) {
// Handle overlap - discard overlapping data from new segment
const timeDiff = newStartTime - lastEndTime - sampleInterval;
let startIndex = 0;
if (timeDiff < 0) {
console.log(`Overlap detected for ${seismogram.codes()}: ${Math.abs(timeDiff)} ms`);
// Overlap exists - calculate how many samples to skip
const overlapSamples = Math.ceil(Math.abs(timeDiff) / sampleInterval);
startIndex = overlapSamples;
}
// Append non-overlapping data for typed arrays
if (startIndex < newSegment.y.length) {
const newData = newSegment.y.slice(startIndex);
const combined = new lastSegment.y.constructor(lastSegment.y.length + newData.length);
combined.set(lastSegment.y, 0);
combined.set(newData, lastSegment.y.length);
lastSegment.y = combined;
}
} else {
// Gap is too large, add as new segment
console.log(`Gap detected for ${seismogram.codes()}: ${gap} ms`);
seismogram._segmentArray.push(newSegment);
}
return seismogram;
}And for merging all segments without gaps or overlays:
function mergeSegments(seismogram) {
if (!seismogram.segments || seismogram.segments.length <= 1) {
return seismogram;
}
// Sort segments by start time
seismogram.segments.sort((a, b) => a.startTime.valueOf() - b.startTime.valueOf());
const mergedSegments = [];
let currentSegment = seismogram.segments[0];
for (let i = 1; i < seismogram.segments.length; i++) {
const nextSegment = seismogram.segments[i];
// Calculate the end time of current segment based on start time, sample rate, and number of samples
const sampleInterval = 1000 / currentSegment.sampleRate; // in milliseconds
const currentEndTime = currentSegment.startTime.valueOf() + (currentSegment.y.length - 1) * sampleInterval;
const nextStartTime = nextSegment.startTime.valueOf();
// Calculate gap in milliseconds
const gap = nextStartTime - currentEndTime - sampleInterval;
// If gap is less than half a sample interval, merge
if (gap < sampleInterval / 2) {
// Handle overlap - keep only non-overlapping data from next segment
const timeDiff = nextStartTime - currentEndTime - sampleInterval;
let startIndex = 0;
if (timeDiff < 0) {
// Overlap exists - calculate how many samples to skip
console.log(`Overlap detected for ${seismogram.codes()}: ${Math.abs(timeDiff)} ms`);
const overlapSamples = Math.ceil(Math.abs(timeDiff) / sampleInterval);
startIndex = overlapSamples;
}
// Concatenate data for typed arrays
if (startIndex < nextSegment.y.length) {
const newData = nextSegment.y.slice(startIndex);
const combined = new currentSegment.y.constructor(currentSegment.y.length + newData.length);
combined.set(currentSegment.y, 0);
combined.set(newData, currentSegment.y.length);
currentSegment.y = combined;
}
// Keep currentSegment for next iteration
} else {
// Gap is too large, save current segment and start new one
console.log(`Gap detected for ${seismogram.codes()}: ${gap} ms`);
mergedSegments.push(currentSegment);
currentSegment = nextSegment;
}
}
// Don't forget the last segment
mergedSegments.push(currentSegment);
seismogram._segmentArray = mergedSegments;
return seismogram;`
}Metadata
Metadata
Assignees
Labels
No labels