Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DCCALShower_factory.cc
Go to the documentation of this file.
1 /*
2  * File: DCCALHit_factory.cc
3  *
4  * Created on 11/25/18 by A.S.
5  * use structure similar to FCAL
6  */
7 
8 #include <iostream>
9 #include <fstream>
10 #include <math.h>
11 #include <DVector3.h>
12 #include <mutex>
13 using namespace std;
14 
15 #include <JANA/JEvent.h>
16 #include <JANA/JCalibration.h>
17 #include <JANA/JResourceManager.h>
18 using namespace jana;
19 
20 #include "DIRC/DDIRCLutReader.h"
21 #include "CCAL/DCCALShower.h"
23 #include "CCAL/DCCALHit.h"
24 #include "CCAL/DCCALGeometry.h"
25 #include "HDGEOMETRY/DGeometry.h"
26 
27 #include "hycal.h"
28 
29 static mutex CCAL_MUTEX;
30 static bool CCAL_PROFILE_LOADED = false;
31 
32 //------------------
33 // LoadCCALProfileData
34 //------------------
35 bool DCCALShower_factory::LoadCCALProfileData(JApplication *japp, int32_t runnumber)
36 {
37  /*
38  static bool first = true;
39 
40  // we are just setting some global stuff inside island.F so it's OK
41  if(!first) {
42  return true;
43  } else {
44  first = false;
45  }
46  */
48  return true;
49  else
50  CCAL_PROFILE_LOADED = true;
51 
52  string ccal_profile_file;
53  gPARMS->SetDefaultParameter("CCAL_PROFILE_FILE", ccal_profile_file, "CCAL profile data file name");
54 
55  // make sure we have a pointer to the JApplication
56  if(japp == nullptr)
57  return false;
58 
59  // follow similar procedure as other resources (DMagneticFieldMapFineMesh)
60  map<string,string> profile_file_name;
61  JCalibration *jcalib = japp->GetJCalibration(runnumber);
62  if(jcalib->GetCalib("/CCAL/profile_data/profile_data_map", profile_file_name))
63  jout << "Can't find requested /CCAL/profile_data/profile_data_map in CCDB for this run!" << endl;
64  else if(profile_file_name.find("map_name") != profile_file_name.end()
65  && profile_file_name["map_name"] != "None") {
66  JResourceManager *jresman = japp->GetJResourceManager(runnumber);
67  ccal_profile_file = jresman->GetResource(profile_file_name["map_name"]);
68  }
69 
70  jout<<"Reading CCAL profile data from "<<ccal_profile_file<<" ..."<<endl;
71 
72  // check to see if we actually have a file
73  if(ccal_profile_file.empty()) {
74  jerr << "Empty file..." << endl;
75  return false;
76  }
77 
78 
79  char fname_buf[1000];
80  sprintf(fname_buf,"%s",ccal_profile_file.c_str());
81  int ccal_profile_file_size = (int)ccal_profile_file.size();
82  init_island_(fname_buf, &ccal_profile_file_size);
83 
84 /*
85  ifstream ccal_profile(ccal_profile_file.c_str());
86  for(int i=0; i<=500; i++) {
87  for(int j=0; j<i; j++) {
88  int id1, id2;
89  float fcell_hyc, fd2c;
90 
91  ccal_profile >> id1 >> id2 >> fcell_hyc >> fd2c;
92 
93  //cout << id1 << " " << id2 << " " << fcell_hyc << " " << fd2c << endl;
94 
95  acell[0][i][j] = fcell_hyc;
96  acell[0][j][i] = fcell_hyc;
97  ad2c[0][i][j] = fd2c;
98  ad2c[0][j][i] = fd2c;
99  }
100  }
101 
102  // copy the results to the FORTRAN routines
103  init_island_(acell, ad2c);
104 
105  // cleanup
106  ccal_profile.close();
107 */
108 
109  return true;
110 }
111 
112 
113 //----------------
114 // Constructor
115 //----------------
117 {
118  // Set defaults
119  MIN_CLUSTER_BLOCK_COUNT = 2;
120  MIN_CLUSTER_SEED_ENERGY = 0.035; // GeV
121  MIN_CLUSTER_ENERGY = 0.05; // GeV
122  MAX_CLUSTER_ENERGY = 15.9; // GeV
123  TIME_CUT = 15.0 ; // ns
124  MAX_HITS_FOR_CLUSTERING = 80;
125  SHOWER_DEBUG = 0;
126  DO_NONLINEAR_CORRECTION = 0;
127  CCAL_RADIATION_LENGTH = 0.86;
128  CCAL_CRITICAL_ENERGY = 1.1e-3;
129 
130 
131  gPARMS->SetDefaultParameter("CCAL:SHOWER_DEBUG", SHOWER_DEBUG);
132  gPARMS->SetDefaultParameter("CCAL:MIN_CLUSTER_BLOCK_COUNT", MIN_CLUSTER_BLOCK_COUNT);
133  gPARMS->SetDefaultParameter("CCAL:MIN_CLUSTER_SEED_ENERGY", MIN_CLUSTER_SEED_ENERGY);
134  gPARMS->SetDefaultParameter("CCAL:MIN_CLUSTER_ENERGY", MIN_CLUSTER_ENERGY);
135  gPARMS->SetDefaultParameter("CCAL:MAX_CLUSTER_ENERGY", MAX_CLUSTER_ENERGY);
136  gPARMS->SetDefaultParameter("CCAL:MAX_HITS_FOR_CLUSTERING", MAX_HITS_FOR_CLUSTERING);
137  gPARMS->SetDefaultParameter("CCAL:TIME_CUT",TIME_CUT,"time cut for associating CCAL hits together into a cluster");
138  gPARMS->SetDefaultParameter("CCAL:DO_NONLINEAR_CORRECTION", DO_NONLINEAR_CORRECTION);
139  gPARMS->SetDefaultParameter("CCAL:CCAL_RADIATION_LENGTH", CCAL_RADIATION_LENGTH);
140  gPARMS->SetDefaultParameter("CCAL:CCAL_CRITICAL_ENERGY", CCAL_CRITICAL_ENERGY);
141 
142 }
143 
144 
145 //------------------
146 // brun
147 //------------------
148 jerror_t DCCALShower_factory::brun(JEventLoop *eventLoop, int32_t runnumber)
149 {
150 
151  DApplication *dapp = dynamic_cast<DApplication*>(eventLoop->GetJApplication());
152  const DGeometry *geom = dapp->GetDGeometry(runnumber);
153 
154  //vector<double> CCALpos;
155  //geom->Get("//composition[@name='ComptonEMcal']/posXYZ[@volume='comptonEMcal']/@X_Y_Z",CCALpos);
156 
157  if (geom) {
158  geom->GetTargetZ(m_zTarget);
159  geom->GetCCALZ(m_CCALfront);
160  }
161  else{
162  cerr << "No geometry accessbile." << endl;
163  return RESOURCE_UNAVAILABLE;
164  }
165 
166 
167  //------------------------------------------------------------
168  // read in island algorithm configurations
169 
170  std::unique_lock<std::mutex> lck(CCAL_MUTEX);
171  LoadCCALProfileData(eventLoop->GetJApplication(), runnumber);
172  lck.unlock();
173 
174  //------------------------------------------------------------
175  // read in the nonlinearity parameters:
176 
177  vector< vector<float> > nonlin_params;
178  if( eventLoop->GetCalib("/CCAL/nonlinear_energy_correction",nonlin_params) )
179  jout << "Error loading /CCAL/nonlinear_energy_correction !" << endl;
180  else {
181  if( (int)nonlin_params.size() != CCAL_CHANS ) {
182  cout << "DCCALShower_factory: Wrong number of entries to nonlinear energy correction table (should be 144)." << endl;
183  for( int ii = 0; ii < CCAL_CHANS; ++ii ) {
184  Nonlin_p0.push_back(0.0);
185  Nonlin_p1.push_back(0.0);
186  Nonlin_p2.push_back(0.0);
187  Nonlin_p3.push_back(0.0);
188  }
189  } else {
190  for( vector< vector<float> >::const_iterator iter = nonlin_params.begin(); iter != nonlin_params.end(); ++iter ) {
191  if( iter->size() != 4 ) {
192  cout << "DCCALShower_factory: Wrong number of values in nonlinear energy correction table (should be 4)" << endl;
193  continue;
194  }
195 
196  Nonlin_p0.push_back( (*iter)[0] );
197  Nonlin_p1.push_back( (*iter)[1] );
198  Nonlin_p2.push_back( (*iter)[2] );
199  Nonlin_p3.push_back( (*iter)[3] );
200 
201  }
202  }
203  }
204 
205 
206  //------------------------------------------------------------
207  // read in shower timewalk parameters
208 
209  vector< vector<float> > timewalk_params;
210  if( eventLoop->GetCalib("/CCAL/shower_timewalk_correction",timewalk_params) )
211  jout << "Error loading /CCAL/shower_timewalk_correction !" << endl;
212  else {
213  if( (int)timewalk_params.size() != 2 ) {
214  cout << "DCCALShower_factory: Wrong number of entries to timewalk correction table (should be 144)." << endl;
215  for( int ii = 0; ii < 2; ++ii ) {
216  timewalk_p0.push_back(0.0);
217  timewalk_p1.push_back(0.0);
218  timewalk_p2.push_back(0.0);
219  timewalk_p3.push_back(0.0);
220  }
221  } else {
222  for( vector< vector<float> >::const_iterator iter = timewalk_params.begin(); iter != timewalk_params.end(); ++iter ) {
223  if( iter->size() != 4 ) {
224  cout << "DCCALShower_factory: Wrong number of values in timewalk correction table (should be 4)" << endl;
225  continue;
226  }
227 
228  timewalk_p0.push_back( (*iter)[0] );
229  timewalk_p1.push_back( (*iter)[1] );
230  timewalk_p2.push_back( (*iter)[2] );
231  timewalk_p3.push_back( (*iter)[3] );
232 
233  }
234  }
235  }
236 
237  if( SHOWER_DEBUG ) {
238  cout << "\n\nNONLIN_P0 NONLIN_P1 NONLIN_P2 NONLIN_P3" << endl;
239  for(int ii = 0; ii < (int)Nonlin_p0.size(); ii++) {
240  cout << Nonlin_p0[ii] << " " << Nonlin_p1[ii] << " " << Nonlin_p2[ii] << " " << Nonlin_p3[ii] << endl;
241  }
242  cout << "\n\n";
243  }
244  //------------------------------------------------------------
245 
246  // LoadCCALProfileData() runs some Fortran routines which need access to globals - dangerous!
247  //std::lock_guard<std::mutex> lck(CCAL_MUTEX);
248 
249  //LoadCCALProfileData(eventLoop->GetJApplication(), runnumber);
250 
251  return NOERROR;
252 }
253 
254 
255 //------------------
256 // evnt
257 //------------------
258 jerror_t DCCALShower_factory::evnt(JEventLoop *eventLoop, uint64_t eventnumber)
259 {
260 
261  vector< const DCCALHit* > ccalhits;
262  eventLoop->Get( ccalhits );
263  int n_h_hits = (int)ccalhits.size();
264  if( n_h_hits > MAX_HITS_FOR_CLUSTERING ) return NOERROR;
265 
266 
267 
268  // Geometry:
269 
270  vector< const DCCALGeometry* > ccalGeomVect;
271  eventLoop->Get( ccalGeomVect );
272  if (ccalGeomVect.size() < 1)
273  return OBJECT_NOT_AVAILABLE;
274  const DCCALGeometry& ccalGeom = *(ccalGeomVect[0]);
275 
276  DVector3 vertex(0.0, 0.0, m_zTarget); // for now, use center of target as vertex
277 
278 
279  int n_h_clusters = 0;
280  vector< ccalcluster_t > ccalcluster; // will hold all clusters
281  vector< cluster_t > cluster_storage; // will hold elements of every cluster
282 
283 
284  // The Fortran code below uses common blocks, so we need to set a lock
285  // so that different threads are not running on top of each other
286 
287  std::unique_lock<std::mutex> lck(CCAL_MUTEX);
288 
289 
290  // if a single module has multiple hits in same event, one will overwrite the
291  // other in the cluster pattern. for now just keep hit with larger energy:
292 
293  vector< const DCCALHit* > hit_storage;
294  cleanHitPattern( ccalhits, hit_storage );
295  n_h_hits = (int)hit_storage.size();
296 
297 
298  static int ich[MCOL][MROW];
299  for(int icol = 1; icol <= MCOL; ++icol) {
300  for(int irow = 1; irow <= MROW; ++irow) {
301  ECH(icol,irow) = 0;
302  STAT_CH(icol,irow) = 0;
303  if(icol>=6 && icol<=7 && irow>=6 && irow<=7) { STAT_CH(icol,irow) = -1; }
304  ich[icol-1][irow-1] = (12-icol)+(12-irow)*12;
305  }
306  }
307 
308  NCOL = 12; NROW = 12;
310 
311  for (int i = 0; i < n_h_hits; i++) {
312  const DCCALHit *ccalhit = hit_storage[i];
313  int row = 12-ccalhit->row;
314  int col = 12-ccalhit->column;
315  ECH(col,row) = int(ccalhit->E*10.+0.5);
316  }
317 
318  main_island_();
319 
320  int init_clusters = adcgam_cbk_.nadcgam;
321  for(int k = 0; k < init_clusters; ++k) {
322 
323  cluster_t clust_storage; // stores hit information of cluster cells
324  ccalcluster_t clust; // stores cluster parameters
325 
326  // results of main_island_():
327  float e = adcgam_cbk_.u.fadcgam[k][0];
328  float x = adcgam_cbk_.u.fadcgam[k][1];
329  float y = adcgam_cbk_.u.fadcgam[k][2];
330  float xc = adcgam_cbk_.u.fadcgam[k][4];
331  float yc = adcgam_cbk_.u.fadcgam[k][5];
332  float chi2 = adcgam_cbk_.u.fadcgam[k][6];
333  int type = adcgam_cbk_.u.iadcgam[k][7];
334  int dime = adcgam_cbk_.u.iadcgam[k][8];
335  int status = adcgam_cbk_.u.iadcgam[k][10];
336 
337  if( dime < MIN_CLUSTER_BLOCK_COUNT ) { continue; }
338  if( e < MIN_CLUSTER_ENERGY || e > MAX_CLUSTER_ENERGY ) { continue; }
339  n_h_clusters += 1;
340 
341 
342  //------------------------------------------------------------
343  // Do energy and position corrections:
344 
345  float ecellmax = -1; int idmax = -1;
346  float sW = 0.0;
347  float xpos = 0.0;
348  float ypos = 0.0;
349  float e1 = 0.0;
350  float W;
351 
352  // get id of cell with max energy:
353  for(int j = 0; j < (dime>MAX_CC ? MAX_CC : dime); ++j) {
354  float ecell = 1.e-4*(float)ICL_IENER(k,j);
355  int id = ICL_INDEX(k,j);
356  int kx = (id/100), ky = id%100;
357  id = ich[kx-1][ky-1];
358  e1 += ecell;
359  if(ecell>ecellmax) {
360  ecellmax = ecell;
361  idmax = id;
362  }
363  }
364  // x and y pos of max cell
365  float xmax = ccalGeom.positionOnFace(idmax).X();
366  float ymax = ccalGeom.positionOnFace(idmax).Y();
367 
368 
369  // loop over hits in cluster and fill clust_storage
370  int ccal_id;
371  for(int j = 0; j < (dime>MAX_CC ? MAX_CC : dime); ++j) {
372  int id = ICL_INDEX(k,j);
373  int kx = (id/100), ky = id%100;
374  ccal_id = ich[kx-1][ky-1];
375 
376  float ecell = 1.e-4*(float)ICL_IENER(k,j);
377  float xcell = ccalGeom.positionOnFace(ccal_id).X();
378  float ycell = ccalGeom.positionOnFace(ccal_id).Y();
379 
380  if(type%10 == 1 || type%10 == 2) {
381  xcell += xc;
382  ycell += yc;
383  }
384 
385 
386  float hittime = 0.;
387  for(int ihit = 0; ihit < n_h_hits; ihit++) {
388  int trialid = 12*(hit_storage[ihit]->row) + hit_storage[ihit]->column;
389  if(trialid == ccal_id) {
390  hittime = hit_storage[ihit]->t;
391  //iop = hit_storage[ihit]->intOverPeak;
392  break;
393  }
394  }
395 
396  if( ecell > 0.009 && fabs(xcell-xmax) < 6. && fabs(ycell-ymax) < 6.) {
397  W = 4.2 + log(ecell/e);
398  if(W > 0) { // i.e. if cell has > 1.5% of cluster energy
399  sW += W;
400  xpos += xcell*W;
401  ypos += ycell*W;
402  }
403  }
404 
405  clust_storage.id[j] = ccal_id;
406  clust_storage.E[j] = ecell;
407  clust_storage.x[j] = xcell;
408  clust_storage.y[j] = ycell;
409  clust_storage.t[j] = hittime;
410 
411  }
412 
413  for(int j = dime; j < MAX_CC; ++j) // zero the rest
414  clust_storage.id[j] = -1;
415 
416  float weightedTime = getEnergyWeightedTime( clust_storage, dime );
417  float showerTime = getCorrectedTime( weightedTime, e );
418 
419 
420  //------------------------------------------------------------
421  // Apply correction for finite depth of hit:
422 
423  float x1, y1;
424  float zV = vertex.Z();
425  float z0 = m_CCALfront - zV;
426  if(sW) {
427  float dz;
428  dz = shower_depth(e);
429  float zk = 1. / (1. + dz/z0);
430  x1 = zk*xpos/sW;
431  y1 = zk*ypos/sW;
432  } else {
433  printf("WRN bad cluster log. coord, center id = %i %f\n", idmax, e);
434  x1 = 0.0;
435  y1 = 0.0;
436  }
437 
438  // fill cluster bank for further processing:
439  clust.type = type;
440  clust.nhits = dime;
441  clust.id = idmax;
442  clust.E = e;
443  clust.time = showerTime;
444  clust.x = x;
445  clust.y = y;
446  clust.chi2 = chi2;
447  clust.x1 = x1;
448  clust.y1 = y1;
449  clust.emax = ecellmax;
450  clust.status = status;
451 
452  cluster_storage.push_back(clust_storage);
453  ccalcluster.push_back(clust);
454 
455  }
456 
457 
458  // Release the lock
459  lck.unlock();
460 
461 
462  if(n_h_clusters == 0) return NOERROR;
463  final_cluster_processing(ccalcluster, n_h_clusters);
464 
465 
466  //------------------------------------------------------------
467  // Fill Shower Object:
468 
469  for(int k = 0; k < n_h_clusters; ++k) {
470 
471  // Build hit object
472  DCCALShower *shower = new DCCALShower;
473 
474  shower->E = ccalcluster[k].E;
475  shower->x = ccalcluster[k].x;
476  shower->y = ccalcluster[k].y;
477  shower->z = m_CCALfront;
478  shower->x1 = ccalcluster[k].x1;
479  shower->y1 = ccalcluster[k].y1;
480  shower->time = ccalcluster[k].time;
481  shower->chi2 = ccalcluster[k].chi2;
482  shower->type = ccalcluster[k].type;
483  shower->dime = ccalcluster[k].nhits;
484  shower->status = ccalcluster[k].status;
485  shower->sigma_E = ccalcluster[k].sigma_E;
486  shower->Emax = ccalcluster[k].emax;
487  shower->idmax = ccalcluster[k].id;
488 
489  for(int icell=0; icell<ccalcluster[k].nhits; icell++) {
490  shower->id_storage[icell] = cluster_storage[k].id[icell];
491  shower->en_storage[icell] = cluster_storage[k].E[icell];
492  shower->t_storage[icell] = cluster_storage[k].t[icell];
493 
494  // if(cluster_storage[k].E[icell] > 0.) { // maybe redundant if-statement???
495  // shower->AddAssociatedObject(ccalhits[ cluster_storage[k].id[icell] ]);
496  // }
497  }
498 
499  _data.push_back( shower );
500  }
501 
502 
503  return NOERROR;
504 
505 }
506 
507 
508 
509 
510 //------------------------
511 // cleeanHitPattern
512 //------------------------
513 void DCCALShower_factory::cleanHitPattern( vector< const DCCALHit* > hitarray, vector< const DCCALHit* > &hitarrayClean )
514 {
515 
516  for( vector< const DCCALHit* >::const_iterator iHit = hitarray.begin(); iHit != hitarray.end(); ++iHit ) {
517  int id12 = ((*iHit)->row)*12 + (*iHit)->column;
518  int findVal = -1;
519  for( vector<const DCCALHit*>::size_type ii = 0; ii != hitarrayClean.size(); ++ii ) {
520  int id = 12*(hitarrayClean[ii]->row) + hitarrayClean[ii]->column;
521  if( id == id12 ) { findVal = (int)ii; break; }
522  }
523  if( findVal >= 0 ) {
524  if( (*iHit)->E > hitarrayClean[findVal]->E ) {
525  hitarrayClean.erase( hitarrayClean.begin()+findVal );
526  hitarrayClean.push_back( (*iHit) );
527  }
528  } else {
529  hitarrayClean.push_back( (*iHit) );
530  }
531  }
532 
533  return;
534 
535 }
536 
537 
538 
539 
540 //----------------------------
541 // final_cluster_processing
542 //----------------------------
544 {
545 
546 
547  //--------------------------
548  // final cluster processing:
549  // - do nolinear energy correction
550  // - add status and energy resolution
551 
552  for(int i = 0; i < n_h_clusters; ++i) {
553  float e = ccalcluster[i].E;
554  int idmax = ccalcluster[i].id;
555  float ecorr = e;
556  if(DO_NONLINEAR_CORRECTION) ecorr = energy_correct( e, idmax );
557 
558  if( SHOWER_DEBUG ) {
559  cout << "\n\nShower energy before correction: " << e << " GeV" << endl;
560  cout << "Shower energy after correction: " << ecorr << " GeV\n\n" << endl;
561  }
562 
563  //float x = ccalcluster[i].x1;
564  //float y = ccalcluster[i].y1;
565  // coord_align(i, e, idmax);
566 
567  int status = ccalcluster[i].status;
568  int type = ccalcluster[i].type;
569  int dime = ccalcluster[i].nhits;
570 
571  if(status < 0) {
572  printf("error in island : cluster with negative status");
573  exit(1);
574  }
575  int itp, ist;
576  itp = 0;
577  if(status==1) itp += 1;
578 
579  for(int k = 0; k < (dime>MAX_CC ? MAX_CC : dime); ++k) {
580  if(itp>=10) {itp = 12; break;}
581  }
582 
583  ist = type;
584  if(status>2) ist += 20;
585 
586  double se = sqrt(0.9*0.9*e*e+2.5*2.5*e+1.0); // from HYCAL reconstruction, may need to tune
587  se /= 100.;
588  if(itp%10==1)
589  se *= 1.5;
590  else if(itp%10==2) {
591  if(itp>10)
592  se *= 0.8;
593  else
594  se *=1.25;
595  }
596  ccalcluster[i].E = ecorr;
597  ccalcluster[i].type = itp;
598  ccalcluster[i].status = ist;
599  ccalcluster[i].sigma_E = se;
600  }
601 
602  return;
603 
604 }
605 
606 
607 
608 //------------------------
609 // getEnergyWeightedTime
610 //------------------------
612 {
613 
614  float weightedtime = 0.;
615  float totEn = 0;
616  for(int j = 0; j < (nHits > MAX_CC ? MAX_CC : nHits); ++j) {
617  weightedtime += cluster_storage.t[j]*cluster_storage.E[j];
618  totEn += cluster_storage.E[j];
619  }
620  weightedtime /= totEn;
621 
622  return weightedtime;
623 
624 }
625 
626 
627 
628 //------------------------
629 // getCorrectedTime
630 //------------------------
631 
632 float DCCALShower_factory::getCorrectedTime( float time, float energy )
633 {
634  // timewalk correction:
635  // t + p0*exp(p1 + p2*E) + p3
636 
637  int iPar;
638  if( energy < 1.0 ) iPar = 0;
639  else iPar = 1;
640 
641  float dt = timewalk_p0[iPar]*exp(timewalk_p1[iPar] + timewalk_p2[iPar]*energy) + timewalk_p3[iPar];
642  float t_cor = time - dt;
643 
644  return t_cor;
645 
646 }
647 
648 
649 
650 
651 
652 //------------------------
653 // shower_depth
654 //------------------------
655 float DCCALShower_factory::shower_depth( float energy )
656 {
657 
658  float z0 = CCAL_RADIATION_LENGTH, e0 = CCAL_CRITICAL_ENERGY;
659  float depth = (energy > 0.) ? z0*log(1.+energy/e0) : 0.;
660  return depth;
661 
662 }
663 
664 
665 
666 //------------------------
667 // energy_correct
668 //------------------------
669 float DCCALShower_factory::energy_correct( float energy, int id )
670 {
671 
672  if( Nonlin_p1[id] == 0. && Nonlin_p2[id] == 0. && Nonlin_p3[id] == 0.) return energy;
673  if( energy < 0.5 || energy > 12. ) return energy;
674 
675 
676  float emin = 0., emax = 12.;
677  float e0 = (emin+emax)/2.;
678 
679  float de1 = energy - emin*f_nonlin( emin, id );
680  float de2 = energy - emax*f_nonlin( emax, id );
681  float de = energy - e0*f_nonlin( e0, id );
682 
683  while( fabs(emin-emax) > 1.e-5 ) {
684  if( de1*de > 0. && de2*de < 0.) {
685  emin = e0;
686  de1 = energy - emin*f_nonlin( emin, id );
687  } else {
688  emax = e0;
689  de2 = energy - emax*f_nonlin( emax, id );
690  }
691  e0 = (emin+emax)/2.;
692  de = energy - e0*f_nonlin( e0, id );
693  }
694 
695  return e0;
696 
697 }
698 
699 
700 //------------------------
701 // f_nonlin
702 //------------------------
703 float DCCALShower_factory::f_nonlin( float e, int id )
704 {
705 
706  return pow( (e/Nonlin_p0[id]), Nonlin_p1[id] + Nonlin_p2[id]*e + Nonlin_p3[id]*e*e );
707 
708 }
709 
DVector2 positionOnFace(int row, int column) const
DApplication * dapp
int id[MAX_CC]
Definition: hycal.h:60
void main_island_()
float energy_correct(float energy, int id)
int row
Definition: DCCALHit.h:22
bool GetCCALZ(double &z_ccal) const
Definition: DGeometry.cc:1700
int id
Definition: hycal.h:72
int column
Definition: DCCALHit.h:23
TVector3 DVector3
Definition: DVector3.h:14
float energy_correct(float c_energy, int central_id)
float shower_depth(float energy)
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
sprintf(text,"Post KinFit Cut")
ccalhit_t ccalhit[T_BLOCKS]
#define y
double Emax
Definition: DCCALShower.h:46
struct @6 adcgam_cbk_
double x
Definition: DCCALShower.h:39
double y1
Definition: DCCALShower.h:43
float x
Definition: hycal.h:77
double en_storage[MAX_CC]
Definition: DCCALShower.h:51
#define MROW
Definition: hycal.h:6
float E[MAX_CC]
Definition: hycal.h:61
#define MCOL
Definition: hycal.h:5
double z
Definition: DCCALShower.h:41
int id_storage[MAX_CC]
Definition: DCCALShower.h:50
static bool CCAL_PROFILE_LOADED
double t_storage[MAX_CC]
Definition: DCCALShower.h:52
float x[MAX_CC]
Definition: hycal.h:62
float x1
Definition: hycal.h:80
float emax
Definition: hycal.h:83
JApplication * japp
#define NROW
Definition: hycal.h:129
double y
Definition: DCCALShower.h:40
float f_nonlin(float e, int id)
float shower_depth(float energy)
double chi2
Definition: DCCALShower.h:44
TEllipse * e
bool LoadCCALProfileData(JApplication *japp, int32_t runnumber)
#define SET_YSIZE
Definition: hycal.h:123
int n_h_hits
#define ICL_IENER(M, N)
Definition: hycal.h:117
DGeometry * GetDGeometry(unsigned int run_number)
#define CRYS_SIZE_X
Definition: hycal.h:56
double x1
Definition: DCCALShower.h:42
cluster_t cluster_storage[MAX_CLUSTERS]
double E
Definition: DCCALShower.h:38
float y1
Definition: hycal.h:81
float t[MAX_CC]
Definition: hycal.h:64
double sqrt(double)
float E
Definition: DCCALHit.h:26
float y
Definition: hycal.h:78
int type
Definition: hycal.h:70
float chi2
Definition: hycal.h:79
void cleanHitPattern(vector< const DCCALHit * > hitarray, vector< const DCCALHit * > &hitarrayClean)
#define CRYS_SIZE_Y
Definition: hycal.h:57
void final_cluster_processing(vector< ccalcluster_t > &ccalcluster, int n_h_clusters)
jerror_t brun(JEventLoop *eventLoop, int32_t runnumber)
float getEnergyWeightedTime(cluster_t cluster_storage, int nHits)
int status
Definition: hycal.h:84
float E
Definition: hycal.h:73
float time
Definition: hycal.h:76
#define SET_XSIZE
Definition: hycal.h:122
#define ECH(M, N)
Definition: hycal.h:109
int nhits
Definition: hycal.h:71
double time
Definition: DCCALShower.h:47
int n_h_clusters
Double_t ymax
Definition: bcal_hist_eff.C:91
ccalcluster_t ccalcluster[MAX_CLUSTERS]
jerror_t evnt(JEventLoop *eventLoop, uint64_t eventnumber)
printf("string=%s", string)
#define MAX_CC
Definition: hycal.h:20
#define ICL_INDEX(M, N)
Definition: hycal.h:116
#define STAT_CH(M, N)
Definition: hycal.h:113
float getCorrectedTime(float time, float energy)
static mutex CCAL_MUTEX
bool GetTargetZ(double &z_target) const
z-location of center of target
Definition: DGeometry.cc:1933
float y[MAX_CC]
Definition: hycal.h:63
void init_island_(char filename[1000], int *name_length)
#define NCOL
Definition: hycal.h:128
double sigma_E
Definition: DCCALShower.h:45