15 #include <JANA/JEvent.h>
16 #include <JANA/JCalibration.h>
17 #include <JANA/JResourceManager.h>
52 string ccal_profile_file;
53 gPARMS->SetDefaultParameter(
"CCAL_PROFILE_FILE", ccal_profile_file,
"CCAL profile data file name");
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"]);
70 jout<<
"Reading CCAL profile data from "<<ccal_profile_file<<
" ..."<<endl;
73 if(ccal_profile_file.empty()) {
74 jerr <<
"Empty file..." << endl;
80 sprintf(fname_buf,
"%s",ccal_profile_file.c_str());
81 int ccal_profile_file_size = (int)ccal_profile_file.size();
119 MIN_CLUSTER_BLOCK_COUNT = 2;
120 MIN_CLUSTER_SEED_ENERGY = 0.035;
121 MIN_CLUSTER_ENERGY = 0.05;
122 MAX_CLUSTER_ENERGY = 15.9;
124 MAX_HITS_FOR_CLUSTERING = 80;
126 DO_NONLINEAR_CORRECTION = 0;
127 CCAL_RADIATION_LENGTH = 0.86;
128 CCAL_CRITICAL_ENERGY = 1.1e-3;
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);
162 cerr <<
"No geometry accessbile." << endl;
163 return RESOURCE_UNAVAILABLE;
171 LoadCCALProfileData(eventLoop->GetJApplication(), runnumber);
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;
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);
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;
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] );
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;
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);
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;
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] );
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;
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;
270 vector< const DCCALGeometry* > ccalGeomVect;
271 eventLoop->Get( ccalGeomVect );
272 if (ccalGeomVect.size() < 1)
273 return OBJECT_NOT_AVAILABLE;
276 DVector3 vertex(0.0, 0.0, m_zTarget);
293 vector< const DCCALHit* > hit_storage;
294 cleanHitPattern( ccalhits, hit_storage );
295 n_h_hits = (int)hit_storage.size();
299 for(
int icol = 1; icol <=
MCOL; ++icol) {
300 for(
int irow = 1; irow <=
MROW; ++irow) {
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;
311 for (
int i = 0; i <
n_h_hits; i++) {
313 int row = 12-ccalhit->
row;
314 int col = 12-ccalhit->
column;
315 ECH(col,row) = int(ccalhit->
E*10.+0.5);
321 for(
int k = 0; k < init_clusters; ++k) {
337 if( dime < MIN_CLUSTER_BLOCK_COUNT ) {
continue; }
338 if( e < MIN_CLUSTER_ENERGY || e > MAX_CLUSTER_ENERGY ) {
continue; }
345 float ecellmax = -1;
int idmax = -1;
353 for(
int j = 0; j < (dime>
MAX_CC ?
MAX_CC : dime); ++j) {
354 float ecell = 1.e-4*(float)
ICL_IENER(k,j);
356 int kx = (
id/100), ky =
id%100;
357 id = ich[kx-1][ky-1];
371 for(
int j = 0; j < (dime>
MAX_CC ?
MAX_CC : dime); ++j) {
373 int kx = (
id/100), ky =
id%100;
374 ccal_id = ich[kx-1][ky-1];
376 float ecell = 1.e-4*(float)
ICL_IENER(k,j);
380 if(type%10 == 1 || type%10 == 2) {
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;
396 if( ecell > 0.009 && fabs(xcell-xmax) < 6. && fabs(ycell-ymax) < 6.) {
397 W = 4.2 + log(ecell/e);
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;
413 for(
int j = dime; j <
MAX_CC; ++j)
414 clust_storage.
id[j] = -1;
416 float weightedTime = getEnergyWeightedTime( clust_storage, dime );
417 float showerTime = getCorrectedTime( weightedTime, e );
424 float zV = vertex.Z();
425 float z0 = m_CCALfront - zV;
429 float zk = 1. / (1. + dz/z0);
433 printf(
"WRN bad cluster log. coord, center id = %i %f\n", idmax, e);
443 clust.
time = showerTime;
449 clust.
emax = ecellmax;
452 cluster_storage.push_back(clust_storage);
453 ccalcluster.push_back(clust);
462 if(n_h_clusters == 0)
return NOERROR;
463 final_cluster_processing(ccalcluster, n_h_clusters);
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;
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];
499 _data.push_back( shower );
516 for( vector< const DCCALHit* >::const_iterator iHit = hitarray.begin(); iHit != hitarray.end(); ++iHit ) {
517 int id12 = ((*iHit)->row)*12 + (*iHit)->column;
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; }
524 if( (*iHit)->E > hitarrayClean[findVal]->E ) {
525 hitarrayClean.erase( hitarrayClean.begin()+findVal );
526 hitarrayClean.push_back( (*iHit) );
529 hitarrayClean.push_back( (*iHit) );
553 float e = ccalcluster[i].E;
554 int idmax = ccalcluster[i].id;
559 cout <<
"\n\nShower energy before correction: " << e <<
" GeV" << endl;
560 cout <<
"Shower energy after correction: " << ecorr <<
" GeV\n\n" << endl;
567 int status = ccalcluster[i].status;
568 int type = ccalcluster[i].type;
569 int dime = ccalcluster[i].nhits;
572 printf(
"error in island : cluster with negative status");
577 if(status==1) itp += 1;
579 for(
int k = 0; k < (dime>
MAX_CC ?
MAX_CC : dime); ++k) {
580 if(itp>=10) {itp = 12;
break;}
584 if(status>2) ist += 20;
586 double se =
sqrt(0.9*0.9*e*e+2.5*2.5*e+1.0);
596 ccalcluster[i].E = ecorr;
597 ccalcluster[i].type = itp;
598 ccalcluster[i].status = ist;
599 ccalcluster[i].sigma_E = se;
614 float weightedtime = 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];
620 weightedtime /= totEn;
638 if( energy < 1.0 ) iPar = 0;
641 float dt = timewalk_p0[iPar]*exp(timewalk_p1[iPar] + timewalk_p2[iPar]*energy) + timewalk_p3[iPar];
642 float t_cor = time - dt;
658 float z0 = CCAL_RADIATION_LENGTH, e0 = CCAL_CRITICAL_ENERGY;
659 float depth = (energy > 0.) ? z0*log(1.+energy/e0) : 0.;
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;
676 float emin = 0., emax = 12.;
677 float e0 = (emin+emax)/2.;
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 );
683 while( fabs(emin-emax) > 1.
e-5 ) {
684 if( de1*de > 0. && de2*de < 0.) {
686 de1 = energy - emin*f_nonlin( emin,
id );
689 de2 = energy - emax*f_nonlin( emax,
id );
692 de = energy - e0*f_nonlin( e0,
id );
706 return pow( (e/Nonlin_p0[
id]), Nonlin_p1[
id] + Nonlin_p2[
id]*e + Nonlin_p3[
id]*e*e );
DVector2 positionOnFace(int row, int column) const
float energy_correct(float energy, int id)
bool GetCCALZ(double &z_ccal) const
float energy_correct(float c_energy, int central_id)
float shower_depth(float energy)
sprintf(text,"Post KinFit Cut")
ccalhit_t ccalhit[T_BLOCKS]
double en_storage[MAX_CC]
static bool CCAL_PROFILE_LOADED
float f_nonlin(float e, int id)
float shower_depth(float energy)
bool LoadCCALProfileData(JApplication *japp, int32_t runnumber)
DGeometry * GetDGeometry(unsigned int run_number)
cluster_t cluster_storage[MAX_CLUSTERS]
void cleanHitPattern(vector< const DCCALHit * > hitarray, vector< const DCCALHit * > &hitarrayClean)
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)
ccalcluster_t ccalcluster[MAX_CLUSTERS]
jerror_t evnt(JEventLoop *eventLoop, uint64_t eventnumber)
printf("string=%s", string)
float getCorrectedTime(float time, float energy)
bool GetTargetZ(double &z_target) const
z-location of center of target
void init_island_(char filename[1000], int *name_length)