Brief description of class still missing. More...
#include <SparseTimeRange.h>
Public Member Functions | |
void | add (const TimeRange &r, bool acceptOverlap=false) |
void | add (const SparseTimeRange &r, bool acceptOverlap=false) |
void | clear () |
SparseTimeRange | hit (const TimeRange &r) const |
SparseTimeRange | hit (const SparseTimeRange &r) const |
SparseTimeRange | intersection (const TimeRange &r) const |
SparseTimeRange | intersection (const SparseTimeRange &r) const |
bool | intersects (const SparseTimeRange &r) const |
bool | intersects (const TimeRange &r) const |
SparseTimeRange | invert (bool infiniteEnds=false) const |
SparseTimeRange | invert (const TimeRange &r) const |
bool | isNull () const |
void | printDebug () const |
TimeRange | range () const |
const QVector< TimeRange > & | ranges () const |
void | remove (const SparseTimeRange &r) |
void | remove (const TimeRange &r) |
void | removeBlocks (double dt) |
void | removeGaps (double dt) |
void | scale (double center, double factor) |
void | shift (double dt) |
SparseTimeRange () | |
SparseTimeRange (const SparseTimeRange &r) | |
SparseTimeRange (const TimeRange &r) | |
void | testIndex () const |
~SparseTimeRange () | |
Protected Member Functions | |
int | index (double t) const |
SparseTimeRange | intersection (int index, const TimeRange &r) const |
int | remove (int &index, const TimeRange &r) |
Brief description of class still missing.
Full description of class still missing
Description of constructor still missing
{ _n2=1; }
: QVector<TimeRange>(r) { _n2=r._n2; }
GeopsyCore::SparseTimeRange::SparseTimeRange | ( | const TimeRange & | r | ) |
{ _n2=1; append(r); }
void GeopsyCore::SparseTimeRange::add | ( | const TimeRange & | r, |
bool | acceptOverlap = false |
||
) |
Add r to this. Overlaps are left as gaps if acceptOverlap is false.
References GeopsyCore::TimeRange::end(), index(), GeopsyCore::TimeRange::lengthSeconds(), GeopsyCore::TimeRange::setEnd(), GeopsyCore::TimeRange::setStart(), GeopsyCore::TimeRange::start(), and TRACE.
Referenced by add(), GeopsyCore::GuralpSignal::addRecord(), GeopsyGui::ChronogramLayer::exportGaps(), GeopsyCore::Signal::setDeltaT(), GeopsyCore::Signal::setNSamples(), GeopsyCore::StationSignals::timeRange(), and ManualPick::~ManualPick().
{ TRACE; if(r.lengthSeconds()==0.0) return; ASSERT(r.start()<r.end()); /* S=start of R E=end of R Trivial cases: (accepting or rejecting overlaps) A. current list is empty just add B. S is after the end of last block just add C. S is at the end of last block set end of last block to E Normal cases: i-1 i i+1 -----S ----- ----- A ----- S ----- ----- B ----- S----- ----- C ----- --S-- ----- D Case A can be reduced to case B, if we remove first block and R is merged with first block. Accepting overlaps: Case B: i-1 i i+1 ----- S E ----- ----- O:B:A insert R and return ----- S E----- ----- O:B:B set i start to S and return ----- S --E-- ----- O:B:C set i start to S and return ----- S -----E ----- O:B:D set i start to S and return ----- S ----- E ----- O:B:E remove i, loop over i Case C: i-1 i i+1 ----- S--E-- ----- O:C:A return ----- S-----E ----- O:C:B return ----- S----- E ----- O:C:C remove i, loop over i Case D: i-1 i i+1 ----- --SE- ----- O:D:A return ----- --S--E ----- O:D:B return ----- --S-- E ----- O:D:C remove i, set S to i start, loop over i Rejecting overlaps: Case B: i-1 i i+1 ----- S E ----- ----- o:B:A insert R and return ----- S E----- ----- o:B:B set i start to S and return ----- S --E-- ----- o:B:C insert block from S to i start, set i start to E and return ----- S -----E ----- o:B:D set i start to S, i end to i start and return ----- S ----- E ----- o:B:E set i start to S, i end to i start, set S to i end, loop over i Case C: i-1 i i+1 ----- S--E-- ----- o:C:A set i start to E and return ----- S-----E ----- o:C:B remove i and return ----- S----- E ----- o:C:C remove i, set S to i end, loop over i Case D: i-1 i i+1 ----- --SE- ----- o:D:A set i end to S, insert R modified from E to i end and return ----- --S--E ----- o:D:B set i end to S and return ----- --S-- E ----- o:D:C set i end to S, set S to i end, loop over i Block i+1 is disregarded in all cases. It is considered only when performing a loop over i. Last cases (*:B:E, *:C:C and *:D:C) assume only that E is larger than i end. */ // Trivial cases if(isEmpty()) { append(r); // Trivial case A return; } int i=index(r.start()); if(i==count()-1) { double t=at(i).end()*_relPrec; if(r.start()>t) { append(r); // Trivial case B return; } else if(r.start()<t && at(i).end()<r.start()*_relPrec) { // start~=last end operator[](i).setEnd(r.end()); // Trivial case C return; } } TimeRange rm(r); // Case reduction A to B if(i>0 && rm.start()<at(i-1).end()*_relPrec) { // rm.start()~=at(i).end() rm.setStart(at(i-1).start()); remove(i-1); i--; } if(acceptOverlap) { for( ;i<count();) { TimeRange& cur=operator[](i); if(rm.start()*_relPrec<cur.start()) { if(rm.end()*_relPrec<cur.start()) { insert(i, rm); // Case O:B:A return; } else if (rm.end()<cur.end()*_relPrec) { cur.setStart(rm.start()); // Cases O:B:B to O:B:D return; } else { remove(i); // Case O:B:E } } else if(rm.start()<cur.start()*_relPrec) { if(rm.end()<cur.end()*_relPrec) { return; // Cases O:C:A and O:C:B } else { remove(i); // Case O:C:C } } else { if(rm.end()<cur.end()*_relPrec) { return; // Cases O:D:A and O:D:B } else { rm.setStart(cur.start()); remove(i); // Case O:C:C } } } } else { for( ;i<count();) { TimeRange& cur=operator[](i); if(rm.start()*_relPrec<cur.start()) { double t=rm.end()*_relPrec; if(t<cur.start()) { insert(i, rm); // Case o:B:A return; } else if (t<cur.end()) { if(rm.end()<cur.start()*_relPrec) { cur.setStart(rm.start()); // Case o:B:B return; } else { double t=cur.start(); // Case o:B:C cur.setStart(rm.end()); rm.setEnd(t); insert(i, rm); return; } } else if(rm.end()<cur.end()*_relPrec) { double t=cur.start(); // Case o:B:D cur.setStart(rm.start()); cur.setEnd(t); return; } else { double t=cur.start(); // Case o:B:E cur.setStart(rm.start()); rm.setStart(cur.end()); cur.setEnd(t); i++; } } else if(rm.start()<cur.start()*_relPrec) { if(rm.end()<cur.end()*_relPrec) { if(rm.end()*_relPrec<cur.end()) { cur.setStart(rm.end()); // Case o:C:A return; } else { remove(i); // Case o:C:B return; } } else { rm.setStart(cur.end()); remove(i); // Case o:C:C } } else { if(rm.end()<cur.end()*_relPrec) { if(rm.end()*_relPrec<cur.end()) { double t=rm.end(); // Case o:D:A rm.setEnd(rm.start()); rm.setStart(cur.start()); cur.setStart(t); insert(i, rm); return; } else { cur.setEnd(rm.start()); // Case o:D:B return; } } else { double t=rm.start(); // Case o:D:C rm.setStart(cur.end()); cur.setEnd(t); i++; } } } } append(rm); }
void GeopsyCore::SparseTimeRange::add | ( | const SparseTimeRange & | r, |
bool | acceptOverlap = false |
||
) |
void GeopsyCore::SparseTimeRange::clear | ( | ) |
Referenced by GeopsyCore::Signal::setDeltaT(), and GeopsyCore::Signal::setNSamples().
{ QVector<TimeRange>::clear(); _n2=1; }
SparseTimeRange GeopsyCore::SparseTimeRange::hit | ( | const TimeRange & | r | ) | const |
Returns all time ranges of this hit by r.
References GeopsyCore::TimeRange::intersects(), and TRACE.
{ TRACE; SparseTimeRange res; for(const_iterator it=begin(); it!=end(); it++) { if(r.intersects(*it)) { res.append(*it); } } return res; }
SparseTimeRange GeopsyCore::SparseTimeRange::hit | ( | const SparseTimeRange & | r | ) | const |
Returns all time ranges of this hit by r.
References intersects(), and TRACE.
{ TRACE; SparseTimeRange res; for(const_iterator it=begin(); it!=end(); it++) { if(r.intersects(*it)) { res.append(*it); } } return res; }
int GeopsyCore::SparseTimeRange::index | ( | double | t | ) | const [protected] |
Returns the index of the time range that ends after t. If t is less than the end of first range, 0 is returned. If t is greater or equal to the start of last range, count()-1 is returned.
References TRACE.
Referenced by add(), GeopsyCore::SparseKeepSignal::intersection(), intersection(), invert(), GeopsyCore::SparseKeepSignal::keeps(), remove(), GeopsyCore::SparseKeepSignal::remove(), GeopsyCore::SparseKeepSignal::setSampling(), and testIndex().
{ TRACE; t*=_relPrec; // Shift a little bit by time precision if(t<at(0).end()) { // t<at(0).end() return 0; } int lasti=count()-1; if(t>=at(lasti).start()) { // t>=at(lasti).start() return lasti; } int i=_n2; int step2=i >> 1; while(step2>0) { if(i>lasti) i-=step2; else if(t<at(i).end()) { // t<at(i).end() if(t>=at(i-1).end()) break; // t>=at(i-1).end() i-=step2; } else { i+=step2; } step2=step2 >> 1; } //ASSERT(i<=lasti); return i; }
SparseTimeRange GeopsyCore::SparseTimeRange::intersection | ( | const TimeRange & | r | ) | const [inline] |
Reimplemented in GeopsyCore::SparseKeepSignal.
References index(), and GeopsyCore::TimeRange::start().
Referenced by RealTimeArrayManager::createTasks(), GeopsyGui::SignalLayer::drawGaps(), GeopsyGui::ChronogramLayer::exportGaps(), GeopsyCore::SparseKeepSignal::intersection(), intersection(), intersects(), GeopsyGui::ChronogramLayer::paintData(), GeopsyGui::ChronogramLayer::rangeUpdate(), GeopsyCore::Signal::setTimeRange(), and GeopsyCore::StationSignals::timeRange().
{ if(isEmpty()) return *this; return intersection(index(r.start()), r); }
SparseTimeRange GeopsyCore::SparseTimeRange::intersection | ( | const SparseTimeRange & | r | ) | const |
Returns the intersection between this and r.
References intersection(), and TRACE.
{ TRACE; SparseTimeRange res; for(const_iterator it=r.begin();it!=r.end();it++) { SparseTimeRange tmp=intersection(*it); // We can append directly (without add()) because *it are already sorted // and not continuous for(iterator itRes=tmp.begin();itRes!=tmp.end();itRes++) { res.append(*itRes); } } return res; }
SparseTimeRange GeopsyCore::SparseTimeRange::intersection | ( | int | index, |
const TimeRange & | r | ||
) | const [protected] |
References GeopsyCore::TimeRange::end(), GeopsyCore::TimeRange::setEnd(), GeopsyCore::TimeRange::setStart(), GeopsyCore::TimeRange::start(), and TRACE.
{ TRACE; SparseTimeRange res; if(r.end()<at(i).start()*_relPrec || r.start()*_relPrec>at(i).end()) return res; for(;i<count() && at(i).end()<r.end();i++) { res.append(at(i)); } // Add the last block that had its end after r.end() but can have a start() before. if(i<count() && at(i).start()<r.end()) { res.append(at(i)); } if(!res.isEmpty()) { TimeRange& resStart=res.first(); if(resStart.start()<r.start()) { resStart.setStart(r.start()); } TimeRange& resEnd=res.last(); if(resEnd.end()>r.end()) { resEnd.setEnd(r.end()); } } return res; }
bool GeopsyCore::SparseTimeRange::intersects | ( | const SparseTimeRange & | r | ) | const [inline] |
References intersection().
Referenced by hit().
{ SparseTimeRange res=intersection(r); return !res.isEmpty(); }
bool GeopsyCore::SparseTimeRange::intersects | ( | const TimeRange & | r | ) | const [inline] |
References intersection().
{ SparseTimeRange res=intersection(r); return !res.isEmpty(); }
SparseTimeRange GeopsyCore::SparseTimeRange::invert | ( | bool | infiniteEnds = false | ) | const |
References TRACE.
Referenced by GeopsyGui::SignalLayer::drawGaps(), GeopsyGui::ChronogramLayer::exportGaps(), and GeopsyGui::ChronogramLayer::paintData().
{ TRACE; SparseTimeRange res; int n=count(); if(n>0) { if(infiniteEnds) { res.append(TimeRange(-1e99, at(0).start())); } for(int i=1; i<n; i++) { res.append(TimeRange(at(i-1).end(), at(i).start())); } if(infiniteEnds) { res.append(TimeRange(at(n-1).end(), 1e99)); } } return res; }
SparseTimeRange GeopsyCore::SparseTimeRange::invert | ( | const TimeRange & | r | ) | const |
References GeopsyCore::TimeRange::end(), index(), GeopsyCore::TimeRange::start(), and TRACE.
{ TRACE; SparseTimeRange res; if(isEmpty()) { res.append(r); } else { int i=index(r.start()); if(at(i).start()>r.start()*_relPrec) { res.append(TimeRange(r.start(), at(i).start())); } for(i++;i<count() && at(i).end()<r.end();i++) { res.append(TimeRange(at(i-1).end(), at(i).start())); } if(i<count()) { // Add the last gap res.append(TimeRange(at(i-1).end(), at(i).start())); } else if(at(i-1).end()*_relPrec<r.end()) { res.append(TimeRange(at(i-1).end(), r.end())); } } return res; }
bool GeopsyCore::SparseTimeRange::isNull | ( | ) | const [inline] |
Referenced by GeopsyCore::SparseKeepSignal::keeps().
{return QVector<TimeRange>::isEmpty();}
void GeopsyCore::SparseTimeRange::printDebug | ( | ) | const |
Reimplemented in GeopsyCore::SparseKeepSignal.
References TRACE.
Referenced by RealTimeArrayManager::createTasks(), and GeopsyCore::SparseKeepSignal::printDebug().
{ TRACE; int n=count(); if(n>0) { printf("%i sub-ranges from %s to %s (n2=%i)\n", n, Number::secondsToTime(first().start()).toAscii().data(), Number::secondsToTime(last().end()).toAscii().data(), _n2); for(int i=0; i<n; i++) { printf(" sub-range %i from %s to %s\n", i, Number::secondsToTime(at(i).start()).toAscii().data(), Number::secondsToTime(at(i).end()).toAscii().data()); } } else { printf("no sub-ranges\n"); } }
TimeRange GeopsyCore::SparseTimeRange::range | ( | ) | const [inline] |
Referenced by GeopsyCore::Signal::cut(), StructureStationSignals::organizeSubPool(), Process::run(), ArrayCore::ArrayProcess::setFrequency(), GeopsyCore::StationSignals::setKeep(), GeopsyCore::StationSignals::setSampling(), and GeopsyCore::Signal::setTimeRange().
{ if(isEmpty()) return TimeRange(); else return TimeRange(first().start(), last().end()); }
const QVector<TimeRange>& GeopsyCore::SparseTimeRange::ranges | ( | ) | const [inline] |
void GeopsyCore::SparseTimeRange::remove | ( | const SparseTimeRange & | r | ) |
Removes all ranges that overlap with r
References TRACE.
Referenced by GeopsyGui::ChronogramLayer::paintData(), and remove().
{ TRACE; for(const_iterator it=r.begin(); it!=r.end(); it++) { remove(*it); } }
void GeopsyCore::SparseTimeRange::remove | ( | const TimeRange & | r | ) | [inline] |
Removes all ranges that overlap with r
Reimplemented in GeopsyCore::SparseKeepSignal.
References index(), and GeopsyCore::TimeRange::start().
{ if(!isEmpty()) { int i=index(r.start()); remove(i, r); } }
int GeopsyCore::SparseTimeRange::remove | ( | int & | index, |
const TimeRange & | r | ||
) | [protected] |
index must be the index of the time range that ends after the start of r. Compute it with index(). index is increased by one only if there are removed ranges and if the first range is cut (used only by SparseKeepSignal).`
References GeopsyCore::TimeRange::end(), remove(), GeopsyCore::TimeRange::setEnd(), GeopsyCore::TimeRange::setStart(), GeopsyCore::TimeRange::start(), and TRACE.
{ TRACE; TimeRange& rStart=operator[](index); if(r.start()>rStart.start() && r.start()<rStart.end()) { rStart.setEnd(r.start()); index++; } int nRemoved=0; if(index<count() && r.start()<at(index).start()*_relPrec) { double tEnd=r.end()*_relPrec; for(int i=index;i<count() && at(i).end()<tEnd;i++) { nRemoved++; } QVector<TimeRange>::remove(index, nRemoved); int lowerN2=_n2 >> 1; while(count()<lowerN2) { _n2=lowerN2; lowerN2=_n2 >> 1; } } if(index<count()) { TimeRange& rEnd=operator[](index); if(r.end()>rEnd.start() && r.end()<rEnd.end()) { rEnd.setStart(r.end()); } } return nRemoved; }
void GeopsyCore::SparseTimeRange::removeBlocks | ( | double | dt | ) |
Removes all blocks smaller than dt seconds
References GeopsyCore::TimeRange::lengthSeconds(), and TRACE.
Referenced by GeopsyGui::ChronogramLayer::paintData().
{ TRACE; if(dt<=0.0) return; for(int i=count()-1; i>=0; i--) { TimeRange& r=operator[](i); if(r.lengthSeconds()<dt) { remove(i); } } }
void GeopsyCore::SparseTimeRange::removeGaps | ( | double | dt | ) |
Removes all gaps smaller than dt seconds
References GeopsyCore::TimeRange::end(), GeopsyCore::TimeRange::setEnd(), GeopsyCore::TimeRange::start(), and TRACE.
Referenced by GeopsyGui::ChronogramLayer::exportGaps(), and GeopsyGui::ChronogramLayer::paintData().
{ TRACE; if(dt<=0.0) return; for(int i=count()-2;i>=0;i--) { TimeRange& r1=operator[](i); const TimeRange& r2=at(i+1); if(r2.start()-r1.end()<dt) { r1.setEnd(r2.end()); remove(i+1); } } }
void GeopsyCore::SparseTimeRange::scale | ( | double | center, |
double | factor | ||
) |
References TRACE.
Referenced by GeopsyCore::Signal::setDeltaT().
{ TRACE; ASSERT(factor>0.0); for(int i=count()-1;i>=0;i--) { operator[](i).scale(center, factor); } }
void GeopsyCore::SparseTimeRange::shift | ( | double | dt | ) |
References TRACE.
Referenced by GeopsyCore::Signal::setT0(), and GeopsyCore::GuralpSignal::timeRange().
{ TRACE; for(int i=count()-1;i>=0;i--) { operator[](i).shift(dt); } }
void GeopsyCore::SparseTimeRange::testIndex | ( | ) | const |
For all ranges, checks returned index for start, middle and end points.
References index(), and TRACE.
{ TRACE; int n=count(), i; for(i=0; i<n-1; i++) { ASSERT(index( at(i).start())==i); ASSERT(index( 0.5 * (at(i).start() + at(i).end()) )==i); ASSERT(index( at(i).end())==i+1); } ASSERT(index( at(i).start())==i); ASSERT(index( 0.5 * (at(i).start() + at(i).end()) )==i); ASSERT(index( at(i).end())==i); }