00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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
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
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
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
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
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
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
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
00233 mutable double _maxAmplitude;
00234
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;
00246 QDateTime _timeReference;
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
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
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
00357 TimePick * o=static_cast<TimePick *>(metaData(TimePick::staticId()));
00358 o->setValue(name, time);
00359 }
00360
00361 inline int Signal::timePickCount() const
00362 {
00363
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
00371 MiniSeedRecords * o=static_cast<MiniSeedRecords *>(metaData(MiniSeedRecords::staticId()));
00372 *o=r;
00373 }
00374
00375 inline const MiniSeedRecords& Signal::miniSeedRecords() const
00376 {
00377
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
00385 GuralpRecords * o=static_cast<GuralpRecords *>(metaData(GuralpRecords::staticId()));
00386 *o=r;
00387 }
00388
00389 inline const GuralpRecords& Signal::guralpRecords() const
00390 {
00391
00392 const GuralpRecords * o=static_cast<const GuralpRecords *>(metaData(GuralpRecords::staticId()));
00393 return *o;
00394 }
00395
00396 inline QString Signal::comments() const
00397 {
00398
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
00406 Comments * o=static_cast<Comments *>(metaData(Comments::staticId()));
00407 return o->setValue(c);
00408 }
00409
00410 }
00411
00412 #endif // SIGNAL_H