All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Public Types | Public Member Functions
GeopsyCore::GuralpCompressedBlock Class Reference

Brief description of class still missing. More...

#include <GuralpCompressedBlock.h>

List of all members.

Public Types

enum  StreamType {
  Data, MuxChannel, Status, ChannelData,
  BytePipe, Information, Unknown
}

Public Member Functions

Signal::Components component () const
int compressionCode ()
void debugPrint () const
 GuralpCompressedBlock ()
 GuralpCompressedBlock (const GuralpCompressedBlock &o)
uint hash () const
bool isData () const
QString name () const
int nSamples () const
void operator= (const GuralpCompressedBlock &o)
bool operator== (const GuralpCompressedBlock &o) const
bool parseBody (const char *gcfBody)
bool parseHeader (const char *gcfHeader)
bool readBody (QFile &f)
bool readHeader (QFile &f)
int sample (int index) const
double samplingFrequency () const
void skipBody (QFile &f)
QDateTime startTime () const
StreamType streamType () const
const char * streamTypeString () const
TimeRange timeRange (const QDateTime &refTime) const
 ~GuralpCompressedBlock ()

Detailed Description

Brief description of class still missing.

Full description of class still missing


Member Enumeration Documentation

Enumerator:
Data 
MuxChannel 
Status 
ChannelData 
BytePipe 
Information 
Unknown 

Constructor & Destructor Documentation

References TRACE.

  {
    TRACE;
    _nSamples=0;
    _samples=0;
    _samplingFrequency=0.0;
    _systemID[0]='\0';
    _device[0]='\0';
  }

References operator=(), and TRACE.

  {
    TRACE;
    _samples=0;
    operator=(o);
  }

References TRACE.

  {
    TRACE;
    delete [] _samples;
  }

Member Function Documentation

References GeopsyCore::Signal::East, GeopsyCore::Signal::North, GeopsyCore::Signal::UndefinedComponent, and GeopsyCore::Signal::Vertical.

  {
    switch(_component) {
    case 'Z':
      return Signal::Vertical;
    case 'N':
      return Signal::North;
    case 'E':
      return Signal::East;
    default:
      return Signal::UndefinedComponent;
    }
  }
{return _compressionCode;}

References streamTypeString(), and TRACE.

  {
    TRACE;
    printf("------ Guralp compressed block -----------\n");
    printf("System ID=%s\n",_systemID);
    printf("Device serial number=%4s\n",_device);
    printf("Stream type=%s\n",streamTypeString());
    printf("  Component=%c\n",_component);
    printf("  Channel number/Output tap=%c\n",_channel);
    printf("Start time=%s\n",_startTime.toString("yyyy-MM-dd hh:mm:ss").toAscii().data());
    printf("Sampling frequency=%lf\n", _samplingFrequency);
    printf("Compression code=%i\n", _compressionCode);
    printf("Number of samples=%i\n", _nSamples);
  }
uint GeopsyCore::GuralpCompressedBlock::hash ( ) const [inline]

Referenced by GeopsyCore::qHash().

{return _hash;}

Referenced by GeopsyCore::SignalFileFormat::fromContent().

{return _component!='0' && _component!='I';}
QString GeopsyCore::GuralpCompressedBlock::name ( ) const [inline]
{return _device;}

Referenced by GeopsyCore::GuralpSignal::addRecord().

{return _nSamples;}
void GeopsyCore::GuralpCompressedBlock::operator= ( const GuralpCompressedBlock o)

Copy operator.

References TRACE.

Referenced by GuralpCompressedBlock().

  {
    TRACE;
    _hash=o._hash;
    strcpy(_systemID, o._systemID);
    strcpy(_device, o._device);
    _component=o._component;
    _channel=o._channel;
    _startTime=o._startTime;
    _samplingFrequency=o._samplingFrequency;
    _compressionCode=o._compressionCode;
    _nSamples=o._nSamples;
    delete [] _samples;
    _samples=0;
  }
bool GeopsyCore::GuralpCompressedBlock::operator== ( const GuralpCompressedBlock o) const

Checks streamID, systemID, sampling frequency, channel and component.

  {
    if(strcmp(_systemID, o._systemID)!=0) return false;
    if(_component!=o._component) return false;
    if(_channel!=o._channel) return false;
    if(strcmp(_device,o._device)!=0) return false;
    if(_samplingFrequency!=o._samplingFrequency) return false;
    return true;
  }
bool GeopsyCore::GuralpCompressedBlock::parseBody ( const char *  gcfBody)

References QGpCoreTools::endl(), QGpCoreTools::tr(), and TRACE.

Referenced by readBody().

  {
    TRACE;
    _samples[0]=File::fromBigEndian(*((qint32 *)gcfBody));
    gcfBody+=4;
    switch(_compressionCode) {
    case 1:
      if(*((qint32 *)gcfBody)!=0) {
        App::stream() << tr("Warning: first sample difference must be null.") << endl;
      }
      gcfBody+=4;
      for(int i=1; i<_nSamples; i++) {
        _samples[i]=_samples[i-1]+File::fromBigEndian(*((qint32 *)gcfBody));
        gcfBody+=4;
      }
      break;
    case 2:
      if(*((qint16 *)gcfBody)!=0) {
        App::stream() << tr("Warning: first sample difference must be null.") << endl;
      }
      gcfBody+=2;
      for(int i=1; i<_nSamples; i++) {
        _samples[i]=_samples[i-1]+File::fromBigEndian(*((qint16 *)gcfBody));
        gcfBody+=2;
      }
      break;
    case 4:
      if(*gcfBody!=0) {
        App::stream() << tr("Warning: first sample difference must be null.") << endl;
      }
      gcfBody++;
      for(int i=1; i<_nSamples; i++) {
        _samples[i]=_samples[i-1]+*gcfBody;
        gcfBody++;
      }
      break;
    default:
      return false;
    }
    // Reverse Integrating Constant check
    if(File::fromBigEndian(*((qint32 *)gcfBody))!=_samples[_nSamples-1]) {
      App::stream() << tr("Error: bad Reverse Integrating Constant: %1 (read from block=%2)")
          .arg(_samples[_nSamples-1]).arg(File::fromBigEndian(*((qint32 *)gcfBody))) << endl;
      return false;
    } else {
      return true;
    }
  }
bool GeopsyCore::GuralpCompressedBlock::parseHeader ( const char *  gcfHeader)

References QGpCoreTools::endl(), QGpCoreTools::tr(), and TRACE.

Referenced by readHeader().

  {
    TRACE;
    char str[7];
    // All GCF header are stored in big endian
    qint32 gcfNativeHeader[4];
    for(int i= 0; i<4; i++) {
      gcfNativeHeader[i]=File::fromBigEndian(((const qint32 *)gcfHeader)[i]);
    }
    // Hash for fast comparisons. native header index 2 and 3 must be partially included in comparison
    _hash=gcfNativeHeader[0];
    _hash+=gcfNativeHeader[1];
    // system ID
    base36ToAscii(gcfNativeHeader[0], str);
    strcpy(_systemID, str);
    // stream ID
    base36ToAscii(gcfNativeHeader[1], str);
    strncpy(_device, str, 4);
    _device[4]='\0';
    _component=str[4];
    _channel=str[5];
    switch (_component) {
    case 'Z':
    case 'N':
    case 'E':
    case 'X':
    case 'C':
      if(( _channel > 'D' && _channel < 'G' ) || _channel > 'S') {
        if(_component=='C') {
          App::stream() << tr("Error: Channel Data stream, bad stream ID: %1 (expected CD)").arg(str) << endl;
          return false;
        } else {
          App::stream() << tr("Error: Data stream, bad output tap: %1 (expected 0-9,A-C,G-S)").arg(_channel) << endl;
          return false;
        }
      }
      break;
    case 'M':
      if(_channel > 'F') {
        App::stream() << tr("Error: Mux channel stream, bad channel number: %1 (expected 0-9,A-F)").arg(_channel) << endl;
        return false;
      }
      App::stream() << tr("Error: mux channel stream are currently not supported") << endl;
      return false;
    case '0':
      if(_channel!='0') {
        App::stream() << tr("Error: Status stream, bad stream ID: %1 (expected OO)").arg(str) << endl;
        return false;
      }
      return true;
    case 'B':
      if(_channel!='P') {
        App::stream() << tr("Error: Byte Pipe stream, bad stream ID: %1 (expected BP)").arg(str) << endl;
        return false;
      }
      App::stream() << tr("Error: byte pipe stream are currently not supported") << endl;
      return false;
    case 'I':
      if(_channel!='B') {
        App::stream() << tr("Error: Information Block, bad stream ID: %1 (expected IB)").arg(str) << endl;
        return false;
      }
      return true;
    default:
      App::stream() << tr("Error: bad stream ID: %1").arg(str) << endl;
      return false;
    }
    // Date code
    _startTime.setDate(QDate(1989, 11, 17));
    _startTime.setTime(QTime(0, 0));
    _startTime=_startTime.addDays((gcfNativeHeader[2] & 0xFFFE0000) >> 17);
    _startTime=_startTime.addSecs(gcfNativeHeader[2] & 0x0001FFFF);
    // Data format
    uint intSamplingFrequency=(gcfNativeHeader[3] & 0x00FF0000) >> 16;
    _samplingFrequency=intSamplingFrequency;
    if(_samplingFrequency==0.0) {
      App::stream() << tr("Error: null sampling frequency") << endl;
      return false;
    }
    _hash+=intSamplingFrequency;
    _compressionCode=(gcfNativeHeader[3] & 0x0000FF00) >> 8;
    int newNSamples;
    switch(_compressionCode) {
    case 1:
      newNSamples=gcfNativeHeader[3] & 0x000000FF;
      break;
    case 2:
      newNSamples=(gcfNativeHeader[3] & 0x000000FF) << 1;
      break;
    case 4:
      newNSamples=(gcfNativeHeader[3] & 0x000000FF) << 2;
      break;
    default:
      App::stream() << tr("Error: bad compression code: %1 (expected 1, 2 or 4)").arg(_compressionCode) << endl;
      return false;
    }
    if(newNSamples<1) {
      App::stream() << tr("Error: negative or null number of samples") << endl;
      return false;
    }
    if(newNSamples!=_nSamples) {
      delete [] _samples;
      _samples=new int[newNSamples];
    }
    _nSamples=newNSamples;
    return true;
  }
bool GeopsyCore::GuralpCompressedBlock::readBody ( QFile &  f) [inline]

References parseBody().

Referenced by GeopsyCore::SignalFileFormat::fromContent().

  {
    char body[1008];
    qint64 n=f.read(body,1008);
    if(n!=1008) return false;
    return parseBody(body);
  }
bool GeopsyCore::GuralpCompressedBlock::readHeader ( QFile &  f) [inline]

References parseHeader().

Referenced by GeopsyCore::SignalFileFormat::fromContent().

  {
    // Read the 16 bytes header
    char header[16];
    qint64 n=f.read(header, 16);
    if(n!=16) return false;
    return parseHeader(header);
  }
int GeopsyCore::GuralpCompressedBlock::sample ( int  index) const [inline]
{return _samples[index];}
{return _samplingFrequency;}
void GeopsyCore::GuralpCompressedBlock::skipBody ( QFile &  f) [inline]
  {
    f.seek(f.pos()+1008); // 1024-byte blocks less 16-byte header
  }
QDateTime GeopsyCore::GuralpCompressedBlock::startTime ( ) const [inline]

Referenced by GeopsyCore::GuralpSignal::addRecord().

{return _startTime;}

References BytePipe, ChannelData, Data, Information, MuxChannel, Status, and Unknown.

Referenced by streamTypeString().

  {
    switch(_component) {
    case 'Z':
    case 'N':
    case 'E':
    case 'X':
      return Data;
    case 'C':
      if(_channel=='D' ) {
        return ChannelData;
      } else {
        return Data;
      }
    case 'M':
      return MuxChannel;
    case 'O':
      return Status;
    case 'B':
      return BytePipe;
    case 'I':
      return Information;
    default:
      return Unknown;
    }
  }

References BytePipe, ChannelData, Data, Information, MuxChannel, Status, streamType(), and Unknown.

Referenced by debugPrint().

  {
    switch(streamType()) {
    case Data:
      return "Data";
    case MuxChannel:
      return "MuxChannel";
    case Status:
      return "Status";
    case ChannelData:
      return "ChannelData";
    case BytePipe:
      return "BytePipe";
    case Information:
      return "Information";
    case Unknown:
      break;
    }
    return "Unknown";
  }
TimeRange GeopsyCore::GuralpCompressedBlock::timeRange ( const QDateTime &  refTime) const

References TRACE.

Referenced by GeopsyCore::GuralpSignal::addRecord().

  {
    TRACE;
    int t=refTime.secsTo(_startTime);
    return TimeRange(t, t+_nSamples/_samplingFrequency);
  }

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines