📄 ccsds_pro.cpp
字号:
#include <error.h>
#include <assert.h>
#include <stdlib.h>
#include <time.h>
#include "StdAfx.h"
#include "ccsds_pro.h"
#include "ccsds.h"
#include "fits_sci.h"
/*****************************************************
** 函数名: get_fits_filename
** 输入: hxmtfile
** hxmtfile --- 文件名结构
** 输出: filename,ptname, mode, fitsfilename
** filename --- 最终的保存路径
** ptname --- 1级产品的目录名
** mode --- 模式
** fitsfilename---fits文件名
** 调用说明:
** is_x_mode() .......得到飞行模式
** get_cir_num()......巡天模式下得到飞行圈数
** get_x_id().........定点模式下得到任务标识号
**
** 功能描述: 输入一个文件名结构变量,判断出文件类型,并返回最终的保存路径,1级产品的目录名,模式,fits文件名称
****************************************************************************************/
int get_fits_filename( const hxmt_file_t *hxmtfile, std::string &filename, std::string &ptname, int &mode, std::string &fitsfilename )
{
if( hxmtfile == NULL )
return -1;
int res; //模式(1表示巡天,0定点)
char fitsname[20] = "Mnnnnnnst.NA1"; //fits所有文件名称,M根据模式不同分别为X(巡天),P(定点),类型不同其中的st取不同的值
char path[20] = "Mnnnnnn_A"; //1级产品的目录名,M取值如同上面
if( (res = is_x_mode(hxmtfile->start)) < 0 )//判断模式文件中是否有对应的模式,为真则没有对应模式
return res; //返回负数,退出函数
if( res ) {
fitsname[0] = 'X';//巡天模式
path[0] = 'X';
int n = get_cir_num( hxmtfile->start );//取得圈数
if( n < 0 )
return -1;
sprintf( fitsname+1, "%.6d", n );//把圈数写入文件名中
sprintf( path+1, "%.6d" , n ); //把圈数写入目录名中
fitsname[7] = 's';
path[7] = '_';
} else {
fitsname[0] = 'P';//定点模式
path[0] = 'P';
std::string id = get_x_id( hxmtfile->start );//取得定点模式下的标识
if( id == "" )
return -1;
strncpy( fitsname+1, id.c_str(), min(6, id.length()) );//把标识写入文件名中
strncpy( path+1, id.c_str(), min(6, id.length()) ); //把标识写入目录名中
}
mode = res;//通过mode返回模式
/******************根据文件名中的type确定fits文件的名字**********************/
switch( hxmtfile->type ) {
case SCI_HXTA:
fitsname[7] = 'X'; fitsname[8] = 'N'; break;//硬X射线事例A
case SCI_HXTB:
fitsname[7] = 'Y'; fitsname[8] = 'N'; break;//硬X射线事例B
case SCI_HXTC:
fitsname[7] = 'Z'; fitsname[8] = 'N'; break;//硬X射线事例C
case SCI_SXT1:
fitsname[7] = 'U'; fitsname[8] = 'N'; break;//软X科学数据1
case SCI_SXT2:
fitsname[7] = 'V'; fitsname[8] = 'N'; break;//软X科学数据2
case EPH:
fitsname[7] = 'B'; fitsname[8] = 'A'; break;//星历数据文件
case JS:
fitsname[7] = 'L'; fitsname[8] = 'A'; break;//时间校准文件
case ML:
fitsname[7] = 'I'; fitsname[8] = 'A'; break;//命令历史文件
case ZT:
fitsname[7] = 'A'; fitsname[8] = 'A'; break;//姿态数据文件
case TIMELINE:
fitsname[7] = 'T'; fitsname[8] = 'A'; break;//TIMELINE文件
case FZCS:
fitsname[7] = 'S'; fitsname[8] = 'A'; break;//遥测数据文件
case HXFREQ:
fitsname[7] = 'F'; fitsname[8] = 'H'; break;//硬X射线记数率
case HXPUL:
fitsname[7] = 'P'; fitsname[8] = 'H'; break;//硬X脉冲宽度
case HXHV:
fitsname[7] = 'H'; fitsname[8] = 'H'; break;//硬X高压监测
case PTCFREQ:
fitsname[7] = 'Q'; fitsname[8] = 'H'; break;//粒子监测器记数率
default:
break;
}
extern std::string product_dest_dir; //一级产品保存目录
filename = product_dest_dir;
/******************根据文件名中的type确定一级产品保存路径***************/
switch( hxmtfile->type ) {
case SCI_HXTA:
case SCI_HXTB:
case SCI_HXTC:
case SCI_SXT1:
case SCI_SXT2:
filename += path;
filename += "\\NSD\\"; //科学文件保存路径
break;
case EPH:
case JS:
case ML:
case TIMELINE:
case FZCS:
case ZT:
filename += path;
filename += "\\AUX1\\";//辅助文件的保存路径
break;
case HXFREQ:
case HXPUL:
case HXHV:
case PTCFREQ:
filename += path;
filename += "\\HKD\\";//载荷housekeeping文件的保存路径
break;
default:
break;
}
filename += fitsname; //最终的保存路径
ptname = path; //通过ptname返回1级产品的目录名
fitsfilename = fitsname; //通过fitsfilename返回fits文件名
return 0; //函数执行完毕返回0
}
/**********************************************
** 函数名: Tm2Time
** 输入: data
** data --- 时间码数组
** 输出: tm,usec
** tm--- 秒以上累计秒
** usec-- 累计微妙
** 功能描述: 输入一个时间码数组,输出对应的时间,以秒和微妙输出
*************************************************/
int Tm2Time( const unsigned char *data, time_t *tm, time_t *usec )
{
/*
__int64 ltime;
ltime = (((int)data[0])<<24) + (((int)data[1])<<16) + (((int)data[2])<<8) + ((int)data[3]);
ltime <<= 16;
ltime += (((int)data[4])<<8) + ((int)data[5]);
*/
// struct tm *t = _gmtime64( <ime );
extern time_t global_time_offset;//时间零点
long ltime;//秒以上部分累计秒
long utime;//微秒
ltime = (((int)data[0])<<24) + (((int)data[1])<<16) + (((int)data[2])<<8) + ((int)data[3]);//取时间数组中对应的秒
utime = (((int)data[4])<<8) + ((int)data[5]);//取时间数组中对应的微妙
// struct tm *t = gmtime( <ime );
// *tm = *t;
*tm = ltime + global_time_offset;//秒
*usec = utime * 20; //微妙
return 0;
}
/*****************************************************
** 函数名: process_hx_sci
** 输入: hxmtfile
** hxmtfile --- 文件名结构变量
** 输出:
** 返回0则说明函数执行成功,其他则说明没有处理成功
** 调用说明:
** reset_find_pointer()
** Tm2Time()
** event_type()
** stime()
** ptime()
** get_fits_filename()
** update_fits_keys()
** close_fits_sci()
** set_hxtime()
** write_fits_hx_sci()
** 功能描述: 处理科学数据源包并生成高能X射线事例的fits文件
****************************************************************************************/
int process_hx_sci( const hxmt_file_t *hxmtfile )
{
unsigned long offset = 0; //偏移量
unsigned char *buffer = NULL;//读入的科学数据存放区
FILE *in = NULL; //文件结构
int prev_event_type = 0x03; //高能X射线事例类型,初始值设定为系统秒事例
int status = NO_ERROR;
fitsfile *fptr = NULL;//fits文件结构
hxmt_file_t hxmt;//文件结构
int modetype, mode_for_update;//模式
std::string fits_name;
timespec_t fits_start;//起时间
timespec_t fits_end; //结始束时间
bool bnewfitsfile = true;
if( !hxmtfile || (in = fopen(hxmtfile->filename.c_str(), "r+b")) == NULL )//打开文件
return -1;
hxmt = *hxmtfile;
if( (buffer = (unsigned char *)malloc(FREAD_BUFFER_SIZE)) == NULL )//开一个4096字节的空间
{
fclose(in);
return -ERROR_NOT_ENOUGH_MEMORY;
}
memset( buffer, 0, FREAD_BUFFER_SIZE );//新开空间置0
ZT_t::reset_find_pointer(); //重新设置查找姿态文件的起始点
while( !feof(in) && !ferror(in) )
{
int nStart = 0;//数据起点
offset += fread(buffer+offset, sizeof(unsigned char), FREAD_BUFFER_SIZE-offset, in);//从文件中读数据到buffer
if( offset < SCI_PACKET_LENGTH )//小于500字节继续读入科学数据
continue;
while( offset - nStart >= SCI_PACKET_LENGTH )//当buffer中的未处理的数据大于500字节时循环处理buffer中的数据
{
H_SCI_header *sci = (H_SCI_header *)(buffer+nStart);//得到一包数据的高能X射线包头,由sic指向
unsigned char *data = buffer+nStart+HXM_SCI_PACKET_HDR_LENGTH;//得到一包数据的事例数据部分
Tm2Time( sci->time_code, &hxmt.start.time, &hxmt.start.usec );//读科学数据包头中的时间码得到起始时间
for( int i = 0; i < 96; i++ )//循环处理96个高能X射线事例
{
HXM_t *hxm = (HXM_t *)data;
unsigned char hxm_data[2];
timespec_t time;
hx_t h_time;//定义一个高能X射线事例结构变量
memset( hxm_data, 0, sizeof(hxm_data) );//置0
memset( &h_time, 0, sizeof(h_time) );//置0
int e = event_type( hxm );
//01:GPS秒事例11: 系统秒事例,如果是秒事例则对应取秒事例,否则取物理事例
if( e == 0x01 || e == 0x03 ) {
hxmt.start.time = stime( hxm );
prev_event_type = e;
} else {
hxmt.start.usec = ptime(hxm)<<2;//取秒事例的18位秒以下的微妙数
{
std::string prev_fitsname;//上一次处理的文件路径
if( fptr )
prev_fitsname = fptr->Fptr->filename;
std::string new_fitsname;//新路径
std::string pathname; //一级产品目录
if( get_fits_filename(&hxmt, new_fitsname, pathname, modetype, fits_name) )//通过new_fitsname返回新路径
{
status = -4; goto PROCESS_OUT;
}
if( new_fitsname != prev_fitsname )//判断新路径和上次路径是否一样
{
if( fptr != NULL ) {
update_fits_keys( fptr, &fits_start, &fits_end, mode_for_update );//更新fits头中的关键字
close_fits_sci( fptr );
}
fptr = NULL;
if( 0 != open_fits_hx_sci( &hxmt, &fptr ) )//写fits头中的信息,建立fits头
{
status = -3; goto PROCESS_OUT;
}
mode_for_update = modetype;//模式
bnewfitsfile = true;
}
}
hxm_data[0] = (char)energy( hxm );//高能X射线事例能量
hxm_data[1] = (char)chaNo( hxm ) + (char)brd_no( hxm ) * 6;//高能X射线事例通道号
if( hxm_data[1] == 0 )
continue;
time.time = hxmt.start.time;
time.usec = ptime(hxm)<<2;
struct tm *tm = NULL;
if( (tm = localtime(&time.time)) != NULL )
set_hxtime( &h_time, tm, time.usec );//得到高能X射线事例时间(用7个字节表示)
if( bnewfitsfile ) {
fits_start = fits_end = hxmt.start;
bnewfitsfile = false;
}
if( 0 != write_fits_hx_sci( fptr, (const char *)hxm_data, h_time, 1, &hxmt.start) )//写科学数据到fits文件中
{
status = -2;
goto PROCESS_OUT;
}
fits_end = hxmt.start;
}
data += HXM_LENGTH;//循环得到下一个事例
}
nStart += SCI_PACKET_LENGTH;//循环处理下一个数据源包
}
offset -= nStart;//数据长度小于500字节时所剩的字节数
memcpy( buffer, buffer+nStart, offset );//把数据长度小于500字节时所剩的字节数拷贝到数据区开头下次再处理
}
PROCESS_OUT:
if( fptr ) {
update_fits_keys( fptr, &fits_start, &fits_end, mode_for_update );
close_fits_sci( fptr );
}
free( buffer );
fclose( in );
return NO_ERROR;
}
/*****************************************************
** 函数名: process_sx_sci
** 输入: hxmtfile
** hxmtfile --- 文件名结构变量
** 输出:
** 返回0则说明函数执行成功,其他则说明没有处理成功
** 调用说明:
** reset_find_pointer()
** Tm2Time()
** event_type()
** stime()
** ptime()
** get_fits_filename()
** update_fits_keys()
** close_fits_sci()
** set_sxtime()
** write_fits_sx_sci()
** 功能描述: 处理科学数据源包并生成低能X射线事例的fits文件
****************************************************************************************/
int process_sx_sci( const hxmt_file_t *hxmtfile )//程序具体注释请参照上个处理高能X射线的函数
{
unsigned long offset = 0;
unsigned char *buffer = NULL;
FILE *in = NULL;
int prev_event_type = 3;
int status = NO_ERROR;
fitsfile *fptr = NULL;
hxmt_file_t hxmt;
int modetype, mode_for_update;
std::string fits_name;
timespec_t fits_start;
timespec_t fits_end;
bool bnewfitsfile = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -