All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Public Member Functions | Static Public Member Functions | Public Attributes
GeopsyCore::SEGYTraceHeader Class Reference

Brief description of class still missing. More...

#include <SEGYTraceHeader.h>

List of all members.

Public Member Functions

QDateTime dateTime () const
void read (QDataStream &s)
Point receiver () const
 SEGYTraceHeader ()
bool setCoordinateFactor (const Point &rec, const Point &src)
bool setElevationFactor (const Point &rec, const Point &src)
bool setNSamples (int n)
void setReceiver (const Point &rec)
void setSource (const Point &src)
bool setSUT0 (double t)
bool setT0 (double t)
Point source () const
double SUt0 () const
double t0 () const
void write (QDataStream &s)

Static Public Member Functions

static SignalFileFormat::Format determineByteOrderSEGY (QString fileName)
static SignalFileFormat::Format determineByteOrderSU (QString fileName)
static double IBMFloat2ieee (qint32 val)
static bool isSampleCodingValid (qint16 sampleCoding)

Public Attributes

union {
   struct {
      qint16   aliasFilterFrequency
      qint16   aliasFilterSlope
      qint16   amplitudeUnit
      qint16   coordinateFactor
      qint16   coordinateUnit
      qint16   correlated
      qint16   dataUse
      qint16   day
      qint16   delayRecordingTime
      qint16   elevationFactor
      qint16   endMuteTime
      qint16   endSweepFrequency
      qint16   endSweepTaper
      qint32   ensembleNumber
      qint16   gainConstant
      qint16   gainType
      qint16   highCutFrequency
      qint16   highCutSlope
      qint16   hour
      qint16   ignored01
      qint16   ignored02
      qint16   ignored03
      qint16   ignored04
      qint16   ignored05
      qint32   ignored06
      qint32   ignored07
      qint32   ignored08
      qint32   ignored09
      qint32   ignored10
      qint16   ignored11
      qint32   ignored12
      qint16   ignored13
      qint16   ignored14
      qint16   ignored15
      qint16   ignored16
      qint16   ignored17
      qint32   ignored18
      qint32   ignored19
      qint16   ignored20
      qint16   ignored21
      qint32   ignored22
      qint32   ignored23
      qint16   initialGain
      qint16   lagTimeA
      qint16   lagTimeB
      qint16   lengthSweepFrequency
      qint16   lowCutFrequency
      qint16   lowCutSlope
      qint16   minute
      qint16   notchFilterFrequency
      qint16   notchFilterSlope
      qint16   numberStackHorizontal
      qint16   numberSumVertical
      qint32   originalRecordNumber
      qint32   receiverDatumElevation
      qint32   receiverElevation
      qint16   receiverStaticCorrection
      qint16   receiverUpholeTime
      qint32   receiverWaterDepth
      qint32   receiverXCoordinate
      qint32   receiverYCoordinate
      quint16   sampleInterval
      quint16   sampleNumber
      qint16   second
      qint32   sourceDatumElevation
      qint32   sourceDepth
      qint32   sourceNumber
      qint32   sourceReceiverDistance
      qint16   sourceStaticCorrection
      qint32   sourceSurfaceElevation
      qint16   sourceUpholeTime
      qint32   sourceWaterDepth
      qint32   sourceXCoordinate
      qint32   sourceYCoordinate
      qint16   startMuteTime
      qint16   startSweepFrequency
      qint16   startSweepTaper
      qint16   subWeatheringVelocity
      qint16   sweepType
      qint16   taperType
      qint16   timeBase
      qint16   timeFactor
      qint16   totalStaticCorrection
      qint16   traceIndentificationCode
      qint32   traceNumberInEnsemble
      qint32   traceNumberInFile
      qint32   traceNumberInLine
      qint32   traceNumberInRecord
      qint16   weatheringVelocity
      qint16   weightFactor
      qint16   year
   }   field
   struct {
      qint32   raw0 [7]
      qint16   raw1 [4]
      qint32   raw2 [8]
      qint16   raw3 [2]
      qint32   raw4 [4]
      qint16   raw5 [46]
      qint32   raw6 [5]
      qint16   raw7 [20]
   }   raw
}; 

Detailed Description

Brief description of class still missing.

Format of SEGY trace header (same as the SU trace header) The following offsets are read from SEG Y rev 1 (2002) SEG Technical Standards Committee

This document is available at: http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf


Constructor & Destructor Documentation

References TRACE.

  {
    TRACE;
    ASSERT(sizeof(SEGYTraceHeader)==240);
    memset(this, 0, 240);
  }

Member Function Documentation

References field, and TRACE.

  {
    TRACE;
    QDateTime t(QDate( field.year , 1, 1), QTime(field.hour, field.minute, field.second));
    t=t.addDays(field.day - 1);
    return t;
  }

Determination of byter order is based on sample type read from file header. For SEGY format only.

References QGpCoreTools::endl(), isSampleCodingValid(), GeopsyCore::SignalFileFormat::SegYBigEndian, GeopsyCore::SignalFileFormat::SegYLittleEndian, QGpCoreTools::tr(), TRACE, and GeopsyCore::SignalFileFormat::Unknown.

Referenced by GeopsyCore::SignalFileFormat::fromContent(), and GeopsyCore::SignalFileFormat::fromSuffix().

  {
    TRACE;
    QFile f(fileName);
    if( !f.open(QIODevice::ReadOnly) ) {
      return SignalFileFormat::Unknown;
    }
    QDataStream s(&f);
    qint64 binHeaderOffset=3200;
    // Skip file header: need the number of extended textual file headers and sample coding
    qint16 sampleCoding;
    s.setByteOrder(QDataStream::LittleEndian);
    f.seek(binHeaderOffset + 24);
    s >> sampleCoding;
    bool littleEndian=isSampleCodingValid(sampleCoding);
    s.setByteOrder(QDataStream::BigEndian);
    f.seek(binHeaderOffset + 24);
    s >> sampleCoding;
    bool bigEndian=isSampleCodingValid(sampleCoding);
    if((littleEndian && bigEndian) || (!littleEndian && !bigEndian)) {
      App::stream() << tr("Cannot determine byte order for SEGY format.") << endl;
      return SignalFileFormat::Unknown;
    } else if(littleEndian) {
      return SignalFileFormat::SegYLittleEndian;
    } else {
      return SignalFileFormat::SegYBigEndian;
    }
  }

Determination of byter order is based on number of samples read from trace header. There is no other fixed and mandatory field that can help us to determine the byte order. All traces are read and number of samples are calculated, if it matched the file size, than there are good chances that the right byte order has been found. For SU format only.

References QGpCoreTools::endl(), GeopsyCore::SignalFileFormat::SuBigEndian, GeopsyCore::SignalFileFormat::SuLittleEndian, QGpCoreTools::tr(), TRACE, and GeopsyCore::SignalFileFormat::Unknown.

Referenced by GeopsyCore::SignalFileFormat::fromContent(), and GeopsyCore::SignalFileFormat::fromSuffix().

  {
    TRACE;
    QFile f(fileName);
    if( !f.open(QIODevice::ReadOnly) ) {
      return SignalFileFormat::Unknown;
    }
    QDataStream s(&f);
    s.setByteOrder(QDataStream::LittleEndian);
    bool littleEndian=suCanReadAll(s, f.size());
    f.seek(0);
    s.setByteOrder(QDataStream::BigEndian);
    bool bigEndian=suCanReadAll(s, f.size());
    if((littleEndian && bigEndian) || (!littleEndian && !bigEndian)) {
      App::stream() << tr("Cannot determine byte order for SU format.") << endl;
      return SignalFileFormat::Unknown;
    } else if(littleEndian) {
      return SignalFileFormat::SuLittleEndian;
    } else {
      return SignalFileFormat::SuBigEndian;
    }
  }
double GeopsyCore::SEGYTraceHeader::IBMFloat2ieee ( qint32  val) [static]

Conversion from IBM floats to IEEE double precision.

See http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture for IBM structure.

References QGpCoreTools::exp(), and TRACE.

  {
    TRACE;
    //val=0xC276A000; // test: -118.625 with IBM floats (see wiki)
    /*
      2^(-24)*16^(t-64)=2^(-24)*2^(4t-256)=2^(4t-280)
      -24 is to set fmant as a fraction
      -256 for ibm float bias
      +1023 to introduce double bias
      (-280+1023)*16=0x2E70
      16 is a 4-bit shift, from short to 12 bit representation of double exp
      0x7f00 & *(reinterpret_cast<unsigned short *>(&val)+1) is the ibm float exp multiplied by 16
      which must be multipled by 4, hence only divided by 4.

      Conversion to IEEE double:
      For a null fraction, val=2^(exp-1023), 2^-1=3fe0 0000 0000 0000  (3fe=1022)
                                             2^-2=3fd0 0000 0000 0000
    */
    double res=0.0;
    if(val) {
      union {
        double val;
        unsigned short s[4];
      } t;
      t.val=0.0;
      double fmant=static_cast<double>(0x00ffffff & val);
  #if Q_BYTE_ORDER==Q_BIG_ENDIAN
      // Never tested on a big endian architecture
      unsigned short& exp=t.s[0];
  #else
      unsigned short& exp=t.s[3];
  #endif
      exp=(0x7f000000 & val) >> 18;
      exp+=0x2E70;
      if(val<0) { // negative number
        res=-fmant*t.val;
      } else {
        res=fmant*t.val;
      }
    }
    return res;
  }
bool GeopsyCore::SEGYTraceHeader::isSampleCodingValid ( qint16  sampleCoding) [static]

Referenced by determineByteOrderSEGY().

  {
    switch(sampleCoding) {
    case 1:
    case 2:
    case 3:
    case 5:
    case 8:
      return true;
    default:
      return false;
    }
  }
void GeopsyCore::SEGYTraceHeader::read ( QDataStream &  s)

References raw, and TRACE.

  {
    TRACE;
    for(int i=0;i<7;i++) s >> raw.raw0[i];
    for(int i=0;i<4;i++) s >> raw.raw1[i];
    for(int i=0;i<8;i++) s >> raw.raw2[i];
    for(int i=0;i<2;i++) s >> raw.raw3[i];
    for(int i=0;i<4;i++) s >> raw.raw4[i];
    for(int i=0;i<46;i++) s >> raw.raw5[i];
    for(int i=0;i<5;i++) s >> raw.raw6[i];
    for(int i=0;i<20;i++) s >> raw.raw7[i];
  }

References field, and TRACE.

  {
    TRACE;
    double sfxy=decodeCoordinateFactor();
    double sfz=decodeElevationFactor();
    return Point((double) field.receiverXCoordinate*sfxy,
                 (double) field.receiverYCoordinate*sfxy,
                 (double) field.receiverElevation*sfz);
  }
bool GeopsyCore::SEGYTraceHeader::setCoordinateFactor ( const Point rec,
const Point src 
)

References QGpCoreTools::endl(), field, QGpCoreTools::tr(), QGpCoreTools::Point2D::x(), and QGpCoreTools::Point2D::y().

Referenced by GeopsyCore::Signal::writeSegySu().

  {
    double max=fabs(src.x());
    double min=fabs(src.x());
    if(fabs(src.y())>max)
      max=fabs(src.y());
    else if(fabs(src.y())<min)
      min=fabs(src.y());
    if(fabs(rec.x())>max)
      max=fabs(rec.x());
    else if(fabs(rec.x())<min)
      min=fabs(rec.x());
    if(fabs(rec.y())>max)
      max=fabs(rec.y());
    else if(fabs(rec.y())<min)
      min=fabs(rec.y());

    field.coordinateFactor=factor(min, max, 2147483647.0);
    if(field.coordinateFactor==0) {
      App::stream() << tr("Coordinate range cannot be represented with SEGY format ([%1, %2]).").arg(min).arg(max) << endl;
      return false;
    } else {
      return true;
    }
  }
bool GeopsyCore::SEGYTraceHeader::setElevationFactor ( const Point rec,
const Point src 
)

References field, and QGpCoreTools::Point::z().

Referenced by GeopsyCore::Signal::writeSegySu().

  {
    double max=fabs(src.z());
    double min=fabs(src.z());
    if(fabs(rec.z())>max)
      max=fabs(rec.z());
    else if(fabs(rec.z())<min)
      min=fabs(rec.z());

    field.elevationFactor=factor(min, max, 2147483647.0);
    return field.elevationFactor!=0;
  }

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

Referenced by GeopsyCore::Signal::writeSegySu().

  {
    TRACE;
    if(n>65535) {
      App::stream() << tr("too many samples for SEG-Y traces: maximum=65535, value=%1").arg(n) << endl;
      return false;
    } else {
      field.sampleNumber=n;
      return true;
    }
  }

References field, QGpCoreTools::Point2D::x(), QGpCoreTools::Point2D::y(), and QGpCoreTools::Point::z().

Referenced by GeopsyCore::Signal::writeSegySu().

  {
    double sfxy=encodeCoordinateFactor();
    double sfz=encodeElevationFactor();
    field.receiverXCoordinate=(qint32)round(rec.x()*sfxy);
    field.receiverYCoordinate=(qint32)round(rec.y()*sfxy);
    field.receiverElevation=(qint32)round(rec.z()*sfz);
    field.receiverDatumElevation=0;
    field.coordinateUnit=1; // Length (Meters or feet)
  }

References field, QGpCoreTools::Point2D::x(), QGpCoreTools::Point2D::y(), and QGpCoreTools::Point::z().

Referenced by GeopsyCore::Signal::writeSegySu().

  {
    double sfxy=encodeCoordinateFactor();
    double sfz=encodeElevationFactor();
    field.sourceXCoordinate=(qint32)round(src.x()*sfxy);
    field.sourceYCoordinate=(qint32)round(src.y()*sfxy);
    field.sourceSurfaceElevation=(qint32)round(src.z()*sfz);
    field.sourceDepth=0;
    field.sourceDatumElevation=0;
    field.coordinateUnit=1; // Length (Meters or feet)
  }

SU considers all fields after byte 180 differently than SEGY standard.

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

Referenced by GeopsyCore::Signal::writeSegySu().

  {
    TRACE;
    if(fabs(t)>32.767) {
      App::stream() << tr("T0 cannot be represented with SU format (%1>32.767).").arg(t) << endl;
      return false;
    } else {
      field.delayRecordingTime=round(t*1e3);  // milliseconds is stored
      return true;
    }
  }

T0 according to SEGY standard.

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

Referenced by GeopsyCore::Signal::writeSegySu().

  {
    TRACE;
    t*=1e3;  // milliseconds is stored
    field.timeFactor=factor(t, t, 32767.0);
    if(field.timeFactor==0) {
      App::stream() << tr("T0 cannot be represented with SEGY format (%1 ms).").arg(t) << endl;
      return false;
    } else {
      double f=encodeTimeFactor();
      field.delayRecordingTime=(int)round(f*t);
      return true;
    }
  }

References field, and TRACE.

  {
    TRACE;
    double sfxy=decodeCoordinateFactor();
    double sfz=decodeElevationFactor();
    return Point((double) field.sourceXCoordinate*sfxy,
                 (double) field.sourceYCoordinate*sfxy,
                 (double) (field.sourceSurfaceElevation-field.sourceDepth)*sfz);
  }

SU considers all fields after byte 180 differently than SEGY standard.

References field, and TRACE.

  {
    TRACE;
    return field.delayRecordingTime*1e-3;
  }

T0 according to SEGY standard.

References field, and TRACE.

  {
    TRACE;
    double f=decodeTimeFactor();
    return field.delayRecordingTime*1.e-3*f;
  }
void GeopsyCore::SEGYTraceHeader::write ( QDataStream &  s)

References raw, and TRACE.

Referenced by GeopsyCore::Signal::writeSegySu().

  {
    TRACE;
    for(int i=0;i<7;i++) s << raw.raw0[i];
    for(int i=0;i<4;i++) s << raw.raw1[i];
    for(int i=0;i<8;i++) s << raw.raw2[i];
    for(int i=0;i<2;i++) s << raw.raw3[i];
    for(int i=0;i<4;i++) s << raw.raw4[i];
    for(int i=0;i<46;i++) s << raw.raw5[i];
    for(int i=0;i<5;i++) s << raw.raw6[i];
    for(int i=0;i<20;i++) s << raw.raw7[i];
  }

Member Data Documentation

union { ... }

Referenced by read(), and write().


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