⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccsds_pro.cpp

📁 本源码是一个用于卫星数据处理的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  
#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( &ltime );
 	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( &ltime );
//	*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 + -