Table of Contents
Write Efficiency
The DAQ system can not quite keep up with the trigger rate typically - some triggered events are lost. We can look at random traces to calculate the true event rate for a category of pulses strong enough that they should trigger the DAQ, then find the rate that we see triggered events of that category; the ratio of the two rates is the write efficiency. True rates can be derived from observed rates by dividing by the efficiency.
NaI-triggered data
For NaI-triggered data we want to look at pulses in zip4 pA - that's the channel that records triggers from the NaI array.
Example
Load some NaI-triggered data:
// load NaI series into one chain
gStyle->SetOptStat(0)
gStyle->SetOptFit(1)
TString datapath ="/data/chocula/fritts/data/k100proc/midasrq/byseries/"
TString ser[] = {"07220916_2059","07220916_2200","07220917_1039","07220917_1225","07220917_2125","07220917_2155"}
//TString lab[] = {"0V","-4V","-21V","-65V","-84V","-84V"}
int nser = 6
TChain *e
TChain *z
e = new TChain("rqDir/eventTree")
z = new TChain("rqDir/zip1")
z4 = new TChain("rqDir/zip4")
// load odd-numbered series only, those are the NaI-triggered series
for(int s=0;s<nser;s++)if(s%2==1)e->Add(Form("%s/%s/umn*root",datapath.Data(),ser[s].Data()));
for(int s=0;s<nser;s++)if(s%2==1)z->Add(Form("%s/%s/umn*root",datapath.Data(),ser[s].Data()));
for(int s=0;s<nser;s++)if(s%2==1)z4->Add(Form("%s/%s/umn*root",datapath.Data(),ser[s].Data()));
z->AddFriend(e)
z->AddFriend(z4)
//z->SetLineColor(kRed)
TCut crand = "EventCategory"
We can use walk algorithm quantities to look for NaI triggers in random traces:
z->Draw("zip4.PAWKmax:zip4.PAWKr50",crand)
Most random events are in the narrow band at the bottom - just flat traces. The band at the top is TTL pulses from the NaI array. The horizontal axis is the 50% start time of the pulse according to the walk algorithm. This algorithm doesn't work properly if the pulse is too early or too late. So we choose a time window where the algorithm works properly.
float nrand nrand=z->GetEntries(crand) float nrandhit nrandhit=z->GetEntries(crand+"zip4.PAWKmax>0.6e-6&&zip4.PAWKr50>0.00035&&zip4.PAWKr50<0.003") // note: my criterion for a hit is based on PTWK quantities // in the trace window 0.00035 to 0.003 seconds (for PTWKr50) the walk algorithm seems to work properly float twindow = 0.003-0.00035 float rate_rand rate_rand = log(nrand/(nrand-nrandhit))/twindow // 11.8466 Hz
The code above calculates the trigger rate in randoms. We count the number of randoms and the number of randoms that have a “hit” (a pulse) according to our criteria. The proper way to get the rate for a Poisson process is shown in the second-to-last line. The rate we see in this data is 11.85 Hz.
Note - we can also calculate the uncertainty in this rate - I will add that later.
Now we get the rate of pulses seen in the triggered data:
float timesec = 102291-89791+87895-55573+49158-3690 float ntrig ntrig = z->GetEntries(!crand+"zip4.PAWKmax>0.6e-6") float rate_trig rate_trig = ntrig/timesec // 10.2368 Hz
It is indeed somewhat less than the true rate. We now calculate the write efficiency:
float effic_write effic_write = rate_trig/rate_rand // cout<<"// "<<rate_rand<<"\t"<<rate_trig<<"\t"<<effic_write<<endl // 11.8466 10.2368 0.86411
We get a write efficiency of 86.4%.
Addendum to example
The example above did not show how to calculated “timesec”, the number of seconds in the active part of the run. It's easier to do that for a single series rather than the multiple series above, so here we'll start over and load only a single series.
// load one NaI series
TString datapath ="/data/chocula/fritts/data/k100proc/midasrq/byseries/"
TString ser = "07220916_2200"
TChain *e
TChain *z
e = new TChain("rqDir/eventTree")
z = new TChain("rqDir/zip1")
z4 = new TChain("rqDir/zip4")
e->Add(Form("%s/%s/umn*root",datapath.Data(),ser.Data()));
z->Add(Form("%s/%s/umn*root",datapath.Data(),ser.Data()));
z4->Add(Form("%s/%s/umn*root",datapath.Data(),ser.Data()));
z->AddFriend(e)
z->AddFriend(z4)
TCut crand = "EventCategory"
Now calculate the live time. This is the period of time during the series in which the DAQ is set to trigger on data. Every series starts with 1000 randoms, so we look at the 1001th event and the final event. For each event the EventTime is shown - that's the Unix Time of the event in seconds, so we just subtract the two and take that as the live time.
// calculate live time for single series
int nentries = z->GetEntries()
z->GetEntry(nentries-1)
double timesec = z->GetLeaf("EventTime")->GetValue()
z->GetEntry(1000) // this is the first event after the initial 1000 randoms. So this is when the "live" part of the run begins.
timesec -= z->GetLeaf("EventTime")->GetValue()
cout<<timesec<<endl
// The result for this series is timesec = 45468. That's the time in seconds, equal to about 12.6 hours
