Brief description of class still missing. More...
#include <CitySignal.h>
Public Types | |
enum | RecorderType { Unknown, CityShark1, CityShark2 } |
Public Member Functions | |
int | channelNum () const |
CitySignal () | |
int | duration () const |
const DateTime & | endTime () const |
bool | erase (QFile *stream) |
bool | erased () const |
const char * | fileIndex () const |
QString | fileName () const |
int | frequency () const |
int | gain () const |
bool | loadSignals (QFile *stream) const |
int | maxAllowedAmpl () const |
int | maxReachedAmpl () const |
int | nSamples () const |
bool | readHeader (QFile *stream, int version) |
double | saturation () const |
const DateTime & | startTime () const |
~CitySignal () |
Brief description of class still missing.
Full description of class still missing
{Unknown, CityShark1, CityShark2};
Description of constructor still missing
References BLOCK_SIZE, TRACE, and Unknown.
{ TRACE; _frequency=0; _duration=0; _recorder=Unknown; _erased=false; _dataOffset=0; _currentBlock[BLOCK_SIZE]='\0'; _fileIndex[3]='\0'; }
int GeopsyCore::CitySignal::channelNum | ( | ) | const [inline] |
Referenced by GeopsyGui::CitySignalItem::data().
{return _channelNum;}
int GeopsyCore::CitySignal::duration | ( | ) | const [inline] |
Referenced by GeopsyGui::CitySignalItem::data().
{return _duration;}
const DateTime& GeopsyCore::CitySignal::endTime | ( | ) | const [inline] |
Referenced by GeopsyGui::CitySignalItem::data().
{return _endTime;}
bool GeopsyCore::CitySignal::erase | ( | QFile * | stream | ) |
References BLOCK_SIZE, CityShark1, CityShark2, and TRACE.
Referenced by GeopsyCore::CityScanner::erase().
{ TRACE; if(_erased) return true; switch (_recorder) { case CityShark1: stream->seek(_dataOffset - 13 * BLOCK_SIZE); if(stream->write( "ERASED ", BLOCK_SIZE)!=BLOCK_SIZE) return false; break; case CityShark2: stream->seek(_dataOffset - 19 * BLOCK_SIZE); if(stream->write( "ERASED2 ", BLOCK_SIZE)!=BLOCK_SIZE) return false;; break; default: return false; } _erased=true; return true; }
bool GeopsyCore::CitySignal::erased | ( | ) | const [inline] |
Referenced by GeopsyGui::CitySignalItem::data().
{return _erased;}
const char* GeopsyCore::CitySignal::fileIndex | ( | ) | const [inline] |
Referenced by GeopsyGui::CitySignalItem::data().
{return _fileIndex;}
QString GeopsyCore::CitySignal::fileName | ( | ) | const [inline] |
Referenced by loadSignals(), and readHeader().
{return _startTime.toString("yyMMdd_hhmm")+"."+_fileIndex;}
int GeopsyCore::CitySignal::frequency | ( | ) | const [inline] |
Referenced by GeopsyGui::CitySignalItem::data().
{return _frequency;}
int GeopsyCore::CitySignal::gain | ( | ) | const [inline] |
Referenced by GeopsyGui::CitySignalItem::data().
{return _gain;}
bool GeopsyCore::CitySignal::loadSignals | ( | QFile * | stream | ) | const |
Read flash card accessed with stream
References GeopsyCore::GeopsyCoreEngine::currentDB(), QGpCoreTools::DateTime::dateTime(), GeopsyCore::DoubleSignal::deltaT(), GeopsyCore::DoubleSignal::duration(), GeopsyCore::Signal::East, fileName(), QGpCoreTools::DateTime::fractions(), GeopsyCore::geopsyCore, LOCK_SAMPLES, GeopsyCore::Signal::North, QGpCoreTools::DateTime::secondsTo(), GeopsyCore::Signal::setComments(), GeopsyCore::Signal::setComponent(), GeopsyCore::Signal::setCountPerVolt(), GeopsyCore::Signal::setDeltaT(), GeopsyCore::Signal::setFile(), GeopsyCore::Signal::setNSamples(), GeopsyCore::Signal::setNumberInFile(), GeopsyCore::GeopsyCoreEngine::setProgressMaximum(), GeopsyCore::GeopsyCoreEngine::setProgressValue(), GeopsyCore::SignalFile::setSignalName(), GeopsyCore::Signal::setT0(), GeopsyCore::SignalFile::setTimeReference(), GeopsyCore::Signal::setTimeReference(), GeopsyCore::DoubleSignal::setType(), GeopsyCore::GeopsyCoreEngine::showMessage(), GeopsyCore::SignalFileFormat::Temporary, QGpCoreTools::DateTime::toString(), QGpCoreTools::tr(), TRACE, GeopsyCore::Signal::unitPerCount(), UNLOCK_SAMPLES, GeopsyCore::Signal::Vertical, and GeopsyCore::DoubleSignal::Waveform.
Referenced by GeopsyGui::CityLoader::on_loadBut_clicked().
{ TRACE; QDateTime timeReference; double t0=_startTime.fractions(); if(!SignalFile::setTimeReference(t0, timeReference, _startTime.dateTime())) { return false; } QString originalFileName=fileName(); geopsyCore->showMessage(tr("Reading flash card ...")); // Read all channels in one buffer int n=_nSamples*_channelNum*3; char * data=new char [n]; stream->seek(_dataOffset); // Read buffer with 20 blocks (to display advance) int block20Size=n/20; int blockRemaining=n%20; geopsyCore->setProgressMaximum(20); for(int i=0; i<20; i++) { geopsyCore->setProgressValue(i); stream->read(data+i*block20Size, block20Size); } if(blockRemaining>0) { stream->read(data+20*block20Size, blockRemaining); } geopsyCore->setProgressValue(20); geopsyCore->showMessage(tr( "Loading file %1" ).arg(originalFileName) ); // Compute gain and conversion factors /* Conversion factors initialy transcripted from Frechet switch(_frequency) { case 50: resp=209715; break; // 1048575 /5 case 100: resp=52428.6; break; // 262143 /5 case 125: resp=26214.2; break; // 131071 /5 case 200: resp=13107; break; // 65535 /5 case 250: resp=6553.4; break; // 32767 /5 default: resp=0.0; break; }*/ // Conversion factors from new version: 9/4/2004 // First resp is set to the amplitude range for counts // Check that it is correct, there might be 1 to be subtracted (e.g. from -8192 to 8191 or -8191 to 8191?) double resp; switch (_frequency) { case 10: case 20: case 25: case 40: case 50: resp=1048576.0; break; case 60: resp=524288.0; break; case 75: case 80: case 100: resp=262144.0; break; case 125: case 150: resp=131072.0; break; case 200: resp=65536.0; break; case 250: resp=32768.0; break; case 300: resp=16384.0; break; case 400: resp=8192.0; break; case 500: case 600: resp=4096.0; break; case 750: resp=2048.0; break; case 1000: resp=1024.0; break; default: resp=1.0; break; } // Then divided by the peak to peak voltage difference (currently 5 volts) resp/=5.0; double countPerVolt=resp*_gain; // Create a new temporary file SignalFile * newFile=new SignalFile(geopsyCore->currentDB(), originalFileName, SignalFileFormat::Temporary); geopsyCore->setProgressMaximum(_channelNum-1); for(int iSig=0; iSig<_channelNum; iSig++) { Signal * newSignal=new Signal(geopsyCore->currentDB()); newSignal->setFile(newFile); newSignal->setNumberInFile(iSig); newSignal->setT0(t0); newSignal->setDeltaT(1.0/_frequency); newSignal->setType(Signal::Waveform); int recNum=iSig/3 + 1; if(_channelNum > 3) SignalFile::setSignalName(newSignal, originalFileName, QString("_%1").arg(recNum), recNum, originalFileName); else SignalFile::setSignalName(newSignal, originalFileName, "", 1, originalFileName); if(iSig % 3==0) newSignal->setComponent(Signal::Vertical); else if(iSig % 3==1) newSignal->setComponent(Signal::North); else if(iSig % 3==2) newSignal->setComponent(Signal::East); newSignal->setTimeReference(timeReference); newSignal->setNSamples(_nSamples); newSignal->setCountPerVolt(countPerVolt); QString cmt; cmt+="Station serial number: "+QString::number(_serialNum)+"\n"; cmt+="Station software version: "+QString::number(_softwareVersion)+"\n"; cmt+="Starting date: "+_startTime.toString("dd.MM.yyyy")+"\n"; cmt+="Starting time: "+_startTime.toString("hh:mm:ssz", 3)+"\n"; cmt+="Ending date: "+_endTime.toString("dd.MM.yyyy")+"\n"; cmt+="Ending time: "+_endTime.toString("hh:mm:ssz", 3)+"\n"; cmt+="Latitude : "+QString::number(_latitudeDeg)+" "+QString::number(_latitudeMin)+" N\n"; cmt+="Longitude: "+QString::number(_longitudeDeg)+" "+QString::number(_longitudeMin)+" E\n"; cmt+="Altitude : "+QString::number(_altitude)+" m\n"; cmt+="No. satellites: "+QString::number(_satNum)+"\n"; cmt+="Gain: "+QString::number(_gain)+"\n"; // Duration calculated between start and end time does not account for the last sample duration cmt+="Time drift: "+QString::number(_startTime.secondsTo(_endTime)-newSignal->duration()+newSignal->deltaT())+" s"; newSignal->setComments(cmt); // Extract samples for this signal from buffer LOCK_SAMPLES(double, newSamples, newSignal) char * ptr=data+3*iSig; int di=_channelNum*3; double unitPerCount=newSignal->unitPerCount(); for(int i=0; i<_nSamples; i++) { newSamples[i]=getSample(ptr+i*di)*unitPerCount; } UNLOCK_SAMPLES(newSignal) geopsyCore->setProgressValue(iSig); } delete [] data; return true; }
int GeopsyCore::CitySignal::maxAllowedAmpl | ( | ) | const [inline] |
Referenced by GeopsyGui::CitySignalItem::data().
{return _maxAllowedAmpl;}
int GeopsyCore::CitySignal::maxReachedAmpl | ( | ) | const [inline] |
Referenced by GeopsyGui::CitySignalItem::data().
{return _maxReachedAmpl;}
int GeopsyCore::CitySignal::nSamples | ( | ) | const [inline] |
Referenced by GeopsyGui::CitySignalItem::data().
{return _nSamples;}
bool GeopsyCore::CitySignal::readHeader | ( | QFile * | stream, |
int | version | ||
) |
version is used only to fill signal comments. It does not modify the way samples or header information is extracted. It switches automatically to CityShark 1 or 2 with DEB or DEB2 keyword found at the beginning of every signal.
References QGpCoreTools::DateTime::addSeconds(), BLOCK_SIZE, CityShark2, QGpCoreTools::endl(), fileName(), QGpCoreTools::DateTime::fromString(), QGpCoreTools::tr(), and TRACE.
Referenced by GeopsyCore::CityScanner::normalScan().
{ TRACE; _softwareVersion=version; char * ptr; qint64 initialOffset=stream->pos(); char timeBuf[15]; timeBuf[14]='\0'; // Signals always start and end with those tags (2 for Cityshark 2): // DEB, DEB2, ERASE or ERASE2 readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); if(strncmp(ptr, "DEB", 3)==0) { _erased=false; setRecorder(ptr+3); } else if(strncmp(ptr, "ERASED", 6)==0) { _erased=true; setRecorder(ptr+6); } else { // No more signal header found App::stream() << tr(" # Warning # No more file header found. Valid data occupy %1 bytes (%2 Mbytes)") .arg(initialOffset).arg((double)initialOffset/(1024.0*1024.0)) << endl; return false; } // Channel number, serial number readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); _serialNum=atoi(getCouple(ptr)); _channelNum=atoi(ptr); // FILE tag readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); if(strcmp(ptr, "FILE")!=0) { App::stream() << tr( " # Error # Cannot read keyword FILE, block corrupted, skipping it" ) << endl; return false; } // Start time (MMJJHHmm) readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); strncpy(timeBuf, ptr, 8); // Start time (sszzz) readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); strncpy(timeBuf+8, ptr, 2); strncpy(timeBuf+10, ".", 1); strncpy(timeBuf+11, ptr+2, 3); App::freezeStream(true); // Avoid message from time conversion _startTime.fromString(timeBuf, "MMddhhmmssz"); App::freezeStream(false); setCurrentYear(_startTime); // File index readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); strncpy(_fileIndex, ptr, 3); // PARAM tag readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); if(strcmp(ptr, "PARAM")!=0) { App::stream() << tr(" # Error # Cannot read keyword PARAM, block corrupted, skipping it") << endl; return false; } // Frequency, duration readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); _duration=atoi(getCouple(ptr)); _frequency=atoi(ptr); _nSamples=_frequency*_duration*60; if(_nSamples <= 0) { App::stream() << tr( " # Error # Number of samples is null or negative, block corrupted, skipping it" ) << endl; return false; } // Gain readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); _gain=atoi(ptr); // Saturation readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); _saturation=atof(ptr); // Maximum allowed amplitude readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); _maxAllowedAmpl=atoi(ptr); // Maximum reached amplitude readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); _maxReachedAmpl=atoi(ptr); // Test if all blocks have been read correctly if(( stream->pos()-initialOffset)!=12*BLOCK_SIZE) { if(stream->atEnd()) { App::stream() << tr( " # Error # End of file reached (CityShark 1 infos), partial block skipped" ) << endl; return false; } else { App::stream() << tr( " # Error # Block not read correctly due to an unknown error (CityShark 1 infos)" ) << endl; return false; } } if(_recorder==CityShark2) { // Latitude, Longitude (degrees) readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); _longitudeDeg=atoi(getCouple( ptr) ); _latitudeDeg=atoi(ptr); // Latitude (minutes) readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); _latitudeMin=atof(ptr); // Longitude (minutes) readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); _longitudeMin=atof(ptr); // Number of satelites, altitude readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); _altitude=atof(getCouple( ptr) ); _satNum=atoi(ptr); if(_softwareVersion >= 413) { // since station software version 0413 // Calculate end time from time elapsed from start in milliseconds readBlock(stream); _endTime=_startTime; _endTime.addSeconds(atoi( File::stripWhiteSpace(_currentBlock) )*0.001); readBlock(stream); // useless block } else { // End time (MMJJHHmm) readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); strncpy(timeBuf, ptr, 8); // End time (ss.mmm) readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); strncpy(timeBuf + 8, ptr, 2); strncpy(timeBuf + 10, ".", 1); strncpy(timeBuf + 11, ptr+2, 3); App::freezeStream(true); _endTime.fromString(timeBuf, "MMddhhmmssz"); App::freezeStream(false); setCurrentYear(_endTime); } // Test if all blocks have been read correctly if(( stream->pos() - initialOffset)!=18 * BLOCK_SIZE) { if(stream->atEnd()) { App::stream() << tr( " # Error # End of file reached (CityShark 2 infos), partial block skipped" ) << endl; return false; } else { App::stream() << tr( " # Error # Block not read correctly due to an unknown error (CityShark 2 infos)" ) << endl; return false; } } } initialOffset=stream->pos(); // DATA readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); if(strcmp( ptr, "DATA" )!=0) { App::stream() << tr( " # Error # Cannot read keyword DATA, block corrupted, skipping it" ) << endl; return false; } _dataOffset=stream->pos(); // Skip data block int dataLength=_channelNum * _nSamples * 3; stream->seek(stream->pos() + dataLength); // FIN readBlock(stream); ptr=File::stripWhiteSpace(_currentBlock); if(strcmp( ptr, "FIN" )!=0) { App::stream() << tr( " # Warning # Cannot read keyword FIN for file %1, end of trace may be corrupted" ).arg(fileName()) << endl; } // Test if all blocks have been read correctly if(( stream->pos() - initialOffset)!=dataLength + BLOCK_SIZE * 2) { if(stream->atEnd()) { App::stream() << tr(" ### End of file reached (data part), partial block skipped") << endl; return false; } else { App::stream() << tr(" ### Block not read correctly due to an unknown error (data part)") << endl; return false; } } App::stream() << tr(" File %1 ok").arg(fileName()) << endl; return true; }
double GeopsyCore::CitySignal::saturation | ( | ) | const [inline] |
Referenced by GeopsyGui::CitySignalItem::data().
{return _saturation;}
const DateTime& GeopsyCore::CitySignal::startTime | ( | ) | const [inline] |
Referenced by GeopsyGui::CitySignalItem::data().
{return _startTime;}