StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TrimBeamLineFiles.C
1 /*
2  TrimBeamLineFiles.C
3 
4  Author: G. Van Buren, BNL, May 2006
5 
6  Purpose:
7  In order to get an appropriate number of good triggers per
8  fill to use in the BeamLine constraint calibration, a query
9  is made to the database. This query can do a reasonably good
10  job of obtaining a steady number of events per run, but not
11  so per fill. This macro does the subsequent work of paring this
12  down per fill. An effort is made to use at least one file from
13  each run in the fill, and files with few good triggers are
14  avoided. Otherwise, selection of files from within fills is
15  random.
16 
17  Because the real number of events which reconstruct primary
18  vertices may be less than the predicted "good" events per file,
19  a fudgefactor is allowed to adjust for this efficiency.
20 
21  Usage:
22  In this example, we try to get 10k events per run in a query
23  and then pare that down to 2k events per fill. A few test runs
24  might show that our reconstruction only gives us about 75% as
25  many good vertices as predicted from the database. So we make
26  the query (I have left the 'where' clause ambiguous for the
27  user to replace appropriately), then run this macro:
28 
29  > cat > query.txt << EOF
30 select
31 floor(bi.blueFillNumber) as fill,
32 sum(ts.numberOfEvents/ds.numberOfFiles) as gdEvtPerFile,
33 ds.numberOfFiles,
34 sum(dt.numberOfEvents*ts.numberOfEvents/ds.numberOfEvents) as gdInFile,
35 dt.file, rd.glbSetupName
36 --
37 from daqFileTag as dt
38 left join l0TriggerSet as ts on ts.runNumber=dt.run
39 left join runDescriptor as rd on rd.runNumber=dt.run
40 left join daqSummary as ds on ds.runNumber=dt.run
41 left join beamInfo as bi on bi.runNumber=dt.run
42 left join detectorSet as de on de.runNumber=dt.run
43 left join runStatus as rs on rs.runNumber=dt.run
44 left join magField as mf on mf.runNumber=dt.run
45 --
46 where ...
47 and ...
48 --
49 group by dt.file
50 having (@t4:=sum(dt.numberOfEvents*ts.numberOfEvents/ds.numberOfEvents))>60
51 and (@t3:=mod(avg(dt.filesequence+(10*dt.fileStream)),(@t2:=floor(sum(ts.numberOfEvents)/10000.0)+1)))=0
52 ;
53 <<EOF
54  > cat query.txt | mysql -h heston.star.bnl.gov --port=3501 -C RunLog > output.txt
55  > root -b -q 'TrimBeamLineFiles.C("output.txt","out.list",2000,0.75)'
56 
57 
58 */
59 
60 //______________________________________________________________________
61 // Function declarations:
62 
63 void TrimBeamLineFiles(const char* input, const char* output="out.list",
64  int min=2500, double fudgefactor=1.0);
65 int flush_fill();
66 
67 //______________________________________________________________________
68 // Global variables:
69 
70 int minfiles=2; // minimum number of files to examine per fill
71 double minimum=0;
72 int ct,fill,oldfill;
73 double nper[1024];
74 int nfiles[1024];
75 double good[1024];
76 TString fname[1024];
77 ofstream* out;
78 
79 //______________________________________________________________________
80 void TrimBeamLineFiles(const char* input, const char* output,
81  int min, double fudgefactor) {
82  minimum = min;
83  ifstream in(input);
84  out = new ofstream(output);
85  char line1[1024];
86  char line2[1024];
87 
88  in >> line1;
89  if (strcmp(line1,"fill")) {
90  fill = atoi(line1);
91  } else {
92  in >> line2 >> line2 >> line2 >> line2 >> line2;
93  in >> fill;
94  }
95 
96  int numfiles = 0;
97  oldfill = fill;
98  ct = 0;
99  while (!in.eof() && ct<1024) {
100  if (fill != oldfill && fill>0) {
101  numfiles += flush_fill();
102  oldfill = fill;
103  ct=0;
104  }
105  double goodb;
106  in >> nper[ct] >> nfiles[ct] >> goodb >> line1 >> line2;
107  good[ct] = fudgefactor * goodb;
108  fname[ct] = line1;
109  if (fill>0) ct++;
110  in >> fill;
111  }
112  numfiles += flush_fill();
113  printf("Total file count = %d\n",numfiles);
114  out->close();
115  delete out;
116  out=0;
117 }
118 
119 //______________________________________________________________________
120 int flush_fill() {
121  // ct is the number of files provided to sort through
122 
123  if (ct<=0) return 0;
124  int k;
125  double totgood = 0;
126  for (k=0;k<ct;k++) totgood += good[k];
127 
128  int mfiles = minfiles;
129  int nused=0;
130  double tcount;
131  Bool_t happy = kFALSE;
132  while (!happy) {
133 
134  double mctratio = ((double) mfiles)/((double) ct);
135  double fneed = TMath::Max(minimum/totgood,mctratio);
136  fneed = TMath::Min(fneed,1.0);
137 
138  double using[1024];
139  int giveup=0;
140  int gaveup=10;
141 
142  while (nused<mfiles && giveup<gaveup) { // insure using >= mfiles
143  gRandom->RndmArray(ct,using);
144  int rused = 0;
145  nused = 0;
146  tcount = 0;
147 
148  for (k=0;k<ct;k++) {
149  Bool_t last_k = (k==(ct-1) || nper[k] != nper[k+1]);
150 
151  // Use at least 1 per run where we expect lots of good events
152  if (last_k && rused==0 && good[k]>750) using[k] = 0.0;
153  if (good[k]<50) using[k]=1.0;
154  if (using[k] <= fneed) {
155  tcount += good[k];
156  rused++;
157  nused++;
158  }
159  if (last_k) rused=0;
160  }
161  giveup++;
162  }
163 
164  if (tcount < minimum && mfiles < ct) {
165  // Bump it up more quickly
166  mfiles = TMath::Max(mfiles+1,(int) (fneed*ct));
167  } else {
168  happy = kTRUE;
169  }
170 
171  }
172 
173  for (k=0;k<ct;k++) {
174  if (using[k] <= fneed) (*out) << fname[k].Data() << endl;
175  }
176  printf("Guess for fill %d = %f (%d files)\n",oldfill,tcount,nused);
177  if (tcount<minimum)
178  printf("^^^^^ WARNING ^^^^^ Below minimum=%d\n",(int) minimum);
179  return nused;
180 }
181 
182 //______________________________________________________________________
183 // $Id: TrimBeamLineFiles.C,v 1.1 2006/05/11 19:43:09 genevb Exp $
184 // $Log: TrimBeamLineFiles.C,v $
185 // Revision 1.1 2006/05/11 19:43:09 genevb
186 // Introduce macro
187 //
188 //