All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Public Member Functions | Protected Member Functions
GeopsyCore::SparseTimeRange Class Reference

Brief description of class still missing. More...

#include <SparseTimeRange.h>

Inheritance diagram for GeopsyCore::SparseTimeRange:
QVector GeopsyCore::SparseKeepSignal

List of all members.

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)

Detailed Description

Brief description of class still missing.

Full description of class still missing


Constructor & Destructor Documentation

Description of constructor still missing

{
  _n2=1;
}
    : QVector<TimeRange>(r)
{
  _n2=r._n2;
}
{
  _n2=1;
  append(r);
}

Description of destructor still missing

References TRACE.

{
  TRACE;
}

Member Function Documentation

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 
)

Add r to this. Overlaps are left as gaps if acceptOverlap is false.

References add(), and TRACE.

{
  TRACE;
  int n=r.count();
  for(int i=0; i<n; i++) {
    add(r.at(i), acceptOverlap);
  }
}

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;
}

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;
}

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;
}

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]

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");
  }
}

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;
}

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);
    }
  }
}

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);
  }
}

References TRACE.

Referenced by GeopsyCore::Signal::setT0(), and GeopsyCore::GuralpSignal::timeRange().

{
  TRACE;
  for(int i=count()-1;i>=0;i--) {
    operator[](i).shift(dt);
  }
}

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);
}

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines