Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JEventProcessor_bcal_calib_cosmic_cdc.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: JEventProcessor_bcal_calib_cosmic_cdc.cc
4 // Created: Tue Jul 1 13:11:51 EDT 2014
5 // Creator: dalton (on Linux gluon05.jlab.org 2.6.32-358.18.1.el6.x86_64 x86_64)
6 //
7 
9 using namespace jana;
10 
12 #include <DAQ/Df250PulseIntegral.h>
13 #include <DAQ/Df250PulseIntegral.h>
14 #include <BCAL/DBCALHit.h>
15 #include "BCAL/DBCALGeometry.h"
16 
17 float getx(float r, float phi) {
18  return r*cos(phi);
19 }
20 float gety(float r, float phi) {
21  return r*sin(phi);
22 }
23 float getr(float x, float y) {
24  return sqrt(x*x + y*y);
25 }
26 // float getphi(float x, float y) {
27 // return atan(y/x);
28 // }
29 float getposphi(float x, float y) {
30  float phi=0;
31  if (x!=0) phi = atan2(y,x);
32  if (phi<0) phi+=2*PI;
33  return phi;
34 }
35 float getdistance(float x1, float y1, float x2, float y2) {
36  float deltax2 = (x1-x2)*(x1-x2);
37  float deltay2 = (y1-y2)*(y1-y2);
38  return sqrt(deltax2+deltay2);
39 }
40 
41 
42 // Routine used to create our JEventProcessor
43 #include <JANA/JApplication.h>
44 #include <JANA/JFactory.h>
45 extern "C"{
46  void InitPlugin(JApplication *app){
47  InitJANAPlugin(app);
48  app->AddProcessor(new JEventProcessor_bcal_calib_cosmic_cdc());
49  }
50 } // "C"
51 
52 
53 //------------------
54 // JEventProcessor_bcal_calib_cosmic_cdc (Constructor)
55 //------------------
57 {
58 
59 }
60 
61 //------------------
62 // ~JEventProcessor_bcal_calib_cosmic_cdc (Destructor)
63 //------------------
65 {
66 
67 }
68 
69 //------------------
70 // init
71 //------------------
73 {
74  // This is called once at program startup. If you are creating
75  // and filling historgrams in this plugin, you should lock the
76  // ROOT mutex like this:
77  //
78  // japp->RootWriteLock();
79  // ... fill historgrams or trees ...
80  // japp->RootUnLock();
81  //
82 
83  /// Setup the parameters
84  /**
85  VERBOSE=1 Output every event
86  VERBOSE=2 Output every intersection
87  VERBOSE=3 Output every sector
88  VERBOSE=4 Output every hit
89  */
90  VERBOSE=0;
91  gPARMS->SetDefaultParameter("BCCC:VERBOSE",VERBOSE);
92 
93  /// Create the root tree
94  bcal_calib_cosmic_cdc_tree = new TTree("bcal_calib_cosmic_cdc",
95  "tree of DBCALHit energies and the length of the track through each cell.");
96  bcal_calib_cosmic_cdc_tree->Branch("eventnum",&eventnum,"eventnum/i");
97  bcal_calib_cosmic_cdc_tree->Branch("cell",&cell,"cell/i");
98 // bcal_calib_cosmic_cdc_tree->Branch("",&,"/i");
99  bcal_calib_cosmic_cdc_tree->Branch("layer",&tlayer,"layer/i");
100  bcal_calib_cosmic_cdc_tree->Branch("module",&tmodule,"module/i");
101  bcal_calib_cosmic_cdc_tree->Branch("sector",&tsector,"sector/i");
102  bcal_calib_cosmic_cdc_tree->Branch("globalsect",&tglobalsect,"globalsect/i");
103  bcal_calib_cosmic_cdc_tree->Branch("numcells",&numcells,"numcells/i");
104  bcal_calib_cosmic_cdc_tree->Branch("dist",&tdist,"dist/f");
105  bcal_calib_cosmic_cdc_tree->Branch("use",&use,"use/f");
106  bcal_calib_cosmic_cdc_tree->Branch("dse",&dse,"dse/f");
107  bcal_calib_cosmic_cdc_tree->Branch("track_m",&track_m,"track_m/f");
108  bcal_calib_cosmic_cdc_tree->Branch("track_c",&track_c,"track_c/f");
109  bcal_calib_cosmic_cdc_tree->Branch("chisq",&chisq,"chisq/f");
110  bcal_calib_cosmic_cdc_tree->Branch("Ndof",&Ndof,"Ndof/i");
111 
112  return NOERROR;
113 }
114 
115 //------------------
116 // brun
117 //------------------
118 jerror_t JEventProcessor_bcal_calib_cosmic_cdc::brun(JEventLoop *eventLoop, int32_t runnumber)
119 {
120  // This is called whenever the run number changes
121 
122  return NOERROR;
123 }
124 
125 //------------------
126 // evnt
127 //------------------
128 jerror_t JEventProcessor_bcal_calib_cosmic_cdc::evnt(JEventLoop *loop, uint64_t eventnumber)
129 {
130  // This is called for every event. Use of common resources like writing
131  // to a file or filling a histogram should be mutex protected. Using
132  // loop->Get(...) to get reconstructed objects (and thereby activating the
133  // reconstruction algorithm) should be done outside of any mutex lock
134  // since multiple threads may call this method at the same time.
135  // Here's an example:
136  //
137  // vector<const MyDataClass*> mydataclasses;
138  // loop->Get(mydataclasses);
139  //
140  // japp->RootWriteLock();
141  // ... fill historgrams or trees ...
142  // japp->RootUnLock();
143 
144  // load BCAL geometry
145  vector<const DBCALGeometry *> BCALGeomVec;
146  loop->Get(BCALGeomVec);
147  if(BCALGeomVec.size() == 0)
148  throw JException("Could not load DBCALGeometry object!");
149  auto dBCALGeom = BCALGeomVec[0];
150 
151  /// DTrackCandidate:CDCCOSMIC
152  /// Get a vector of DTrackCandidate:CDCCOSMIC objects for this event
153  vector<const DTrackCandidate*> CDCCOSMIC_vec;
154  loop->Get(CDCCOSMIC_vec,"CDCCOSMIC");
155  unsigned int num_CDCCOSMIC = CDCCOSMIC_vec.size();
156  /// Create vectors to store the ID of the hit cells and the traversed distance
157  vector<int> CellId_vec;
158  vector<float> distance_vec;
159  /// Only do anything if there is a track found
160  if (num_CDCCOSMIC>0) {
161  /// Get the parameters of the fitted track
162  const DTrackCandidate* CDCCOSMIC = CDCCOSMIC_vec[0];
163  const DVector3 cdcmom = CDCCOSMIC->momentum();
164  const DVector3 cdcpos = CDCCOSMIC->position();
165  chisq = CDCCOSMIC->chisq;
166  Ndof = CDCCOSMIC->Ndof;
167 
168  /// Extract the slope and intercept
169  track_m = cdcmom.y()/cdcmom.x();
170  track_c = cdcpos.y() - track_m*cdcpos.x();
171  if (VERBOSE>=1)
172  printf("BCCC >> pos (%6.2f,%6.2f,%6.2f) mom (%6.2f,%6.2f,%6.2f) m=%6.2f, c=%6.2f, chisq=%6.2f, Ndof=%i\n",
173  cdcpos.x(), cdcpos.y(), cdcpos.z(), cdcmom.x(), cdcmom.y(), cdcmom.z(),track_m,track_c,chisq,Ndof);
174  /// Store the parameters for both track intersections with the 5 layers
175  float r[5], phi[2][5], x[2][5], y[2][5];
176  float* bcal_radii;
177  bcal_radii = dBCALGeom->GetBCAL_radii();
178  /// For each layer boundary, calculate the intersection of the DTrackCandidate
179  /// with the circle and store the r and phi value for both intersections.
180  for (int laybound=0; laybound<=4; laybound++) {
181 
182  r[laybound] = dBCALGeom->bcal_radii[laybound];
183 
184  float A = 1 + track_m*track_m;
185  float B = 2 * track_m * track_c;
186  float C = track_c*track_c - r[laybound]*r[laybound];
187  float disc = (B*B - 4*A*C);
188 
189  x[0][laybound] = 0, y[0][laybound] = 0, x[1][laybound] = 0, y[1][laybound] = 0;
190  phi[0][laybound]=0 , phi[1][laybound]=0;
191  if (disc > 0) {
192  x[0][laybound] = (-B + sqrt(disc))/(2*A);
193  x[1][laybound] = (-B - sqrt(disc))/(2*A);
194  y[0][laybound] = track_m*x[0][laybound] + track_c;
195  y[1][laybound] = track_m*x[1][laybound] + track_c;
196  phi[0][laybound] = getposphi(x[0][laybound],y[0][laybound]);
197  phi[1][laybound] = getposphi(x[1][laybound],y[1][laybound]);
198  }
199  if (VERBOSE>=2) {
200  for (int track=0; track<=1; track++) {
201  int fADC_cellId = dBCALGeom->fADCcellId_rphi( r[laybound], phi[track][laybound]);
202  int module = dBCALGeom->module( fADC_cellId );
203  int layer = dBCALGeom->layer( fADC_cellId );
204  int sector = dBCALGeom->sector( fADC_cellId );
205  int glosector = dBCALGeom->getglobalsector(module,sector);
206  printf("BCCC >> intersection: boundary=%i (x,y)=(%6.2f,%6.2f) (r,phi)=(%6.2f,%6.3f) cellId 0x%4x (mod,lay,sec,glosec) = (%2i,%2i,%2i,%3i)\n",
207  laybound, x[track][laybound], y[track][laybound], r[laybound], phi[track][laybound],
208  fADC_cellId, module, layer, sector, glosector);
209  }
210  }
211  // fADC_cellId = dBCALGeom->fADCcellId_rphi( r[laybound], phi[1][laybound]);
212  // module = dBCALGeom->module( fADC_cellId );
213  // layer = dBCALGeom->layer( fADC_cellId );
214  // sector = dBCALGeom->sector( fADC_cellId );
215  // glosector = dBCALGeom->getglobalsector(module,sector);
216  // if (VERBOSE>=2) {
217  // printf("BCCC >> intersection: boundary=%i (x,y)=(%6.2f,%6.2f) (r,phi)=(%6.2f,%6.3f) cellId 0x%4x (mod,lay,sec,glosec) = (%2i,%2i,%2i,%3i)\n",
218  // laybound, x[1][laybound], y[1][laybound], r[laybound], phi[1][laybound], fADC_cellId, module, layer, sector, glosector);
219  }
220 
221  /// For each intersection set, step through each layer
222  for (int track=0; track<=1; track++) {
223  float total_distance = 0;
224  /// For each layer, step through each sector
225  for (int layer=0; layer<=3; layer++) {
226  /// IN refers to inner radial boundary, OUT refers to outer radial boundary
227  /// Find the global sector number for the entrance and exit sectors in this layer
228  int fADC_cellIdIN = dBCALGeom->fADCcellId_rphi( r[layer], phi[track][layer]);
229  int moduleIN = dBCALGeom->module( fADC_cellIdIN );
230  int sectorIN = dBCALGeom->sector( fADC_cellIdIN );
231  int globalsectorIN = dBCALGeom->getglobalsector(moduleIN,sectorIN);
232  int fADC_cellIdOUT = dBCALGeom->fADCcellId_rphi( r[layer+1], phi[track][layer+1]);
233  int moduleOUT = dBCALGeom->module( fADC_cellIdOUT );
234  int sectorOUT = dBCALGeom->sector( fADC_cellIdOUT );
235  int globalsectorOUT = dBCALGeom->getglobalsector(moduleOUT,sectorOUT);
236  int globalsectormin, globalsectormax; // These are the ordered edge sectors, smallest and largets
237  /// Check that the cells are valid
238  if (fADC_cellIdIN<=0 || fADC_cellIdOUT<=0) {
239  printf("BCCC >>Cells are not valid, event %i\n",eventnumber);
240  } else {
241  if (globalsectorIN == globalsectorOUT) {
242  /// If the track only goes through 1 sector in this layer, then you are done,
243  /// get the distance from the (x,y) values of the layer inner and outer boundary intersections
244  float dist = getdistance(x[track][layer], y[track][layer], x[track][layer+1], y[track][layer+1]);
245  if (VERBOSE>=3)
246  printf("BCCC >> single sector layer: point (%6.3f,%6.3f) point (%6.3f,%6.3f)\n",
247  x[track][layer], y[track][layer], x[track][layer+1], y[track][layer+1]);
248  total_distance+=dist;
249  if (VERBOSE>=2)
250  printf("BCCC >> (mod,lay,sec,glosec) = (%2i,%2i,%2i,%3i) fADC_cellId 0x%4x philess %6.3f, phimore %6.3f dist = %6.2f\n",
251  moduleIN,layer+1,sectorIN,globalsectorIN,fADC_cellIdIN,0.0,0.0,dist);
252  CellId_vec.push_back(fADC_cellIdIN);
253  distance_vec.push_back(dist);
254  } else {
255  /// If the track goes through multiple sectors then find the intersection of the DTrackCandidate
256  /// with the sector boundary.
257  if (globalsectorIN > globalsectorOUT) {
258  globalsectormin = globalsectorOUT;
259  globalsectormax = globalsectorIN;
260  } else {
261  globalsectormax = globalsectorOUT;
262  globalsectormin = globalsectorIN;
263  }
264  if (VERBOSE>=2) {
265  printf("BCCC >> layer=%i phi=%5.2f fADC_cellId 0x%4x (mod,sec) = (%2i,%2i) %3i\n",
266  layer, phi[track][layer], fADC_cellIdIN, moduleIN, sectorIN, globalsectorIN);
267  printf("BCCC >> layer=%i phi=%5.2f fADC_cellId 0x%4x (mod,sec) = (%2i,%2i) %3i\n",
268  layer, phi[track][layer+1], fADC_cellIdOUT, moduleOUT, sectorOUT, globalsectorOUT);
269  }
270 
271  for (int glosect=globalsectormin; glosect<=globalsectormax; glosect++) {
272  float dist = 0;
273  int sector = dBCALGeom->getsector(glosect);
274  int module = dBCALGeom->getmodule(glosect);
275  int fADCId = dBCALGeom->cellId(module,layer+1,sector); // layers are 1 to 4
276  float phi = dBCALGeom->phi(fADCId);
277  float phihalfSize = dBCALGeom->phiSize(fADCId)/2.;
278  float philess=phi-phihalfSize, phimore=phi+phihalfSize;
279  float mless, xless, yless, mmore, xmore, ymore;
280  /// For each sector, get line boundary on each side and find the (x,y) point
281  /// at which the track crosses that line
282  mless = tan(philess);
283  mmore = tan(phimore);
284  xless = track_c/(mless-track_m);
285  yless = (mless*track_c)/(mless-track_m);
286  xmore = track_c/(mmore-track_m);
287  ymore = (mmore*track_c)/(mmore-track_m);
288  // printf("BCCC >>mless %6.2f, xless %6.2f, yless %6.2f, mmore %6.2f, xmore %6.2f, ymore %6.2f\n",
289  // mless, xless, yless, mmore, xmore, ymore);
290  /// Edge sectors in each layer have
291  if (glosect==globalsectorIN) {
292  if (glosect==globalsectormin) {
293  dist = getdistance(x[track][layer],y[track][layer],xmore,ymore);
294  } else {
295  dist = getdistance(x[track][layer],y[track][layer],xless,yless);
296  }
297  } else {
298  if (glosect==globalsectorOUT) {
299  if (glosect==globalsectormin) {
300  dist = getdistance(x[track][layer+1],y[track][layer+1],xmore,ymore);
301  } else {
302  dist = getdistance(x[track][layer+1],y[track][layer+1],xless,yless);
303  }
304  } else {
305  /// For a central sector, get line boundary on each side and find the distance
306  /// the phi less side and the phi more side
307  // printf("BCCC >>philess %6.2f, mless %6.2f, xless %6.2f, yless %6.2f, phimore %6.2f, mmore %6.2f, xmore %6.2f, ymore %6.2f\n",
308  // philess, mless, xless, yless, phimore, mmore, xmore, ymore);
309  dist = getdistance(xless, yless, xmore, ymore);
310  }
311  }
312  CellId_vec.push_back(fADCId);
313  distance_vec.push_back(dist);
314  total_distance+=dist;
315  if (VERBOSE>=2)
316  printf("BCCC >> (mod,lay,sec,glosec) = (%2i,%2i,%2i,%3i) fADC_cellId 0x%4x philess %6.3f, phimore %6.3f dist = %6.2f\n",
317  module,layer+1,sector,glosect,fADCId,philess,phimore,dist);
318  }
319  } // end multiple sector logic
320  } // end check that cells are valid
321  } // end loop over layers
322  if (VERBOSE>=1) {
323  float dist = getdistance(x[track][0],y[track][0],x[track][4],y[track][4]);
324  printf("BCCC >> total distance in BCAL: %f cm, expected %f\n",total_distance,dist);
325  }
326  }
327  }
328 
329 
330  /// DBCALHit
331  /// Get a vector of DBCALHit objects for this event (1 object for each crate/slot/channel above threshold)
332  vector<const DBCALHit*> BCALHit_vec;
333  loop->Get(BCALHit_vec);
334  unsigned int num_BCALHit = BCALHit_vec.size();
335  /// Creat maps from the BCAL cell ID to the DBCALHit object pointer
336 
337  map<int, const DBCALHit*>::iterator myiter;
338  map<int, const DBCALHit*> upstream;
339  map<int, const DBCALHit*> downstream;
340  /// Loop over all DBCALHit objects in this event
341  for(unsigned int c_chan=0; c_chan<num_BCALHit; c_chan++){
342  const DBCALHit *BCALHit = BCALHit_vec[c_chan];
343  //int fADCId = dBCALGeom->fADCId_fADC( BCALHit->module, BCALHit->layer, BCALHit->sector );
344  int fADCId = dBCALGeom->cellId( BCALHit->module, BCALHit->layer, BCALHit->sector );
345  if (VERBOSE>=4)
346  printf("BCCC >> Hit: (module, layer, sector) = (%2i,%2i,%2i) fADCId 0x%x\n",\
347  BCALHit->module, BCALHit->layer, BCALHit->sector, fADCId);
348  /// Fill the maps with the hits for this event.
349  if (BCALHit->end == DBCALGeometry::kUpstream ) {
350  upstream[fADCId] = BCALHit;
351  } else {
352  if (BCALHit->end == DBCALGeometry::kDownstream ) {
353  downstream[fADCId] = BCALHit;
354  } else {
355  printf("BCCC >>Bad BCAL enum\n");
356  }
357  }
358  }
359  if (VERBOSE>=1)
360  printf("BCCC >> found %ld upstream and %ld downstream hits for map.\n",upstream.size(),downstream.size());
361  //cout << "found " << upstream.size() << " upstream and " << downstream.size() << " downstream hits for map.\n";
362 
363  // Although we are only filling objects local to this plugin, TTree::Fill() periodically writes to file: Global ROOT lock
364  japp->RootWriteLock(); //ACQUIRE ROOT LOCK
365  {
366  eventnum = eventnumber;
367  /// Loop over the intersected cells
368  unsigned int num_CellId = CellId_vec.size();
369  for (unsigned int cellnum=0; cellnum<num_CellId; cellnum++) {
370  cell = CellId_vec[cellnum];
371  tdist = distance_vec[cellnum];
372  tmodule = dBCALGeom->module( cell );
373  tlayer = dBCALGeom->layer( cell );
374  tsector = dBCALGeom->sector( cell );
375  tglobalsect = dBCALGeom->getglobalsector(tmodule,tsector);
376  numcells = num_CellId;
377  use=0;
378  dse=0;
379  myiter = upstream.find(cell);
380  if (myiter!=upstream.end()) {
381  const DBCALHit* US = myiter->second;
382  use = US->E;
383  }
384  myiter = downstream.find(cell);
385  if (myiter!=downstream.end()) {
386  const DBCALHit* DS = myiter->second;
387  dse = DS->E;
388  }
389  if (VERBOSE>=2)
390  printf("BCCC >> eventnum %4i cellnum %2i 0x%4x (mod,lay,sec) = (%2i,%2i,%2i) %3i %6.2f %6.2f %6.2f \n",
391  eventnum, cellnum, cell, tmodule, tlayer, tsector, tglobalsect, tdist, use, dse);
392 
393  bcal_calib_cosmic_cdc_tree->Fill();
394  }
395  }
396  japp->RootUnLock(); //RELEASE ROOT LOCK
397 
398  return NOERROR;
399 }
400 
401 //------------------
402 // erun
403 //------------------
405 {
406  // This is called whenever the run number changes, before it is
407  // changed to give you a chance to clean up before processing
408  // events from the next run number.
409  return NOERROR;
410 }
411 
412 //------------------
413 // fini
414 //------------------
416 {
417  // Called before program exit after event processing is finished.
418  return NOERROR;
419 }
420 
421 
422 /* emacs
423  * Local Variables:
424  * mode:C++
425  * mode:font-lock
426  * c-file-style: "stroustrup"
427  * tab-width: 4
428  * End:
429  */
Definition: track.h:16
float E
Definition: DBCALHit.h:30
jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber)
Called every event.
float getposphi(float x, float y)
jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber)
Called everytime a new run number is detected.
Int_t layer
TVector3 DVector3
Definition: DVector3.h:14
int module
Definition: DBCALHit.h:25
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
#define y
const DVector3 & position(void) const
float getdistance(float x1, float y1, float x2, float y2)
jerror_t fini(void)
Called after last event of last event source has been processed.
int layer
Definition: DBCALHit.h:26
JApplication * japp
DBCALGeometry::End end
Definition: DBCALHit.h:28
#define PI
Definition: kinematics.h:18
jerror_t init(void)
Called once at program start.
float gety(float r, float phi)
InitPlugin_t InitPlugin
float getr(float x, float y)
const bool VERBOSE
int sector
Definition: DBCALHit.h:27
&lt;A href=&quot;index.html#legend&quot;&gt; &lt;IMG src=&quot;CORE.png&quot; width=&quot;100&quot;&gt; &lt;/A&gt;
double sqrt(double)
double sin(double)
float chisq
Chi-squared for the track (not chisq/dof!)
const DVector3 & momentum(void) const
float getx(float r, float phi)
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.
int Ndof
Number of degrees of freedom in the fit.
printf("string=%s", string)