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

A signal with samples in double precision with metadata (name, coordinates,...) More...

#include <Signal.h>

Inheritance diagram for GeopsyCore::Signal:
GeopsyCore::DoubleSignal QGpCoreTools::SharedObject QGpCoreTools::XMLClass GeopsyCore::SignalTemplate< double > CacheItem GeopsyCore::DynamicSignal

List of all members.

Public Types

enum  AmplitudeUnits {
  UndefinedUnit, Displacement, Velocity, Acceleration,
  CustomUnit
}
enum  Components {
  Vertical, North, East, All,
  Horizontal, UndefinedComponent
}
enum  PickWhat { Min = 1, Max = 2 }

Public Member Functions

int add (const Signal *sig, const TimeRange &tw, bool checkInvalid=false, double invalidValue=1e99)
void addMetaData (MetaData *d)
double amplitudeAt (double abscissa) const
AmplitudeUnits amplitudeUnit () const
QString amplitudeUnitStandardName () const
QString amplitudeUnitUserName () const
double averageAmplitude (int itmin=0, int itmax=0) const
int byteIncrement () const
QString comments () const
int compare (const Signal &o) const
Components component () const
QString componentStandardName () const
QString componentUserName () const
virtual const double * constLockSamples () const
const double * constLockSamples (char *file, int line) const
void copyBasicProperties (const Signal &p)
void copySamplesFrom (const Signal *sig)
void copySamplesFrom (const Signal *sig, const TimeRange &tw)
double correlation (const Signal *sig, const TimeRange &tw)
void correlation (const Signal *s1, const Signal *s2, double maxDelay)
double countPerUnit () const
double countPerVolt () const
Signalcut (TimeRange r) const
SignalDBdatabase () const
virtual QString debugName () const
QString effectiveAmplitudeUnit () const
double endTime () const
TIME endTimeAsTIME () const
SignalFilefile () const
const GuralpRecordsguralpRecords () const
bool hasMetaData (int id) const
QVariant header (const MetaDataIndex &index) const
int id () const
bool isHeaderModified () const
bool isOriginalFile () const
bool isReadOnlySamples () const
virtual double * lockSamples ()
double * lockSamples (char *file, int line)
double maximumAmplitude (int itmin=0, int itmax=0) const
double maximumAmplitudeAt (const TimeRange &r=TimeRange()) const
MetaDatametaData (int id)
const MetaDatametaData (int id) const
const MetaDataMapmetaDataMap () const
const MiniSeedRecordsminiSeedRecords () const
QString name () const
QString nameComponent () const
void normalizedCorrelation (const Signal *s1, const Signal *s2, double maxDelay)
int numberInFile () const
int offsetInFile () const
bool operator< (const Signal &o) const
bool operator== (const Signal &o) const
bool operator> (const Signal &o) const
void pickCoppens (const QString &pickName, double delta, double end, double start=0., bool relative=false, double mute=0.)
void pickMinMax (const QString &pickName, double from, double to, PickWhat what)
bool read (FILE *f, SignalDB *db)
const Pointreceiver () const
void removeMetaData (int id)
void resetAmplitudes () const
double roundTimePick (const QString &name) const
void setAmplitudeUnit (AmplitudeUnits u)
void setByteIncrement (int i)
void setComments (QString c)
void setComponent (Components c)
void setCountPerVolt (double c)
void setDatabase (SignalDB *db)
virtual void setDeltaT (double newval)
void setFile (SignalFile *f)
void setGuralpRecords (const GuralpRecords &r)
bool setHeader (const MetaDataIndex &index, QVariant val)
void setHeaderModified (bool m)
void setId (int id)
void setMiniSeedRecords (const MiniSeedRecords &r)
void setName (QString n)
virtual void setNSamples (int n)
void setNumberInFile (int i)
void setOffsetInFile (int o)
void setReadOnlySamples (bool ro)
void setReceiver (const Point &p)
void setSource (const Point &p)
void setT0 (double t)
void setTemporary ()
void setTimePick (const QString &name, double time)
void setTimeRange (const SparseTimeRange &r)
void setTimeReference (QDateTime t)
void setTimeReference (QString t)
void setUnitPerVolt (double c)
void setVoltPerCount (double c)
void setVoltPerUnit (double c)
 Signal (SignalDB *db)
 Signal (const Signal &sig, SignalDB *db=0)
const Pointsource () const
double sourceReceiverAzimuth () const
double sourceReceiverDistance () const
double t0 () const
TIME t0AsTIME () const
bool taper (const TimeRange &tw, const TaperParameters &param)
double timePick (const QString &name) const
int timePickCount () const
const SparseTimeRangetimeRange () const
QDateTime timeReference () const
QString timeReferenceString () const
double unitPerCount () const
double unitPerVolt () const
double voltPerCount () const
double voltPerUnit () const
bool warnReadOnlySamples () const
bool writeAscii (QFile &f, int numInFile) const
bool writeGse (QFile &f) const
bool writeMiniSeed (QFile &f) const
bool writeSac (QDataStream &s) const
bool writeSeg2 (QFile &f) const
bool writeSegySu (QDataStream &s, int indexInFile, bool su) const
virtual XMLMember xml_member (XML_MEMBER_ARGS)
virtual bool xml_setProperty (XML_SETPROPERTY_ARGS)
virtual const QString & xml_tagName () const
virtual void xml_writeChildren (XML_WRITECHILDREN_ARGS) const
virtual void xml_writeProperties (XML_WRITEPROPERTIES_ARGS) const
virtual ~Signal ()

Static Public Member Functions

static QString componentLetter (Components c)
static Components globalSeismographicNetworkComponent (const char *c)
static SignalnewCopy (Signal *sig)
static AmplitudeUnits standardAmplitudeUnit (QString u)
static Components standardComponent (QString c)
static QString standardName (Components c)
static QString standardName (AmplitudeUnits u)
static AmplitudeUnits userAmplitudeUnit (QString u)
static Components userComponent (QString c)
static QString userName (Components c)
static QString userName (AmplitudeUnits u)

Static Public Attributes

static const QString xmlSignalTag = "Signal"

Protected Attributes

QMutex _amplitudeMutex
double _averageAmplitude
uint _isHeaderModified:1
uint _isReadOnlySamples:1
double _maxAmplitude
double _t0
SparseTimeRange _timeRange
uint _unused:30

Detailed Description

A signal with samples in double precision with metadata (name, coordinates,...)


Member Enumeration Documentation

Enumerator:
UndefinedUnit 
Displacement 
Velocity 
Acceleration 
CustomUnit 
Enumerator:
Vertical 
North 
East 
All 
Horizontal 
UndefinedComponent 
Enumerator:
Min 
Max 
{Min=1, Max=2};

Constructor & Destructor Documentation

Construct a signal and add it to database db

References _isHeaderModified, _isReadOnlySamples, _t0, GeopsyCore::SignalDB::addSignal(), resetAmplitudes(), TRACE, Velocity, and Vertical.

Referenced by cut(), and newCopy().

                            :
    DoubleSignal (), SharedObject(), XMLClass(),
    _timeReference(QDate(2000, 1, 1), QTime(0, 0, 0))
{
  TRACE;
  _id=0;
  _t0=0;
  _component=Vertical;
  _countPerVolt=1.0;
  _voltPerUnit=1.0;
  _amplitudeUnit=Velocity;
  _numberInFile=-1;
  _file=0;
  _offsetInFile=0;
  _byteIncrement=0;
  _isReadOnlySamples=false;
  _isHeaderModified=false;
  resetAmplitudes();
  _db=db;
  _db->addSignal(this); // _id is automatically set here
}
GeopsyCore::Signal::Signal ( const Signal p,
SignalDB db = 0 
)

Create a temporary copy of original This signal will be deleted once the last subpool containing it will be deleted. Samples are not copied.

References GeopsyCore::SignalDB::addSignal(), copyBasicProperties(), resetAmplitudes(), setTemporary(), and TRACE.

                                              :
  DoubleSignal (p), SharedObject(), XMLClass()
{
  TRACE;
  copyBasicProperties(p);
  resetAmplitudes();

  if(db)
    _db=db;
  else
    _db=p._db;
  _db->addSignal(this); // _id is automatically set here
  setTemporary();
}

References GeopsyCore::MetaDataMap::clear(), QGpCoreTools::SharedObject::referenceCount(), GeopsyCore::SignalDB::signalDeleted(), and TRACE.

{
  TRACE;
  ASSERT(!_db || referenceCount()<=0); // When the database is deleted, all signals are forced to be deleted.
  _optionalData.clear();
  if(_db) _db->signalDeleted(this);
}

Member Function Documentation

int GeopsyCore::Signal::add ( const Signal sig,
const TimeRange tw,
bool  checkInvalid = false,
double  invalidValue = 1e99 
) [inline]

References GeopsyCore::TimeRange::lengthSeconds(), GeopsyCore::TimeRange::start(), t0(), and TRACE.

Referenced by StructureStationSignals::organizeSubPool(), and GeopsyGui::ChronogramLayer::rangeUpdate().

{
  TRACE;
  return DoubleSignal::add(sig, tw.start() - sig->t0(), tw.start() - t0(), tw.lengthSeconds(),
                               checkInvalid, invalidValue);
}
void GeopsyCore::Signal::addMetaData ( MetaData d) [inline]

Referenced by MatFormat::load().

{_optionalData.add(d);}
double GeopsyCore::Signal::amplitudeAt ( double  abscissa) const [inline]

Returns the amplitude of the signal at time or frequency abscissa (depends upon signal type). The index is rounded to the lowest sample. No interpolation is perfomed.

Reimplemented from GeopsyCore::DoubleSignal.

References _t0, GeopsyCore::DoubleSignal::_type, TRACE, and GeopsyCore::DoubleSignal::Waveform.

Referenced by GeopsyGui::PickLayer::mouseMoveEvent().

{
  TRACE;
  if(_type==Waveform)
    return DoubleSignal::amplitudeAt(abscissa - _t0);
  else
    return DoubleSignal::amplitudeAt(abscissa);
}

Referenced by compare(), and writeSac().

{return _amplitudeUnit;}
QString GeopsyCore::Signal::amplitudeUnitUserName ( ) const [inline]

Referenced by header().

{return userName(_amplitudeUnit);}
double GeopsyCore::Signal::averageAmplitude ( int  itmin = 0,
int  itmax = 0 
) const

Returns the average amplitude and store it in _averageAmplitude if itmin==0 and itmax==nSamples()-1 If itmin==itmax==0, it returns directly _averageAmplitude without re-checking it.

Reimplemented from GeopsyCore::DoubleSignal.

References _amplitudeMutex, _averageAmplitude, and TRACE.

Referenced by GeopsyCore::SignalHeaderObject::averageAmplitude(), compare(), GeopsyGui::SignalLayer::drawSignal(), and header().

{
  TRACE;
  // Better if amplitude mutex is not locked while signal mutex is blocked
  // A special case was encountered with DynamicSignal::set() and a drawing thread active
  // at the same moment.
  if(itmin==0 && itmax==0) {
    QMutexLocker ml(&_amplitudeMutex);
    if(_averageAmplitude!=1e99) return _averageAmplitude;
    itmax=_nSamples-1;
  }
  double v=DoubleSignal::averageAmplitude(itmin, itmax);
  if(itmin <= 0 && itmax >= _nSamples-1) {
    QMutexLocker ml(&_amplitudeMutex);
    _averageAmplitude=v;
  }
  return v;
}
int GeopsyCore::Signal::byteIncrement ( ) const [inline]

Referenced by xml_writeProperties().

{return _byteIncrement;}
QString GeopsyCore::Signal::comments ( ) const [inline]

References metaData(), GeopsyCore::Comments::staticId(), and GeopsyCore::MetaString::value().

Referenced by SignalTableItem::data().

{
  // Comments is always available in MetaDataFactory, hence o is never null
  const Comments * o=static_cast<const Comments *>(metaData(Comments::staticId()));
  return o->value();
}
int GeopsyCore::Signal::compare ( const Signal o) const

References GeopsyCore::MetaDataFactory::AmplitudeUnit, amplitudeUnit(), GeopsyCore::SortKey::at(), GeopsyCore::MetaDataFactory::AverageAmplitude, averageAmplitude(), GeopsyCore::MetaData::compare(), GeopsyCore::MetaDataFactory::Component, component(), GeopsyCore::SortKey::count(), GeopsyCore::MetaDataFactory::CountPerUnit, countPerUnit(), GeopsyCore::MetaDataFactory::CountPerVolt, countPerVolt(), GeopsyCore::MetaDataFactory::DataCount, GeopsyCore::SignalTemplate< double >::dataSizeMb(), GeopsyCore::DoubleSignal::deltaT(), GeopsyCore::MetaDataFactory::DeltaT, GeopsyCore::MetaDataFactory::Dummy, GeopsyCore::DoubleSignal::duration(), GeopsyCore::MetaDataFactory::Duration, GeopsyCore::MetaDataFactory::EndTime, endTime(), file(), GeopsyCore::MetaDataFactory::FileFormat, GeopsyCore::MetaDataFactory::FileName, GeopsyCore::MetaDataFactory::FileNumber, GeopsyCore::SignalDB::filePool(), GeopsyCore::SignalFile::format(), GeopsyCore::MetaDataFactory::HeaderModified, GeopsyCore::MetaDataIndex::id(), GeopsyCore::MetaDataFactory::ID, GeopsyCore::MetaDataIndex::index(), GeopsyCore::SignalFilePool::indexOf(), isHeaderModified(), GeopsyCore::MetaDataFactory::IsOriginalFile, isOriginalFile(), GeopsyCore::MetaDataFactory::MaximumAmplitude, maximumAmplitude(), metaData(), GeopsyCore::SignalFile::name(), GeopsyCore::MetaDataFactory::Name, name(), GeopsyCore::SignalTemplate< double >::nSamples(), GeopsyCore::MetaDataFactory::NSamples, GeopsyCore::MetaDataFactory::NumberInFile, numberInFile(), GeopsyCore::MetaDataFactory::Pointer, receiver(), GeopsyCore::MetaDataFactory::ReceiverX, GeopsyCore::MetaDataFactory::ReceiverY, GeopsyCore::MetaDataFactory::ReceiverZ, GeopsyCore::SortKey::reversed(), SAFE_UNINITIALIZED, GeopsyCore::MetaDataFactory::SampleSize, GeopsyCore::DoubleSignal::samplingFrequency(), GeopsyCore::MetaDataFactory::SamplingFrequency, GeopsyCore::MetaDataFactory::ShortFileName, GeopsyCore::SignalFile::shortName(), SIGNAL_COMPARE, SIGNAL_COMPARE_KERNEL, SIGNAL_COMPARE_STRING, source(), GeopsyCore::MetaDataFactory::SourceReceiverAzimuth, sourceReceiverAzimuth(), GeopsyCore::MetaDataFactory::SourceReceiverDistance, sourceReceiverDistance(), GeopsyCore::MetaDataFactory::SourceReceiverRoughAzimuth, GeopsyCore::MetaDataFactory::SourceX, GeopsyCore::MetaDataFactory::SourceY, GeopsyCore::MetaDataFactory::SourceZ, GeopsyCore::MetaDataIndex::subId(), GeopsyCore::MetaDataFactory::T0, t0(), GeopsyCore::MetaDataFactory::TimeReference, timeReference(), GeopsyCore::SignalFileFormat::toString(), TRACE, GeopsyCore::DoubleSignal::type(), GeopsyCore::MetaDataFactory::Type, GeopsyCore::MetaDataFactory::UnitPerCount, unitPerCount(), GeopsyCore::MetaDataFactory::UnitPerVolt, unitPerVolt(), GeopsyCore::MetaDataFactory::VoltPerCount, voltPerCount(), GeopsyCore::MetaDataFactory::VoltPerUnit, voltPerUnit(), and QGpCoreTools::XMLClass::xml_tagName().

Referenced by ToolLinearFKActive::initStations(), and ShotRecord::organizeSubPool().

{
  TRACE;
#define SIGNAL_COMPARE_KERNEL \
        if(n1 < n2) comp=-1; \
        else if(n1 > n2) comp=1; \
        else continue; \
        break;

#define SIGNAL_COMPARE(type, function) \
      { \
        type n1=function; \
        type n2=o.function; \
        SIGNAL_COMPARE_KERNEL \
      }

#define SIGNAL_COMPARE_STRING(function) \
      { \
        QString n1=function; \
        QString n2=o.function; \
        comp=n1.localeAwareCompare(n2); \
        if(comp==0) continue; \
        break; \
      }

  int n=SortKey::count();
  for(int i=0; i<n; i++) {
    const SortKey& k=SortKey::at(i);
    int comp;
    SAFE_UNINITIALIZED(comp,0);
    // Standard meta data
    if(k.id()<MetaDataFactory::DataCount) {
      switch (k.id()) {
      case MetaDataFactory::ID: SIGNAL_COMPARE(int, id())
      case MetaDataFactory::T0: SIGNAL_COMPARE(double, t0())
      case MetaDataFactory::DeltaT: SIGNAL_COMPARE(double, deltaT())
      case MetaDataFactory::NSamples: SIGNAL_COMPARE(int, nSamples())
      case MetaDataFactory::SourceX: SIGNAL_COMPARE(double, source().x())
      case MetaDataFactory::SourceY: SIGNAL_COMPARE(double, source().y())
      case MetaDataFactory::SourceZ: SIGNAL_COMPARE(double, source().z())
      case MetaDataFactory::ReceiverX: SIGNAL_COMPARE(double, receiver().x())
      case MetaDataFactory::ReceiverY: SIGNAL_COMPARE(double, receiver().y())
      case MetaDataFactory::ReceiverZ: SIGNAL_COMPARE(double, receiver().z())
      case MetaDataFactory::Name: SIGNAL_COMPARE_STRING(name())
      case MetaDataFactory::Type: SIGNAL_COMPARE(int, type())
      case MetaDataFactory::FileNumber: {
          SignalFilePool& filePool=_db ->filePool();
          int n1=filePool.indexOf(file());
          int n2=filePool.indexOf(o.file());
          SIGNAL_COMPARE_KERNEL
        }
      case MetaDataFactory::NumberInFile: SIGNAL_COMPARE(int , numberInFile())
      case MetaDataFactory::TimeReference : SIGNAL_COMPARE(QDateTime , timeReference())
      case MetaDataFactory::FileName: {
          QString n1=file() ? file()->name() : QString::null;
          QString n2=o.file() ? o.file()->name() : QString::null;
          comp=n1.localeAwareCompare(n2);
          if(comp==0) continue;
          break;
        }
      case MetaDataFactory::FileFormat: {
          QString n1=file() ? file()->format().toString() : QString::null;
          QString n2=o.file() ? o.file()->format().toString() : QString::null;
          comp=n1.localeAwareCompare(n2);
          if(comp==0) continue;
          break;
        }
      case MetaDataFactory::ShortFileName: {
          QString n1=file() ? file()->shortName() : QString::null;
          QString n2=o.file() ? o.file()->shortName() : QString::null;
          comp=n1.localeAwareCompare(n2);
          if(comp==0) continue;
          break;
        }
      case MetaDataFactory::Duration: SIGNAL_COMPARE(double, duration())
      case MetaDataFactory::EndTime: SIGNAL_COMPARE(double, endTime())
      case MetaDataFactory::Component: SIGNAL_COMPARE(int, component())
      case MetaDataFactory::MaximumAmplitude: SIGNAL_COMPARE(double, maximumAmplitude())
      case MetaDataFactory::AverageAmplitude: SIGNAL_COMPARE(double, averageAmplitude())
      case MetaDataFactory::IsOriginalFile: SIGNAL_COMPARE(int, isOriginalFile() ? 0 : 1)
      case MetaDataFactory::SamplingFrequency: SIGNAL_COMPARE(double, samplingFrequency())
      case MetaDataFactory::Pointer:
        if(this < &o) comp=-1;
        else if(this > &o) comp=1;
        else continue;
        break;
      case MetaDataFactory::CountPerVolt: SIGNAL_COMPARE(double, countPerVolt())
      case MetaDataFactory::VoltPerCount: SIGNAL_COMPARE(double, voltPerCount())
      case MetaDataFactory::VoltPerUnit: SIGNAL_COMPARE(double, voltPerUnit())
      case MetaDataFactory::UnitPerVolt: SIGNAL_COMPARE(double, unitPerVolt())
      case MetaDataFactory::CountPerUnit: SIGNAL_COMPARE(double, countPerUnit())
      case MetaDataFactory::UnitPerCount: SIGNAL_COMPARE(double, unitPerCount())
      case MetaDataFactory::AmplitudeUnit: SIGNAL_COMPARE(int, amplitudeUnit())
      case MetaDataFactory::SampleSize: SIGNAL_COMPARE(double, dataSizeMb())
      case MetaDataFactory::HeaderModified: SIGNAL_COMPARE(bool, isHeaderModified())
      case MetaDataFactory::SourceReceiverDistance: SIGNAL_COMPARE(double, sourceReceiverDistance())
      case MetaDataFactory::SourceReceiverAzimuth: SIGNAL_COMPARE(double, sourceReceiverAzimuth())
      case MetaDataFactory::SourceReceiverRoughAzimuth: {  // Return equal azimuth if diff less than 90
          if(sourceReceiverDistance()==0.0 || o.sourceReceiverDistance()==0.0) {
            continue;
          } else {
            double n1=sourceReceiverAzimuth();
            double n2=o.sourceReceiverAzimuth();
            if(fabs(n2-n1)<0.5*M_PI || fabs(n2-n1)>1.5*M_PI) continue;
            else if(n1<1.5*M_PI && n1>0.5*M_PI && (n2>1.5*M_PI || n2<0.5*M_PI)) comp=-1;
            else if(n1>M_PI && n2<M_PI) comp=-1;
            else comp=1;
          }
          break;
        }
      case MetaDataFactory::Dummy:      // Not comparable members
      case MetaDataFactory::DataCount:
        continue;
      }
    } else {
      // Optional meta data
      const MetaData * d1=metaData(k.id());
      const MetaData * d2;
      if(d1) {
        d2=o.metaData(k.id());
        ASSERT(d2 && d1->xml_tagName()==d2->xml_tagName());
      } else {
        continue;
      }
      comp=d1->compare(k.subId(), k.index(), d2);
      if(comp==0) continue;
    }
    if(k.reversed()) {
      return -comp;
    } else {
      return comp;
    }
  }
  return 0;
}

References All, East, Horizontal, North, QGpCoreTools::tr(), TRACE, and Vertical.

Referenced by debugName(), nameComponent(), MapWindow::subPoolUpdate(), and writeSac().

{
  TRACE;
  switch (c) {
  case Vertical:
    return tr("Z");
  case East:
    return tr("E");
  case North:
    return tr("N");
  case All:
    return tr("A");
  case Horizontal:
    return tr("H");
  default:
    return tr("?");
  }
}
QString GeopsyCore::Signal::componentStandardName ( ) const [inline]
QString GeopsyCore::Signal::componentUserName ( ) const [inline]
const double * GeopsyCore::Signal::constLockSamples ( ) const [virtual]

Reimplemented from GeopsyCore::SignalTemplate< double >.

References GeopsyCore::GeopsyCoreEngine::cache(), file(), GeopsyCore::geopsyCore, GeopsyCore::SignalTemplate< double >::isAllocated(), QGpCoreTools::Cache::makeAvailable(), GeopsyCore::SignalTemplate< double >::samples(), and TRACE.

Referenced by GeopsyCore::SubSignalPool::subtractSignal().

{
  TRACE;
  lockData();
  if(isAllocated()) {
    return samples();
  }
  if(isSaved() || !file()) {
    if(geopsyCore->cache()->makeAvailable(this)) {
      return samples();
    } else {
      unlockData();
      return 0;
    }
  }
  if(geopsyCore->cache()->makeAvailable(this)) {
    load(samples());
    return samples();
  } else {
    unlockData();
    return 0;
  }
}
const double* GeopsyCore::Signal::constLockSamples ( char *  file,
int  line 
) const [inline]

References _t0, _timeRange, and TRACE.

Referenced by Signal().

{
  TRACE;
  _timeReference=o._timeReference;
  _t0=o._t0;
  _timeRange=o._timeRange;
  _receiver=o._receiver;
  _source=o._source;
  _name=o._name;
  _component=o._component;
  _countPerVolt=o._countPerVolt;
  _voltPerUnit=o._voltPerUnit;
  _amplitudeUnit=o._amplitudeUnit;
  _optionalData=o._optionalData;
}
void GeopsyCore::Signal::copySamplesFrom ( const Signal sig) [inline]
void GeopsyCore::Signal::copySamplesFrom ( const Signal sig,
const TimeRange tw 
) [inline]

References copySamplesFrom(), GeopsyCore::TimeRange::lengthSeconds(), GeopsyCore::TimeRange::start(), t0(), and TRACE.

{
  TRACE;
  DoubleSignal::copySamplesFrom(sig, tw.start()-sig->t0(), tw.start()-t0(), tw.lengthSeconds());
}
double GeopsyCore::Signal::correlation ( const Signal sig,
const TimeRange tw 
) [inline]

References GeopsyCore::TimeRange::lengthSeconds(), GeopsyCore::TimeRange::start(), t0(), and TRACE.

Referenced by GeopsyCore::SubSignalPool::correlations(), and T0Correlation::value().

{
  TRACE;
  return DoubleSignal::correlation(sig, tw.start() - sig->t0(), tw.start() - t0(), tw.lengthSeconds());
}
void GeopsyCore::Signal::correlation ( const Signal s1,
const Signal s2,
double  maxDelay 
)

Correlates signal s1 to s2 and saves results in this signal. If this signal has the correct number of samples and the correct sampling frequency, the value of this signal are not cleaned and the results are stacked on existing values. If not, the signal is initialized with 0.

References component(), GeopsyCore::DoubleSignal::correlation(), GeopsyCore::DoubleSignal::deltaT(), QGpCoreTools::Point::distanceTo(), QGpCoreTools::endl(), name(), nameComponent(), GeopsyCore::SignalTemplate< double >::nSamples(), receiver(), setComponent(), setName(), setReceiver(), setT0(), GeopsyCore::DoubleSignal::setType(), t0(), QGpCoreTools::tr(), TRACE, UndefinedComponent, and GeopsyCore::DoubleSignal::Waveform.

{
  TRACE;
  if(!DoubleSignal::correlation(s1, s2, maxDelay)) {
    App::stream() << tr("Error calculating correlation between signals %1 and %2, probably an allocation error")
                       .arg(s1->nameComponent()).arg(s2->nameComponent()) << endl;
  }
  // Change t0 according to tw and set x as the interdistance, name is the compound of both name
  // Use the effective maxDelay (given by signal lenght)
  maxDelay=(nSamples()-1)*deltaT()*0.5;
  setT0(-maxDelay+s1->t0()-s2->t0()); // Adjust for differences in T0 (not sure if it is the correct direction)
  setReceiver(Point(s1->receiver().distanceTo(s2->receiver()), 0.0, 0.0));
  if(s1->component()==s2->component()) {
    setName(s1->name() + " & " + s2->name());
    setComponent(s1->component());
  } else {
    setName(s1->nameComponent() + " & " + s2->nameComponent());
    setComponent(UndefinedComponent);
  }
  setType(Waveform);
}
double GeopsyCore::Signal::countPerUnit ( ) const [inline]
double GeopsyCore::Signal::countPerVolt ( ) const [inline]

Creates a new signal on range r. If the range of this signal and r do not match, null is returned. If r limits do not match with signal sampling, range is rounded to first and last sample included in range r.

References copySamplesFrom(), GeopsyCore::DoubleSignal::deltaT(), GeopsyCore::TimeRange::end(), GeopsyCore::TimeRange::intersection(), GeopsyCore::TimeRange::lengthSamples(), GeopsyCore::TimeRange::lengthSeconds(), GeopsyCore::SparseTimeRange::range(), GeopsyCore::TimeRange::setEnd(), setNSamples(), GeopsyCore::TimeRange::setStart(), setT0(), setTimeRange(), Signal(), GeopsyCore::TimeRange::start(), t0(), timeRange(), and TRACE.

Referenced by GeopsyCore::SubSignalPool::cut(), and Process::run().

{
  TRACE;
  // Find the intersection with the this time range
  // rthis has always a limits compatible with sampling
  TimeRange rthis=timeRange().range();
  r=r.intersection(rthis);
  // Adjust start of r to match sig sampling
  double roundedStart=(r.start()-t0())/deltaT();
  if(roundedStart<0.0) {
    r.setStart(t0());
  } else {
    double sampleFrac=roundedStart-floor(roundedStart);
    if(sampleFrac>1e-7) { // 1/10000000 of sampling period precision
      r.setStart(t0()+ceil(roundedStart)*deltaT());
      int n=r.lengthSamples(deltaT());
      if(r.start()+n*deltaT()>r.end()) { // Check if rounding to sampling period passes over the end of range
                               // If so, remove one sample.
        r.setEnd(r.start()+(n-1)*deltaT());
      }
    }
  }
  // If not null, extract the cut signal
  if(r.lengthSeconds()>0.0) {
    Signal * newSig=new Signal(*this);
    newSig->setT0(r.start());
    newSig->setNSamples(r.lengthSamples(deltaT()));
    newSig->setTimeRange(timeRange());
    newSig->copySamplesFrom(this, r);
    return newSig;
  } else {
    return 0;
  }
}
QString GeopsyCore::Signal::debugName ( ) const [inline, virtual]

References componentLetter(), and TRACE.

{
  TRACE;
  return _name + "_" + componentLetter(_component) + QString::number(_id);
}

Returns the name of the units for amplitude depends upon the availability of countPerVolt() and voltPerUnit() (these values must be different than 1).

References Acceleration, CustomUnit, Displacement, QGpCoreTools::tr(), TRACE, UndefinedUnit, and Velocity.

Referenced by SignalViewer::setSignals(), and GraphicWindow::updateLabels().

{
  TRACE;
  if(_voltPerUnit!=1.0) {
    switch (_amplitudeUnit) {
    case UndefinedUnit:
      return QObject::tr("Undefined");
    case Displacement:
      return QObject::tr("m");
    case Velocity:
      return QObject::tr("m/s");
    case Acceleration:
      return QObject::tr("m/s^2");
    case CustomUnit:
      return QObject::tr("Custom unit");
    }
  } else if(_countPerVolt!=1.0) {
    return QObject::tr("Volts");
  }
  return QObject::tr("Counts");
}
double GeopsyCore::Signal::endTime ( ) const [inline]
{return DateTime::capAddSecs(_timeReference, endTime());}
SignalFile* GeopsyCore::Signal::file ( ) const [inline]

is a tree-letter code from Global Seismographic Network naming convention for recording channels. This code is based on Seed manual appendix A (http://www.iris.edu/manuals/SEED_appA.htm).

If a geopsy component can be deduced, returned value is something else than UndefinedComponent.

References East, North, TRACE, UndefinedComponent, and Vertical.

{
  TRACE;
  if(strlen(c)!=3) {
    return UndefinedComponent;
  }
  // First letter, Band Code
  switch(c[0]) {
  case 'F': //                               sample rate=[1000, 5000[ Hz, corner period >= 10 sec
  case 'G': //                               sample rate=[1000, 5000[ Hz, corner period < 10 sec
  case 'D': //                               sample rate=[250, 1000[ Hz, corner period >= 10 sec
  case 'C': //                               sample rate=[250, 1000[ Hz, corner period < 10 sec
  case 'E': // Extremely Short Period        sample rate=[80, 250[ Hz, corner period < 10 sec
  case 'S': // Short Period                  sample rate=[10, 80[ Hz, corner period < 10 sec
  case 'H': // High Broad Band               sample rate=[80, 250[ Hz, corner period >= 10 sec
  case 'B': // Broad Band                    sample rate=[10, 80[ Hz, corner period >= 10 sec
  case 'M': // Mid Period                    sample rate=]1, 10[ Hz
  case 'L': // Long Period                   sample rate=1 Hz
  case 'V': // Very Long Period              sample rate=0.1 Hz
  case 'U': // Ultra Long Period             sample rate=0.01 Hz
  case 'R': // Extremely Long Period         sample rate=0.001 Hz
  case 'P': // On the order of 0.1 to 1 day  sample rate=[0.00001, 0.0001[
  case 'T': // On the order of 1 to 10 days  sample rate=[0.000001, 0.00001[
  case 'Q': // Greater than 10 days          sample rate<0.000001
  case 'A': // Administrative Instrument Channel
  case 'O': // Opaque Instrument Channel
    break;
  default:
    return UndefinedComponent;
  }
  // Second and third letters, Instrument Code and Orientation Code
  // Only seismometers and geophones are recognized
  switch(c[1]) {
  case 'H': // High Gain Seismometer
  case 'L': // Low Gain Seismometer
  case 'G': // Gravimeter
  case 'M': // Mass Position Seismometer
  case 'N': // Accelerometer
  case 'P': // Geophone
    switch(c[2]) {
    case 'Z':
      return Vertical;
    case 'N':
      return North;
    case 'E':
      return East;
    default:
      break;
    }
    break;
  default:
    break;
  }
  return UndefinedComponent;
}

References metaData(), and GeopsyCore::GuralpRecords::staticId().

{
  // GuralpRecords is always available in MetaDataFactory, hence o is never null
  const GuralpRecords * o=static_cast<const GuralpRecords *>(metaData(GuralpRecords::staticId()));
  return *o;
}
bool GeopsyCore::Signal::hasMetaData ( int  id) const [inline]
{return _optionalData.hasData(id);}
QVariant GeopsyCore::Signal::header ( const MetaDataIndex index) const

References GeopsyCore::MetaDataFactory::AmplitudeUnit, amplitudeUnitUserName(), GeopsyCore::MetaDataFactory::AverageAmplitude, averageAmplitude(), GeopsyCore::MetaDataFactory::Component, componentUserName(), GeopsyCore::MetaDataFactory::CountPerUnit, countPerUnit(), GeopsyCore::MetaDataFactory::CountPerVolt, countPerVolt(), GeopsyCore::MetaData::data(), database(), GeopsyCore::MetaDataFactory::DataCount, GeopsyCore::SignalTemplate< double >::dataSizeMb(), GeopsyCore::DoubleSignal::deltaT(), GeopsyCore::MetaDataFactory::DeltaT, GeopsyCore::MetaDataFactory::Dummy, GeopsyCore::DoubleSignal::duration(), GeopsyCore::MetaDataFactory::Duration, GeopsyCore::MetaDataFactory::EndTime, endTime(), file(), GeopsyCore::MetaDataFactory::FileFormat, GeopsyCore::MetaDataFactory::FileName, GeopsyCore::MetaDataFactory::FileNumber, GeopsyCore::SignalDB::filePool(), GeopsyCore::SignalFile::format(), GeopsyCore::MetaDataFactory::HeaderModified, GeopsyCore::MetaDataIndex::id(), GeopsyCore::MetaDataFactory::ID, id(), GeopsyCore::MetaDataIndex::index(), GeopsyCore::SignalFilePool::indexOf(), isHeaderModified(), GeopsyCore::MetaDataFactory::IsOriginalFile, isOriginalFile(), GeopsyCore::MetaDataFactory::MaximumAmplitude, maximumAmplitude(), metaData(), GeopsyCore::SignalFile::name(), GeopsyCore::MetaDataFactory::Name, name(), GeopsyCore::SignalTemplate< double >::nSamples(), GeopsyCore::MetaDataFactory::NSamples, GeopsyCore::MetaDataFactory::NumberInFile, numberInFile(), GeopsyCore::MetaDataFactory::Pointer, receiver(), GeopsyCore::MetaDataFactory::ReceiverX, GeopsyCore::MetaDataFactory::ReceiverY, GeopsyCore::MetaDataFactory::ReceiverZ, GeopsyCore::MetaDataFactory::SampleSize, GeopsyCore::MetaDataFactory::SamplingFrequency, GeopsyCore::MetaDataFactory::ShortFileName, GeopsyCore::SignalFile::shortName(), source(), GeopsyCore::MetaDataFactory::SourceReceiverAzimuth, sourceReceiverAzimuth(), GeopsyCore::MetaDataFactory::SourceReceiverDistance, sourceReceiverDistance(), GeopsyCore::MetaDataFactory::SourceReceiverRoughAzimuth, GeopsyCore::MetaDataFactory::SourceX, GeopsyCore::MetaDataFactory::SourceY, GeopsyCore::MetaDataFactory::SourceZ, GeopsyCore::MetaDataIndex::subId(), GeopsyCore::MetaDataFactory::T0, t0(), GeopsyCore::MetaDataFactory::TimeReference, timeReferenceString(), GeopsyCore::SignalFileFormat::toString(), QGpCoreTools::tr(), TRACE, GeopsyCore::DoubleSignal::type(), GeopsyCore::MetaDataFactory::Type, GeopsyCore::DoubleSignal::typeString(), GeopsyCore::MetaDataFactory::UnitPerCount, unitPerCount(), GeopsyCore::MetaDataFactory::UnitPerVolt, unitPerVolt(), GeopsyCore::MetaDataFactory::VoltPerCount, voltPerCount(), GeopsyCore::MetaDataFactory::VoltPerUnit, voltPerUnit(), QGpCoreTools::Point2D::x(), QGpCoreTools::Point2D::y(), and QGpCoreTools::Point::z().

Referenced by GeopsyMainWindow::createNewGroup(), SignalTableItem::data(), GeopsyCore::SubSignalPool::exportTable(), GeopsyCore::SignalProcess::headerCore(), SignalTableItem::setData(), GeopsyCore::SignalExpression::value(), and writeGse().

{
  TRACE;
  if(index.id()<MetaDataFactory::DataCount) {
    switch (index.id()) {
    case MetaDataFactory::ID: return id();
    case MetaDataFactory::T0: return t0();
    case MetaDataFactory::DeltaT: return deltaT();
    case MetaDataFactory::NSamples: return nSamples();
    case MetaDataFactory::Duration: return duration();
    case MetaDataFactory::EndTime: return endTime();
    case MetaDataFactory::ReceiverX: return receiver().x();
    case MetaDataFactory::ReceiverY: return receiver().y();
    case MetaDataFactory::ReceiverZ: return receiver().z();
    case MetaDataFactory::SourceX: return source().x();
    case MetaDataFactory::SourceY: return source().y();
    case MetaDataFactory::SourceZ: return source().z();
    case MetaDataFactory::Name: return name();
    case MetaDataFactory::Component: return componentUserName();
    case MetaDataFactory::Type: return typeString(type());
    case MetaDataFactory::FileNumber: {
        return database()->filePool().indexOf(file());
      }
    case MetaDataFactory::FileName: if(file()) return file() ->name(); else return tr("### Temporary signal ###");
    case MetaDataFactory::ShortFileName: if(file()) return file() ->shortName(); else return tr("### Temporary signal ###");
    case MetaDataFactory::FileFormat: if(file()) return file()->format().toString(); else return tr("### Temporary signal ###");
    case MetaDataFactory::NumberInFile: return numberInFile();
    case MetaDataFactory::TimeReference: return timeReferenceString();
    case MetaDataFactory::MaximumAmplitude: return maximumAmplitude();
    case MetaDataFactory::AverageAmplitude: return averageAmplitude();
    case MetaDataFactory::IsOriginalFile:
      if(file() && file() ->isOriginalFile())
        return tr("Original");
      else
        return tr("Processed");
    case MetaDataFactory::SamplingFrequency: return 1.0/deltaT();
    case MetaDataFactory::Pointer: return QString::number((long) this, 16);
    case MetaDataFactory::CountPerVolt: return countPerVolt();
    case MetaDataFactory::VoltPerCount: return voltPerCount();
    case MetaDataFactory::VoltPerUnit: return voltPerUnit();
    case MetaDataFactory::UnitPerVolt: return unitPerVolt();
    case MetaDataFactory::CountPerUnit: return countPerUnit();
    case MetaDataFactory::UnitPerCount: return unitPerCount();
    case MetaDataFactory::AmplitudeUnit: return amplitudeUnitUserName();
    case MetaDataFactory::SampleSize: return dataSizeMb();
    case MetaDataFactory::HeaderModified: return isHeaderModified();
    case MetaDataFactory::SourceReceiverDistance: return sourceReceiverDistance();
    case MetaDataFactory::SourceReceiverAzimuth:
    case MetaDataFactory::SourceReceiverRoughAzimuth: return Angle::mathToGeographic(sourceReceiverAzimuth());
    case MetaDataFactory::Dummy: return "####";
    case MetaDataFactory::DataCount: break;
    }
  } else {
    const MetaData * d=metaData(index.id());
    if(d) {
      return d->data(index.subId(), index.index());
    }
  }
  return QVariant();
}
int GeopsyCore::Signal::id ( ) const [inline]
bool GeopsyCore::Signal::isHeaderModified ( ) const [inline]
bool GeopsyCore::Signal::isOriginalFile ( ) const [inline]

References isOriginalFile().

Referenced by compare(), header(), GeopsyCore::SignalHeaderObject::isOriginalFile(), and isOriginalFile().

{if(file() && file() ->isOriginalFile()) return true; else return false;}
bool GeopsyCore::Signal::isReadOnlySamples ( ) const [inline]
double * GeopsyCore::Signal::lockSamples ( ) [virtual]

General function to be called before using the samples.

Reimplemented from GeopsyCore::SignalTemplate< double >.

References GeopsyCore::GeopsyCoreEngine::cache(), file(), GeopsyCore::geopsyCore, GeopsyCore::SignalTemplate< double >::isAllocated(), QGpCoreTools::Cache::makeAvailable(), GeopsyCore::SignalTemplate< double >::samples(), and TRACE.

{
  TRACE;
  lockData();
  if(isAllocated()) {
    return samples();
  }
  if(isSaved() || !file()) {
    if(geopsyCore->cache()->makeAvailable(this)) {
      return samples();
    } else {
      unlockData();
      return 0;
    }
  }
  if(geopsyCore->cache()->makeAvailable(this)) {
    load(samples());
    return samples();
  } else {
    unlockData();
    return 0;
  }
}
double* GeopsyCore::Signal::lockSamples ( char *  file,
int  line 
) [inline]
double GeopsyCore::Signal::maximumAmplitude ( int  itmin = 0,
int  itmax = 0 
) const

Returns the maximum amplitude and store it in _maxAmplitude if itmin==0 and itmax==nSamples()-1 If itmin==itmax==0, it returns directly _maxAmplitude without re-checking it.

Reimplemented from GeopsyCore::DoubleSignal.

References _amplitudeMutex, _maxAmplitude, and TRACE.

Referenced by compare(), GeopsyCore::SubSignalPool::decimateAmplitude(), GeopsyGui::SignalLayer::drawingAmplitude(), GeopsyGui::SignalLayer::drawSignal(), header(), GeopsyGui::SignalLayer::maxAmplitude(), GeopsyCore::SignalHeaderObject::maximumAmplitude(), GeopsyGui::SignalLayer::minMaxY(), GeopsyGui::PickLayer::paintData(), Process::run(), T0Correlation::value(), and writeSeg2().

{
  TRACE;
  // Better if amplitude mutex is not locked while signal mutex is blocked
  // A special case was encountered with DynamicSignal::set() and a drawing thread active
  // at the same moment.
  if(itmin==0 && itmax==0) {
    QMutexLocker ml(&_amplitudeMutex);
    if(_maxAmplitude!=1e99) return _maxAmplitude;
    itmax=_nSamples-1;
  }
  double v=DoubleSignal::maximumAmplitude(itmin, itmax);
  if(itmin <= 0 && itmax >= _nSamples-1) {
    QMutexLocker ml(&_amplitudeMutex);
    _maxAmplitude=v;
  }
  return v;
}

Returns the time of the maximum amplitude.

References GeopsyCore::DoubleSignal::_deltaT, _t0, GeopsyCore::TimeRange::end(), GeopsyCore::SignalTemplate< double >::nSamples(), GeopsyCore::TimeRange::start(), and TRACE.

{
  TRACE;
  double t;
  if(r.start()==0.0 && r.end()==0.0) {
    t=DoubleSignal::maximumAmplitudeAt(0, nSamples());
  } else {
    double f=1.0/_deltaT;
    t=DoubleSignal::maximumAmplitudeAt((r.start()-_t0)*f, (r.end()-_t0)*f);
  }
  return _t0+_deltaT*t;
}
MetaData* GeopsyCore::Signal::metaData ( int  id) [inline]
const MetaData* GeopsyCore::Signal::metaData ( int  id) const [inline]

References GeopsyCore::MetaData::data().

{return _optionalData.data(id);}
const MetaDataMap& GeopsyCore::Signal::metaDataMap ( ) const [inline]

Referenced by GeopsyCore::SharedMetaData::add().

{return _optionalData;}

References metaData(), and GeopsyCore::MiniSeedRecords::staticId().

{
  // MiniSeedRecords is always available in MetaDataFactory, hence o is never null
  const MiniSeedRecords * o=static_cast<const MiniSeedRecords *>(metaData(MiniSeedRecords::staticId()));
  return *o;
}
QString GeopsyCore::Signal::name ( ) const [inline]
Signal * GeopsyCore::Signal::newCopy ( Signal sig) [static]

References copySamplesFrom(), Signal(), and TRACE.

{
  TRACE;
  Signal * newSig=new Signal(*sig);
  newSig->copySamplesFrom(sig);
  return newSig;
}
void GeopsyCore::Signal::normalizedCorrelation ( const Signal s1,
const Signal s2,
double  maxDelay 
)

Correlates signal s1 to s2 and saves results in this signal. If this signal has the correct number of samples and the correct sampling frequency, the value of this signal are not cleaned and the results are stacked on existing values. If not, the signal is initialized with 0.

References component(), GeopsyCore::DoubleSignal::deltaT(), QGpCoreTools::Point::distanceTo(), QGpCoreTools::endl(), name(), nameComponent(), GeopsyCore::DoubleSignal::normalizedCorrelation(), GeopsyCore::SignalTemplate< double >::nSamples(), receiver(), setComponent(), setName(), setReceiver(), setT0(), GeopsyCore::DoubleSignal::setType(), t0(), QGpCoreTools::tr(), TRACE, UndefinedComponent, and GeopsyCore::DoubleSignal::Waveform.

Referenced by GeopsyCore::SubSignalPool::normalizedCorrelations().

{
  TRACE;
  if(!DoubleSignal::normalizedCorrelation(s1, s2, maxDelay)) {
    App::stream() << tr("Error calculating normalized correlation between signals %1 and %2, probably an allocation error")
                       .arg(s1->nameComponent()).arg(s2->nameComponent()) << endl;
  }
  // Change t0 according to tw and set x as the interdistance, name is the compound of both name
  // Use the effective maxDelay (given by signal length)
  maxDelay=(nSamples()-1)*deltaT()*0.5;
  setT0(-maxDelay+s1->t0()-s2->t0()); // Adjust for differences in T0 (not sure if it is the correct direction)
  setReceiver(Point(s1->receiver().distanceTo(s2->receiver()), 0.0, 0.0));
  if(s1->component()==s2->component()) {
    setName(s1->name() + " & " + s2->name());
    setComponent(s1->component());
  } else {
    setName(s1->nameComponent() + " & " + s2->nameComponent());
    setComponent(UndefinedComponent);
  }
  setType(Waveform);
}
int GeopsyCore::Signal::numberInFile ( ) const [inline]
int GeopsyCore::Signal::offsetInFile ( ) const [inline]

Referenced by xml_writeProperties().

{return _offsetInFile;}
bool GeopsyCore::Signal::operator< ( const Signal o) const [inline]
{return compare(o)<0;}
bool GeopsyCore::Signal::operator== ( const Signal o) const [inline]
{return compare(o)==0;}
bool GeopsyCore::Signal::operator> ( const Signal o) const [inline]
{return compare(o)>0;}
void GeopsyCore::Signal::pickCoppens ( const QString &  pickName,
double  delta,
double  end,
double  start = 0.,
bool  relative = false,
double  mute = 0. 
)

References GeopsyCore::DoubleSignal::_deltaT, _isHeaderModified, _t0, CONST_LOCK_SAMPLES, setTimePick(), TRACE, and UNLOCK_SAMPLES.

Referenced by GeopsyCore::SubSignalPool::pickCoppens().

{
  TRACE;
  CONST_LOCK_SAMPLES(double, thisSamples, this)
    double vmax=0.;
    int ivmax=0;
    int iend=(int) ((end-_t0)/_deltaT);
    if(iend < 0) iend=0;
    if(iend >= _nSamples) iend=_nSamples-1;
    int i0;
    if(relative) i0=0;
    else i0=(int) ((start-_t0)/_deltaT);
    if(i0 < 0) i0=0;
    if(i0 >= _nSamples) i0=iend;
    int i;
    for(i=i0; i <= iend; i++) {
      if(fabs(thisSamples[ i ]) > vmax) {
        vmax=fabs(thisSamples[ i ]);
        ivmax=i;
      }
    }
    if(relative) i0=ivmax + (int) (start/_deltaT);
    if(i0 < 0) i0=0;
    if(i0 >= iend) i0=iend;
    int deltaN=(int) (delta/_deltaT);
    if(deltaN < 2)
      deltaN=2;
    if(deltaN > iend-i0)
      deltaN=iend-i0;
    double vmute=vmax * mute;
    double denom=0.;
    double num=0.;
    double max=0;
    int i_max=i0;
    double tmp;
    for(i=i0; i <= iend; i++) {
      if(fabs(thisSamples[ i ]) > vmute) {
        num+=thisSamples[ i ] * thisSamples[ i ];
        denom+=thisSamples[ i ] * thisSamples[ i ];
      }
      if(i > i0 + deltaN) {
        if(fabs(thisSamples[ i-deltaN ]) > vmute)
          num -= thisSamples[ i-deltaN ] * thisSamples[ i-deltaN ];
      }
      if(denom) tmp=num/denom;
      else tmp=0;
      if(tmp > max) {
        max=0.999 * tmp;
        i_max=i-deltaN;
      }
    }
    setTimePick(pickName, _t0 + (double) i_max * _deltaT);
    _isHeaderModified=true;
  UNLOCK_SAMPLES(this)
}
void GeopsyCore::Signal::pickMinMax ( const QString &  pickName,
double  from,
double  to,
PickWhat  what 
)

References GeopsyCore::DoubleSignal::_deltaT, _isHeaderModified, _t0, CONST_LOCK_SAMPLES, Max, Min, setTimePick(), TRACE, and UNLOCK_SAMPLES.

{
  TRACE;
  CONST_LOCK_SAMPLES(double, thisSamples, this)
    int ifrom=(int) ((from-_t0)/_deltaT);
    if(ifrom < 0)
      ifrom=0;
    if(ifrom >= _nSamples)
      ifrom=_nSamples-1;
    int ito=int((to-_t0)/_deltaT);
    if(ito < 0)
      ito=0;
    if(ito >= _nSamples)
      ito=_nSamples-1;
    double extr=thisSamples[ ifrom ];
    int iextr=ifrom;
    switch (what) {
    case Min:
      for(int i=ifrom + 1; i < ito; i++) {
        if(thisSamples[ i ] < extr) {
          iextr=i;
          extr=thisSamples[ i ];
        }
      }
      break;
    case Max:
      for(int i=ifrom + 1; i < ito; i++) {
        if(thisSamples[ i ] > extr) {
          iextr=i;
          extr=thisSamples[ i ];
        }
      }
      break;
    }
    setTimePick(pickName, _t0 + (double) iextr * _deltaT);
    _isHeaderModified=true;
  UNLOCK_SAMPLES(this)
}
bool GeopsyCore::Signal::read ( FILE *  f,
SignalDB db 
)

Read header properties from stream for database db.

References All, CustomUnit, East, Horizontal, North, setComponent(), setDeltaT(), setHeaderModified(), setId(), setName(), setNSamples(), setT0(), setTimePick(), setTimeReference(), GeopsyCore::DoubleSignal::setType(), QGpCoreTools::Point2D::setX(), QGpCoreTools::Point2D::setY(), QGpCoreTools::Point::setZ(), TRACE, UndefinedComponent, UndefinedUnit, GeopsyCore::SignalDB::version(), and Vertical.

{
  TRACE;
  int bufLen=256;
  char * buf=new char [ bufLen ];
  File::readLine(buf, bufLen, f);
  if(strncmp(buf, "ID=", 3)==0) setId(atoi(buf + 3));
  else return readError(buf);
  File::readLine(buf, bufLen, f);
  char * lastBufChar=buf + strlen(buf)-1;
  if(*lastBufChar=='\n') *lastBufChar='\0';
  if(strncmp(buf, "NAME=", 5)==0) setName(buf + 5);
  else return readError(buf);
  File::readLine(buf, bufLen, f);
  if(strncmp(buf, "COMPONENT=", 10)==0) {
    int comp=atoi(buf + 10);
    // Due to historical reasons the number in the sdb file is not the same
    // as the number in the Signal structure
    switch (comp) {
    case 0:
      setComponent(Signal::Vertical);
      break;
    case 2:
      setComponent(Signal::North);
      break;
    case 1:
      setComponent(Signal::East);
      break;
    case 3:
      setComponent(Signal::UndefinedComponent);
      break;
    case 4:
      setComponent(Signal::Horizontal);
      break;
    case 5:
      setComponent(Signal::All);
      break;
    }
  } else return readError(buf);
  File::readLine(buf, bufLen, f);
  if(strncmp(buf, "T0=", 3)==0) setT0(atof(buf + 3));
  else return readError(buf);
  File::readLine(buf, bufLen, f);
  if(strncmp(buf, "TIME REFERENCE=", 15)==0 || strncmp(buf, "TIME DATUM=", 11)==0) {
    char * valuePtr=buf;
    if(valuePtr[6]=='R') valuePtr+=15; else valuePtr+=11;
    if(strlen(valuePtr) > 0) {
      QTime t;
      QDate d;
      int dd=1, MM=1, yyyy=2004, hh=0, mm=0, ss=0;
      char * tmpPtr=strtok(valuePtr, "/");
      if(tmpPtr) dd=atoi(tmpPtr);
      tmpPtr=strtok(NULL, "/");
      if(tmpPtr) MM=atoi(tmpPtr);
      tmpPtr=strtok(NULL, " ");
      if(tmpPtr) yyyy=atoi(tmpPtr);
      d.setYMD(yyyy, MM, dd);
      tmpPtr=strtok(NULL, ":");
      if(tmpPtr) hh=atoi(tmpPtr);
      tmpPtr=strtok(NULL, ":");
      if(tmpPtr) {
        mm=atoi(tmpPtr);
        ss=atoi(tmpPtr + strlen(tmpPtr) + 1);
      }
      t.setHMS(hh, mm, ss);
      if(t.isValid() && d.isValid()) setTimeReference(QDateTime(d, t));
    }
  } else return readError(buf);
  File::readLine(buf, bufLen, f);
  if(strncmp(buf, "DELTA T=", 8)==0) setDeltaT(atof(buf + 8));
  else return readError(buf);
  // Transformation to complex is delayed when the file will be loaded
  File::readLine(buf, bufLen, f);
  if(strncmp(buf, "TYPE=", 5)==0)
    setType((DoubleSignal::SignalType) atoi(buf + 5));
  else return readError(buf);
  File::readLine(buf, bufLen, f);
  // Compatibility with version 2 is ensured as PICK ID will also be read in this loop
  while(strncmp(buf, "PICK ", 4)==0) {
    double val;
    int i;
    sscanf(buf + 4, "%i=%lg", &i, &val);
    if(i>=1 && i<=10) setTimePick(QString::number(i-1), val); // Version 2 accept only pick from 1 to 10
    File::readLine(buf, bufLen, f);
  }
  if(strncmp(buf, "RECEIVER=", 9)==0) {
    double x, y, z;
    sscanf(buf + 9, "%lg %lg %lg", &x, &y, &z);
    _receiver.setX(x);
    _receiver.setY(y);
    _receiver.setZ(z);
  } else return readError(buf);
  File::readLine(buf, bufLen, f);
  if(strncmp(buf, "SOURCE=", 7)==0) {
    double x, y, z;
    sscanf(buf + 7, "%lg %lg %lg", &x, &y, &z);
    _source.setX(x);
    _source.setY(y);
    _source.setZ(z);
  } else return readError(buf);

  if(db->version()>=3) {
    File::readLine(buf, bufLen, f);
    if(strncmp(buf, "N SAMPLES=", 10)==0)
      sscanf(buf + 10, "%i", &_nSamples);
    else return readError(buf);
    setNSamples(_nSamples);
    File::readLine(buf, bufLen, f);
    if(strncmp(buf, "N SAMPLES IN FILE=", 18)!=0) return readError(buf);
    File::readLine(buf, bufLen, f);
    if(strncmp(buf, "NUMBER IN FILE=", 15)==0)
      sscanf(buf + 15, "%i", &_numberInFile);
    else return readError(buf);
    File::readLine(buf, bufLen, f);
    if(strncmp(buf, "OFFSET IN FILE=", 15)==0) {
      long tmp;
      sscanf(buf + 15, "%li", &tmp);
      _offsetInFile=tmp;
  } else return readError(buf);
    File::readLine(buf, bufLen, f);
    if(strncmp(buf, "BYTE INCREMENT=", 15)==0)
      sscanf(buf + 15, "%i", &_byteIncrement);
    else return readError(buf);
    File::readLine(buf, bufLen, f);
    if(strncmp(buf, "CHECKSUM=", 9)!=0) return readError(buf); // not stored anymore
    File::readLine(buf, bufLen, f);
    if(strncmp(buf, "COUNT PER VOLT=", 15)==0)
      sscanf(buf + 15, "%lg", &_countPerVolt);
    else return readError(buf);
    File::readLine(buf, bufLen, f);
    if(strncmp(buf, "VOLT PER UNIT=", 14)==0)
      sscanf(buf + 14, "%lg", &_voltPerUnit);
    else return readError(buf);
    File::readLine(buf, bufLen, f);
    if(strncmp(buf, "AMPLITUDE UNIT=", 15)==0) {
      int tmp;
      sscanf(buf + 15, "%i", &tmp);
      if(tmp>=UndefinedUnit && tmp<=CustomUnit)
        _amplitudeUnit=static_cast<AmplitudeUnits>(tmp);
    } else return readError(buf);
  }
  setHeaderModified(false);
  delete [] buf;
  return true;
}
const Point& GeopsyCore::Signal::receiver ( ) const [inline]
void GeopsyCore::Signal::removeMetaData ( int  id) [inline]
{_optionalData.remove(id);}
void GeopsyCore::Signal::resetAmplitudes ( ) const [inline]
double GeopsyCore::Signal::roundTimePick ( const QString &  name) const

Returns the time of the nearest sample for timePick named name.

References GeopsyCore::DoubleSignal::_deltaT, _t0, metaData(), GeopsyCore::TimePick::staticId(), and GeopsyCore::TimePick::value().

{
  // TimePick is always available in MetaDataFactory, hence o is never null
  const TimePick * o=static_cast<const TimePick *>(metaData(TimePick::staticId()));
  return _t0+_deltaT*round((o->value(name)-_t0)/_deltaT);
}
void GeopsyCore::Signal::setByteIncrement ( int  i) [inline]

Referenced by xml_setProperty().

{_byteIncrement=i;}
void GeopsyCore::Signal::setComments ( QString  c) [inline]

References metaData(), GeopsyCore::MetaString::setValue(), and GeopsyCore::Comments::staticId().

Referenced by GeopsyCore::CitySignal::loadSignals(), and GeopsyCore::GeopsyCoreEngine::showSignal().

{
  // Comments is always available in MetaDataFactory, hence o is never null
  Comments * o=static_cast<Comments *>(metaData(Comments::staticId()));
  return o->setValue(c);
}

Set current recorder factor for converting counts into volts

References GeopsyCore::SignalTemplate< double >::isAllocated(), LOCK_SAMPLES, GeopsyCore::SignalTemplate< double >::multiply(), resetAmplitudes(), TRACE, and UNLOCK_SAMPLES.

Referenced by GeopsyCore::CitySignal::loadSignals(), GeopsyCore::SignalHeaderObject::setCountPerVolt(), setHeader(), and xml_setProperty().

{
  TRACE;
  if(c!=_countPerVolt) {
    lockData(); // Lock without allocating the samples
    if(isAllocated() || isSaved()) { // Swaped signal must be corrected as well
      LOCK_SAMPLES(double, thisSamples, this)
        multiply(_countPerVolt/c);
        resetAmplitudes();
      UNLOCK_SAMPLES(this)
    }
    unlockData();
    _countPerVolt=c;
  }
}
void GeopsyCore::Signal::setDatabase ( SignalDB db) [inline]
{_db=db;}
void GeopsyCore::Signal::setDeltaT ( double  newval) [virtual]
void GeopsyCore::Signal::setFile ( SignalFile f) [inline]

References metaData(), and GeopsyCore::GuralpRecords::staticId().

{
  // GuralpRecords is always available in MetaDataFactory, hence o is never null
  GuralpRecords * o=static_cast<GuralpRecords *>(metaData(GuralpRecords::staticId()));
  *o=r;
}
bool GeopsyCore::Signal::setHeader ( const MetaDataIndex index,
QVariant  val 
)

References GeopsyCore::DoubleSignal::_deltaT, GeopsyCore::SignalTemplate< double >::_nSamples, GeopsyCore::MetaDataFactory::AmplitudeUnit, GeopsyCore::MetaDataFactory::Component, GeopsyCore::MetaDataFactory::CountPerVolt, GeopsyCore::MetaDataFactory::DataCount, GeopsyCore::MetaDataFactory::DeltaT, GeopsyCore::MetaDataFactory::Duration, GeopsyCore::MetaDataFactory::EndTime, GeopsyCore::MetaDataIndex::id(), GeopsyCore::MetaDataIndex::index(), metaData(), GeopsyCore::MetaDataFactory::Name, READONLY_STANDARD_METADATA, GeopsyCore::MetaDataFactory::ReceiverX, GeopsyCore::MetaDataFactory::ReceiverY, GeopsyCore::MetaDataFactory::ReceiverZ, GeopsyCore::MetaDataFactory::SamplingFrequency, setAmplitudeUnit(), setComponent(), setCountPerVolt(), GeopsyCore::MetaData::setData(), setDeltaT(), setHeaderModified(), setT0(), setTimeReference(), setUnitPerVolt(), setVoltPerCount(), setVoltPerUnit(), QGpCoreTools::Point2D::setX(), QGpCoreTools::Point2D::setY(), QGpCoreTools::Point::setZ(), GeopsyCore::MetaDataFactory::SourceX, GeopsyCore::MetaDataFactory::SourceY, GeopsyCore::MetaDataFactory::SourceZ, GeopsyCore::MetaDataIndex::subId(), GeopsyCore::MetaDataFactory::T0, GeopsyCore::MetaDataFactory::TimeReference, TRACE, GeopsyCore::MetaDataFactory::UnitPerVolt, userAmplitudeUnit(), userComponent(), GeopsyCore::MetaDataFactory::VoltPerCount, and GeopsyCore::MetaDataFactory::VoltPerUnit.

Referenced by GeopsyCore::AsciiSignalFormat::assign(), GeopsyCore::SubSignalPool::importTable(), SignalTableItem::setData(), GeopsyCore::SignalProcess::setHeaderCore(), and GeopsyCore::SignalExpression::setValue().

{
  TRACE;
  if(index.id()<MetaDataFactory::DataCount) {
    switch (index.id()) {
    case MetaDataFactory::T0:
      setT0(Number::timeToSeconds(val.toString()));
      break;
    case MetaDataFactory::DeltaT:
      setDeltaT(val.toDouble());
      break;
    case MetaDataFactory::ReceiverX:
      _receiver.setX(val.toDouble());
      break;
    case MetaDataFactory::ReceiverY:
      _receiver.setY(val.toDouble());
      break;
    case MetaDataFactory::ReceiverZ:
      _receiver.setZ(val.toDouble());
      break;
    case MetaDataFactory::SourceX:
      _source.setX(val.toDouble());
      break;
    case MetaDataFactory::SourceY:
      _source.setY(val.toDouble());
      break;
    case MetaDataFactory::SourceZ:
      _source.setZ(val.toDouble());
      break;
    case MetaDataFactory::Name:
      _name=val.toString();
      break;
    case MetaDataFactory::Component:
      setComponent(userComponent(val.toString()));
      break;
    case MetaDataFactory::TimeReference:
      setTimeReference(val.toString());
      break;
    case MetaDataFactory::SamplingFrequency:
      setDeltaT(1.0/val.toDouble());
      break;
    case MetaDataFactory::Duration:
      setDeltaT(Number::timeToSeconds(val.toString())/(double)_nSamples);
      break;
    case MetaDataFactory::EndTime:
      setT0(Number::timeToSeconds(val.toString())-_deltaT * _nSamples);
      break;
    case MetaDataFactory::CountPerVolt:
      setCountPerVolt(val.toDouble());
      break;
    case MetaDataFactory::VoltPerCount:
      setVoltPerCount(val.toDouble());
      break;
    case MetaDataFactory::VoltPerUnit:
      setVoltPerUnit(val.toDouble());
      break;
    case MetaDataFactory::UnitPerVolt:
      setUnitPerVolt(val.toDouble());
      break;
    case MetaDataFactory::AmplitudeUnit:
      setAmplitudeUnit(userAmplitudeUnit(val.toString()));
      break;
    READONLY_STANDARD_METADATA
      return false;
    }
  } else {
    MetaData * d=metaData(index.id());
    if(d) {
      if(!d->setData(index.subId(), index.index(), val)) {
        return false;
      }
    } else {
      return false;
    }
  }
  setHeaderModified(true);
  return true;
}
void GeopsyCore::Signal::setHeaderModified ( bool  m) [inline]
void GeopsyCore::Signal::setId ( int  id)

Sets signal ID. Called only by SignalDB::addSignal() (with id=-1) and when loading from an XML stream (id>-1).

References TRACE, and GeopsyCore::SignalDB::uniqueId().

Referenced by GeopsyCore::SignalDB::addSignal(), read(), and xml_setProperty().

{
  TRACE;
  _id=-1; // remove this signal from the list of ids
  _id=_db->uniqueId(id);
}

References metaData(), and GeopsyCore::MiniSeedRecords::staticId().

{
  // MiniSeedRecords is always available in MetaDataFactory, hence o is never null
  MiniSeedRecords * o=static_cast<MiniSeedRecords *>(metaData(MiniSeedRecords::staticId()));
  *o=r;
}
void GeopsyCore::Signal::setName ( QString  n) [inline]
void GeopsyCore::Signal::setNSamples ( int  n) [virtual]
void GeopsyCore::Signal::setNumberInFile ( int  i) [inline]
void GeopsyCore::Signal::setOffsetInFile ( int  o) [inline]
void GeopsyCore::Signal::setReadOnlySamples ( bool  ro) [inline]
void GeopsyCore::Signal::setReceiver ( const Point p) [inline]
void GeopsyCore::Signal::setSource ( const Point p) [inline]
void GeopsyCore::Signal::setT0 ( double  t)

Called by copy contructor, but can also be called for a new signal created with other constructor (before first allocation of data samples)

Usually initial reference count is set to 0. We decrease it to -1 without checking and deleting Adding signal to db set its reference count to 0 Next the temporary signal will be added to one or more visual subpool When the last visual subpool is closed, the count drops to 0 and the signal is deleted, the destructor remove it from database automatically. If the signal is not displayed or added to a subpool then you must delete it manually.

References _isHeaderModified, _isReadOnlySamples, QGpCoreTools::SharedObject::removeReference(), and TRACE.

Referenced by GeopsyCore::SubSignalPool::convolution(), GeopsyCore::SubSignalPool::correlations(), GeopsyCore::SubSignalPool::normalizedCorrelations(), and Signal().

{
  TRACE;
  _file=0;
  _numberInFile=0;
  _offsetInFile=0;
  _byteIncrement=0;
  _isReadOnlySamples=false;
  _isHeaderModified=true;
  removeReference(); /* Adding signal to db set its reference count to 1
                      We decrease it to 0 without checking and deleting
                      Next the temporary signal will be added to one or more visual subpool
                      When the last visual subpool is closed, the count drops to 0 and the
                      signal is deleted, the destructor remove it from database automatically. */

}
void GeopsyCore::Signal::setTimePick ( const QString &  name,
double  time 
) [inline]

Set time for pick with index. Time picks are optional data members

References metaData(), GeopsyCore::TimePick::setValue(), and GeopsyCore::TimePick::staticId().

Referenced by GeopsyGui::PickLayer::mouseMoveEvent(), GeopsyGui::PickLayer::mousePressEvent(), pickCoppens(), pickMinMax(), read(), and Process::run().

{
  // TimePick is always available in MetaDataFactory, hence o is never null
  TimePick * o=static_cast<TimePick *>(metaData(TimePick::staticId()));
  o->setValue(name, time);
}

Set available signal within the range defined by t0() and endTime().

References _timeRange, GeopsyCore::SparseTimeRange::intersection(), and GeopsyCore::SparseTimeRange::range().

Referenced by cut().

void GeopsyCore::Signal::setTimeReference ( QDateTime  t) [inline]
void GeopsyCore::Signal::setTimeReference ( QString  t) [inline]
{_timeReference=QDateTime::fromString(t, "dd/MM/yyyy hh:mm:ss" );}
void GeopsyCore::Signal::setUnitPerVolt ( double  c) [inline]
void GeopsyCore::Signal::setVoltPerCount ( double  c) [inline]

Set current sensor factor for converting volts into amplitudeUnit

References GeopsyCore::SignalTemplate< double >::isAllocated(), LOCK_SAMPLES, GeopsyCore::SignalTemplate< double >::multiply(), resetAmplitudes(), TRACE, and UNLOCK_SAMPLES.

Referenced by setHeader(), GeopsyCore::SignalHeaderObject::setVoltPerUnit(), and xml_setProperty().

{
  TRACE;
  if(c!=_voltPerUnit) {
    lockData(); // Lock without allocating the samples
    if(isAllocated() || isSaved()) { // Swaped signal must be corrected as well
      LOCK_SAMPLES(double, thisSamples, this)
        multiply(_voltPerUnit/c);
        resetAmplitudes();
      UNLOCK_SAMPLES(this)
    }
    unlockData();
    _voltPerUnit=c;
  }
}
const Point& GeopsyCore::Signal::source ( ) const [inline]
double GeopsyCore::Signal::sourceReceiverAzimuth ( ) const [inline]
double GeopsyCore::Signal::sourceReceiverDistance ( ) const [inline]

Returns amplitude unit from a string containing standardized names

References Acceleration, CustomUnit, Displacement, TRACE, and Velocity.

Referenced by GeopsyCore::SignalHeaderObject::setAmplitudeUnit(), and xml_setProperty().

{
  TRACE;
  static QMap<QString, AmplitudeUnits> unitMap;
  if(unitMap.isEmpty()) {
    unitMap.insert("Displacement", Displacement);
    unitMap.insert("Velocity", Velocity);
    unitMap.insert("Acceleration", Acceleration);
  }
  QMap<QString,AmplitudeUnits>::iterator it=unitMap.find(u);
  if(it!=unitMap.end()) {
    return it.value();
  } else {
    return CustomUnit;
  }
}

Returns component from a string containing standardized component names

References All, East, Horizontal, North, TRACE, UndefinedComponent, and Vertical.

Referenced by GeopsyCore::SignalHeaderObject::setComponent(), GeopsyCore::AsciiSignalFormatComponent::xml_setProperty(), and xml_setProperty().

{
  TRACE;
  static QMap<QString, Components> m;
  if(m.isEmpty()) {
    m.insert("Vertical", Vertical);
    m.insert("North", North);
    m.insert("East", East);
    m.insert("Horizontal", Horizontal);
    m.insert("All", All);
  }
  QMap<QString,Components>::iterator it=m.find(c);
  if(it!=m.end()) {
    return it.value();
  } else {
    return UndefinedComponent;
  }
}

Return standard name for component

References All, East, Horizontal, North, TRACE, and Vertical.

Referenced by GeopsyCore::AsciiSignalFormatComponent::xml_writeProperties().

{
  TRACE;
  switch (c) {
  case Vertical:
    return "Vertical";
  case North:
    return "North";
  case East:
    return "East";
  case All:
    return "All";
  case Horizontal:
    return "Horizontal";
  default:
    return "Undefined";
  }
}

Returns the theoretical name of the units for amplitude.

References Acceleration, Displacement, TRACE, and Velocity.

{
  TRACE;
  switch (u) {
  case Displacement:
    return "Displacement";
  case Velocity:
    return "Velocity";
  case Acceleration:
    return "Acceleration";
  default:
    break;
  }
  return "Custom";
}
double GeopsyCore::Signal::t0 ( ) const [inline]
TIME GeopsyCore::Signal::t0AsTIME ( ) const [inline]
{return DateTime::capAddSecs(_timeReference, t0());}
bool GeopsyCore::Signal::taper ( const TimeRange t,
const TaperParameters param 
) [inline]

Applies a taper window to the signal over the range t.

Returns false if not processed due to memory problem.

Reimplemented from GeopsyCore::DoubleSignal.

References _t0, GeopsyCore::TimeRange::shifted(), and TRACE.

Referenced by GeopsyCore::SubSignalPool::taper().

{
  TRACE;
  return DoubleSignal::taper(tw.shifted(-_t0), param);
}
double GeopsyCore::Signal::timePick ( const QString &  name) const [inline]
int GeopsyCore::Signal::timePickCount ( ) const [inline]

References GeopsyCore::TimePick::count(), metaData(), and GeopsyCore::TimePick::staticId().

{
  // TimePick is always available in MetaDataFactory, hence o is never null
  const TimePick * o=static_cast<const TimePick *>(metaData(TimePick::staticId()));
  return o->count(0);
}
QDateTime GeopsyCore::Signal::timeReference ( ) const [inline]
QString GeopsyCore::Signal::timeReferenceString ( ) const [inline]

Referenced by header(), GeopsyCore::SignalHeaderObject::timeReference(), and xml_writeProperties().

{return _timeReference.toString( "dd/MM/yyyy hh:mm:ss" );}
double GeopsyCore::Signal::unitPerCount ( ) const [inline]
double GeopsyCore::Signal::unitPerVolt ( ) const [inline]

Referenced by compare(), header(), and GeopsyCore::SignalHeaderObject::unitPerVolt().

{return 1.0/_voltPerUnit;}

REturns amplitude unit from a string entered by the user (hence in its own language)

References Acceleration, CustomUnit, Displacement, QGpCoreTools::tr(), TRACE, and Velocity.

Referenced by setHeader().

{
  TRACE;
  static QMap<QString, AmplitudeUnits> unitMap;
  if(unitMap.isEmpty()) {
    unitMap.insert(tr("Displacement"), Displacement);
    unitMap.insert(tr("Velocity"), Velocity);
    unitMap.insert(tr("Acceleration"), Acceleration);
  }
  QMap<QString,AmplitudeUnits>::iterator it=unitMap.find(u);
  if(it!=unitMap.end()) {
    return it.value();
  } else {
    return CustomUnit;
  }
}

Returns component from a string entered by the user (hence in its own language)

References All, East, Horizontal, North, QGpCoreTools::tr(), TRACE, UndefinedComponent, and Vertical.

Referenced by setHeader().

{
  TRACE;
  static QMap<QString, Components> m;
  if(m.isEmpty()) {
    m.insert(tr("Vertical"), Vertical);
    m.insert(tr("North"), North);
    m.insert(tr("East"), East);
    m.insert(tr("Horizontal"), Horizontal);
    m.insert(tr("All"), All);
  }
  QMap<QString,Components>::iterator it=m.find(c);
  if(it!=m.end()) {
    return it.value();
  } else {
    return UndefinedComponent;
  }
}
QString GeopsyCore::Signal::userName ( Components  c) [static]

Return name for component in user's own language

References All, East, Horizontal, North, QGpCoreTools::tr(), TRACE, and Vertical.

Referenced by GeopsyCore::StationSignals::addSignal(), and GeopsyCore::StationSignals::hasAllComponents().

{
  TRACE;
  switch (c) {
  case Vertical:
    return tr("Vertical");
  case North:
    return tr("North");
  case East:
    return tr("East");
  case All:
    return tr("All");
  case Horizontal:
    return tr("Horizontal");
  default:
    return tr("Undefined");
  }
}

Returns the theoretical name of the units for amplitude in user own language

References Acceleration, Displacement, QGpCoreTools::tr(), TRACE, and Velocity.

{
  TRACE;
  switch (u) {
  case Displacement:
    return tr("Displacement");
  case Velocity:
    return tr("Velocity");
  case Acceleration:
    return tr("Acceleration");
  default:
    break;
  }
  return tr("Custom");
}
double GeopsyCore::Signal::voltPerCount ( ) const [inline]

Referenced by compare(), header(), and GeopsyCore::SignalHeaderObject::voltPerCount().

{return 1.0/_countPerVolt;}
double GeopsyCore::Signal::voltPerUnit ( ) const [inline]
bool GeopsyCore::Signal::warnReadOnlySamples ( ) const [inline]
bool GeopsyCore::Signal::writeAscii ( QFile &  f,
int  numInFile 
) const

References GeopsyCore::DoubleSignal::_deltaT, GeopsyCore::SignalTemplate< double >::_nSamples, GeopsyCore::DoubleSignal::amplitude(), CONST_LOCK_SAMPLES, GeopsyCore::DoubleSignal::isComplex(), GeopsyCore::DoubleSignal::isReal(), nameComponent(), GeopsyCore::DoubleSignal::phase(), TRACE, and UNLOCK_SAMPLES.

{
  TRACE;
  QByteArray buf;
  buf+="# channel ";
  buf+=QByteArray::number(numInFile+1);
  buf+=" ";
  buf+=nameComponent();
  buf+="\n";
  if(f.write(buf)!=buf.count()) return false;
  CONST_LOCK_SAMPLES(double, thisSamples, this)
    if(isReal()) {
      for(int i=0; i < _nSamples; i ++) {
        buf.clear();
        buf+=QByteArray::number(thisSamples[ i ], 'g', 15);
        buf+="\n";
        if(f.write(buf)!=buf.count()) return false;
      }
    } else if(isComplex()) {
      double fNyquist=0.5/_deltaT;
      int nSamples2=_nSamples >> 1;
      double df=fNyquist/(double) nSamples2;
      for(int i=1; i <= nSamples2; i++) {
        buf.clear();
        buf+=QByteArray::number(df * (double) i, 'g', 15);
        buf+="\t";
        buf+=QByteArray::number(amplitude(thisSamples, i), 'g', 15);
        buf+="\t";
        buf+=QByteArray::number(phase(thisSamples, i), 'g', 15);
        buf+="\n";
        if(f.write(buf)!=buf.count()) return false;
      }
    }
  UNLOCK_SAMPLES(this)
  return true;
}
bool GeopsyCore::Signal::writeGse ( QFile &  f) const

References GeopsyCore::SignalTemplate< double >::_nSamples, QGpCoreTools::DateTime::addSeconds(), GeopsyCore::Gse::checksum(), component(), GeopsyCore::Gse::compress6(), CONST_LOCK_SAMPLES, countPerUnit(), GeopsyCore::DoubleSignal::deltaT(), GeopsyCore::Gse::diff(), East, header(), name(), North, GeopsyCore::SignalTemplate< double >::nSamples(), GeopsyCore::DoubleSignal::restoreType(), GeopsyCore::DoubleSignal::saveType(), t0(), timeReference(), QGpCoreTools::DateTime::toString(), QGpCoreTools::tr(), TRACE, unitPerCount(), UNLOCK_SAMPLES, Vertical, and GeopsyCore::DoubleSignal::Waveform.

{
  TRACE;
  const DoubleSignal * sig=saveType(Waveform);

  static const QString errorMsg(tr("[GSE] Error while writing %1"));

  // Build header line
  // Index 0
  QString header("WID2 ");
  DateTime t(timeReference());
  t.addSeconds(t0());
  // Index 6
  header+=t.toString("yyyy/MM/dd hh:mm:ssz").left(23)+" ";
  // Index 30
  header+=name().leftJustified(5, QChar(' '), true)+" ";
  /* See http://www.iris.edu/manuals/seed/SEEDManual_V2.4_Appendix-A.pdf
     for FDSN channel codes
     Geopsy always export in HH, which means High Broad Band with high gain.
  */
  // Index 36
  switch (component()) {
  case Vertical:  header+="HHZ      "; break;
  case North:     header+="HHN      "; break;
  case East:      header+="HHE      "; break;
  default:        header+="         "; break;
  }
  // Index 45
  header+="CM6 ";
  // Index 49
  header+=QString::number(nSamples()).leftJustified(8, QChar(' '), true)+" ";
  // Index 58
  header+=QString::number(1.0/deltaT()).leftJustified(11, QChar(' '), true)+" ";
  // Index 70: calibration factor at calper
  header+=QString::number(1e9*unitPerCount()).leftJustified(10, QChar(' '), true)+" ";
  // Index 81: calibration period
  header+="  1.000 ";
  // Index 89: Instrument type
  header+="  NONE ";
  // Index 96: horizontal orientation of sensor (from north)
  // Index 102: vertical horientation
  switch(component()) {
  case Vertical:
    header+=" -1.0 ";
    header+=" 0.0 ";
    break;
  default:
    header+="  0.0 ";
    header+="90.0 ";
    break;
  }
  header+="\n";
  header+="DAT2\n";
  if(f.write(header.toAscii().data(), header.count())!=header.count())
    return writeError(sig, errorMsg.arg(tr("header")));
  // Samples
  int iComp=0,nComp=0;
  CONST_LOCK_SAMPLES(double, sigSamples, sig)
    double conversionFactor=countPerUnit();
    int * decomp=new int[_nSamples];
    for(int i=0; i < _nSamples; i ++) {
      decomp[i]=(int) floor(sigSamples[ i ] * conversionFactor + 0.5);
    }
    int cs=Gse::checksum(decomp, _nSamples);
    Gse::diff(decomp, _nSamples);
    Gse::diff(decomp, _nSamples);
    char * comp=Gse::compress6(_nSamples, decomp, nComp);
    nComp-=80; // Force last line to be written after loop
    for(iComp=0;iComp<nComp;iComp+=80) {
      if(f.write(comp+iComp,80)!=80 || f.write("\n")!=1) {
        return writeError(sig, errorMsg.arg(tr("compressed samples")));
      }
    }
    nComp+=80; // Recover orignal nComp
    // Write beginning of last line
    nComp-=iComp; // Get the number of chars of last line
    if(f.write(comp+iComp,nComp)!=nComp) {
      return writeError(sig, errorMsg.arg(tr("compressed samples (last line)")));
    }
    // Fill the rest with spaces
    for(;nComp<80; nComp++) {
      if(f.write(" ", 1)!=1) {
        return writeError(sig, errorMsg.arg(tr("compressed samples (last line)")));
      }
    }
    // Write checksum
    header="\nCHK2 ";
    header+=QString::number(cs);
    header+="\n";
    if(f.write(header.toAscii().data(),header.count())!=header.count()) {
      return writeError(sig, errorMsg.arg(tr("check sum")));
    }
    delete [] comp;
    delete [] decomp;
  UNLOCK_SAMPLES(sig);
  restoreType(sig);
  return true;
}
bool GeopsyCore::Signal::writeMiniSeed ( QFile &  f) const

References GeopsyCore::SignalTemplate< double >::_nSamples, All, component(), CONST_LOCK_SAMPLES, countPerUnit(), East, QGpCoreTools::endl(), Horizontal, name(), North, GeopsyCore::SignalTemplate< double >::samples(), GeopsyCore::DoubleSignal::samplingFrequency(), t0(), timeReference(), QGpCoreTools::tr(), TRACE, UndefinedComponent, UNLOCK_SAMPLES, and Vertical.

{
  TRACE;
  LibMSeed::MSRecord * msr=LibMSeed::msr_init(0);
  msr->reclen=512; // Always output 512 byte records compatible with seiscomp mseedscan plugin
  msr->encoding=DE_FLOAT32;
  msr->numsamples=_nSamples;
  msr->sampletype='f';
  msr->byteorder=1; // Big endian
  msr->dataquality= 'D';
  if(name().indexOf("_")==2 && name().count()<=8) {
    strcpy(msr->network, name().left(2).toAscii().data());
    strcpy(msr->station, name().mid(3, 5).toAscii().data());
  } else { // Non standard signal names
    App::stream() << tr("Non standard signal name (NN_SSSSS), skip network code (NN)") << endl;
    strcpy(msr->network, "");
    strcpy(msr->station, name().left(11).toAscii().data());
  }
  strcpy(msr->location, "");
  // Set start time
  LibMSeed::BTime t;
  QDateTime st=timeReference();
  double t0round=round(t0()*10000.0);
  int t0secs=(int)floor(t0round*0.0001);
  st=st.addSecs(t0secs);
  t.year=st.date().year();
  t.day=QDate(t.year, 1,1).daysTo(st.date())+1;
  t.hour=st.time().hour();
  t.min=st.time().minute();
  t.sec=st.time().second();
  t.fract=(quint16) (t0round-t0secs*10000.0);
  msr->starttime=LibMSeed::ms_btime2hptime (&t);
  switch (component()) {
  case All:
  case Horizontal:
  case UndefinedComponent:
  case Vertical:
    strcpy(msr->channel, "BHZ");
    break;
  case North:
    strcpy(msr->channel, "BHN");
    break;
  case East:
    strcpy(msr->channel, "BHE");
    break;
  }
  msr->samprate=samplingFrequency();

  int packedSamples;
  double * samples=new double[_nSamples];
  msr->datasamples=samples;
  CONST_LOCK_SAMPLES(double, thisSamples, this)
    double factor=countPerUnit();
    for (int i=0; i<_nSamples; i++) {
      samples[i]=(float)(thisSamples[i]*factor);
    }
  UNLOCK_SAMPLES(this)
  msr_pack(msr, &miniSeedRecordHandler, &f, &packedSamples, 1, 0);
  msr->datasamples=0;
  delete [] samples;
  msr_free(&msr);
  return packedSamples==_nSamples;
}
bool GeopsyCore::Signal::writeSac ( QDataStream &  s) const

References GeopsyCore::SignalTemplate< double >::_nSamples, _t0, Acceleration, amplitudeUnit(), GeopsyCore::SACHeader::bools, GeopsyCore::SACHeader::chars, component(), componentLetter(), CONST_LOCK_SAMPLES, countPerUnit(), countPerVolt(), GeopsyCore::DoubleSignal::deltaT(), Displacement, QGpCoreTools::endl(), GeopsyCore::SACHeader::field, GeopsyCore::SACHeader::floats, GeopsyCore::SACHeader::ints, metaData(), name(), GeopsyCore::SignalTemplate< double >::nSamples(), receiver(), GeopsyCore::TimePick::registered(), GeopsyCore::DoubleSignal::restoreType(), GeopsyCore::DoubleSignal::saveType(), GeopsyCore::TimePick::staticId(), t0(), timePick(), timeReference(), QGpCoreTools::tr(), TRACE, UNLOCK_SAMPLES, Velocity, GeopsyCore::DoubleSignal::Waveform, GeopsyCore::SACHeader::write(), QGpCoreTools::Point2D::x(), QGpCoreTools::Point2D::y(), and QGpCoreTools::Point::z().

{
  TRACE;
  const DoubleSignal * sig=saveType(Waveform);

  static const QString errorMsg(tr("[SAC] Error while writing %1"));

  SACHeader h;
  h.floats.field.USER7=receiver().x();
  h.floats.field.USER8=receiver().y();
  h.floats.field.USER9=receiver().z();
  switch (amplitudeUnit()) {
  case Displacement: h.ints.field.IDEP=6; break;
  case Velocity: h.ints.field.IDEP=7; break;
  case Acceleration: h.ints.field.IDEP=8; break;
  default: h.ints.field.IDEP=5; break;
  }
  h.ints.field.NVHDR=6; // SAC version 6 compatible (2002)
  h.ints.field.IFTYPE=1; // iftype is time series
  h.bools.field.LEVEN=0xffffffff; // leven is true
  h.ints.field.NPTS=nSamples();
  h.floats.field.DELTA=deltaT();
  h.floats.field.SCALE=countPerVolt();
  if(name().length() > 8)
    strncpy(h.chars.field.KSTNM, name().toAscii().data(), 8);
  else
    strncpy(h.chars.field.KSTNM, name().toAscii().data(), name().length());
  strncpy(h.chars.field.KCMPNM, componentLetter(component()).toAscii().data(), 1);
  QDateTime td=timeReference();
  int secs=(int) floor(t0());
  td=td.addSecs(secs);
  QDate tdd=td.date();
  QTime tdt=td.time();
  h.ints.field.NZYEAR=tdd.year();
  h.ints.field.NZJDAY=QDate(tdd.year(), 1, 1).daysTo(tdd) + 1;
  h.ints.field.NZHOUR=tdt.hour();
  h.ints.field.NZMIN=tdt.minute();
  h.ints.field.NZSEC=tdt.second();
  double t0=_t0-(double) secs;
  h.ints.field.NZMSEC=(int) floor(t0 * 1000);
  t0 -= (double) h.ints.field.NZMSEC * 0.001;
  h.floats.field.B=t0;
  // Picks: SAC can store only ten without names
  //        save only pick named SAC_0 to SAC_9
  bool hasSacPick=false;
  const TimePick * tp=static_cast<const TimePick *>(metaData(TimePick::staticId()));
  for(int i=0;i<10;i++) {
    QString pn="SAC_"+QString::number(i);
    if(TimePick::registered(pn) && tp->hasIndex(0, pn)) {
      h.floats.field.T[i]=timePick(pn);
      hasSacPick=true;
    }
  }
  if(!hasSacPick) {
    App::stream() << tr("SAC header can store only 10 unamed time picks.\n"
                        "Only picks named 'SAC_0' to 'SAC_9'") << endl;
  }
  if(!h.write(s)) return writeError(sig, errorMsg.arg(tr("header")));
  qint64 offset=s.device()->pos();
  CONST_LOCK_SAMPLES(double, sigSamples, sig)
    float val;
    double conversionFactor=countPerUnit();
    for(int i=0; i < _nSamples; i ++) {
      val=(float) (sigSamples[ i ] * conversionFactor);
      s << val;
    }
  UNLOCK_SAMPLES(sig);
  if(s.device()->pos()-offset!=_nSamples*(int)sizeof(float))
    return writeError(sig, errorMsg.arg(tr("samples")));
  restoreType(sig);
  return true;
}
bool GeopsyCore::Signal::writeSeg2 ( QFile &  f) const

References GeopsyCore::SignalTemplate< double >::_nSamples, _t0, CONST_LOCK_SAMPLES, GeopsyCore::DoubleSignal::deltaT(), QGpCoreTools::endl(), maximumAmplitude(), metaData(), GeopsyCore::TimePick::names(), GeopsyCore::SignalTemplate< double >::nSamples(), GeopsyCore::DoubleSignal::restoreType(), GeopsyCore::DoubleSignal::saveType(), GeopsyCore::TimePick::staticId(), str, timePick(), QGpCoreTools::tr(), TRACE, UNLOCK_SAMPLES, GeopsyCore::DoubleSignal::Waveform, QGpCoreTools::Point2D::x(), QGpCoreTools::Point2D::y(), and QGpCoreTools::Point::z().

{
  TRACE;
  const DoubleSignal * sig=saveType(Waveform);
  char buf[ 32 ];

  double factor=32767./maximumAmplitude();
  unsigned long pos=f.pos();
  unsigned long posEnd;

  qint16 blocksize=32;
  qint16 length;
  int rem4, val;
  static const QString errorMsg(tr("[SEG2] Error while writing %1"));
  static const QString errorLengthMsg(errorMsg.arg("%1 (written length %2, instead of %3)"));
  QString str;
  *reinterpret_cast<qint16*>(buf)=0x4422;
  *reinterpret_cast<long*>(buf+4)=nSamples()*4;
  *reinterpret_cast<long*>(buf+8)=nSamples();
  *reinterpret_cast<qint16*>(buf+12)=2;
  if(f.write(buf, 32)!=32) return writeError(sig, errorMsg.arg("header"));
  str=QString("DELAY %1\n").arg(_t0, 0, 'g');
  length=str.length()+2;
  if(f.write((const char *)&length, 2)!=2)
    return writeError(sig, errorLengthMsg.arg("DELAY").arg(length-2));
  if(f.write(str.toAscii().data(), length-2)!=length-2)
    return writeError(sig, errorLengthMsg.arg("DELAY").arg(length-2));
  blocksize+=length;
  str=QString("SAMPLE_INTERVAL %1\n").arg(deltaT(), 0, 'g');
  length=str.length() + 2;
  if(f.write((char*) &length, 2)!=2)
    return writeError(sig, errorLengthMsg.arg("SAMPLE_INTERVAL").arg(length-2));
  if(f.write(str.toAscii().data(), length-2)!=length-2)
    return writeError(sig, errorLengthMsg.arg("SAMPLE_INTERVAL").arg(length-2));
  blocksize+=length;
  str=QString("DESCALING_FACTOR %1\n").arg(1./factor, 0, 'g');
  length=str.length() + 2;
  if(f.write((char*) & length, 2)!=2)
    return writeError(sig, errorLengthMsg.arg("DESCALING_FACTOR").arg(length-2));
  if(f.write(str.toAscii().data(), length-2)!=length-2)
    return writeError(sig, errorLengthMsg.arg("DESCALING_FACTOR").arg(length-2));
  blocksize+=length;
  str="STACK 1\n";
  length=str.length() + 2;
  if(f.write((char*) & length, 2)!=2)
    return writeError(sig, errorLengthMsg.arg("STACK").arg(length-2));
  if(f.write(str.toAscii().data(), length-2)!=length-2)
    return writeError(sig, errorLengthMsg.arg("STACK").arg(length-2));
  blocksize+=length;
  str=QString("SOURCE_LOCATION %1 %2 %3\n")
        .arg(_source.x(), 0, 'f')
        .arg(_source.y(), 0, 'f')
        .arg(_source.z(), 0, 'f');
  length=str.length() + 2;
  if(f.write((char*) & length, 2)!=2)
    return writeError(sig, errorLengthMsg.arg("SOURCE_LOCATION").arg(length-2));
  if(f.write(str.toAscii().data(), length-2)!=length-2)
    return writeError(sig, errorLengthMsg.arg("SOURCE_LOCATION").arg(length-2));
  blocksize+=length;
  str=QString("RECEIVER_LOCATION %1 %2 %3\n")
        .arg(_receiver.x(), 0, 'f')
        .arg(_receiver.y(), 0, 'f')
        .arg(_receiver.z(), 0, 'f');
  length=str.length() + 2;
  if(f.write((char*) & length, 2)!=2)
    return writeError(sig, errorLengthMsg.arg("RECEIVER_LOCATION").arg(length-2));
  if(f.write(str.toAscii().data(), length-2)!=length-2)
    return writeError(sig, errorLengthMsg.arg("RECEIVER_LOCATION").arg(length-2));
  blocksize+=length;
  const TimePick * tp=static_cast<const TimePick *>(metaData(TimePick::staticId()));
  QStringList picks=tp->names();
  for(QStringList::iterator it=picks.begin(); it!=picks.end(); it++) {
    QString pn=*it;
    if(pn.isEmpty() || pn.contains(" ")) {
      App::stream() << tr("SEG2 header cannot store arrival times named with complex names (\"%1\").").arg(pn) << endl;
    } else {
      double p=timePick(pn);
      if(p!=0.0) {
        str=QString("ARRIVAL_TIME %1 %2\n").arg(pn).arg(p, 0, 'g');
        length=str.length()+2;
        if(f.write((char*) &length, 2)!=2)
          return writeError(sig, errorLengthMsg.arg("ARRIVAL_TIME %3").arg(length-2).arg(pn));
        if(f.write(str.toAscii().data(), length-2)!=length-2)
          return writeError(sig, errorLengthMsg.arg("ARRIVAL_TIME %3").arg(length-2).arg(pn));
        blocksize+=length;
      }
    }
  }
  str=QString("NAME\n%1\n").arg(_name);
  length=str.length() + 2;
  if(f.write((const char*) & length, 2)!=2)
    return writeError(sig, errorLengthMsg.arg("NAME").arg(length-2));
  if(f.write(str.toAscii().data(), length-2)!=length-2)
    return writeError(sig, errorLengthMsg.arg("NAME").arg(length-2));
  blocksize+=length;
  length=-1;
  if(f.write((const char*) &length, 2)!=2)
    return writeError(sig, errorMsg.arg("end of signal header (length)"));
  blocksize+=2;
  rem4=blocksize % 4;
  if(rem4>0) {
    if(f.write(buf, rem4)!=rem4)
      return writeError(sig, errorMsg.arg("alignment of signal header(%1)").arg(rem4));
    blocksize+=rem4;
  }
  CONST_LOCK_SAMPLES(double, sigSamples, sig)
    for(int i=0; i<_nSamples; i++) {
      val=(int)(sigSamples[i]*factor);
      if(f.write((const char*) &val, 4)!=4) {
        return writeError(sig, errorMsg.arg("signal sample(%1)").arg(i));
      }
    }
  UNLOCK_SAMPLES(sig);
  posEnd=f.pos();
  f.seek(pos + 2);
  if(f.write((const char*) &blocksize, 2)!=2)
  return writeError(sig, errorMsg.arg("signal block size"));
  f.seek(posEnd);

  restoreType(sig);
  return true;
}
bool GeopsyCore::Signal::writeSegySu ( QDataStream &  s,
int  indexInFile,
bool  su 
) const

Writes this signal as a SEGY or SU trace with IEEE floating point. For SU export, sets su to true.

References GeopsyCore::SignalTemplate< double >::_nSamples, _t0, CONST_LOCK_SAMPLES, countPerUnit(), GeopsyCore::DoubleSignal::deltaT(), GeopsyCore::SEGYTraceHeader::field, GeopsyCore::SignalTemplate< double >::nSamples(), GeopsyCore::DoubleSignal::restoreType(), GeopsyCore::DoubleSignal::saveType(), GeopsyCore::SEGYTraceHeader::setCoordinateFactor(), GeopsyCore::SEGYTraceHeader::setElevationFactor(), GeopsyCore::SEGYTraceHeader::setNSamples(), GeopsyCore::SEGYTraceHeader::setReceiver(), GeopsyCore::SEGYTraceHeader::setSource(), GeopsyCore::SEGYTraceHeader::setSUT0(), GeopsyCore::SEGYTraceHeader::setT0(), t0(), timeReference(), TRACE, UNLOCK_SAMPLES, GeopsyCore::DoubleSignal::Waveform, and GeopsyCore::SEGYTraceHeader::write().

{
  TRACE;
  const DoubleSignal * sig=saveType(Waveform);

  SEGYTraceHeader h;

  h.field.traceNumberInLine=indexInFile+1;
  h.field.traceNumberInFile=indexInFile+1;
  h.field.originalRecordNumber=1;
  h.field.traceNumberInRecord=_numberInFile+1;
  h.field.traceIndentificationCode=1;
  h.field.numberSumVertical=1;
  h.field.numberStackHorizontal=1;
  h.field.dataUse=1; // Production data
  if(!h.setNSamples(nSamples())) {
     return false;
  }
  h.field.sampleInterval=(qint16)round(1.e+6*deltaT());
  // Calculate scale factor to apply on coordinates and elevations
  if(!h.setCoordinateFactor(_receiver, _source)) {
    return false;
  }
  if(!h.setElevationFactor(_receiver, _source)) {
    return false;
  }
  h.setReceiver(_receiver);
  h.setSource(_source);

  QDateTime td=timeReference();
  int secs=(int)floor(t0());
  td=td.addSecs(secs);
  QDate tdd=td.date();
  QTime tdt=td.time();
  h.field.year=tdd.year();
  quint16 year;
  year=tdd.year();
  h.field.day=QDate(year, 1, 1).daysTo(tdd) + 1;
  h.field.hour=tdt.hour();
  h.field.minute=tdt.minute();
  h.field.second=tdt.second();
  if(su) {
    if(!h.setSUT0(_t0)) {
      return false;
    }
  } else {
    if(!h.setT0(_t0)) {
      return false;
    }
  }
  h.field.timeBase=4;   // UTC time base
  h.field.gainType=1;   // Fixed gain
  h.field.correlated=1; // Not correlated

  h.write(s);
  ASSERT(sizeof(float)==4);
  CONST_LOCK_SAMPLES(double, sigSamples, sig)
    double conversionFactor=countPerUnit();
    for(int i=0; i<_nSamples; i++) {
      s << (float) (sigSamples[i]*conversionFactor);
    }
  UNLOCK_SAMPLES(this)

  restoreType(sig);
  return true;
}

Re-implement this function to offer XML restore (children and properties) support to your class.

From tag and map (with contains the attibute value) return a unique identifier under the format of a XMLMember. XMLMember is initialized with 3 types of contructors:

  • An integer: id number of a property
  • A XMLClass * : a child of this object identified by tag
  • Default constructor: error, unknow child or property

Map of attributes can be inspected in this way (can be achived also in xml_setProperty()):

    static const QString tmp("childrenName");
    XMLRestoreAttributeIterator it=map.find(tmp);
    if(it!=map.end()) {
      // found attribute "childrenName"
    }

If the map of attributes is not used:

    Q_UNUSED(attributes);
    if(tag=="x1") return XMLMember(0);
    else if(tag=="y1") return XMLMember(1);
    else if(tag=="x2") return XMLMember(2);
    else if(tag=="y2") return XMLMember(3);
    else return XMLMember(XMLMember::Unknown);

Arithmetic operations + and - apply to XMLMember to avoid confusion of property id numbers between inherited objects. Offset 3 corresponds to the number of properties defined in this object.

    if(tag=="anInteger") return XMLMember(0);
    else if(tag=="aString") return XMLMember(1);
    else if(tag=="aDouble") return XMLMember(2);
    return AbstractLine::xml_member(tag, attributes, context)+3;

For the arguments of this function use Macro XML_MEMBER_ARGS.

Reimplemented from QGpCoreTools::XMLClass.

References GeopsyCore::MetaDataMap::add(), GeopsyCore::MetaDataMap::data(), QGpCoreTools::endl(), QGpCoreTools::XMLClassFactory::id(), GeopsyCore::MetaDataFactory::instance(), GeopsyCore::SignalDB::resolveMetaData(), GeopsyCore::MetaData::storeAsXML(), QGpCoreTools::tr(), and QGpCoreTools::XMLClass::xml_tagName().

Referenced by GeopsyCore::XMLSignal::xml_member().

{
  Q_UNUSED(context);
  // First look for standard members
  if(tag.size()>=2) {
    switch (tag[0].unicode()) {
    case 'A':
      if(tag=="AmplitudeUnit") return XMLMember(11);
      break;
    case 'B':
      if(tag=="ByteIncrement") return XMLMember(15);
      break;
    case 'b': // Special tag handled by XMLParser directly, avoid meta data queries
      if(tag=="binDataFile") return XMLMember(XMLMember::Unknown);
      break;
    case 'C':
      if(tag.size()>=4) {
        switch (tag[3].unicode()) {
        case 'c':
          if(tag=="CheckSum") return XMLMember(16);
          break;
        case 'n':
          if(tag=="CountPerVolt") return XMLMember(9);
          break;
        case 'p':
          if(tag=="Component") return XMLMember(2);
          break;
        default:
          break;
        }
      }
      break;
    case 'D':
      if(tag=="DeltaT") return XMLMember(5);
      break;
    case 'I':
      if(tag=="ID") return XMLMember(0);
      break;
    case 'N':
      switch (tag[1].unicode()) {
      case 'a':
        if(tag=="Name") return XMLMember(1);
        break;
      case 'S':
        if(tag=="NSamples") return XMLMember(7);
        break;
      case 'u':
        if(tag=="NumberInFile") return XMLMember(8);
        break;
      default:
        break;
      }
      break;
    case 'O':
      if(tag=="OffsetInFile") return XMLMember(14);
      break;
    case 'R':
      if(tag=="Receiver") return XMLMember(12);
      break;
    case 'S':
      if(tag=="Source") return XMLMember(13);
      break;
    case 'T':
      switch (tag[1].unicode()) {
      case '0':
        if(tag=="T0") return XMLMember(3);
        break;
      case 'i':
        if(tag=="TimeReference") return XMLMember(4);
        break;
      case 'y':
        if(tag=="Type") return XMLMember(6);
        break;
      default:
        break;
      }
      break;
    case 'V':
      if(tag=="VoltPerUnit") return XMLMember(10);
      break;
    default:
      break;
    }
  }
  // Not a standard data name, look for non-standard ones...
  static QString sharedAtt="sharedId";
  XMLRestoreAttributeIterator it=attributes.find(sharedAtt);
  if(it!=attributes.end()) { // It is a link to shared data
    MetaData * d=_db->resolveMetaData(it.value().toInt());
    if(d) {
      if(tag==d->xml_tagName()) {
        _optionalData.add(d);
        return XMLMember(101);
      } else {
        App::stream() << tr("Mismatch resolving shared meta data shared id %1: expecting type %2, found %3.")
            .arg(it.value().toInt()).arg(tag.toString()).arg(d->xml_tagName()) << endl;
      }
    }
  } else { // Not shared
    int id=MetaDataFactory::instance()->id(tag.toString());
    if(id>-1) {
      MetaData * d=_optionalData.data(id);
      if(d->storeAsXML()) {
        return XMLMember(d);
      } else {
        return XMLMember(100);
      }
    } else {
      App::stream() << tr("Unknown MetaData %1").arg(tag.toString()) << endl;
    }
  }
  return XMLMember(XMLMember::Unknown);
}

Re-implement this function to offer XML restore properties support to your class.

From memberID set the corresponding property with value content. The map of attributes is given as a supplementary information (not useful in all cases).

For a general case:

  Q_UNUSED(attributes);
  double val=content.toDouble();
  switch (memberID) {
  case 0:
    _x1=val;
    return true;
  case 1:
    _y1=val;
    return true;
  case 2:
    _x2=val;
    return true;
  case 3:
    _y2=val;
    return true;
  default:
    return false;
  }

For classes inheriting other classes (see also xml_member())

  switch (memberID) {
  case 0:
    _anInteger=content.toString();
    return true;
  case 1:
    _aString=content.toInt();
    return true;
  case 2:
    _aDouble=content.toDouble();
    return true;
  default:
    return AbstractLine::xml_setProperty(memberID-3, map, content);

For the arguments of this function use Macro XML_SETPROPERTY_ARGS.

Reimplemented from QGpCoreTools::XMLClass.

References GeopsyCore::MetaDataMap::data(), GeopsyCore::MetaData::fromString(), QGpCoreTools::Point::fromString(), GeopsyCore::MetaDataFactory::instance(), setAmplitudeUnit(), setByteIncrement(), setComponent(), setCountPerVolt(), setDeltaT(), setId(), setName(), setNSamples(), setNumberInFile(), setOffsetInFile(), setReceiver(), setSource(), setT0(), setTimeReference(), GeopsyCore::DoubleSignal::setType(), setVoltPerUnit(), standardAmplitudeUnit(), standardComponent(), and GeopsyCore::DoubleSignal::type().

Referenced by GeopsyCore::XMLSignal::xml_setProperty().

{
  Q_UNUSED(context);
  switch (memberID) {
  case 0:
    setId(content.toInt());
    return true;
  case 1:
    setName(content.toString());
    return true;
  case 2:
    setComponent(standardComponent(content.toString()));
    return true;
  case 3:
    setT0(content.toDouble());
    return true;
  case 4:
    setTimeReference(content.toString());
    return true;
  case 5:
    setDeltaT(content.toDouble());
    return true;
  case 6:
    setType(type(content.toString()));
    return true;
  case 7:
    setNSamples(content.toInt());
    return true;
  case 8:
    setNumberInFile (content.toInt());
    return true;
  case 9:
    setCountPerVolt (content.toDouble());
    return true;
  case 10:
    setVoltPerUnit (content.toDouble());
    return true;
  case 11:
    setAmplitudeUnit(standardAmplitudeUnit(content.toString()));
    return true;
  case 12: {
      Point p;
      p.fromString(content);
      setReceiver(p);
      return true;
    }
  case 13: {
      Point p;
      p.fromString(content);
      setSource(p);
      return true;
    }
  case 14:
    setOffsetInFile (content.toInt());
    return true;
  case 15:
    setByteIncrement (content.toInt());
    return true;
  case 16: // checksum, ignored, not stored anymore
    return true;
  case 100: {
      // Meta data already exist, tested before...
      MetaData * d=_optionalData.data(MetaDataFactory::instance()->id(tag.toString()));
      static const QString tmp("index");
      XMLRestoreAttributeIterator it=attributes.find(tmp);
      if(it!=attributes.end()) {
        d->fromString(it.value().toString(), content.toString());
      } else {
        d->fromString(0, content.toString());
      }
    }
    return true;
  case 101:
    return true;
  default:
    return false;
  }
}
virtual const QString& GeopsyCore::Signal::xml_tagName ( ) const [inline, virtual]

Implements QGpCoreTools::XMLClass.

{return xmlSignalTag;}

Reimplemented from QGpCoreTools::XMLClass.

References QGpCoreTools::SortedVector< Key, T >::at(), GeopsyCore::MetaDataMap::count(), GeopsyCore::MetaData::isStored(), QGpCoreTools::SharedObject::referenceCount(), GeopsyCore::MetaData::storeAsXML(), GeopsyCore::MetaDataMap::vector(), QGpCoreTools::XMLClass::xml_attributes(), and QGpCoreTools::XMLClass::xml_save().

{
  Q_UNUSED(context);
  // Optional meta data (only if not shared)
  int n=_optionalData.count();
  const SortedVector<int, MetaData>& v=_optionalData.vector();
  for(int i=0; i<n; i++) {
    const MetaData * d=v.at(i);
    if(d->isStored() && d->storeAsXML() && d->referenceCount()==1) {
      XMLSaveAttributes att;
      d->xml_attributes(att, context);
      d->xml_save(s, context, att);
    }
  }
}

Reimplemented from QGpCoreTools::XMLClass.

References amplitudeUnitStandardName(), QGpCoreTools::SortedVector< Key, T >::at(), byteIncrement(), componentStandardName(), GeopsyCore::MetaDataMap::count(), countPerVolt(), GeopsyCore::DoubleSignal::deltaT(), GeopsyCore::MetaData::isStored(), name(), GeopsyCore::SignalTemplate< double >::nSamples(), numberInFile(), offsetInFile(), receiver(), QGpCoreTools::SharedObject::referenceCount(), source(), GeopsyCore::MetaData::storeAsXML(), t0(), timeReferenceString(), GeopsyCore::DoubleSignal::type(), GeopsyCore::DoubleSignal::typeString(), GeopsyCore::MetaDataMap::vector(), voltPerUnit(), GeopsyCore::MetaData::writeProperties(), QGpCoreTools::XMLClass::writeProperty(), QGpCoreTools::XMLClass::xml_attributes(), and GeopsyCore::MetaData::xml_writeLink().

Referenced by GeopsyCore::XMLSignal::xml_writeProperties().

{
  Q_UNUSED(context);
  writeProperty(s, "ID", id());
  writeProperty(s, "Name", name());
  writeProperty(s, "Component", componentStandardName());
  writeProperty(s, "T0", t0());
  writeProperty(s, "TimeReference", timeReferenceString());
  writeProperty(s, "DeltaT", deltaT());
  writeProperty(s, "Type", typeString(type()));
  writeProperty(s, "NSamples", nSamples());
  writeProperty(s, "CountPerVolt", countPerVolt());
  writeProperty(s, "VoltPerUnit", voltPerUnit());
  writeProperty(s, "AmplitudeUnit", amplitudeUnitStandardName());
  writeProperty(s, "NumberInFile", numberInFile());
  writeProperty(s, "Receiver", receiver().toString(15));
  writeProperty(s, "Source", source().toString(15));
  writeProperty(s, "OffsetInFile", offsetInFile());
  writeProperty(s, "ByteIncrement", byteIncrement());
  // Optional data
  int n=_optionalData.count();
  const SortedVector<int, MetaData>& v=_optionalData.vector();
  for(int i=0; i<n; i++) {
    const MetaData * d=v.at(i);
    if(d->isStored()) {
      if(d->referenceCount()>1) {
        d->xml_writeLink(s);
      } else if(!d->storeAsXML()) {
        XMLSaveAttributes att;
        d->xml_attributes(att, context);
        d->writeProperties(s, att);
      }
    }
  }
}

Member Data Documentation

QMutex GeopsyCore::Signal::_amplitudeMutex [mutable, protected]
double GeopsyCore::Signal::_averageAmplitude [mutable, protected]

Referenced by averageAmplitude().

double GeopsyCore::Signal::_maxAmplitude [mutable, protected]

Referenced by maximumAmplitude().

double GeopsyCore::Signal::_t0 [protected]
uint GeopsyCore::Signal::_unused [protected]
const QString GeopsyCore::Signal::xmlSignalTag = "Signal" [static]

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