//-------------------------------------------------------- // tscalring_main.C // // Analysis of data from ROC10 and ROC11. // The ROC to find scalers are : 10/11 = R/L. // R. Michaels, Jan 2003 // See also http://www.jlab.org/~rom/scaler_roc10.html //-------------------------------------------------------- // To printout (1) or not (0). This is for debug. #define PRINTOUT 0 // To get 6 data from Ring or 5. If defined, we read 6, otherwise // comment this out and we'll read 5 (for data prior to Jan 9, '03, // see also halog 91208). BTW, if this is set wrong you'll see messages // about "DISASTER: The helicity is wrong !!" but they are fake. #define READ6 #define NBCM 6 #define MAXRING 20 #define BCM_CUT1 1000 // cut on BCM (x1 gain) to require beam on. #define BCM_CUT3 3000 // cut on BCM (x3 gain) to require beam on. #define BCM_CUT10 7000 // cut on BCM (x10 gain) to require beam on. #include #include #include "THaCodaFile.h" #include "THaEvData.h" #include "THaScaler.h" #ifndef __CINT__ #include "TROOT.h" #include "TFile.h" #include "TH1.h" #include "TH2.h" #include "TProfile.h" #include "TNtuple.h" #include "TRandom.h" #endif using namespace std; int loadHelicity(); int ranBit(unsigned int& seed); unsigned int getSeed(); void resetSums(); int incrementSums(int helicity_now, double prev_clock, double prev_trig, double prev_bcm, double prev_l1a); // Global variables -------------------------------------- #define NBIT 24 int hbits[NBIT]; // The NBIT shift register int present_reading; // present reading of helicity int predicted_reading; // prediction of present reading (should = present_reading) int present_helicity; // present helicity (using prediction) #define NDELAY 2 // number of quartets between // present reading and present helicity // (i.e. the delay in reporting the helicity) int recovery_flag = 0; // flag to determine if we need to recover // from an error (1) or not (0) unsigned int iseed; // value of iseed for present_helicity unsigned int iseed_earlier; // iseed for predicted_reading // Ring buffer sums, avg over ~2 sec, sorted by 2 helicities (index) double rsum_clk[2],rsum_bcm[2],rsum_trig[2],rsum_l1a[2]; double rsum_num[2]; double corr_bcm0, corr_bcm1, ringped[2]; int main(int argc, char* argv[]) { int myroc, iev, nevents; int trig, clkp, clkm, lastclkp, lastclkm; Float_t time, sum, asy; int helicity, qrt, gate, timestamp; int len, data, status, nscaler, header; int numread, badread, i, jstat; int ring_clock, ring_qrt, ring_helicity; int ring_trig, ring_bcm, ring_l1a, ring_hel2; int prev_clock, prev_trig, prev_bcm, prev_l1a, prev_hel2; int sum_clock, sum_trig, sum_bcm, sum_l1a; int latest_clock, latest_trig, latest_bcm, latest_l1a; int inquad, nrread, q1_helicity, helicity_now; int ring_data[MAXRING], rloc; string filename, bank, mybank; if (argc < 3) { cout << "Usage: " << argv[0]<<" file bank [nevents]" << endl; cout << "where file = CODA file to analyze " << endl; cout << "and bank = 'Right', 'Left' (spectrometer)" << endl; cout << "and nevents is the number of events you want (optional)"<= 4) nevents = atoi(argv[3]); cout << "bank "<Init("1-1-2003") == -1) { cout << "Error initializing scaler object. "<codaRead(); if (status != 0) break; evdata.LoadEvent(coda->getEvBuffer()); len = evdata.GetRocLength(myroc); if (nevents > 0 && iev++ > nevents) goto finish; if (len <= 4) continue; if (evdata.GetEvType() == 140) continue; scaler->LoadData(evdata); if ( !scaler->IsRenewed() ) continue; memset(farray_ntup, 0, (nlen+1)*sizeof(Float_t)); // Having loaded the scaler object, we pull out what we can from it. // Note, we must average the two helicities to get non-helicity rates because ROC10/11 // data only have helicity scalers. (In contrast, event type 140 has all scalers.) time = (scaler->GetPulser(1,"clock") + scaler->GetPulser(-1,"clock"))/1024; latest_clock = (scaler->GetPulser(1,"clock") + scaler->GetPulser(-1,"clock")); if (myroc == 11) { latest_trig = (scaler->GetTrig(1,3) + scaler->GetTrig(-1,3)); } else { latest_trig = (scaler->GetTrig(1,1) + scaler->GetTrig(-1,1)); } latest_bcm = (scaler->GetBcm(1,"bcm_u3") + scaler->GetBcm(-1,"bcm_u3")); latest_l1a = (scaler->GetNormData(1,"TS-accept") + scaler->GetNormData(-1,"TS-accept")); if (PRINTOUT) cout << dec << "latest data "<GetBcmRate(1,"bcm_u1") + scaler->GetBcmRate(-1,"bcm_u1")); farray_ntup[2] = 0.5*(scaler->GetBcmRate(1,"bcm_u3") + scaler->GetBcmRate(-1,"bcm_u3")); farray_ntup[3] = 0.5*(scaler->GetBcmRate(1,"bcm_u10") + scaler->GetBcmRate(-1,"bcm_u10")); farray_ntup[4] = 0.5*(scaler->GetBcmRate(1,"bcm_d1") + scaler->GetBcmRate(-1,"bcm_d1")); farray_ntup[5] = 0.5*(scaler->GetBcmRate(1,"bcm_d3") + scaler->GetBcmRate(-1,"bcm_d3")); farray_ntup[6] = 0.5*(scaler->GetBcmRate(1,"bcm_d10") + scaler->GetBcmRate(-1,"bcm_d10")); for (trig = 1; trig <= 5; trig++) { farray_ntup[6+trig] = 0.5*(scaler->GetTrigRate(1,trig) + scaler->GetTrigRate(-1,trig)); } if (PRINTOUT == 1 && len >= 16) { scaler->Print(); for (i = 0; i < 6; i++) cout << " bcm -> "< "<GetNormData(1,"clock"); clkm = scaler->GetNormData(-1,"clock"); farray_ntup[12] = clkp - lastclkp; farray_ntup[13] = clkm - lastclkm; lastclkp = clkp; lastclkm = clkm; farray_ntup[14] = 0.5*(scaler->GetNormRate(1,"TS-accept") + scaler->GetNormRate(-1,"TS-accept")); string bcms[] = {"bcm_u1", "bcm_u3", "bcm_u10", "bcm_d1", "bcm_d3", "bcm_d10"}; // // Next we construct the helicity correlated asymmetries. // for (int ibcm = 0; ibcm < 6; ibcm++ ) { sum = scaler->GetBcmRate(1,bcms[ibcm].c_str()) - bcmped[ibcm] + scaler->GetBcmRate(-1,bcms[ibcm].c_str()) - bcmped[ibcm]; asy = -999; if (sum != 0) { asy = (scaler->GetBcmRate(1,bcms[ibcm].c_str()) - scaler->GetBcmRate(-1,bcms[ibcm].c_str())) / sum; } farray_ntup[15+ibcm] = asy; } for (trig = 1; trig <= 5; trig++) { asy = -999; if (scaler->GetBcmRate(1,"bcm_u3") > BCM_CUT3 && scaler->GetBcmRate(-1,"bcm_u3") > BCM_CUT3) { sum = scaler->GetTrigRate(1,trig)/scaler->GetBcmRate(1,"bcm_u3") + scaler->GetTrigRate(-1,trig)/scaler->GetBcmRate(-1,"bcm_u3"); if (sum != 0) { asy = (scaler->GetTrigRate(1,trig)/scaler->GetBcmRate(1,"bcm_u3") - scaler->GetTrigRate(-1,trig)/scaler->GetBcmRate(-1,"bcm_u3")) / sum; } } farray_ntup[20+trig] = asy; } sum = scaler->GetPulser(1,"clock") + scaler->GetPulser(-1,"clock"); asy = -999; if (sum != 0) { asy = (scaler->GetPulser(1,"clock") - scaler->GetPulser(-1,"clock")) / sum; } farray_ntup[26] = asy; // // Next we ignore the scaler object and obtain data directly from the event. // data = evdata.GetRawData(myroc,3); helicity = (data & 0x10) >> 4; qrt = (data & 0x20) >> 5; gate = (data & 0x40) >> 6; timestamp = evdata.GetRawData(myroc,4); data = evdata.GetRawData(myroc,5); nscaler = data & 0x7; // if (evdata.GetEvType() == 9) cout << "Ev 9 qrt "< 2) nscaler = 2; // shouldn't be necessary // 32 channels of scaler data for two helicities. if (PRINTOUT) cout << "Synch event ----> " << endl; for (int ihel = 0; ihel < nscaler; ihel++) { header = evdata.GetRawData(myroc,index++); if (PRINTOUT) { cout << "Scaler for helicity = " << dec << ihel; cout << " unique header = " << hex << header << endl; } for (int ichan = 0; ichan < 32; ichan++) { data = evdata.GetRawData(myroc,index++); if (PRINTOUT) { cout << "channel # " << dec << ichan+1; cout << " (hex) data = " << hex << data << endl; } } } numread = evdata.GetRawData(myroc,index++); badread = evdata.GetRawData(myroc,index++); if (PRINTOUT) cout << "FIFO num of last good read " << dec << numread << endl; if (badread != 0) { cout << "DISASTER: There are bad readings " << endl; cout << "FIFO num of last bad read " << endl; } // Ring buffer analysis: analyze subset of scaler channels in 30 Hz ring buffer. int nring = 0; while (index < len && nring == 0) { header = evdata.GetRawData(myroc,index++); if ((header & 0xffff0000) == 0xfb1b0000) { nring = header & 0x3ff; } } if (PRINTOUT) cout << "Num in ring buffer = " << dec << nring << endl; // The following assumes three are (now 6) pieces of data per 'iring' for (int iring = 0; iring < nring; iring++) { ring_clock = evdata.GetRawData(myroc,index++); data = evdata.GetRawData(myroc,index++); ring_qrt = (data & 0x10) >> 4; ring_helicity = (data & 0x1); present_reading = ring_helicity; if (ring_qrt) { inquad = 1; if (loadHelicity()) { // cout << "CHECK HEL "<Fill(farray2); resetSums(); } prev_clock = ring_clock; prev_trig = ring_trig; prev_bcm = ring_bcm; prev_l1a = ring_l1a; // Empirical check of delayed helicity scheme. ring_data[rloc%MAXRING] = ring_bcm; if (inquad == 1 && nrread++ > 12) { farray_ntup[27] = (float)nrread; // need to cut that this is >0 in analysis farray_ntup[28] = ring_clock; farray_ntup[29] = ring_trig; farray_ntup[30] = ring_bcm; farray_ntup[31] = ring_l1a; farray_ntup[32] = (float)present_reading; farray_ntup[33] = (float)present_helicity; for (int ishift = 3; ishift <= 12; ishift++) { Float_t pdat = ring_data[(rloc-ishift)%MAXRING]; Float_t mdat = ring_data[(rloc-ishift+1)%MAXRING]; Float_t sum = pdat + mdat; Float_t asy = 99999; if (sum != 0) { if (present_reading == 1) { asy = (pdat - mdat)/sum; } else { asy = (mdat - pdat)/sum; } } // ishift = 9 is the correct one. (should be 8, but the helicity // bits are one cycle out of phase w.r.t. data) farray_ntup[31+ishift] = asy; if (PRINTOUT) cout << "shift "<Fill(farray_ntup); rloc++; if (PRINTOUT) { cout << "buff [" << dec << iring << "] "; cout << " clock " << ring_clock << " qrt " << ring_qrt; cout << " helicity " << ring_helicity<<" 2nd hel "<= 0; i--) ranseed = ranseed<<1|(seedbits[i]&1); ranseed = ranseed&0xFFFFFF; return ranseed; } // ************************************************************* // // Increment the sums from the ring buffer, sorted by helicity // returns: // 0 = continue // 1 = time to fill ntuple and zero the counters. // // ************************************************************* int incrementSums(int helicity_now, double clock, double trig, double bcm, double l1a) { if (helicity_now < 0 || helicity_now > 1) { cout << "ERROR: illegal helicity value in incrementSums()"<= 30 && rsum_num[1] >= 30) return 1; return 0; } void resetSums() { memset(rsum_clk, 0, 2*sizeof(double)); memset(rsum_bcm, 0, 2*sizeof(double)); memset(rsum_trig, 0, 2*sizeof(double)); memset(rsum_l1a, 0, 2*sizeof(double)); memset(rsum_num, 0, 2*sizeof(double)); return; }