GeopsyCore/Signal.h
Go to the documentation of this file.
00001 /***************************************************************************
00002 **
00003 **  This file is part of GeopsyCore.
00004 **
00005 **  This library is free software; you can redistribute it and/or
00006 **  modify it under the terms of the GNU Lesser General Public
00007 **  License as published by the Free Software Foundation; either
00008 **  version 2.1 of the License, or (at your option) any later version.
00009 **
00010 **  This file is distributed in the hope that it will be useful, but WITHOUT
00011 **  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 **  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
00013 **  License for more details.
00014 **
00015 **  You should have received a copy of the GNU Lesser General Public
00016 **  License along with this library; if not, write to the Free Software
00017 **  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018 **
00019 **  See http://www.geopsy.org for more information.
00020 **
00021 **  Created : 2003-11-10
00022 **  Authors :
00023 **    Marc Wathelet
00024 **    Marc Wathelet (ULg, Liège, Belgium)
00025 **    Marc Wathelet (LGIT, Grenoble, France)
00026 **
00027 ***************************************************************************/
00028 
00029 #ifndef SIGNAL_H
00030 #define SIGNAL_H
00031 
00032 #include <QGpCoreTools.h>
00033 
00034 #include "GeopsyCoreDLLExport.h"
00035 #include "SignalFile.h"
00036 #include "DoubleSignal.h"
00037 #include "MetaData.h"
00038 #include "MetaDataIndex.h"
00039 #include "DuplicateRays.h"
00040 #include "SparseTimeRange.h"
00041 #include "MiniSeedRecords.h"
00042 #include "GuralpRecords.h"
00043 #include "MetaDataMap.h"
00044 #include "MetaDataFactory.h"
00045 #include "TimePick.h"
00046 #include "Comments.h"
00047 
00048 namespace GeopsyCore {
00049 
00050 class SubSignalPool;
00051 class SignalDB;
00052 
00053 class GEOPSYCORE_EXPORT Signal: public DoubleSignal, public SharedObject, public XMLClass
00054 {
00055   TRANSLATIONS( "Signal" )
00056 public:
00057   enum Components {Vertical, North, East, All, Horizontal, UndefinedComponent};
00058   enum PickWhat {Min=1, Max=2};
00059   enum AmplitudeUnits {UndefinedUnit, Displacement, Velocity, Acceleration, CustomUnit};
00060 
00061   Signal(SignalDB * db);
00062   Signal(const Signal& sig, SignalDB * db=0);
00063   virtual ~Signal();
00064 
00065   virtual const QString& xml_tagName() const {return xmlSignalTag;}
00066   static const QString xmlSignalTag;
00067 
00068   static Signal * newCopy(Signal * sig);
00069 
00070   void setTemporary();
00071   void copyBasicProperties(const Signal& p);
00072 
00073   bool operator<(const Signal& o) const {return compare(o)<0;}
00074   bool operator>(const Signal& o) const {return compare(o)>0;}
00075   bool operator==(const Signal& o) const {return compare(o)==0;}
00076   int compare(const Signal& o) const;
00077 
00078   // Modification control
00079   bool isHeaderModified() const {return _isHeaderModified;}
00080   void setHeaderModified(bool m) {_isHeaderModified=m;}
00081   inline bool warnReadOnlySamples() const;
00082   bool isReadOnlySamples() const {return _isReadOnlySamples;}
00083   void setReadOnlySamples(bool ro) {_isReadOnlySamples=ro;}
00084   void resetAmplitudes() const {_maxAmplitude=1e99; _averageAmplitude=1e99;}
00085 
00086   // Functions to save signal values into a stream
00087   bool writeSeg2(QFile& f) const;
00088   bool writeAscii(QFile& f, int numInFile) const;
00089   bool writeSac(QDataStream& s) const;
00090   bool writeSegySu(QDataStream& s, int indexInFile, bool su) const;
00091   bool writeGse(QFile& f) const;
00092   bool writeMiniSeed(QFile& f) const;
00093 
00094   // Interface functions to data members
00095   QString name() const {return _name;}
00096   void setName(QString n) {_name=n;}
00097   Components component() const {return _component;}
00098   void setComponent(Components c) {_component=c;}
00099   static Components userComponent(QString c);
00100   static Components standardComponent(QString c);
00101   static QString userName(Components c);
00102   static QString standardName(Components c);
00103   static Components globalSeismographicNetworkComponent(const char * c);
00104   static QString componentLetter(Components c);
00105   QString componentUserName() const {return userName(_component);}
00106   QString componentStandardName() const {return standardName(_component);}
00107   QString nameComponent() const;
00108   inline virtual QString debugName() const;
00109 
00110   const Point& source() const {return _source;}
00111   void setSource(const Point& p) {_source=p;}
00112   const Point& receiver() const {return _receiver;}
00113   void setReceiver(const Point& p) {_receiver=p;}
00114   double sourceReceiverDistance() const {return _source.distanceTo(_receiver);}
00115   double sourceReceiverAzimuth() const {return _source.azimuthTo(_receiver);}
00116 
00117   virtual void setNSamples(int n);
00118   virtual void setDeltaT(double newval);
00119 
00120   double t0() const {return _t0;}
00121   void setT0(double t);
00122   TIME t0AsTIME() const {return DateTime::capAddSecs(_timeReference, t0());}
00123   QDateTime timeReference() const {return _timeReference;}
00124   QString timeReferenceString() const {return _timeReference.toString( "dd/MM/yyyy hh:mm:ss" );}
00125   void setTimeReference(QDateTime t) {_timeReference=t;}
00126   void setTimeReference(QString t) {_timeReference=QDateTime::fromString(t, "dd/MM/yyyy hh:mm:ss" );}
00127   double endTime() const {return t0() + deltaT() * _nSamples;}
00128   const SparseTimeRange& timeRange() const {return _timeRange;}
00129   void setTimeRange(const SparseTimeRange& r);
00130   TIME endTimeAsTIME() const {return DateTime::capAddSecs(_timeReference, endTime());}
00131 
00132   SignalFile * file() const {return _file;}
00133   void setFile(SignalFile * f) {_file=f;}
00134   bool isOriginalFile() const {if(file() && file() ->isOriginalFile()) return true; else return false;}
00135 
00136   int numberInFile() const {return _numberInFile;}
00137   void setNumberInFile(int i) {_numberInFile=i;}
00138   int offsetInFile() const {return _offsetInFile;}
00139   void setOffsetInFile(int o) {_offsetInFile=o;}
00140   int byteIncrement() const {return _byteIncrement;}
00141   void setByteIncrement(int i) {_byteIncrement=i;}
00142 
00143   double countPerVolt() const {return _countPerVolt;}
00144   void setCountPerVolt(double c);
00145 
00146   double voltPerCount() const {return 1.0/_countPerVolt;}
00147   void setVoltPerCount(double c) {setCountPerVolt(1.0/c);}
00148 
00149   double voltPerUnit() const {return _voltPerUnit;}
00150   void setVoltPerUnit(double c);
00151 
00152   double unitPerVolt() const {return 1.0/_voltPerUnit;}
00153   void setUnitPerVolt(double c) {setVoltPerUnit(1.0/c);}
00154 
00155   double unitPerCount() const {return 1.0/countPerUnit();}
00156   double countPerUnit() const {return _countPerVolt * _voltPerUnit;}
00157 
00158   int id() const {return _id;}
00159   void setId(int id);
00160 
00161   SignalDB * database() const {return _db;}
00162   void setDatabase(SignalDB * db) {_db=db;}
00163 
00164   AmplitudeUnits amplitudeUnit() const {return _amplitudeUnit;}
00165   void setAmplitudeUnit(AmplitudeUnits u) {_amplitudeUnit=u;}
00166   static AmplitudeUnits userAmplitudeUnit(QString u);
00167   static AmplitudeUnits standardAmplitudeUnit(QString u);
00168   static QString userName(AmplitudeUnits u);
00169   static QString standardName(AmplitudeUnits u);
00170   QString amplitudeUnitUserName() const {return userName(_amplitudeUnit);}
00171   QString amplitudeUnitStandardName() const {return standardName(_amplitudeUnit);}
00172   QString effectiveAmplitudeUnit() const;
00173 
00174   double maximumAmplitude(int itmin=0, int itmax=0) const;
00175   double maximumAmplitudeAt(const TimeRange& r=TimeRange()) const;
00176   double averageAmplitude(int itmin=0, int itmax=0) const;
00177   inline double amplitudeAt(double abscissa) const;
00178 
00179   // Funtion to perform signal processing
00180   inline bool taper(const TimeRange& tw, const TaperParameters& param);
00181   void copySamplesFrom(const Signal * sig) {DoubleSignal::copySamplesFrom(sig);}
00182   inline void copySamplesFrom(const Signal * sig, const TimeRange& tw);
00183   Signal * cut(TimeRange r) const;
00184   inline int add(const Signal * sig, const TimeRange& tw, bool checkInvalid=false, double invalidValue=1e99);
00185   void pickCoppens(const QString& pickName, double delta, double end, double start=0.,
00186                     bool relative=false, double mute=0. );
00187   void pickMinMax(const QString& pickName, double from, double to, PickWhat what);
00188   double correlation(const Signal * sig, const TimeRange& tw);
00189   void correlation(const Signal * s1, const Signal * s2, double maxDelay);
00190   void normalizedCorrelation(const Signal * s1, const Signal * s2, double maxDelay);
00191 
00192   // Function to restore old databases (compatibility)
00193   bool read(FILE *f, SignalDB * db);
00194 
00195   virtual double * lockSamples();
00196   virtual const double * constLockSamples() const;
00197   double * lockSamples(char * file, int line) {return DoubleSignal::lockSamples(file, line);}
00198   const double * constLockSamples(char * file, int line) const {return DoubleSignal::constLockSamples(file, line);}
00199 
00200   // Generic MetaData interface
00201   void addMetaData(MetaData * d) {_optionalData.add(d);}
00202   void removeMetaData(int id) {_optionalData.remove(id);}
00203   bool hasMetaData(int id) const {return _optionalData.hasData(id);}
00204   MetaData * metaData(int id) {return _optionalData.data(id);}
00205   const MetaData * metaData(int id) const {return _optionalData.data(id);}
00206   const MetaDataMap& metaDataMap() const {return _optionalData;}
00207 
00208   QVariant header(const MetaDataIndex& index) const;
00209   bool setHeader(const MetaDataIndex& index, QVariant val);
00210 
00211   // Specific optional predefined MetaData
00212   inline double timePick(const QString& name) const;
00213   double roundTimePick(const QString& name) const;
00214   inline void setTimePick(const QString& name, double time);
00215   inline int timePickCount() const;
00216 
00217   inline void setMiniSeedRecords(const MiniSeedRecords& r);
00218   inline const MiniSeedRecords& miniSeedRecords() const;
00219 
00220   inline void setGuralpRecords(const GuralpRecords& r);
00221   inline const GuralpRecords& guralpRecords() const;
00222 
00223   inline QString comments() const;
00224   inline void setComments(QString c);
00225 
00226   // XML serialization
00227   virtual void xml_writeProperties(XML_WRITEPROPERTIES_ARGS) const;
00228   virtual void xml_writeChildren(XML_WRITECHILDREN_ARGS) const;
00229   virtual bool xml_setProperty(XML_SETPROPERTY_ARGS);
00230   virtual XMLMember xml_member(XML_MEMBER_ARGS);
00231 protected:
00232   // Updated by maxAmplitude()
00233   mutable double _maxAmplitude;
00234   // Updated by averageAmplitude()
00235   mutable double _averageAmplitude;
00236   mutable QMutex _amplitudeMutex;
00237 
00238   uint _isHeaderModified:1;
00239   uint _isReadOnlySamples:1;
00240   uint _unused:30;
00241 
00242   double _t0;
00243   SparseTimeRange _timeRange;
00244 private:
00245   int _id;    // Unique ID in the database
00246   QDateTime _timeReference;  // reference time and date of acquisition
00247   Point _receiver;
00248   Point _source;
00249   QString _name;
00250   SignalFile * _file;
00251   int _numberInFile;
00252   qint64 _offsetInFile;
00253   int _byteIncrement;
00254   Components _component;
00255   MetaDataMap _optionalData;
00256 
00257   double _countPerVolt;
00258   double _voltPerUnit;
00259   AmplitudeUnits _amplitudeUnit;
00260 
00261   SignalDB * _db;
00262 
00263   bool writeError(const DoubleSignal * sig, QString logMessage) const;
00264   bool readError(const char * buf);
00265 
00266   // Functions to load samples from specific file formats into memory
00267   bool load(double * samples) const;
00268   bool loadGeopsySignal(double * samples) const;
00269   bool loadSeg2(double * samples) const;
00270   bool loadSegD(double * samples) const;
00271   bool loadSu(double * samples, QDataStream::ByteOrder bo) const;
00272   bool loadSegY(double * samples, QDataStream::ByteOrder bo) const;
00273   bool loadPasscalSegY(double * samples, QDataStream::ByteOrder bo) const;
00274   bool loadSac(double * samples, QDataStream::ByteOrder bo) const;
00275   bool loadRD3(double * samples) const;
00276   bool loadNiSismo(double * samples) const;
00277   bool loadRadan(double * samples) const;
00278   bool loadGse2(double * samples) const;
00279   bool loadCity2(double * samples) const {return loadAscii(samples, "Loading City 2 values from %1");}
00280   bool loadAscii(double * samples, const QString &title) const;
00281   bool loadSismalp(double * samples) const;
00282   bool loadSyscom3Bytes(double * samples) const;
00283   bool loadSyscom2Bytes(double * samples) const;
00284   bool loadGuralpGcf(double * samples) const;
00285   bool loadWav(double * samples) const;
00286   bool loadMiniSeed(double * samples) const;
00287   bool loadAsciiOneColumn(double * samples) const;
00288   bool loadFourier(double * samples) const;
00289   static bool loadMultiChannelsWav(Signal * sig0, double * samples0);
00290   static bool loadMultiChannelsAscii(Signal * sig0, double * samples0);
00291   static bool loadMultiChannelsFourier(Signal * sig0, double * samples0);
00292   static SubSignalPool beginMultiChannelLoad(Signal * sig0, double * samples0,
00293                                                  int & nSig, double **& samplePtr);
00294   static void endMultiChannelLoad(Signal * sig0, const SubSignalPool& loadedSigs, SignalType typeInFile=DoubleSignal::Waveform);
00295   static void miniSeedRecordHandler (char *record, int reclen, void *f);
00296 };
00297 
00298 inline bool Signal::warnReadOnlySamples() const
00299 {
00300   TRACE;
00301   if(_isReadOnlySamples) {
00302     App::stream() << tr("Trying to modify read only signal %1, aborted").arg(name()) << endl;
00303     return true;
00304   } else return false;
00305 }
00306 
00307 inline QString Signal::debugName() const
00308 {
00309   TRACE;
00310   return _name + "_" + componentLetter(_component) + QString::number(_id);
00311 }
00312 
00313 inline double Signal::amplitudeAt(double abscissa) const
00314 {
00315   TRACE;
00316   if(_type==Waveform)
00317     return DoubleSignal::amplitudeAt(abscissa - _t0);
00318   else
00319     return DoubleSignal::amplitudeAt(abscissa);
00320 }
00321 
00322 inline bool Signal::taper(const TimeRange& tw, const TaperParameters& param)
00323 {
00324   TRACE;
00325   return DoubleSignal::taper(tw.shifted(-_t0), param);
00326 }
00327 
00328 inline void Signal::copySamplesFrom(const Signal * sig, const TimeRange& tw)
00329 {
00330   TRACE;
00331   DoubleSignal::copySamplesFrom(sig, tw.start()-sig->t0(), tw.start()-t0(), tw.lengthSeconds());
00332 }
00333 
00334 inline int Signal::add(const Signal * sig, const TimeRange& tw, bool checkInvalid, double invalidValue)
00335 {
00336   TRACE;
00337   return DoubleSignal::add(sig, tw.start() - sig->t0(), tw.start() - t0(), tw.lengthSeconds(),
00338                                checkInvalid, invalidValue);
00339 }
00340 
00341 inline double Signal::correlation(const Signal * sig, const TimeRange& tw)
00342 {
00343   TRACE;
00344   return DoubleSignal::correlation(sig, tw.start() - sig->t0(), tw.start() - t0(), tw.lengthSeconds());
00345 }
00346 
00347 inline double Signal::timePick(const QString& name) const
00348 {
00349   // TimePick is always available in MetaDataFactory, hence o is never null
00350   const TimePick * o=static_cast<const TimePick *>(metaData(TimePick::staticId()));
00351   return o->value(name);
00352 }
00353 
00354 inline void Signal::setTimePick(const QString& name, double time)
00355 {
00356   // TimePick is always available in MetaDataFactory, hence o is never null
00357   TimePick * o=static_cast<TimePick *>(metaData(TimePick::staticId()));
00358   o->setValue(name, time);
00359 }
00360 
00361 inline int Signal::timePickCount() const
00362 {
00363   // TimePick is always available in MetaDataFactory, hence o is never null
00364   const TimePick * o=static_cast<const TimePick *>(metaData(TimePick::staticId()));
00365   return o->count(0);
00366 }
00367 
00368 inline void Signal::setMiniSeedRecords(const MiniSeedRecords& r)
00369 {
00370   // MiniSeedRecords is always available in MetaDataFactory, hence o is never null
00371   MiniSeedRecords * o=static_cast<MiniSeedRecords *>(metaData(MiniSeedRecords::staticId()));
00372   *o=r;
00373 }
00374 
00375 inline const MiniSeedRecords& Signal::miniSeedRecords() const
00376 {
00377   // MiniSeedRecords is always available in MetaDataFactory, hence o is never null
00378   const MiniSeedRecords * o=static_cast<const MiniSeedRecords *>(metaData(MiniSeedRecords::staticId()));
00379   return *o;
00380 }
00381 
00382 inline void Signal::setGuralpRecords(const GuralpRecords& r)
00383 {
00384   // GuralpRecords is always available in MetaDataFactory, hence o is never null
00385   GuralpRecords * o=static_cast<GuralpRecords *>(metaData(GuralpRecords::staticId()));
00386   *o=r;
00387 }
00388 
00389 inline const GuralpRecords& Signal::guralpRecords() const
00390 {
00391   // GuralpRecords is always available in MetaDataFactory, hence o is never null
00392   const GuralpRecords * o=static_cast<const GuralpRecords *>(metaData(GuralpRecords::staticId()));
00393   return *o;
00394 }
00395 
00396 inline QString Signal::comments() const
00397 {
00398   // Comments is always available in MetaDataFactory, hence o is never null
00399   const Comments * o=static_cast<const Comments *>(metaData(Comments::staticId()));
00400   return o->value();
00401 }
00402 
00403 inline void Signal::setComments(QString c)
00404 {
00405   // Comments is always available in MetaDataFactory, hence o is never null
00406   Comments * o=static_cast<Comments *>(metaData(Comments::staticId()));
00407   return o->setValue(c);
00408 }
00409 
00410 } // namespace GeopsyCore
00411 
00412 #endif // SIGNAL_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines