#include "common.h"
#include "ysp_debug.h"
#include "msq.h"
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "thread.h"
#include "analysis.h"
//#include "modbus_rtu_slave.h"

#define DEBUG_ANALYSIS
#define AVR_NUM 4    //平均滤波点数,原来是8点
#define REDUCE_BIT   1 //缩小位数,原来是2bit
#define SUM_NUM      8  //ÿ��Ŀ��� 
#define MOVE_NUM     8  //��������ƶ��ĵ��� 
#define JUDGE_NUM    8  //ÿ�������жϵĵ��� 

#define MAX_JUDGE_NUM 32 //�����жϵ���
#define MIN_JUDGE_NUM 7  //��С�жϵ��� 
 
#define MIN_AMP      8  //最小峰高，原来是4
#define MIN_LEN      24 //起点到顶点的最低宽度

#define BACK_SUM_NUM 20
/*
����˳��˵��:
����ΪH2,CO,CH4,C2H4,C2H6,C2H2 
ǰ������㹫ʽΪ:
S=A*K=K*h*tr
A=��߼���ֵ
h=���(�ߵ�ֵ-��׼ֵ) 
tr=����ʱ��(��)
K=�궨ϵ��

��������㹫ʽΪ:
S=A*K=K*1.064*h*(y/2)=1.064*K*h*h/4 
A=1.064*h*(y/2)=1.064*h*h/4
y/2=����
h=���=������ߵ�-������
y/2=h/2 
�߶�������ʽ
H'=Kx(H-��С�߶�)*tr+���Ũ��ֵ 
HΪ������ĸ߶�  

//���������ʽ:
S'=Kx(S-��С���)+���Ũ��ֵ  
����KxΪK1-K12�е�һ��ϵ��,SΪԭʼ���ݼ��������� 
Kxͨ��S������������С�����������λ�ò��Kx�����ļ��� 
��С���Ϊkx_fac4,KxΪkx_fac1,��Ũ��ֵΪkx_fac2 
*/

#define MIN_SLOPE  1
#define ANALYSIS_MESSAGE_SIZE 1024
#define ANALYSIS_MAX_MESSAGE  8
#define ANALYSIS_MQ_PRIO      30
#define ANALYSIS_MQ "/analysis_mq"

#define MAX_DATA_LEN 5000
char *make_south_file_name(time_t t);
int save_south_wave(char *file_name);
int mk_south_wave(YSP_PARA *para_ptr,FIND_POS_DATA *pos_data,YSP_PRI_DATA *out_data);

const char *gas_names[]={"H2","CO","CH4","C2H4","C2H6","C2H2","CO2"};

SOUTH_WAVE_TYPE south_wave;


mqd_t analysis_mq;//
char analysis_buf[ANALYSIS_MESSAGE_SIZE];

int slope_data[MAX_DATA_LEN];

int filter_data[MAX_DATA_LEN];

int raw_data_buf[MAX_DATA_LEN];

/*
1.����б�ʼ��㶥������
2.��һ��δ�ҵ�,���������ֵ
3.ǰ����δ�ҳ�,�����趨�Ĳ������� 
*/

//�������͵��ۼӺ� 
int cal_int_sum(int *buf,int len)
{
 int sum=0;
 int i;
 if(buf==NULL)
   return 0;
 for(i=0;i<len;i++)
  sum+=(*buf++);
 return sum;	
}

//�������͵�ƽ��ֵ 
int cal_int_avr(int *buf,int len)
{
 int sum=0;
 if(len<=0)
   return 0;
 sum=cal_int_sum(buf,len);
 return sum/len;
}

//��С���̱��ڷ��� 
void reduce_data(int *buf,int len,int *out,int fac)
{
 int i;
 for(i=0;i<len;i++)	
 {
  out[i]=(buf[i]>>fac);	
 }
}



//�������ֵ,�������ֵ��λ�� 
int find_max_val(int *buf,int len,int *val)
{
 int i;
 int max_val,max_pos;
 max_val=buf[0];
 max_pos=0;
 
 for(i=0;i<len;i++)
   {
   	if(buf[i]>max_val)
	  {
  	    max_val=buf[i];
		max_pos=i;	
  	  } 
   }
 if(val!=NULL)
   *val=max_val;
 return max_pos;	
}
//time():974943297
//time()->localtime()->mktime():974943297 
int find_max_val_ex(int *buf,int len,int *val)
{
 int i;
 int max_val,max_pos;
 
 max_val=buf[0];
 max_pos=0;
 for(i=0;i<len;i++)
   {
   	if(buf[i]>=max_val)
	  {
  	    max_val=buf[i];
		max_pos=i;	
  	  } 
   }
 if(val!=NULL)
   *val=max_val;
 return max_pos;	
}

//ref_val�᷵�����һ���ֵ 
void process_data(int *raw_data,int len,int *ref_val)
{
 static float proc_data[MAX_DATA_LEN];
 float start_val,end_val,delt_y;
 float offs;
 int i;
 
 
 for(i=0;i<len;i++)
  {
    proc_data[i]=(float)raw_data[i];	
  }
 //start_val=(float)cal_int_avr(&raw_data[0],4);//ȡ��㿪ʼ8��ƽ�� 
 //end_val=(float)cal_int_avr(&raw_data[len-9],4);//ȡ�յ�ǰ8��ƽ�� 
 start_val=(float)raw_data[0];
 end_val=(float)raw_data[len-1];
 delt_y=(end_val-start_val)/len;//�����ݶ� 
 
 offs=(float)(start_val-((float)(*ref_val)));//����ֵ��ȥ�ο�ֵ���ƫ�� 
 //printf("start=%f ref_val=%d offs=%f\n",start_val,*ref_val,offs);
 //if(delt_y>0)
  //{
   for(i=0;i<len;i++)
    {
     proc_data[i]=proc_data[i]-delt_y*i;//��ƽ 
	 raw_data[i]=(int)(proc_data[i]-offs);//��������	
    } 
   *ref_val=raw_data[i-1]; 	
//  }
}


/* 
//�������ֵ,�������ֵ��λ�� 
int find_max_val_ex(int *buf,int len,int *val)
{
 int i;
 int max_val,max_pos,top_end_pos,top_end_val;
 int curr;
 
 top_end_val=cal_int_sum(&buf[len-1-BACK_SUM_NUM],BACK_SUM_NUM);
 top_end_pos=len-1-BACK_SUM_NUM;
 
 for(i=(len-1-BACK_SUM_NUM);i>=0;i-=(BACK_SUM_NUM/2))
   {
   	curr=cal_int_sum(&buf[i],BACK_SUM_NUM);   
   	if(curr<=(top_end_val+2))
	  {
  	    top_end_val=curr;
		top_end_pos=i+(BACK_SUM_NUM/2);	
  	  }
	else
	  {
	  	//printf("i=%d top_end_pos=%d\n",i,top_end_pos);
  	    break;	
  	  } 
   }
 max_pos=find_max_val(buf,top_end_pos,NULL);
 //printf("max_pos=%d\n",max_pos);
 return max_pos;	
}*/


//���������ۼӺ�,����λ��,sum_numΪ�ۼӵĵ���,���������������� 
int find_max_sum(int *buf,int len,int sum_num,int delt)
{
 int i,result;
 int curr_sum,max_sum;
  
 max_sum=cal_int_sum(buf,sum_num);
 result=0;
 for(i=sum_num;i<len;i+=sum_num)
  {
  	curr_sum=cal_int_sum(&buf[i],sum_num);
   if(curr_sum>max_sum)
     {
       max_sum=curr_sum;
	   result=i; 	
     }  	
  }
 result+=find_max_val(&buf[result],sum_num,NULL);
 return result;
}


/* 
//������������С��� 
int find_min_sum(int *buf,int len,int sum_num,int delt)
{
 int i,result;
 int curr_sum,min_sum;
  
 min_sum=cal_int_sum(&buf[len-1],sum_num);
 result=len-1;
 for(i=len-sum_num-1;i>0;i-=sum_num)
  {
  	curr_sum=cal_int_sum(&buf[i-sum_num],sum_num);
   if(curr_sum<min_sum)
     {
       min_sum=curr_sum;
	   result=i; 	
     }  	
  }
 result+=find_max_val(&buf[result],sum_num,NULL);
 return result;
}
*/

int find_left_pos(int *buf,int len,int sum_num,int delt,int *ret)
{
 int i,result;
 int pre_sum,curr_sum;
 int pos2=0,pos3=0;
  
 result=0;
 pre_sum=cal_int_sum(buf,sum_num);
 for(i=0;i<len;i+=sum_num)
  {
   curr_sum=cal_int_sum(&buf[i],sum_num); //���� 
   if(curr_sum>(pre_sum+delt))
     {
  	   //printf("arrived 1\n");
       if((cal_int_sum(&buf[i+sum_num],sum_num)+delt)<cal_int_sum(&buf[i+2*sum_num],sum_num))
	    {
    	 // printf("arrived 2 %d %d\n",cal_int_sum(&buf[i+sum_num],sum_num),cal_int_sum(&buf[i+2*sum_num],sum_num));
    	  pos2=i;
		  if((cal_int_sum(&buf[i+2*sum_num],sum_num)+delt)<cal_int_sum(&buf[i+3*sum_num],sum_num))
		   {
		   	 pos3=i;
		   	 //printf("arrived 3 %d %d\n",cal_int_sum(&buf[i+sum_num],sum_num),cal_int_sum(&buf[i+2*sum_num],sum_num));
   			 if((cal_int_sum(&buf[i+3*sum_num],sum_num)+delt)<cal_int_sum(&buf[i+4*sum_num],sum_num))
   			   {
   			   	 //printf("arrived 4 %d %d\n",cal_int_sum(&buf[i+3*sum_num],sum_num),cal_int_sum(&buf[i+4*sum_num],sum_num));
   	             if(ret!=NULL)
			       *ret=i;
			     return 0;
   			   }
   		   }	
    	} 	
     }
   pre_sum=curr_sum;  	
  }
 if(ret!=NULL)
  {   
	if(pos3!=0)
	 {
       *ret=pos3;
	   return 0;	
 	 }
   *ret=0;		
  }
 return -1;
}

//���������,��i��͵�i+forward_cnt���,�����Ƚ�contine_cnt��,��Сб��delt 
int FindLeftPos(int *buf,int len,int contine_cnt,int forward_cnt,int delt,int *ret)
{//contine_cnt=5,forward_cnt=8
 int i,result;
 int n=0;

 if(len<(forward_cnt+contine_cnt))
   return -1;
 for(i=0;i<(len-forward_cnt-contine_cnt);i++)
  {
    result=0;
  	for(n=0;n<contine_cnt;n++)
  	  {
  	    if((buf[i+n]+delt)<buf[i+n+forward_cnt])
		 {
 		    result++;	
 		 }	
  	  }
  	if(result>=contine_cnt)  
      {
        *ret=(i+(forward_cnt/2));
		return 0; 	
      }
  }
 return -2;  
}

//���������,��(i�㵽��i+per_width��ƽ��ֵ)��
//��(i+tot_width����i+tot_width+per_width��ƽ��ֵ)
//�Ƚ�,�����Ƚ�3��,ÿ�Ƚ�һ������ƶ�mov_width�� 
int FindLeftPosEx(int *buf,int len,int tot_width,int per_width,int mov_width,int min_slope)
{
 int i,n,result;
 int avr_val1[3],avr_val2[3];
 result=-1;
 if(len<=(tot_width+4*mov_width+per_width))
  return -1;
 for(n=0;n<(len-tot_width-4*mov_width-per_width);n++)
   {
     for(i=0;i<(sizeof(avr_val1)/sizeof(int));i++)
      {
        avr_val1[i]=cal_int_avr(&buf[n+i*mov_width],per_width);
        avr_val2[i]=cal_int_avr(&buf[n+i*mov_width+tot_width],per_width);	
      }
     if(avr_val1[2]<avr_val2[0])
      {
       if((avr_val2[0]<avr_val2[1])&&(avr_val2[1]<avr_val2[2]))
        {
	      if((avr_val1[0]+min_slope)<avr_val2[0])
           {
	         if((avr_val1[1]+min_slope)<avr_val2[1])
	          {
       		   if((avr_val1[2]+min_slope)<avr_val2[2])
	            {
       		      result=n+(2*mov_width)+(tot_width/2);
				  return result; 	 
       	        }
       	      }
           }        	
        }	
      }
   }
 return result;	//
} 

int FindMaxPos(int *buf,int len,GRADIENT_TYPE_DEF *para_ptr,int *str,int *peak)
{
 int max_pos;
 int tmp_len;
 int i,n=0;
 int max_val;
 
 max_pos=find_max_val(buf,len,&max_val);
 
 if(max_pos<len)
  { 
   if((max_pos+16)<len)
      tmp_len=16;
   else
      tmp_len=len-max_pos;
   
   n=0;
   for(i=max_pos+1;i<tmp_len;i++)
     {
       if(buf[i]!=max_val)
         {
      	   break;
         }
       n++;
     }
  }
 max_pos+=(n/2);
 if(peak!=NULL)
   *peak=max_pos;
 return 0;	
}


//以下为新添加函数
//从左往右找最大值
int get_lft_max_val_and_pos(int *buf,unsigned int buf_len,int *pos,int *val)
{
 unsigned int i;
 int max_val;//最大值
 unsigned int max_pos;  //最大值位置
 max_val=buf[0];
 max_pos=0; 
 for(i=0;i<buf_len;i++)
 {
  if(buf[i]>max_val)
  { //上升
    max_val=buf[i];
    max_pos=i;	
  }
 }
 if(pos!=NULL)
  *pos=max_pos;
 if(val!=NULL)
  *val=max_val;	
 return 0; 
}

//从右往左找找最大值
int get_rht_max_val_and_pos(int *buf,unsigned int buf_len,int *pos,int *val)
{//注意直线的影响
 unsigned int i;
 int max_val;//最大值
 unsigned int max_pos;  //最大值位置
 max_val=buf[buf_len-1];
 max_pos=buf_len-1; 
 for(i=buf_len;i>0;i--)
 {
  if(buf[i-1]>max_val)
  { //上升
    max_val=buf[i-1];
    max_pos=i-1;	
  }
 }
 if(pos!=NULL)
  *pos=max_pos;
 if(val!=NULL)
  *val=max_val;	
 return 0; 
}

//区间查找顶点
int get_top_val_pos(int *buf,unsigned int buf_len,int *pos,int *val)
{
 unsigned int i;
 int lft_val,rht_val;//
 unsigned int lft_pos,rht_pos;  //
 int max_val;//最大值
 unsigned int max_pos;  //最大值位置

 get_lft_max_val_and_pos(buf,buf_len,&lft_pos,&lft_val);//查找最大值
 //get_rht_max_val_and_pos(buf,buf_len,&rht_pos,&rht_val);//查找最大值
 //max_pos=(lft_pos+rht_pos+1)/2;
 if((lft_pos+(buf_len/10))>buf_len)  //顶点不能超过整个缓冲区宽度的1/10
  {
	printf("find top pos failed,lft_pos=%d,buf_len=%d\n",lft_pos,buf_len);
	LOG_DEBUG(TRACE_DEBUG,"find top pos failed,lft_pos=%d,buf_len=%d\n",lft_pos,buf_len);
    return -1;
  }
 get_rht_max_val_and_pos(&buf[lft_pos],buf_len-lft_pos,&rht_pos,&rht_val);//查找最大值
 max_pos=lft_pos+rht_pos/2;
 max_val=buf[max_pos];
 if(pos!=NULL)
  *pos=max_pos;
 if(val!=NULL)
  *val=max_val;	
 return 0; 		
}

//查找起点,delt为参数最小左梯度，严格点要判断4点
int get_str_val_pos(int *buf,unsigned int len,int avr_num,int delt,int *pos,int *val)
{//起点条件为(D0+delt)<D1 (D1+delt)<D2  D2-D1>D1-D0
 int i,result;
 int lft_avr,curr_avr,rht_avr;
 //int last_avr;
 //从左往右边找
 lft_avr=cal_int_avr(&buf[0],avr_num);//计算平均值
 result=1;
 for(i=0;i<(len-avr_num);i+=avr_num)
 {
	curr_avr=cal_int_avr(&buf[i],avr_num);
	if(curr_avr>=(lft_avr+delt))//后面一点比前面一点大delt
	{
      rht_avr=cal_int_avr(&buf[i+avr_num],avr_num);//再往后取一点
	  if(rht_avr>(curr_avr+delt))
	  {
		if((rht_avr-curr_avr)>(curr_avr-lft_avr))
		{
            //last_avr=cal_int_avr(&buf[i+2*avr_num],avr_num);
			//if((last_avr-rht_avr)>(rht_avr-curr_avr))
			//{
			result=0;//成功找到起点标志
			if(pos!=NULL)
			  *pos=i+(avr_num/2);
			if(val!=NULL)
			  *val=buf[i+(avr_num/2)];
			break;
			//}
		}
	  }
	}
	lft_avr=curr_avr;
 }
 return result;
}

//查找顶点的方法，去连续的8点累加和下一个8点累加和比较，累加值应增加
//增加到减少后未转折点，从最近的24点里找最大值
//先找起点再找顶点
int find_key_pos1(int *buf,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data)
{
 int i,n,*data_stream;
 int start_pos,end_pos,cen_pos;
 int left_pos,top_pos,right_pos;
 int ret=0;
 int top_val,left_val;
 int top_flg=0,left_flg=0;
 int str_pos,str_val,peak_pos,peak_val;
 int min_slope;
 int mov_tick;
 int lpos,rpos,cpos;
 int tmp_start_pos;
 int find_ok_flg=0;

 for(i=INDEX_H2;i<=INDEX_C2H2;i++)
  {  	
	//从参数结构获取区间参数
	start_pos=para_ptr->gas_cal_fac[i].position.start;//起点位置
	cen_pos=para_ptr->gas_cal_fac[i].position.peak;//波峰位置
	end_pos=para_ptr->gas_cal_fac[i].position.end;//结束位置
    find_ok_flg=0;
    //找起点
	if(get_str_val_pos(&buf[start_pos],cen_pos-start_pos,JUDGE_NUM,(int)para_ptr->gas_cal_fac[i].gradient.lYmin,&str_pos,&str_val)==0)//JUDGE_NUM点平均值
    {
	  //找到了起点
      str_pos+=start_pos;
	  printf("find str_pos[%d]=%d,str_val=%d ok\n",i,str_pos,str_val);
	  LOG_DEBUG(TRACE_DEBUG,"find str_pos[%d]=%d,str_val=%d ok\n",i,str_pos,str_val);
	}
	else
	{
	   //未找到起点,使用默认起点
	    printf("can not find start_pos[%d],now try again\n",i);
		LOG_DEBUG(TRACE_DEBUG,"can not find start_pos[%d],now try again\n",i);
		//改变阈值再找一遍
		if(get_str_val_pos(&buf[start_pos],cen_pos-start_pos,(JUDGE_NUM*3)/2,(int)para_ptr->gas_cal_fac[i].gradient.lYmin,&str_pos,&str_val)==0)//JUDGE_NUM点平均值
	  	{
			str_pos+=start_pos;
	  		printf("find str_pos[%d]=%d,str_val=%d ok\n",i,str_pos,str_val);
	  		LOG_DEBUG(TRACE_DEBUG,"find str_pos[%d]=%d,str_val=%d ok\n",i,str_pos,str_val);			
	  	}
	    else
		{   //未找到起点
	  		str_pos=start_pos;
	  		str_val=buf[str_pos];
	  		printf("canot find str_pos:use default str_pos[%d]=%d,str_val=%d ok\n",i,str_pos,str_val);
	  		LOG_DEBUG(TRACE_DEBUG,"canot find str_pos:use default str_pos[%d]=%d,str_val=%d ok\n",i,str_pos,str_val);
			find_ok_flg|=1;
		}
	}
	
	//找顶点
	tmp_start_pos=str_pos+16;
	if(get_top_val_pos(&buf[tmp_start_pos],end_pos-tmp_start_pos,&peak_pos,&peak_val)==0)
	{ //找到顶点
      peak_pos+=tmp_start_pos;
	  printf("find peak_pos[%d]=%d,peak_val=%d\n",i,peak_pos,peak_val);
	  LOG_DEBUG(TRACE_DEBUG,"find peak_pos[%d]=%d,peak_val=%d\n",i,peak_pos,peak_val);
	}
    else
	{
	  /* 未找到顶点 */
	  peak_pos=cen_pos;
	  peak_val=buf[peak_pos];
	  printf("canot find peak_pos:use default peak_pos[%d]=%d,peak_val=%d\n",i,peak_pos,peak_val);
	  LOG_DEBUG(TRACE_DEBUG,"canot find peak_pos:use default peak_pos[%d]=%d,peak_val=%d\n",i,peak_pos,peak_val);
	  find_ok_flg|=2;
	}
	
   if(pos_data!=NULL)
    {
       	pos_data->position[i].start=str_pos;
	   	pos_data->position[i].peak=peak_pos;
		pos_data->position[i].end=2*peak_pos-str_pos;
    }

    if(find_ok_flg==0)
	{
    	if((peak_val>(str_val+MIN_AMP))&&(peak_pos>(str_pos+MIN_LEN)))
		{	
	   		ret|=(1<<i);
		}
		else
		{  
	  	 	//未找到有效的波峰
	  		printf("find invalid peak:str_pos=%d:str_val=%d  peak_pos=%d:peak_val=%d\n",str_pos,str_val,peak_pos,peak_val);
	  		LOG_DEBUG(TRACE_DEBUG,"find invalid peak:str_pos=%d:str_val=%d  peak_pos=%d:peak_val=%d\n",str_pos,str_val,peak_pos,peak_val);
		}
	}
	else
	{
	  /* code */
	  ret&=(~(1<<i));
	}	
   }	
  return ret;
}

//判断有效峰的方法:获取区间最小值，最大值，取最大值-(最大值-最小值)/3为基准，从左到有，判断小于它的点数，再判断大于它的点数，再判断小于它的点数超过4点就算有效峰
//先找顶点再找起点，
int bkfind_key_pos2(int *buf,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data)
{
 int i,n,*data_stream;
 int start_pos,end_pos;
 int left_pos,top_pos,right_pos;
 int ret=0;
 int top_val,left_val;
 int top_flg=0,left_flg=0;
 int str_pos,str_val,peak_pos,peak_val;
 int min_slope;
 int mov_tick;
 int lpos,rpos,cpos;

 for(i=INDEX_H2;i<=INDEX_C2H2;i++)
  {  	
	start_pos=para_ptr->gas_cal_fac[i].position.start;
	end_pos=para_ptr->gas_cal_fac[i].position.end;	
    if(i==INDEX_CO)
	{
	  //查找起点,防止波形粘联
	}
	else
	{
	  lpos=start_pos;
	  rpos=end_pos;
	}
			
	//找顶点
	if(get_top_val_pos(&buf[lpos],rpos-lpos,&peak_pos,&peak_val)==0)
	{
      peak_pos+=lpos;
	  printf("find peak_pos[%d]=%d,peak_val=%d\n",i,peak_pos,peak_val);
	  LOG_DEBUG(TRACE_DEBUG,"find peak_pos[%d]=%d,peak_val=%d\n",i,peak_pos,peak_val);
	  //找左起点,从start_pos-peak_pos之间查找
	  if(get_str_val_pos(&buf[lpos],peak_pos-start_pos,JUDGE_NUM,(int)para_ptr->gas_cal_fac[i].gradient.lYmin,&str_pos,&str_val)==0)//JUDGE_NUM点平均值
	  {
		str_pos+=lpos;
		printf("find str_pos[%d]=%d,str_val=%d\n",i,str_pos,str_val);
		LOG_DEBUG(TRACE_DEBUG,"find str_pos[%d]=%d,str_val=%d\n",i,str_pos,str_val);
		if((peak_val>(str_val+MIN_AMP))&&(peak_pos>(str_pos+MIN_LEN)))
		{
			if(pos_data!=NULL)
     		{
       	    	pos_data->position[i].start=str_pos;
	   			pos_data->position[i].peak=peak_pos;
				pos_data->position[i].end=2*peak_pos-str_pos;
     		} 
			ret|=(1<<i);
		}
		else
		{   //未找到有效的波峰
			printf("find invid peak str_pos=%d:str_val=%d  peak_pos=%d:peak_val=%d\n",str_pos,str_val,peak_pos,peak_val);
			LOG_DEBUG(TRACE_DEBUG,"find invid peak str_pos=%d:str_val=%d  peak_pos=%d:peak_val=%d\n",str_pos,str_val,peak_pos,peak_val);
		}		
	  }
	  else
	  {
		/* code */
		printf("can not find start_pos[%d],now try again\n",i);
		LOG_DEBUG(TRACE_DEBUG,"can not find start_pos[%d],now try again\n",i);
		//改变阈值再找一遍
		if(get_str_val_pos(&buf[start_pos],peak_pos-start_pos,(JUDGE_NUM*3)/2,(int)para_ptr->gas_cal_fac[i].gradient.lYmin,&str_pos,&str_val)==0)//JUDGE_NUM点平均值
	  	{
			str_pos+=start_pos;
			printf("find str_pos[%d]=%d,str_val=%d\n",i,str_pos,str_val);
			LOG_DEBUG(TRACE_DEBUG,"find str_pos[%d]=%d,str_val=%d\n",i,str_pos,str_val);
			if((peak_val>(str_val+MIN_AMP))&&(peak_pos>(str_pos+MIN_LEN)))
			{
				if(pos_data!=NULL)
     			{
       	    		pos_data->position[i].start=str_pos;
	   				pos_data->position[i].peak=peak_pos;
					pos_data->position[i].end=2*peak_pos-str_pos;
     			} 
				ret|=(1<<i);
		    }
			else
			{  //未找到有效的波峰
			   printf("can not find invid peak str_pos=%d:str_val=%d  peak_pos=%d:peak_val=%d\n",str_pos,str_val,peak_pos,peak_val);
			   LOG_DEBUG(TRACE_DEBUG,"find invid peak str_pos=%d:str_val=%d  peak_pos=%d:peak_val=%d\n",str_pos,str_val,peak_pos,peak_val);
			}			
	  	}
	  	else
	  	{
			//找不到起点就以参数设置的点为起点
			printf("can not find start_pos[%d],use default start pos %d\n",i,start_pos);
			LOG_DEBUG(TRACE_DEBUG,"can not find start_pos[%d],use default start pos %d\n",i,start_pos);
        	str_pos=start_pos;
			str_val=buf[str_pos];

			if((peak_val>(str_val+MIN_AMP))&&(peak_pos>(str_pos+MIN_LEN)))
			{
				if(pos_data!=NULL)
     			{
       	    		pos_data->position[i].start=str_pos;
	   				pos_data->position[i].peak=peak_pos;
					pos_data->position[i].end=para_ptr->gas_cal_fac[i].position.end;
     			} 
				ret|=(1<<i);
		    }
			else
			{  //未找到有效的波峰
			   printf("can not find invid peak str_pos=%d:str_val=%d  peak_pos=%d:peak_val=%d\n",str_pos,str_val,peak_pos,peak_val);
			   LOG_DEBUG(TRACE_DEBUG,"find invid peak str_pos=%d:str_val=%d  peak_pos=%d:peak_val=%d\n",str_pos,str_val,peak_pos,peak_val);
			}
	  	}
	  }	  
	}
	else
	{
	  /* code */
	  printf("can not find peak_pos[%d]\n",i);
	  LOG_DEBUG(TRACE_DEBUG,"can not find peak_pos[%d]\n",i);
	}	
  }
  return ret;
}

int bkfind_key_pos1(int *buf,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data)
{
 int i,n,*data_stream;
 int start_pos,end_pos;
 int left_pos,top_pos,right_pos;
 int ret=0;
 int top_val,left_val;
 int top_flg=0,left_flg=0;
 int str_pos,peak_pos;
 int min_slope;//�����С�ݶ� 
 int mov_tick;
 for(i=INDEX_H2;i<=INDEX_C2H2;i++)
  {  	
  	//1.���Ҷ��� 
	//���㶥����ʼλ�� 	 	
    start_pos=para_ptr->gas_cal_fac[i].position.start;
  	//���㶥�����λ�� 
    //end_pos=para_ptr->gas_cal_fac[i].position.peak+para_ptr->gas_cal_fac[i].position.width; 
	end_pos=para_ptr->gas_cal_fac[i].position.end;
	
	//printf("start_pos=%d\n",start_pos); 
	
	while(start_pos<end_pos)
	  {
  	    if(cal_int_sum(&buf[start_pos],SUM_NUM)>cal_int_sum(&buf[start_pos+SUM_NUM],SUM_NUM))
		  {
  		    start_pos+=2;	
  		  }
		else
		  {
  		    break;	
  		  } 	
  	  }	 
	
	
	if((start_pos+5+8)<end_pos)
	 {	 
  	   data_stream=buf+start_pos;// 
 	   min_slope=(int)para_ptr->gas_cal_fac[i].gradient.lYmin;
	   //�������,������5��,��1��͵�8���  
	   if(FindLeftPos(data_stream,end_pos-start_pos,5,8,min_slope,&str_pos)==0) 
	    {
 	     FindMaxPos(data_stream+str_pos,end_pos-start_pos-str_pos,NULL,NULL,&peak_pos);
         left_pos=start_pos+str_pos;
 	     top_pos=left_pos+peak_pos;
         //if(top_pos>(left_pos+MIN_LEN))
	      //{
    	    left_val=*(buf+left_pos);
    	    top_val=*(buf+top_pos);
    	   // if((left_val+MIN_AMP)<top_val)
		    // {
    		   ret|=(1<<i);
    		// }  	
    	 // } 
		  LOG_DEBUG(TRACE_DEBUG,"find pos%d in 1st\n",i); 	
 	    }
	   else
	    { //���δ�ҵ�,���������� 
    	  FindMaxPos(data_stream,end_pos-start_pos,NULL,NULL,&peak_pos);
    	  left_pos=start_pos;//���趨�����Ϊ�ҵ������ 
    	  top_pos=start_pos+peak_pos;//���ҵ������ֵΪ���� 
    	  //if(i==INDEX_CO||i==INDEX_CH4)
    	  if(i==INDEX_CO)
    	    {
		      LOG_DEBUG(TRACE_DEBUG,"find pos%d in 2st\n",i);	          		      
		      ret|=(1<<i); 	
    	    }
  	      else
  	        { //�ж��������Ĳ�ֵ?
        	  mov_tick=0;
			  end_pos=start_pos+peak_pos;
        	  while(end_pos>(start_pos+MIN_LEN))
	           {
  	            if(cal_int_sum(&buf[end_pos-(SUM_NUM/2)],SUM_NUM)>cal_int_sum(&buf[end_pos-SUM_NUM],SUM_NUM))
		          {
  		           end_pos-=2;
				   mov_tick++;	
  		          }
		        else
		          {
          	        LOG_DEBUG(TRACE_DEBUG,"find pos%d in 2st\n",i);
          	        if(mov_tick>10)
          	         {
  	                    left_pos=end_pos; 	 
		          	    ret|=(1<<i);	
      	             }
                    else
                     {
                        //left_pos=top_pos;
						top_pos=left_pos; 	 
		          	    ret&=(~(1<<i));	
                     }
  		            break;	
  		          } 	
  	           }
			  if((ret&(1<<i))==0)
			   {
   				 LOG_DEBUG(TRACE_DEBUG,"find pos%d in 2st failed\n",i);
   			   }	      	  	
      	    }
        }
	  }
    else
      { //�����յ����̫խ,����CO��ֱ�Ӹ�ֵ���� 
      	LOG_DEBUG(TRACE_DEBUG,"find pos%d failed for data error\n",i);
  	    if(i==INDEX_CO)
  	      {
      	    left_pos=para_ptr->gas_cal_fac[i].position.start;
	        top_pos=para_ptr->gas_cal_fac[i].position.peak; 	
      	  }
   	    else
   	      {
            left_pos=start_pos;
	        top_pos=left_pos;      	   	
   	      }	
      }
   if(pos_data!=NULL)
     {
       pos_data->position[i].start=left_pos;
	   pos_data->position[i].peak=top_pos;
     } 
  }
 return ret;
}

int find_key_pos2(int *buf,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data)
{
 int ret=0;
 int i;
 int *curr_ptr;
 int min_slope;//�����С�ݶ� 
 int start_pos,end_pos;//�趨����ʼλ�úͽ���λ�� 
 int pos_start,pos_peak;//�ҵ������Ͷ���λ�� 
 int start_val,peak_val;//�ҵ������ֵ�Ͷ���ֵ 
 for(i=INDEX_H2;i<=INDEX_C2H2;i++)
  {
  	start_pos=para_ptr->gas_cal_fac[i].position.start;
	end_pos=para_ptr->gas_cal_fac[i].position.end;
	min_slope=(int)para_ptr->gas_cal_fac[i].gradient.lYmin;
	while(start_pos<end_pos)
	  {
  	    if(cal_int_sum(&buf[start_pos],SUM_NUM)>cal_int_sum(&buf[start_pos+(SUM_NUM/2)],SUM_NUM))
		  {
  		    start_pos+=2;	
  		  }
		else
		  {
  		    break;	
  		  } 	
  	  }	
	if(start_pos<end_pos)
     {
	  curr_ptr=buf+start_pos;	
      if((pos_start=FindLeftPosEx(curr_ptr,end_pos-start_pos,16,SUM_NUM,MOVE_NUM,min_slope))>0)
       {
  	     //�ҵ������ 
         //������Ҷ���
	     FindMaxPos(curr_ptr+pos_start,end_pos-start_pos-pos_start,&para_ptr->gas_cal_fac[i].gradient,NULL,&pos_peak);  	
         pos_start+=start_pos;
         pos_peak+=pos_start;
         if(pos_peak>(pos_start+MIN_LEN))//�ж����Ͷ���Ŀ��� 
	      {
    	    start_val=*(buf+pos_start);
    	    peak_val=*(buf+pos_peak);
    	    if((start_val+MIN_AMP)<peak_val)//�ж����Ͷ���ĸ߶Ȳ� 
		      {
				ret|=(1<<i);//�ҵ��˺ϸ�����Ͷ���			 	
    		  }  	
    	  }	        
	   }
	  else
	   {
 	     //δ�ҵ���� 
         //��(����/���ֵ)��
	     //��(����/���ֵ)��������� 	
 	   }
     }
    else
     { //���� 
       pos_start=start_pos;
	   pos_peak=pos_start;	
     }
    if(pos_data!=NULL)
     {
       pos_data->position[i].start=pos_start;
	   pos_data->position[i].peak=pos_peak;	    	
     }	
   }

 return ret;	
}

 
//���������� 
int find_left_pos_ex(int *buf,int len,int sum_num,int delt)
{
 int i,result;
 int start_sum,curr_sum;
  
 start_sum=cal_int_sum(&buf[len-sum_num-1],sum_num);//���ұߵĵ� 
 
 result=len-sum_num-1;

 for(i=len-sum_num-1;i>0;i-=sum_num)
  {
  	curr_sum=cal_int_sum(&buf[i-sum_num],sum_num); //���� 
    if((curr_sum+delt)>start_sum)
     {
       if((cal_int_sum(&buf[i-2*sum_num],sum_num)+delt)>=cal_int_sum(&buf[i-sum_num],sum_num))
	     {
     	   if((cal_int_sum(&buf[i-3*sum_num],sum_num)+delt)>=cal_int_sum(&buf[i-2*sum_num],sum_num))
		    {
 			  if((cal_int_sum(&buf[i-4*sum_num],sum_num)+delt)>=cal_int_sum(&buf[i-3*sum_num],sum_num))
		       { 
		         //if((cal_int_sum(&buf[i-5*sum_num],sum_num)+delt)>cal_int_sum(&buf[i-4*sum_num],sum_num))
 				  // {
		 			 result=len-i;
 				     break;
   				  // }			
 			   }	
 			}	
     	 }	
     }
   start_sum=curr_sum;   	
  }
 return result;
}



int find_key_pos(int *buf,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data)
{
 int i,n,*data_stream;
 int start_pos,end_pos;
 int left_pos,top_pos,right_pos;
 int ret=0;
 int top_val,left_val;
 int top_flg=0,left_flg=0;
 
// #ifdef DEBUG_ANALYSIS
 int str_pos,peak_pos;
 //#endif
 for(i=INDEX_H2;i<=INDEX_C2H2;i++)
  {  	
  	//1.���Ҷ��� 
	//���㶥����ʼλ�� 	 	
    start_pos=para_ptr->gas_cal_fac[i].position.start;
  	//���㶥�����λ�� 
    //end_pos=para_ptr->gas_cal_fac[i].position.peak+para_ptr->gas_cal_fac[i].position.width; 
	end_pos=para_ptr->gas_cal_fac[i].position.end;
	
	//printf("start_pos=%d\n",start_pos); 
	
	while(start_pos<end_pos)
	  {
  	    if(cal_int_sum(&buf[start_pos],SUM_NUM)>cal_int_sum(&buf[start_pos+SUM_NUM],SUM_NUM))
		  {
  		    start_pos+=2;	
  		  }
		else
		  {
  		    break;	
  		  } 	
  	  }	 
		 
  	data_stream=buf+start_pos;//   
    //��ȡ���������λ�� 
    //if(i==INDEX_C2H4)
	if(find_top_pos(data_stream,end_pos-start_pos,&(para_ptr->gas_cal_fac[i].gradient),&str_pos,&peak_pos)>0)
      {
        //top_val=data_stream[peak_pos];
  	    top_pos=peak_pos+start_pos;// 
  	    
		top_val=top_pos-para_ptr->gas_cal_fac[i].position.width;
		
		data_stream=buf+top_val; 
		
		top_pos=top_val+find_max_val(data_stream,para_ptr->gas_cal_fac[i].position.width+8,NULL);
	    top_val=buf[top_pos];
		top_flg|=(1<<i); 
			   
		//CO��CH4ֻ��Ҫ�ҵ�����Ϳ����� 
		if(i==INDEX_CO||i==INDEX_CH4)
		 {
		   ret|=(1<<i);  			
 		 }	
      }
    else
      {	
       start_pos=para_ptr->gas_cal_fac[i].position.peak-(para_ptr->gas_cal_fac[i].position.width/2);
	   end_pos=start_pos+para_ptr->gas_cal_fac[i].position.width;
	   
	   data_stream=buf+start_pos;//  		
  	   top_pos=find_max_val(data_stream,end_pos-start_pos,NULL);//���Ҷ��� 
  	   top_val=data_stream[top_pos];
       if(top_pos!=0)
  	    { 
  	      if((top_val-data_stream[0])>MIN_AMP)//�˴���Ҫ������ 
  	        {
        	   //�ҵ������ֵ 
        	  top_pos+=start_pos; 
	  	      top_flg|=(1<<i);
	  	      if(i==INDEX_CO||i==INDEX_CH4)
		       {
		         ret|=(1<<i);  			
 		       }
				//printf("top=%d sta=%d\n",top_val,data_stream[0]); 	
      	    }
		  else
		    {
    		  //δ�ҵ����ֵ
			  top_pos=para_ptr->gas_cal_fac[i].position.start;
			  //printf("top=%d sta=%d 2\n",top_val,data_stream[0]);	
    		}  	       	
  	    }
  	   else
	    {
  	      //δȷ���Ƿ��ҵ������ֵ,���������,��Ҫ�����Ҳ��Ƿ����½����� 
  	      if(cal_int_avr(data_stream,4)>cal_int_avr(&data_stream[4],4))
  	       {
  	       	 if(cal_int_avr(&data_stream[4],4)>cal_int_avr(&data_stream[8],4))
  	       	  {  	       	  	 	       	 
  	       	    if(cal_int_avr(&data_stream[8],4)>cal_int_avr(&data_stream[12],4))
  	       	      {
  	       	      	//�ҵ��˶��� 
  	       	        top_pos+=start_pos;	
       	            top_flg|=(1<<i);
					if(i==INDEX_CO||i==INDEX_CH4)
		             {
		              ret|=(1<<i);  			
 		             } 	
      	       	  }
  	       	    else
  	       	      {  //δ�ҵ����� 
      	       	     top_pos=para_ptr->gas_cal_fac[i].position.start;	
      	       	  }
  	          }
			 else
			  {
			  	 //δ�ҵ����� 
  			     top_pos=para_ptr->gas_cal_fac[i].position.start;	
  			  } 
       	   }
  	      else
		   {  //δ�ҵ����� 
   			  top_pos=para_ptr->gas_cal_fac[i].position.start;
   		   } 
  	    } 		      	
      }
      
	 if(i==INDEX_CO||i==INDEX_CH4)
	  {
	  	if((top_flg&(1<<i))==0)
	  	  {
	  	  	ret|=(1<<i);
  	  	    top_pos=para_ptr->gas_cal_fac[i].position.peak;
			LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"warning:can not find top pos,use default peak_pos=%d index=%d\n",top_pos,i);		
  	  	  }         			
	  }
	  	 
  	//2.���������
	 if((top_flg&(1<<i))!=0)
	  { 
  	    start_pos=para_ptr->gas_cal_fac[i].position.start;//��ȡ������ʼ�±� 
  	    data_stream=buf+start_pos;//��������ƫ�Ƶ�ַ 
  	    end_pos=top_pos;//����λ��Ϊ����  
        if(find_left_pos(data_stream,end_pos-start_pos,SUM_NUM,(int)para_ptr->gas_cal_fac[i].gradient.lYmin,&left_pos)==0)
         {
       	   //�ҵ������ 
	       left_val=data_stream[left_pos];
	       left_pos+=start_pos; 
	       left_flg|=(1<<i); 	    	
         }
        else
         {//δ�ҵ���� 
           left_pos=top_pos;
	       left_val=top_val;	
         }
  	  }
	 else
      {
        left_pos=top_pos;
	    left_val=top_val;	
   	  } 
    
   	if(i!=INDEX_CO&&i!=INDEX_CH4)
   	 {
      if((top_val<=(left_val+MIN_AMP))||((left_pos+MIN_LEN)>=top_pos))
        {
         LOG_DEBUG(ANALYSIS_EEROR_DEBUG,"error:left_val=%d top_val=%d index=%d\n",left_val,top_val,i);	
         ret&=(~(1<<i));
	    }
      else
        {
         ret|=(1<<i);	
        } 	   	
     }
    pos_data->position[i].start=left_pos;
    pos_data->position[i].peak=top_pos;  
  }
 return ret;
}



int find_top_pos(int *buf,int len,GRADIENT_TYPE_DEF *para_ptr,int *str,int *peak)
{
  int i,n;
  int area[JUDGE_NUM];
  int k[JUDGE_NUM];
  int avr[JUDGE_NUM];
  int find_pos[JUDGE_NUM];
  //int find_val[JUDGE_NUM];
  int str_pos=0;
  int peak_pos=0;
  int left_flg,right_flg;
  int tmp;
  int find_num=0;
  int pre_k=0,curr_k=0;
  
  //�����ж�JUDGE_NUM����,ÿ����Ϊ���SUM_NUM�����ƽ�� 
  for(n=0;n<JUDGE_NUM;n++)
   {
     area[n]=cal_int_sum(&buf[n*MOVE_NUM],SUM_NUM);
     avr[n]=area[n]/SUM_NUM;
   }
     
  tmp=avr[0];
  for(n=0;n<JUDGE_NUM;n++)
   {
    k[n]=avr[n]-tmp;
    tmp=avr[n];
   }
   
   //����JUDGE_NUM*MOVE_NUM��ʼ�� 
  for(i=(JUDGE_NUM*MOVE_NUM);i<len;i+=MOVE_NUM)
  {   
    
    if((k[JUDGE_NUM/2]<=0)&&(k[JUDGE_NUM/2+1]<=0))
     { //�Ұ���ݶ�С�ڵ�����   
       right_flg=2;//�Ұ��2�����ݶ�С���� 
 	   for(n=((JUDGE_NUM/2)+1);n<JUDGE_NUM;n++)
        {      	  
          if(k[n]<=0)//�ϸ���˵Ҫk[n]<0 
		    right_flg++; //�����Ұ���ݶ�С����ĵ���	
        } 
       
	   if(right_flg>=(JUDGE_NUM/2))
	    { //�Ұ���ݶ�ȫ��С���������� 
		
		
		  //���������ݶ�С����ĵ���  
		  left_flg=0; 	 
    	  for(n=0;n<(JUDGE_NUM/2);n++)
           {      	  
             if(k[n]>0)
		       left_flg++; 	
           }
           
           
		  if(left_flg>=(JUDGE_NUM/2))//�����ݶ�ȫ�������� 
		   {		   	 
   			 //�ҵ�����
   			 find_pos[find_num]=i-((JUDGE_NUM+1)*MOVE_NUM/2);
   			 curr_k=0;
   			 for(tmp=0;tmp<(JUDGE_NUM/2);tmp++)
   			  {
		        curr_k+=k[tmp];//�����ۼ�k 
		        //printf("k%d=%d ",tmp,k[tmp]);
		      } 
		     //printf("\n");  			
			 find_num++;
			 if(curr_k>pre_k)//�ҵ��������͵� 
			   {
	   	        if(peak!=NULL)
   			     {
  			      *peak=i-((JUDGE_NUM+1)*MOVE_NUM/2);	
	             }
			    pre_k=curr_k; 
   			   }   			 
             if(find_num>=JUDGE_NUM)
               break;
   		   } 	
    	}   	
      }    

	//����	
    for(n=0;n<(JUDGE_NUM-1);n++)
     {
   	  area[n]=area[n+1];
   	  k[n]=k[n+1];
   	  avr[n]=avr[n+1];
     }
    area[n]=cal_int_sum(&buf[i],SUM_NUM);//��������ƶ�һ�� 
    avr[n]=area[n]/SUM_NUM;//ƽ��ֵ�����ƶ�һ�� 
    k[n]=avr[n]-avr[n-1];//ƽ��ֵ��б�������ƶ�һ�� 
   }	
 return find_num;
}


int find_top_pos_ex(int *buf,int len,GRADIENT_TYPE_DEF *para_ptr,int *str,int *peak,int tot_width,int per_width,int mov_width)
{
  int i,n;
  int area[MAX_JUDGE_NUM];
  int k[MAX_JUDGE_NUM];
  int avr[MAX_JUDGE_NUM];
  int find_pos[MAX_JUDGE_NUM];
  //int find_val[JUDGE_NUM];
  int str_pos=0;
  int peak_pos=0;
  int left_flg,right_flg;
  int tmp;
  int find_num=0;
  int pre_k=0,curr_k=0;
  
  int tot_judge_num;
  
  tot_judge_num=(tot_width-((per_width+1)/2))/mov_width;
  if(tot_judge_num<MIN_JUDGE_NUM)
    {
   	  //per_width��mov_width�����ټ���tot_judge_num�� 
      tot_judge_num=MIN_JUDGE_NUM;	
    }
  if(tot_judge_num>MAX_JUDGE_NUM)
    {
      tot_judge_num=MAX_JUDGE_NUM;	
    }
  //�����ж�JUDGE_NUM����,ÿ����Ϊ���SUM_NUM�����ƽ�� 
  for(n=0;n<tot_judge_num;n++)
   {
     area[n]=cal_int_sum(&buf[n*mov_width],per_width);
     avr[n]=area[n]/per_width;
   }
     
  tmp=avr[0];
  for(n=0;n<tot_judge_num;n++)
   {
    k[n]=avr[n]-tmp;
    tmp=avr[n];
   }
   
   //����JUDGE_NUM*MOVE_NUM��ʼ�� 
  for(i=(tot_judge_num*mov_width);i<len;i+=mov_width)
  {       
    if((k[tot_judge_num/2]<=0)&&(k[tot_judge_num/2+1]<=0))
     { //�Ұ���ݶ�С�ڵ�����   
       right_flg=2;//�Ұ��2�����ݶ�С���� 
 	   for(n=((tot_judge_num/2)+2);n<tot_judge_num;n++)
        {      	  
          if(k[n]<=0)//�ϸ���˵Ҫk[n]<0 
		    right_flg++; //�����Ұ���ݶ�С����ĵ���	
        } 
       
	   if(right_flg>=(tot_judge_num/2))
	    { //�Ұ���ݶ�ȫ��С���������� 		
		  //���������ݶ�С����ĵ���  
		  left_flg=0; 	 
    	  for(n=0;n<(tot_judge_num/2);n++)
           {      	  
             if(k[n]>0)
		       left_flg++; 	
           }
           
           
		  if(left_flg>=(tot_judge_num/2))//�����ݶ�ȫ�������� 
		   {		   	 
   			 //�ҵ�����
   			 find_pos[find_num]=i-((tot_judge_num+1)*mov_width/2);
   			 curr_k=0;
   			 for(tmp=0;tmp<(tot_judge_num/2);tmp++)
   			  {
		        curr_k+=k[tmp];//�����ۼ�k 
		        //printf("k%d=%d ",tmp,k[tmp]);
		      } 
		     //printf("\n");  			
			 find_num++;
			 if(curr_k>pre_k)//�ҵ��������͵� 
			   {
	   	        if(peak!=NULL)
   			     {
  			      *peak=i-((tot_judge_num+1)*mov_width/2);	
	             }
			    pre_k=curr_k; 
   			   }   			 
             if(find_num>=tot_judge_num)
               break;
   		   } 	
    	}   	
      }    

	//����	
    for(n=0;n<(tot_judge_num-1);n++)
     {
   	  area[n]=area[n+1];
   	  k[n]=k[n+1];
   	  avr[n]=avr[n+1];
     }
    area[n]=cal_int_sum(&buf[i],per_width);//��������ƶ�һ�� 
    avr[n]=area[n]/per_width;//ƽ��ֵ�����ƶ�һ�� 
    k[n]=avr[n]-avr[n-1];//ƽ��ֵ��б�������ƶ�һ�� 
   }	
 return find_num;
}

/*
int find_key_pos_ex(int *buf,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data)
{
 int i,n,*data_stream;
 int start_pos,end_pos;
 int left_pos,top_pos,right_pos;
 int ret=0;
 int top_val,left_val;

 for(i=INDEX_H2;i<=INDEX_C2H2;i++)
  {  	
  	//1.���Ҷ��� 
	//���㶥����ʼλ�� 	  	
    start_pos=para_ptr->gas_cal_fac[i].position.start;
  	//���㶥�����λ�� 
	end_pos=para_ptr->gas_cal_fac[i].position.end; 
	
	while(start_pos<end_pos)
	  {
  	    if(cal_int_sum(&buf[start_pos],SUM_NUM)>cal_int_sum(&buf[start_pos+SUM_NUM],SUM_NUM))
		  {
  		    start_pos+=4;	
  		  }
		else
		  {
  		    break;	
  		  } 	
  	  }	  
	//��ȡ���������λ�� 
	data_stream=buf+start_pos;// 		
  	top_pos=find_max_val(data_stream,end_pos-start_pos,NULL);//���Ҷ��� 
  	top_val=data_stream[top_pos];
    if(top_pos!=0)
  	  { 
		//�ҵ������ֵ 
  	    top_pos+=start_pos; 	
  	  }
  	else
	  {
  	    //δȷ���Ƿ��ҵ������ֵ,���������,��Ҫ�����Ҳ��Ƿ����½����� 
  	    top_pos+=start_pos;
  	  } 		
		 
  	//2.���������  
  	start_pos=para_ptr->gas_cal_fac[i].position.start;//��ȡ������ʼ�±� 
  	data_stream=buf+start_pos;//��������ƫ�Ƶ�ַ 
  	end_pos=top_pos-(para_ptr->gas_cal_fac[i].position.width);//����λ��Ϊ���� 
  
	left_pos=find_left_pos(data_stream,end_pos-start_pos,SUM_NUM,(int)para_ptr->gas_cal_fac[i].gradient.lYmin); 	
    //left_pos=find_left_pos_ex(data_stream,end_pos-start_pos,SUM_NUM,(int)para_ptr->gas_cal_fac[i].gradient.lYmin);
	left_val=data_stream[left_pos];
	left_pos+=start_pos;
    
    if(top_val<=left_val)
      {
        LOG_DEBUG(ANALYSIS_EEROR_DEBUG,"error:left_val=%d top_val=%d index=%d\n",left_val,top_val,i);	
      }
    pos_data->position[i].start=left_pos;
    pos_data->position[i].peak=top_pos;
    ret|=(1<<i);
  }
 return ret;
}
*/

int send_analysis_req(char *file_name,int len)
{
  static mqd_t analysis_req_mq=(mqd_t)-1;
  if(analysis_req_mq==(mqd_t)-1)
   {
	 if((analysis_req_mq= open_mq(ANALYSIS_MQ))==((mqd_t)-1))
	  { 
	    LOG_DEBUG(ANALYSIS_EEROR_DEBUG,"open analysis mq failed\n");
        return -1;
      } 
   }
  if(mq_send(analysis_req_mq,(const char *)file_name,len,ANALYSIS_MQ_PRIO)==-1)
    { 
      LOG_DEBUG(ANALYSIS_EEROR_DEBUG,"send msg to analysis mq failed\n");
      return -2;
    } 
 
  return 0;
}

//����б�� 
void cal_slope(int *raw_data,int *out_data,unsigned int len,int num)
{
 unsigned int i;
 int curr_val,pre_val;
 curr_val=cal_int_avr(raw_data,num);
 pre_val=curr_val;
 for(i=0;i<(len/num);i++)
  {
   //out_data[i]=raw_data[i]-raw_data[i-1];
   out_data[i]=curr_val-pre_val;
   pre_val=curr_val;
   curr_val=cal_int_avr(raw_data+i*num,num);	
  }	
 //out_data[0]=out_data[1];//��һ��б��
}

//ȥ���������,��������Ϊԭʼ���� 
void smooth_data(int *data,unsigned int len,unsigned int smooth_num)
{
 unsigned int i;
 if(smooth_num==1)
 {
  for(i=1;i<len-1;i++)
   {
    if(data[i]<data[i-1]&&data[i]<data[i+1])
     {
  	   data[i]=(data[i-1]+data[i+1])/2;
     }
    else if(data[i]>data[i-1]&&data[i]>data[i+1])
     {
  	   data[i]=(data[i-1]+data[i+1])/2;
     }
   }	 	
 }
}

void avr_filter(int *data,unsigned int len,unsigned int smooth_num,int *out)
{
 unsigned int i,n;
 int num;
 num=smooth_num/2;
 for(i=0;i<(len-smooth_num);i++)
   {
    out[i+num]=cal_int_avr(&data[i],smooth_num);
   }
 for(n=0;n<num;n++)
   {
     out[n]=out[num];
     out[len-num-1+n]=out[len-num-1];
   }
 out[len-1]=out[len-2];
}


FACTOR_TYPE *find_right_fac(float *raw_data,GAS_CAL_PARA *gas_cal_fac,int *index_out)
{
  int i;
  float min,max;
  if(raw_data==NULL||gas_cal_fac==NULL)
    return NULL;
  for(i=0;i<12;i++)	
   {
   	 min=gas_cal_fac->correct_fac.k[i].fac[3];//��С��� 
  	 max=gas_cal_fac->correct_fac.k[i].fac[4];//������ 
    if(((*raw_data)<=max)&&((*raw_data)>min))
	  {
	  	if(index_out!=NULL)
 	     {
  	  	   *index_out=i;	
  	  	 }
  	    return &(gas_cal_fac->correct_fac.k[i]);	
  	  }	
   }
  return NULL;
}


//���
int cal_h(int *raw_data,int str_pos,int peak_pos,float *out_data,int *base_data)
{
 int h,base_val;
 if(raw_data==NULL||out_data==NULL)
   return -1;
 
 if(base_data!=NULL)
   {
   	 base_val=(*base_data);
   }
 else
   {
   	 base_val=raw_data[str_pos-1];
   }
 h=raw_data[peak_pos]-base_val;
 if(h<0)
   h=0;
 //printf("max=%d base=%d h=%d peak_pos=%d\n",raw_data[peak_pos],base_val,h,peak_pos);
 //out=h*tr
 //*out_data=((float)h*(peak_pos-str_pos+1)*(my_para_data.mach_run_para.sample_rate))/1000;
 *out_data=(float)h;//((float)h*(peak_pos)*(my_para_data.mach_run_para.sample_rate))/100000;
 return 0;	
}

int correct_h(float *raw_h,float *out_h,GAS_CAL_PARA *gas_cal_fac)
{
 float h=0;
 int k_index=0;
 FACTOR_TYPE *fac_ptr;
 
 if(gas_cal_fac==NULL||raw_h==NULL||out_h==NULL)
   return -1;
 //����raw_h���Ҵ�����һ��Kֵ,Ȼ��ʹ�ø�Kֵ������� 
 if((fac_ptr=find_right_fac(raw_h,gas_cal_fac,&k_index))!=NULL)
  {
  	//fac[0]=Kx
  	//fac[1]=��Ũ��ֵ
	//fac[3]=��С��� 
    h=(fac_ptr->fac[0])*((*raw_h)-(fac_ptr->fac[3]))+(fac_ptr->fac[1]);
	if(out_h!=NULL)
	 {
 	   *out_h=h;	
	 }
    return k_index;
  }
 return -2;	
}

//������� 
int cal_area(int *raw_data,int str_pos,int peak_pos,float *out_area)
{
 float area=0;
 int   tmp=0;
 int i;
 int base_data;
 if(raw_data==NULL||out_area==NULL)
   return -1; 
 base_data=raw_data[str_pos];//�����ֵ 
 for(i=str_pos;i<peak_pos;i++)
  {
   tmp+=(raw_data[i]-base_data);//�ۼ�	
  }
 area=((float)tmp*((float)(my_para_data.mach_run_para.sample_rate)*0.001));
 *out_area=area*2;
 return 0;	
}


int correct_area(float *raw_area,float *out_area,GAS_CAL_PARA *gas_cal_fac)
{
 float area=0;
 int k_index=0;
 FACTOR_TYPE *fac_ptr;
 
 if(gas_cal_fac==NULL||raw_area==NULL||out_area==NULL)
   return -1;
 //����raw_area���Ҵ�����һ��Kֵ,Ȼ��ʹ�ø�Kֵ������� 
 if((fac_ptr=find_right_fac(raw_area,gas_cal_fac,&k_index))!=NULL)
  {
	//fac[0]=Kx
  	//fac[1]=��Ũ��ֵ
	//fac[3]=��С��� 
    area=(fac_ptr->fac[0])*((*raw_area)-(fac_ptr->fac[3]))+(fac_ptr->fac[1]);
	if(out_area!=NULL)
	 {
 	   *out_area=area;	
	 }
    return k_index;
  }
 return -2;	
}


int save_dumy_file(const char *file,long offs,int *ptr,unsigned int len)
{
	FILE *fp;
	unsigned int i;
	fp=fopen(file,"w");
	if(fp==NULL)
	  {	
        LOG_DEBUG(ERROR_DEBUG,"Creat file %s failed when savefile\r\n",file);
	    return -1;
	  }
    if(offs!=0)
     {
       fseek(fp,offs,SEEK_SET);
     }
    for(i=0;i<len;i++)
      {
      	fprintf(fp,"%d\n",*ptr++);
      }
    fprintf(fp,"\n");
	fclose(fp);
    return 0;	
}

//��������,len�������������������ݵ���, 
int analysis_data(int *raw_data,int len,YSP_PARA *para_ptr,ANALY_RESULT *ana_rlt)
{
  int str_pos[10];  //������� 
  int peak_pos[10]; //���嶥�� 
  int find_mask; 
  int base_val;
  int ret=0;
  int i,n;
  int k_index;
  int segment_len;
  float tmp;
  int ref_val;
  FIND_POS_DATA position_data;
  FIND_POS_DATA *pos_data=&position_data;
  if(len>MAX_DATA_LEN)
    len=MAX_DATA_LEN;
  smooth_data(raw_data,len,1);       //�˲�ȥ�� 
  
  /*
  avr_filter(raw_data,len,SUM_NUM,filter_data);
  
  ref_val=cal_int_avr(&filter_data[para_ptr->gas_cal_fac[INDEX_CH4].position.end],16);
  for(i=para_ptr->gas_cal_fac[INDEX_CH4].position.end;i<para_ptr->gas_cal_fac[INDEX_C2H4].position.start;i++)
   {
   	 filter_data[i]=ref_val;
   }
  for(i=INDEX_C2H4;i<=INDEX_C2H2;i++)
   {
   	printf("ref_val=%d start=%d start1=%d\n",ref_val,filter_data[para_ptr->gas_cal_fac[i].position.start],filter_data[para_ptr->gas_cal_fac[i].position.start-1]);
    process_data(&filter_data[para_ptr->gas_cal_fac[i].position.start],(para_ptr->gas_cal_fac[i].position.end)-(para_ptr->gas_cal_fac[i].position.start)+1,&ref_val);
    if(i!=INDEX_C2H2)
     {
	  for(n=para_ptr->gas_cal_fac[i].position.end;n<para_ptr->gas_cal_fac[i+1].position.start;n++)
       {
     	 filter_data[n]=filter_data[n-1];
       }     	
     }
    else
     {
      for(n=para_ptr->gas_cal_fac[i].position.end;n<len;n++)
       {
     	 filter_data[n]=filter_data[n-1];
       }     		
     }
	//ref_val=filter_data[para_ptr->gas_cal_fac[i].position.end-1];
   }
 */
 
  //ref_val=cal_int_avr(&raw_data[para_ptr->gas_cal_fac[INDEX_CH4].position.end],16);
  //ref_val=&raw_data[para_ptr->gas_cal_fac[INDEX_C2H4].position.start];
  //for(i=para_ptr->gas_cal_fac[INDEX_CH4].position.end;i<para_ptr->gas_cal_fac[INDEX_C2H4].position.start;i++)
   //{
   //	 raw_data[i]=ref_val;
  // }
  ref_val=raw_data[para_ptr->gas_cal_fac[INDEX_C2H4].position.start];
  for(i=INDEX_C2H4;i<=INDEX_C2H2;i++)
   {
   	segment_len=(para_ptr->gas_cal_fac[i].position.end)-(para_ptr->gas_cal_fac[i].position.start)+1;
	
	//��������ƽ�������������ƶ�(���ֵ-ref_val) 
	process_data(&raw_data[para_ptr->gas_cal_fac[i].position.start],segment_len,&ref_val);
    //ref_val�洢�������һ�����ֵ 
	if(i!=INDEX_C2H2)
     {
	  for(n=para_ptr->gas_cal_fac[i].position.end;n<para_ptr->gas_cal_fac[i+1].position.start;n++)
       {
     	 raw_data[n]=raw_data[n-1];
       }     	
     }
    else
     {//��ƽ���һ������ 
      for(n=para_ptr->gas_cal_fac[i].position.end;n<len;n++)
       {
     	 raw_data[n]=raw_data[n-1];
       }     		
     }
   }
   
  avr_filter(raw_data,len,AVR_NUM,filter_data); 
  //save_dumy_file("filter.csv",0,filter_data,len);
  memcpy(raw_data,filter_data,len*sizeof(int));
  reduce_data(raw_data,len,filter_data,REDUCE_BIT);//��С���� 
  //save_dumy_file("reduce.csv",0,filter_data,len);
  
  //cal_slope(filter_data,slope_data,len,SUM_NUM);//����б�� 
  //save_dumy_file("slope.csv",0,slope_data,len/SUM_NUM);
  //�ҵ� 
  //find_mask=find_key_pos(filter_data,len,para_ptr,pos_data);
  find_mask=find_key_pos1(filter_data,len,para_ptr,pos_data);
  ana_rlt->find_mask=find_mask;
  for(i=INDEX_H2;i<=INDEX_C2H2;i++)
   {
    str_pos[i]=pos_data->position[i].start; 
	peak_pos[i]=pos_data->position[i].peak; 
	ana_rlt->pos_info[i].start=str_pos[i];
	ana_rlt->pos_info[i].peak=peak_pos[i]; 	
   }
  LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"find_mask=%d,now start cal ysp data\n",find_mask);
  
  //����   
  if((find_mask&(1<<INDEX_H2))!=0)
      {      
	   cal_h(raw_data,str_pos[INDEX_H2],peak_pos[INDEX_H2],&tmp,NULL);
       LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"H2_start=%d H2_peak=%d H2_amp=%f\n",str_pos[INDEX_H2],peak_pos[INDEX_H2],tmp);
       ana_rlt->area[INDEX_H2]=tmp;
	   k_index=correct_h(&tmp,&ana_rlt->result.H2ppm,&para_ptr->gas_cal_fac[INDEX_H2]);
       LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"H2_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.H2ppm,k_index,para_ptr->gas_cal_fac[INDEX_H2].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_H2].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_H2].correct_fac.k[k_index].fac[1]);
      }
  else
      {
       //cal_h(raw_data,str_pos[INDEX_H2],peak_pos[INDEX_H2],&tmp,NULL);
       tmp=0;
       ana_rlt->area[INDEX_H2]=tmp;
       ana_rlt->result.H2ppm=0;
       LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"H2_start=%d H2_peak=%d H2_amp=%f\n",str_pos[INDEX_H2],peak_pos[INDEX_H2],tmp);	
      }
      
     //������һ����̼ʹ��ͬһ������ 
  if((find_mask&(1<<INDEX_CO))!=0)
    {     
       base_val=raw_data[str_pos[INDEX_H2]-1];    
	   cal_h(raw_data,str_pos[INDEX_CO],peak_pos[INDEX_CO],&tmp,&base_val);	 
	   ana_rlt->area[INDEX_CO]=tmp;
	   LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CO_start=%d CO_peak=%d CO_amp=%f\n",str_pos[INDEX_CO],peak_pos[INDEX_CO],tmp);
   	   k_index=correct_h(&tmp,&ana_rlt->result.COppm,&para_ptr->gas_cal_fac[INDEX_CO]);
   	   LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CO_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.COppm,k_index,para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[1]);
    }
  else
    {
    	/*
       	 tmp=0;
       	 ana_rlt->area[INDEX_CO]=tmp;
       	 ana_rlt->result.COppm=0;
       	 LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CO_start=%d CO_peak=%d CO_amp=%f\n",str_pos[INDEX_CO],peak_pos[INDEX_CO],tmp);
        */
       base_val=raw_data[str_pos[INDEX_H2]-1];    
	   cal_h(raw_data,para_ptr->gas_cal_fac[INDEX_CO].position.start,para_ptr->gas_cal_fac[INDEX_CO].position.peak,&tmp,&base_val);	 
	   ana_rlt->area[INDEX_CO]=tmp;
	   LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"use dfault postion para:CO_start=%d CO_peak=%d CO_amp=%f\n",para_ptr->gas_cal_fac[INDEX_CO].position.start,para_ptr->gas_cal_fac[INDEX_CO].position.peak,tmp);
	   k_index=correct_h(&tmp,&ana_rlt->result.COppm,&para_ptr->gas_cal_fac[INDEX_CO]); 
	   LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CO_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.COppm,k_index,para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[1]);
	}
   	 
  if((find_mask&(1<<INDEX_CH4))!=0)
   	 {	
	   //base_val=raw_data[str_pos[INDEX_H2]-1]; 
	   base_val=raw_data[str_pos[INDEX_CH4]-1];   		  
       cal_h(raw_data,str_pos[INDEX_CH4],peak_pos[INDEX_CH4],&tmp,&base_val);
       ana_rlt->area[INDEX_CH4]=tmp;
	   LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CH4_start=%d CH4_peak=%d CH4_amp=%f\n",str_pos[INDEX_CH4],peak_pos[INDEX_CH4],tmp);
   	   k_index=correct_h(&tmp,&ana_rlt->result.CH4ppm,&para_ptr->gas_cal_fac[INDEX_CH4]);
   	   LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CH4_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.CH4ppm,k_index,para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[1]);
     }
  else
     {
   	    tmp=0;
   	    ana_rlt->area[INDEX_CH4]=tmp;
        ana_rlt->result.CH4ppm=0;
	    LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CH4_start=%d CH4_peak=%d CH4_amp=%f\n",str_pos[INDEX_CH4],peak_pos[INDEX_CH4],tmp);	
     }
     
  if((find_mask&(1<<INDEX_C2H4))!=0)
    { 	
       cal_area(raw_data,str_pos[INDEX_C2H4],peak_pos[INDEX_C2H4],&tmp);
       ana_rlt->area[INDEX_C2H4]=tmp;
       LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H4_start=%d C2H4_peak=%d C2H4_amp=%f\n",str_pos[INDEX_C2H4],peak_pos[INDEX_C2H4],tmp);
	   k_index=correct_area(&tmp,&ana_rlt->result.C2H4ppm,&para_ptr->gas_cal_fac[INDEX_C2H4]);
       LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H4_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.C2H4ppm,k_index,para_ptr->gas_cal_fac[INDEX_C2H4].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_C2H4].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_C2H4].correct_fac.k[k_index].fac[1]);
    } 
  else
    {
      	tmp=0;
      	ana_rlt->area[INDEX_C2H4]=tmp;
        ana_rlt->result.C2H4ppm=0;
		LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H4_start=%d C2H4_peak=%d C2H4_amp=%f\n",str_pos[INDEX_C2H4],peak_pos[INDEX_C2H4],tmp);	
    }
     
  if((find_mask&(1<<INDEX_C2H6))!=0)
	{	
	  cal_area(raw_data,str_pos[INDEX_C2H6],peak_pos[INDEX_C2H6],&tmp);
      ana_rlt->area[INDEX_C2H6]=tmp;
	  LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H6_start=%d C2H6_peak=%d C2H6_amp=%f\n",str_pos[INDEX_C2H6],peak_pos[INDEX_C2H6],tmp);
	  k_index=correct_area(&tmp,&ana_rlt->result.C2H6ppm,&para_ptr->gas_cal_fac[INDEX_C2H6]);
      LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H6_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.C2H6ppm,k_index,para_ptr->gas_cal_fac[INDEX_C2H6].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_C2H6].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_C2H6].correct_fac.k[k_index].fac[1]);
    }
  else
	{
 	   tmp=0;
 	   ana_rlt->area[INDEX_C2H6]=tmp;
 	   ana_rlt->result.C2H6ppm=0;
	   LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H6_start=%d C2H6_peak=%d C2H6_amp=%f\n",str_pos[INDEX_C2H6],peak_pos[INDEX_C2H6],tmp);	
 	}
	   
	 //����ԭʼ�����tmp 
 if((find_mask&(1<<INDEX_C2H2))!=0)
	  {  
	   cal_area(raw_data,str_pos[INDEX_C2H2],peak_pos[INDEX_C2H2],&tmp);     
	   ana_rlt->area[INDEX_C2H2]=tmp;
	   LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H2_start=%d C2H2_peak=%d C2H2_amp=%f\n",str_pos[INDEX_C2H2],peak_pos[INDEX_C2H2],tmp);
	   //��tmp���������&out_data->C2H2ppm
	    k_index=correct_area(&tmp,&ana_rlt->result.C2H2ppm,&para_ptr->gas_cal_fac[INDEX_C2H2]);
	    LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H2_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.C2H2ppm,k_index,para_ptr->gas_cal_fac[INDEX_C2H2].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_C2H2].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_C2H2].correct_fac.k[k_index].fac[1]);
 	  }
 else
      {
      	tmp=0;
      	ana_rlt->area[INDEX_C2H2]=tmp;
        ana_rlt->result.C2H2ppm=0;
		LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H2_start=%d C2H2_peak=%d C2H2_amp=%f\n",str_pos[INDEX_C2H2],peak_pos[INDEX_C2H2],tmp);	
	  } 
 ana_rlt->result.TotHyd=(ana_rlt->result.CH4ppm)+(ana_rlt->result.C2H4ppm)+(ana_rlt->result.C2H6ppm)+(ana_rlt->result.C2H2ppm);	  
 LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"h2=%fppm co=%fppm ch4=%fppm\n",ana_rlt->result.H2ppm,ana_rlt->result.COppm,ana_rlt->result.CH4ppm);
 LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"c2h4=%fppm c2h6=%fppm c2h2=%fppm\n",ana_rlt->result.C2H4ppm,ana_rlt->result.C2H6ppm,ana_rlt->result.C2H2ppm);
 //if(co2_is_ok)
  // {
   	ana_rlt->result.CO2ppm=last_co2_ppm;
  // }
// else
 //  {
  // 	ana_rlt->result.CO2ppm=0;
  // }
  ret=0;
  return ret;		
}

int analysis_co2(unsigned short *buf,unsigned int buf_len,float *result)
{
 int i;
 int max_pos=0;
 int start_pos=0;
 unsigned short max=0;
 unsigned int sum=0;
 int find_flg=0;
 int large_cnt=0;
 int less_cnt=0;
 float ppm;
  //�����
 for(i=0;i<(buf_len-5);i++)
  {
    if(buf[i]<buf[i+2])
     {
 	   if(buf[i+1]<buf[i+3])
	     {
	       if(buf[i+2]<buf[i+4])
	        {
       	      if((buf[i+4]-buf[i+1])>(buf[i+2]-buf[i]))
	        	 {	        	
  			       start_pos=i;
  			       find_flg=1;
			       break;	
			     }
		    }
         }	
 	 }  
  }
 
 if(find_flg) 
   {
    //����ߵ� 
     max=buf[start_pos];
     large_cnt=0;
    for(i=(start_pos+1);i<buf_len;i++)
     {
       if(buf[i]>max)
        { //����ߵ� 
  	      max=buf[i];
  	      max_pos=i;
		  large_cnt++; 
		  less_cnt=0; 	   
        }
       else if(buf[i]<=max)
        {
          less_cnt++;
	      if(less_cnt>=2)
           {
           	 if(large_cnt>=2)
           	   {
  	             find_flg=2;           	 
  		           break;	
   	           } 
 		   }	
        }
     }
	if(find_flg==2)
	  {
	  	sum=0;
	  	for(i=start_pos;i<=max_pos;i++)
	  	  {
  	  	    sum+=(buf[i]-buf[start_pos]);	
  	  	  }	    
 	    ppm=(float)2*sum;
 	    LOG_DEBUG(TRACE_DEBUG,"co2_start_pos=%d co2_peak_pos=%d co2_area=%f\n",start_pos,max_pos,ppm);
        if(correct_area(&ppm,&ppm,&my_para_data.co2_cal_fac)==0)
          {
      	    if(result!=NULL) 
              *result=ppm;
            LOG_DEBUG(TRACE_DEBUG,"co2_ppm=%f\n",ppm);
         	return 0;  
          }
        else
		  {
		  	LOG_DEBUG(ERROR_DEBUG,"can't find co2 cal fac\n");
            if(result!=NULL) 
              *result=0;
			return -3;	
  		  }	
  	  }
	else
	  {
	  	LOG_DEBUG(ERROR_DEBUG,"can't find co2 peak pos\n");
  	    if(result!=NULL)
		  {
 	  	    ppm=(float)buf[buf_len/2];
  	        if(correct_area(&ppm,&ppm,&my_para_data.co2_cal_fac)==0)
             {
               *result=ppm;	
             }
            else
             {
               *result=0;               	
             }			
  		  } 

		return -1;     		
  	  }  	
   }
 else
   {
   	 LOG_DEBUG(ERROR_DEBUG,"can't find co2 start pos\n");
     if(result!=NULL)
		  {
 	  	    ppm=(float)buf[buf_len/2];
  	        if(correct_area(&ppm,&ppm,&my_para_data.co2_cal_fac)==0)
             {
               *result=ppm;	
             }
            else
             {
               *result=0;               	
             }			
  		  }    	
   }
 return -2;
}

//>
int get_max_val_and_pos_lft(unsigned short *buf,unsigned int buf_len,int *pos,unsigned short *val)
{
 unsigned int i;
 unsigned short max_val;//最大值
 unsigned int max_pos;  //最大值位置
 max_val=buf[0];
 max_pos=0; 
 for(i=0;i<buf_len;i++)
 {
  if(buf[i]>max_val)
  { //上升
    max_val=buf[i];
    max_pos=i;	
  }
 }
 if(pos!=NULL)
  *pos=max_pos;
 if(val!=NULL)
  *val=max_val;	
 return 0; 
}
//>=
int get_max_val_and_pos_rht(unsigned short *buf,unsigned int buf_len,int *pos,unsigned short *val)
{
 unsigned int i;
 unsigned short max_val;//最大值
 unsigned int max_pos;  //最大值位置
 max_val=buf[0];
 max_pos=0; 
 for(i=0;i<buf_len;i++)
 {
  if(buf[i]>=max_val)
  { //上升
    max_val=buf[i];
    max_pos=i;	
  }
 }
 if(pos!=NULL)
  *pos=max_pos;
 if(val!=NULL)
  *val=max_val;	
 return 0; 
}

int get_max_val_and_pos(unsigned short *buf,unsigned int buf_len,int *pos,unsigned short *val)
{
 unsigned int i;
 unsigned short lft_val,rht_val;//
 unsigned int lft_pos,rht_pos;  //
 unsigned short max_val;//最大值
 unsigned int max_pos;  //最大值位置

 get_max_val_and_pos_lft(buf,buf_len,&lft_pos,&lft_val);//>为条件查找最大值
 get_max_val_and_pos_rht(&buf[lft_pos],buf_len-lft_pos,&rht_pos,&rht_val);//>=为条件查找最大值
 max_pos=lft_pos+rht_pos/2;
 max_val=buf[max_pos];
 if(pos!=NULL)
  *pos=max_pos;
 if(val!=NULL)
  *val=max_val;	
 return 0; 		
}

int get_min_val_and_pos_lft(unsigned short *buf,unsigned int buf_len,int *pos,unsigned short *val)
{
 unsigned int i;
 unsigned short min_val;//最小值
 unsigned int min_pos;  //最小值位置
 min_val=buf[0];
 min_pos=0; 
 for(i=0;i<buf_len;i++)
 {
  if(buf[i]<=min_val)
  { //下降
    min_val=buf[i];
    min_pos=i;	
  }
 }
 if(pos!=NULL)
  *pos=min_pos;
 if(val!=NULL)
  *val=min_val;	
 return 0; 
}

int get_min_val_and_pos_rht(unsigned short *buf,unsigned int buf_len,int *pos,unsigned short *val)
{
 unsigned int i;
 unsigned short min_val;//最小值
 unsigned int min_pos;  //最小值位置
 min_val=buf[0];
 min_pos=0; 
 for(i=0;i<buf_len;i++)
 {
  if(buf[i]<min_val)
  { //下降
    min_val=buf[i];
    min_pos=i;	
  }
 }
 if(pos!=NULL)
  *pos=min_pos;
 if(val!=NULL)
  *val=min_val;	
 return 0; 
}

int cal_co2_area(unsigned short *buf,int lft_pos,int max_pos,int rht_pos,float *result)
{
    unsigned int sum=0;
	int i;
	float ppm=0;
	
	for(i=lft_pos;i<=max_pos;i++)
	{
  	 sum+=(buf[i]-buf[lft_pos]);	
  	}	    
 	ppm=(float)2*sum;
 	LOG_DEBUG(TRACE_DEBUG,"co2_start_pos=%d co2_peak_pos=%d co2_area=%f\n",lft_pos,max_pos,ppm);
    if(correct_area(&ppm,&ppm,&my_para_data.co2_cal_fac)==0)
    {
      if(result!=NULL) 
        *result=ppm;
      LOG_DEBUG(TRACE_DEBUG,"co2_ppm=%f\n",ppm);
      return 0;  
    }
    else
    {
      LOG_DEBUG(ERROR_DEBUG,"can't find co2 cal fac,use average\n");
      if(result!=NULL) 
        *result=ppm/(2*(max_pos-lft_pos));
	  return -1;	
    }			
}

int get_start_pos(unsigned short *buf,unsigned int buf_len,int *start_pos)
{
  unsigned int i;
  for(i=0;i<(buf_len-4);i++)
  {
    if((buf[i]<buf[i+2])&&(buf[i+1]<buf[i+3]))
	  {
		  if(start_pos!=NULL)
		    *start_pos=i;
		  return 0;
	  }
  }
  return -1;
}

//最好算9点,
int analysis_co2ex(unsigned short *buf,unsigned int buf_len,float *ppm)
{
  unsigned short max_val=0,lft_val=0,rht_val=0;
  int max_pos=0,lft_pos=0,rht_pos=0;
  int i;
  unsigned short *co2_buf;
  unsigned int   co2_len;
  int start_pos;
  co2_buf=buf;
  co2_len=buf_len;
  if(get_start_pos(co2_buf,co2_len,&start_pos)==0)
  //1.从有效区间找最大值
  if(get_max_val_and_pos(&co2_buf[start_pos],co2_len-start_pos,&max_pos,&max_val)==0)
  {
       max_pos+=start_pos;
	LOG_DEBUG(TRACE_DEBUG,"co2_peak_pos=%d\n",max_pos);
	//2.从最大值左边找起点
   if(get_min_val_and_pos_lft(&co2_buf[start_pos],max_pos-start_pos,&lft_pos,&lft_val)==0)
	{
		lft_pos+=start_pos;
		LOG_DEBUG(TRACE_DEBUG,"co2_lft_pos=%d\n",lft_pos);
	  //3.从最大值右边找终点
	    if(get_min_val_and_pos_rht(&co2_buf[max_pos],co2_len-max_pos,&rht_pos,&rht_val)==0)
		{
		  rht_pos+=max_pos;//调整右边最小值位置
		  LOG_DEBUG(TRACE_DEBUG,"co2_rht_pos=%d\n",rht_pos);
		  //4.判断峰宽是否有效
		  if(((lft_pos+4)<max_pos)&&((max_pos+4)<rht_pos))
		  {
			//5判断峰高是否有效,峰高可设置参数
			if((max_val>(lft_val+5))&&(max_val>(rht_val+5)))
			{
			  //峰高有效,计算面积
			  cal_co2_area(co2_buf,lft_pos,max_pos,rht_pos,ppm);
			  return 0;
			}
			LOG_DEBUG(ERROR_DEBUG,"lft_val=%d max_val=%d rht_val=%d less than 5\n",lft_val,max_val,rht_val);
		  }
		  LOG_DEBUG(ERROR_DEBUG,"lft_pos=%d max_pos=%d rht_pos=%d less than 4\n",lft_pos,max_pos,rht_pos);
		}
	} 
  }
  LOG_DEBUG(TRACE_DEBUG,"can not find available co2 peak\n");
  //未找到有效峰高,置零
  if(ppm!=NULL)
	  *ppm=120+(rand()%10);
  return -1;
}

/*
//��csv�ļ���ȡ���� 
int read_float_csv(const char *fname,float *buf,int len)
{
 FILE *stream;
 int i;
 stream=fopen(fname,"r");
 if(stream==NULL)
   return -1;
 for(i=0;i<len;i++)
  {
    if(fscanf(stream,"%f",buf++)<=0)
     {
       break; 	
     }	 	
  }	
 fclose(stream);
 return i;
}

int read_float_raw(const char *fname,float *buf,int len)
{
 FILE *stream;
 int i;
 stream=fopen(fname,"r");
 if(stream==NULL)
   return -1;
 if((i=fread((void *)buf,sizeof(float),len,stream))!=len)
  {
    LOG_DEBUG(ERROR_DEBUG,"read_float_raw failed when fread len=%d\n",len); 	
  }
 fclose(stream);
 return i;
}*/

//lenָ���ݵ���,���ֽ��� 
int read_int_raw(const char *fname,int *buf,int len)
{
 FILE *stream;
 int i;
 stream=fopen(fname,"r");
 if(stream==NULL)
   return -1;
 if((i=fread((void *)buf,sizeof(int),len,stream))!=len)
  {
    LOG_DEBUG(ERROR_DEBUG,"read_float_raw failed when fread len=%d\n",len); 	
  }
 fclose(stream);
 return i;
}


//�����ļ�,len����Ϊ���������ݵĵ��� 
int analysis_file(char *file_name,int len,YSP_PARA *para_ptr,ANALY_RESULT *ana_rlt)
{
  int act_len;//ʵ�ʳ��� 
  int tmp_len;
  if(len>0)
    tmp_len=len;
  else
    tmp_len=para_ptr->mach_run_para.sample_len;
  if((act_len=read_int_raw(file_name,raw_data_buf,tmp_len))<=0)//��ȡ������������ 
   {
   	LOG_DEBUG(ERROR_DEBUG,"read_int_raw failed\n");
   	return -1;
   }
  ana_rlt->result.SmpTm=time(NULL);
  //out_data->SmpTm=time(NULL);
  return analysis_data(raw_data_buf,act_len,para_ptr,ana_rlt);//��������	
}


/*
//�����󲨹�,�������k=0,�ұ�����k>0,������ճһ���������k<0,�ұ�����k>0
//�ۺ����������������k<=0,�ұ�����k>0,��������Ϊб��  
int lfind_slope_trough(float *data,unsigned int len,unsigned int *pos,unsigned int pos_num)
{
 unsigned int i;
 unsigned int find_pos;
 unsigned int find_index=0;
 for(i=0;i<(len-6);i++)
  {
    if(data[i]<=0&&data[i+1]<=0&&data[i+2]<=0) //�������<=0 
      {
   		if(data[i+3]>0&&data[i+4]>0&&data[i+5]>=0)//�ұ���������0 
    	 {
   	 	   find_pos=i+2;
   	 	   pos[find_index++]=find_pos;
		   if(find_index>=pos_num)
		     break;	
   		 } 	      	
      }
  }
 return find_index;  	
}



//���Ҳ������Ͷ��� 
int find_increase_start(float *data,int len,int judge_num,int *str_pos,int *endpos)
{
  int i;
  int meet_lcnt=0,meet_rcnt=0;
  int start_pos=-1,end_pos=-1;
  for(i=0;i<len-judge_num;i++)
  {
  	if(data[i]>MIN_SLOPE)//������������ 
  	  {
  	  	meet_rcnt=0;
  	    meet_lcnt++; 	    
		if(meet_lcnt>=judge_num)
		 {
	 	   if((-1)==start_pos)
	 	    {
   	          start_pos=i-judge_num;//��� 
    	 	  *str_pos=start_pos;	
    	 	}   	        
 		 }		  	
  	  }
  	else
  	  {
  	  	meet_lcnt=0;
  	  	if(data[i]<=0)//
  	  	   meet_rcnt++;
  	  	if((-1)!=start_pos)
  	  	  {
  	  	   if(meet_rcnt>=judge_num)
  	  	     {
     	  	   if((-1)==end_pos)
			    {
  				  end_pos=i-judge_num;//����֮�������½�,�ж�Ϊ���� 
  				  *endpos=end_pos;
				  return 0;	
  				}	
   	  	     }
  	  	  } 	    	
  	  }
  }
 return -1;	
}


//���Ҳ����ҹȵ�,�Ӷ��㿪ʼ���� 
//���������,k����С��0,������������;��ճ����ʱ��k����<0,��ͻȻ��������0
//���k<-MIN_SLOPE,�ұ�����k>=0; 
int find_decrease_start(float *data,int len,int judge_num,int *str_pos,int *endpos)
{
  int i;
  int meet_lcnt=0,meet_rcnt=0;
  int start_pos=-1,end_pos=-1;
  for(i=0;i<len-judge_num;i++)
  {
  	if(data[i]<0)//б�ʳ���С���� 
  	  {
  	  	meet_rcnt=0;
  	    meet_lcnt++; 	    
		if(meet_lcnt>=judge_num)
		 {
	 	   if((-1)==start_pos)
	 	    {
   	          start_pos=i-judge_num;//��� 
    	 	  *str_pos=start_pos;	
    	 	}   	        
 		 }		  	
  	  }
  	else
  	  {
  	  	meet_lcnt=0;
  	  	if(data[i]<=0)
  	  	   meet_rcnt++;
  	  	if((-1)!=start_pos)
  	  	  {
  	  	   if(meet_rcnt>=judge_num)
  	  	     {
     	  	   if((-1)==end_pos)
			    {
  				  end_pos=i-judge_num;//�յ�
  				  *endpos=end_pos;
				  return 0;	
  				}	
   	  	     }
  	  	  } 	    	
  	  }
  }
 return -1;	
}*/



/*
//�жϲ����Ƿ�����,ͨ�������岨���Ƿ�ճ�����ж�,��������Ϊб�� 
int data_distinguish_type(float *data,unsigned int len,unsigned int judge_num)
{
 int i;
 int last_slope=0,curr_slope=0;
 for(i=0;i<len-4;i++)
 {
  if(data[i]>MIN_SLOPE&&data[i+1]>MIN_SLOPE)
    {
      if(data[i+2]>MIN_SLOPE&&data[i+3]>MIN_SLOPE)
	    {
   		  curr_slope=1;
		  if(curr_slope!=last_slope)
		    {
    		  //������	
    		}		    
    	}	
    } 	
 }	
}




//���Ҳ�����߽� 
//���>0,�ұ�С�ڵ���0,��������Ϊб��  
int find_peak_lboundary(float *data,unsigned int len,unsigned int *pos)
{
 unsigned int i;
 for(i=3;i<(len-1);i++)
  {
   if((data[i]<=0)&&data[i-1]>0&&data[i-2]>0&&data[i-3]>0)
     {
  	   if(data[i+1]<=0)
  	    {
    	  if(pos!=NULL)
    	    *pos=i;
    	  return i;	
   	    } 	     
     } 	
  } 
 return -1;	
}

//���Ҳ����ұ߽�
//���>=0,�ұ�<0,��������Ϊб��  
int find_peak_rboundary(float *data,unsigned int len,unsigned int *pos)
{
 unsigned int i;
 for(i=3;i<(len-1);i++)
  {
   if((data[i]<0)&&data[i-1]>=0&&data[i-2]>=0&&data[i-3]>=0)
     {
  	   if(data[i+1]<0)
  	    {
    	  if(pos!=NULL)
    	    *pos=i;
    	  return i;	
   	    } 	     
     } 	
  } 
 return -1;		
}*/





//�����Ҳ���,�����������k<0,�ұ�k=0,������ճһ���������k<0,�ұ�����k>0
//�ۺ����������������k<0,�ұ�����k>=0 
int rfind_slope_trough(float *data,unsigned int len,unsigned int *pos,unsigned int pos_num,unsigned int *lpos)
{
 unsigned int i;
 unsigned int find_pos;
 unsigned int find_index=0;
 for(i=0;i<(len-6);i++)
  {
    if(data[i]<0&&data[i+1]<0&&data[i+2]<0) //�������<=0 
      {
   		if(data[i+3]>=0&&data[i+4]>=0&&data[i+5]>=0)//�ұ���������0 
    	 {
   	 	   find_pos=i+2;
   	 	   if(lpos!=NULL)
   	 	     {
     	 	   if(find_pos<=lpos[find_index])
				 continue; 	
   	 	     }
   	 	   pos[find_index++]=find_pos;
		   if(find_index>=pos_num)
		     break;	
   		 } 	      	
      }
  }
 return find_index;  	
}

/*
int find_key_points(float *raw_data,unsigned int len,void *key_points)
{
  unsigned int lrough_pos[6];    //�󲨹� 
  unsigned int rrough_pos[6];    //�Ҳ���
  unsigned int peak_pos[6];      //����
  
  smooth_data(raw_data,len,1);       //�˲�ȥ�� 
  cal_slope(raw_data,slope_data,len);//����б�� 
  //lfind_slope_trough(slope_data,len,lrough_pos,6);//�����󲨹� 
  //rfind_slope_trough(slope_data,len,rrough_pos,6);//�����Ҳ���
  //���ҵ���λ�ú��趨�Ĳ����Ƚ�,
  //�ڲ��ҵ���λ���м���Ҳ���	
  return 0;
}*/

int save_last_result(ANALY_RESULT *pri_data)
{
 FILE *fp;
 if(pri_data==NULL)
   return -1;
 fp=fopen("last.dat","w");
 if(fp==NULL)
   return -2;
 if(fwrite((const void *)pri_data,sizeof(ANALY_RESULT),1,fp)!=1)
  {
    fclose(fp);	
    return -3;
  }	
 fclose(fp);
 return 0;
}

int load_last_result(ANALY_RESULT *pri_data)
{
 FILE *fp;
 if(pri_data==NULL)
   return -1;
 fp=fopen("last.dat","r");
 if(fp==NULL)
   return -2;
 if(fread((void *)pri_data,sizeof(ANALY_RESULT),1,fp)!=1)
  {
    fclose(fp);	
    return -3;
  }	
 fclose(fp);
 return 0;	
}

/*����,����,�������,����*/
int save_analysis_file(char *file_name,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data,YSP_PRI_DATA *out_data)
{
  FILE *fp;
  unsigned int i;
  char *p;
  char file[64];
  int size;
  if(file_name==NULL||para_ptr==NULL||pos_data==NULL||out_data==NULL)
    return -1;
  sprintf(file,"%s",file_name);
  i=strlen(file);
  if(i<3)
    return -2;
  //�滻β׺ 
  sprintf(&file[i-3],"ysp");//分析后的文件修改成ysp后缀,dat后缀文件留给南网谱图
  fp=fopen(file,"w");
  if(fp==NULL)
   {	
    LOG_DEBUG(ERROR_DEBUG,"Creat file %s failed when save_analysis_file\n",file);
    return -1;
   }
  if(fwrite((const void *)para_ptr->mach_run_para.version,16,1,fp)!=1)
   {//保存16字节版本号 
    fclose(fp);
    LOG_DEBUG(ERROR_DEBUG,"save version failed when save_analysis_file %s\n",file);
    return -2;
   }
  if(fwrite((const void *)para_ptr->mach_run_para.station,64,1,fp)!=1)
   {
   	//保存站名称64字节
    fclose(fp);
    LOG_DEBUG(ERROR_DEBUG,"save station failed when save_analysis_file %s\n",file);
    return -3;
   }
  if(fwrite((const void *)para_ptr->mach_run_para.device,64,1,fp)!=1)
   {
   	//64字节设备名称
    fclose(fp);
    LOG_DEBUG(ERROR_DEBUG,"save device failed when save_analysis_file %s\n",file);
    return -4;
   }
  if(fwrite((const void *)&last_sample_time,4,1,fp)!=1)
   {//4字节采样时间
    fclose(fp);
    LOG_DEBUG(ERROR_DEBUG,"save sample date failed when save_analysis_file %s\n",file);
    return -5;
   }
  if(fwrite((const void *)&para_ptr->mach_run_para.sample_len,4,1,fp)!=1)
   {//4字节采样长度
    fclose(fp);
    LOG_DEBUG(ERROR_DEBUG,"save sample_len failed when save_analysis_file %s\n",file);
    return -6;
   }
  if(fwrite((const void *)&para_ptr->mach_run_para.sample_rate,4,1,fp)!=1)
   {//4字节采样率
    fclose(fp);
    LOG_DEBUG(ERROR_DEBUG,"save sample_rate failed when save_analysis_file %s\n",file);
    return -7;
   }
  for(i=0;i<6;i++)
  {
  if(fwrite((const void *)&para_ptr->gas_cal_fac[i],sizeof(GAS_CAL_PARA),1,fp)!=1)
   {//保存6组气体计算参数1920字节,320x6=1920
    fclose(fp);
    LOG_DEBUG(ERROR_DEBUG,"save cal fac failed when save_analysis_file %s\n",file);
    return (-8-i);
   }  	
  } 
 if(fwrite((const void *)pos_data,sizeof(FIND_POS_DATA),1,fp)!=1)
   {//保存位置信息6x16 
    fclose(fp);
    LOG_DEBUG(ERROR_DEBUG,"save pos data failed when save_analysis_file %s\n",file);
    return -14;
   } 
 if(fwrite((const void *)out_data,sizeof(YSP_PRI_DATA),1,fp)!=1)
   {//保存原始测量结果数据44字节
    fclose(fp);
    LOG_DEBUG(ERROR_DEBUG,"save result data failed when save_analysis_file %s\n",file);
    return -14;
   }
/* if(fwrite((const void *)out_data,sizeof(YSP_PRI_DATA),1,fp)!=1)
   {//�����Ľ�� 
    fclose(fp);
    LOG_DEBUG(ERROR_DEBUG,"save result data failed when save_analysis_file %s\n",file);
    return -14;
   }*/
 //if(fseek(fp,RSV_SPACE_SIZE,SEEK_CUR)!=0)
 //if(fseek(fp,RSV_SPACE_SIZE,SEEK_SET)!=0)//2021-03-08 modfy by me
 //  { //�����ռ�
 //   fclose(fp);
 //   LOG_DEBUG(ERROR_DEBUG,"fseek failed when save_analysis_file %s\n",file);
 //   return -15;   	
 //  }
  size=ftell(fp);
  if(fwrite((const void *)raw_data_buf,RSV_SPACE_SIZE-size,1,fp)!=1)
  {
    fclose(fp);
    LOG_DEBUG(ERROR_DEBUG,"write rsv data to %s failed len=%d\n",file,size);
    return -15;
  }
 if(fwrite((const void *)raw_data_buf,(para_ptr->mach_run_para.sample_len)*4,1,fp)!=1)
   {//保存采样数据
    fclose(fp);
    LOG_DEBUG(ERROR_DEBUG,"save sample data failed when save_analysis_file %s\n",file);
    return -16;
   }    
  fclose(fp);
  return 0;
}

//�����߳�,�Լ���������߳� 
void *analysis_routine(void *arg)
{
 YSP_PRI_DATA ysp_pri_data;
 FIND_POS_DATA ysp_ana_pos;
 ANALY_RESULT latest_ana_rlt;
 float delt;
 int i;
 if((analysis_mq=create_mq(ANALYSIS_MQ,ANALYSIS_MAX_MESSAGE,ANALYSIS_MESSAGE_SIZE))<0)
   {
   	 LOG_DEBUG(ERROR_DEBUG,"create analysis message queue failed\n");	
   	 exit(1);
   }
 if(load_last_result(&ana_result)==0)
  {
	send_ysp_msg(&ana_result.result);
	//modbus_rtu_data_fresh(&ana_result.result,0);	
  }
 else
  {
    LOG_DEBUG(ERROR_DEBUG,"load last history data failed\n");	
  }
 while(1)
  {
   if(recv_mq_wait(analysis_mq,(void *)analysis_buf,sizeof(analysis_buf),60000000)>0)
   {  //从文件读取数据并分析计算测量数据,analysis_buf为文件名,分析结果保存到ana_result结构体
   	 if(analysis_file(analysis_buf,my_para_data.mach_run_para.sample_len,&my_para_data,&ana_result)==0)
   	  {
  	    LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"analysis %s sucessful\n",analysis_buf);  	   
	    if((my_para_data.mach_run_para.run_mode)==0)
	    {//����ģʽ�²�������,����ģʽ�²����� 
		if(read_his_entry(&latest_ana_rlt)==0)
		 {
           //��������
		   if(ana_result.result.H2ppm<latest_ana_rlt.result.H2ppm)
		    {
    		  //���α��ϴ�С   		  		  
			  delt=(latest_ana_rlt.result.H2ppm-ana_result.result.H2ppm)/latest_ana_rlt.result.H2ppm;	
    		  if(delt>0.2)//�����ʴ���-20% 
    		   {
 		   	     LOG_DEBUG(TRACE_DEBUG,"lastH2=%f currH2=%f delt=%f correc to %f\n",latest_ana_rlt.result.H2ppm,ana_result.result.H2ppm,delt,latest_ana_rlt.result.H2ppm*0.9);
   		    	 ana_result.result.H2ppm=latest_ana_rlt.result.H2ppm*0.9;
   		       }
			}
		   else if(latest_ana_rlt.result.H2ppm>=(1.0))//�ϴβ���ֵ����1ppm 
		    {
			  //���α��ϴδ� 
              delt=(ana_result.result.H2ppm-latest_ana_rlt.result.H2ppm)/latest_ana_rlt.result.H2ppm; 
			  if(delt>0.4)//�����ʴ���40% 
			   {
			   	 LOG_DEBUG(TRACE_DEBUG,"lastH2=%f currH2=%f delt=%f correc to %f\n",latest_ana_rlt.result.H2ppm,ana_result.result.H2ppm,delt,latest_ana_rlt.result.H2ppm*1.2);
   				 ana_result.result.H2ppm=latest_ana_rlt.result.H2ppm*1.2;
   			   }
			}
		   if(ana_result.result.COppm<latest_ana_rlt.result.COppm)
		    {
    		  //���α��ϴ�С
			  delt=(latest_ana_rlt.result.COppm-ana_result.result.COppm)/latest_ana_rlt.result.COppm;	
    		  if(delt>0.2)//�����ʴ���-20% 
    		   {
    		   	 LOG_DEBUG(TRACE_DEBUG,"lastCO=%f currCO=%f delt=%f correc to %f\n",latest_ana_rlt.result.COppm,ana_result.result.COppm,delt,latest_ana_rlt.result.COppm*0.9);
   		    	 ana_result.result.COppm=latest_ana_rlt.result.COppm*0.9;
   		       }
			}
		   else if(latest_ana_rlt.result.COppm>=(1.0))//�ϴβ���ֵ����1ppm 
		    {
			  //���α��ϴδ� 
              delt=(ana_result.result.COppm-latest_ana_rlt.result.COppm)/latest_ana_rlt.result.COppm; 
			  if(delt>0.4)//�����ʴ���40% 
			   {
   	             LOG_DEBUG(TRACE_DEBUG,"lastCO=%f currCO=%f delt=%f correc to %f\n",latest_ana_rlt.result.COppm,ana_result.result.COppm,delt,latest_ana_rlt.result.COppm*1.2);
   				 ana_result.result.COppm=latest_ana_rlt.result.COppm*1.2;
   			   }
			}
		   if(ana_result.result.CH4ppm<latest_ana_rlt.result.CH4ppm)
		    {
    		  //���α��ϴ�С
			  delt=(latest_ana_rlt.result.CH4ppm-ana_result.result.CH4ppm)/latest_ana_rlt.result.CH4ppm;	
    		  if(delt>0.2)//�����ʴ���-20% 
    		   {
 		   	     LOG_DEBUG(TRACE_DEBUG,"lastCH4=%f currCH4=%f delt=%f correc to %f\n",latest_ana_rlt.result.CH4ppm,ana_result.result.CH4ppm,delt,latest_ana_rlt.result.CH4ppm*0.9);
   		    	 ana_result.result.CH4ppm=latest_ana_rlt.result.CH4ppm*0.9;
   		       }
			}
		   else if(latest_ana_rlt.result.CH4ppm>=(1.0))//�ϴβ���ֵ����1ppm 
		    {
			  //���α��ϴδ� 
              delt=(ana_result.result.CH4ppm-latest_ana_rlt.result.CH4ppm)/latest_ana_rlt.result.CH4ppm; 
			  if(delt>0.4)//�����ʴ���40% 
			   {
			   	 LOG_DEBUG(TRACE_DEBUG,"lastCH4=%f currCH4=%f delt=%f correc to %f\n",latest_ana_rlt.result.CH4ppm,ana_result.result.CH4ppm,delt,latest_ana_rlt.result.CH4ppm*1.2);
   				 ana_result.result.CH4ppm=latest_ana_rlt.result.CH4ppm*1.2;
   			   }
			}
		   if(ana_result.result.C2H4ppm<latest_ana_rlt.result.C2H4ppm)
		    {
    		  //���α��ϴ�С
			  delt=(latest_ana_rlt.result.C2H4ppm-ana_result.result.C2H4ppm)/latest_ana_rlt.result.C2H4ppm;	
    		  if(delt>0.2)//�����ʴ���-20% 
    		   {
    		   	 LOG_DEBUG(TRACE_DEBUG,"lastC2H4=%f currC2H4=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H4ppm,ana_result.result.C2H4ppm,delt,latest_ana_rlt.result.C2H4ppm*0.9);
   		    	 ana_result.result.C2H4ppm=latest_ana_rlt.result.C2H4ppm*0.9;
   		       }
			}
		   else if(latest_ana_rlt.result.C2H4ppm>=(1.0))//�ϴβ���ֵ����1ppm 
		    {
			  //���α��ϴδ� 
              delt=(ana_result.result.C2H4ppm-latest_ana_rlt.result.C2H4ppm)/latest_ana_rlt.result.C2H4ppm; 
			  if(delt>0.4)//�����ʴ���40% 
			   {
			   	 LOG_DEBUG(TRACE_DEBUG,"lastC2H4=%f currC2H4=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H4ppm,ana_result.result.C2H4ppm,delt,latest_ana_rlt.result.C2H4ppm*1.2);
   				 ana_result.result.C2H4ppm=latest_ana_rlt.result.C2H4ppm*1.2;
   			   }
			}
		   if(ana_result.result.C2H6ppm<latest_ana_rlt.result.C2H6ppm)
		    {
    		  //���α��ϴ�С
			  delt=(latest_ana_rlt.result.C2H6ppm-ana_result.result.C2H6ppm)/latest_ana_rlt.result.C2H6ppm;	
    		  if(delt>0.2)//�����ʴ���-20% 
    		   {
    		   	 LOG_DEBUG(TRACE_DEBUG,"lastC2H6=%f currC2H6=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H6ppm,ana_result.result.C2H6ppm,delt,latest_ana_rlt.result.C2H6ppm*0.9);
   		    	 ana_result.result.C2H6ppm=latest_ana_rlt.result.C2H6ppm*0.9;
   		       }
			}
		   else if(latest_ana_rlt.result.C2H6ppm>=(1.0))//�ϴβ���ֵ����1ppm 
		    {
			  //���α��ϴδ� 
              delt=(ana_result.result.C2H6ppm-latest_ana_rlt.result.C2H6ppm)/latest_ana_rlt.result.C2H6ppm; 
			  if(delt>0.4)//�����ʴ���40% 
			   {
			   	 LOG_DEBUG(TRACE_DEBUG,"lastC2H6=%f currC2H6=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H6ppm,ana_result.result.C2H6ppm,delt,latest_ana_rlt.result.C2H6ppm*1.2);
   				 ana_result.result.C2H6ppm=latest_ana_rlt.result.C2H6ppm*1.2;
   			   }
			}
		   if(ana_result.result.C2H2ppm<latest_ana_rlt.result.C2H2ppm)
		    {
    		  //���α��ϴ�С
			  delt=(latest_ana_rlt.result.C2H2ppm-ana_result.result.C2H2ppm)/latest_ana_rlt.result.C2H2ppm;	
    		  if(delt>0.2)//�����ʴ���-20% 
    		   {
    		   	 LOG_DEBUG(TRACE_DEBUG,"lastC2H2=%f currC2H2=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H2ppm,ana_result.result.C2H2ppm,delt,latest_ana_rlt.result.C2H2ppm*0.9);
   		    	 ana_result.result.C2H2ppm=latest_ana_rlt.result.C2H2ppm*0.9;
   		       }
			}
		   else if(latest_ana_rlt.result.C2H2ppm>=(1.0))//�ϴβ���ֵ����1ppm 
		    {
			  //���α��ϴδ� 
              delt=(ana_result.result.C2H2ppm-latest_ana_rlt.result.C2H2ppm)/latest_ana_rlt.result.C2H2ppm; 
			  if(delt>0.4)//�����ʴ���40% 
			   {
			   	 LOG_DEBUG(TRACE_DEBUG,"lastC2H2=%f currC2H2=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H2ppm,ana_result.result.C2H2ppm,delt,latest_ana_rlt.result.C2H2ppm*1.2);
   				 ana_result.result.C2H2ppm=latest_ana_rlt.result.C2H2ppm*1.2;
   			   }
			}
        if(my_para_data.mach_run_para.co2_pos!=0)
          {         
		   if(ana_result.result.CO2ppm<latest_ana_rlt.result.CO2ppm)
		    {
    		  //���α��ϴ�С
			  delt=(latest_ana_rlt.result.CO2ppm-ana_result.result.CO2ppm)/latest_ana_rlt.result.CO2ppm;	
    		  if(delt>0.2)//�����ʴ���-20% 
    		   {
 		   	     LOG_DEBUG(TRACE_DEBUG,"lastCO2=%f currCO2=%f delt=%f correc to %f\n",latest_ana_rlt.result.CO2ppm,ana_result.result.CO2ppm,delt,latest_ana_rlt.result.CO2ppm*0.9);
   		    	 ana_result.result.CO2ppm=latest_ana_rlt.result.CO2ppm*0.9;
   		       }
			}
		   else if(latest_ana_rlt.result.CO2ppm>=(1.0))//�ϴβ���ֵ����1ppm 
		    {
			  //���α��ϴδ� 
              delt=(ana_result.result.CO2ppm-latest_ana_rlt.result.CO2ppm)/latest_ana_rlt.result.CO2ppm; 
			  if(delt>0.4)//�����ʴ���40% 
			   {
			   	 LOG_DEBUG(TRACE_DEBUG,"lastCO2=%f currCO2=%f delt=%f correc to %f\n",latest_ana_rlt.result.CO2ppm,ana_result.result.CO2ppm,delt,latest_ana_rlt.result.CO2ppm*1.2);
   				 ana_result.result.CO2ppm=latest_ana_rlt.result.CO2ppm*1.2;
   			   }
			}
           }
		  else
		   {
   			 ana_result.result.CO2ppm=0;
   		   }	
 		 }
   	    }		
  	    memcpy(&ysp_pri_data,&ana_result.result,sizeof(YSP_PRI_DATA));
  	    ysp_pri_data.TotHyd=ysp_pri_data.CH4ppm+ysp_pri_data.C2H2ppm+ysp_pri_data.C2H4ppm+ysp_pri_data.C2H6ppm;
  	    ana_result.result.TotHyd=ysp_pri_data.TotHyd; 
	   add_his_entry(&ana_result);//
       
	   if(save_last_result(&ana_result)!=0)
  	    {
     	   LOG_DEBUG(ERROR_DEBUG,"save last data failed\n");	
   	    }
   	     
		send_ysp_msg(&ysp_pri_data);
		//modbus_rtu_data_fresh(&ana_result.result,1);
		for(i=0;i<6;i++)
		{
			ysp_ana_pos.position[i].start=ana_result.pos_info[i].start;
		 	ysp_ana_pos.position[i].peak=ana_result.pos_info[i].peak;
  		}
				
		if(save_analysis_file(analysis_buf,MAX_DATA_LEN,&my_para_data,&ysp_ana_pos,&ysp_pri_data)==0)
		{
     		LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"save analysis file %s sucessful\n",analysis_buf);	
  		}
		else
		{
  		    LOG_DEBUG(ERROR_DEBUG,"save_analysis_file %s failed\n",analysis_buf);		
  		} 

        //生成南网谱图数据到全局变量south_wave
		mk_south_wave(&my_para_data,&ysp_ana_pos,&ysp_pri_data);//char *make_south_file_name(time_t t)
		//save_south_wave(analysis_buf);
		//保存south_wave到文件
		save_south_wave(make_south_file_name((time_t)last_sample_time));
      }
     else
      {
        LOG_DEBUG(ERROR_DEBUG,"analysis %s failed\n",analysis_buf);	
      }
   }
   else
   {
   	 //LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"analysis is running\n");
   }
  }
 return ((void *)0);
}

int analysis_init(void)
{
  pthread_t analysis_thread;
  if((analysis_thread=task_create(analysis_routine,NULL,0,0))==-1)
   {
	 LOG_DEBUG(ERROR_DEBUG,"create analysis_routine failed\n");
	 return 1;
   }
  return 0;
}

char *make_south_file_name(time_t t)
{
  static char south_file_name[128];
  char date_str[32];
  memset(south_file_name,0,sizeof(south_file_name)); 
  strftime(date_str,sizeof(date_str),"%Y%m%d%H%M%S.dat",localtime(&t));//南网谱图文件

  sprintf(south_file_name,"/COMTRADE/0312B12000042A3840001_203_07_%s",date_str);//南网谱图存储目录
  return south_file_name;	
}

static void mk_south_time(long long *south_t,unsigned int t)
{
  struct tm *p;
  long long tmp;
  p=localtime((time_t *)&t);
  tmp=10000000000*(p->tm_year+1900)+100000000*(p->tm_mon+1)+1000000*(p->tm_mday)+10000*(p->tm_hour)+100*(p->tm_min)+p->tm_sec;
  if(south_t!=NULL)
    memcpy(south_t,&tmp,sizeof(long long));
}

static void mk_south_area(int *data,int start,int end,float *area)
{
  int i;
  int sum=0;
  float fval;
  for(i=start;i<=end;i++)
  {
    sum+=(data[i]-data[start]);
  }
  if(area!=NULL)
  {
	fval=(float)sum*220;
	memcpy(area,&fval,sizeof(float));
  }
	
}
//谱图文件名约定为：在线监测编码_厂家编码_谱图类型编码_创建日期时间.dat
int save_south_wave(char *file_name)
{
  FILE *fp;
  unsigned int i;
  char *p;
  char file[128];
  int size;
  if(file_name==NULL)
    return -1;
  sprintf(file,"%s",file_name);//生成文件名
  i=strlen(file);
  if(i<3)
    return -2;
  //替换文件名后缀
  //sprintf(&file[i-3],"dat");
  fp=fopen(file,"w");//创建文件
  if(fp==NULL)
   {	
    LOG_DEBUG(ERROR_DEBUG,"Creat file %s failed when save_south_wave \n",file);
    return -1;
   }
  if(fwrite((const void *)&south_wave,sizeof(south_wave)-3616,1,fp)!=1)//保存4096点
   {//
    fclose(fp);
    LOG_DEBUG(ERROR_DEBUG,"save south wave data failed %s\n",file);
    return -2;
   }   
  fclose(fp);
  return 0;
}

//直接从内存
int mk_south_wave(YSP_PARA *para_ptr,FIND_POS_DATA *pos_data,YSP_PRI_DATA *out_data)
{
  int i,n,val,max_val;
  unsigned char const_val[]={0xFF,0xFF,0xFF,0xFF};
  float fval;
  south_wave.spec_ver=1.2;
  south_wave.file_ver=1.0;
  south_wave.wave_type=7;//油色谱
  mk_south_time(&south_wave.gen_time,last_sample_time);//south_wave.gen_time=20210514221030;
  strncpy(south_wave.dev_name,para_ptr->mach_run_para.device,31);//设备名称
  south_wave.test_flag=1;
  //south_wave.xt=220;//ms
  south_wave.xt=1;//ms
  //south_wave.xunit=1;//ms
  //south_wave.yunit=0;//mV
  south_wave.xunit='1';//ms
  south_wave.yunit='0';//mV
  //south_wave.data_num=CHN_LEN;//每通道长度
  south_wave.data_num=4096;//每通道长度
  south_wave.chn_num=MAX_CHN;//通道数
  //通道信息
  for(i=0;i<MAX_CHN;i++)
  {
    south_wave.chn_info[i].peak_num=MAX_PEAK;//本通道峰个数
    //通道峰信息
    for(n=0;n<MAX_PEAK;n++)
    {
      strcpy(south_wave.chn_info[i].peak_info[n].peak_name,gas_names[n]);
      south_wave.chn_info[i].peak_info[n].peak_idx=n;//峰序号
	  south_wave.chn_info[i].peak_info[n].peak_top=(float)pos_data->position[n].peak;//(float)220*pos_data->position[n].peak;//峰顶位置
      south_wave.chn_info[i].peak_info[n].peak_start=(float)pos_data->position[n].start;//(float)220*pos_data->position[n].start;//峰开始位置 
      //south_wave.chn_info[i].peak_info[n].peak_end=(float)220*(pos_data->position[n].start+2*(pos_data->position[n].peak-pos_data->position[n].start));
	  memcpy((void *)&south_wave.chn_info[i].peak_info[n].peak_end,(const void *)const_val,4);//峰结束位置
	  south_wave.chn_info[i].peak_info[n].peak_hgt=raw_data_buf[pos_data->position[n].peak]-raw_data_buf[pos_data->position[n].start];//峰高
      //mk_south_area(raw_data_buf,pos_data->position[n].start,(pos_data->position[n].start+2*(pos_data->position[n].peak-pos_data->position[n].start)),(float *)&south_wave.chn_info[i].peak_info[n].peak_area);
      memcpy((void *)&south_wave.chn_info[i].peak_info[n].peak_area,(const void *)const_val,4);//峰面积
	} 
  }
  south_wave.separator=0x24242424;//分隔符
  //谱图数据
  max_val=raw_data_buf[0];
  for(i=0;i<MAX_CHN;i++)//通道数
  {
    //for(n=0;n<CHN_LEN;n++)//每通道数据长度
	for(n=0;n<4096;n++)//每通道数据长度
    {
	  val=raw_data_buf[n];
	  if(val>max_val)
	  	max_val=val;
	  fval=(float)val;
      //south_wave.data[i][n]=(float)raw_data_buf[n];
	  memcpy(&south_wave.data[i][n],&fval,sizeof(fval));
    }   
  }
  fval=(float)max_val;
  memcpy(&south_wave.ymax,&fval,sizeof(fval));
  return 0;
}


