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;}