00001
00002
00003
00004
00005 #include "EmcCluster.h"
00006 #include "EmcSectorRec.h"
00007
00008 using namespace std;
00009
00010
00011
00012
00013 int const EmcCluster::fgMaxNofPeaks=10;
00014
00015
00016
00017 int const EmcCluster::fgPeakIter=6;
00018
00019
00020 float const EmcCluster::fgEmin=0.002;
00021
00022
00023 float const EmcCluster::fgChisq=3.;
00024
00025
00026 float const EmcCluster::fgXABSURD=-999999.;
00027 float const EmcCluster::fgYABSURD=-999999.;
00028
00029 EmcModule::EmcModule()
00030 : ich(0),
00031 softKey(0),
00032 amp(0),
00033 tof(0),
00034 deadmap(0),
00035 warnmap(0),
00036 adc(0),
00037 tac(0)
00038 {
00039 }
00040
00041
00042 EmcModule::EmcModule(int ich_, int softkey_, float amp_, float tof_,
00043 int deadmap_, int warnmap_, float adc_, float tac_)
00044 : ich(ich_),
00045 softKey(softkey_),
00046 amp(amp_),
00047 tof(tof_),
00048 deadmap(deadmap_),
00049 warnmap(warnmap_),
00050 adc(adc_),
00051 tac(tac_)
00052 {
00053 }
00054
00055
00056
00057
00058 void EmcCluster::GetCorrPos(float* px, float* py)
00059 {
00060
00061
00062 float e, x, y, xx, yy, xy;
00063
00064 e = GetTotalEnergy();
00065 GetMoments(&x, &y, &xx, &xy, &yy);
00066 fOwner->CorrectPosition(e, x, y, px, py);
00067 }
00068
00069
00070
00071 void EmcCluster::GetGlobalPos( float* px, float* py, float* pz )
00072
00073 {
00074
00075 float xc, yc;
00076
00077 GetCorrPos( &xc, &yc );
00078
00079 fOwner->SectorToGlobal( xc, yc, 0., px, py, pz );
00080
00081 }
00082
00083
00084
00085 float EmcCluster::GetTowerEnergy( int ich )
00086
00087 {
00088 vector<EmcModule>::iterator ph;
00089 if( fHitList.empty() ) return 0;
00090 ph = fHitList.begin();
00091 while( ph != fHitList.end() ) {
00092 if( (*ph).ich == ich ) return (*ph).amp;
00093 ph++;
00094 }
00095 return 0;
00096 }
00097
00098
00099
00100 float EmcCluster::GetTowerEnergy( int ix, int iy )
00101
00102 {
00103 int ich, ixl, iyl;
00104 vector<EmcModule>::iterator ph;
00105
00106 if( fHitList.empty() ) return 0;
00107 ph = fHitList.begin();
00108 while( ph != fHitList.end() ) {
00109 ich = (*ph).ich;
00110 iyl = ich/fOwner->GetNx();
00111 ixl = ich % fOwner->GetNx();
00112 if( ixl == ix && iyl == iy ) return (*ph).amp;
00113 ph++;
00114 }
00115 return 0;
00116 }
00117
00118
00119 float EmcCluster::GetTowerToF( int ich )
00120
00121 {
00122 vector<EmcModule>::iterator ph;
00123 if( fHitList.empty() ) return 0;
00124 ph = fHitList.begin();
00125 while( ph != fHitList.end() ) {
00126 if( (*ph).ich == ich ) return (*ph).tof;
00127 ph++;
00128 }
00129 return 0;
00130 }
00131
00132
00133
00134 int EmcCluster::GetTowerDeadMap( int ich )
00135
00136 {
00137 vector<EmcModule>::iterator ph;
00138 if( fHitList.empty() ) return 0;
00139 ph = fHitList.begin();
00140 while( ph != fHitList.end() ) {
00141 if( (*ph).ich == ich ) return (*ph).deadmap;
00142 ph++;
00143 }
00144 return 0;
00145 }
00146
00147
00148
00149 int EmcCluster::GetTowerWarnMap( int ich )
00150
00151 {
00152 vector<EmcModule>::iterator ph;
00153 if( fHitList.empty() ) return 0;
00154 ph = fHitList.begin();
00155 while( ph != fHitList.end() ) {
00156 if( (*ph).ich == ich ) return (*ph).warnmap;
00157 ph++;
00158 }
00159 return 0;
00160 }
00161
00162
00163
00164 float EmcCluster::GetTowerADC( int ich )
00165
00166 {
00167 vector<EmcModule>::iterator ph;
00168 if( fHitList.empty() ) return 0;
00169 ph = fHitList.begin();
00170 while( ph != fHitList.end() ) {
00171 if( (*ph).ich == ich ) return (*ph).adc;
00172 ph++;
00173 }
00174 return 0.;
00175 }
00176
00177
00178
00179 float EmcCluster::GetTowerTAC( int ich )
00180
00181 {
00182 vector<EmcModule>::iterator ph;
00183 if( fHitList.empty() ) return 0;
00184 ph = fHitList.begin();
00185 while( ph != fHitList.end() ) {
00186 if( (*ph).ich == ich ) return (*ph).tac;
00187 ph++;
00188 }
00189 return 0.;
00190 }
00191
00192
00193
00194
00195
00196 int EmcCluster::GetNDead()
00197 {
00198 EmcModule hmax = GetMaxTower();
00199 int dead = hmax.deadmap;
00200 int ndead = 0;
00201
00202 dead = dead>>4;
00203 for ( int iy=0; iy<3; iy++ )
00204 {
00205 for ( int iz=0; iz<3; iz++ )
00206 {
00207 ndead += dead&1;
00208 dead = dead>>1;
00209 }
00210 dead = dead>>2;
00211 }
00212 return ndead;
00213 }
00214
00215
00216
00217 int EmcCluster::GetDeadMap()
00218 {
00219
00220
00221 EmcModule hmax = GetMaxTower();
00222 return hmax.deadmap;
00223
00224 }
00225
00226
00227
00228 int EmcCluster::GetWarnMap()
00229 {
00230
00231
00232 EmcModule hmax = GetMaxTower();
00233 return hmax.warnmap;
00234
00235 }
00236
00237
00238
00239 float EmcCluster::GetTotalEnergy()
00240
00241 {
00242 vector<EmcModule>::iterator ph;
00243 float et=0;
00244 if( fHitList.empty() ) return 0;
00245 ph = fHitList.begin();
00246 while( ph != fHitList.end() ) {
00247 et += (*ph).amp;
00248 ph++;
00249 }
00250 return et;
00251 }
00252
00253
00254
00255 float EmcCluster::GetECore()
00256
00257 {
00258 vector<EmcModule>::iterator ph;
00259 float xcg, ycg, xx, xy, yy, dx, dy;
00260 float energy, es, et;
00261 int ix, iy, ixy;
00262
00263 GetMoments( &xcg, &ycg, &xx, &xy, &yy );
00264 xcg /= fOwner->GetModSizex();
00265 ycg /= fOwner->GetModSizey();
00266 energy = GetTotalEnergy();
00267 fOwner->SetProfileParameters(0,energy,xcg,ycg);
00268
00269 es=0;
00270 if( fHitList.empty() ) return 0;
00271 ph = fHitList.begin();
00272 while( ph != fHitList.end() ) {
00273 ixy = (*ph).ich;
00274 iy = ixy/fOwner->GetNx();
00275 ix = ixy - iy*fOwner->GetNx();
00276 dx = xcg - ix;
00277 dy = ycg - iy;
00278 et = fOwner->PredictEnergy(dx, dy, -1);
00279 if( et > 0.02 ) es += (*ph).amp;
00280 ph++;
00281 }
00282 return es;
00283 }
00284
00285
00286
00287 float EmcCluster::GetE4()
00288
00289 {
00290 float xcg, ycg, xx, xy, yy;
00291 float e1, e2, e3, e4;
00292 int ix0, iy0, isx, isy;
00293
00294 GetMoments( &xcg, &ycg, &xx, &xy, &yy );
00295 xcg /= fOwner->GetModSizex();
00296 ycg /= fOwner->GetModSizey();
00297 ix0 = int(xcg+0.5);
00298 iy0 = int(ycg+0.5);
00299
00300 isx = 1;
00301 if( xcg-ix0 < 0 ) isx = -1;
00302 isy = 1;
00303 if( ycg-iy0 < 0 ) isy = -1;
00304
00305 e1 = GetTowerEnergy(ix0, iy0 );
00306 e2 = GetTowerEnergy(ix0+isx, iy0 );
00307 e3 = GetTowerEnergy(ix0+isx, iy0+isy);
00308 e4 = GetTowerEnergy(ix0 , iy0+isy);
00309
00310 return (e1 + e2 + e3 + e4);
00311 }
00312
00313
00314 float EmcCluster::GetE9()
00315
00316 {
00317 float xcg, ycg, xx, xy, yy;
00318 int i, ic, ich, ixc, ix0, iy0, ichmax, ichmin, nhit;
00319 float e;
00320 EmcModule *hlist, *vv;
00321 vector<EmcModule>::iterator ph;
00322
00323 e=0;
00324
00325 nhit = fHitList.size();
00326
00327 if( nhit <= 0 ) return e;
00328
00329 hlist = new EmcModule[nhit];
00330
00331 ph = fHitList.begin();
00332 vv = hlist;
00333 while( ph != fHitList.end() ) *vv++ = *ph++;
00334
00335 qsort( hlist, nhit, sizeof(EmcModule), fOwner->HitNCompare );
00336
00337 GetMoments( &xcg, &ycg, &xx, &xy, &yy );
00338 xcg /= fOwner->GetModSizex();
00339 ycg /= fOwner->GetModSizey();
00340 ix0 = int(xcg+0.5);
00341 iy0 = int(ycg+0.5);
00342 ich = iy0*fOwner->GetNx() + ix0;
00343
00344 ichmax = ich + fOwner->GetNx() + 1;
00345 ichmin = ich - fOwner->GetNx() - 1;
00346
00347 for( i=0; i<nhit; i++ )
00348 if( hlist[i].ich >= ichmin ) break;
00349 while( (i < nhit) && ( (ic=hlist[i].ich) <= ichmax) ) {
00350 ixc = ic - ic/fOwner->GetNx()*fOwner->GetNx();
00351 if( abs(ixc-ix0) <= 1 ) e += hlist[i].amp;
00352 i++;
00353 }
00354
00355 delete [] hlist;
00356 return e;
00357 }
00358
00359
00360
00361 float EmcCluster::GetE9( int ich )
00362
00363 {
00364 int i, ic, ixc, ix0, ichmax, ichmin, nhit;
00365 float e;
00366 EmcModule *hlist, *vv;
00367 vector<EmcModule>::iterator ph;
00368
00369 e=0;
00370
00371 nhit = fHitList.size();
00372
00373 if( nhit <= 0 ) return e;
00374
00375 hlist = new EmcModule[nhit];
00376
00377 ph = fHitList.begin();
00378 vv = hlist;
00379 while( ph != fHitList.end() ) *vv++ = *ph++;
00380
00381 qsort( hlist, nhit, sizeof(EmcModule), fOwner->HitNCompare );
00382
00383 ichmax = ich + fOwner->GetNx() + 1;
00384 ichmin = ich - fOwner->GetNx() - 1;
00385 ix0 = ich - ich/fOwner->GetNx()*fOwner->GetNx();
00386
00387 for( i=0; i<nhit; i++ )
00388 if( hlist[i].ich >= ichmin ) break;
00389 while( (i < nhit) && ( (ic=hlist[i].ich) <= ichmax) ) {
00390 ixc = ic - ic/fOwner->GetNx()*fOwner->GetNx();
00391 if( abs(ixc-ix0) <= 1 ) e += hlist[i].amp;
00392 i++;
00393 }
00394
00395 delete [] hlist;
00396 return e;
00397 }
00398
00399
00400
00401 EmcModule EmcCluster::GetImpactTower()
00402
00403 {
00404 float x, y;
00405 int ix, iy, ich;
00406 EmcModule ht;
00407
00408 GetCorrPos( &x, &y );
00409 ix = lowint(x/fOwner->GetModSizex() + 0.5);
00410 iy = lowint(y/fOwner->GetModSizey() + 0.5);
00411 if( ix < 0 || ix > fOwner->GetNx()-1 || iy < 0 || iy > fOwner->GetNy()-1 ) {
00412 printf("????? EmcClusterChi2: Something wrong in GetImpactTower: (x,y)=(%f,%f) (ix,iy)=(%d,%d) \n", x, y, ix, iy);
00413 memset(&ht, 0, sizeof(EmcModule));
00414 ht.ich = -1;
00415 return ht;
00416 }
00417 else {
00418 ich = iy*fOwner->GetNx() + ix;
00419 ht.ich = ich;
00420 ht.amp = GetTowerEnergy( ich );
00421 ht.tof = GetTowerToF( ich );
00422 ht.deadmap = GetTowerDeadMap( ich );
00423 ht.warnmap = GetTowerWarnMap( ich );
00424 ht.adc=GetTowerADC(ich);
00425 ht.tac=GetTowerTAC(ich);
00426 return ht;
00427 }
00428 }
00429
00430
00431
00432 EmcModule EmcCluster::GetMaxTower()
00433
00434 {
00435 vector<EmcModule>::iterator ph;
00436 float emax=0;
00437 EmcModule ht;
00438
00439 memset(&ht, 0, sizeof(EmcModule));
00440 ht.ich = -1;
00441 if( fHitList.empty() ) return ht;
00442
00443 ph = fHitList.begin();
00444 while( ph != fHitList.end() ) {
00445 if( (*ph).amp > emax ) { emax = (*ph).amp; ht = *ph; }
00446 ph++;
00447 }
00448 return ht;
00449 }
00450
00451
00452
00453 void EmcCluster::GetHits(EmcModule* phit, int n)
00454
00455 {
00456 int nhit;
00457 EmcModule *hlist, *vv;
00458 vector<EmcModule>::iterator ph;
00459 vector<EmcModule> hl;
00460
00461 fOwner->ZeroVector(phit, n);
00462 nhit = fHitList.size();
00463
00464 if( nhit <= 0 ) return;
00465
00466 hlist = new EmcModule[nhit];
00467
00468 ph = fHitList.begin();
00469 vv = hlist;
00470 while( ph != fHitList.end() ) *vv++ = *ph++;
00471
00472 qsort( hlist, nhit, sizeof(EmcModule), fOwner->HitACompare );
00473 for( int i=0; i<min(nhit,n); i++ ) phit[i]=hlist[i];
00474 delete [] hlist;
00475 }
00476
00477
00478
00479 void EmcCluster::GetMoments( float* px, float* py, float* pxx, float* pxy, float* pyy )
00480
00481 {
00482 vector<EmcModule>::iterator ph;
00483 float e, x, y, xx, yy, xy;
00484 int nhit;
00485 EmcModule *phit, *p;
00486
00487 *px = fgXABSURD; *py = fgYABSURD;
00488 *pxx = 0; *pxy = 0; *pyy = 0;
00489 nhit=fHitList.size();
00490 if( nhit <= 0 ) return;
00491
00492 phit = new EmcModule[nhit];
00493 ph = fHitList.begin();
00494 p=phit;
00495 while( ph != fHitList.end() ) {
00496 p->ich = (*ph).ich;
00497 p->amp = (*ph).amp;
00498 ph++;
00499 p++;
00500 }
00501 fOwner->Momenta( nhit, phit, &e, &x, &y, &xx, &yy, &xy );
00502 *px = x*fOwner->GetModSizex();
00503 *py = y*fOwner->GetModSizey();
00504 *pxx = xx*fOwner->GetModSizex()*fOwner->GetModSizex();
00505 *pxy = xy*fOwner->GetModSizex()*fOwner->GetModSizey();
00506 *pyy = yy*fOwner->GetModSizey()*fOwner->GetModSizey();
00507 delete [] phit;
00508 }
00509
00510
00511
00512 void EmcCluster::GetErrors( float* pde, float* pdx, float* pdy, float* pdz)
00513 {
00514
00515
00516 float e, x, y;
00517
00518 e = GetTotalEnergy();
00519 GetCorrPos( &x, &y );
00520 fOwner->CalculateErrors( e, x, y, pde, pdx, pdy, pdz);
00521
00522 }
00523
00524
00525
00526 void EmcCluster::GetChar( float* pe,
00527 float* pxcg, float* pycg,
00528 float* pxc, float* pyc,
00529 float* pxg, float* pyg, float* pzg,
00530 float* pxx, float* pxy, float* pyy,
00531 float* pde, float* pdx, float* pdy, float* pdz )
00532 {
00533
00534
00535
00536 *pe = GetTotalEnergy();
00537 GetMoments( pxcg, pycg, pxx, pxy, pyy );
00538 fOwner->CorrectPosition( *pe, *pxcg, *pycg, pxc, pyc );
00539 fOwner->SectorToGlobal( *pxc, *pyc, 0, pxg, pyg, pzg );
00540 fOwner->CalculateErrors( *pe, *pxc, *pyc, pde, pdx, pdy, pdz);
00541
00542 }
00543
00544
00545
00546 int EmcCluster::GetPeaks( EmcPeakarea* PkList, EmcModule* ppeaks )
00547 {
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 int npk, ipk, nhit;
00561 int ixypk, ixpk, iypk, in, nh, ic;
00562 int ixy, ix, iy, nn;
00563 int ig, ng, igmpk1[fgMaxNofPeaks], igmpk2[fgMaxNofPeaks];
00564 int PeakCh[fgMaxNofPeaks];
00565 float epk[fgMaxNofPeaks*2], xpk[fgMaxNofPeaks*2], ypk[fgMaxNofPeaks*2];
00566 float ratio, eg, dx, dy, a, chi, chi0;
00567 float *Energy[fgMaxNofPeaks], *totEnergy, *tmpEnergy;
00568 EmcModule *ip;
00569 EmcModule *phit, *hlist, *vv;
00570 EmcPeakarea peak(fOwner);
00571 vector<EmcModule>::iterator ph;
00572 vector<EmcModule> hl;
00573
00574 nhit = fHitList.size();
00575
00576 if( nhit <= 0 ) return 0;
00577
00578 hlist = new EmcModule[nhit];
00579
00580 ph = fHitList.begin();
00581 vv = hlist;
00582 while( ph != fHitList.end() ) *vv++ = *ph++;
00583
00584
00585 qsort( hlist, nhit, sizeof(EmcModule), fOwner->HitNCompare );
00586
00587
00588
00589
00590 npk=0;
00591 for( ic=0; ic<nhit; ic++ ) {
00592 float amp = hlist[ic].amp;
00593 if( amp > fOwner->GetPeakThreshold() ) {
00594 int ich = hlist[ic].ich;
00595 int ichmax = ich + fOwner->GetNx() + 1;
00596 int ichmin = ich - fOwner->GetNx() - 1;
00597 int ixc = ich - ich/fOwner->GetNx()*fOwner->GetNx();
00598 int in = ic + 1;
00599
00600 while( (in < nhit) && (hlist[in].ich <= ichmax) ) {
00601 int ix = hlist[in].ich - hlist[in].ich/fOwner->GetNx()*fOwner->GetNx();
00602 if( (abs(ixc-ix) <= 1) && (hlist[in].amp >= amp) ) goto new_ic;
00603 in++;
00604 }
00605 in = ic - 1;
00606
00607 while( (in >= 0) && (hlist[in].ich >= ichmin) ) {
00608 int ix = hlist[in].ich - hlist[in].ich/fOwner->GetNx()*fOwner->GetNx();
00609 if( (abs(ixc-ix) <= 1) && (hlist[in].amp > amp) ) goto new_ic;
00610 in--;
00611 }
00612 if( npk >= fgMaxNofPeaks ) { delete [] hlist; return -1; }
00613
00614
00615 PeakCh[npk]=ic;
00616 npk++;
00617 }
00618 new_ic: continue;
00619 }
00620
00621
00622 if( npk <= 1 ) {
00623 hl.erase( hl.begin(), hl.end() );
00624 for( int ich=0; ich<nhit; ich++ ) hl.push_back(hlist[ich]);
00625 peak.ReInitialize(hl);
00626 PkList[0]=peak;
00627
00628 if( npk == 1 ) *ppeaks = hlist[PeakCh[0]];
00629 else *ppeaks = GetMaxTower();
00630
00631 delete [] hlist;
00632 return 1;
00633 }
00634
00635
00636
00637 for( ipk=0; ipk<npk; ipk++ ) { Energy[ipk] = new float[nhit]; }
00638 totEnergy = new float[nhit];
00639 tmpEnergy = new float[nhit];
00640 for ( int i = 0; i < nhit; ++i )
00641 {
00642 totEnergy[i]=0.0;
00643 tmpEnergy[i]=0.0;
00644 }
00645
00646
00647
00648 ratio = 1.;
00649 for( int iter=0; iter<fgPeakIter; iter++ ) {
00650 fOwner->ZeroVector( tmpEnergy, nhit );
00651 for( ipk=0; ipk<npk; ipk++ ) {
00652
00653 ic = PeakCh[ipk];
00654 if( iter > 0 ) ratio = Energy[ipk][ic]/totEnergy[ic];
00655 eg = hlist[ic].amp * ratio;
00656 ixypk = hlist[ic].ich;
00657 iypk = ixypk/fOwner->GetNx();
00658 ixpk = ixypk - iypk*fOwner->GetNx();
00659 epk[ipk] = eg;
00660 xpk[ipk] = eg * ixpk;
00661 ypk[ipk] = eg * iypk;
00662
00663
00664 if( ic < nhit-1 ){
00665 for( in=ic+1; in<nhit; in++ ) {
00666 ixy = hlist[in].ich;
00667 iy = ixy/fOwner->GetNx();
00668 ix = ixy - iy*fOwner->GetNx();
00669
00670 if( (ixy-ixypk) > fOwner->GetNx()+1 ) break;
00671 if( abs(ix-ixpk) <= 1 ) {
00672 if( iter > 0 ) ratio = Energy[ipk][in]/totEnergy[in];
00673 eg = hlist[in].amp * ratio;
00674 epk[ipk] += eg;
00675 xpk[ipk] += eg*ix;
00676 ypk[ipk] += eg*iy;
00677 }
00678 }
00679 }
00680
00681
00682 if( ic >= 1 ){
00683 for( in=ic-1; in >= 0; in-- ) {
00684 ixy = hlist[in].ich;
00685 iy = ixy/fOwner->GetNx();
00686 ix = ixy - iy*fOwner->GetNx();
00687 if( (ixypk-ixy) > fOwner->GetNx()+1 ) break;
00688 if( abs(ix-ixpk) <= 1 ) {
00689 if( iter > 0 ) ratio = Energy[ipk][in]/totEnergy[in];
00690 eg = hlist[in].amp * ratio;
00691 epk[ipk] += eg;
00692 xpk[ipk] += eg*ix;
00693 ypk[ipk] += eg*iy;
00694 }
00695 }
00696 }
00697
00698 xpk[ipk] = xpk[ipk]/epk[ipk];
00699 ypk[ipk] = ypk[ipk]/epk[ipk];
00700 fOwner->SetProfileParameters(0, epk[ipk], xpk[ipk], ypk[ipk]);
00701
00702 for( in=0; in<nhit; in++ ) {
00703 ixy = hlist[in].ich;
00704 iy = ixy/fOwner->GetNx();
00705 ix = ixy - iy*fOwner->GetNx();
00706 dx = xpk[ipk]-ix;
00707 dy = ypk[ipk]-iy;
00708 a = 0;
00709
00710
00711 if( ABS(dx) < 2.5 && ABS(dy) < 2.5 )
00712 a = epk[ipk]*fOwner->PredictEnergy(dx, dy, -1);
00713
00714 Energy[ipk][in] = a;
00715 tmpEnergy[in] += a;
00716 }
00717
00718 }
00719 float flim = 0.000001;
00720 for ( in = 0; in < nhit; in++ )
00721 {
00722 if (tmpEnergy[in] > flim)
00723 {
00724 totEnergy[in] = tmpEnergy[in];
00725 }
00726 else
00727 {
00728 totEnergy[in] = flim;
00729 }
00730 }
00731 }
00732
00733 phit = new EmcModule[nhit];
00734
00735 ng=0;
00736 for( ipk=0; ipk<npk; ipk++ ) {
00737 nh=0;
00738
00739
00740 for( in=0; in<nhit; in++ ) {
00741 if( tmpEnergy[in] > 0 ) {
00742 ixy = hlist[in].ich;
00743 a = hlist[in].amp * Energy[ipk][in]/tmpEnergy[in];
00744 if( a > fgEmin ) {
00745 phit[nh].ich=ixy;
00746 phit[nh].amp=a;
00747 phit[nh].tof= hlist[in].tof;
00748 phit[nh].deadmap= hlist[in].deadmap;
00749 phit[nh].warnmap= hlist[in].warnmap;
00750
00751
00752 phit[nh].adc=0.;
00753 phit[nh].tac=0.;
00754
00755 nh++;
00756 }
00757 }
00758 }
00759
00760
00761 if( nh>0 ) {
00762 chi=fOwner->Chi2Limit(nh)*10;
00763 int ndf;
00764
00765 fOwner->Gamma(nh, phit,&chi, &chi0, &epk[ng], &xpk[ng], &ypk[ng],
00766 &epk[ng+1], &xpk[ng+1], &ypk[ng+1], ndf);
00767
00768 igmpk1[ipk]=ng;
00769 igmpk2[ipk]=ng;
00770 if( epk[ng+1]>0 ) { ng++; igmpk2[ipk]=ng;}
00771 ng++;
00772 }
00773 else {
00774 igmpk1[ipk]=-1;
00775 igmpk2[ipk]=-1;
00776 }
00777 }
00778
00779 fOwner->ZeroVector( tmpEnergy, nhit );
00780 for( ipk=0; ipk<npk; ipk++ ) {
00781 ig=igmpk1[ipk];
00782 if( ig >= 0 ) {
00783 fOwner->SetProfileParameters(0, epk[ig], xpk[ig], ypk[ig]);
00784 for( in=0; in<nhit; in++ ) {
00785 Energy[ipk][in]=0;
00786 for(ig=igmpk1[ipk]; ig<=igmpk2[ipk]; ig++){
00787 ixy = hlist[in].ich;
00788 iy = ixy/fOwner->GetNx();
00789 ix = ixy - iy*fOwner->GetNx();
00790 dx = xpk[ig]-ix;
00791 dy = ypk[ig]-iy;
00792 a = epk[ig]*fOwner->PredictEnergy(dx, dy, epk[ig]);
00793 Energy[ipk][in] += a;
00794 tmpEnergy[in] += a;
00795 }
00796 }
00797 }
00798 }
00799
00800 ip = ppeaks;
00801 nn=0;
00802 for( ipk=0; ipk<npk; ipk++ ) {
00803 nh=0;
00804 for( in=0; in<nhit; in++ ) {
00805 if( tmpEnergy[in] > 0 ) {
00806 ixy = hlist[in].ich;
00807 a = hlist[in].amp * Energy[ipk][in]/tmpEnergy[in];
00808 if( a > fgEmin ) {
00809 phit[nh].ich=ixy;
00810 phit[nh].amp=a;
00811 phit[nh].tof=hlist[in].tof;
00812 phit[nh].deadmap=hlist[in].deadmap;
00813 phit[nh].warnmap=hlist[in].warnmap;
00814
00815
00816 phit[nh].adc=0.;
00817 phit[nh].tac=0.;
00818
00819 nh++;
00820 }
00821 }
00822 }
00823 if( nh>0 ) {
00824 *ip++ = hlist[PeakCh[ipk]];
00825 hl.erase( hl.begin(), hl.end() );
00826 for( in=0; in<nh; in++ ) hl.push_back(phit[in]);
00827 peak.ReInitialize(hl);
00828 PkList[nn++]=peak;
00829 }
00830 }
00831
00832 delete [] phit;
00833 delete [] hlist;
00834 for( ipk=0; ipk<npk; ipk++ ) delete [] Energy[ipk];
00835 delete [] totEnergy;
00836 delete [] tmpEnergy;
00837
00838 return nn;
00839 }
00840
00841
00842
00843
00844 void EmcPeakarea::GetChar( float* pe, float* pec,
00845 float* pecore, float* pecorec,
00846 float* pxcg, float* pycg,
00847 float* pxcgmin, float* pycgmin,
00848 float* pxc, float* pyc,
00849 float* pxg, float* pyg, float* pzg,
00850 float* pxx, float* pxy, float* pyy,
00851 float* pchi,
00852 float* pde, float* pdx, float* pdy, float* pdz )
00853
00854
00855 {
00856 float chi, chi0;
00857 float e1, x1, y1, e2, x2, y2;
00858 int nh;
00859 EmcModule *phit, *vv;
00860 vector<EmcModule>::iterator ph;
00861 vector<EmcModule> hl;
00862 float tmplvalue;
00863
00864 *pe = 0;
00865 hl = fHitList;
00866 nh = hl.size();
00867 if( nh <= 0 ) return;
00868
00869 phit = new EmcModule[nh];
00870
00871 ph = hl.begin();
00872 vv = phit;
00873 while( ph != hl.end() ) *vv++ = *ph++;
00874
00875 chi = fgChisq*1000;
00876 int ndf;
00877 fOwner->Gamma(nh, phit, &chi, &chi0, &e1, &x1, &y1, &e2, &x2, &y2, ndf);
00878 fNdf=ndf;
00879 *pchi=chi0;
00880
00881
00882 tmplvalue=fOwner->Chi2Correct(chi0, ndf)*ndf;
00883 if(tmplvalue>0.) fCL=TMath::Prob(tmplvalue, ndf);
00884 else fCL=1.;
00885
00886
00887 *pxcgmin = x1*fOwner->GetModSizex();
00888 *pycgmin = y1*fOwner->GetModSizey();
00889
00890 *pe = GetTotalEnergy();
00891 *pecore = GetECore();
00892 GetMoments( pxcg, pycg, pxx, pxy, pyy );
00893 fOwner->CorrectPosition(*pe, *pxcgmin, *pycgmin, pxc, pyc);
00894 fOwner->SectorToGlobal( *pxc, *pyc, 0, pxg, pyg, pzg );
00895 fOwner->CalculateErrors( *pe, *pxc, *pyc, pde, pdx, pdy, pdz);
00896 fOwner->CorrectEnergy( *pe, *pxcg, *pycg, pec );
00897 fOwner->CorrectECore( *pecore, *pxc, *pyc, pecorec );
00898
00899 delete [] phit;
00900
00901 }
00902
00903
00904
00905 float EmcPeakarea::GetChi2()
00906
00907
00908 {
00909 float chi, chi0, chicorr;
00910 float e1, x1, y1, e2, x2, y2;
00911 int nh;
00912 EmcModule *phit, *vv;
00913 vector<EmcModule>::iterator ph;
00914 vector<EmcModule> hl;
00915
00916 hl = fHitList;
00917 nh = hl.size();
00918 if( nh <= 0 ) return 0;
00919
00920 phit = new EmcModule[nh];
00921
00922 ph = hl.begin();
00923 vv = phit;
00924 while( ph != hl.end() ) *vv++ = *ph++;
00925
00926 chi = fgChisq*1000;
00927 int ndf;
00928 fOwner->Gamma(nh, phit, &chi, &chi0, &e1, &x1, &y1, &e2, &x2, &y2, ndf);
00929 fNdf=ndf;
00930 chicorr = fOwner->Chi2Correct(chi0, ndf);
00931
00932 delete [] phit;
00933 return chi0;
00934 }
00935
00936
00937
00938 float EmcPeakarea::GetCLNew()
00939
00940 {
00941 float xcg, ycg, xx, xy, yy;
00942 float e1, e2, e3, e4;
00943 float e1m, e2m, e3m, e4m;
00944 float e1p, e2p, e3p, e4p;
00945 float s1, s2, s3, s4;
00946 float dx, dy, dt, et, etot, sc;
00947 float chi2, pr;
00948 int ix0, iy0, isx, isy, ndf;
00949
00950 etot = GetTotalEnergy();
00951 GetMoments( &xcg, &ycg, &xx, &xy, &yy );
00952 xcg /= fOwner->GetModSizex();
00953 ycg /= fOwner->GetModSizey();
00954 ix0 = int(xcg+0.5);
00955 iy0 = int(ycg+0.5);
00956 dx = ABS(xcg-ix0);
00957 dy = ABS(ycg-iy0);
00958
00959 isx = 1;
00960 if( xcg-ix0 < 0 ) isx = -1;
00961 isy = 1;
00962 if( ycg-iy0 < 0 ) isy = -1;
00963
00964 e1 = GetTowerEnergy(ix0, iy0 );
00965 e2 = GetTowerEnergy(ix0+isx, iy0 );
00966 e3 = GetTowerEnergy(ix0+isx, iy0+isy);
00967 e4 = GetTowerEnergy(ix0 , iy0+isy);
00968
00969 if( dy > dx ) {
00970 et = e2;
00971 e2 = e4;
00972 e4 = et;
00973 dt = dx;
00974 dx = dy;
00975 dy = dt;
00976 }
00977
00978 e1m = e1 + e2 + e3 + e4;
00979 e2m = e1 + e2 - e3 - e4;
00980 e3m = e1 - e2 - e3 + e4;
00981 e4m = e4 - e3;
00982
00983 e1p = 0.932;
00984 e2p = 0.835 - 2*dy*dy/(dy+0.099);
00985 e3p = 0.835 - 2*dx*dx/(dx+0.099);
00986 e4p = 0.02;
00987
00988 sc = sqrt(0.1*0.1/etot + 0.03*0.03)/0.04;
00989 s1 = sc*0.02;
00990 sc = sqrt(0.1*0.1/etot + 0.02*0.02)/0.04;
00991 s2 = sc*(0.056-0.026*e2p);
00992 s3 = sc*(0.056-0.026*e2p);
00993 s4 = sc*0.03;
00994
00995 chi2 = 0.;
00996 chi2 += (e1p*etot-e1m)*(e1p*etot-e1m)/s1/s1/etot/etot;
00997 chi2 += (e2p*etot-e2m)*(e2p*etot-e2m)/s2/s2/etot/etot;
00998 chi2 += (e3p*etot-e3m)*(e3p*etot-e3m)/s3/s3/etot/etot;
00999 chi2 += (e4p*etot-e4m)*(e4p*etot-e4m)/s4/s4/etot/etot;
01000 chi2 /= 0.7;
01001
01002 ndf = 4;
01003 pr = TMath::Prob(chi2, ndf);
01004 return pr;
01005 }
01006
01007
01008
01009 float EmcPeakarea::GetChi2New()
01010
01011 {
01012 float xcg, ycg, xx, xy, yy;
01013 float e1, e2, e3, e4;
01014 float e1m, e2m, e3m, e4m;
01015 float e1p, e2p, e3p, e4p;
01016 float s1, s2, s3, s4;
01017 float dx, dy, dt, et, etot, sc;
01018 float chi2;
01019 int ix0, iy0, isx, isy, ndf;
01020
01021 etot = GetTotalEnergy();
01022 GetMoments( &xcg, &ycg, &xx, &xy, &yy );
01023 xcg /= fOwner->GetModSizex();
01024 ycg /= fOwner->GetModSizey();
01025 ix0 = int(xcg+0.5);
01026 iy0 = int(ycg+0.5);
01027 dx = ABS(xcg-ix0);
01028 dy = ABS(ycg-iy0);
01029
01030 isx = 1;
01031 if( xcg-ix0 < 0 ) isx = -1;
01032 isy = 1;
01033 if( ycg-iy0 < 0 ) isy = -1;
01034
01035 e1 = GetTowerEnergy(ix0, iy0 );
01036 e2 = GetTowerEnergy(ix0+isx, iy0 );
01037 e3 = GetTowerEnergy(ix0+isx, iy0+isy);
01038 e4 = GetTowerEnergy(ix0 , iy0+isy);
01039
01040 if( dy > dx ) {
01041 et = e2;
01042 e2 = e4;
01043 e4 = et;
01044 dt = dx;
01045 dx = dy;
01046 dy = dt;
01047 }
01048
01049 e1m = e1 + e2 + e3 + e4;
01050 e2m = e1 + e2 - e3 - e4;
01051 e3m = e1 - e2 - e3 + e4;
01052 e4m = e4 - e3;
01053
01054 e1p = 0.932;
01055 e2p = 0.835 - 2*dy*dy/(dy+0.099);
01056 e3p = 0.835 - 2*dx*dx/(dx+0.099);
01057 e4p = 0.02;
01058
01059 sc = sqrt(0.1*0.1/etot + 0.03*0.03)/0.04;
01060 s1 = sc*0.02;
01061 sc = sqrt(0.1*0.1/etot + 0.02*0.02)/0.04;
01062 s2 = sc*(0.056-0.026*e2p);
01063 s3 = sc*(0.056-0.026*e2p);
01064 s4 = sc*0.03;
01065
01066 chi2 = 0.;
01067 chi2 += (e1p*etot-e1m)*(e1p*etot-e1m)/s1/s1/etot/etot;
01068 chi2 += (e2p*etot-e2m)*(e2p*etot-e2m)/s2/s2/etot/etot;
01069 chi2 += (e3p*etot-e3m)*(e3p*etot-e3m)/s3/s3/etot/etot;
01070 chi2 += (e4p*etot-e4m)*(e4p*etot-e4m)/s4/s4/etot/etot;
01071 chi2 /= 0.7;
01072
01073 ndf = 4;
01074 return chi2/ndf;
01075 }
01076
01077
01078
01079 void EmcPeakarea::GetCGmin( float* px, float* py )
01080 {
01081
01082
01083 float chi, chi0;
01084 float e1, x1, y1, e2, x2, y2;
01085 int nh;
01086 EmcModule *phit, *vv;
01087 vector<EmcModule>::iterator ph;
01088 vector<EmcModule> hl;
01089
01090 *px = fgXABSURD;
01091 *py = fgYABSURD;
01092 hl = fHitList;
01093 nh = hl.size();
01094 if( nh <= 0 ) return;
01095
01096 phit = new EmcModule[nh];
01097
01098 ph = hl.begin();
01099 vv = phit;
01100 while( ph != hl.end() ) *vv++ = *ph++;
01101
01102 chi = fgChisq*1000;
01103 int ndf;
01104 fOwner->Gamma(nh, phit, &chi, &chi0, &e1, &x1, &y1, &e2, &x2, &y2, ndf);
01105 fNdf=ndf;
01106 *px = x1*fOwner->GetModSizex();
01107 *py = y1*fOwner->GetModSizey();
01108
01109 delete [] phit;
01110
01111 }
01112
01113
01114
01115 int EmcPeakarea::GetGammas( EmcEmshower* ShList)
01116 {
01117
01118
01119
01120
01121
01122
01123
01124 float chi, chi0, e1, x1, y1, e2, x2, y2, chicorr;
01125 int nh, ig;
01126 EmcModule *phit, *vv;
01127 EmcEmshower sh1(fOwner), sh2(fOwner);
01128 vector<EmcModule>::iterator ph;
01129 vector<EmcModule> hl;
01130
01131 hl = fHitList;
01132 nh = hl.size();
01133 if( nh <= 0 ) return 0;
01134
01135 phit = new EmcModule[nh];
01136
01137 ph = hl.begin();
01138 vv = phit;
01139 while( ph != hl.end() ) *vv++ = *ph++;
01140
01141 chi=fOwner->Chi2Limit(nh);
01142
01143 int ndf;
01144 fOwner->Gamma(nh, phit, &chi, &chi0, &e1, &x1, &y1, &e2, &x2, &y2, ndf);
01145 chicorr = fOwner->Chi2Correct(chi, ndf);
01146 if(e1>0)
01147 sh1.ReInitialize(e1, x1*fOwner->GetModSizex(), y1*fOwner->GetModSizey(),
01148 chi, ndf);
01149 else
01150 sh1.ReInitialize(0, fgXABSURD, fgYABSURD, 0, 0);
01151
01152 if( e2 > 0 )
01153 sh2.ReInitialize(e2, x2*fOwner->GetModSizex(), y2*fOwner->GetModSizey(),
01154 chi, ndf);
01155 else
01156 sh2.ReInitialize(0, fgXABSURD, fgYABSURD, 0, ndf);
01157
01158 if( e2 > e1 ) {
01159 sh1.ReInitialize(e2, x2*fOwner->GetModSizex(), y2*fOwner->GetModSizey(),
01160 chi, ndf);
01161 sh2.ReInitialize(e1, x1*fOwner->GetModSizex(), y1*fOwner->GetModSizey(),
01162 chi, ndf);
01163 }
01164
01165 ig = 0;
01166 if( e1>0 ) {
01167 ShList[ig++]=sh1;
01168 if( e2>0 ) {
01169 ShList[ig++]=sh2;
01170 }
01171 }
01172
01173 delete [] phit;
01174 return ig;
01175 }
01176
01177
01178
01179
01180 EmcEmshower::EmcEmshower():
01181 fNdf(0),
01182 fCL(1.),
01183 fEnergy(0.),
01184 fXcg(0.),
01185 fYcg(0.),
01186 fChisq(999.999)
01187 {}
01188
01189
01190
01191 EmcEmshower::EmcEmshower(EmcSectorRec *sector):
01192 fOwner(sector),
01193 fNdf(0),
01194 fCL(1.),
01195 fEnergy(0.),
01196 fXcg(0.),
01197 fYcg(0.),
01198 fChisq(999.999)
01199 {}
01200
01201
01202
01203 EmcEmshower::EmcEmshower(float e, float x, float y, float chi, int ndf,
01204 EmcSectorRec *sector):
01205 fOwner(sector),
01206 fNdf(ndf),
01207 fCL(1.),
01208 fEnergy(e),
01209 fXcg(x),
01210 fYcg(y),
01211 fChisq(chi)
01212 {}
01213
01214
01215
01216 void EmcEmshower::GetCorrPos( float* px, float* py )
01217
01218 {
01219 fOwner->CorrectPosition(fEnergy, fXcg, fYcg, px, py );
01220 }
01221
01222
01223
01224 void EmcEmshower::GetGlobalPos( float* px, float* py, float* pz )
01225
01226 {
01227 float xc, yc;
01228
01229 GetCorrPos( &xc, &yc );
01230
01231 fOwner->SectorToGlobal( xc, yc, 0, px, py, pz );
01232 }
01233
01234
01235
01236 void EmcEmshower::GetErrors( float* pde, float* pdx, float* pdy, float* pdz)
01237
01238 {
01239 float e, x, y;
01240
01241 e = GetTotalEnergy();
01242 GetCorrPos( &x, &y );
01243 fOwner->CalculateErrors( e, x, y, pde, pdx, pdy, pdz);
01244 }
01245
01246
01247
01248 void EmcEmshower::GetChar( float* pe,
01249 float* pxcg, float* pycg,
01250 float* pxc, float* pyc,
01251 float* pxg, float* pyg, float* pzg,
01252 float* pchi,
01253 float* pde, float* pdx, float* pdy, float* pdz )
01254 {
01255
01256
01257
01258 float tmplvalue;
01259
01260 *pe = GetTotalEnergy();
01261 GetCG( pxcg, pycg );
01262 fOwner->CorrectPosition( *pe, *pxcg, *pycg, pxc, pyc );
01263 fOwner->SectorToGlobal( *pxc, *pyc, 0, pxg, pyg, pzg );
01264 fOwner->CalculateErrors( *pe, *pxc, *pyc, pde, pdx, pdy, pdz);
01265 *pchi=fChisq;
01266
01267
01268 tmplvalue=fOwner->Chi2Correct(fChisq, fNdf)*fNdf;
01269 if(tmplvalue>0.) fCL=TMath::Prob(tmplvalue, fNdf);
01270 else fCL=1.;
01271
01272 }
01273
01274
01275