Brief description of class still missing. More...
#include <Process.h>
Signals | |
void | readyToPick (SubSignalPool *subPool, QString key, TimeRange recRange) |
Public Member Functions | |
bool | failed () const |
Process () | |
bool | setArguments (int &argc, char **argv) |
~Process () | |
Static Public Attributes | |
static const QString | defaultDataDir = "../data" |
static const QString | defaultDestDir = "../sac" |
static const QString | defaultStationFile = "stations.txt" |
static const QString | defaultTimeDir = "../timedrift" |
static const QString | defaultTitanFormatFile = "/kephrenrtu/titanUncorrectedT0.ascfmt" |
static const QString | defaultWorkDir = "." |
Protected Member Functions | |
virtual void | run () |
Brief description of class still missing.
Full description of class still missing
Process::Process | ( | ) |
Description of constructor still missing
References QGpCoreTools::SharedObject::addReference(), defaultDataDir, defaultDestDir, defaultStationFile, defaultTimeDir, defaultTitanFormatFile, defaultWorkDir, readyToPick(), and TRACE.
{ TRACE; _dataDir=defaultDataDir; _timeDir=defaultTimeDir; _stationFile=defaultStationFile; _destDir=defaultDestDir; _workDir=defaultWorkDir; _titanFormatFile=defaultTitanFormatFile; _samplingFrequency=100.0; _pickOnly=false; _failed=false; connect(this, SIGNAL(readyToPick(SubSignalPool *, QString, TimeRange)), this, SLOT(pick(SubSignalPool *, QString, TimeRange)), Qt::QueuedConnection); _pickToolCount=0; // Special TITAN format _titanFormat.addReference(); // Prevent its deletion }
Description of destructor still missing
References QGpCoreTools::SharedObject::removeReference(), and TRACE.
{ TRACE; _titanFormat.removeReference(); // Allow its deletion }
bool Process::failed | ( | ) | const [inline] |
Referenced by main().
{return _failed;}
void Process::readyToPick | ( | SubSignalPool * | subPool, |
QString | key, | ||
TimeRange | recRange | ||
) | [signal] |
void Process::run | ( | ) | [protected, virtual] |
References QGpCoreTools::DateTime::addSeconds(), GeopsyCore::SubSignalPool::addSignal(), QGpCoreTools::Curve< pointType >::at(), GeopsyCore::GeopsyCoreEngine::clear(), GeopsyCore::Signal::component(), GeopsyCore::FilterParameters::convolutionWindow(), GeopsyCore::Signal::copySamplesFrom(), GeopsyCore::SubSignalPool::count(), GeopsyCore::GeopsyCoreEngine::currentDB(), GeopsyCore::Signal::cut(), QGpCoreTools::DateTime::dateTime(), GeopsyCore::DoubleSignal::deltaT(), GeopsyCore::TimeRange::end(), QGpCoreTools::endl(), GeopsyCore::Signal::endTime(), GeopsyCore::Signal::file(), GeopsyCore::DoubleSignal::filter(), GeopsyCore::SubSignalPool::first(), GeopsyCore::geopsyCore, GeopsyCore::TimeRange::intersection(), GeopsyCore::TimeRange::lengthSeconds(), GeopsyCore::GeopsyCoreEngine::load(), GeopsyCore::Signal::maximumAmplitude(), QGpCoreTools::Thread::msleep(), GeopsyCore::SignalTemplate< sampleType >::multiply(), GeopsyCore::SignalFile::name(), GeopsyCore::Signal::name(), GeopsyCore::SignalTemplate< sampleType >::nSamples(), GeopsyCore::SparseTimeRange::range(), readyToPick(), GeopsyCore::SubSignalPool::remove(), GeopsyCore::SubSignalPool::removeAll(), GeopsyCore::SignalDB::removeFile(), GeopsyCore::SignalDB::removeSignal(), GeopsyCore::DoubleSignal::samplingFrequency(), GeopsyCore::SubSignalPool::save(), QGpCoreTools::DateTime::secondsTo(), GeopsyCore::FilterParameters::setBand(), QGpCoreTools::DateTime::setDateTime(), GeopsyCore::FilterParameters::setMethod(), GeopsyCore::FilterParameters::setMinimumFrequency(), GeopsyCore::Signal::setNSamples(), GeopsyCore::Signal::setT0(), GeopsyCore::Signal::setTimePick(), GeopsyCore::Signal::setTimeReference(), GeopsyCore::FilterParameters::setWidth(), GeopsyCore::TaperParameters::setWindow(), GeopsyCore::DoubleSignal::shift(), GeopsyCore::TimeRange::start(), GeopsyCore::Signal::t0(), GeopsyCore::Signal::timePick(), GeopsyCore::Signal::timeRange(), GeopsyCore::Signal::timeReference(), QGpCoreTools::DateTime::toString(), QGpCoreTools::tr(), TRACE, and QGpCoreTools::Point2D::y().
{ TRACE; QStringList infoFilter, ascFilter, ftpFilter, tmpWorkFilter; infoFilter.append("*.info"); ascFilter.append("*.ASC"); ftpFilter.append("*.*.*"); tmpWorkFilter.append("tmp_work_*"); SignalFileFormat fmt(SignalFileFormat::Ascii, &_titanFormat); QStringList tmpWorkDirs=_workDir.entryList(tmpWorkFilter, QDir::NoDotAndDotDot | QDir::Dirs); foreach(QString wd, tmpWorkDirs) { QDir d(_workDir); d.cd(wd); QStringList tmpFiles=d.entryList(QDir::Files); foreach(QString f, tmpFiles) { d.remove(f); } if(!_workDir.rmdir(wd)) { App::stream() << tr("Cannot remove directory %1").arg(wd) << endl; return; } } App::stream() << tr("Start loop ...") << endl; QStringList * currentStations=0; int tempDirIndex=100000; for(ScheduleList::iterator itSched=_schedule.begin();itSched!=_schedule.end();itSched++) { App::stream() << tr("%1/%2").arg(itSched->site).arg(itSched->array) << endl; QDir siteDestDir(_destDir); siteDestDir.cd(itSched->site); siteDestDir.cd(itSched->array); DateTime recStart, recEnd; recStart.setDateTime(itSched->start); recEnd.setDateTime(itSched->end); TimeRange recRange(_timeReference.secondsTo(recStart), _timeReference.secondsTo(recEnd)); if(itSched->array.startsWith("HV")) { currentStations=&_hvStations; _hvStations.clear(); _hvStations.append(itSched->info); } else { currentStations=&_arrayStations; } for(QStringList::iterator itStation=currentStations->begin(); itStation!=currentStations->end(); itStation++) { Curve<Point2D>& statUncorr2Corr=_timeUncorr2Corr[*itStation]; // Create a new temporary working directory QString tmpWorkDirName="tmp_work_"+*itStation+"_"+QString::number(tempDirIndex); _workDir.mkdir(tmpWorkDirName); QDir tmpWorkDir(_workDir); tmpWorkDir.cd(tmpWorkDirName); tempDirIndex++; QProcess p; p.setWorkingDirectory(tmpWorkDir.absolutePath()); QStringList args; args.append("-ts"); // Bug in titan... if this option is not there, timing is not correct args.append("86400"); // Ask for the maximum possible length args.append("-asc"); // Ask for ASCII files args.append("-f"); // Set input as files for(QDate day=itSched->start.date(); day<=itSched->end.date();day=day.addDays(1)) { QDir d(_dataDir); d.cd(*itStation); d.cd("ftp"); d.cd(*itStation); d.cd(day.toString("yyyy.MM.dd")); QStringList ftpFiles=d.entryList(ftpFilter, QDir::Files | QDir::NoDotAndDotDot); foreach(QString f, ftpFiles) { args.append(d.absoluteFilePath(f)); } } App::stream() << tr("rtitan2 -ts 86400 -asc -f ... "); p.start("rtitan2", args); while(!p.waitForFinished()) {} // Remove *.info files QStringList infoFiles=tmpWorkDir.entryList(infoFilter, QDir::Files | QDir::NoDotAndDotDot); if(infoFiles.isEmpty()) { App::stream() << tr("error in rtitan2") << endl; } else { App::stream() << tr("ok") << endl; } foreach(QString f, infoFiles) { tmpWorkDir.remove(f); } QString manualLimitsKey; QStringList ascFiles=tmpWorkDir.entryList(ascFilter, QDir::Files | QDir::NoDotAndDotDot); foreach(QString signalFile, ascFiles) { SubSignalPool subPool=geopsyCore->load(tmpWorkDir.absoluteFilePath(signalFile), fmt); if(subPool.count()!=1) { _failed=true; return; } Signal * sig=subPool.first(); subPool.remove(sig); if(sig->name()!=*itStation || sig->component()==Signal::UndefinedComponent) { App::stream() << tr("skip (bad name or component)") << endl; tmpWorkDir.remove(signalFile); geopsyCore->currentDB()->removeFile(sig->file()); continue; } if(fabs(sig->samplingFrequency()-_samplingFrequency)>1e-10) { App::stream() << tr("skip (sampling at %1 Hz instead of %2 Hz)").arg(sig->samplingFrequency()).arg(_samplingFrequency) << endl; tmpWorkDir.remove(signalFile); geopsyCore->currentDB()->removeFile(sig->file()); continue; } if(sig->timePick("adcDelay")!=_adcDelay) { App::stream() << tr("adc delay=%1 (expected %2)").arg(sig->timePick("adcDelay")).arg(_adcDelay) << endl; tmpWorkDir.remove(signalFile); geopsyCore->currentDB()->removeFile(sig->file()); _failed=true; return; } if(sig->timePick("filterDelay")!=_filterDelay) { App::stream() << tr("filter delay=%1 (expected %2)").arg(sig->timePick("filterDelay")).arg(_filterDelay) << endl; tmpWorkDir.remove(signalFile); geopsyCore->currentDB()->removeFile(sig->file()); _failed=true; return; } // Set time reference to global timeReference, t0 are uncorrected DateTime t0Sig; t0Sig.setDateTime(sig->timeReference()); t0Sig.addSeconds(sig->t0()); sig->setTimeReference(_timeReference.dateTime()); sig->setT0(_timeReference.secondsTo(t0Sig)); // Cut signal with manual limits _manualLimitsMutex.lock(); manualLimitsKey=itSched->site+":"+itSched->array+":"+*itStation; QMap<QString, SparseTimeRange>::iterator it=_manualLimits.find(manualLimitsKey); if(_pickOnly) { if(it!=_manualLimits.end()) { const QVector<TimeRange>& rList=it.value().ranges(); int i=1; for(QVector<TimeRange>::const_iterator itr=rList.begin(); itr!=rList.end(); itr++, i++) { sig->setTimePick(QString("%1_Begin").arg(i), itr->start()); sig->setTimePick(QString("%1___End").arg(i), itr->end()); } } _manualLimitsMutex.unlock(); // Force load of samples sig->maximumAmplitude(); _pickSubPool.addSignal(sig); continue; } if(it==_manualLimits.end()) { geopsyCore->currentDB()->removeFile(sig->file()); _manualLimitsMutex.unlock(); App::stream() << tr("No manual limits found for %1").arg(manualLimitsKey) << endl; _failed=true; return; } _manualLimitsMutex.unlock(); const QVector<TimeRange>& manualCutRanges=it.value().ranges(); for(QVector<TimeRange>::const_iterator itr=manualCutRanges.begin(); itr!=manualCutRanges.end(); itr++) { TimeRange manualCutRange=*itr; Signal * cutsig=sig->cut(manualCutRange); if(!cutsig) { App::stream() << tr("No signal found.") << endl; continue; } // High-pass filter FilterParameters filterParam; filterParam.setMinimumFrequency(0.05); filterParam.setBand(FilterParameters::HighPass); filterParam.setMethod(FilterParameters::Convolution); filterParam.convolutionWindow().setWindow(TaperParameters::Tukey); filterParam.setWidth(0.5); cutsig->filter(filterParam); // Do not include the first and last 30 seconds (filter border effects) Signal * cutsig30=cutsig->cut(TimeRange(cutsig->t0()+30, cutsig->endTime()-30)); geopsyCore->currentDB()->removeSignal(cutsig); if(!cutsig30) { App::stream() << tr("Too short signal.") << endl; geopsyCore->currentDB()->removeSignal(cutsig30); continue; } cutsig=cutsig30; // Cut signal in blocks of 15 minutes double tUncorr=cutsig->t0(); while(tUncorr<cutsig->endTime()) { /*DateTime currentTime(_timeReference); currentTime.addSeconds(tUncorr); App::stream() << "Current time: " << currentTime.toString("yyyy-MM-dd hh:mm:ssz") << endl;*/ double tCorr=statUncorr2Corr.at(tUncorr).y(); double tCorrEnd=(floor(tCorr/900.0)+1.0)*900; if(tCorrEnd-tCorr<60) tCorrEnd+=900; // Avoid blocks of less than 1 minute TimeRange blockRecRange=TimeRange(tCorr, tCorrEnd).intersection(recRange); if(blockRecRange.lengthSeconds()==0) { tUncorr+=cutsig->deltaT()*floor((tCorrEnd-tCorr)/cutsig->deltaT()); continue; } if(blockRecRange.start()>tCorr) { // Changing t0, we must keep a round number of samples double dt=ceil((blockRecRange.start()-tCorr)/cutsig->deltaT())*cutsig->deltaT(); tCorr+=dt; tUncorr+=dt; } if(tCorrEnd-tCorr<60) { // Avoid blocks of less than 1 minute tCorrEnd+=900; // Update blockRecRange... blockRecRange=TimeRange(tCorr, tCorrEnd).intersection(recRange); } if(blockRecRange.end()<tCorrEnd) { // Changing end time tCorrEnd=blockRecRange.end(); } if(tCorrEnd-tCorr<60.0) { // Less than a minute, drop it tUncorr+=900.0; continue; } TimeRange blockRange(tUncorr, tUncorr+(tCorrEnd-tCorr)); DateTime tCorrTime(_timeReference); tCorrTime.addSeconds(tCorr); DateTime tCorrEndTime(_timeReference); tCorrEndTime.addSeconds(tCorrEnd); App::stream() << "t (corr) [" << tCorrTime.toString("yyyy-MM-dd hh:mm:ssz") << ", " << tCorrEndTime.toString("yyyy-MM-dd hh:mm:ssz") << "]" << endl; DateTime tUncorrTime(_timeReference); tUncorrTime.addSeconds(blockRange.start()); DateTime tUncorrEndTime(_timeReference); tUncorrEndTime.addSeconds(blockRange.end()); App::stream() << "t (uncorr) [" << tUncorrTime.toString("yyyy-MM-dd hh:mm:ssz") << ", " << tUncorrEndTime.toString("yyyy-MM-dd hh:mm:ssz") << "]" << endl; DateTime sUncorrTime(_timeReference); sUncorrTime.addSeconds(cutsig->t0()); DateTime sUncorrEndTime(_timeReference); sUncorrEndTime.addSeconds(cutsig->endTime()); App::stream() << "sig (uncorr) [" << sUncorrTime.toString("yyyy-MM-dd hh:mm:ssz") << ", " << sUncorrEndTime.toString("yyyy-MM-dd hh:mm:ssz") << "]" << endl; // Cut signal Signal * cutsig15=cutsig->cut(blockRange); if(!cutsig15) { break; } DateTime scUncorrTime(_timeReference); scUncorrTime.addSeconds(cutsig15->timeRange().range().start()); DateTime scUncorrEndTime(_timeReference); scUncorrEndTime.addSeconds(cutsig15->timeRange().range().end()); App::stream() << "cut sig (uncorr) [" << scUncorrTime.toString("yyyy-MM-dd hh:mm:ssz") << ", " << scUncorrEndTime.toString("yyyy-MM-dd hh:mm:ssz") << "]" << endl; // Go to next time block (step a round number of samples) tUncorr+=ceil((tCorrEnd-tCorr)/cutsig15->deltaT())*cutsig15->deltaT(); // Shift and correct time double tRounded=floor(tCorr/cutsig->deltaT())*cutsig->deltaT(); cutsig15->shift(tRounded-tCorr); cutsig15->setT0(tRounded); App::stream() << "Shift by " << (tRounded-tCorr) << " s" << endl; // Remove first and last samples (2, to force a hole in all cases) Signal * finalSig=new Signal(*cutsig15); finalSig->setT0(tRounded+2*cutsig->deltaT()); finalSig->setNSamples(cutsig15->nSamples()-4); finalSig->copySamplesFrom(cutsig15, finalSig->timeRange().range()); // WAU49 had a sensor with reversed connections (not always) if(*itStation=="WAU49" && itSched->info.toInt()==-1) { finalSig->multiply(-1); } // Save shifted signal SubSignalPool savePool; savePool.addSignal(finalSig); DateTime timeBlock(_timeReference); timeBlock.addSeconds(finalSig->t0()); DateTime endTimeBlock(_timeReference); endTimeBlock.addSeconds(finalSig->endTime()); App::stream() << timeBlock.toString("yyyy-MM-dd hh:mm:ssz") << " ---> " << endTimeBlock.toString("yyyy-MM-dd hh:mm:ssz") << endl; savePool.save(siteDestDir.absoluteFilePath(*itStation+"_"+ timeBlock.toString("yyyyMMdd-hhmm")+"_"+ Signal::componentLetter(cutsig->component())+".sac"), false, SignalFileFormat::SacBigEndian); savePool.remove(finalSig); geopsyCore->currentDB()->removeSignal(cutsig15); geopsyCore->currentDB()->removeSignal(finalSig); } geopsyCore->currentDB()->removeSignal(cutsig); } tmpWorkDir.remove(signalFile); geopsyCore->currentDB()->removeFile(sig->file()); geopsyCore->clear(); } if(_pickOnly) { _pickToolMutex.lock(); while(_pickToolCount>=3) { _pickToolMutex.unlock(); msleep(1000); _pickToolMutex.lock(); _removeMutex.lock(); foreach(Signal * sig, _toRemove) { QFile(sig->file()->name()).remove(); geopsyCore->currentDB()->removeFile(sig->file()); } _toRemove.clear(); _removeMutex.unlock(); } _pickToolCount++; _pickToolMutex.unlock(); emit readyToPick(new SubSignalPool(_pickSubPool), manualLimitsKey, recRange); _pickSubPool.removeAll(); } } } if(_pickOnly) { _pickToolMutex.lock(); while(_pickToolCount>0) { _pickToolMutex.unlock(); msleep(1000); _pickToolMutex.lock(); _removeMutex.lock(); foreach(Signal * sig, _toRemove) { QFile(sig->file()->name()).remove(); geopsyCore->currentDB()->removeFile(sig->file()); } _toRemove.clear(); _removeMutex.unlock(); } } }
bool Process::setArguments | ( | int & | argc, |
char ** | argv | ||
) |
References QGpCoreTools::endl(), QGpCoreTools::DateTime::fromString(), Schedule::read(), QGpCoreTools::tr(), and QGpCoreTools::XMLHeader::xml_restoreFile().
Referenced by main().
{ // Check arguments int i, j=1; for(i=1; i<argc; i++) { QByteArray arg=argv[i]; if(arg[0]=='-') { if(arg=="-data") { CoreApplication::checkOptionArg(i, argc, argv); _dataDir.setPath(argv[i]); } else if(arg=="-time") { CoreApplication::checkOptionArg(i, argc, argv); _timeDir.setPath(argv[i]); } else if(arg=="-stations") { CoreApplication::checkOptionArg(i, argc, argv); _stationFile=argv[i]; } else if(arg=="-dest") { CoreApplication::checkOptionArg(i, argc, argv); _destDir.setPath(argv[i]); } else if(arg=="-fmt") { CoreApplication::checkOptionArg(i, argc, argv); _titanFormatFile=argv[i]; } else if(arg=="-time-ref") { CoreApplication::checkOptionArg(i, argc, argv); _timeReference.fromString(argv[i], "yyyy-MM-dd"); } else if(arg=="-pick-only") { _pickOnly=true; } else if(arg=="-sampling-frequency") { CoreApplication::checkOptionArg(i, argc, argv); _samplingFrequency=atof(argv[i]); } else { App::stream() << tr("kephrenrtu: bad option %1, see -help").arg(argv[i]) << endl; return false; } } else { argv[j++]=argv[i]; } } if(j < argc) { argv[j]=0; argc=j; } if(_samplingFrequency==100.0) { _adcDelay=0.000156; _filterDelay=0.507969; } else if(_samplingFrequency==250.0) { _adcDelay=0.000156; _filterDelay=0.224469; } else { App::stream() << tr("Unsupported sampling frequency (%1 Hz)").arg(_samplingFrequency) << endl; return false; } // Read manual limits App::stream() << tr("Read manual limits ...") << endl; _manualLimitsFileName=_destDir.absoluteFilePath("manuallimits"); loadManualLimits(); // Read _schedule App::stream() << tr("Read _schedule ...") << endl; _schedule=Schedule::read(_dataDir.absoluteFilePath("schedule.txt")); App::stream() << tr(" found %1 entries").arg(_schedule.count()) << endl; // Read station list App::stream() << tr("Read stations ...") << endl; _arrayStations=readStations(); if(_arrayStations.isEmpty()) return 2; App::stream() << tr(" found %1 stations").arg(_arrayStations.count()) << endl; // Build time corrections App::stream() << tr("Read time corrections ...") << endl; if(!loadTimeCorrections()) return 2; // TODO: remove -fmt option and build it internally if(_titanFormatFile.isEmpty()) { App::stream() << tr("Missing titan format file") << endl; return false; } XMLHeader hdr(&_titanFormat); if(hdr.xml_restoreFile(_titanFormatFile)!=XMLClass::NoError) { App::stream() << tr("Error opening file %1").arg(_titanFormatFile) << endl; return false; } return true; }
const QString Process::defaultDataDir = "../data" [static] |
Referenced by Process().
const QString Process::defaultDestDir = "../sac" [static] |
Referenced by Process().
const QString Process::defaultStationFile = "stations.txt" [static] |
Referenced by Process().
const QString Process::defaultTimeDir = "../timedrift" [static] |
Referenced by Process().
const QString Process::defaultTitanFormatFile = "/kephrenrtu/titanUncorrectedT0.ascfmt" [static] |
Referenced by Process().
const QString Process::defaultWorkDir = "." [static] |
Referenced by Process().