C++生成加拿大凤凰(Phoenix)TSn文件格式

最近给 地球物理勘探行业 (大地电磁方法)做了个文件格式转换工具。

将自有的明码时间域文件转换成加拿大凤凰(Phoenix)V8的TSn格式。

凤凰(Phoenix)的格式,24bits存放一组ADC采样码。这个和我们平时32/64bits存储由差异。主要是考虑到仪器原有的adc芯片的精度与存储效率问题。

无码无真相,首先是写header:

/* 写Phoenix记录头 */
void TSnWork::writeHeader()
{
    fwrite(&goHeadPhoenix.uiSec,1, 1, pFile);
    fwrite(&goHeadPhoenix.uiMin,1, 1, pFile);
    fwrite(&goHeadPhoenix.uiHour,1, 1,pFile);
    fwrite(&goHeadPhoenix.uiDay,1, 1, pFile);
    fwrite(&goHeadPhoenix.uiMonth,1, 1, pFile);
    fwrite(&goHeadPhoenix.uiYear,1, 1, pFile);
    fwrite(&goHeadPhoenix.uiDayOfWeek,1, 1, pFile);
    fwrite(&goHeadPhoenix.uiCentury,1, 1, pFile);

    fwrite(&goHeadPhoenix.uiDevSN,2, 1, pFile);
    fwrite(&goHeadPhoenix.uiSampleCntPerRecordPerCh,2, 1, pFile);
    fwrite(&goHeadPhoenix.uiChCntPerScan,1, 1, pFile);
    fwrite(&goHeadPhoenix.uiRecoedHeaderLength,1, 1, pFile);
    fwrite(&goHeadPhoenix.uiRecStatus,1, 1, pFile);
    fwrite(&goHeadPhoenix.uiBitSaturationCode,2, 1, pFile);
    fwrite(&goHeadPhoenix.uiBitWidth,1, 1, pFile);
    fwrite(&goHeadPhoenix.uiFS,2, 1, pFile);
    fwrite(&goHeadPhoenix.uiFSUnit,1, 1, pFile);
    fwrite(&goHeadPhoenix.uiClockStatus,1, 1, pFile);

    fwrite(&goHeadPhoenix.iClockErr,4, 1, pFile);

    fwrite(goHeadPhoenix.acReserved, 6, 1, pFile);

    QString oStrPhoenixHeader = QString("%1世纪   %2/%3/%4/ %5:%6:%7 星期%8")
            .arg(goHeadPhoenix.uiCentury)
            .arg(goHeadPhoenix.uiYear)
            .arg(goHeadPhoenix.uiMonth)
            .arg(goHeadPhoenix.uiDay)
            .arg(goHeadPhoenix.uiHour)
            .arg(goHeadPhoenix.uiMin)
            .arg(goHeadPhoenix.uiSec)
            .arg(goHeadPhoenix.uiDayOfWeek);

    emit sigMsg(MSG_Normal, "写Phoenix记录头时间: "+ oStrPhoenixHeader);
}

再是写数据(ADC采样码):

void TSnWork::writeADC(float number)
{
    unsigned char high;
    unsigned char middle;
    unsigned char low;

    unsigned char buffer[3];

    unsigned int intNumber;

    if(number >= 0)
    {
        intNumber = int(std::abs(floor(number)));
    }
    else
    {
        intNumber = ~int(std::abs(floor(number))) + 1;
    }

    high   = intNumber/65536;
    middle = (intNumber%65536)/256;
    low    = intNumber%256;

    buffer[0] = low;
    buffer[1] = middle;
    buffer[2] = high;

    fwrite(buffer, BIT_WIDTH, 1, pFile);
}

MT  的TS5 和  AMT的 TS4   连续采样简单,直接写就ok。

MT 间隔采样 TS3, TS4

AMT 间隔采样 TS2, TS3

相对来说要skip,同时要把header 里面的utc秒给skip对齐。

以下是AMT TS3 的流程代码:

/* 间隔采样, 第一个片段丢弃,第二个片段留着指定的 L3NS record个数 */
void TSnWork::writeAMT_TS3(quint32 uiHSMP, quint32 uiL3NS)
{
        /* 区别对待自有设备连续采集和间隔采集 */
    if(goHeaderWFEM.uiSlicBase == goHeaderWFEM.uiSliceSample)
    {
        uiSlicCnt = goHeaderWFEM.uiDataCnt/uiHSMP/goHeaderWFEM.uiFS/2;
        uiSkipSecs = 2*uiHSMP - uiL3NS ;
        uiAddSecs =  2*uiHSMP - uiL3NS;
    }
    else
    {
        uiSlicCnt = goHeaderWFEM.uiDataCnt/goHeaderWFEM.uiSliceSample/goHeaderWFEM.uiFS/2;
        uiSkipSecs = 2*goHeaderWFEM.uiSliceSample - uiL3NS;
        uiAddSecs =  2*goHeaderWFEM.uiSlicBase - uiL3NS ;
    }

    for(quint64 i = 0; i < uiSlicCnt; i++)
    {
        for(quint32 j = 0; j < uiL3NS; j++)
        {
            this->writeHeader();

            this->writeScan( goHeaderWFEM.uiFS );

            this->updateHeadPhoenix( 1 );

            emit sigMsg(MSG_Normal, QString("AMT TS3 间隔采样,\u058E记录:%1/%2\u058E片段:%3/%4 \n")
                        .arg(j+1)
                        .arg(uiL3NS)
                        .arg(i+1)
                        .arg(uiSlicCnt));
        }
        this->skipRows( goHeaderWFEM.uiFS*uiSkipSecs );
        this->updateHeadPhoenix( uiAddSecs );
    }

    fclose(pFile);

    emit sigMsg(MSG_Over, "AMT TS3 间隔采样写入完毕!");
}

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值