/*==> rate.c =================================================== calculate the rates,.. measured by scalers !! -> measures the TaCoS-system time !!! ----------------------------------------------------------- */ /*=== includes ============================================== */ #include /* -> usleep*/ #include /* -> fabs and simu*/ #include /* -> rand */ #include /* -> MAX*/ #include "rate.h" #include "rsimu.h" #include "dev/scalers.h" #include "target/main/target.h" /* for rate simu */ #include "target/main/threads.h" /* for rate simu */ /*=== defines =============================================== */ #define RATE_BG 7 #define RATE_REF_RATE 0 #define RATE_REF_FREQ 10.416667L /*MHz*/ /*=== structs =============================================== */ struct sc_data { struct timespec time; scaler_t value[NETRATE_NUM_RATES]; }; struct sc_data_diff { int time; /* time difference in usec */ scaler_t value[NETRATE_NUM_RATES]; }; typedef struct { struct sc_data old; struct sc_data new; struct sc_data_diff diff; } scaler_val_t; /* a buffer to remember the last n readouts of the charge Integrator rates */ /* 10 Hz readout is too much for this statistics */ #define R_NUM_WRRATES 20 typedef struct { rate_t rate[NP_NUM_WIRES][R_NUM_WRRATES]; /* at each position ill have the (rate at this wire)/R_NUM_CIRATES in MHz*/ int pos; /* actual position in the buffer*/ rate_t pedestal[NP_NUM_WIRES]; /* for calculating the real IA rate at the wire*/ double calf[NP_NUM_WIRES]; /* calibration factor */ int rpos[NP_NUM_WIRES]; /* positions, where the rates can be found */ } wrate_t; /* this structure will contain the information need to compute the first derivatives of the rate-"function" */ typedef struct { int pos; rate_t rate[NETRATE_NUM_DRSLICES]; rate_t srateq[NETRATE_NUM_DRSLICES]; rate_t s1, s2, s3, s4, s5; drate_t dr; } drateh_t; /*=== variables ============================================= */ /* general options for rate.c */ rate_t *Acc; int Testrun; int Debugmode; int Use_ref_rate; the_rates_t Rate; /* Scaler values for calculating the rates */ scaler_val_t Scaler; /* single wire rate calculation structure */ wrate_t WR; drateh_t DR; /*=== missing system prototypes ============================= */ /*--- init-rates() ---------------------------------------- initializes the scalers and fills the rate structures with the first values returns: void ------------------------------------------------------- */ void init_rates(int testrun, int use_ref_rate, rate_t *acc, data_t *d) { int i, j; Acc = acc; init_rsimu(); Use_ref_rate = use_ref_rate; Testrun = testrun; Rate.integrated_ia = 0; Rate.ia_mean = 0.0; Rate.sigma_mean = 0.0; WR.pos = 0; for(i=0; i=0; i--) { xds = tt/DR.srateq[i]; DR.s1 += 1/DR.srateq[i]; DR.s2 += DR.rate[i]*xds; DR.s3 += DR.rate[i]/DR.srateq[i]; DR.s4 += xds; DR.s5 += tt*xds; tt--; } for(i=d->autom.dr_slices-1; i>DR.pos; i--) { xds = tt/DR.srateq[i]; DR.s1 += 1/DR.srateq[i]; DR.s2 += DR.rate[i]*xds; DR.s3 += DR.rate[i]/DR.srateq[i]; DR.s4 += xds; DR.s5 += tt*xds; tt--; } nen = (DR.s1*DR.s5 - DR.s4*DR.s4); DR.dr.a = (DR.s1*DR.s2 - DR.s3*DR.s4) / nen; DR.dr.b = (DR.s5*DR.s3 - DR.s4*DR.s2) / nen; DR.dr.sa = sqrt(DR.s1/nen); DR.dr.sb = sqrt(DR.s5/nen); /*print_scrollX("%3d>> a: %5.2g/%5.2g | b: %5.2g/%5.2g | nen: %5.2g | s: %5.2g - %5.2g - %5.2g - %5.2g - %5.2g", DR.pos, DR.dr.a, DR.dr.sa, DR.dr.b, DR.dr.sb, nen, DR.s1, DR.s2, DR.s3, DR.s4, DR.s5);*/ } /*--- update_rates() ------------------------------------------ measures the rates,.. defines the TaCoS-systemtime,.. calculates some rates and rate relevant stuff _and_ checks for a overall emergency,.. the actual time for the _whole_ TaCoS(target) system is the time measured right before reading out the scalers,.. ---------------------------------------------------------- */ void update_rates(data_t *d) { int i, j, tt, tc; rate_t helper; /* set the new target-system time */ getclock(TIMEOFDAY, &Scaler.new.time); d->time = Scaler.new.time; if(!Testrun) { /* !!!!!!!!!!!!! REAL RUNNING !!!!!!!!!!!!!!!! */ for(i=0; iautom.timeco; /* calculate the integrated interaction rate,.. -> lumi (Hz*sec)*/ Rate.integrated_ia += (intrate_t) (Rate.ia * Scaler.diff.time); /* Calculate the mean of the measured rate */ Rate.ia_mean = Rate.ia * (((double) 1)/((double)tc)) + Rate.ia_mean * (((double)tc-1)/((double)tc)); /* Calculate the sigma of the measured rate,.. and its mean */ Rate.sigma = fabs(Rate.ia - Rate.ia_mean); Rate.sigma_mean = Rate.sigma * (((double) 1)/((double)tc)) + Rate.sigma_mean * (((double)tc-1)/((double)tc)); /*---------------------------------------------------------*/ /* single wire rates calculation */ for(i=0; i filling of the array */ DR.pos++; if(DR.pos>d->autom.dr_slices-1) { DR.pos = 0; } tt = 0; DR.rate[DR.pos] = Rate.ia; for(i=DR.pos; iautom.dr_slices; i++) { DR.srateq[i] = (rate_t) ((double)DR.rate[i]*d->autom.dr_factor* (double)((double)((double)d->autom.dr_offset+(double)tt)/(double)d->autom.dr_slices)); DR.srateq[i] *= DR.srateq[i]; tt++; } for(i=0; iautom.dr_factor* (double)((double)((double)d->autom.dr_offset+(double)tt)/(double)d->autom.dr_slices)); DR.srateq[i] *= DR.srateq[i]; tt++; } /*print_scrollX("%f - %g", DR.rate[DR.pos], DR.srateq[DR.pos]);*/ calc_dr(d); Rate.dr = DR.dr; /* return back the rates*/ d->rate = Rate; /* fill in the 'old'-structure */ Scaler.old.time = Scaler.new.time; for(i=0; i