Int_t THaScaler::LoadData(const THaEvData& evdata) { // Load data from THaEvData object. Return of 0 is ok. // Note: GetEvBuffer is no faster than evdata.Get... static int ldebug = 0; static Int_t data[2*SCAL_NUMBANK*SCAL_NUMCHAN+100]; new_load = kFALSE; Int_t nlen = 0; if (evstr_type == 1) { // data in the event stream (physics triggers) if (!evdata.IsPhysicsTrigger()) return 0; nlen = evdata.GetRocLength(crate); if (nlen == 0) return 0; } else { // traditional scaler event type 140 if (evdata.GetEvType() != 140) return 0; nlen = evdata.GetEvLength(); } if (ldebug) cout << "Loading evdata, bank = "<<bankgroup<<" "<<evstr_type<<" "<<crate<<" "<<evdata.GetEvType()<<" "<<nlen<<endl; Int_t maxlen = sizeof(data)/sizeof(Int_t); if (nlen > maxlen) nlen = maxlen; for (Int_t i = 0; i < nlen; i++) { if (evstr_type == 1) { data[i] = evdata.GetRawData(crate, i); } else { data[i] = evdata.GetRawData(i); } if (ldebug) { cout << " data["<<i<<"] = "<<data[i]<<" =0x"<<hex<<data[i]<<dec<<endl; } } ExtractRaw(data,nlen); return 0; };
//____________________________________________________________________ Int_t THaQWEAKHelicityReader::FindWord( const THaEvData& evdata, const ROCinfo& info ) // find the index of the word we are looking for given a header // or simply return the index already stored in ROC info (in that case // the header stored in ROC info needs to be 0 { Int_t len = evdata.GetRocLength(info.roc); if (len <= 4) return -1; Int_t i; if( info.header == 0 ) i = info.index; else { for( i=0; i<len && (evdata.GetRawData(info.roc, i) & 0xffff000) != info.header; ++i) {} i += info.index; } return (i < len) ? i : -1; }
//_____________________________________________________________________________ void WordLoc::Load( const THaEvData& evdata ) { // Load data at header/notoskip position from crate data buffer typedef const UInt_t rawdata_t; Int_t roclen = evdata.GetRocLength(crate); if( roclen < ntoskip+1 ) return; rawdata_t* cratebuf = evdata.GetRawDataBuffer(crate), *endp = cratebuf+roclen; assert(cratebuf); // Must exist if roclen > 0 // Accelerated search for the header word. Coded explicitly because there // is no "memstr" in the standard library. //FIXME: Can this be made faster because each header is followed by the offset // to the next header? // Get the first byte of the header, regardless of byte order int h = ((UChar_t*)&header)[0]; rawdata_t* p = cratebuf; while( (p = (rawdata_t*)memchr(p,h,sizeof(rawdata_t)*(endp-p-1)+1)) && p <= endp-ntoskip-1 ) { // The header must be aligned at a word boundary int off = (p-cratebuf) & (sizeof(rawdata_t)-1); // same as % sizeof() if( off != 0 ) { p += sizeof(rawdata_t)-off; continue; } // Compare all 4 bytes of the header word if( memcmp(p,&header,sizeof(rawdata_t)) == 0 ) { // Fetch the requested word (as UInt_t, i.e. 4 bytes) // BTW, notoskip == 0 makes no sense since it would fetch the header itself data = *(p+ntoskip); break; } p += sizeof(rawdata_t); } }
//____________________________________________________________________ Int_t THaQWEAKHelicityReader::ReadData( const THaEvData& evdata ) { // Obtain the present data from the event for QWEAK helicity mode. static const char* here = "THaQWEAKHelicityReader::ReadData"; // std::cout<<" kHel, kTime, kRing="<< kHel<<" "<<kTime<<" "<<kRing<<endl; // for (int jk=0; jk<3; jk++) // { // std::cout<<" which="<<jk // <<" roc="<<fROCinfo[jk].roc // <<" header="<<fROCinfo[jk].header // <<" index="<<fROCinfo[jk].index // <<endl; // } // std::cout<<" fHaveROCs="<<fHaveROCs<<endl; if( !fHaveROCs ) { ::Error( here, "ROC data (detector map) not properly set up." ); return -1; } Int_t hroc = fROCinfo[kHel].roc; Int_t len = evdata.GetRocLength(hroc); if (len <= 4) return -1; Int_t ihel = FindWord( evdata, fROCinfo[kHel] ); if (ihel < 0) { ::Error( here , "Cannot find helicity" ); return -1; } Int_t data = evdata.GetRawData( hroc, ihel ); fPatternTir =(data & 0x20)>>5; fHelicityTir=(data & 0x10)>>4; fTSettleTir =(data & 0x40)>>6; hroc=fROCinfo[kTime].roc; len = evdata.GetRocLength(hroc); if (len <= 4) { ::Error( here, "length of roc event not matching expection "); return -1; } Int_t itime = FindWord (evdata, fROCinfo[kTime] ); if (itime < 0) { ::Error( here, "Cannot find timestamp" ); return -1; } fTimeStampTir=static_cast<UInt_t> (evdata.GetRawData( hroc, itime )); // Invert the gate polarity if requested // if( fNegGate ) // fGate = !fGate; hroc=fROCinfo[kRing].roc; len = evdata.GetRocLength(hroc); if (len <= 4) { ::Error( here, "length of roc event not matching expection (message 2)"); // std::cout<<" len ="<<len<<endl; // std::cout<<"kRING="<<kRing<<" hroc="<<hroc<<endl; return -1; } Int_t index=0; while (index < len && fIRing == 0) { Int_t header=evdata.GetRawData(hroc,index++); if ((header & 0xffff0000) == 0xfb1b0000) { fIRing = header & 0x3ff; } } // std::cout<<" fIRing ="<<fIRing<<" index="<<index<<endl; if(fIRing>kHelRingDepth) { ::Error( here, "Ring depth to large "); return -1; } for(int i=0;i<fIRing; i++) { fTimeStampRing[i]=evdata.GetRawData(hroc,index++); data=evdata.GetRawData(hroc,index++); fHelicityRing[i]=(data & 0x1); fPatternRing[i]= (data & 0x10)>>4; fT3Ring[i]=evdata.GetRawData(hroc,index++); fU3Ring[i]=evdata.GetRawData(hroc,index++); fT5Ring[i]=evdata.GetRawData(hroc,index++); fT10Ring[i]=evdata.GetRawData(hroc,index++); } // Print(); FillHisto(); return 0; }
//_____________________________________________________________________________ void RoclenLoc::Load( const THaEvData& evdata ) { // Get event length for this crate data = evdata.GetRocLength(crate); }
int main(int argc, char* argv[]) { int myroc, iev, nevents; int trig, clkp, clkm, lastclkp, lastclkm; Float_t time, sum, asy; int found,index; int len, data, status, nscaler, header; int numread0, numread1, badread, i, jstat; int ring_clock, ring_qrt, ring_helicity; int ring_t3, ring_bcm, ring_l1a, ring_t1; int prev_clock, prev_trig, prev_bcm, prev_l1a, prev_hel2; int sum_clock, sum_t3, 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 < 2) { cout << "Usage: " << argv[0]<<" file [nevents]" << endl; cout << "where file = CODA file to analyze " << endl; cout << "and nevents is the number of events you want (optional)"<<endl; cout << "(default nevents = all of them)"<<endl; return 1; } filename = argv[1]; mybank = "evgen"; myroc = 23; nevents = 0; if (argc >= 3) nevents = atoi(argv[3]); cout << "bank "<<mybank<<" num events "<<nevents<<endl; // Pedestals. Left, Right Arms. u1,u3,u10,d1,d3,d10 Float_t bcmpedL[NBCM] = { 188.2, 146.2, 271.6, 37.8, 94.2, 260.2 }; Float_t bcmpedR[NBCM] = { 53.0, 41.8, 104.1, 0., 101.6, 254.6 }; Float_t bcmped[NBCM]; // Pedestals for Ring buffer analysis // L-arm tuned from run e01012_20288, R-arm from e01012_1288 Float_t ringpedL[2] = { 112.2, 112.2 }; Float_t ringpedR[2] = { 112.2, 112.2 }; Float_t ringped[2]; if (myroc == 23) { cout << "Using Left Arm BCM pedestals (for now) "<<endl; for (i = 0; i < NBCM; i++) { bcmped[i] = bcmpedL[i]; } for (i = 0; i < 2; i++) ringped[i] = ringpedL[i]; } else { cout << "Using Right Arm BCM pedestals"<<endl; for (i = 0; i < NBCM; i++) { bcmped[i] = bcmpedR[i]; } for (i = 0; i < 2; i++) ringped[i] = ringpedR[i]; } // Scaler object to extract data using scaler.map. // WARNING: bank = "Left" goes with event type 140 data, // while "EvLeft" goes with ROC11 data. Similarly "Right", "EvRight". THaScaler *scaler = new THaScaler(mybank.c_str()); if (scaler->Init("3-1-2006") == -1) { cout << "Error initializing scaler object. "<<endl; return 1; } // Initialize root and output. TROOT scalana("scalroot","Hall A scaler analysis"); TFile hfile("scaler.root","RECREATE","Scaler data in Hall A"); // Define the ntuple here. Part of the ntuple is filled from scaler // object (scal_obj) and part is from event data (evdata). // If you add a variable, I suggest you keep track of the indices the same way. // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 char scal_obj_rawrates[]="time:u1:u3:u10:d1:d3:d10:t1:t2:t3:t4:t5:clkp:clkm:tacc:"; // 15 16 17 18 19 20 21 22 23 24 25 26 char scal_obj_asymmetries[]="au1:au3:au10:ad1:ad3:ad10:at1:at2:at3:at4:at5:aclk:"; // 27 28 29 30 31 32 33 char evdata_rawrates[]="evt:evclk:evtrig:evbcm:evl1a:evmhel:evphel:"; // Asymmetries delayed various amounts, using RING BUFFER. The correct // one is presumably the one delayed by NDELAY quads, but we need to check. // 34 35 36 37 38 39 40 41 42 43 char asydelay[]="a3d1:a3d2:a3d3:a3d4:a3d5:a3d6:a3d7:a3d8:a3d9:a3d10"; int nlen = strlen(scal_obj_rawrates) + strlen(scal_obj_asymmetries) + strlen(evdata_rawrates) + strlen(asydelay); char *string_ntup = new char[nlen+1]; strcpy(string_ntup, scal_obj_rawrates); strcat(string_ntup, scal_obj_asymmetries); strcat(string_ntup, evdata_rawrates); strcat(string_ntup,asydelay); TNtuple *ntup = new TNtuple("ascal","Scaler Rates",string_ntup); Float_t* farray_ntup = new Float_t[nlen+1]; // 2nd ntuple for 1-sec averaged ring buffer // 0 1 2 3 4 5 6 7 8 9 10 11 char ring_rates[]="evt:clkp:clkm:clk:bcmp:bcmm:bcm:trig:l1a:nump:numm:num:aclk:abcm:atrig:al1a"; //12 13 14 15 TNtuple *rnt = new TNtuple("aring","Ring values", ring_rates); Float_t *farray2 = new Float_t[16]; THaCodaFile *coda = new THaCodaFile(TString(filename.c_str())); THaEvData *evdata = new THaCodaDecoder(); inquad = 0; q1_helicity = 0; rloc = 0; status = 0; sum_clock = 0; sum_t3 = 0; sum_bcm = 0; sum_l1a = 0; prev_clock = 0; prev_trig = 0; prev_bcm = 0; prev_l1a = 0; prev_hel2 = 0; lastclkp = 0; lastclkm = 0; nrread = 0; iev = 0; resetSums(); while (status == 0) { status = coda->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 ROC23 // 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")); latest_trig = (scaler->GetTrig(1,3) + scaler->GetTrig(-1,3)); 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 "<<latest_clock<<" "<<latest_trig<<" "<<latest_bcm<<" "<<latest_l1a<<endl; farray_ntup[0] = time; farray_ntup[1] = 0.5*(scaler->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 -> "<<farray_ntup[i]; cout << endl << endl; for (i = 0; i < 5; i++) cout << " trig -> "<<farray_ntup[i+7]; cout << endl << endl; } clkp = scaler->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. // found = 0; index = 0; while ( !found ) { data = evdata->GetRawData(myroc,index++); if ( (data & 0xffff0000) == 0xfb0b0000) found = 1; if (PRINTOUT) cout << "evbuffer["<<index-1<<"] = 0x"<<hex<<data<<" = (dec) "<<dec<<data<<endl; if (index >= len) break; } if (!found) continue; nscaler = data & 0x7; // if (evdata->GetEvType() == 9) cout << "Ev 9 qrt "<<qrt<<" helicity "<<helicity<<" gate "<<gate<<" timestamp "<<timestamp<<endl; if (PRINTOUT) { cout << "nscaler in this event " << nscaler << endl; } if (nscaler <= 0) continue; if (nscaler > 2) nscaler = 2; // shouldn't be necessary // 32 channels of scaler data for two helicities. if (PRINTOUT) cout << "Scaler data in 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 << " data = 0x" << hex << data; cout << " = (dec) "<< dec << data << endl; } } } numread0 = evdata->GetRawData(myroc,index++); numread1 = evdata->GetRawData(myroc,index++); badread = evdata->GetRawData(myroc,index++); if (PRINTOUT) cout << "FIFO num of last good read " << dec << numread0 << numread1 << 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 "<<present_reading<<" " // << predicted_reading << endl; if (present_reading != predicted_reading) { cout << "DISASTER: The helicity is wrong !!"<<endl; recovery_flag = 1; // ask for recovery } q1_helicity = present_helicity; } } else { inquad++; } if (inquad == 1 || inquad == 4) { helicity_now = q1_helicity; } else { helicity_now = 1 - q1_helicity; } ring_t3 = evdata->GetRawData(myroc,index++); ring_bcm = evdata->GetRawData(myroc,index++); ring_l1a = evdata->GetRawData(myroc,index++); #ifdef READ6 ring_t1 = evdata->GetRawData(myroc,index++); #else ring_t1 = -99; #endif sum_clock = sum_clock + ring_clock; sum_t3 = sum_t3 + ring_t3; sum_bcm = sum_bcm + ring_bcm; sum_l1a = sum_l1a + ring_l1a; // We know the helicity bits come one window later, so we adjust // for that here. jstat = incrementSums(helicity_now, prev_clock, prev_trig, prev_bcm, prev_l1a); if (jstat == 1) { farray2[0] = (Float_t) evdata->GetEvNum(); farray2[1] = rsum_clk[0]; farray2[2] = rsum_clk[1]; farray2[3] = rsum_clk[0] + rsum_clk[1]; corr_bcm0 = rsum_bcm[0] - ringped[0]; // the 2 peds had better corr_bcm1 = rsum_bcm[1] - ringped[1]; // be the same (but we check) farray2[4] = rsum_bcm[0]; farray2[5] = rsum_bcm[1]; farray2[6] = corr_bcm0 + corr_bcm1; farray2[7] = rsum_t3[0] + rsum_t3[1]; farray2[8] = rsum_l1a[0] + rsum_l1a[1]; farray2[9] = rsum_num[0]; farray2[10] = rsum_num[1]; farray2[11] = rsum_num[0] + rsum_num[1]; sum = rsum_clk[0] + rsum_clk[1]; asy = -999; if (sum != 0) asy = (rsum_clk[0] - rsum_clk[1])/sum; farray2[12] = asy; // Charge asymmetry. Don't forget to normalize to clock. asy = -999; sum = corr_bcm0 + corr_bcm1; if (sum != 0) asy = (corr_bcm0 - corr_bcm1)/sum; farray2[13] = asy; asy = -999; if (corr_bcm0 != 0 && corr_bcm1 != 0) { Float_t trig0 = rsum_t3[0] / corr_bcm0; Float_t trig1 = rsum_t3[1] / corr_bcm1; sum = trig0 + trig1; if (sum != 0) { asy = (trig0 - trig1) / sum; } } farray2[14] = asy; asy = -999; if (corr_bcm0 != 0 && corr_bcm1 != 0) { Float_t l1a0 = rsum_l1a[0] / corr_bcm0; Float_t l1a1 = rsum_l1a[1] / corr_bcm1; sum = l1a0 + l1a1; if (sum != 0) { asy = (l1a0 - l1a1) / sum; } } farray2[15] = asy; rnt->Fill(farray2); resetSums(); } prev_clock = ring_clock; prev_trig = ring_t3; 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_t3; 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 "<<ishift<<" "<<asy<<endl; } } ntup->Fill(farray_ntup); rloc++; if (PRINTOUT) { cout << "buff [" << dec << iring << "] "; cout << " clock " << ring_clock << " qrt " << ring_qrt; cout << " helicity " << ring_helicity<<" T1 "<<ring_t1<<endl; cout << " T3 " << ring_t3 << " bcm " << ring_bcm; cout << " L1a "<<ring_l1a<<endl; cout << " inquad "<<inquad<<endl; cout << " sums: "<<endl; cout << " clock "<<sum_clock<<" trig "<<sum_t3; cout << " bcm "<<sum_bcm<<" l1a "<<sum_l1a<<endl; cout << " update from online sums: "<<endl; cout << " clock "<<latest_clock<<" trig "<<latest_trig; cout << " bcm "<<latest_bcm<<" l1a "<<latest_l1a<<endl; } } } finish: cout << "All done"<<endl<<flush; cout << "Sums from ring buffer: "<<dec<<endl; cout << " Clock "<<sum_clock<<" trigger "<<sum_t3; cout << " BCM "<<sum_bcm<<" L1a "<<sum_l1a<<endl; cout << "Latest data from online sums: "<<endl; cout << " Clock "<<latest_clock<<" trigger "<<latest_trig; cout << " BCM "<<latest_bcm<<" L1a "<<latest_l1a<<endl; hfile.Write(); hfile.Close(); exit(0); }
int main(int argc, char* argv[]) { int helicity, qrt, gate, timestamp; int len, data, status, nscaler, header; int numread, badread, i, found, index; int ring_clock, ring_qrt, ring_helicity; int ring_trig, ring_bcm, ring_l1a, ring_v2fh; int sum_clock, sum_trig, sum_bcm, sum_l1a; int inquad, nrread, q1_helicity; int ring_data[MAXRING], rloc; if (argc < 2) { cout << "You made a mistake... bye bye !\n" << endl; cout << "Usage: 'tscalroc" << MYROC << " filename'" << endl; cout << " where 'filename' is the CODA file."<<endl; exit(0); } // Setup // Pedestals. Left, Right Arms. u1,u3,u10,d1,d3,d10 Float_t bcmpedL[NBCM] = { 188.2, 146.2, 271.6, 37.8, 94.2, 260.2 }; Float_t bcmpedR[NBCM] = { 53.0, 41.8, 104.1, 0., 101.6, 254.6 }; Float_t bcmped[NBCM]; if (MYROC == 11) { cout << "Using Left Arm BCM pedestals"<<endl; for (i = 0; i < NBCM; i++) { bcmped[i] = bcmpedL[i]; } } else { cout << "Using Right Arm BCM pedestals"<<endl; for (i = 0; i < NBCM; i++) { bcmped[i] = bcmpedR[i]; } } // Initialize root and output. TROOT scalana("scalroot","Hall A scaler analysis"); TFile hfile("scaler.root","RECREATE","Scaler data in Hall A"); // Define the ntuple here // 0 1 2 3 4 5 6 char rawrates[]="evt:clk:trig:bcm:l1a:mhel:phel:"; // Asymmetries delayed various amounts, using RING BUFFER // 7 8 9 10 11 12 13 14 15 16 char asydelay[]="a3d1:a3d2:a3d3:a3d4:a3d5:a3d6:a3d7:a3d8:a3d9:a3d10"; int nlen = strlen(rawrates) + strlen(asydelay); char *string_ntup = new char[nlen+1]; strcpy(string_ntup,rawrates); strcat(string_ntup,asydelay); TNtuple *ntup = new TNtuple("ascal","Scaler Rates",string_ntup); Float_t farray_ntup[17]; // Dimension = size of string_ntup (i.e. nlen+1) THaCodaFile *coda = new THaCodaFile(TString(argv[1])); THaEvData *evdata = new THaCodaDecoder(); inquad = 0; q1_helicity = 0; rloc = 0; status = 0; sum_clock = 0; sum_trig = 0; sum_bcm = 0; sum_l1a = 0; nrread = 0; memset(ring_data, 0, MAXRING*sizeof(int)); while (status == 0) { status = coda->codaRead(); if (status != 0) break; evdata->LoadEvent(coda->getEvBuffer()); len = evdata->GetRocLength(MYROC); if (len <= 4) continue; data = evdata->GetRawData(MYROC,3); helicity = (data & 0x10) >> 4; qrt = (data & 0x20) >> 5; gate = (data & 0x40) >> 6; timestamp = evdata->GetRawData(MYROC,4); found = 0; index = 5; while ( !found ) { data = evdata->GetRawData(MYROC,index++); if ( (data & 0xffff0000) == 0xfb0b0000) found = 1; if (index >= len) break; } if (!found) break; nscaler = data & 0x7; if (PRINTOUT) { cout << hex << "helicity " << helicity << " qrt " << qrt; cout << " gate " << gate << " time stamp " << timestamp << endl; cout << "nscaler in this event " << nscaler << endl; } if (nscaler <= 0) continue; if (nscaler > 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; } // Subset of scaler channels stored in a 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 6 pieces of data per 'iring' // This was true after Jan 10, 2003. 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()) { if (present_reading != predicted_reading) { cout << "DISASTER: The helicity is wrong !!"<<endl; recovery_flag = 1; // ask for recovery } q1_helicity = present_helicity; } } else { inquad++; } ring_trig = evdata->GetRawData(MYROC,index++); ring_bcm = evdata->GetRawData(MYROC,index++); ring_l1a = evdata->GetRawData(MYROC,index++); ring_v2fh = evdata->GetRawData(MYROC,index++); sum_clock = sum_clock + ring_clock; sum_trig = sum_trig + ring_trig; sum_bcm = sum_bcm + ring_bcm; sum_l1a = sum_l1a + ring_l1a; ring_data[rloc%MAXRING] = ring_bcm; if (inquad == 1 && nrread++ > 12) { farray_ntup[0] = (float)nrread; farray_ntup[1] = ring_clock; farray_ntup[2] = ring_trig; farray_ntup[3] = ring_bcm; farray_ntup[4] = ring_l1a; farray_ntup[5] = (float)present_reading; farray_ntup[6] = (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; } } farray_ntup[4+ishift] = asy; } ntup->Fill(farray_ntup); } rloc++; if (PRINTOUT) { cout << "buff [" << dec << iring << "] "; cout << " clock " << ring_clock << " qrt " << ring_qrt; cout << " helicity " << ring_helicity; cout << " trigger " << ring_trig << " bcm " << ring_bcm; cout << " L1a "<<ring_l1a<<endl; cout << " ring_v2fh (helicity in v2f) "<<ring_v2fh<<endl; cout << " inquad "<<inquad<<endl; cout << " sums: "<<endl; cout << " clock "<<sum_clock<<" trig "<<sum_trig<<endl; cout << " bcm "<<sum_bcm<<" l1a "<<sum_l1a<<endl; } } } cout << "All done"<<endl; hfile.Write(); hfile.Close(); return 0; }
int main(int argc, char* argv[]) { int i,iev,evnum,trig,iskip,status; Int_t clkp, clkm, lastclkp, lastclkm; Float_t sum,asy; TString filename = "run.dat"; char bank[100] = "EvLeft"; // Event stream, Left HRS cout << "Analyzing CODA file "<<filename<<endl; cout << "Bank = "<<bank<<endl<<flush; evnum = 10000000; if (argc > 1) evnum = atoi(argv[1]); THaScaler *scaler = new THaScaler(bank); if (scaler->Init("1-10-2004") == -1) { cout << "Error initializing scaler "<<endl; return 1; } THaCodaData *coda = new THaCodaFile(filename); THaEvData *evdata = new THaCodaDecoder(); // Pedestals. Left, Right Arms. u1,u3,u10,d1,d3,d10 Float_t bcmpedL[NBCM] = { 188.2, 146.2, 271.6, 37.8, 94.2, 260.2 }; Float_t bcmpedR[NBCM] = { 53.0, 41.8, 104.1, 0., 101.6, 254.6 }; Float_t bcmped[NBCM]; if (strcmp(bank,"EvLeft") == 0) { cout << "Using Left Arm BCM pedestals"<<endl; for (i = 0; i < NBCM; i++) { bcmped[i] = bcmpedL[i]; } } else { cout << "Using Right Arm BCM pedestals"<<endl; for (i = 0; i < NBCM; i++) { bcmped[i] = bcmpedR[i]; } } // Initialize root and output TROOT scalana("scalroot","Hall A scaler analysis"); TFile hfile("scaler.root","RECREATE","Scaler data in Hall A"); // Define the ntuple here // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 char rawrates[]="time:u1:u3:u10:d1:d3:d10:t1:t2:t3:t4:t5:clkp:clkm:tacc:"; // 15 16 17 18 19 20 21 22 23 24 25 26 char asymmetries[]="au1:au3:au10:ad1:ad3:ad10:at1:at2:at3:at4:at5:aclk"; int nlen = strlen(rawrates) + strlen(asymmetries); char *string_ntup = new char[nlen+1]; strcpy(string_ntup,rawrates); strcat(string_ntup,asymmetries); TNtuple *ntup = new TNtuple("ascal","Scaler Rates",string_ntup); Float_t farray_ntup[27]; // Note, dimension is same as size of string_ntup (i.e. nlen+1) status = 0; iev = 0; iskip = 0; lastclkp = 0; lastclkm = 0; while (status == 0) { if(coda) status = coda->codaRead(); if (status != 0) { cout << "coda status nonzero. assume EOF"<<endl; goto quit; } evdata->LoadEvent(coda->getEvBuffer()); // Dirty trick to average over larger time intervals (depending on // SKIPEVENT) to reduce the fluctuations due to clock. if (evdata->GetRocLength(MYROC) > 16) iskip++; if (SKIPEVENT != 0 && iskip < SKIPEVENT) continue; iskip = 0; scaler->LoadData(*evdata); // Not every trigger has new scaler data, so skip if not new. if ( !scaler->IsRenewed() ) { cout << "not renewed "<<endl<<flush; continue; } if (iev++ > evnum) goto quit; // Fill the ntuple here // Note, we must average the two helicities here to get non-helicity rates Double_t time = (scaler->GetPulser(1,"clock") + scaler->GetPulser(-1,"clock"))/1024; farray_ntup[0] = time; farray_ntup[1] = 0.5*(scaler->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)); } clkp = scaler->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"}; 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; if (DEBUG) { cout << "event type "<<evdata->GetEvType()<< " event number "<<evdata->GetEvNum()<<endl; scaler->Print(); if (farray_ntup[12] < 1000) cout << "Low clock"<<endl; cout << " clock(+) "<<scaler->GetNormRate(1,"clock"); cout << " clock(-) "<<scaler->GetNormRate(-1,"clock")<<endl; if (farray_ntup[16]>0.005||farray_ntup[16]<-0.005) cout << "Big asy"<<endl; } ntup->Fill(farray_ntup); } quit: hfile.Write(); hfile.Close(); exit(0); }