N-sim
Emulation and simulation of
Wireless Sensor Networks



   Home


   Project Page


   Download


   CVS



   Installation


   Configuration


   Plug-ins




 Hosted by
SourceForge.net Logo

/home/brennan/n-sim/Vaike/linux/system-addons/drivers/amptek.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by LANL/LANS pelowitz                              *
00003  *   pelowitz.lanl.gov                                                     *
00004  *                                                                         *
00005  *   Code modifications: Balakumar J. Balasubramaniam (bbalasub@gmail.com) *
00006  *                       Ernst Ingo-Esch (ernst@lanl.gov)                  *
00007  *                                                                         *
00008  *   This program is not free software; you cannot redistribute it         *
00009  *   it under the terms of the GNU General Public License as published by  *
00010  *   the Free Software Foundation; either version 2 of the License, or     *
00011  *   any later version.                                                    *
00012  *                                                                         *
00013  *   This program is distributed in the hope that it will be useful,       *
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00016  *   GNU General Public License for more details.                          *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU General Public License     *
00019  *   along with this program; if not, write to the                         *
00020  *   Free Software Foundation, Inc.,                                       *
00021  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00022  ***************************************************************************/
00023 
00024 //THIS VERSION Balakumar Balasubramaniam J
00025 // Last updated: 26 October, 2007
00026 
00027 #ifdef HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030 
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <stdio.h>
00034 #include <time.h>
00035 #include <string.h>
00036 #include <sys/types.h> 
00037 #include <sys/stat.h> 
00038 //#include <signal.h>
00039 //#include <unistd.h>
00040 #include </usr/include/math.h>
00041 #include "usb.h"
00042 #include <assert.h>
00043 #include <sys/types.h>
00044 #include <sys/socket.h>
00045 #include <netinet/in.h>
00046 //#include "/usr/include/linux/sctp.h"
00047 #include <netdb.h>
00048 #include <unistd.h>
00049 #include <errno.h>
00050 
00051 #define PROGVERSION "1.0.0.1"
00052 
00053 #define BOOL int
00054 #define TRUE 1
00055 #define FALSE 0
00056 
00057 #define D0  0x01
00058 #define D1  0x02
00059 #define D2  0x04
00060 #define D3  0x08
00061 #define D4  0x10
00062 #define D5  0x20
00063 #define D6  0x40
00064 #define D7  0x80
00065 #define DFF 0xff
00066 
00067 #define LOG_FILEPATH_FLAG       0x00000001
00068 #define SPECTRA_FILEPATH_FLAG   0x00000002
00069 #define SPECTRA_SECONDS_FLAG    0x00000004
00070 #define LOG_DOLOG_FLAG          0x00000008
00071 #define PRE_ALARM_FLAG          0x00000010
00072 #define POST_ALARM_FLAG         0x00000020
00073 #define RING_SIZE_FLAG          0x00000040
00074 #define DEAD_BAND_FLAG          0x00000080
00075 #define BG_PERIOD_FLAG          0x00000100
00076 #define SIGMA_ALARM_FLAG        0x00000200
00077 #define PEAKTRACK_BIN_FLAG      0x00000400
00078 #define PEAKTRACK_ROI_FLAG      0x00000800
00079 #define PEAKTRACK_SMOOTH_FLAG   0x00001000
00080 #define ALARM_FILEPATH_FLAG     0x00002000
00081 #define SPECTRAOUT_SIZE_FLAG    0x00004000
00082 #define BG_MINIMUM_FLAG         0x00008000
00083 #define FORCE_NOALARM_FLAG      0x00010000
00084 #define PEAKTRACK_FORCE_FLAG    0x00020000
00085 #define ALL_FLAGS               0x0003ffff
00086 #define IPPROTO_SCTP    132
00087 
00088 /* the device's vendor and product id */
00089 //#define MY_VID 1234
00090 //#define MY_PID 5678
00091 #define MY_VID 0x0BD7
00092 #define MY_PID 0xA021
00093 
00094 #define REQUESTTYPEIN 0xc8
00095 #define REQUESTTYPEOUT 0x48
00096 
00097 /* the device's endpoints */
00098 #define EP_IN_STATUSA  0x81
00099 #define EP_IN_SPECTRAA 0x82
00100 #define EP_IN_STATUSB  0x83
00101 #define EP_IN_SPECTRAB 0x84
00102 #define EP_IN_CONFIGUR 0x85
00103 #define EP_OUT_CONFIGUR 0x01
00104 #define EP_OUT 0x01
00105 
00106 #define CLEARBUFF_A 0x80
00107 #define CLEARBUFF_B 0x81
00108 #define ENABLEMCA 0x82
00109 #define DISABLEMCA 0x83
00110 
00111 #define BUF_SIZE 65
00112 #define CONFIG_SIZE 64
00113 #define STATUS_SIZE 64
00114 #define SPECT_SIZE (8192*3+1)
00115 #define SPECT_FSIZE (8192)
00116 
00117 #define NOSPECTRA_TYPE          0
00118 #define UNASSIGNED_TYPE         1
00119 #define PREALARM_TYPE           2
00120 #define ALARM_TYPE              3
00121 #define POSTALARM_TYPE          4
00122 #define GUARD_TYPE              5
00123 #define BG_TYPE                 6
00124 
00125 //will probably have to comment this out
00126 //unsigned int sleep(unsigned int seconds);
00127 
00128 // The remote receiver information goes here (bjb addition)
00129 char *server="10.10.10.20";
00130 int port=2000;
00131 #define FRAGMENTSIZE 1024
00132 #define PKTDELAY 10000
00133 int fd;
00134 struct hostent *he;
00135 struct sockaddr_in their_addr;
00136 #define min(x,y) (x<y ? x:y)
00137 int tcpconnectopen=0;
00138 
00139 //data to configure the instrument
00140 struct {
00141         char *szParameter;
00142         char cIndex;
00143         char cMask;
00144         char cSigned;
00145 } config[] = {
00146         "reset_lockout=",                       0,      D7,                     0,
00147         "flat_top_width=",                      0,      D6|D5|D4|D3,            0,
00148         "decimation_factor=",                   0,      D2|D1|D0,               0,
00149         "slow_channel_threshold=",              1,      DFF,                    0,
00150         "fast_channel_threshold=",              2,      DFF,                    0,
00151         "output_dac_offset=",                   3,      D7|D6|D5|D4|D3|D2|D1,   1,
00152         "dac_enabled=",                         3,      D0,                     0,
00153         "normal_operation1=",                   4,      D7|D6,                  0,
00154         "mca_enabled=",                         4,      D5,                     0,
00155         "mcamcs_channel_mode=",                 4,      D4|D3|D2,               0,
00156         "dac_output=",                          4,      D1|D0,                  0,
00157         "pileup_reject_interval=",              5,      DFF,                    0,
00158         "peaking_time=",                        6,      D7|D6|D5|D4,            0,
00159         "detector_reset_lockout_period=",       6,      D3|D2,                  0,
00160         "auto_baseline_reset_during_detector_reset=",   6,      D1,             0,
00161         "dont_disable_mca_during_detector_reset=",      6,      D0,             0,
00162         "rtd_slow_threshold=",                  7,      DFF,                    0,
00163         "normal_operation2=",                   8,      D7,                     0,
00164         "analog_gain=",                         8,      D6|D5,                  0,
00165         "rtd_on=",                              8,      D4,                     0,
00166         "rtd_time_threshold=",                  8,      D3|D2|D1|D0,            0,
00167         "50_digital_attenuation=",              9,      D7,                     0,
00168         "blr_enabled=",                         9,      D6,                     0,
00169         "blr_down_correction=",                 9,      D5|D4,                  0,
00170         "blr_up_correction=",                   9,      D3|D2,                  0,
00171         "blr_correction_threshold=",            9,      D1|D0,                  0,
00172         "gate=",                                10,     D7|D6,                  0,
00173         "mca_buffer_select=",                   10,     D5|D4,                  0,
00174         "digital_scope_trigger=",               10,     D3,                     0,
00175         "aux_out=",                             10,     D2|D1|D0,               0,
00176         "preset_time_lsb=",                     11,     DFF,                    0,
00177         "preset_time_byte2=",                   12,     DFF,                    0,
00178         "preset_time_msb=",                     13,     DFF,                    0,
00179         "fine_grain_normalizer_lsb=",           23,     DFF,                    0,
00180         "digital_scope_trigger_position=",      24,     D7|D6,                  0,
00181         "fine_grain_normalizer_msb=",           24,     D5|D4|D3|D2|D1|D0,      0,
00182         "preset_counts_lsb=",                   25,     DFF,                    0,
00183         "preset_counts_byte2=",                 26,     DFF,                    0,
00184         "preset_counts_byte3=",                 27,     DFF,                    0,
00185         "preset_counts_msb=",                   28,     DFF,                    0,
00186         "mca_or_mcs_mode=",                     29,     D7,                     0,
00187         "mcs_enabled=",                         29,     D5,                     0,
00188         "mcs_time_base=",                       29,     D3|D2|D1|D0,            0,
00189         "sca1_lower_threshold_lsb=",            32,     DFF,                    0,
00190         "sca1_lower_threshold_msb=",            33,     DFF,                    0,
00191         "sca1_upper_threshold_lsb=",            34,     DFF,                    0,
00192         "sca1_enabled=",                        35,     D7,                     0,
00193         "sca1_upper_threshold_msb=",            35,     D6|D5|D4|D3|D2|D1|D0,   0,
00194         "sca2_lower_threshold_lsb=",            36,     DFF,                    0,
00195         "sca2_lower_threshold_msb=",            37,     DFF,                    0,
00196         "sca2_upper_threshold_lsb=",            38,     DFF,                    0,
00197         "sca2_enabled=",                        39,     D7,                     0,
00198         "sca2_upper_threshold_msb=",            39,     D6|D5|D4|D3|D2|D1|D0,   0,
00199         "sca3_lower_threshold_lsb=",            40,     DFF,                    0,
00200         "sca3_lower_threshold_msb=",            41,     DFF,                    0,
00201         "sca3_upper_threshold_lsb=",            42,     DFF,                    0,
00202         "sca3_enabled=",                        43,     D7,                     0,
00203         "sca3_upper_threshold_msb=",            43,     D6|D5|D4|D3|D2|D1|D0,   0,
00204         "sca4_lower_threshold_lsb=",            44,     DFF,                    0,
00205         "sca4_lower_threshold_msb=",            45,     DFF,                    0,
00206         "sca4_upper_threshold_lsb=",            46,     DFF,                    0,
00207         "sca4_enabled=",                        47,     D7,                     0,
00208         "sca4_upper_threshold_msb=",            47,     D6|D5|D4|D3|D2|D1|D0,   0,
00209         "sca5_lower_threshold_lsb=",            48,     DFF,                    0,
00210         "sca5_lower_threshold_msb=",            49,     DFF,                    0,
00211         "sca5_upper_threshold_lsb=",            50,     DFF,                    0,
00212         "sca5_enabled=",                        51,     D7,                     0,
00213         "sca5_upper_threshold_msb=",            51,     D6|D5|D4|D3|D2|D1|D0,   0,
00214         "sca6_lower_threshold_lsb=",            52,     DFF,                    0,
00215         "sca6_lower_threshold_msb=",            53,     DFF,                    0,
00216         "sca6_upper_threshold_lsb=",            54,     DFF,                    0,
00217         "sca6_enabled=",                        55,     D7,                     0,
00218         "sca6_upper_threshold_msb=",            55,     D6|D5|D4|D3|D2|D1|D0,   0,
00219         "sca7_lower_threshold_lsb=",            56,     DFF,                    0,
00220         "sca7_lower_threshold_msb=",            57,     DFF,                    0,
00221         "sca7_upper_threshold_lsb=",            58,     DFF,                    0,
00222         "sca7_enabled=",                        59,     D7,                     0,
00223         "sca7_upper_threshold_msb=",            59,     D6|D5|D4|D3|D2|D1|D0,   0,
00224         "sca8_lower_threshold_lsb=",            60,     DFF,                    0,
00225         "sca8_lower_threshold_msb=",            61,     DFF,                    0,
00226         "sca8_upper_threshold_lsb=",            62,     DFF,                    0,
00227         "sca8_enabled=",                        63,     D7,                     0,
00228         "sca8_upper_threshold_msb=",            63,     D6|D5|D4|D3|D2|D1|D0,   0,
00229         NULL,0,0,0
00230         };
00231         
00232 //configuration and status buffer
00233 //unsigned char tmp[BUF_SIZE];
00234 unsigned char cur_config[BUF_SIZE];
00235                 
00236 //date of last change to configfile
00237 char szConfigChange[18] = {"0000_00_00_000000"};
00238 //path to the executable -- used to find the .config file
00239 char szExecutablePath[256];
00240 //holds the .config file and path
00241 char szConfigPathFile[256];
00242 //holds the log file and path
00243 char szLogPathFile[256];
00244 //holds the spectra path and file
00245 char szSpectraPathFile[256];
00246 //holds the alarm path and file
00247 char szAlarmPathFile[256];
00248 //holds the bg written when in alarm
00249 char szAlarmBGPathFile[256];
00250 //collection duration in sec
00251 int iCollectSeconds;
00252 //flag for log 0=no log, 1 = min log, 2 = max log
00253 int iDoLog;
00254 
00255 //how often to save (seconds) back ground
00256 int bg_period = 3600;
00257 time_t bg_previous = 0;
00258 
00259 //alarm and spectra ring buffer
00260 int pre_alarm=1;
00261 int post_alarm=1;
00262 int ring_size=32;
00263 int ring_size_prev=0;
00264 int dead_band=2;
00265 int bg_minimum=20;
00266 int ring_insertion_point = 0;
00267 int ring_count = 0;
00268 double sigma_alarm = 5.0;
00269 int force_noalarm = 600;
00270 
00271 //peak tracking and rebin
00272 int spectraout_size=2500;
00273 int peaktrack_bin=750;
00274 int peaktrack_roi=50;
00275 int peaktrack_smooth=6;
00276 double fpeaktrack_offset = 0.0;
00277 double fpeaktrack_force = 1.0;
00278 float fA_TParam;
00279 float fA_Param;
00280 float fB_TParam;
00281 float fB_Param;
00282 float fC_TParam;
00283 float fC_Param;
00284 
00285 //alarm and background
00286 BOOL bInAlarm = FALSE;
00287 BOOL bHaveBG = FALSE;
00288 
00289 struct RING_ELEMENT{
00290         time_t time;    //start time of the spectra
00291         int iSum;
00292         double iSqSum; // bjb add
00293         int iType;
00294         int iSize;
00295         double fDuration;
00296         unsigned char status[BUF_SIZE]; //status from inst
00297         double fspectra[SPECT_FSIZE];//real version of spectra 
00298 }ring_element,*pring_element;
00299 
00300 struct RING_ELEMENT alarm_spectra;
00301 struct RING_ELEMENT bg_spectra;
00302 struct RING_ELEMENT alarmbg_spectra;
00303 struct RING_ELEMENT tmp_spectra;
00304 struct RING_ELEMENT rebin_spectra;
00305 struct RING_ELEMENT *ring_buffer = NULL;
00306 
00307 usb_dev_handle *open_dev(void);
00308 void print_to_log(char*);
00309 char getconfig(char* pcBuf, int iOffset, char cMask, char cSigned);
00310 double Transmogrify(double fInPut, double fPeakTrackOffset, BOOL bUseTemp);
00311 double PeakTrack(double*dOutSpectrum, int iSize, int iExpectedBinPeak, int iRegionSize, int iSmoothWindow);
00312 void ReBIN(double*dInSpectrum, int iInSize, double*dOutSpectrum, int iOutSize, double dPeakTrackOffset, BOOL bUseTemp);
00313 
00314 void zero_spectra(struct RING_ELEMENT* pring_element)
00315 {
00316         pring_element->iSum = 0;
00317         pring_element->iSqSum=0; //bjb add
00318         pring_element->fDuration = 0.0;
00319         memset(&pring_element->fspectra,0,sizeof(pring_element->fspectra));
00320 }
00321 
00322 void add_spectra(struct RING_ELEMENT* pring_elementdest, struct RING_ELEMENT* pring_elementsrc)
00323 {
00324         int i;
00325         pring_elementdest->iSum += pring_elementsrc->iSum;
00326         pring_elementdest->iSqSum += pring_elementsrc->iSqSum;  //bjb add
00327         pring_elementdest->fDuration += pring_elementsrc->fDuration;
00328         for (i = 0; i < SPECT_FSIZE; i++)
00329                 pring_elementdest->fspectra[i] += pring_elementsrc->fspectra[i]; 
00330 }
00331 
00332 void print_spectra(struct RING_ELEMENT* pring_element,char* szPath,double fPeakTrackOffset)
00333 {
00334         int i,iLength;
00335         char szFilename[512];
00336         struct tm*timeinfo;
00337         FILE *outfile;
00338         timeinfo = localtime(&pring_element->time);
00339         //build the spectra name with time stamp
00340         sprintf(szFilename,"%s_%04d_%02d_%02d_%02d%02d%02d.txt",
00341                 szPath,
00342                 timeinfo->tm_year+1900,
00343                 timeinfo->tm_mon+1,
00344                 timeinfo->tm_mday,
00345                 timeinfo->tm_hour,
00346                 timeinfo->tm_min,
00347                 timeinfo->tm_sec);
00348 
00349         //make sure we have a good file name
00350         //step around the potential "C:" if running on windoz
00351         //some linux systems have problems with space in the file name
00352         //if that is the case here then add the check for space
00353         for (i = 2; i < (signed)strlen(szFilename); i++) 
00354         {
00355                 if ((szFilename[i] == ':') || (szFilename[i] == '\n') || (szFilename[i] == '?') || (szFilename[i] == '*')) 
00356                         szFilename[i] = '_';
00357         }
00358 
00359         outfile = fopen(szFilename,"w");
00360         
00361         print_to_log(szFilename);
00362         
00363         if (outfile)
00364         {
00365                 fprintf(outfile,"Type: ");
00366                 
00367                 switch (pring_element->iType) {
00368                 case NOSPECTRA_TYPE:
00369                         fprintf(outfile,"No Spectra");
00370                         break;
00371                 case UNASSIGNED_TYPE:
00372                         fprintf(outfile,"Unassigned");
00373                         break;
00374                 case PREALARM_TYPE:
00375                         fprintf(outfile,"Pre-Alarm");
00376                         break;
00377                 case ALARM_TYPE:
00378                         fprintf(outfile,"Alarm");
00379                         break;
00380                 case POSTALARM_TYPE:
00381                         fprintf(outfile,"Post-Alarm");
00382                         break;
00383                 case GUARD_TYPE:
00384                         fprintf(outfile,"Guard");
00385                         break;
00386                 case BG_TYPE:
00387                         fprintf(outfile,"Background");
00388                         break;
00389                 default:
00390                         fprintf(outfile,"UNKNOWN");
00391                 }
00392                 fprintf(outfile,"\n");
00393                 if (pring_element->iType != NOSPECTRA_TYPE)
00394                 {
00395                         fprintf(outfile,"Time: %04d\\%02d\\%02d %02d:%02d:%02d\n",
00396                                 timeinfo->tm_year+1900,
00397                                 timeinfo->tm_mon+1,
00398                                 timeinfo->tm_mday,
00399                                 timeinfo->tm_hour,
00400                                 timeinfo->tm_min,
00401                                 timeinfo->tm_sec);
00402                 
00403                         fprintf(outfile,"Duration (mSec): %f\n",pring_element->fDuration);
00404                         fprintf(outfile,"Integral Sum: %d\n",pring_element->iSum);
00405                         fprintf(outfile,"Peak Track: %f\n",fPeakTrackOffset);
00406                 
00407                         fprintf(outfile,"CONFIGURATION");
00408                         for (i = 0; i < CONFIG_SIZE; i++)
00409                         {
00410                                 if (i%16==0)fprintf(outfile,"\n  %04d ",i);
00411                                 fprintf(outfile,"%02x ",cur_config[i]);
00412                         }
00413                         
00414                         fprintf(outfile,"\nSTATUS");
00415                         for (i = 0; i < STATUS_SIZE; i++)
00416                         {
00417                                 if (i%16==0)fprintf(outfile,"\n  %04d ",i);
00418                                 fprintf(outfile,"%02x ",pring_element->status[i]);
00419                         }
00420                 
00421                         iLength = getconfig(cur_config, 4, D2|D3|D4, 0);
00422                         fprintf(outfile,"\nSPECTRA (size:%d)\n", pring_element->iSize);
00423                         for (i = 0; i < pring_element->iSize; i++)
00424                                 fprintf(outfile,"%04d %lf\n",i,pring_element->fspectra[i]);
00425                 }
00426                 fclose(outfile);
00427         }
00428         else
00429         {
00430                 print_to_log("ERROR: Failed on write spectra file.");
00431         }
00432 }
00433 
00434 // this is where the packets are sent across the network
00435 // bjb addition send_spectra
00436 int send_spectra(struct RING_ELEMENT* pring_element,char* szPath,double fPeakTrackOffset)
00437 {
00438  char *pkt;
00439  int pktsize;
00440  char *tempstr;
00441  struct tm*timeinfo;
00442  int i, error;
00443  int remaining, total, tcnt;
00444  
00445  timeinfo = localtime(&pring_element->time);
00446  tempstr=malloc(1024); // tempstr holds the string that will be strcat-ted to pkt
00447 
00448  if (tempstr == NULL)
00449   {
00450    print_to_log("ERROR: memory allocation in send_spectra");
00451    return -1;
00452   } 
00453  // we need the size of the packet later on. so keep count of the number of characters
00454  pktsize=0;
00455  // allocate some large memory. this could be optimized depending upon the maximum size of the packet that will be sent
00456  pkt=malloc(2*SPECT_SIZE+CONFIG_SIZE+STATUS_SIZE);
00457  if (pkt == NULL)
00458   {
00459    print_to_log("ERROR: memory allocation in send_spectra");
00460    return -1;
00461   } 
00462  // initialize strings to NULL
00463  tempstr[0]='\0';
00464  pkt[0]='\0'; 
00465  // first create the pkt to be sent through the socket
00466  pktsize+=sprintf(tempstr,"PIPESTART ");
00467  strcat(pkt,tempstr);
00468 
00469  pktsize+=sprintf(tempstr,"Type: ");
00470  strcat(pkt,tempstr);
00471  switch (pring_element->iType)
00472  {
00473     case NOSPECTRA_TYPE:
00474      pktsize+=sprintf(tempstr,"No Spectra");
00475      strcat(pkt,tempstr);
00476      break;
00477     case UNASSIGNED_TYPE:
00478      pktsize+=sprintf(tempstr,"Unassigned");
00479      strcat(pkt,tempstr);
00480      break;
00481     case PREALARM_TYPE:
00482      pktsize+=sprintf(tempstr,"Pre-Alarm");
00483      strcat(pkt,tempstr);
00484      break;
00485     case ALARM_TYPE:
00486      pktsize+=sprintf(tempstr,"Alarm");
00487      strcat(pkt,tempstr);
00488      break;
00489     case POSTALARM_TYPE:
00490      pktsize+=sprintf(tempstr,"Post-Alarm");
00491      strcat(pkt,tempstr);
00492      break;
00493     case GUARD_TYPE:
00494      pktsize+=sprintf(tempstr,"Guard");
00495      strcat(pkt,tempstr);
00496      break;
00497     case BG_TYPE:
00498      pktsize+=sprintf(tempstr,"Background");
00499      strcat(pkt,tempstr);
00500      break;
00501     default:
00502      pktsize+=sprintf(tempstr,"UNKNOWN");
00503      strcat(pkt,tempstr);
00504  }     
00505  pktsize+=sprintf(tempstr," ");
00506  strcat(pkt,tempstr);
00507 
00508  if (pring_element->iType != NOSPECTRA_TYPE)
00509  {
00510     pktsize+=sprintf(tempstr,"Time: %04d\\%02d\\%02d %02d:%02d:%02d ",
00511                 timeinfo->tm_year+1900, timeinfo->tm_mon+1, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
00512     strcat(pkt,tempstr);
00513     
00514     pktsize+=sprintf(tempstr,"Duration (mSec): %f ", pring_element->fDuration);
00515     strcat(pkt,tempstr);
00516     pktsize+=sprintf(tempstr,"Integral Sum: %d ", pring_element->iSum);
00517     strcat(pkt,tempstr);
00518     pktsize+=sprintf(tempstr,"Peak Track: %f ", fPeakTrackOffset);
00519     strcat(pkt,tempstr);
00520 
00521     pktsize+=sprintf(tempstr,"CONFIGURATION ");
00522     strcat(pkt,tempstr);
00523     for (i=0;i<CONFIG_SIZE; i++)
00524     {
00525      if (i%16==0)
00526       {
00527        pktsize+=sprintf(tempstr," %04d ",i);
00528        strcat(pkt,tempstr);
00529       }
00530        pktsize+=sprintf(tempstr," %02x ",cur_config[i]);
00531        strcat(pkt,tempstr);
00532     }
00533 
00534     pktsize+=sprintf(tempstr,"STATUS ");
00535     strcat(pkt,tempstr);
00536     for (i=0;i<STATUS_SIZE; i++)
00537     {
00538      if (i%16==0)
00539       {
00540        pktsize+=sprintf(tempstr," %04d ",i);
00541        strcat(pkt,tempstr);
00542       }
00543        pktsize+=sprintf(tempstr," %02x ",pring_element->status[i]);
00544        strcat(pkt,tempstr);
00545     }
00546 
00547     pktsize+=sprintf(tempstr,"SPECTRA (size:%d) ", pring_element->iSize);
00548     strcat(pkt,tempstr);
00549 
00550     for (i=0;i<pring_element->iSize; i++)
00551     {
00552        pktsize+=sprintf(tempstr," %04d %lf ",i, pring_element->fspectra[i]);
00553        strcat(pkt,tempstr);
00554     }
00555  }
00556  pktsize+=sprintf(tempstr,"PIPEEND");
00557  strcat(pkt,tempstr);
00558  
00559  // now send the pkt through the socket
00560  if (tcpconnectopen==0)
00561  {
00562  if ((fd = socket(PF_INET,SOCK_STREAM,0))<0) 
00563  {
00564         perror("Socket");
00565         print_to_log("ERROR: socket error during open\n");
00566         return fd;
00567  }
00568  if ((he =  gethostbyname(server))==NULL)
00569  {
00570         herror("gethostbyname");
00571         print_to_log("ERROR: gethostbyname error\n");
00572         return -1;  
00573  }
00574  
00575  their_addr.sin_family = AF_INET;
00576  their_addr.sin_port = htons(port);
00577  their_addr.sin_addr = *((struct in_addr *)he->h_addr);
00578  memset(their_addr.sin_zero,'\0',sizeof(their_addr.sin_zero));
00579 
00580  if (connect(fd,(struct sock_addr*)(& their_addr),sizeof(struct sockaddr))<0)
00581  { 
00582   perror("connect error");
00583   print_to_log("connect error\n");
00584  }
00585  else
00586   tcpconnectopen=1;
00587  } 
00588 
00589  printf("sending packet (size = %d)\n", pktsize);
00590  // send stuff here (break up packets to match MTU)
00591 // remaining=pktsize;
00592 // total=0;
00593 // tcnt=0;
00594 // while (total<pktsize)
00595 // {
00596   //if ((error = sendto(fd,pkt+total,min(FRAGMENTSIZE,remaining),0,(struct sock_addr*)(& their_addr),sizeof(struct sockaddr))) <0)
00597   if ((error = send(fd,pkt,pktsize,MSG_NOSIGNAL)) <0)  
00598   {
00599    if (errno==EPIPE)
00600     tcpconnectopen=0;
00601    perror("sendto");
00602    print_to_log("ERROR: sendto error\n");
00603   }
00604 //  tcnt++;
00605 //  total+=error;
00606 //  remaining-=error;
00607 //  printf("%d)sendto returned %d\n",tcnt,error);  
00608 //  usleep(PKTDELAY); // need delay to mitigate packet collision
00609 // }
00610   free(pkt);
00611   free(tempstr);
00612   return 0;
00613 }
00614 
00615 //write string to the log file if iDoLog > 0
00616 void print_to_log(char* szText)
00617 {
00618   char szfilename[256];
00619   time_t rawtime;
00620   struct tm* timeinfo;
00621   FILE *outfile;
00622 
00623   if (iDoLog > 0)
00624   {
00625         time(&rawtime);
00626         timeinfo = localtime(&rawtime);
00627         sprintf(szfilename,"%s_%04d_%02d_%02d.log",
00628                 szLogPathFile,
00629                 timeinfo->tm_year+1900,
00630                 timeinfo->tm_mon+1,
00631                 timeinfo->tm_mday);
00632         outfile = fopen(szfilename,"a");
00633         if (outfile)
00634         {
00635           fprintf(outfile,"%04d\\%02d\\%02d %02d:%02d:%02d %s\n",
00636                   timeinfo->tm_year+1900,
00637                   timeinfo->tm_mon+1,
00638                   timeinfo->tm_mday,
00639                   timeinfo->tm_hour,
00640                   timeinfo->tm_min,
00641                   timeinfo->tm_sec,
00642                   szText);
00643           fclose(outfile);
00644         }
00645         if (iDoLog >= 4)
00646                 printf("%04d\\%02d\\%02d %02d:%02d:%02d %s\n",
00647                         timeinfo->tm_year+1900,
00648                         timeinfo->tm_mon+1,
00649                         timeinfo->tm_mday,
00650                         timeinfo->tm_hour,
00651                         timeinfo->tm_min,
00652                         timeinfo->tm_sec,
00653                         szText);
00654   }
00655 }
00656 
00657 double Transmogrify(double fInPut, double fPeakTrackOffset, BOOL bUseTemp)
00658 {
00659         double  dATemp,dBTemp,dCTemp;
00660         if (fPeakTrackOffset > 0.0)
00661         {
00662                 dATemp = 0.0;
00663                 dBTemp = fPeakTrackOffset;
00664                 dCTemp = 0.0;
00665         }
00666         else
00667         {
00668                 dATemp = (bUseTemp)?fA_TParam:fA_Param;
00669                 dBTemp = (bUseTemp)?fB_TParam:fB_Param;
00670                 dCTemp = (bUseTemp)?fC_TParam:fC_Param;
00671         }
00672         return (dATemp * fInPut * fInPut + dBTemp * fInPut + dCTemp);
00673 }
00674 
00675 
00676 //assume iExpectedBinPeak iRegionSize/2
00677 double PeakTrack(double*dOutSpectrum, int iSize, int iExpectedBinPeak, int iRegionSize, int iSmoothWindow)
00678 {
00679         double dShift = -1.0;
00680         int iMaxPointL = 0;
00681         int iMaxPointR = 0;
00682         int iMaxPoint = 0;
00683         double dMaxValueL = 0.0;
00684         double dMaxValueR = 0.0;
00685         int iPoint;
00686         
00687         if ((iExpectedBinPeak + iRegionSize/2) < iSize)
00688         {
00689                 double* pdSmooth = (double*)malloc(sizeof(double)*iRegionSize);
00690                 //double dSmooth[iRegionSize];
00691                 double dSmoothTemp;
00692                 int i,j,k;
00693                 int iHalfRegionSize = iRegionSize/2;
00694 
00695                 //smooth the window around the expected peak
00696                 if (iSmoothWindow)
00697                 {
00698                         for (i = iExpectedBinPeak-iHalfRegionSize,j=0; i < iExpectedBinPeak+iHalfRegionSize; i++,j++)
00699                         {
00700                                 dSmoothTemp = 0.0;
00701                                 for (k = i - iSmoothWindow/2; k < i + iSmoothWindow/2; k++)
00702                                         dSmoothTemp += dOutSpectrum[k];
00703                                 pdSmooth[j] = dSmoothTemp/iSmoothWindow;
00704                         }       
00705                 }
00706                 else
00707                 {
00708                         memcpy(pdSmooth,&dOutSpectrum[iExpectedBinPeak-iRegionSize/2],sizeof(double)*iRegionSize);
00709                 }
00710 
00711                 //find highest peak from left
00712                 for (iPoint = 0; iPoint < iRegionSize; iPoint++)
00713                 {
00714                         if (dMaxValueL < pdSmooth[iPoint])
00715                         {
00716                                 iMaxPointL = iPoint;
00717                                 dMaxValueL = pdSmooth[iPoint];
00718                         }
00719                         //TRACE("L = %d %f\r\n",iPoint,pdSmooth[iPoint]);
00720                 }
00721 
00722                 for (/*int*/ iPoint = iRegionSize-1; iPoint >= 0; iPoint--)
00723                 {
00724                         if (dMaxValueR < pdSmooth[iPoint])
00725                         {
00726                                 iMaxPointR = iPoint;
00727                                 dMaxValueR = pdSmooth[iPoint];
00728                         }
00729                         //TRACE("R = %d %f\r\n",iPoint,pdSmooth[iPoint]);
00730                 }
00731 
00732                 if (iMaxPointL != iMaxPointR)
00733                         iMaxPoint = (iMaxPointL + iMaxPointR)/2;
00734                 else
00735                         iMaxPoint = iMaxPointL;
00736 
00737                 if (iMaxPoint>=0)       //expected / observed
00738                         dShift = (double)iExpectedBinPeak/(double)(iExpectedBinPeak + (iMaxPoint - (iRegionSize/2)));
00739 
00740                 free (pdSmooth);
00741         }
00742         return dShift;
00743 }
00744 
00745 void ReBIN(double*dInSpectrum, int iInSize, double*dOutSpectrum, int iOutSize, double dPeakTrackOffset, BOOL bUseTemp)
00746 {
00747         int i;
00748         for (i = 0; i < iOutSize; i++)
00749                 dOutSpectrum[i] = 0.0;
00750 
00751         double fStart, fEnd;
00752         double fFirst, fLast;
00753         int iStart, iEnd;
00754         int   iTwixt;
00755         double fTotal;
00756         int iSourceIndex;
00757         
00758         //step across the source spectrum figuring the start KEV and end KEV for each bin
00759         //and distribute the source spectra into the destination spectra accordingly
00760 
00761         for (iSourceIndex = 0; iSourceIndex < iInSize; iSourceIndex++)
00762         {
00763                 fStart = Transmogrify((double)iSourceIndex, dPeakTrackOffset, bUseTemp);
00764                 fEnd   = Transmogrify((double)(iSourceIndex+1), dPeakTrackOffset, bUseTemp);
00765                 fTotal = fEnd - fStart;
00766                 fFirst = fStart - (int)fStart;
00767                 fLast  = fEnd - (int)fEnd;
00768                 iTwixt = (int)((int)fEnd - fStart);
00769                 iStart = (int)fStart;   
00770                 iEnd   = (int)fEnd;     
00771                 if ((iStart < iOutSize) && (iStart >= 0))
00772                 {
00773                         if (iStart == iEnd)
00774                         {
00775                                         dOutSpectrum[iStart] += dInSpectrum[iSourceIndex];
00776                         }
00777                         else
00778                         {
00779 
00780                                 //do we have any "fractional" bin to start with
00781                                 if ((fFirst > 0.0) && (fStart < iOutSize)) 
00782                                 {
00783                                         double dTemp = (double)((1.0-fFirst) * dInSpectrum[iSourceIndex])/fTotal; 
00784                                         dOutSpectrum[iStart] += dTemp;
00785                                 }
00786 
00787                                 //do all of the "whole" bins
00788                                 if (iTwixt > 0)
00789                                         for (i = 0; i < iTwixt; i++)
00790                                         {
00791                                                 double fTemp = dInSpectrum[iSourceIndex]/fTotal;
00792                                                 if ((iStart+i) < iOutSize)
00793                                                 {
00794                                                         if ((fFirst <= 0.0) && (iStart+i >= 0))
00795                                                         {
00796                                                                 dOutSpectrum[iStart+i] += fTemp;
00797                                                         }
00798                                                         else
00799                                                         {
00800                                                                 int iTemp = iStart+i+1;
00801                                                                 if ((iTemp < iOutSize) && (iTemp >= 0))
00802                                                                 {
00803                                                                         dOutSpectrum[iStart+i+1] += fTemp;
00804                                                                 }
00805                                                         }
00806                                                 }
00807                                         }
00808 
00809                                 //do the end "fractional" bin if we have any
00810                                 if ((fLast > 0.0) && (iEnd < iOutSize))
00811                                 {
00812                                         double fTemp = fLast * dInSpectrum[iSourceIndex]/fTotal;
00813                                         dOutSpectrum[iEnd] += fTemp;
00814                                 }
00815                         }
00816                 }
00817         }
00818 }
00819 
00820 //try to open the usb device
00821 usb_dev_handle *open_dev(void)
00822 {
00823   struct usb_bus *bus;
00824   struct usb_device *dev;
00825 
00826   for(bus = usb_get_busses(); bus; bus = bus->next) 
00827     {
00828       for(dev = bus->devices; dev; dev = dev->next) 
00829         {
00830           if(dev->descriptor.idVendor == MY_VID
00831              && dev->descriptor.idProduct == MY_PID)
00832             {
00833               return usb_open(dev);
00834             }
00835         }
00836     }
00837   return NULL;
00838 }
00839 
00840 //get the cMask bits from the iOffset byte in pcBuf
00841 char getconfig(char* pcBuf, int iOffset, char cMask, char cSigned)
00842 {
00843         int iCount = 0;
00844         char cResult;
00845         unsigned char cTempMask = cMask;
00846         while ((cTempMask & 0x01)==0x00)
00847         {
00848                 iCount++;
00849                 cTempMask >>= 1;
00850         }
00851         if (cSigned)
00852                 cResult = (pcBuf[iOffset] >> iCount);
00853         else
00854                 cResult = (pcBuf[iOffset] >> iCount) & cTempMask;
00855 
00856         return cResult;
00857 }
00858 
00859 //set the cMask bits in the iOffset byte in the pcBuf to the
00860 //right justified bits in cValue
00861 void setconfig(char* pcBuf, int iOffset, unsigned char cMask, char cValue)
00862 {
00863         int iCount = 0;
00864         char cTempMask = cMask;
00865         while ((cTempMask & 0x01)==0x00)
00866         {
00867                 iCount++;
00868                 cTempMask >>= 1;
00869         }
00870 //      printf("in setconfig pcBuff:%08x iOffset:%d cMask:%02x cValue:%d iCount:%d\n",
00871 //              pcBuf,iOffset,cMask,cValue,iCount);
00872         pcBuf[iOffset] = (pcBuf[iOffset] & ~cMask) | ((cValue << iCount) & cMask);
00873 }
00874 
00875 //print out to the log file the configuration information in tmp
00876 void log_configuration(char* tmp)
00877 {
00878         int n;
00879         char s[256];
00880         n = 0;
00881         while (config[n].szParameter)
00882         {
00883                 sprintf(s,"%s%d",config[n].szParameter,
00884                         getconfig(tmp,config[n].cIndex,
00885                                 config[n].cMask,
00886                                 config[n].cSigned));
00887                 print_to_log(s);
00888                 n++;
00889         }
00890 }
00891 
00892 void reconfig1(void)
00893 {
00894   //get all the "REQUIRED" elements from the config file
00895   FILE* infile;
00896   //if we reconfigure then we probably want a new bg spectra
00897   bg_previous = 0;
00898   bInAlarm = FALSE;
00899   bHaveBG = FALSE;
00900    
00901   //open the config file
00902   infile = fopen(szConfigPathFile,"r");
00903   //get the "REQUIRED" configuration from it
00904   if (infile)
00905   {
00906           char linebuffer[512];
00907           char *szAt;
00908           unsigned int iFlags = 0x00000000;
00909           fgets(linebuffer,sizeof(linebuffer),infile);
00910           while (strlen(linebuffer) && (iFlags != ALL_FLAGS))
00911           {
00912                 if (strstr(linebuffer,"REQUIRED_log_filepath="))
00913                 {
00914                         szAt = strchr(linebuffer,'=') + 1;
00915                         strcpy(szLogPathFile,szAt);
00916                         szLogPathFile[strlen(szLogPathFile)-1] = 0;
00917                         iFlags |= LOG_FILEPATH_FLAG;
00918                 }
00919                 else if (strstr(linebuffer,"REQUIRED_spectra_filepath="))
00920                 {
00921                         szAt = strchr(linebuffer,'=') + 1;
00922                         strcpy(szSpectraPathFile,szAt);
00923                         szSpectraPathFile[strlen(szSpectraPathFile)-1] = 0;
00924                         iFlags |= SPECTRA_FILEPATH_FLAG;
00925                 }
00926                 else if (strstr(linebuffer,"REQUIRED_alarm_filepath="))
00927                 {
00928                         szAt = strchr(linebuffer,'=') + 1;
00929                         strcpy(szAlarmPathFile,szAt);
00930                         szAlarmPathFile[strlen(szAlarmPathFile)-1] = 0;
00931                         strcpy(szAlarmBGPathFile,szAlarmPathFile);
00932                         strcat(szAlarmBGPathFile,"_BG");
00933                         iFlags |= ALARM_FILEPATH_FLAG;
00934                 }
00935                 else if (strstr(linebuffer,"REQUIRED_spectra_seconds="))
00936                 {
00937                         szAt = strchr(linebuffer,'=') + 1;
00938                         sscanf(szAt,"%d",&iCollectSeconds);
00939                         iFlags |= SPECTRA_SECONDS_FLAG;
00940                 }
00941                 else if (strstr(linebuffer,"REQUIRED_log_dolog="))
00942                 {
00943                         szAt = strchr(linebuffer,'=') + 1;
00944                         sscanf(szAt,"%d",&iDoLog);
00945                         iFlags |= LOG_DOLOG_FLAG;
00946                 }
00947                 else if (strstr(linebuffer,"REQUIRED_pre_alarm="))
00948                 {
00949                         szAt = strchr(linebuffer,'=') + 1;
00950                         sscanf(szAt,"%d",&pre_alarm);
00951                         iFlags |= PRE_ALARM_FLAG;
00952                 }
00953                 else if (strstr(linebuffer,"REQUIRED_post_alarm="))
00954                 {
00955                         szAt = strchr(linebuffer,'=') + 1;
00956                         sscanf(szAt,"%d",&post_alarm);
00957                         iFlags |= POST_ALARM_FLAG;
00958                 }
00959                 else if (strstr(linebuffer,"REQUIRED_ring_size="))
00960                 {
00961                         ring_size_prev = ring_size;
00962                         szAt = strchr(linebuffer,'=') + 1;
00963                         sscanf(szAt,"%d",&ring_size);                   
00964                         iFlags |= RING_SIZE_FLAG;
00965                 }
00966                 else if (strstr(linebuffer,"REQUIRED_dead_band="))
00967                 {
00968                         szAt = strchr(linebuffer,'=') + 1;
00969                         sscanf(szAt,"%d",&dead_band);
00970                         iFlags |= DEAD_BAND_FLAG;
00971                 }
00972                 else if (strstr(linebuffer,"REQUIRED_bg_period="))
00973                 {
00974                         szAt = strchr(linebuffer,'=') + 1;
00975                         sscanf(szAt,"%d",&bg_period);
00976                         iFlags |= BG_PERIOD_FLAG;
00977                 }
00978                 else if (strstr(linebuffer,"REQUIRED_sigma_alarm="))
00979                 {
00980                         szAt = strchr(linebuffer,'=') + 1;
00981                         sscanf(szAt,"%lf",&sigma_alarm);
00982                         iFlags |= SIGMA_ALARM_FLAG;
00983                 }
00984                 else if (strstr(linebuffer,"REQUIRED_peaktrack_bin="))
00985                 {
00986                         szAt = strchr(linebuffer,'=') + 1;
00987                         sscanf(szAt,"%d",&peaktrack_bin);
00988                         iFlags |= PEAKTRACK_BIN_FLAG;
00989                 }
00990                 else if (strstr(linebuffer,"REQUIRED_peaktrack_roi="))
00991                 {
00992                         szAt = strchr(linebuffer,'=') + 1;
00993                         sscanf(szAt,"%d",&peaktrack_roi);
00994                         iFlags |= PEAKTRACK_ROI_FLAG;
00995                 }
00996                 else if (strstr(linebuffer,"REQUIRED_peaktrack_smooth="))
00997                 {
00998                         szAt = strchr(linebuffer,'=') + 1;
00999                         sscanf(szAt,"%d",&peaktrack_smooth);
01000                         iFlags |= PEAKTRACK_SMOOTH_FLAG;
01001                 }
01002                 else if (strstr(linebuffer,"REQUIRED_spectraout_size="))
01003                 {
01004                         szAt = strchr(linebuffer,'=') + 1;
01005                         sscanf(szAt,"%d",&spectraout_size);
01006                         iFlags |= SPECTRAOUT_SIZE_FLAG;
01007                 }
01008                 else if (strstr(linebuffer,"REQUIRED_bg_minimum="))
01009                 {
01010                         szAt = strchr(linebuffer,'=') + 1;
01011                         sscanf(szAt,"%d",&bg_minimum);
01012                         iFlags |= BG_MINIMUM_FLAG;
01013                 }
01014                 else if (strstr(linebuffer,"REQUIRED_force_noalarm="))
01015                 {
01016                         szAt = strchr(linebuffer,'=') + 1;
01017                         sscanf(szAt,"%d",&force_noalarm);
01018                         iFlags |= FORCE_NOALARM_FLAG;
01019                 }
01020                 else if (strstr(linebuffer,"REQUIRED_peaktrack_force="))
01021                 {
01022                         szAt = strchr(linebuffer,'=') + 1;
01023                         sscanf(szAt,"%lf",&fpeaktrack_force);
01024                         iFlags |= PEAKTRACK_FORCE_FLAG;
01025                 }
01026                 fgets(linebuffer,sizeof(linebuffer),infile);
01027           }
01028           fclose(infile);
01029   }
01030   else
01031   {
01032         //couldn't open the config file so write a new one
01033         print_to_log("WARNING: Cannot find config file. Creating default file!");
01034         strcpy(szLogPathFile,"Log");
01035         strcpy(szSpectraPathFile,"Spectra");
01036         strcpy(szAlarmPathFile,"Alarm");
01037         strcpy(szAlarmBGPathFile,"Alarm_BG");
01038         iCollectSeconds=1;
01039         iDoLog=1;
01040         pre_alarm=1;
01041         post_alarm=1;
01042         ring_size=64;
01043         dead_band=2;
01044         bg_period=3600;
01045         sigma_alarm=5.0;
01046         peaktrack_bin=1460;
01047         peaktrack_smooth=6;
01048         fpeaktrack_force=1.0;
01049         spectraout_size=2500;
01050         bg_minimum=60;
01051         infile = fopen(szConfigPathFile,"w");
01052         if (infile)
01053         {
01054                 fprintf(infile,
01055                         "REQUIRED_log_dolog=1\n"
01056                         "REQUIRED_log_filepath=Log\n"
01057                         "REQUIRED_spectra_filepath=Spectra\n"
01058                         "REQUIRED_alarm_filepath=Alarm\n"
01059                         "REQUIRED_spectra_seconds=1\n"
01060                         "REQUIRED_pre_alarm=1\n"
01061                         "REQUIRED_post_alarm=1\n"
01062                         "REQUIRED_ring_size=64\n"
01063                         "REQUIRED_dead_band=2\n"
01064                         "REQUIRED_bg_period=3600\n"
01065                         "REQUIRED_sigma_alarm=5.0\n"
01066                         "REQUIRED_peaktrack_bin=1460\n"
01067                         "REQUIRED_peaktrack_roi=100\n"
01068                         "REQUIRED_peaktrack_smooth=6\n"
01069                         "REQUIRED_peaktrack_force=1.0\n"
01070                         "REQUIRED_spectraout_size=2500\n"
01071                         "REQUIRED_bg_minimum=60\n"
01072                         "REQUIRED_force_noalarm=600\n"
01073                         "reset_lockout=0\n"
01074                         "flat_top_width=6\n"
01075                         "decimation_factor=1\n"
01076                         "slow_channel_threshold=0\n"
01077                         "fast_channel_threshold=19\n"
01078                         "output_dac_offset=13\n"
01079                         "dac_enabled=1\n"
01080                         "normal_operation1=0\n"
01081                         "mca_enabled=1\n"
01082                         "mcamcs_channel_mode=5\n"
01083                         "dac_output=1\n"
01084                         "pileup_reject_interval=0\n"
01085                         "peaking_time=8\n"
01086                         "detector_reset_lockout_period=2\n"
01087                         "auto_baseline_reset_during_detector_reset=0\n"
01088                         "dont_disable_mca_during_detector_reset=0\n"
01089                         "rtd_slow_threshold=0\n"
01090                         "normal_operation2=0\n"
01091                         "analog_gain=1\n"
01092                         "rtd_on=0\n"
01093                         "rtd_time_threshold=6\n"
01094                         "50_digital_attenuation=1\n"
01095                         "blr_enabled=0\n"
01096                         "blr_down_correction=3\n"
01097                         "blr_up_correction=3\n"
01098                         "blr_correction_threshold=3\n"
01099                         "gate=0\n"
01100                         "mca_buffer_select=0\n"
01101                         "digital_scope_trigger=0\n"
01102                         "aux_out=0\n"
01103                         "preset_time_lsb=0\n"
01104                         "preset_time_byte2=0\n"
01105                         "preset_time_msb=0\n"
01106                         "fine_grain_normalizer_lsb=0\n"
01107                         "digital_scope_trigger_position=2\n"
01108                         "fine_grain_normalizer_msb=4\n"
01109                         "preset_counts_lsb=0\n"
01110                         "preset_counts_byte2=0\n"
01111                         "preset_counts_byte3=0\n"
01112                         "preset_counts_msb=0\n"
01113                         "mca_or_mcs_mode=0\n"
01114                         "mcs_enabled=1\n"
01115                         "mcs_time_base=0\n"
01116                         "sca1_lower_threshold_lsb=0\n"
01117                         "sca1_lower_threshold_msb=0\n"
01118                         "sca1_upper_threshold_lsb=0\n"
01119                         "sca1_enabled=0\n"
01120                         "sca1_upper_threshold_msb=0\n"
01121                         "sca2_lower_threshold_lsb=0\n"
01122                         "sca2_lower_threshold_msb=0\n"
01123                         "sca2_upper_threshold_lsb=0\n"
01124                         "sca2_enabled=0\n"
01125                         "sca2_upper_threshold_msb=0\n"
01126                         "sca3_lower_threshold_lsb=0\n"
01127                         "sca3_lower_threshold_msb=0\n"
01128                         "sca3_upper_threshold_lsb=0\n"
01129                         "sca3_enabled=0\n"
01130                         "sca3_upper_threshold_msb=0\n"
01131                         "sca4_lower_threshold_lsb=0\n"
01132                         "sca4_lower_threshold_msb=0\n"
01133                         "sca4_upper_threshold_lsb=0\n"
01134                         "sca4_enabled=0\n"
01135                         "sca4_upper_threshold_msb=0\n"
01136                         "sca5_lower_threshold_lsb=0\n"
01137                         "sca5_lower_threshold_msb=0\n"
01138                         "sca5_upper_threshold_lsb=0\n"
01139                         "sca5_enabled=0\n"
01140                         "sca5_upper_threshold_msb=0\n"
01141                         "sca6_lower_threshold_lsb=0\n"
01142                         "sca6_lower_threshold_msb=0\n"
01143                         "sca6_upper_threshold_lsb=0\n"
01144                         "sca6_enabled=0\n"
01145                         "sca6_upper_threshold_msb=0\n"
01146                         "sca7_lower_threshold_lsb=0\n"
01147                         "sca7_lower_threshold_msb=0\n"
01148                         "sca7_upper_threshold_lsb=0\n"
01149                         "sca7_enabled=0\n"
01150                         "sca7_upper_threshold_msb=0\n"
01151                         "sca8_lower_threshold_lsb=0\n"
01152                         "sca8_lower_threshold_msb=0\n"
01153                         "sca8_upper_threshold_lsb=0\n"
01154                         "sca8_enabled=0\n"
01155                         "sca8_upper_threshold_msb=0\n");
01156 
01157                 fclose(infile);
01158         }
01159         else
01160                 print_to_log("WARNING: Cannot create default file!");
01161   }
01162 }
01163 
01164 int reconfig2(usb_dev_handle *dev)
01165 {
01166   struct stat buf;
01167   struct tm* timeinfo;
01168   char s[512];
01169   char szTemp[512];
01170   int i,j,iResult;
01171   FILE *infile;
01172 
01173   //get the two descriptor strings from the instrument
01174   if (usb_get_string_simple(dev,1,szTemp,sizeof(szTemp)) > 0)
01175   {
01176           sprintf(s,"Descriptor 1:%s",szTemp);
01177           print_to_log(s);
01178   }
01179   if (usb_get_string_simple(dev,2,szTemp,sizeof(szTemp)) > 0)
01180   {
01181           sprintf(s,"Descriptor 2:%s",szTemp);
01182           print_to_log(s);
01183   }
01184   //get the current instrument configuration
01185   if ((iResult = usb_bulk_read(dev, EP_IN_CONFIGUR, cur_config, sizeof(cur_config), 5000)) 
01186      != (sizeof(cur_config)-1))
01187   {
01188         sprintf(s,"ERROR: bulk read configuration (%d) failed",iResult);
01189         print_to_log(s);
01190         return -1;
01191   }
01192   else
01193   {
01194         //log the previous configuration
01195         strcpy(s,"OLD CONFIGURATION");
01196         szTemp[0] = 0;
01197         for (i = 0; i < CONFIG_SIZE; i++)
01198         {
01199                 if ((i & 0x0000000f) == 0)
01200                 {
01201                         sprintf(szTemp,"\n  %04d ",i);
01202                         strcat(s,szTemp);
01203                 }
01204                 sprintf(szTemp,"%02x ",cur_config[i]);
01205                 strcat(s,szTemp);
01206         }
01207         print_to_log(s);        
01208 
01209         //print the verbose veraion only if iDoLog says so
01210         if (iDoLog > 1)
01211                 log_configuration(cur_config);
01212 
01213         //get the remaining configuration information
01214         //build the 64 byte configuration based on the 
01215         //old configuration.  Note: only changed values
01216         //need to be included in the config file
01217         infile = fopen(szConfigPathFile,"r");
01218         if (infile)
01219         {
01220           char linebuffer[256];
01221           char *szAt;
01222           char cValue;
01223           //read a line from the config file
01224           while (fgets(linebuffer,sizeof(linebuffer),infile))
01225           {
01226             int n;
01227                 BOOL bFound;
01228                 //see if any of our config strings are included
01229                 //note that this assumes the config strings are
01230                 //unique and that they start the line
01231                 n = 0;
01232                 bFound = FALSE;
01233                 if ((strlen(linebuffer)>2) && (strstr(linebuffer,"REQUIRED_")==NULL))
01234                 {
01235                         while (config[n].szParameter && !bFound)
01236                         {
01237                                 if (strstr(linebuffer,config[n].szParameter))
01238                                 {
01239                                         int dValue;
01240                                         //go to the character after the =
01241                                         szAt = strchr(linebuffer,'=')+1;
01242                                         sscanf(szAt,"%d",&dValue);
01243                                         //set the value in the config array
01244                                         cValue = (char)dValue;
01245                                         setconfig(cur_config,config[n].cIndex,config[n].cMask,cValue);
01246                                         bFound = TRUE;
01247                                 }
01248                                 n++;
01249                         }
01250                         if (!bFound)
01251                         {
01252                                 for (i = 0; i < strlen(linebuffer); i++)
01253                                         if (linebuffer[i] == '\n') linebuffer[i] = 0;
01254                                 sprintf(s,"Configuration parameter \"%s\" not found.",linebuffer);
01255                                 print_to_log(s);
01256                         }
01257                 }
01258           }
01259           fclose(infile);
01260         }
01261 
01262         //log the new configuration
01263         strcpy(s,"NEW CONFIGURATION");
01264         szTemp[0] = 0;
01265         for (i = 0; i < CONFIG_SIZE; i++)
01266         {
01267                 if ((i & 0x0000000f) == 0)
01268                 {
01269                         sprintf(szTemp,"\n  %04d ",i);
01270                         strcat(s,szTemp);
01271                 }
01272                 sprintf(szTemp,"%02x ",cur_config[i]);
01273                 strcat(s,szTemp);
01274         }
01275         print_to_log(s);
01276 
01277         //only do the verbose if iDoLog says so
01278         if (iDoLog > 2)
01279                 log_configuration(cur_config);
01280 
01281         //send new configuration to instrument
01282         iResult=usb_bulk_write(dev, EP_OUT, cur_config, sizeof(cur_config)-1, 5000); 
01283         if (iResult <= 0)
01284         {
01285                 //log any errors
01286                 sprintf(s,"ERROR: bulk write returned: %d",iResult);
01287                 print_to_log(s);
01288                 return -1;
01289         }
01290 
01291         //read back the new configuration
01292         if ((iResult = usb_bulk_read(dev, EP_IN_CONFIGUR, cur_config, sizeof(cur_config), 5000)) 
01293                 != (sizeof(cur_config)-1))
01294         {
01295                 sprintf(s,"ERROR: bulk read configuration (%d) failed",iResult);
01296                 print_to_log(s);
01297                 return -1;
01298         }
01299 
01300         //log the new configuration
01301         strcpy(s,"NEW CONFIGURATION READBACK");
01302         szTemp[0] = 0;
01303         for (i = 0; i < CONFIG_SIZE; i++)
01304         {
01305                 if ((i & 0x0000000f) == 0)
01306                 {
01307                         sprintf(szTemp,"\n  %04d ",i);
01308                         strcat(s,szTemp);
01309                 }
01310                 sprintf(szTemp,"%02x ",cur_config[i]);
01311                 strcat(s,szTemp);
01312         }
01313         print_to_log(s);
01314   }
01315   
01316   //free up any existing storage in the ring buffer
01317   if (ring_buffer)
01318   {
01319         free(ring_buffer);
01320         ring_buffer = NULL;
01321   }       
01322 
01323   //get memory for the new ring buffer
01324   ring_buffer = malloc(sizeof(ring_element)*ring_size);
01325   memset(ring_buffer,0,sizeof(ring_element)*ring_size);
01326   
01327   //start at a known point in the ring
01328   ring_insertion_point = 0;
01329   ring_count = 0;
01330   
01331   //get the config file's last modified time
01332   //so we can reconfig on the fly if the config file
01333   //gets modified
01334   stat(szConfigPathFile,&buf);
01335   timeinfo = localtime(&buf.st_mtime);
01336   sprintf(s,"%04d_%02d_%02d_%02d%02d%02d\n",
01337                 timeinfo->tm_year+1900,
01338                 timeinfo->tm_mon+1,
01339                 timeinfo->tm_mday,
01340                 timeinfo->tm_hour,
01341                 timeinfo->tm_min,
01342                 timeinfo->tm_sec);
01343   strcpy(szConfigChange,s);
01344   return 0;
01345 }
01346 
01347 void End(void)
01348 {
01349         print_to_log("Exiting");
01350 }
01351 /*
01352 void Quit(int i)
01353 {
01354         printf("Quitting\n");
01355 }
01356 */
01357 int main(int argc, char**argv)
01358 {
01359   struct stat buf;
01360   int iDuration;
01361   int iCollectUSec;
01362   int iPostAlarmCount;
01363   usb_dev_handle *dev; /* the device handle */
01364   int ret; // bjb
01365   char buffr[65535]; //bjb
01366   //configuration and status buffer
01367   //unsigned char tmp[BUF_SIZE];
01368   //spectra buffer
01369   unsigned char spectra[SPECT_SIZE];
01370   //various vars
01371   int i,j,q,iResult,iSeq;
01372   //easy translation from byte,byte,byte to int
01373   union {
01374           char c[4];
01375           int  i;
01376   } translate;
01377   //spectra file
01378   FILE* outfile;
01379   //configuration file
01380 //  FILE* infile;
01381   //file name of spectra file 
01382   char filename[256];
01383   //struct to hold time from os
01384   time_t rawtime;
01385   //struct to hold values of date, time
01386   struct tm* timeinfo;
01387   //string buffer to facilitate talking to log
01388   char s[512];
01389   char szTemp[64];
01390   float mux, sigx; // mean and sigma of the count rate from the background
01391 
01392   atexit(End);
01393 //  signal(9, Quit);
01394 
01395   //get the current path, we'll use it if 
01396   //we can't find a path in the config file
01397   //and to find the config file
01398   if (argc > 0)
01399         strcpy(szExecutablePath,argv[0]);
01400 
01401   //default to 60 second spectra
01402   iCollectSeconds = 60;
01403 
01404   //default to doing a simple log file
01405   iDoLog = 1;
01406 
01407   //correct for windows .exe
01408   if (szExecutablePath[strlen(szExecutablePath)-4] == '.')
01409     szExecutablePath[strlen(szExecutablePath)-4] = 0;
01410   //build the configuration file path
01411   strcpy(szConfigPathFile,szExecutablePath);
01412   strcat(szConfigPathFile,".config");
01413   strcpy(szLogPathFile,szExecutablePath);
01414 
01415   reconfig1();
01416  
01417   print_to_log("Starting version: "PROGVERSION);
01418 
01419   usb_init(); /* initialize the library */
01420   usb_find_busses(); /* find all busses */
01421   usb_find_devices(); /* find all connected devices */
01422   //get a handle to the device 
01423   if((dev = open_dev()) == NULL)
01424   {
01425       print_to_log("ERROR: USB device not found!");
01426       exit(-1);
01427   }
01428 // begin bjb code
01429   ret=usb_get_driver_np(dev,0,buffr,sizeof(buffr)); 
01430   if (ret==0)
01431    {
01432     print_to_log("ERROR: interface 0 already claimed by another driver... attempting to detach it\n");
01433     ret=usb_detach_kernel_driver_np(dev,0);
01434     print_to_log("ERROR: usb_detach_kernel_driver_np failed\n");
01435    }                            // check if USB device is already claimed by a driver and attempt detach if it is
01436 // end bjb code
01437 
01438   //think this isn't necessary on this type of instrument
01439   //but should do it anyway
01440 //bjb  if(usb_set_configuration(dev, 1) < 0)
01441 //bjb  {
01442 //bjb      print_to_log("ERROR: USB setting config 1 failed");
01443 //bjb      usb_close(dev);
01444 //bjb      exit(-1);
01445 //bjb  }
01446   //get control of the interface--don't let anyone else
01447   //talk to the instrument while we are
01448   if(usb_claim_interface(dev, 0) < 0)
01449   {
01450       print_to_log("ERROR: USB claiming interface 0 failed");
01451       usb_close(dev);
01452       exit(-1);
01453   }
01454 // bjb code  begin
01455  ret=usb_set_altinterface(dev,0);
01456  assert(ret>=0);
01457 // end bjb code 
01458 
01459   if (reconfig2(dev) < 0)
01460         exit(-1);
01461 
01462   //read a spectra -- having some problems with garbage in the buffer
01463   //don't use this spectra
01464 //  iResult = usb_bulk_read(dev, EP_IN_SPECTRAA, spectra, 
01465 //      sizeof(spectra), 5000);
01466         
01467   //clear buffer A
01468   //this is the actual start of the first acquisition
01469   iResult = usb_control_msg(dev, USB_TYPE_VENDOR | USB_RECIP_OTHER, 
01470         0x80, 0, 0, spectra, 0, 5000);
01471   sleep(1);
01472   iResult = usb_control_msg(dev, USB_TYPE_VENDOR | USB_RECIP_OTHER, 
01473         0x80, 0, 0, spectra, 0, 5000);
01474         
01475   if (iResult < 0) 
01476   {
01477         sprintf(s,"ERROR: Cannot clear buffer.  usb_control_msg returned %d",iResult);
01478         print_to_log(s);
01479         exit(-1);
01480   }
01481 
01482   //get time at start of spectra
01483   time(&rawtime);
01484   timeinfo = localtime(&rawtime);
01485   //get time at start of the spectra
01486   ring_buffer[ring_insertion_point].time = rawtime;
01487   
01488   bInAlarm = FALSE;
01489   bHaveBG = FALSE;
01490   
01491   //repeat forever 
01492   for(iSeq = 1; iSeq <= 2; /*iSeq++*/)
01493   //while(1)
01494   {
01495         //check time of configuration file
01496         struct stat buf;
01497         stat(szConfigPathFile,&buf);
01498         timeinfo = localtime(&buf.st_mtime);
01499         sprintf(s,"%04d_%02d_%02d_%02d%02d%02d\n",
01500                 timeinfo->tm_year+1900,
01501                 timeinfo->tm_mon+1,
01502                 timeinfo->tm_mday,
01503                 timeinfo->tm_hour,
01504                 timeinfo->tm_min,
01505                 timeinfo->tm_sec);
01506         //did it change from startup
01507         if (strcmp(s,szConfigChange)!=0)
01508         {
01509                 //reconfig if it did change
01510                 reconfig1();
01511                 print_to_log("INFO: config file changed -- reconfiguring");
01512                 if (reconfig2(dev) < 0)
01513                         exit(-1);
01514         }
01515 
01516         iDuration = 0;
01517         iCollectUSec = iCollectSeconds*500000;
01518         //Sleep(iCollectMSec-25);
01519         usleep(iCollectUSec);//wait half
01520         while (iDuration < (iCollectSeconds*1000))
01521         {
01522                 //Sleep(5);
01523                 iCollectUSec = (iCollectSeconds*1000-iDuration)>>1;
01524                 if (iCollectUSec > 5)
01525                         usleep(iCollectUSec*1000);
01526                 if ((iResult = usb_bulk_read(dev, EP_IN_STATUSA, ring_buffer[ring_insertion_point].status, BUF_SIZE, 5000))
01527                         != (BUF_SIZE-1))
01528                 {
01529                         sprintf(s,"ERROR: bulk read STATUS A (%d) failed",iResult);
01530                         print_to_log(s);
01531                         return -1;
01532                 }
01533                 else
01534                 {
01535                         translate.c[0] = ring_buffer[ring_insertion_point].status[10];
01536                         translate.c[1] = ring_buffer[ring_insertion_point].status[11];
01537                         translate.c[2] = ring_buffer[ring_insertion_point].status[12];
01538                         translate.c[3] = 0;
01539                         iDuration = translate.i * 100 + ring_buffer[ring_insertion_point].status[9];//in milliseconds
01540                 }
01541         }
01542 
01543         //read the configuration from the instrument
01544         //although we currently have the config in cur_config this ensures that
01545         //the actual configuration is present (and it only takes 1msec)
01546         if ((iResult = usb_bulk_read(dev, EP_IN_CONFIGUR, cur_config, sizeof(cur_config), 5000)) 
01547                 != (sizeof(cur_config)-1))
01548         {
01549                 //log any error
01550                 sprintf(s,"ERROR: bulk read configuration (%d) failed",iResult);
01551                 print_to_log(s);
01552                 exit(-1);
01553         }
01554 
01555         //read the status from the instrument
01556         if ((iResult = usb_bulk_read(dev, EP_IN_STATUSA, 
01557                 ring_buffer[ring_insertion_point].status, BUF_SIZE, 5000)) != (BUF_SIZE-1))
01558         {
01559                 //put errors in the log file
01560                 sprintf(s,"ERROR: bulk read STATUS A (%d) failed",iResult);
01561                 print_to_log(s);
01562                 exit(-1);
01563         }
01564         else
01565         {
01566                 //put the duration in the spectra 
01567                 //printf("%d\n",(unsigned int)ring_buffer[ring_insertion_point].status[12]);
01568                 //printf("%d\n",(unsigned int)ring_buffer[ring_insertion_point].status[11]);
01569                 //printf("%d\n",(unsigned int)ring_buffer[ring_insertion_point].status[10]);                            
01570                 //printf("%d\n",(unsigned int)ring_buffer[ring_insertion_point].status[9]);
01571                 //printf("\n");         
01572                 translate.c[0] = ring_buffer[ring_insertion_point].status[10];
01573                 translate.c[1] = ring_buffer[ring_insertion_point].status[11];
01574                 translate.c[2] = ring_buffer[ring_insertion_point].status[12];
01575                 translate.c[3] = 0;
01576                 ring_buffer[ring_insertion_point].fDuration = translate.i * 100 + ring_buffer[ring_insertion_point].status[9];//in milliseconds
01577                 // printf("added spectra to ring buffer (duration=%f)\n", ring_buffer[ring_insertion_point].fDuration);
01578                 //translate.i=1;
01579                 //printf("printing translated value...\n");
01580                 //printf("%c\t%c\t%c\t%c\n",64+translate.c[0],64+translate.c[1],64+translate.c[2],64+translate.c[3]);
01581                 //read the spectra data
01582                 iResult = usb_bulk_read(dev, EP_IN_SPECTRAA, spectra, 
01583                         sizeof(spectra), 5000);
01584                 // printf("spectra read complete (iResult =%d)\n", iResult);
01585                 //put the spectra in the spectra file
01586                 if ((iResult >= 0))// && outfile)
01587                 {
01588                         //zero the buffer and start the next acquisition
01589                         //clear inst buffer A
01590                         int iResult2;
01591                         iResult2 = usb_control_msg(dev, USB_TYPE_VENDOR | USB_RECIP_OTHER, 
01592                                 0x80, 0, 0, spectra, 0, 5000);
01593                         // printf("enable mca again...\n");
01594                         iResult2 = usb_control_msg(dev, USB_TYPE_VENDOR | USB_RECIP_OTHER, 
01595                                 0x82, 0, 0, spectra, 0, 5000);
01596                                 
01597                         if (iResult2 < 0) 
01598                         {//error report on failure
01599                                 sprintf(s,"ERROR: usb_control_msg returned %d",iResult);
01600                                 print_to_log(s);
01601                                 exit(-1);
01602                         }
01603                 
01604                         //s/get time at start of the next spectra
01605                         time(&ring_buffer[(ring_insertion_point+1 % ring_size)].time);
01606 
01607                         ring_buffer[ring_insertion_point].iSum = 0;
01608                         ring_buffer[ring_insertion_point].iSqSum = 0;                   
01609                         ring_buffer[ring_insertion_point].iType = UNASSIGNED_TYPE;
01610                         
01611                         for (i = 0,j=0; i < iResult; i++)
01612                         {
01613                                 switch (i%3) 
01614                                 {
01615                                 case 0:
01616                                         translate.c[0] = spectra[i];
01617                                         break;
01618                                 case 1:
01619                                         translate.c[1] = spectra[i];
01620                                         break;
01621                                 case 2:
01622                                         translate.c[2] = spectra[i];
01623                                         ring_buffer[ring_insertion_point].iSum += translate.i;
01624                                         ring_buffer[ring_insertion_point].iSqSum += (double)(translate.i)*(double)(translate.i);  //bjb add
01625                                         ring_buffer[ring_insertion_point].fspectra[j++] = (double)translate.i;
01626                                         //ring_buffer[ring_insertion_point].fspectra[j++] = (double)ring_insertion_point;
01627                                         break;
01628                                 }
01629                         }
01630                         ring_buffer[ring_insertion_point].iSize = j;
01631                         
01632                         //do any alarm processing here
01633                         //consider reading the most recent background back in along with the offset and sqrt sum at startup so that
01634                         //      after initial bg we always have a bg and bg sqrt.
01635                         
01636                         //if not in alarm and have bg and (sum sqrt/time / sum bg sqrt/time) > sigma_alarm
01637                                 //set "in alarm" flag
01638                                 //clear then add all pre alarm spectras to alarm spectra  -- that we have received(may not have enough)
01639                                 //log event
01640                         if (!bInAlarm)//start an alarm state only if not currently in an alarm
01641                         {
01642                                 if (bHaveBG)//don't do an alarm unless we have sufficient bg
01643                                 {
01644                                         //is there an actual alarm situation
01645                                         //may need to change the division to use a "normalized isum"
01646                                         //printf("%f::%f::%f\n",
01647                                         //      sqrt(ring_buffer[ring_insertion_point].iSum/ring_buffer[ring_insertion_point].fDuration),
01648                                         //      sqrt(bg_spectra.iSum/bg_spectra.fDuration),
01649                                         //      sigma_alarm);   //shorty commented out
01650                                         // count rate (BG), count rate (current), duration, calculated sigma, set sigma
01651                                         sigx=(ring_buffer[ring_insertion_point].iSum/(ring_buffer[ring_insertion_point].fDuration/1000)-bg_spectra.iSum/(bg_spectra.fDuration/1000))/(sqrt(bg_spectra.iSum/(bg_spectra.fDuration/1000))/sqrt(ring_buffer[ring_insertion_point].fDuration/1000));
01652                                         printf("%f,%f,%f,%f,%f\n",
01653                                                 bg_spectra.iSum/(bg_spectra.fDuration/1000), ring_buffer[ring_insertion_point].iSum/(ring_buffer[ring_insertion_point].fDuration/1000),ring_buffer[ring_insertion_point].fDuration/1000, sigx, sigma_alarm);    // shorty addition              
01654                                         
01655                                         //mux=bg_spectra.iSum/(bg_spectra.fDuration/1000);      // bjb addition
01656                                         //sigx=sqrt(bg_spectra.iSum/(bg_spectra.fDuration/1000));  // bjb addition
01657                                         if (ring_buffer[ring_insertion_point].iSum/(ring_buffer[ring_insertion_point].fDuration/1000) > bg_spectra.iSum/(bg_spectra.fDuration/1000) + sigma_alarm*sqrt(bg_spectra.iSum/(bg_spectra.fDuration/1000))/sqrt(ring_buffer[ring_insertion_point].fDuration/1000))
01658                                         //if (ring_buffer[ring_insertion_point].iSum/(ring_buffer[ring_insertion_point].fDuration/1000) > mux+sigma_alarm*sigx) // bjb addition
01659                                         //if ((sqrt(ring_buffer[ring_insertion_point].iSum/ring_buffer[ring_insertion_point].fDuration) /
01660                                         //  sqrt(bg_spectra.iSum/bg_spectra.fDuration)) > sigma_alarm) // bjb comment out
01661                                         //bjb addition//if ((bg_spectra.iSum/bg_spectra.fDuration+sigma_alarm*sqrt(bg_spectra.iSum)/bg_spectra.fDuration) < 
01662                                         //bjb addition//ring_buffer[ring_insertion_point].iSum/ring_buffer[ring_insertion_point].fDuration) //bjb addition
01663                                         {
01664                                                 //set all the flags and accumulate the pre alarms
01665                                                 bInAlarm = TRUE;
01666                                                 iPostAlarmCount = 0;
01667                                                 ring_buffer[ring_insertion_point].iType = ALARM_TYPE;
01668                                                 zero_spectra(&alarm_spectra);
01669                                                 alarm_spectra.iType = ALARM_TYPE;
01670                                                 alarm_spectra.time = ring_buffer[ring_insertion_point].time;
01671                                                 alarm_spectra.iSize = ring_buffer[ring_insertion_point].iSize;
01672                                                 memcpy(alarm_spectra.status,ring_buffer[ring_insertion_point].status,BUF_SIZE);
01673                                                 int iExtractPoint;
01674                                                 print_to_log("Start of alarm."); 
01675                                                 for (i = 1; i <= pre_alarm; i++)
01676                                                 {
01677                                                         print_to_log("Pre-alarm spectra added to alarm spectra.");
01678                                                         iExtractPoint = ring_insertion_point-i;
01679                                                         if (iExtractPoint < 0) iExtractPoint += ring_size;
01680                                                         ring_buffer[iExtractPoint].iType = PREALARM_TYPE;
01681                                                         add_spectra(&alarm_spectra,&ring_buffer[iExtractPoint]);
01682                                                 }
01683                                         }
01684                                 }
01685                                 
01686                                 //create a bg spectra
01687                                 //if not in alarm and time for new background and have enough spectra to do bg
01688                                 //generate new background spectra based on current - pre-alarm - deadband + n of older spectra
01689                                 //set have bg
01690                                 //do peak search and save offset for alarm spectra
01691                                 //do re-bin to put into kEv
01692                                 //save bg
01693                                 if (!bInAlarm)
01694                                 {
01695                                         //do we have enough background potential spectra?
01696                                         int iTestPoint = ring_insertion_point;
01697                                         BOOL bNewBackground = TRUE;
01698                                         iTestPoint -= pre_alarm;
01699                                         iTestPoint -= dead_band;
01700                                         if (iTestPoint < 0) iTestPoint += ring_size;
01701                                         //check if the minimum number of spectra are available
01702                                         for (i=0; i<bg_minimum; i++)
01703                                         {
01704                                                 int iTemp = iTestPoint - i;
01705                                                 if (iTemp < 0) iTemp += ring_size;
01706                                                 if ((ring_buffer[iTemp].iType != BG_TYPE) && (ring_buffer[iTemp].iType != UNASSIGNED_TYPE))
01707                                                 {
01708                                                         bNewBackground = FALSE;
01709                                                         break; //break out of the for loop we don't have enough
01710                                                 }
01711                                         }
01712                                         if (bNewBackground)
01713                                         {
01714                                                 int iSpectraCount = 0;
01715                                                 time_t now;
01716                                                 zero_spectra(&tmp_spectra);
01717                                                 
01718                                                 tmp_spectra.time = ring_buffer[iTestPoint].time;
01719                                                 tmp_spectra.iSize = ring_buffer[iTestPoint].iSize;
01720                                                 tmp_spectra.iType = BG_TYPE;
01721                                                 
01722                                                 bg_spectra.time = ring_buffer[iTestPoint].time;
01723                                                 bg_spectra.iSize = spectraout_size;
01724                                                 
01725                                                 for (i = 0; i < BUF_SIZE; i++) bg_spectra.status[i] = ring_buffer[iTestPoint].status[i]; 
01726                                                 while (((ring_buffer[iTestPoint].iType == BG_TYPE) || 
01727                                                         (ring_buffer[iTestPoint].iType == UNASSIGNED_TYPE)) && 
01728                                                         (iSpectraCount < ring_size) && (iTestPoint != ring_insertion_point))
01729                                                 {
01730                                                         ring_buffer[iTestPoint].iType = BG_TYPE;
01731                                                         add_spectra(&tmp_spectra,&ring_buffer[iTestPoint]);
01732                                                         iTestPoint--;
01733                                                         if (iTestPoint < 0) iTestPoint += ring_size;
01734                                                         iSpectraCount++;
01735                                                 }
01736                                                 if (!bHaveBG)
01737                                                         print_to_log("Have Background");
01738                                                 bHaveBG = TRUE;
01739                                                 //re-bin for the number of bins
01740                                                 // shorty comment out//ReBIN(tmp_spectra.fspectra,
01741                                                 //shorty comment out//  tmp_spectra.iSize,rebin_spectra.fspectra,spectraout_size,
01742                                                 //shorty comment out//          (double)spectraout_size/(double)tmp_spectra.iSize,FALSE);
01743                                                 ReBIN(tmp_spectra.fspectra,tmp_spectra.iSize,rebin_spectra.fspectra,spectraout_size,
01744                                                 (double)spectraout_size/(double)tmp_spectra.iSize,FALSE); // shorty addition
01745                                                 //peak track
01746                                                 if (peaktrack_bin > 0)
01747                                                 {
01748                                                         fpeaktrack_offset = PeakTrack(rebin_spectra.fspectra, 
01749                                                                 spectraout_size, peaktrack_bin, peaktrack_roi, peaktrack_smooth);
01750                                                 }
01751                                                 else
01752                                                         fpeaktrack_offset = fpeaktrack_force;
01753                                                 //re-bin for the peak track
01754                                                 //shorty comment out//ReBIN(rebin_spectra.fspectra, 
01755                                                 //shorty comment out//  spectraout_size, bg_spectra.fspectra, spectraout_size, fpeaktrack_offset,FALSE);
01756                                                 ReBIN(rebin_spectra.fspectra, spectraout_size,bg_spectra.fspectra,spectraout_size, fpeaktrack_offset,FALSE); // shorty addition
01757                                                 bg_spectra.iType = BG_TYPE;
01758                                                 bg_spectra.iSize = spectraout_size;
01759                                                 bg_spectra.fDuration = tmp_spectra.fDuration;
01760                                                 bg_spectra.iSum = tmp_spectra.iSum;
01761                                                 bg_spectra.iSqSum = tmp_spectra.iSqSum;                                         
01762                                                 //if n time since last bg write then write bg
01763                                                 time(&now);
01764                                                 if ((now - bg_previous) > bg_period)
01765                                                 {
01766                                                         sprintf(s,"Current Peak Track Offset %f",fpeaktrack_offset);
01767                                                         print_to_log(s);
01768                                                         bg_previous = now;
01769                                                         send_spectra(&bg_spectra,szSpectraPathFile,fpeaktrack_offset);
01770                                                         print_spectra(&bg_spectra,szSpectraPathFile,fpeaktrack_offset);
01771                                                 }
01772                                         }
01773                                 }
01774                         }
01775                                 
01776                         //if in alarm and post alarm count <= post alarm desired
01777                                 //add current to alarm spectra
01778                                 //decrement post alarms 
01779                                 //if post alarm count == post alarm desired
01780                                         //re-bin to bg spectra offset using computed and saved peak offset
01781                                         //print out the spectra 
01782                                         //log event
01783                         if (bInAlarm) //we are currently in an alarm situation
01784                         {
01785                                 //add the current spectra if needed
01786                                 if (iPostAlarmCount <= post_alarm)
01787                                 {
01788                                         add_spectra(&alarm_spectra,&ring_buffer[ring_insertion_point]);
01789                                         ring_buffer[ring_insertion_point].iType = (iPostAlarmCount==0)?ALARM_TYPE:POSTALARM_TYPE;
01790                                         print_to_log("Current spectra added to alarm spectra.");
01791                                 }
01792                                 //see if we have enough to stop adding spectra
01793                                 if (iPostAlarmCount == post_alarm)
01794                                 {
01795                                         time_t temptime;
01796                                         //re-bin to the output size
01797                                         ReBIN(alarm_spectra.fspectra,
01798                                                 alarm_spectra.iSize,
01799                                                 tmp_spectra.fspectra,
01800                                                 spectraout_size,
01801                                                 (double)spectraout_size/(double)alarm_spectra.iSize,
01802                                                 FALSE); // 
01803                                         //re-bin to the peaktrack_offset
01804                                         if (peaktrack_bin <= 0)
01805                                                 fpeaktrack_offset = fpeaktrack_force; 
01806                                         // shorty comment out ReBIN(alarm_spectra.fspectra, 
01807                                         // shorty comment out   alarm_spectra.iSize, tmp_spectra.fspectra, spectraout_size, fpeaktrack_offset,FALSE);
01808                                         ReBIN(tmp_spectra.fspectra, 
01809                                                 tmp_spectra.iSize, 
01810                                                 rebin_spectra.fspectra, 
01811                                                 spectraout_size, 
01812                                                 fpeaktrack_offset,
01813                                                 FALSE); // shorty addition
01814                                         //clear out the full memory
01815                                         memset(alarm_spectra.fspectra,0,sizeof(alarm_spectra.fspectra));
01816                                         //copy the rebin data back into the alarm spectra
01817                                         // shorty comment out memcpy(alarm_spectra.fspectra,tmp_spectra.fspectra,spectraout_size*sizeof(double));
01818                                         memcpy(alarm_spectra.fspectra,rebin_spectra.fspectra,spectraout_size*sizeof(double)); // shorty addition
01819                                         alarm_spectra.iSize=spectraout_size;
01820                                         //print out the alarm spectra
01821                                         send_spectra(&alarm_spectra,szAlarmPathFile,fpeaktrack_offset);                                 
01822                                         print_spectra(&alarm_spectra,szAlarmPathFile,fpeaktrack_offset);
01823                                         //print out the background spectra
01824                                         temptime = bg_spectra.time;
01825                                         bg_spectra.time = alarm_spectra.time;
01826                                         send_spectra(&bg_spectra,szAlarmBGPathFile,fpeaktrack_offset);                                  
01827                                         print_spectra(&bg_spectra,szAlarmBGPathFile,fpeaktrack_offset);
01828                                         bg_spectra.time = temptime;
01829                                         if (peaktrack_bin > 0)
01830                                         {
01831                                                 sprintf(s,"Peak Track Offset Used: %f",fpeaktrack_offset);
01832                                                 print_to_log(s);
01833                                         }
01834                                         //print_to_log("Alarm and Background spectra printed.");        
01835                                 }
01836                                 //if past post alarms and bg is down then drop out of alarm status
01837                                 else if (iPostAlarmCount > post_alarm)
01838                                 {
01839                                         mux=bg_spectra.iSum/(bg_spectra.fDuration/1000);        // bjb addition
01840                                         sigx=sqrt(bg_spectra.iSum/(bg_spectra.fDuration/1000));  // bjb addition
01841                                         
01842                                         if (iPostAlarmCount > force_noalarm)
01843                                         {
01844                                                 bInAlarm = FALSE;
01845                                                 iPostAlarmCount = 0;
01846                                                 bHaveBG = FALSE;
01847                                                 print_to_log("Forced out of alarm status. Building new BG.");
01848                                         }       
01849                                         else if (ring_buffer[ring_insertion_point].iSum/(ring_buffer[ring_insertion_point].fDuration/1000) <= bg_spectra.iSum/(bg_spectra.fDuration/1000) + sigma_alarm*sqrt(bg_spectra.iSum/(bg_spectra.fDuration/1000))/sqrt(ring_buffer[ring_insertion_point].fDuration/1000))                                       
01850 //                                      else if (ring_buffer[ring_insertion_point].iSum/(ring_buffer[ring_insertion_point].fDuration/1000) <= mux+sigma_alarm*sigx) // bjb addition
01851                                         // bjb addition// else if ((bg_spectra.iSum/bg_spectra.fDuration+sigma_alarm*sqrt(bg_spectra.iSum)/bg_spectra.fDuration) > ring_buffer[ring_insertion_point].iSum/ring_buffer[ring_insertion_point].fDuration)
01852                                         // else if (sqrt((ring_buffer[ring_insertion_point].iSum/ring_buffer[ring_insertion_point].fDuration) /
01853                                         // sqrt(bg_spectra.iSum / bg_spectra.fDuration) < sigma_alarm))
01854                                         {
01855                                                 bInAlarm = FALSE;
01856                                                 iPostAlarmCount = 0;
01857                                                 print_to_log("Normal out of alarm status. Keeping old BG.");
01858                                         }       
01859                                 }       
01860                                 //make sure we've gone beyond this if -- only do it once
01861                                 iPostAlarmCount++;
01862                         }
01863                                 
01864                         //point to the next in the ring buffer
01865                         ring_insertion_point = (ring_insertion_point + 1) % ring_size;
01866                         //keep track of how many we have in the buffer
01867                         //'cause we don't want to try to use spectra that aren't there
01868                         if (ring_count < ring_size) ring_count++;
01869                         
01870                 }
01871                 else
01872                 {
01873                         //put errors in the log file
01874                         sprintf(s,"ERROR: read SPECTRA (%d) failed",iResult);
01875                         print_to_log(s);
01876                         exit(-1);
01877                 }
01878         }
01879         //close the spectra file
01880         if (outfile)
01881                 fclose(outfile);
01882   }//repeat forever
01883 
01884   //actually the os will do these for us
01885   usb_release_interface(dev, 0);
01886   usb_close(dev);
01887 
01888   return 0;
01889 }


© 2007, Los Alamos National Security, LLC.