Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JEventProcessor_FCALgains.cc
Go to the documentation of this file.
2 #include <TLorentzVector.h>
3 #include "TMath.h"
4 #include "JANA/JApplication.h"
5 #include "DANA/DApplication.h"
6 #include "FCAL/DFCALShower.h"
7 #include "FCAL/DFCALCluster.h"
8 #include "FCAL/DFCALHit.h"
10 #include "PID/DVertex.h"
11 #include "GlueX.h"
12 #include <vector>
13 #include <deque>
14 #include <string>
15 #include <iostream>
16 #include <algorithm>
17 #include <stdio.h>
18 #include <stdlib.h>
19 
20 static TH1F* InvMass1 = NULL;
21 static TH1F* InvMass2 = NULL;
22 
23 
24 
25 
26 extern "C"
27 {
28  void InitPlugin(JApplication *locApplication)
29  {
30  InitJANAPlugin(locApplication);
31  locApplication->AddProcessor(new JEventProcessor_FCALgains()); //register this plugin
32  }
33 } // "C"
34 
35 //------------------
36 // init
37 //------------------
39 {
40  // This is called once at program startup. If you are creating
41  // and filling historgrams in this plugin, you should lock the
42  // ROOT mutex like this:
43  japp->RootWriteLock();
44 
45  if(InvMass1 && InvMass2 != NULL){
46  japp->RootUnLock();
47  return NOERROR;
48  }
49 
50  n_channels = 2800;
52  MASS_CUT_LO = 0.1;
53  MASS_CUT_HI = 0.17;
54 
55  InvMass2 = new TH1F("InvMass2","FCAL diphoton mass (Cluster E > 1000 MeV)",500,0.0,0.5);
56  InvMass2->GetXaxis()->SetTitle("invariant mass [GeV]");
57  InvMass2->GetYaxis()->SetTitle("Counts / 1 MeV");
58 
59 
60  h2D_mC = new TH2F( "h2D_mC", "C Matrix as TH2F",
62  h1D_mD = new TH1F( "h1D_mD", "D Matrix as TH1F",n_channels, 0., n_channels );
63  h1D_mL = new TH1F( "h1D_mL", "L Matrix as TH1F",n_channels, 0., n_channels );
64  h1D_massbias = new TH1F( "h1D_massbias", "Mass Bias Value (in bin 2)",5,0.,5.);
65 
66  h1D_mPi0 = new TH1F( "h1D_mPi0", "Reconstructed Pi0 Mass (pre-cuts)",54,0.03,0.3);
67  h1D_mPi0->SetXTitle("GeV/c^2");
68  h1D_mPi0->SetYTitle("Counts / 5 MeV");
69 
70  h1D_massDiff = new TH1F( "h1D_massDiff", "Mass Reconst^2 - Mass Pi0^2",50,-0.15,0.15);
71  h1D_massDiff->SetXTitle("GeV^2");
72  h1D_massDiff->SetYTitle("Counts / 0.006 GeV^2");
73 
74  h1D_mPi0cuts = new TH1F( "h1D_mPi0cuts", "Reconstructed Pi0 Mass (post-cuts)",54,0.03,0.3);
75  h1D_mPi0cuts->SetXTitle("GeV/c^2");
76  h1D_mPi0cuts->SetYTitle("Counts / 5 MeV");
77 
78  h1D_mPi0_window = new TH1F( "h1D_mPi0_window", "Reconstructed Pi0 Mass (post-cuts) actually used",54,0.03,0.3);
79  h1D_mPi0_window->SetXTitle("GeV/c^2");
80  h1D_mPi0_window->SetYTitle("Counts / 5 MeV");
81 
82  h1D_nhits_unordered = new TH1F("h1D_nhits_unordered", "Number of hits at channel" ,100,0,100);
83  h1D_nhits_unordered->SetXTitle("Number of hits");
84 
85  h1D_nhits = new TH1F("h1D_nhits", "Number of hits as function of channel number" ,n_channels,0,2799);
86  h1D_nhits->SetXTitle("Channel Number");
87  h1D_nhits->SetYTitle("Number of Hits");
88 
89  m_fcalgeom = new DFCALGeometry();
90  m_pi0mass = 0.1349766;
91  m_etamass = 0.54751;
92  m_nmesons = 0;
93  m_mesonmass = 0.;
94  m_massbias = 0.;
95 
96  // set up matrices for calibration...
97  m_nhits.ResizeTo(m_nElements,1);
98  m_mD.ResizeTo(m_nElements,1);
99  m_mC.ResizeTo(m_nElements,m_nElements);
100  m_mL.ResizeTo(m_nElements,1);
101  m_mLt.ResizeTo(m_nElements,1);
102 
103  m_nhits.Zero();
104  m_mD.Zero();
105  m_mC.Zero();
106  m_mL.Zero();
107  m_mLt.Zero();
108  m_event = 0;
109  m_TotPastCuts = 0;
110 
111  japp->RootUnLock();
112 
113 
114  return NOERROR;
115 }
117 {
118  return m_fcalgeom->channel( my_y/4 +29, my_x/4 +29 );
119 }
120 
121 
122 //returns in (x,y) coordinates in cm NOT in single step units or in row,column form
123 pair<int,int> JEventProcessor_FCALgains::AbsNumtoXY(int channel)
124 {
125  int row = 4*(m_fcalgeom->row(channel) -29);
126  int column = 4*(m_fcalgeom->column(channel) -29);
127  pair<int,int> xy = make_pair(column,row);
128  return xy;
129 }
130 
131 
132 //------------------
133 // brun
134 //------------------
135 jerror_t JEventProcessor_FCALgains::brun(jana::JEventLoop* locEventLoop, int32_t locRunNumber)
136 {
137  DApplication* locApplication = dynamic_cast<DApplication*>(locEventLoop->GetJApplication());
138  double z_target; double z_fcal;
139  const DGeometry* dgeom = locApplication->GetDGeometry(locRunNumber);
140 
141  dgeom->GetTargetZ(z_target);
142  dgeom->GetFCALZ(z_fcal);
143 
144  z_diff = z_fcal - z_target;
145 
146  return NOERROR;
147 }
148 
149 
150 ////////
151 
152 
153 
154 
155 jerror_t JEventProcessor_FCALgains::evnt(jana::JEventLoop* locEventLoop, uint64_t locEventNumber)
156 {
157 
158  // This is called for every event. Use of common resources like writing
159  // to a file or filling a histogram should be mutex protected. Using
160  // locEventLoop->Get(...) to get reconstructed objects (and thereby activating the
161  // reconstruction algorithm) should be done outside of any mutex lock
162  // since multiple threads may call this method at the same time.
163  //
164  // Here's an example:
165  //
166  // vector<const MyDataClass*> mydataclasses;
167  // locEventLoop->Get(mydataclasses);
168  //
169  // japp->RootWriteLock();
170  // ... fill historgrams or trees ...
171  // japp->RootUnLock();
172 
173  // DOCUMENTATION:
174  // ANALYSIS library: https://halldweb1.jlab.org/wiki/index.php/GlueX_Analysis_Software
175 
176  vector< const DFCALHit*> hits;
177  locEventLoop->Get( hits );
178 
179  vector< const DFCALShower* > locFCALShowers;
180  vector< const DVertex* > kinfitVertex;
181  vector< const DTrackTimeBased* > locTrackTimeBased;
182  if( hits.size() <= 500 ){ // only form clusters and showers if there aren't too many hits
183 
184  locEventLoop->Get(locFCALShowers);
185  locEventLoop->Get(kinfitVertex);
186  locEventLoop->Get(locTrackTimeBased);
187 }
188 
189  vector < const DFCALShower * > matchedShowers;
190  vector < const DTrackTimeBased* > matchedTracks;
191  vector <const DChargedTrackHypothesis*> locParticles;
192 
193 
194 
195 
196  Double_t kinfitVertexX = 0.0, kinfitVertexY = 0.0, kinfitVertexZ = 0.0;
197 
198  for (unsigned int i = 0 ; i < kinfitVertex.size(); i++)
199  {
200  kinfitVertexX = kinfitVertex[i]->dSpacetimeVertex.X();
201  kinfitVertexY = kinfitVertex[i]->dSpacetimeVertex.Y();
202  kinfitVertexZ = kinfitVertex[i]->dSpacetimeVertex.Z();
203  }
204 
205  DVector3 norm(0.0,0.0,-1);
206  DVector3 pos,mom;
207 
208 
209  for (unsigned int i=0; i < locTrackTimeBased.size() ; ++i){
210  for (unsigned int j=0; j< locFCALShowers.size(); ++j){
211 
212  Double_t x = locFCALShowers[j]->getPosition().X();
213  Double_t y = locFCALShowers[j]->getPosition().Y();
214 
215  DVector3 pos_FCAL(0,0,638);
216  if (locTrackTimeBased[i]->rt->GetIntersectionWithPlane(pos_FCAL,norm,pos,mom,NULL,NULL,NULL,SYS_FCAL)==NOERROR)
217  {
218  Double_t trkmass = locTrackTimeBased[i]->mass();
219  Double_t FOM = TMath::Prob(locTrackTimeBased[i]->chisq, locTrackTimeBased[i]->Ndof);
220  Double_t dRho = sqrt(((pos.X() - x)*(pos.X() - x)) + ((pos.Y() - y)* (pos.Y() - y)));
221  if(trkmass < 0.15 && dRho < 5 && FOM > 0.01 ) {
222  matchedShowers.push_back(locFCALShowers[j]);
223 
224  }
225  }
226 
227  }
228  }
229 
230  japp->RootWriteLock();
231 
232  if (locFCALShowers.size() >=2) {
233 
234  for(unsigned int i=0; i<locFCALShowers.size(); i++)
235  {
236  if (find(matchedShowers.begin(), matchedShowers.end(),locFCALShowers[i]) != matchedShowers.end()) continue;
237 
238  const DFCALShower *s1 = locFCALShowers[i];
239 
240  vector<const DFCALCluster*> associated_clusters1;
241 
242  s1->Get(associated_clusters1);
243  Double_t dx1 = s1->getPosition().X() - kinfitVertexX;
244  Double_t dy1 = s1->getPosition().Y() - kinfitVertexY;
245  Double_t dz1 = s1->getPosition().Z() - kinfitVertexZ;
246 
247  Double_t R1 = sqrt(dx1*dx1 + dy1*dy1 + dz1*dz1);
248  Double_t E1 = s1->getEnergy();
249  Double_t t1 = s1->getTime();
250  TLorentzVector sh1_p(E1*dx1/R1, E1*dy1/R1, E1*dz1/R1, E1);
251 
252  for(unsigned int j=i+1; j<locFCALShowers.size(); j++){
253  const DFCALShower *s2 = locFCALShowers[j];
254  if (find(matchedShowers.begin(), matchedShowers.end(),s2) != matchedShowers.end()) continue;
255 
256  vector<const DFCALCluster*> associated_clusters2;
257  s2->Get(associated_clusters2);
258  Double_t dx2 = s2->getPosition().X() - kinfitVertexX;
259  Double_t dy2 = s2->getPosition().Y() - kinfitVertexY;
260  Double_t dz2 = s2->getPosition().Z() - kinfitVertexZ;
261 
262  Double_t R2 = sqrt(dx2*dx2 + dy2*dy2 + dz2*dz2);
263  Double_t E2 = s2->getEnergy();
264  Double_t t2 = s2->getTime();
265 
266  TLorentzVector sh2_p(E2*dx2/R2, E2*dy2/R2, E2*dz2/R2, E2);
267  TLorentzVector ptot = sh1_p+sh2_p;
268  Double_t inv_mass = ptot.M();
269 
270  if(E1>1&&E2>1 && s1->getPosition().Pt() > 20*k_cm && s2->getPosition().Pt() > 20*k_cm && (fabs (t1-t2) < 10)) InvMass2->Fill(inv_mass);
271 
272  h1D_mPi0->Fill(inv_mass);
273  h1D_massDiff->Fill(inv_mass*inv_mass-m_pi0mass*m_pi0mass);
274  ///
275  if(E1 < 1 || E2 < 1) continue;
276  //if(E1 < 0.5 || E2 < 0.5) continue;
277  if(fabs(t1-t2) >= 10.) continue;
278  if(s1->getPosition().Pt() <= 20. || s2->getPosition().Pt() <=20.) continue;
279  if(s1->getPosition().Pt() >= 108. || s2->getPosition().Pt() >=108.) continue;
280  if(inv_mass < 0.03 || inv_mass > 0.3) continue;
281  h1D_mPi0cuts->Fill(inv_mass);
282  if(inv_mass < MASS_CUT_LO || inv_mass > MASS_CUT_HI) continue;
283  h1D_mPi0_window->Fill(inv_mass);
284 
285 
286  m_massbias += (inv_mass*inv_mass - m_pi0mass*m_pi0mass);
287  // if(m_event % 1000 == 0) cout << "Current mass bias is " << m_massbias << endl;
288  h1D_massbias->SetBinContent(2,m_massbias);
289 
290  for(unsigned int loc_j = 0; loc_j < associated_clusters1.size(); loc_j++)
291  {
292  for(unsigned int loc_jj = 0; loc_jj < associated_clusters2.size(); loc_jj++)
293  {
294 
295  vector< DFCALCluster::DFCALClusterHit_t > hits1 = associated_clusters1[loc_j]->GetHits();
296  vector< DFCALCluster::DFCALClusterHit_t > hits2 = associated_clusters2[loc_jj]->GetHits();
297 
298  //cout << "Size of hits1: " <<hits1.size() << endl;
299  //cout << "Size of hits2: " <<hits2.size() << endl;
300 
301  vector< std::pair <double, pair<int,int> > > frac_en;
302 
303  double e_sum1=0; double e_sum2=0;
304 
305 
306  Int_t numhits_per_cluster1 = associated_clusters1[loc_j]->GetNHits();
307  Int_t numhits_per_cluster2 = associated_clusters2[loc_jj]->GetNHits();
308 
309  // cout << " numhits_per_cluster1: " << numhits_per_cluster1 << endl;
310  // cout << " numhits_per_cluster2: " << numhits_per_cluster2 << endl;
311 
312  if(numhits_per_cluster1 == 1 || numhits_per_cluster2 == 1) continue;
313  for( int i = 0; i < numhits_per_cluster1; ++i ){
314 
315  //Get (x,y) for each cluster, convert to a scale factor
316  //double hiten1 = hits1[i].E;
317  int my_channel = XYtoAbsNum(hits1[i].x,hits1[i].y);
318 
319 
320  if(NHITS_CUT!=0) {
321  if(nhits_vec[my_channel] < NHITS_CUT) continue;
322  }
323  e_sum1+=hits1[i].E;
324  }
325 
326  for( int i = 0; i < numhits_per_cluster2; ++i ){
327 
328  //double hiten2 = hits2[i].E;
329  int my_channel = XYtoAbsNum(hits2[i].x,hits2[i].y);
330 
331 
332 
333  if(NHITS_CUT!=0) {
334  if(nhits_vec[my_channel] < NHITS_CUT) continue;
335  }
336 
337 
338  e_sum2+=hits2[i].E;
339  }
340 
341  //cout << " e_sum1: "<< e_sum1 << "E1: " <<E1<< endl;
342  //cout << " e_sum2: "<< e_sum2 << "E2: " <<E2<< endl;
343 
344 
345  //Calculate fractional energies, fill matrices
346  for( int i = 0; i < numhits_per_cluster1; ++i ){
347  int my_x = hits1[i].x;
348  int my_y = hits1[i].y;
349  double my_E = hits1[i].E;
350  m_nhits[XYtoAbsNum(my_x,my_y)]+=1;
351  // hits2D->Fill(my_x/4,my_y/4,1);
352 
353  frac_en.push_back(make_pair( (my_E / e_sum1), make_pair(my_x,my_y)));
354  }
355 
356  for( int i = 0; i < numhits_per_cluster2; ++i ){
357  int my_x = hits2[i].x ;
358  int my_y = hits2[i].y ;
359  double my_E = hits2[i].E;
360  m_nhits[XYtoAbsNum(my_x,my_y)]+=1;
361  frac_en.push_back(make_pair( (my_E / e_sum2), make_pair(my_x,my_y)));
362  }
363 
364  for(unsigned int i = 0; i < frac_en.size(); ++i) {
365  int my_x1 = (frac_en[i].second).first ;
366  int my_y1 = (frac_en[i].second).second ;
367  int my_index1 = XYtoAbsNum(my_x1, my_y1);
368 
369  m_mD[my_index1][0] += -(inv_mass * inv_mass - m_pi0mass*m_pi0mass)*(inv_mass * inv_mass)*frac_en[i].first;
370  m_mL[my_index1][0] += (inv_mass * inv_mass)*frac_en[i].first;
371 
372  for(unsigned int ii = 0; ii < frac_en.size(); ++ii) {
373  int my_x2 = (frac_en[ii].second).first;
374  int my_y2 = (frac_en[ii].second).second;
375  int my_index2 = XYtoAbsNum(my_x2, my_y2);
376 
377  m_mC[my_index1][my_index2] += (inv_mass*inv_mass)*(inv_mass*inv_mass)*(frac_en[i].first)*(frac_en[ii].first);
378  }
379  }
380 
381  for(int p=0; p<n_channels; p++){
382  h1D_mD->SetBinContent(p+1,m_mD[p][0]);
383  h1D_mL->SetBinContent(p+1,m_mL[p][0]);
384  h1D_nhits->SetBinContent(p+1,m_nhits[p][0]);
385  h1D_nhits_unordered->Fill(m_nhits[p][0]);
386 
387  for(int j=0; j<n_channels; j++){
388  h2D_mC->SetBinContent(p+1,j+1,m_mC[p][j]);
389  }
390  }
391 
392  //Done filling matrices
393 
394  }
395  }
396  }
397  }
398 }
399  japp->RootUnLock();
400 
401  // japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
402 
403  return NOERROR;
404 }
405 
406 //------------------
407 // erun
408 //------------------
410 {
411  // This is called whenever the run number changes, before it is
412  // changed to give you a chance to clean up before processing
413  // events from the next run number.
414 
415  return NOERROR;
416 }
417 
418 
419 
420 //------------------
421 // fini
422 //------------------
424 {
425  // Called before program exit after event processing is finished.
426  return NOERROR;
427 }
428 
429 
double getEnergy() const
Definition: DFCALShower.h:156
static double E1[100]
TVector3 DVector3
Definition: DVector3.h:14
jerror_t brun(jana::JEventLoop *locEventLoop, int32_t locRunNumber)
Called every time a new run number is detected.
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
double getTime() const
Definition: DFCALShower.h:161
static TH1F * InvMass1
#define y
static TH1F * InvMass2
bool GetFCALZ(double &z_fcal) const
z-location of front face of CCAL in cm
Definition: DGeometry.cc:1718
JApplication * japp
const double k_cm
Definition: units.h:14
int XYtoAbsNum(int my_x, int my_y)
InitPlugin_t InitPlugin
pair< int, int > AbsNumtoXY(int channel)
TLatex * t1
DGeometry * GetDGeometry(unsigned int run_number)
Definition: GlueX.h:22
int column(int channel) const
Definition: DFCALGeometry.h:65
double sqrt(double)
jerror_t evnt(jana::JEventLoop *locEventLoop, uint64_t locEventNumber)
Called every event.
jerror_t init(void)
Called once at program start.
int channel(int row, int column) const
jerror_t fini(void)
Called after last event of last event source has been processed.
int row(int channel) const
Definition: DFCALGeometry.h:64
DVector3 getPosition() const
Definition: DFCALShower.h:151
bool GetTargetZ(double &z_target) const
z-location of center of target
Definition: DGeometry.cc:1933
jerror_t erun(void)
Called every time run number changes, provided brun has been called.