Bug Summary

File:/home/sdobbs/work/clang/halld_recon/src/libraries/CCAL/DCCALShower_factory.cc
Warning:line 2024, column 16
The left operand of '-' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -main-file-name DCCALShower_factory.cc -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /w/halld-scifs17exp/home/sdobbs/clang/llvm-project/install/lib/clang/12.0.0 -D HAVE_CCDB -D HAVE_RCDB -D HAVE_EVIO -D HAVE_TMVA=1 -D RCDB_MYSQL=1 -D RCDB_SQLITE=1 -D SQLITE_USE_LEGACY_STRUCT=ON -I .Linux_CentOS7.7-x86_64-gcc4.8.5/libraries/CCAL -I libraries/CCAL -I . -I libraries -I libraries/include -I /w/halld-scifs17exp/home/sdobbs/clang/halld_recon/Linux_CentOS7.7-x86_64-gcc4.8.5/include -I external/xstream/include -I /usr/include/tirpc -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/root/root-6.08.06/include -I /w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/ccdb/ccdb_1.06.06/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/rcdb/rcdb_0.06.00/cpp/include -I /usr/include/mysql -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/sqlitecpp/SQLiteCpp-2.2.0^bs130/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/sqlite/sqlite-3.13.0^bs130/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/hdds/hdds-4.9.0/Linux_CentOS7.7-x86_64-gcc4.8.5/src -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/xerces-c/xerces-c-3.1.4/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/evio/evio-4.4.6/Linux-x86_64/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/backward -internal-isystem /usr/local/include -internal-isystem /w/halld-scifs17exp/home/sdobbs/clang/llvm-project/install/lib/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /home/sdobbs/work/clang/halld_recon/src -ferror-limit 19 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-01-21-110224-160369-1 -x c++ libraries/CCAL/DCCALShower_factory.cc
1
2/*
3 * File: DCCALHit_factory.cc
4 *
5 * Created on 11/25/18 by A.S.
6 * use structure similar to FCAL
7 */
8
9#include "CCAL/DCCALShower_factory.h"
10
11
12static mutex CCAL_MUTEX;
13//static bool CCAL_PROFILE_LOADED = false;
14
15
16//==========================================================
17//
18// Constructor
19//
20//==========================================================
21
22DCCALShower_factory::DCCALShower_factory()
23{
24 // Set defaults:
25
26 MIN_CLUSTER_BLOCK_COUNT = 2;
27 MAX_HITS_FOR_CLUSTERING = 80;
28 MIN_CLUSTER_SEED_ENERGY = 0.035; /* [GeV] */
29 MIN_CLUSTER_ENERGY = 0.05; /* [GeV] */
30 MAX_CLUSTER_ENERGY = 15.9; /* [GeV] */
31 TIME_CUT = 15.0; /* [ns] */
32
33 SHOWER_DEBUG = 0;
34 DO_NONLINEAR_CORRECTION = 1;
35
36 CCAL_RADIATION_LENGTH = 0.86;
37 CCAL_CRITICAL_ENERGY = 1.1e-3;
38
39 LOG_POS_CONST = 4.2;
40
41
42 gPARMS->SetDefaultParameter( "CCAL:SHOWER_DEBUG", SHOWER_DEBUG );
43 gPARMS->SetDefaultParameter( "CCAL:MIN_CLUSTER_BLOCK_COUNT", MIN_CLUSTER_BLOCK_COUNT,
44 "minimum number of blocks to form a cluster" );
45 gPARMS->SetDefaultParameter( "CCAL:MIN_CLUSTER_SEED_ENERGY", MIN_CLUSTER_SEED_ENERGY,
46 "minimum energy for a block to be considered as a seed for a cluster" );
47 gPARMS->SetDefaultParameter( "CCAL:MIN_CLUSTER_ENERGY", MIN_CLUSTER_ENERGY,
48 "minimum allowed cluster energy" );
49 gPARMS->SetDefaultParameter( "CCAL:MAX_CLUSTER_ENERGY", MAX_CLUSTER_ENERGY,
50 "maximum allowed cluster energy" );
51 gPARMS->SetDefaultParameter( "CCAL:MAX_HITS_FOR_CLUSTERING", MAX_HITS_FOR_CLUSTERING,
52 "maximum hits allowed to call clustering algorithm" );
53 gPARMS->SetDefaultParameter( "CCAL:TIME_CUT", TIME_CUT,
54 "time cut for associating CCAL hits together into a cluster" );
55 gPARMS->SetDefaultParameter( "CCAL:DO_NONLINEAR_CORRECTION", DO_NONLINEAR_CORRECTION,
56 "set this to zero when no nonlinear correction is desired" );
57 gPARMS->SetDefaultParameter( "CCAL:CCAL_RADIATION_LENGTH", CCAL_RADIATION_LENGTH );
58 gPARMS->SetDefaultParameter( "CCAL:CCAL_CRITICAL_ENERGY", CCAL_CRITICAL_ENERGY );
59 gPARMS->SetDefaultParameter( "CCAL:LOG_POS_CONST", LOG_POS_CONST );
60
61 VERBOSE = 0; ///< >0 once off info ; >2 event by event ; >3 everything
62 gPARMS->SetDefaultParameter("DFCALShower:VERBOSE", VERBOSE, "Verbosity level for DFCALShower objects and factories");
63}
64
65
66
67
68//==========================================================
69//
70// brun
71//
72//==========================================================
73
74jerror_t DCCALShower_factory::brun(JEventLoop *locEventLoop, int32_t runnumber)
75{
76 // Only print messages for one thread whenever run number change
77 static pthread_mutex_t print_mutex = PTHREAD_MUTEX_INITIALIZER{ { 0, 0, 0, 0, 0, 0, 0, { 0, 0 } } };
78 static set<int> runs_announced;
79 pthread_mutex_lock(&print_mutex);
80 bool print_messages = false;
81 if(runs_announced.find(runnumber) == runs_announced.end()){
82 print_messages = true;
83 runs_announced.insert(runnumber);
84 }
85 pthread_mutex_unlock(&print_mutex);
86
87
88 DApplication *dapp = dynamic_cast<DApplication*>(eventLoop->GetJApplication());
89 const DGeometry *geom = dapp->GetDGeometry(runnumber);
90
91 if (geom) {
92 geom->GetTargetZ(m_zTarget);
93 geom->GetCCALPosition(m_CCALdX,m_CCALdY,m_CCALfront);
94 }
95 else{
96 jerr << "No geometry accessible." << endl;
97 return RESOURCE_UNAVAILABLE;
98 }
99
100
101 //------------------------------------------------------//
102 //----------- Read in shower profile data -----------//
103
104 std::unique_lock<std::mutex> lck(CCAL_MUTEX);
105
106 string ccal_profile_file;
107 gPARMS->SetDefaultParameter("CCAL_PROFILE_FILE", ccal_profile_file,
108 "CCAL profile data file name");
109
110 // follow similar procedure as other resources (DMagneticFieldMapFineMesh)
111
112 map< string,string > profile_file_name;
113 JCalibration *jcalib = dapp->GetJCalibration(runnumber);
114
115 if( jcalib->GetCalib("/CCAL/profile_data/profile_data_map", profile_file_name) )
116 {
117 jout << "Can't find requested /CCAL/profile_data/profile_data_map in CCDB for this run!"
118 << endl;
119
120 } else if( profile_file_name.find("map_name") != profile_file_name.end()
121 && profile_file_name["map_name"] != "None" )
122 {
123 JResourceManager *jresman = dapp->GetJResourceManager(runnumber);
124 ccal_profile_file = jresman->GetResource(profile_file_name["map_name"]);
125 }
126
127 if(print_messages)
128 jout<<"Reading CCAL profile data from "<<ccal_profile_file<<" ..."<<endl;
129
130 // check to see if we actually have a file
131 if(ccal_profile_file.empty())
132 {
133 if(print_messages)
134 jerr << "Empty file..." << endl;
135 return RESOURCE_UNAVAILABLE;
136 }
137
138 ifstream ccal_profile(ccal_profile_file.c_str());
139 for(int i=0; i<=500; i++) {
140 for(int j=0; j<=i; j++) {
141 int id1, id2;
142 double fcell_hyc, fd2c;
143
144 ccal_profile >> id1 >> id2 >> fcell_hyc >> fd2c;
145
146 acell[id1][id2] = fcell_hyc;
147 acell[id2][id1] = fcell_hyc;
148 ad2c[id1][id2] = fd2c;
149 ad2c[id2][id1] = fd2c;
150 }
151 }
152 ccal_profile.close();
153
154 lck.unlock();
155
156
157
158
159 //------------------------------------------------------//
160 //---------- Initialize channel status array ----------//
161
162 for(int icol = 0; icol < MCOL12; ++icol) {
163 for(int irow = 0; irow < MROW12; ++irow) {
164 if(icol>=5 && icol<=6 && irow>=5 && irow<=6) { stat_ch[irow][icol] = -1; }
165 else { stat_ch[irow][icol] = 0; }
166 }
167 }
168
169
170
171
172 //------------------------------------------------------//
173 //---------- Read shower timewalk parameters ----------//
174
175 vector< vector<double> > timewalk_params;
176 if( eventLoop->GetCalib("/CCAL/shower_timewalk_correction",timewalk_params) )
177 jout << "Error loading /CCAL/shower_timewalk_correction !" << endl;
178 else {
179 if( (int)timewalk_params.size() != 2 ) {
180 cout << "DCCALShower_factory: Wrong number of entries to timewalk correction table (should be 144)." << endl;
181 for( int ii = 0; ii < 2; ++ii ) {
182 timewalk_p0.push_back(0.0);
183 timewalk_p1.push_back(0.0);
184 timewalk_p2.push_back(0.0);
185 timewalk_p3.push_back(0.0);
186 }
187 } else {
188 for( vector< vector<double> >::const_iterator iter = timewalk_params.begin();
189 iter != timewalk_params.end(); ++iter ) {
190 if( iter->size() != 4 ) {
191 cout << "DCCALShower_factory: Wrong number of values in timewalk correction table (should be 4)" << endl;
192 continue;
193 }
194
195 timewalk_p0.push_back( (*iter)[0] );
196 timewalk_p1.push_back( (*iter)[1] );
197 timewalk_p2.push_back( (*iter)[2] );
198 timewalk_p3.push_back( (*iter)[3] );
199
200 }
201 }
202 }
203
204
205
206
207 //------------------------------------------------------//
208 //--------- Read in non-linearity parameters ----------//
209
210 vector< vector<double> > nonlin_params;
211 if( eventLoop->GetCalib("/CCAL/nonlinear_energy_correction",nonlin_params) )
212 jout << "Error loading /CCAL/nonlinear_energy_correction !" << endl;
213 else {
214 if( (int)nonlin_params.size() != CCAL_CHANS ) {
215 cout << "DCCALShower_factory: Wrong number of entries to nonlinear energy correction table (should be 144)." << endl;
216 for( int ii = 0; ii < CCAL_CHANS; ++ii ) {
217 Nonlin_p0.push_back(0.0);
218 Nonlin_p1.push_back(0.0);
219 Nonlin_p2.push_back(0.0);
220 Nonlin_p3.push_back(0.0);
221 }
222 } else {
223 for( vector< vector<double> >::const_iterator iter = nonlin_params.begin();
224 iter != nonlin_params.end(); ++iter ) {
225 if( iter->size() != 4 ) {
226 cout << "DCCALShower_factory: Wrong number of values in nonlinear energy correction table (should be 4)" << endl;
227 continue;
228 }
229
230 Nonlin_p0.push_back( (*iter)[0] );
231 Nonlin_p1.push_back( (*iter)[1] );
232 Nonlin_p2.push_back( (*iter)[2] );
233 Nonlin_p3.push_back( (*iter)[3] );
234
235 }
236 }
237 }
238
239 if( SHOWER_DEBUG ) {
240 cout << "\n\nNONLIN_P0 NONLIN_P1 NONLIN_P2 NONLIN_P3" << endl;
241 for(int ii = 0; ii < (int)Nonlin_p0.size(); ii++) {
242 cout << Nonlin_p0[ii] << " " << Nonlin_p1[ii] << " " << Nonlin_p2[ii] << " " <<
243 Nonlin_p3[ii] << endl;
244 }
245 cout << "\n\n";
246 }
247
248
249
250
251 return NOERROR;
252}
253
254
255
256
257//==========================================================
258//
259// evnt
260//
261//==========================================================
262
263jerror_t DCCALShower_factory::evnt(JEventLoop *locEventLoop, uint64_t eventnumber)
264{
265
266
267 vector< const DCCALGeometry* > ccalGeomVect;
268 locEventLoop->Get( ccalGeomVect );
269 if (ccalGeomVect.size() < 1)
270 return OBJECT_NOT_AVAILABLE;
271 const DCCALGeometry& ccalGeom = *(ccalGeomVect[0]);
272
273
274
275
276 //------- Get the CCALHits and organize hit pattern -------//
277
278
279 vector< const DCCALHit* > ccalhits;
280 locEventLoop->Get( ccalhits );
281
282 int n_hits = static_cast<int>( ccalhits.size() );
283 if( n_hits < 1 || n_hits > MAX_HITS_FOR_CLUSTERING ) return NOERROR;
284
285
286 vector< vector< const DCCALHit* > > hitPatterns;
287 getHitPatterns( ccalhits, hitPatterns );
288
289 int n_patterns = static_cast<int>( hitPatterns.size() );
290 if( n_patterns < 1 ) return NOERROR;
291
292 vector< ccalcluster_t > ccalClusters; // will hold all clusters
293 vector< cluster_t > clusterStorage; // will hold the constituents of every cluster
294
295
296
297
298 //------- Call island clusterizer on each pattern -------//
299
300
301 for( int ipat = 0; ipat < n_patterns; ipat++ )
302 {
303
304
305 /*----- prepare data in dimensionless format -----*/
306
307 vector< const DCCALHit* > rawHitPattern = hitPatterns[ipat];
308 vector< const DCCALHit* > locHitPattern;
309 cleanHitPattern( rawHitPattern, locHitPattern );
310
311 int n_hits = static_cast<int>( locHitPattern.size() );
312
313 vector< int > ia;
314 vector< int > id;
315
316 for( int ih = 0; ih < n_hits; ih++ ) {
317 const DCCALHit *ccalhit = locHitPattern[ih];
318 int row = 12 - ccalhit->row;
319 int col = 12 - ccalhit->column;
320 int ie = static_cast<int>( ccalhit->E*10. + 0.5 );
321 if( ie > 0 ) {
322 int address = 100*col + row;
323 ia.push_back( address );
324 id.push_back( ie );
325 }
326 }
327
328
329 /*------------- call to island -------------*/
330
331 vector< gamma_t > gammas; gammas.clear();// Output of main_island (holds reconstructed photons)
332 main_island( ia, id, gammas );
333
334
335 /*------------ post-island processing ------------*/
336
337 int init_clusters = static_cast<int>( gammas.size() );
338 if( !init_clusters ) continue;
339
340 processShowers( gammas, ccalGeom, locHitPattern, eventnumber,
341 ccalClusters, clusterStorage );
342
343
344 } // end looping over hit patterns
345
346
347
348
349 //-------------- Fill DCCALShower Object --------------//
350
351 int n_clusters = static_cast<int>( ccalClusters.size() );
352
353 for( int k = 0; k < n_clusters; k++ ) {
354
355 DCCALShower *shower = new DCCALShower;
356
357 shower->E = ccalClusters[k].E;
358 shower->Esum = ccalClusters[k].Esum;
359
360 shower->x = ccalClusters[k].x+m_CCALdX;
361 shower->y = ccalClusters[k].y+m_CCALdY;
362 shower->x1 = ccalClusters[k].x1+m_CCALdX;
363 shower->y1 = ccalClusters[k].y1+m_CCALdY;
364 shower->z = m_CCALfront;
365
366 shower->chi2 = ccalClusters[k].chi2;
367 shower->sigma_E = ccalClusters[k].sigma_E;
368 shower->Emax = ccalClusters[k].emax;
369 shower->time = ccalClusters[k].time;
370
371 shower->dime = ccalClusters[k].nhits;
372 shower->idmax = ccalClusters[k].idmax;
373 shower->id = ccalClusters[k].id;
374
375 shower->type = ccalClusters[k].type;
376
377 int showTypeVal = (ccalClusters[k].type)/10;
378 shower->ClusterType = static_cast<ClusterType_t>( showTypeVal/2 );
379 shower->PeakType = static_cast<PeakType_t>( showTypeVal%2 );
380 //shower->ExyztCovariance(i, j)
381 float xerr = 0.1016;// / sqrt(ccalClusters[k].E) + 0.2219; // HARD CODED VALUE!!!!
382 float yerr = 0.1016;// / sqrt(ccalClusters[k].E) + 0.2219; // HARD CODED VALUE!!!!
383 float zerr = 2.5; // HARD CODED VALUE!!!!
384 float terr = 0.2; // HARD CODED VALUE!!!!
385 float eerr = 0.5;//pow(ccalClusters[k].E, 2) * (0.01586 / ccalClusters[k].E + 0.0002342 / pow(ccalClusters[k].E, 2) + 1.696e-6); // HARD CODED VALUE!!!!
386 //copy xyz errors into covariance matrix
387 shower->ExyztCovariance.ResizeTo(5,5);
388 for (int col = 0; col < 5; col ++) {
389 for (int row = 0; row < 5; row ++) {
390 if (col != row) shower->ExyztCovariance[col][row] = 0;
391 }
392 }
393 shower->ExyztCovariance[0][0] = pow(xerr, 2);
394 shower->ExyztCovariance[1][1] = pow(yerr, 2);
395 shower->ExyztCovariance[2][2] = pow(zerr, 2);
396 shower->ExyztCovariance[3][3] = pow(terr, 2);
397 shower->ExyztCovariance[4][4] = pow(eerr, 2);
398
399 if (VERBOSE>2) {printf("(E,x,y,z,t) "); shower->ExyztCovariance.Print(); }
400
401 for( int icell = 0; icell < ccalClusters[k].nhits; icell++ ) {
402
403 int hitID = clusterStorage[k].id[icell];
404 float hitX = ccalGeom.positionOnFace( hitID ).X();
405 float hitY = ccalGeom.positionOnFace( hitID ).Y();
406 int hitROW = ccalGeom.row( hitY );
407 int hitCOL = ccalGeom.column( hitX );
408
409 DCCALHit *clusHit = new DCCALHit;
410 clusHit->row = hitROW;
411 clusHit->column = hitCOL;
412 clusHit->x = hitX;
413 clusHit->y = hitY;
414 clusHit->E = static_cast<float>( 1000.*clusterStorage[k].E[icell] );
415 clusHit->t = static_cast<float>( clusterStorage[k].t[icell] );
416
417 shower->AddAssociatedObject( clusHit );
418
419 }
420
421 _data.push_back( shower );
422 }
423
424
425 return NOERROR;
426
427}
428
429
430
431
432//==========================================================
433//
434// getHitPatterns
435//
436//==========================================================
437
438void DCCALShower_factory::getHitPatterns( vector< const DCCALHit* > hitarray,
439 vector< vector< const DCCALHit* > > &hitPatterns )
440{
441
442 /*------------------------------
443
444 Method for sorting hit patterns:
445
446 1. Find hit with largest energy.
447 2. Sort hit vector in order of increasing time-difference from this hit
448 3. Push all hits within 15 ns of max hit to a new vector (first few elements of sorted vec)
449 4. Erase the elements that were moved from the previous vector
450 - maybe steps 3&4 can be done simultaneously?
451 5. Push the new vector back to the hitPatterns vector
452 6. Repeat steps 1-5 until no hits remain in original hitarray
453
454 --------------------------------*/
455
456
457 int n_hits = static_cast<int>( hitarray.size() );
458
459 if( n_hits < 1 ) return;
460 if( n_hits < 2 ) {
461 vector< const DCCALHit* > hitVec;
462 hitVec.push_back( hitarray[0] );
463 hitPatterns.push_back( hitVec );
464 return;
465 }
466
467
468 vector< const DCCALHit* > clonedHitArray = hitarray;
469
470 while( clonedHitArray.size() )
471 {
472
473 vector< const DCCALHit* > locHitVec;
474
475 float maxE = -1.;
476 float maxT = 1.e6;
477
478 for( unsigned int ih = 0; ih < clonedHitArray.size(); ih++ ) {
479 float trialE = clonedHitArray[ih]->E;
480 if( trialE > maxE ) { maxE = trialE; maxT = clonedHitArray[ih]->t; }
481 }
482
483 if( maxE < 0. ) break;
484
485
486 sortByTime( clonedHitArray, maxT );
487
488
489 n_hits = static_cast<int>( clonedHitArray.size() );
490
491 int n_good_hits = 0;
492 for( int ih = 0; ih < n_hits; ih++ ) {
493
494 const DCCALHit *locHit = clonedHitArray[ih];
495 float timeDiff = fabs( locHit->t - maxT );
496
497 if( timeDiff < TIME_CUT ) {
498 locHitVec.push_back( locHit );
499 n_good_hits++;
500 } else { break; }
501
502 }
503
504 if( locHitVec.size() ) hitPatterns.push_back( locHitVec );
505
506 clonedHitArray.erase( clonedHitArray.begin(), clonedHitArray.begin() + n_good_hits );
507
508 }
509
510
511 return;
512
513}
514
515
516
517
518//==========================================================
519//
520// sortByTime
521//
522//==========================================================
523
524void DCCALShower_factory::sortByTime( vector< const DCCALHit* > &hitarray, float hitTime )
525{
526
527 int nhits = static_cast<int>( hitarray.size() );
528
529 if( nhits < 2 ) return; // nothing to sort
530
531 for( int ih = 1; ih < nhits; ih++ )
532 {
533
534 float timeDiff = fabs( hitarray[ih]->t - hitTime );
535 float lastTimeDiff = fabs( hitarray[ih-1]->t - hitTime );
536
537 if( timeDiff <= lastTimeDiff )
538 {
539
540 const DCCALHit *Hit = hitarray[ih];
541
542 for( int ii = ih-1; ii >= -1; ii-- ) {
543
544 if( ii >= 0 ) {
545
546 const DCCALHit *locHit = hitarray[ii];
547 float locTimeDiff = fabs( locHit->t - hitTime );
548
549 if( timeDiff < locTimeDiff ) {
550 hitarray[ii+1] = locHit;
551 } else {
552 hitarray[ii+1] = Hit;
553 break;
554 }
555 } else {
556 hitarray[0] = Hit;
557 }
558 }
559
560 } // end if statement
561
562 } // end loop over hits
563
564 return;
565}
566
567
568
569
570//==========================================================
571//
572// cleanHitPattern
573//
574//==========================================================
575
576void DCCALShower_factory::cleanHitPattern( vector< const DCCALHit* > hitarray,
577 vector< const DCCALHit* > &hitarrayClean )
578{
579
580 for( vector< const DCCALHit* >::const_iterator iHit = hitarray.begin();
581 iHit != hitarray.end(); ++iHit ) {
582
583 int id12 = ((*iHit)->row)*12 + (*iHit)->column;
584 int findVal = -1;
585 for( vector<const DCCALHit*>::size_type ii = 0; ii != hitarrayClean.size(); ++ii ) {
586 int id = 12*(hitarrayClean[ii]->row) + hitarrayClean[ii]->column;
587 if( id == id12 ) { findVal = (int)ii; break; }
588 }
589 if( findVal >= 0 ) {
590 if( (*iHit)->E > hitarrayClean[findVal]->E ) {
591 hitarrayClean.erase( hitarrayClean.begin()+findVal );
592 hitarrayClean.push_back( (*iHit) );
593 }
594 } else {
595 hitarrayClean.push_back( (*iHit) );
596 }
597
598 }
599
600 return;
601
602}
603
604
605
606
607//==========================================================
608//
609// processShowers
610//
611//==========================================================
612
613void DCCALShower_factory::processShowers( vector< gamma_t > gammas, DCCALGeometry ccalGeom,
614 vector< const DCCALHit* > locHitPattern, int eventnumber,
615 vector< ccalcluster_t > &ccalClusters, vector< cluster_t > &clusterStorage )
616{
617
618
619 //------------- Do some post-island processing -------------//
620
621
622 int n_clusters = 0;
623 int n_hits = static_cast<int>( locHitPattern.size() );
624
625 int init_clusters = static_cast<int>( gammas.size() );
626 for( int k = 0; k < init_clusters; k++ ) {
627
628 ccalcluster_t locCluster; // stores cluster parameters
629 cluster_t locClusterStorage; // stores hit information of cluster cells
630
631 int type = gammas[k].type;
632 int dime = gammas[k].dime;
633 int id = gammas[k].id;
634 double chi2 = gammas[k].chi2;
635 double e = gammas[k].energy;
636 double x = gammas[k].x;
637 double y = gammas[k].y;
638 double xc = gammas[k].xc;
639 double yc = gammas[k].yc;
640
641
642 // check that shower is not just a single module and that energy is reasonable:
643
644 if( dime < MIN_CLUSTER_BLOCK_COUNT ) { continue; }
645 if( e < MIN_CLUSTER_ENERGY || e > MAX_CLUSTER_ENERGY ) { continue; }
646
647 n_clusters++;
648
649
650 //------------ Find cell with max energy ------------//
651
652 double ecellmax = -1; int idmax = -1;
653 double e1 = 0.0;
654 for( int j = 0; j < (dime>MAX_CC60 ? MAX_CC60 : dime); j++ ) {
655
656
657 double ecell = 1.e-4*static_cast<double>( gammas[k].icl_en[j] );
658
659 int ccal_id = gammas[k].icl_in[j];
660 int kx = 12 - (ccal_id/100), ky = 12 - (ccal_id%100);
661
662 ccal_id = ky*12 + kx;
663
664 e1 += ecell;
665 if( ecell > ecellmax ) {
666 ecellmax = ecell;
667 idmax = ccal_id;
668 }
669
670 }
671
672 double xmax = ccalGeom.positionOnFace(idmax).X();
673 double ymax = ccalGeom.positionOnFace(idmax).Y();
674
675
676 //----------- Loop over constituent hits ------------//
677
678 double sW = 0.0;
679 double xpos = 0.0;
680 double ypos = 0.0;
681 double W;
682
683 for( int j = 0; j < (dime>MAX_CC60 ? MAX_CC60 : dime); j++ ) {
684
685 int ccal_id = gammas[k].icl_in[j];
686 int kx = 12 - (ccal_id/100), ky = 12 - (ccal_id%100);
687 ccal_id = ky*12 + kx;
688
689 double ecell = 1.e-4*static_cast<double>( gammas[k].icl_en[j] );
690 double xcell = ccalGeom.positionOnFace( ccal_id ).X();
691 double ycell = ccalGeom.positionOnFace( ccal_id ).Y();
692
693 if(id%10 == 1 || id%10 == 2) {
694 xcell += xc;
695 ycell += yc;
696 }
697
698 double hittime = 0.;
699 for( int ihit = 0; ihit < n_hits; ihit++ ) {
700 int trialid = 12*( locHitPattern[ihit]->row) + locHitPattern[ihit]->column;
701 if( trialid == ccal_id ) {
702 hittime = locHitPattern[ihit]->t;
703 break;
704 }
705 }
706
707 locClusterStorage.id[j] = ccal_id;
708 locClusterStorage.E[j] = ecell;
709 locClusterStorage.x[j] = xcell;
710 locClusterStorage.y[j] = ycell;
711 locClusterStorage.t[j] = hittime;
712
713
714 // The shower position is calculated using logarithmic weighting:
715
716 if( ecell > 0.009 && fabs(xcell-xmax) < 6. && fabs(ycell-ymax) < 6.) {
717 W = LOG_POS_CONST + log(ecell/e);
718 if( W > 0 ) {
719 sW += W;
720 xpos += xcell*W;
721 ypos += ycell*W;
722 }
723 }
724
725 }
726
727 for( int j = dime; j < MAX_CC60; j++ ) // zero the rest
728 locClusterStorage.id[j] = -1;
729
730 double weightedTime = getEnergyWeightedTime( locClusterStorage, dime );
731 double showerTime = getCorrectedTime( weightedTime, e );
732
733
734
735 //------- Get position at surface of Calorimeter -------//
736
737 DVector3 vertex(0.0, 0.0, m_zTarget); // for now, use center of target as vertex
738
739 double x1, y1;
740 double zV = vertex.Z();
741 double z0 = m_CCALfront - zV;
742 if(sW) {
743 double dz = getShowerDepth( e );
744 double zk = 1. / (1. + dz/z0);
745 x1 = zk*xpos/sW;
746 y1 = zk*ypos/sW;
747 } else {
748 printf("WRN bad cluster log. coord at event %i: center id = %i, energy = %f\n",
749 eventnumber, idmax, e);
750 x1 = 0.0;
751 y1 = 0.0;
752 }
753
754
755
756
757 //-------- Calculate nonlinear-corrected energy --------//
758
759
760 if( idmax < 0 ) {
761 printf("WRN negative idmax recorded at event %i; energy = %f\n", eventnumber, e);
762 }
763
764 double ecorr = e;
765 if( DO_NONLINEAR_CORRECTION ) ecorr = getCorrectedEnergy( e, idmax );
766
767 if( SHOWER_DEBUG ) {
768 cout << "\n\nShower energy before correction: " << e << " GeV" << endl;
769 cout << "Shower energy after correction: " << ecorr << " GeV\n\n" << endl;
770 }
771
772
773
774
775 //-------- Get energy resolution (needs updating) --------//
776
777 double se = sqrt( 0.9*0.9*ecorr*ecorr + 2.5*2.5*ecorr + 1.0 );
778 // from HYCAL reconstruction, need to tune
779 se /= 100.;
780
781 if( (type%10)==1 )
782 se *= 1.5;
783 else if( (type%10)==2 )
784 se *= 1.25;
785
786
787
788 //----------------- Fill cluster bank -----------------//
789
790 locCluster.type = type;
791 locCluster.nhits = dime;
792 locCluster.id = id;
793 locCluster.idmax = idmax;
794
795 locCluster.E = ecorr;
796 locCluster.Esum = e1;
797 locCluster.x = x;
798 locCluster.y = y;
799 locCluster.x1 = x1;
800 locCluster.y1 = y1;
801 locCluster.chi2 = chi2;
802 locCluster.time = showerTime;
803 locCluster.emax = ecellmax;
804 locCluster.sigma_E = se;
805
806 clusterStorage.push_back( locClusterStorage );
807 ccalClusters.push_back( locCluster );
808
809 }
810
811
812 return;
813}
814
815
816
817
818//==========================================================
819//
820// getEnergyWeightedTime
821//
822//==========================================================
823
824double DCCALShower_factory::getEnergyWeightedTime( cluster_t clusterStorage, int nHits )
825{
826
827 double weightedtime = 0.;
828 double totEn = 0;
829 for( int j = 0; j < (nHits > MAX_CC60 ? MAX_CC60 : nHits); j++ ) {
830 weightedtime += clusterStorage.t[j]*clusterStorage.E[j];
831 totEn += clusterStorage.E[j];
832 }
833 weightedtime /= totEn;
834
835 return weightedtime;
836
837}
838
839
840
841
842//==========================================================
843//
844// getCorrectedTime
845//
846//==========================================================
847
848double DCCALShower_factory::getCorrectedTime( double time, double energy )
849{
850 // timewalk correction:
851
852 int iPar;
853 if( energy < 1.0 ) iPar = 0;
854 else iPar = 1;
855
856 double dt = timewalk_p0[iPar]*exp( timewalk_p1[iPar] + timewalk_p2[iPar]*energy ) + timewalk_p3[iPar];
857 double t_cor = time - dt;
858
859 return t_cor;
860
861}
862
863
864
865
866//==========================================================
867//
868// getShowerDepth
869//
870//==========================================================
871
872double DCCALShower_factory::getShowerDepth( double energy )
873{
874
875 double z0 = CCAL_RADIATION_LENGTH, e0 = CCAL_CRITICAL_ENERGY;
876 double depth = (energy > 0.) ? z0*log(1.+energy/e0) : 0.;
877 return depth;
878
879}
880
881
882
883
884//==========================================================
885//
886// getCorrectedEnergy
887//
888//==========================================================
889
890double DCCALShower_factory::getCorrectedEnergy( double energy, int id )
891{
892
893 if( id < 0 ) return energy;
894
895 if( Nonlin_p1[id] == 0. && Nonlin_p2[id] == 0. && Nonlin_p3[id] == 0.) return energy;
896 if( Nonlin_p0[id] == 0. ) return energy;
897 //if( energy < 0.5 || energy > 12. ) return energy;
898
899
900 double emin = 0., emax = 12.;
901 double e0 = (emin+emax)/2.;
902
903 double de1 = energy - emin*nonlin_func( emin, id );
904 double de2 = energy - emax*nonlin_func( emax, id );
905 double de = energy - e0*nonlin_func( e0, id );
906
907 while( fabs(emin-emax) > 1.e-5 ) {
908 if( de1*de > 0. && de2*de < 0.) {
909 emin = e0;
910 de1 = energy - emin*nonlin_func( emin, id );
911 } else {
912 emax = e0;
913 de2 = energy - emax*nonlin_func( emax, id );
914 }
915 e0 = (emin+emax)/2.;
916 de = energy - e0*nonlin_func( e0, id );
917 }
918
919 return e0;
920
921}
922
923
924
925
926//==========================================================
927//
928// nonlin_func
929//
930//==========================================================
931
932double DCCALShower_factory::nonlin_func( double e, int id )
933{
934
935 return pow( (e/Nonlin_p0[id]), Nonlin_p1[id] + Nonlin_p2[id]*e + Nonlin_p3[id]*e*e );
936
937}
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963//==========================================================
964//
965// main_island()
966//
967//==========================================================
968
969void DCCALShower_factory::main_island( vector<int> &ia, vector<int> &id, vector<gamma_t> &gammas )
970{
971
972 //----------------------------------------------
973 // Initialize some useful variables:
974
975 int nhits; // number of hits in detector
976 int ncl; // number of clusters
977 vector<int> lencl; // length of a cluster
978
979
980 nhits = static_cast<int>(ia.size());
981 if( nhits == 0 ) return;
982
983 /*
984 The vector 'ia' will hold the addresses of modules that were hit.
985 They're defined as 100*(i+1)+(j+1) where i is column and j is row of the hit module.
986 Row 0, column 0 is bottom right corner of CCAL (looking upstream).
987
988 The 'id' vector holds the energies of the hit modules (in units of 0.1 MeVs).
989 */
990
991
992 //------------------ Search for clusters: ------------------//
993
994
995 ncl = clus_hyc( nhits, ia, id, lencl );
996
997 /*
998 At this point, the vectors ia and id are sorted such that they are grouped
999 together by simply-connected clusters. For example, the first lencl[0] elements of ia give
1000 the addresses of the elements in the first cluster. The next lencl[1] elements
1001 after that give the addresses of the elements in the second cluster.
1002
1003 The clusters here are just created by grouping everything that is physically
1004 next to each other into one cluster - all simply-connected cells are joined in a cluster.
1005 */
1006
1007
1008 //-------------------- Process Cluster: --------------------//
1009
1010 int nadcgam = 0; // number of found clusters
1011
1012 if( ncl <= 0 ) return;
1013
1014 int ipncl = 0;
1015 for( int icl = 0; icl < ncl; icl++ ) {
1016
1017 int ecl = 0;
1018 for( int ii = 0; ii < lencl[icl]; ii++ )
1019 ecl += id[ipncl+ii];
1020 if( ecl > MIN_ENERGY0. ) {
1021
1022 vector< int > icl_a; // addresses of current cluster
1023 vector< int > icl_d; // energies of current cluster
1024
1025 icl_a.insert( icl_a.begin(), ia.begin()+ipncl, ia.begin()+ipncl+lencl[icl] );
1026 icl_d.insert( icl_d.begin(), id.begin()+ipncl, id.begin()+ipncl+lencl[icl] );
1027
1028
1029 if( SHOWER_DEBUG ) {
1030
1031 cout << "\n\n======================" << endl;
1032 cout << "Processing Cluster " << icl << ":" << endl;
1033 for( unsigned int ih = 0; ih < icl_a.size(); ih++ ) {
1034 cout << icl_a[ih] << " " << icl_d[ih] << endl;
1035 }
1036
1037 }
1038
1039 int before = nadcgam;
1040 gams_hyc( lencl[icl], icl_a, icl_d, nadcgam, gammas );
1041 int after = nadcgam;
1042
1043
1044 if( SHOWER_DEBUG ) {
1045 cout << "Reconstructed " << after-before << " gammas. \n\n" << endl;
1046 }
1047
1048
1049 if( nadcgam > MADCGAM50 ) {
1050 nadcgam = MADCGAM50;
1051 break;
1052 }
1053 }
1054 ipncl = ipncl + lencl[icl];
1055 }
1056
1057
1058 //-------------------- Prepare gammas for final processing --------------------//
1059
1060
1061 // convert position to units of cm:
1062
1063 for( int ig = 0; ig < nadcgam; ig++ ) {
1064 gammas[ig].energy /= 10000.;
1065 gammas[ig].x = (static_cast<double>(MCOL12+1)-2.*gammas[ig].x)*xsize2.09/2.;
1066 gammas[ig].y = (static_cast<double>(MROW12+1)-2.*gammas[ig].y)*ysize2.09/2.;
1067 gammas[ig].xc = -gammas[ig].xc*xsize2.09;
1068 gammas[ig].yc = -gammas[ig].yc*ysize2.09;
1069 }
1070
1071
1072 if( nadcgam < 1 ) return;
1073
1074
1075 // sort gammas in order of decreasing energy:
1076
1077 for( int ig = 1; ig < nadcgam; ig++ )
1078 {
1079 if( gammas[ig].energy > gammas[ig-1].energy ) {
1080 gamma_t ref_gam = gammas[ig];
1081
1082 for( int ii = ig-1; ii >= -1; ii-- ) {
1083 if( ii >= 0 ) {
1084 if( ref_gam.energy > gammas[ii].energy ) {
1085 gammas[ii+1] = gammas[ii];
1086 } else {
1087 gammas[ii+1] = ref_gam;
1088 break;
1089 }
1090 } else {
1091 gammas[0] = ref_gam;
1092 }
1093 }
1094 }
1095 }
1096
1097
1098
1099 return;
1100}
1101
1102
1103
1104
1105
1106//==========================================================
1107//
1108// clus_hyc
1109//
1110//==========================================================
1111
1112int DCCALShower_factory::clus_hyc( int nw, vector<int> &ia, vector<int> &id, vector<int> &lencl )
1113{
1114
1115 //---------------- Local Declarations ---------------//
1116
1117 int maxcl = 200; // maximumum number of clusters allowed
1118 int ncl; // number of clusters
1119 int next, iak; //
1120 int ib, ie; //
1121 int ias, iaf; //
1122 int last, lastcl; //
1123 int leng; //
1124 //
1125 int loclencl[200]; // stores the lengths of clusters locally
1126
1127
1128 //---------------- Event Analysis Code --------------//
1129
1130 ncl = 0;
1131 if( nw < 1 ) return ncl;
1132 if( nw < 2 ) { // if only one hit
1133 ncl = 1;
1134 lencl.push_back(1);
1135 return ncl;
1136 }
1137
1138 order_hyc( nw, ia, id ); // sort the addresses (ia) in increasing order
1139
1140 ncl = 0;
1141 next = 0;
1142
1143 for( int k = 1; k < (nw+1); k++ ) {
1144
1145 if( k < nw ) iak = ia[k];
1146 if( (iak-ia[k-1] <= 1) && (k < nw) ) continue;
1147
1148 ib = next;
1149 ie = k-1;
1150 next = k;
1151
1152 if( ncl >= maxcl ) return ncl;
1153 ncl++;
1154
1155 loclencl[ncl-1] = next-ib;
1156 if(ncl == 1) continue;
1157
1158 ias = ia[ib];
1159 iaf = ia[ie];
1160 last = ib-1;
1161 lastcl = ncl-1;
1162
1163 for( int icl = lastcl; icl > 0; icl-- ) {
1164
1165 leng = loclencl[icl-1];
1166 if( (ias-ia[last]) > 100 ) break; // no subclusters to be glued
1167
1168 for( int ii = last; ii >= last-leng+1; ii-- ) {
1169 if( ( ias-ia[ii] ) > 100 ) break;
1170 if( ( iaf-ia[ii] ) >= 100 ) {
1171
1172 if( (icl < (ncl-1)) && (leng <= 10800) ) {
1173
1174 vector< int > iawork;
1175 ucopy1( ia, iawork, last-leng+1, leng );
1176 ucopy2( ia, last+1, last+1-leng, ib-last-1 );
1177 ucopy3( iawork, ia, ib-leng, leng );
1178
1179 vector< int > idwork;
1180 ucopy1( id, idwork, last-leng+1, leng );
1181 ucopy2( id, last+1, last+1-leng, ib-last-1 );
1182 ucopy3( idwork, id, ib-leng, leng );
1183
1184 for( int jj = icl; jj < ncl-1; jj++ ) {
1185 loclencl[jj-1] = loclencl[jj];
1186 }
1187
1188 }
1189
1190 ib = ib-leng;
1191 loclencl[ncl-2] = loclencl[ncl-1]+leng;
1192 ncl = ncl-1;
1193 break;
1194 }
1195 }
1196
1197 last = last-leng;
1198
1199 } // end loop over previous subclusters
1200 } // end loop over all hits
1201
1202 for( int icl = 0; icl < ncl; icl++ ) {
1203 lencl.push_back( loclencl[icl] );
1204 }
1205
1206
1207 return ncl;
1208}
1209
1210
1211
1212
1213
1214//==========================================================
1215//
1216// order_hyc
1217//
1218//==========================================================
1219
1220void DCCALShower_factory::order_hyc( int nw, vector<int> &ia, vector<int> &id )
1221{
1222 // sort ia and id in order of increasing address
1223
1224 if( nw < 2 ) return; // only one hit
1225
1226 for( int k = 1; k < nw; k++ ) { // loop over hits
1227
1228 if( ia[k] <= ia[k-1] ) { // check if address is less than previous entry
1229 int iak = ia[k];
1230 int idk = id[k];
1231
1232 for( int ii = k-1; ii >= -1; ii = ii-1 ) { // loop over the previous entries
1233
1234 if( ii >= 0 ) {
1235 if( iak < ia[ii] ) {
1236 ia[ii+1] = ia[ii];
1237 id[ii+1] = id[ii];
1238 } else {
1239 ia[ii+1] = iak;
1240 id[ii+1] = idk;
1241 break;
1242 }
1243 } else {
1244 ia[0] = iak;
1245 id[0] = idk;
1246 }
1247
1248 } // end loop over previous entries
1249 } // endif
1250 } // end loop over hits
1251
1252
1253 return;
1254}
1255
1256
1257
1258
1259
1260//==========================================================
1261//
1262// gams_hyc
1263//
1264//==========================================================
1265
1266void DCCALShower_factory::gams_hyc( int nadc, vector<int> &ia, vector<int> &id,
1267 int &nadcgam, vector<gamma_t> &gammas )
1268{
1269
1270 //-------------Local Declarations------------//
1271
1272 int ngam0; // number of gammas found before
1273 int niter; // max number of iterations (6)
1274 int npk; // number of peaks in the cluster
1275 int ipnpk[10]; // counter number with max energy in a peak
1276 int igmpk[2][10]; //
1277 int minpk; // min energy of a counter in a cluster
1278 int idelta; //
1279 int itype; // type of peak
1280 int leng; //
1281 int ixypk, ixpk, iypk; //
1282 int ic, idc, in; //
1283 int ixy, ixymax, ixymin; //
1284 int ix, iy, iyc; //
1285 int iwk; //
1286 int iia; //
1287 int ide; //
1288 int idecorr; //
1289
1290 double fw[13];
1291 double chisq; // current value of chi2
1292 double chisq1; // value of chi2 for preliminary gammas separation
1293 double chisq2; // value of chi2 for final gammas separation
1294 double ratio; //
1295 double eg; //
1296 double epk[10]; //
1297 double xpk[10]; //
1298 double ypk[10]; //
1299 double a, dx, dy; //
1300 double e1, x1, y1; //
1301 double e2, x2, y2; //
1302 double fe, fia; //
1303
1304 int idsum;
1305
1306 idelta = 0;
1307 chisq1 = 90.;
1308 chisq2 = 50.;
1309 niter = 6;
1310
1311 ngam0 = nadcgam;
1312
1313
1314
1315 vector<int> iwrk[13]; // working array for resolved peaks
1316 vector<int> idp[13]; // energy of each cell of the island belonging to each peak
1317 vector<double> fwrk[13]; // working array for resolved peaks
1318
1319 // allocate memory for each vector:
1320
1321 for( int ii=0; ii<13; ii++ ) {
1322 iwrk[ii].reserve(nadc);
1323 fwrk[ii].reserve(nadc);
1324 idp[ii].reserve(nadc);
1325 for( int ih=0; ih<nadc; ih++ ) {
1326 iwrk[ii].push_back(0);
1327 fwrk[ii].push_back(0.);
1328 idp[ii].push_back(0);
1329 }
1330 }
1331
1332
1333
1334
1335 //------------------------------------------
1336 // peaks search:
1337
1338 order_hyc( nadc, ia, id );
1339
1340 idsum = 0;
1341 for( int ic = 0; ic < nadc; ic++ )
1342 idsum += id[ic];
1343
1344 if( nadc < 3 )
1345 minpk = 1;
1346 else {
1347 int trial = 7.*log(1. + 0.0001*static_cast<double>(idsum)) + 0.5;
1348 if( trial > 1 ) minpk = trial;
1349 else minpk = 1;
1350 }
1351 minpk *= 100;
1352
1353
1354 npk = 0;
1355
1356 for( ic = 0; ic < nadc; ic++ ) {
1357 idc = id[ic];
1358 if( idc < minpk ) continue;
1359 ixy = ia[ic];
1360 ixymax = ixy + 100 + 1;
1361 ixymin = ixy - 100 - 1;
1362 iyc = ixy - (ixy/100)*100;
1363
1364 int peakVal = 1;
1365
1366 in = ic+1;
1367 while( in < nadc && ia[in] <= ixymax ) {
1368 iy = ia[in] - (ia[in]/100)*100;
1369 if( abs(iy-iyc) <= 1 && id[in] >= idc ) peakVal = 0;
1370 in++;
1371 }
1372
1373 in = ic-1;
1374 while( in >= 0 && ia[in] >= ixymin ) {
1375 iy = ia[in] - (ia[in]/100)*100;
1376 if( abs(iy-iyc) <= 1 && id[in] > idc ) peakVal = 0;
1377 in -= 1;
1378 }
1379
1380 if( !peakVal ) continue;
1381
1382 npk += 1;
1383 ipnpk[npk-1] = ic;
1384 if( npk == 10 || npk >= 10000/nadc-3 ) break;
1385
1386 }
1387
1388 if( npk <= 0 ) return;
1389
1390 if( SHOWER_DEBUG ) cout << "Found " << npk << " peaks. Now processing..." << endl;
1391
1392 //------------------------------------------
1393 // gammas search for one peak:
1394
1395 if( npk == 1 ) {
1396
1397 if( nadcgam >= MADCGAM50-1 ) return;
1398 nadcgam = nadcgam+1;
1399 chisq = chisq2;
1400
1401 ic = ipnpk[0];
1402 ix = ia[ic]/100;
1403 iy = ia[ic] - ix*100;
1404
1405 itype = peak_type( ix, iy );
1406
1407 e2 = 0.;
1408 gamma_hyc( nadc, ia, id, chisq,
1409 e1, x1, y1,
1410 e2, x2, y2 );
1411
1412 gamma_t gam1;
1413 gamma_t gam2;
1414
1415 gam1.type = itype;
1416 gam1.dime = nadc;
1417 gam1.id = 0;
1418
1419 gam1.chi2 = chisq;
1420 gam1.energy = e1;
1421 gam1.x = x1;
1422 gam1.y = y1;
1423 gam1.xc = 0.;
1424 gam1.yc = 0.;
1425
1426 if( e2 > 0. && nadcgam <= MADCGAM50-1 ) {
1427 nadcgam = nadcgam+1;
1428
1429 gam2.type = itype+10;
1430 gam2.dime = nadc;
1431 gam2.id = 2;
1432
1433 gam2.chi2 = chisq;
1434 gam2.energy = e2;
1435 gam2.x = x2;
1436 gam2.y = y2;
1437 gam2.xc = 0.5*(x2-x1);
1438 gam2.yc = 0.5*(y2-y1);
1439
1440 gam1.type = itype+10;
1441 gam1.id = 1;
1442 gam1.xc = 0.5*(x1-x2);
1443 gam1.yc = 0.5*(y1-y2);
1444
1445 for( int jj = 0; jj < nadc; jj++ ) {
1446 if( jj < MAX_CC60 ) {
1447 gam1.icl_in[jj] = ia[jj];
1448 gam2.icl_in[jj] = ia[jj];
1449 gam1.icl_en[jj] = static_cast<int>(static_cast<double>(id[jj])*e1/(e1+e2) + 0.5);
1450 gam2.icl_en[jj] = static_cast<int>(static_cast<double>(id[jj])*e2/(e1+e2) + 0.5);
1451 }
1452 }
1453
1454 gammas.push_back( gam1 );
1455 gammas.push_back( gam2 );
1456
1457 } else {
1458 for( int jj = 0; jj < nadc; jj++ ) {
1459 if( jj < MAX_CC60 ) {
1460 gam1.icl_in[jj] = ia[jj];
1461 gam1.icl_en[jj] = id[jj];
1462 }
1463 }
1464
1465 gammas.push_back( gam1 );
1466
1467 }
1468
1469
1470 } else { // cluster with more than one peak
1471
1472 //------------------------------------------
1473 /*
1474 First step - 1 gamma in each peak.
1475 Do a preliminary estimation of (E,x,y) of each peak, and split each peak into two hits
1476 only if it is badly needed (chi2 improvement is too high).
1477 If this split occurs, it is only for better (E,x,y) estimation, as it will be
1478 rejoined and reanalyzed in the second step.
1479 */
1480 //------------------------------------------
1481
1482
1483 if( nadcgam >= MADCGAM50-1 ) return;
1484
1485 ratio = 1.;
1486 for( int iter = 0; iter < niter; iter++ ) {
1487 for( int ii = 0; ii < nadc; ii++ ) {
1488 iwrk[0].push_back(0);
1489 fwrk[0].push_back(0.);
1490 }
1491
1492 for( int ipk = 0; ipk < npk; ipk++ ) {
1493
1494 ic = ipnpk[ipk];
1495 if( iter > 0 ) ratio = fwrk[ipk+1][ic]/fwrk[npk+1][ic];
1496 eg = ratio*static_cast<double>(id[ic]);
1497 ixypk = ia[ic];
1498 ixpk = ixypk/100;
1499 iypk = ixypk - ixpk*100;
1500 epk[ipk] = eg;
1501 xpk[ipk] = eg*static_cast<double>(ixpk);
1502 ypk[ipk] = eg*static_cast<double>(iypk);
1503
1504 if( ic < nadc-1 ) {
1505 for( int ii = ic+1; ii < nadc; ii++ ) {
1506 ixy = ia[ii];
1507 ix = ixy/100;
1508 iy = ixy - ix*100;
1509 if( ixy-ixypk > 100+1 ) break;
1510 if( abs(iy-iypk) <= 1 ) {
1511 if( iter != 0 ) ratio = fwrk[ipk+1][ii]/fwrk[npk+1][ii];
1512 eg = ratio*static_cast<double>(id[ii]);
1513 epk[ipk] = epk[ipk] + eg;
1514 xpk[ipk] = xpk[ipk] + eg*static_cast<double>(ix);
1515 ypk[ipk] = ypk[ipk] + eg*static_cast<double>(iy);
1516 }
1517 }
1518 }
1519
1520 if( ic > 0 ) {
1521 for( int ii = ic-1; ii >= 0; ii--) {
1522 ixy = ia[ii];
1523 ix = ixy/100;
1524 iy = ixy - ix*100;
1525 if( ixypk-ixy > 100+1 ) break;
1526 if( abs(iy-iypk) <= 1 ) {
1527 if( iter != 0 ) ratio = fwrk[ipk+1][ii]/fwrk[npk+1][ii];
1528 eg = ratio*static_cast<double>(id[ii]);
1529 epk[ipk] = epk[ipk] + eg;
1530 xpk[ipk] = xpk[ipk] + eg*static_cast<double>(ix);
1531 ypk[ipk] = ypk[ipk] + eg*static_cast<double>(iy);
1532 }
1533 }
1534 }
1535
1536 if( epk[ipk] > 0. ) {
1537 xpk[ipk] = xpk[ipk]/epk[ipk];
1538 ypk[ipk] = ypk[ipk]/epk[ipk];
1539 }
1540
1541 for( int ii = 0; ii < nadc; ii++ ) {
1542 ixy = ia[ii];
1543 ix = ixy/100;
1544 iy = ixy - ix*100;
1545 dx = fabs( static_cast<double>(ix) - xpk[ipk] );
1546 dy = fabs( static_cast<double>(iy) - ypk[ipk] );
1547
1548 a = epk[ipk]*cell_hyc( dx, dy );
1549
1550 fwrk[ipk+1][ii] = a;
1551 fwrk[0][ii] = fwrk[0][ii] + fwrk[ipk+1][ii];
1552 iwrk[ipk+1][ii] = static_cast<int>(a + 0.5);
1553 iwrk[0][ii] = iwrk[0][ii] + iwrk[ipk+1][ii];
1554 }
1555
1556
1557 } // end loop over peaks
1558
1559 for( int ii = 0; ii < nadc; ii++ ) {
1560 iwk = iwrk[0][ii];
1561 if( iwk < 1 ) iwk = 1;
1562 iwrk[npk+1][ii] = iwk;
1563
1564 if( fwrk[0][ii] > 1.e-2 )
1565 fwrk[npk+1][ii] = fwrk[0][ii];
1566 else
1567 fwrk[npk+1][ii] = 1.e-2;
1568
1569 }
1570 } // end of iterations to separate peaks in a cluster
1571
1572
1573
1574 if( SHOWER_DEBUG ) {
1575
1576
1577 cout << "\n\n\nAfter 6 iterations: " << endl;
1578 for( int ipk = 0; ipk < npk; ipk++ ) {
1579 cout << "peak " << ipk+1 << ": " << endl;
1580 for( int jj = 0; jj < nadc; jj++ ) {
1581 cout << ia[jj] <<"; "<< id[jj] <<"; "<< fwrk[ipk+1][jj] << endl;
1582 }
1583 }
1584
1585 }
1586
1587
1588
1589
1590 for( int ipk = 0; ipk < npk; ipk++ ) {
1591
1592 vector<int> iwrk_a;
1593 vector<int> iwrk_d;
1594
1595 leng = 0;
1596 for( int ii = 0; ii < nadc; ii++ ) {
1597 if( fwrk[0][ii] > 1.e-2 ) {
1598 ixy = ia[ii];
1599 fe = static_cast<double>(id[ii])*fwrk[ipk+1][ii]/fwrk[0][ii];
1600
1601 if( fe > idelta ) {
1602 leng = leng+1;
1603 iwrk_a.push_back( ixy );
1604 iwrk_d.push_back( static_cast<int>(fe+0.5) );
1605 }
1606
1607 }
1608 }
1609
1610 if( nadcgam >= MADCGAM50-1 ) return;
1611
1612 igmpk[1][ipk] = 0;
1613 if( leng == 0 ) continue;
1614 nadcgam = nadcgam + 1;
1615 chisq = chisq1;
1616
1617 ic = ipnpk[ipk];
1618 ix = ia[ic]/100;
1619 iy = ia[ic] - ix*100;
1620
1621 itype = peak_type( ix, iy );
1622
1623 e2 = 0.;
1624 gamma_hyc( leng, iwrk_a, iwrk_d, chisq,
1625 e1, x1, y1, e2, x2, y2 );
1626
1627 gamma_t gam1;
1628 gamma_t gam2;
1629
1630 gam1.chi2 = chisq;
1631 gam1.type = itype+40;
1632 gam1.energy = e1;
1633 gam1.x = x1;
1634 gam1.y = y1;
1635 gam1.dime = leng;
1636
1637 gam1.id = 90;
1638
1639 igmpk[0][ipk] = nadcgam;
1640 igmpk[1][ipk] = nadcgam;
1641
1642 if( e2 > 0. && nadcgam <= MADCGAM50-1 ) {
1643 nadcgam = nadcgam+1;
1644
1645 gam2.chi2 = chisq;
1646 gam2.type = itype+50;
1647 gam2.energy = e2;
1648 gam2.x = x2;
1649 gam2.y = y2;
1650 gam2.xc = 0.5*(x2-x1);
1651 gam2.yc = 0.5*(y2-y1);
1652 gam1.xc = 0.5*(x1-x2);
1653 gam1.yc = 0.5*(y1-y2);
1654
1655 gam2.id = 92;
1656 gam1.id = 91;
1657
1658 gam2.dime = leng;
1659 igmpk[1][ipk] = nadcgam;
1660
1661 gammas.push_back( gam1 );
1662 gammas.push_back( gam2 );
1663
1664 } else { gammas.push_back( gam1 ); }
1665
1666 } // end loop over peaks
1667
1668
1669
1670 /*
1671 This is the second step: ( 1 or 2 gamma in each peak )
1672 (e,x,y) of hits were preliminarily estimated in the first step.
1673 */
1674
1675 for( int ii = 0; ii < nadc; ii++ ) {
1676 iwrk[0][ii] = 0;
1677 fwrk[0][ii] = 0.;
1678 idp[0][ii] = 0;
1679 }
1680
1681 for( int ipk = 0; ipk < npk; ipk++ ) {
1682 for( int ii = 0; ii < nadc; ii++ ) {
1683 iwrk[ipk+1][ii] = 0;
1684 fwrk[ipk+1][ii] = 0.;
1685 idp[ipk+1][ii] = 0;
1686
1687 if( igmpk[1][ipk] == 0 ) continue;
1688
1689 for( int ig = igmpk[0][ipk]; ig <= igmpk[1][ipk]; ig++ ) {
1690 ixy = ia[ii];
1691 ix = ixy/100;
1692 iy = ixy-(ix*100);
1693 dx = static_cast<double>(ix) - gammas[ig-1].x;
1694 dy = static_cast<double>(iy) - gammas[ig-1].y;
1695
1696 fia = gammas[ig-1].energy*cell_hyc( dx, dy );
1697 iia = static_cast<int>(fia+0.5);
1698
1699 // part of gamma 'ig' energy belonging to cell 'i' from peak 'ipk':
1700 iwrk[ipk+1][ii] += iia;
1701 fwrk[ipk+1][ii] += fia;
1702 idp[ipk+1][ii] += iia;
1703
1704 iwrk[0][ii] += iia;
1705 fwrk[0][ii] += fia;
1706
1707 }
1708
1709 } // end loop over hits
1710 } // end loop over peaks
1711
1712
1713
1714
1715 // Recover working array and renormalize total sum to the original cell energy:
1716
1717 for( int ii = 0; ii < nadc; ii++ ) {
1718
1719 idp[0][ii] = 0;
1720 for( int ipk = 0; ipk < npk; ipk++ ) {
1721 idp[0][ii] += idp[ipk+1][ii];
1722 }
1723
1724 ide = id[ii] - idp[0][ii];
1725 if( ide == 0 ) continue;
1726 if( fwrk[0][ii] == 0. ) continue;
1727
1728 for( int ipk = 0; ipk < npk; ipk++ ) {
1729 fw[ipk+1] = fwrk[ipk+1][ii]/fwrk[0][ii];
1730 }
1731
1732 idecorr = 0;
1733 for( int ipk = 0; ipk < npk; ipk++ ) {
1734 fia = ide*fw[ipk+1];
1735 if( (fwrk[ipk+1][ii] + fia) > 0. ) {
1736 fwrk[ipk+1][ii] += fia;
1737 fwrk[0][ii] += fia;
1738 }
1739 iia = static_cast<int>(fia+0.5);
1740 if( (iwrk[ipk+1][ii] + iia) > 0 ) {
1741 iwrk[ipk+1][ii] += iia;
1742 iwrk[0][ii] += iia;
1743 idecorr += iia;
1744 } else if( (iwrk[ipk+1][ii] + iia) < 0 ) {
1745 //cout << "WARNING NEGATIVE CORR: ia = " << ia[ii] << "; id = " << id[ii] << endl;
1746 }
1747 } // end loop over peaks
1748
1749 } // end loop over hits
1750
1751
1752
1753 // erase the gammas found in the previous step:
1754
1755 nadcgam = ngam0;
1756 gammas.erase( gammas.begin()+nadcgam, gammas.end() );
1757
1758
1759
1760
1761
1762
1763 for( int ipk = 0; ipk < npk; ipk++ ) {
1764 leng = 0;
1765
1766 vector<int> iwrk_a;
1767 vector<int> iwrk_d;
1768
1769 for( int ii = 0; ii < nadc; ii++ ){
1770 if( iwrk[0][ii] > 0 ) {
1771 fe = id[ii]*fwrk[ipk+1][ii]/fwrk[0][ii];
1772 if( fe > idelta ) {
1773 leng++;
1774 iwrk_a.push_back( ia[ii] );
1775 iwrk_d.push_back( static_cast<int>(fe+0.5) );
1776 }
1777 }
1778 }
1779
1780 if( nadcgam >= MADCGAM50-1 ) return;
1781
1782
1783 if( leng == 0 ) continue;
1784
1785 nadcgam++;
1786
1787 chisq = chisq2;
1788
1789 ic = ipnpk[ipk];
1790 ix = ia[ic]/100;
1791 iy = ia[ic] - ix*100;
1792
1793 itype = peak_type( ix, iy );
1794
1795 e2 = 0.;
1796 gamma_hyc( leng, iwrk_a, iwrk_d, chisq,
1797 e1, x1, y1, e2, x2, y2 );
1798
1799 gamma_t gam1;
1800 gamma_t gam2;
1801
1802 gam1.type = itype+20;
1803 gam1.dime = leng;
1804 gam1.id = 10;
1805
1806 gam1.chi2 = chisq;
1807 gam1.energy = e1;
1808 gam1.x = x1;
1809 gam1.y = y1;
1810 gam1.xc = 0.;
1811 gam1.yc = 0.;
1812
1813 if( e2 > 0. && nadcgam <= MADCGAM50-1 ) {
1814 nadcgam = nadcgam+1;
1815
1816 gam2.type = itype+30;
1817 gam2.dime = leng;
1818 gam2.id = 12;
1819
1820 gam2.chi2 = chisq;
1821 gam2.energy = e2;
1822 gam2.x = x2;
1823 gam2.y = y2;
1824 gam2.xc = 0.5*(x2-x1);
1825 gam2.yc = 0.5*(y2-y1);
1826
1827 gam1.type = itype+30;
1828 gam1.id = 11;
1829 gam1.xc = 0.5*(x1-x2);
1830 gam1.yc = 0.5*(x1-x2);
1831
1832 for( int jj = 0; jj < leng; jj++ ) {
1833 if( jj < MAX_CC60 ) {
1834 gam1.icl_in[jj] = iwrk_a[jj];
1835 gam2.icl_in[jj] = iwrk_a[jj];
1836 gam1.icl_en[jj] = static_cast<int>(
1837 static_cast<double>(iwrk_d[jj])*e1/(e1+e2) + 0.5 );
1838 gam2.icl_en[jj] = static_cast<int>(
1839 static_cast<double>(iwrk_d[jj])*e2/(e1+e2) + 0.5 );
1840 }
1841 }
1842
1843 gammas.push_back( gam1 );
1844 gammas.push_back( gam2 );
1845
1846 } else {
1847 for( int jj = 0; jj < leng; jj++ ) {
1848 if( jj < MAX_CC60 ) {
1849 gam1.icl_in[jj] = iwrk_a[jj];
1850 gam1.icl_en[jj] = iwrk_d[jj];
1851 }
1852 }
1853
1854 gammas.push_back( gam1 );
1855
1856 }
1857
1858
1859 } // end loop over peaks
1860
1861
1862
1863 } // end looping over multi-peak cluster
1864
1865
1866
1867
1868
1869 return;
1870}
1871
1872
1873
1874
1875
1876//==========================================================
1877//
1878// peak_type
1879//
1880//==========================================================
1881
1882int DCCALShower_factory::peak_type( int ix, int iy )
1883{
1884 /*
1885 itype = 2 : if the peak is in the most outer layer
1886 itype = 1 : if the peak is in the most inner layer
1887 itype = 0 : if the peak is anywhere else
1888 */
1889
1890 int itype = 0;
1891 if( (ix == MCOL12/2-1 || ix == MCOL12/2+2) && (iy >= MROW12/2-1 && iy <= MROW12/2+2) ) itype = 1;
1892 if( (iy == MROW12/2-1 || iy == MROW12/2+2) && (ix >= MCOL12/2-1 && ix <= MCOL12/2+2) ) itype = 1;
1893 if( ix == 1 || ix == MCOL12 || iy == 1 || iy == MROW12 ) itype = 2;
1894
1895 return itype;
1896}
1897
1898
1899
1900
1901
1902//==========================================================
1903//
1904// gamma_hyc
1905//
1906//==========================================================
1907
1908void DCCALShower_factory::gamma_hyc( int nadc, vector<int> ia, vector<int> id, double &chisq,
1909 double &e1, double &x1, double &y1,
1910 double &e2, double &x2, double &y2 )
1911{
1912 //-------------Local Declarations------------//
1913
1914 int dof;
1915
1916 double dxy; // initial step for iteration
1917 double stepmin; // minimum step for iteration
1918 double stepx, stepy; // current steps
1919 double parx, pary; //
1920 double chimem, chisq0, chi0; //
1921 double chiold; //
1922 double chi00; //
1923 double x0, y0; //
1924 double ee, xx, yy; //
1
'xx' declared without an initial value
1925 double d2, xm2, xm2cut; //
1926 double chir, chil, chiu, chid; //
1927
1928 dxy = 0.05;
1929 stepmin = 0.002;
1930 xm2cut = 1.7;
1931
1932 int nzero;
1933 vector<int> iaz;
1934
1935 //-------------Event Analysis Code------------//
1936
1937 e2 = 0.;
1938 x2 = 0.;
1939 y2 = 0.;
1940
1941
1942 fill_zeros( nadc, ia, nzero, iaz );
1943 mom1_pht( nadc, ia, id, nzero, iaz, e1, x1, y1 ); // calculate initial values of (E,x,y)
1944
1945 if( nadc
1.1
'nadc' is > 0
<= 0 ) return;
2
Taking false branch
1946
1947 chimem = chisq;
1948 chisq1_hyc( nadc, ia, id, nzero, iaz, e1, x1, y1, chi0 ); // initial value of chi2
1949
1950
1951 chisq0 = chi0;
1952 dof = nzero + nadc - 2;
1953 if( dof < 1 ) dof = 1;
3
Assuming 'dof' is >= 1
4
Taking false branch
1954 chisq = chi0/dof;
1955 x0 = x1;
1956 y0 = y1;
1957
1958
1959 // start of iterations
1960
1961 int rounds = 0;
1962 while( 1 ) {
5
Loop condition is true. Entering loop body
1963
1964 chisq1_hyc( nadc, ia, id, nzero, iaz, e1, x0+dxy, y0, chir );
1965 chisq1_hyc( nadc, ia, id, nzero, iaz, e1, x0-dxy, y0, chil );
1966 chisq1_hyc( nadc, ia, id, nzero, iaz, e1, x0, y0+dxy, chiu );
1967 chisq1_hyc( nadc, ia, id, nzero, iaz, e1, x0, y0-dxy, chid );
1968
1969 if( chi0 > chir || chi0 > chil ) {
6
Assuming 'chi0' is > 'chir'
1970 stepx = dxy;
1971 if( chir > chil ) stepx = -stepx;
7
Assuming 'chir' is <= 'chil'
8
Taking false branch
1972 } else {
1973 stepx = 0.;
1974 parx = chir + chil - 2.*chi0;
1975 if( parx > 0. ) stepx = -dxy*(chir-chil)/(2.*parx);
1976 }
1977 if( chi0 > chiu || chi0 > chid ) {
9
Assuming 'chi0' is > 'chiu'
1978 stepy = dxy;
1979 if( chiu > chid ) stepy = -stepy;
10
Assuming 'chiu' is <= 'chid'
11
Taking false branch
1980 } else {
1981 stepy = 0.;
1982 pary = chiu + chid - 2.*chi0;
1983 if( pary > 0. ) stepy = -dxy*(chiu-chid)/(2.*pary);
1984 }
1985
1986
1987 // if steps at minimum, end iterations
1988
1989 if( fabs(stepx) < stepmin && fabs(stepy) < stepmin ) break;
12
Assuming the condition is true
13
Assuming the condition is true
14
Taking true branch
15
Execution continues on line 2006
1990
1991 chisq1_hyc( nadc, ia, id, nzero, iaz, e1, x0+stepx, y0+stepy, chi00 );
1992
1993 // if chi2 at minimum, end iterations
1994
1995 if( chi00 >= chi0 ) break;
1996
1997 chi0 = chi00;
1998 x0 = x0+stepx;
1999 y0 = y0+stepy;
2000
2001 rounds++;
2002 if( rounds > 10000 ) { cout << "max rounds" << endl; break; }
2003
2004 }
2005
2006 if( chi0 < chisq0 ) { // if chi2 improved, then fix the improved values
16
Assuming 'chi0' is >= 'chisq0'
17
Taking false branch
2007 x1 = x0;
2008 y1 = y0;
2009 chisq = chi0/dof;
2010 }
2011
2012 // if chi2 is less than maximum allowed for one gamma in a peak, return.
2013 // otherwise, try separating the peak into two gammas:
2014
2015 if( chisq <= chimem ) return;
18
Assuming 'chisq' is > 'chimem'
19
Taking false branch
2016
2017 chiold = chisq;
2018 tgamma_hyc( nadc, ia, id, nzero, iaz, chisq, ee, xx, yy, e2, x2, y2 );
20
Calling 'DCCALShower_factory::tgamma_hyc'
44
Returning from 'DCCALShower_factory::tgamma_hyc'
2019
2020 if( e2 > 0. ) { // if chi2 improved, decide if the separation
45
Assuming the condition is true
46
Taking true branch
2021 // has physical meaning by calculating the
2022 // effective mass of the two gammas
2023
2024 d2 = pow((xx-x2)*xsize2.09, 2.0) + pow((yy-y2)*ysize2.09, 2.0);
47
The left operand of '-' is a garbage value
2025 xm2 = ee*e2*d2;
2026
2027 if( xm2 > 0. ) xm2 = sqrt(xm2)/1270.*0.1; // mass in MeV; 1270 = zccal
2028
2029 if( xm2 > xm2cut*xsize2.09 ) { // if the separation has physical meaning
2030 e1 = ee; // fix the parameters of the first gamma
2031 x1 = xx;
2032 y1 = yy;
2033 } else { // if no physical meaning e2=0
2034 e2 = 0.; // (second gamma is killed)
2035 chisq = chiold;
2036 }
2037 }
2038
2039 return;
2040}
2041
2042
2043
2044
2045
2046//==========================================================
2047//
2048// fill_zeros
2049//
2050//==========================================================
2051
2052void DCCALShower_factory::fill_zeros( int nadc, vector<int> ia, int &nneib, vector<int> &iaz )
2053{
2054
2055 int ix, iy, nneibnew;
2056 vector<int> ian;
2057
2058 nneib = 0;
2059 for( int ii = 0; ii < nadc; ii++ ) {
2060 ix = ia[ii]/100;
2061 iy = ia[ii] - ix*100;
2062
2063 if( ix > 1 ) { // fill left neib
2064 nneib = nneib+1;
2065 ian.push_back(iy + (ix-1)*100);
2066
2067 if( iy > 1 ) { // fill bottom left neib
2068 nneib = nneib+1;
2069 ian.push_back(iy-1 + (ix-1)*100);
2070 }
2071 if( iy < MROW12 ) { // fill top left neib
2072 nneib = nneib+1;
2073 ian.push_back(iy+1 + (ix-1)*100);
2074 }
2075 }
2076 if( ix < MCOL12 ) {
2077 nneib = nneib+1;
2078 ian.push_back(iy + (ix+1)*100);
2079
2080 if( iy > 1 ) { // fill bottom right neib
2081 nneib = nneib+1;
2082 ian.push_back(iy-1 + (ix+1)*100);
2083 }
2084 if( iy < MROW12 ) { // fill top right neib
2085 nneib = nneib+1;
2086 ian.push_back(iy+1 + (ix+1)*100);
2087 }
2088 }
2089
2090 if( iy > 1 ) { // fill bottom neib
2091 nneib = nneib+1;
2092 ian.push_back(iy-1 + ix*100);
2093 }
2094 if( iy < MROW12 ) { // fill top neib
2095 nneib = nneib+1;
2096 ian.push_back(iy+1 + ix*100);
2097 }
2098 }
2099
2100
2101 for( int ii = 0; ii < nneib; ii++ ) {
2102 for( int jj = 0; jj < nadc; jj++ ) {
2103 if( ia[jj] == ian[ii] ) ian[ii] = -1;
2104 }
2105 }
2106
2107 for( int ii = 0; ii < nneib; ii++ ) {
2108 if( ian[ii] == -1 ) continue;
2109 for( int jj = ii+1; jj < nneib; jj++ ) {
2110 if( ian[jj] == ian[ii] ) ian[jj] = -1;
2111 }
2112 }
2113
2114 nneibnew = 0;
2115 for( int ii = 0; ii < nneib; ii++ ) {
2116 ix = ian[ii]/100;
2117 iy = ian[ii] - ix*100;
2118 if( ian[ii] != -1 ) {
2119 if( stat_ch[iy-1][ix-1] == 0 ) {
2120 nneibnew = nneibnew+1;
2121 iaz.push_back( ian[ii] );
2122 }
2123 }
2124 }
2125 nneib = nneibnew;
2126
2127
2128 return;
2129}
2130
2131
2132
2133
2134
2135//==========================================================
2136//
2137// mom1_pht
2138//
2139//==========================================================
2140
2141void DCCALShower_factory::mom1_pht( int nadc, vector<int> ia, vector<int> id,
2142 int nzero, vector<int> iaz, double &e1, double &x1, double &y1 )
2143{
2144 //-------------Local Declarations------------//
2145
2146 int ix, iy;
2147 double dx, dy;
2148
2149 double a; //
2150 double corr; // correction to energy
2151
2152 //--------------Event Analysis Code-------------//
2153
2154 e1 = 0.;
2155 x1 = 0.;
2156 y1 = 0.;
2157
2158 if( nadc <= 0 ) return;
2159 for( int ii = 0; ii < nadc; ii++ ) {
2160 a = static_cast<double>(id[ii]);
2161 ix = ia[ii]/100;
2162 iy = ia[ii] - ix*100;
2163 e1 = e1 + a;
2164 x1 = x1 + a*static_cast<double>(ix);
2165 y1 = y1 + a*static_cast<double>(iy);
2166 }
2167 if( e1 <= 0. ) return;
2168 x1 = x1/e1;
2169 y1 = y1/e1;
2170 corr = 0.;
2171 for( int ii = 0; ii < nadc; ii++ ) {
2172 ix = ia[ii]/100;
2173 iy = ia[ii] - ix*100;
2174 dx = static_cast<double>(ix) - x1;
2175 dy = static_cast<double>(iy) - y1;
2176 corr = corr + cell_hyc( dx, dy );
2177 }
2178
2179 if( COUNT_ZERO1 ) {
2180 for( int ii = 0; ii < nzero; ii++ ) {
2181 ix = iaz[ii]/100;
2182 iy = iaz[ii] - ix*100;
2183 dx = static_cast<double>(ix) - x1;
2184 dy = static_cast<double>(iy) - y1;
2185 corr = corr + cell_hyc( dx, dy );
2186 }
2187 }
2188
2189 corr = corr/1.006;
2190 if( SHOWER_DEBUG ) cout << "e, corr = " << e1 << ", " << corr << endl;
2191
2192
2193 if( corr < 0.8 ) {
2194 if( SHOWER_DEBUG ) {
2195 cout << "corr = " << corr << ", " << e1 << ", " << x1 << ", " << y1;
2196 cout << "! Too many around central hole!" << endl;
2197 }
2198 corr = 0.8;
2199 } else if( corr > 1.0 ) {
2200 corr = 1.;
2201 }
2202 e1 = e1/corr;
2203
2204
2205 return;
2206}
2207
2208
2209
2210
2211
2212//==========================================================
2213//
2214// chisq1_hyc
2215//
2216//==========================================================
2217
2218void DCCALShower_factory::chisq1_hyc( int nadc, vector<int> ia, vector<int> id,
2219 int nneib, vector<int> iaz, double e1, double x1, double y1, double &chisq )
2220{
2221 //-------------Local Declarations------------//
2222
2223 int ix, iy;
2224 double dx, dy;
2225 double fa, fcell;
2226
2227
2228 //--------------Event Analysis Code-------------//
2229
2230 chisq = 0.;
2231
2232 for( int ii = 0; ii < nadc; ii++ ) {
2233 fa = static_cast<double>(id[ii]);
2234 ix = ia[ii]/100;
2235 iy = ia[ii] - ix*100;
2236 dx = x1 - static_cast<double>(ix);
2237 dy = y1 - static_cast<double>(iy);
2238 if( e1 != 0. ) {
2239 if( fabs(dx) <= 6.0 && fabs(dy) <= 6.0 ) {
2240 fcell = cell_hyc( dx, dy );
2241 chisq = chisq + e1*pow((fcell-(fa/e1)), 2.)/sigma2(dx, dy, fcell, e1);
2242 }
2243 } else {
2244 chisq = chisq + fa*fa/9.;
2245 cout << "case 0 ch" << endl;
2246 //if( SHOWER_DEBUG ) cout << "case 0 ch" << endl;
2247 }
2248 }
2249
2250 for(int ii = 0; ii < nneib; ii++ ) {
2251 ix = iaz[ii]/100;
2252 iy = iaz[ii] - ix*100;
2253 dx = x1 - static_cast<double>(ix);
2254 dy = y1 - static_cast<double>(iy);
2255 if( e1 != 0. ) {
2256 if( fabs(dx) < 6.0 && fabs(dy) < 6.0 ) {
2257 fcell = cell_hyc( dx, dy );
2258 chisq = chisq + e1*fcell*fcell/sigma2(dx, dy, fcell, e1);
2259 }
2260 } else {
2261 chisq = chisq + id[ii]*id[ii]/9.;
2262 //if( SHOWER_DEBUG ) cout << "case 0 ch" << endl;
2263 }
2264 }
2265
2266
2267 return;
2268}
2269
2270
2271
2272
2273
2274//==========================================================
2275//
2276// sigma2, d2c, & cell_hyc
2277//
2278//==========================================================
2279
2280double DCCALShower_factory::sigma2( double dx, double dy, double fc, double e )
2281{
2282 double sig2;
2283 double alp = 0.816;
2284 double bet1 = 32.1;
2285 double bet2 = 1.72;
2286
2287 double r = dx*dx + dy*dy;
2288 if( r > 25. ) {
2289 sig2 = 100.;
2290 return sig2;
2291 }
2292
2293 sig2 = alp*fc + (bet1 + bet2*sqrt(e/100.))*d2c( dx, dy ) + 0.2/(e/100.);
2294 if( TEST_P1 ) sig2 = sig2/pow(0.0001*e, 0.166);
2295 sig2 *= 100.;
2296
2297 return sig2;
2298}
2299
2300
2301double DCCALShower_factory::d2c( double dx, double dy )
2302{
2303 int i, j;
2304 double ax, ay, wx, wy;
2305 double d2c;
2306
2307 ax = fabs(dx*100.);
2308 ay = fabs(dy*100.);
2309 i = int(ax);
2310 j = int(ay);
2311
2312 if( i < 499 && j < 499 && i >= 0 && j >= 0 ) {
2313 //if( i < 500. && j < 500. ) {
2314
2315 wx = ax-static_cast<double>(i);
2316 wy = ay-static_cast<double>(j);
2317
2318 d2c = ad2c[i][j] * (1.-wx) * (1.-wy) +
2319 ad2c[i+1][j] * wx * (1.-wy) +
2320 ad2c[i][j+1] * (1.-wx) * wy +
2321 ad2c[i+1][j+1] * wx * wy;
2322
2323 } else d2c = 1.;
2324
2325 return d2c;
2326}
2327
2328
2329double DCCALShower_factory::cell_hyc( double dx, double dy )
2330{
2331 int i, j;
2332 double ax, ay, wx, wy;
2333 double cell_hyc;
2334
2335 ax = fabs(dx*100.);
2336 ay = fabs(dy*100.);
2337 i = static_cast<int>(ax);
2338 j = static_cast<int>(ay);
2339
2340 if( i < 499 && j < 499 && i >= 0 && j >= 0 ) {
2341
2342 wx = ax-static_cast<double>(i);
2343 wy = ay-static_cast<double>(j);
2344 //std::cout << "i " << i << " j " << j << " wx " << wx << " wy " << wy << std::endl;
2345 cell_hyc = acell[i][j] * (1.-wx) * (1.-wy) +
2346 acell[i+1][j] * wx * (1.-wy) +
2347 acell[i][j+1] * (1.-wx) * wy +
2348 acell[i+1][j+1] * wx * wy;
2349
2350 } else cell_hyc = 0.;
2351
2352 return cell_hyc;
2353}
2354
2355
2356
2357
2358
2359//==========================================================
2360//
2361// tgamma_hyc( int, vector<int>, vector<int>, int, vector<int>, double,
2362// double, double, double, double, double, double )
2363//
2364//==========================================================
2365
2366void DCCALShower_factory::tgamma_hyc( int nadc, vector<int> ia, vector<int> id,
2367 int nzero, vector<int> iaz, double &chisq, double &e1, double &x1, double &y1,
2368 double &e2, double &x2, double &y2 )
2369{
2370 //-------------- Local Declarations -------------//
2371
2372 int ix, iy;
2373 int dof;
2374
2375 double dx, dy;
2376 double dxy;
2377 double dxc, dyc;
2378 double dx0, dy0;
2379 double dx1, dy1;
2380 double dx2, dy2;
2381 double u, r, rsq, rsq2;
2382 double epsc, eps0, eps1, eps2;
2383 double stepmin, epsmax;
2384 double delch;
2385 double step;
2386 double cosi, scal;
2387 double chisq2, chisqc;
2388 double dchi, dchida, dchi0;
2389 double a1, a2;
2390 double ex;
2391 double e1c, x1c, y1c;
2392 double e2c, x2c, y2c;
2393 double gr, gre, grx, gry;
2394 double grc;
2395 double grec, grxc, gryc;
2396 double gx1, gy1;
2397 double gx2, gy2;
2398 double e0, x0, y0;
2399 double xx, yy, yx;
2400
2401 double f1c, f2c, f1x, f2x, f1y, f2y;
2402 double chisqt, chisqt0, chisqt1, chisqt2;
2403 double chisqtx1, chisqtx2, chisqty1, chisqty2;
2404 double dchidax1, dchidax2, dchiday1, dchiday2;
2405
2406 stepmin = 0.5;
2407 epsmax = 0.9999;
2408 delch = 10.;
2409
2410 //-------------- Event Analysis Code -------------//
2411
2412 yx = 0.;
2413 grx = 0.; gry = 0.;
2414 gre = 0.; gr = 0.;
2415 dx0 = 0.; dy0 = 0.;
2416 eps0 = 0.;
2417
2418 mom2_pht( nadc, ia, id, nzero, iaz, e0, x0, y0, xx, yy, yx );
2419
2420 e2 = 0.;
2421 x2 = 0.;
2422 y2 = 0.;
2423
2424 if( nadc
20.1
'nadc' is > 0
<= 0 ) return;
21
Taking false branch
2425
2426 // choosing of the starting point
2427
2428 dxy = xx - yy;
2429 rsq2 = dxy*dxy + 4.*yx*yx;
2430 if( rsq2 < 1.e-20 ) rsq2 = 1.e-20;
22
Assuming the condition is false
23
Taking false branch
2431 rsq = sqrt(rsq2);
2432 dxc = -sqrt((rsq+dxy)*2.);
2433 dyc = sqrt((rsq-dxy)*2.);
2434 if( yx >= 0. ) dyc = -dyc;
24
Assuming the condition is false
25
Taking false branch
2435 r = sqrt(dxc*dxc + dyc*dyc);
2436 epsc = 0.;
2437 for( int ii = 0; ii < nadc; ii++ ) {
26
Loop condition is true. Entering loop body
27
Loop condition is false. Execution continues on line 2445
2438 ix = ia[ii]/100;
2439 iy = ia[ii] - ix*100;
2440 dx = static_cast<double>(ix) - x0;
2441 dy = static_cast<double>(iy) - y0;
2442 u = dx*dxc/r + dy*dyc/r;
2443 epsc = epsc - 0.01*id[ii]*u*fabs(u);
2444 }
2445 epsc = epsc/(0.01*e0*rsq);
2446 if( epsc > 0.8 ) epsc = 0.8;
28
Assuming the condition is false
29
Taking false branch
2447 if( epsc < -0.8 ) epsc = -0.8;
30
Assuming the condition is false
31
Taking false branch
2448 dxc = dxc/sqrt(1.-(epsc*epsc));
2449 dyc = dyc/sqrt(1.-(epsc*epsc));
2450
2451
2452
2453 // start of iterations:
2454
2455 step = 0.1;
2456 cosi = 0.0;
2457 chisq2 = 1.e35;
2458
2459 for( int iter = 0; iter < 100; iter++ ) {
32
Loop condition is true. Entering loop body
2460
2461 c3to5_pht( e0, x0, y0, epsc, dxc, dyc, e1c, x1c, y1c, e2c, x2c, y2c );
2462
2463 eps1 = (1. + epsc)/2.;
2464 eps2 = (1. - epsc)/2.;
2465 chisqc = 0.;
2466
2467 for( int ii = 0; ii < nadc+nzero; ii++ ) { // chi2 calculation
33
Loop condition is false. Execution continues on line 2492
2468
2469 if( ii < nadc ) {
2470 ex = static_cast<double>(id[ii]);
2471 ix = ia[ii]/100;
2472 iy = ia[ii] - ix*100;
2473 } else {
2474 ex = 0.;
2475 ix = iaz[ii-nadc]/100;
2476 iy = iaz[ii-nadc] - ix*100;
2477 }
2478
2479 dx1 = x1c - static_cast<double>(ix);
2480 dy1 = y1c - static_cast<double>(iy);
2481 dx2 = x2c - static_cast<double>(ix);
2482 dy2 = y2c - static_cast<double>(iy);
2483
2484 f1c = cell_hyc( dx1, dy1 );
2485 f2c = cell_hyc( dx2, dy2 );
2486
2487 chisq2t_hyc( ex, e1c, dx1, dy1, e2c, dx2, dy2, f1c, f2c, chisqt );
2488 chisqc += chisqt;
2489
2490 }
2491
2492 if( chisqc >= chisq2 ) { // new step if no improvement
34
Assuming 'chisqc' is >= 'chisq2'
35
Taking true branch
2493
2494 if( iter
35.1
'iter' is <= 0
> 0 ) {
36
Taking false branch
2495 dchi = chisqc - chisq2;
2496 dchi0 = gr*step;
2497 step = 0.5*step/sqrt(1. + dchi/dchi0);
2498 }
2499 step = 0.5*step;
2500
2501 } else { // calculate gradient
2502
2503 grec = 0.;
2504 grxc = 0.;
2505 gryc = 0.;
2506
2507 for( int ii = 0; ii < nadc+nzero; ii++ ) {
2508
2509 if( ii < nadc ) {
2510 ex = static_cast<double>(id[ii]);
2511 ix = ia[ii]/100;
2512 iy = ia[ii] - ix*100;
2513 } else {
2514 ex = 0.;
2515 ix = iaz[ii-nadc]/100;
2516 iy = iaz[ii-nadc] - ix*100;
2517 }
2518
2519 dx1 = x1c - static_cast<double>(ix);
2520 dy1 = y1c - static_cast<double>(iy);
2521 dx2 = x2c - static_cast<double>(ix);
2522 dy2 = y2c - static_cast<double>(iy);
2523
2524 f1c = cell_hyc( dx1, dy1 );
2525 f2c = cell_hyc( dx2, dy2 );
2526
2527 a1 = e1c*f1c;
2528 a2 = e2c*f2c;
2529 //a0 = a1 + a2;
2530
2531 chisq2t_hyc( ex, e1c, dx1, dy1, e2c, dx2, dy2, f1c, f2c, chisqt0 );
2532 chisq2t_hyc( ex, e1c+1., dx1, dy1, e2c, dx2, dy2, f1c, f2c, chisqt1 );
2533 chisq2t_hyc( ex, e1c, dx1, dy1, e2c+1., dx2, dy2, f1c, f2c, chisqt2 );
2534
2535 f1x = cell_hyc( dx1+0.05, dy1 );
2536 f2x = cell_hyc( dx2+0.05, dy2 );
2537 f1y = cell_hyc( dx1, dy1+0.05 );
2538 f2y = cell_hyc( dx2, dy2+0.05 );
2539
2540 chisq2t_hyc( ex, e1c, dx1+0.05, dy1, e2c, dx2, dy2, f1x, f2c, chisqtx1 );
2541 chisq2t_hyc( ex, e1c, dx1, dy1, e2c, dx2+0.05, dy2, f1c, f2x, chisqtx2 );
2542 chisq2t_hyc( ex, e1c, dx1, dy1+0.05, e2c, dx2, dy2, f1y, f2c, chisqty1 );
2543 chisq2t_hyc( ex, e1c, dx1, dy1, e2c, dx2, dy2+0.05, f1c, f2y, chisqty2 );
2544
2545 dchidax1 = 20.*(chisqtx1 - chisqt0);
2546 dchidax2 = 20.*(chisqtx2 - chisqt0);
2547 dchiday1 = 20.*(chisqty1 - chisqt0);
2548 dchiday2 = 20.*(chisqty2 - chisqt0);
2549 dchida = 0.5*(chisqt1 + chisqt2 - chisqt0);
2550
2551 gx1 = (e1c*f1x - a1)*dchidax1;
2552 gx2 = (e2c*f2x - a2)*dchidax2;
2553 gy1 = (e1c*f1y - a1)*dchiday1;
2554 gy2 = (e2c*f2y - a2)*dchiday2;
2555
2556 grec += dchida*(f1c-f2c)*e0 - ( (gx1+gx2)*dxc + (gy1+gy2)*dyc );
2557 grxc += gx1*eps2 - gx2*eps1;
2558 gryc += gy1*eps2 - gy2*eps1;
2559
2560 }
2561
2562 grc = sqrt( grec*grec + grxc*grxc + gryc*gryc );
2563 if( grc < 1.e-6 ) grc = 1.e-6;
2564 if( iter > 0 ) {
2565 cosi = ( gre*grec + grx*grxc + gry*gryc )/(gr*grc);
2566 scal = fabs((gr/grc) - cosi);
2567 if( scal < 0.1 ) scal = 0.1;
2568 step = step/scal;
2569 }
2570 chisq2 = chisqc;
2571 eps0 = epsc;
2572 dx0 = dxc;
2573 dy0 = dyc;
2574 gre = grec;
2575 grx = grxc;
2576 gry = gryc;
2577 gr = grc;
2578 }
2579 epsc = eps0 - step*gre/gr;
2580 while( fabs(epsc) > epsmax ) {
37
Loop condition is false. Execution continues on line 2584
2581 step = step/2.;
2582 epsc = eps0 - step*gre/gr;
2583 }
2584 dxc = dx0 - step*grx/gr;
2585 dyc = dy0 - step*gry/gr;
2586 if( step*gr < stepmin ) break;
38
Assuming the condition is true
39
Taking true branch
40
Execution continues on line 2589
2587 }
2588
2589 if( (chisq*(nadc+nzero-2) - chisq2) < delch ) return;
41
Assuming the condition is true
42
Taking true branch
43
Returning without writing to 'x1'
2590 dof = nzero+nadc-5;
2591 if( dof < 1 ) dof = 1;
2592 chisq = chisq2/dof;
2593
2594 c3to5_pht( e0, x0, y0, eps0, dx0, dy0, e1, x1, y1, e2, x2, y2 );
2595
2596 return;
2597}
2598
2599
2600
2601
2602
2603//==========================================================
2604//
2605// mom2_pht( int, vector<int>, vector<int>, int, vector<int>,
2606// double, double, double, double, double, double )
2607//
2608//==========================================================
2609
2610void DCCALShower_factory::mom2_pht( int nadc, vector<int> ia, vector<int> id,
2611 int nzero, vector<int> iaz, double &a0, double &x0, double &y0,
2612 double &xx, double &yy, double &yx)
2613{
2614 //-------------- Local Declarations --------------//
2615
2616 int ix, iy;
2617 double dx, dy;
2618 double a;
2619 double corr;
2620
2621 //-------------- Event Analysis Code -------------//
2622
2623 a0 = 0.;
2624 x0 = 0.;
2625 y0 = 0.;
2626 xx = 0.;
2627 yy = 0.;
2628 yx = 0.;
2629
2630 if( nadc <= 0 ) return;
2631 for( int ii = 0; ii < nadc; ii++ ) {
2632 a = static_cast<double>(id[ii]);
2633 ix = ia[ii]/100;
2634 iy = ia[ii] - ix*100;
2635 a0 = a0 + a;
2636 x0 = x0 + a*static_cast<double>(ix);
2637 y0 = y0 + a*static_cast<double>(iy);
2638 }
2639 if( a0 <= 0. ) return;
2640 x0 = x0/a0;
2641 y0 = y0/a0;
2642
2643 for( int ii = 0; ii < nadc; ii++ ) {
2644 a = static_cast<double>(id[ii])/a0;
2645 ix = ia[ii]/100;
2646 iy = ia[ii] - ix*100;
2647 dx = static_cast<double>(ix) - x0;
2648 dy = static_cast<double>(iy) - y0;
2649 xx = xx + a*dx*dx;
2650 yy = yy + a*dy*dy;
2651 yx = yx + a*dx*dy;
2652 }
2653
2654 corr = 0.;
2655 for( int ii = 0; ii < nadc; ii++ ) {
2656 ix = ia[ii]/100;
2657 iy = ia[ii] - ix*100;
2658 dx = static_cast<double>(ix) - x0;
2659 dy = static_cast<double>(iy) - y0;
2660 corr = corr + cell_hyc( dx, dy );
2661 }
2662 if( COUNT_ZERO1 ) {
2663 for( int ii = 0; ii < nzero; ii++ ) {
2664 ix = iaz[ii]/100;
2665 iy = iaz[ii] - ix*100;
2666 dx = static_cast<double>(ix) - x0;
2667 dy = static_cast<double>(iy) - y0;
2668 corr = corr + cell_hyc( dx, dy );
2669 }
2670 }
2671
2672 corr = corr/1.006;
2673 if( corr < 0.8 ) {
2674 corr = 0.8;
2675 } else if( corr > 1. ) {
2676 corr = 1.0;
2677 }
2678 a0 = a0/corr;
2679
2680
2681 return;
2682}
2683
2684
2685
2686
2687
2688//==========================================================
2689//
2690// c3to5_pht( double, double, double, double, double, double,
2691// double, double, double, double, double, double )
2692//
2693//==========================================================
2694
2695void DCCALShower_factory::c3to5_pht( double e0, double x0, double y0, double eps,
2696 double dx, double dy, double &e1, double &x1, double &y1, double &e2,
2697 double &x2, double &y2 )
2698{
2699 e1 = e0*(1.+eps)/2.;
2700 e2 = e0 - e1;
2701 x1 = x0 + 0.5*dx*(1.-eps);
2702 y1 = y0 + 0.5*dy*(1.-eps);
2703 x2 = x0 - 0.5*dx*(1.+eps);
2704 y2 = y0 - 0.5*dy*(1.+eps);
2705
2706 return;
2707}
2708
2709
2710
2711
2712
2713//==========================================================
2714//
2715// chisq2t_hyc( double, double, double, double, double, double,
2716// double, double, double, double )
2717//
2718//==========================================================
2719
2720void DCCALShower_factory::chisq2t_hyc( double ecell, double e1, double dx1, double dy1,
2721 double e2, double dx2, double dy2, double f1, double f2, double &chisqt )
2722{
2723 double s;
2724 double p1, p2;
2725
2726 if( TEST_P1 ) {
2727 p1 = pow(0.0001*e1, 0.166);
2728 p2 = pow(0.0001*e2, 0.166);
2729 } else {
2730 p1 = 1.;
2731 p2 = 1.;
2732 }
2733
2734 if( e1 != 0. && e2 != 0. )
2735 s = e1*sigma2(dx1, dy1, f1, e1)/p1 + e2*sigma2(dx2, dy2, f2, e2)/p2;
2736 else if( e1 == 0. && e2 == 0. )
2737 s = 90000.;
2738 else if( e1 == 0. )
2739 s = e2*sigma2(dx2, dy2, f2, e2)/p2;
2740 else
2741 s = e1*sigma2(dx1, dy1, f1, e1)/p1;
2742
2743 chisqt = pow((e1*f1 + e2*f2 - ecell), 2.)/s;
2744
2745 return;
2746}
2747
2748
2749
2750
2751
2752
2753//==========================================================
2754//
2755// ucopy1( vector<int>, vector<int>, int, int )
2756//
2757//==========================================================
2758
2759void DCCALShower_factory::ucopy1( vector<int> &ia, vector<int> &iwork, int start, int length )
2760{
2761
2762 for( int ii = 0; ii < length; ii++ ) {
2763 iwork.push_back( ia[start+ii] );
2764 }
2765
2766
2767 return;
2768}
2769
2770
2771
2772//==========================================================
2773//
2774// ucopy2( vector<int>, int, int, int )
2775//
2776//==========================================================
2777
2778void DCCALShower_factory::ucopy2( vector<int> &ia, int start1, int start2, int length )
2779{
2780
2781 vector<int> work;
2782 for( int ii = 0; ii < length; ii++ ) {
2783 work.push_back( ia[start1+ii] );
2784 }
2785
2786 for( int ii = 0; ii < length; ii++ ) {
2787 ia[start2+ii] = work[ii];
2788 }
2789
2790
2791 return;
2792}
2793
2794
2795
2796
2797//==========================================================
2798//
2799// ucopy3( vector<int>, vector<int>, int, int )
2800//
2801//==========================================================
2802
2803void DCCALShower_factory::ucopy3( vector<int> &iwork, vector<int> &ia, int start, int length )
2804{
2805
2806 for( int ii = 0; ii < length; ii++ ) {
2807 ia[start+ii] = iwork[ii];
2808 }
2809
2810
2811 return;
2812}
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834