00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 #include "EmcSectorRec.h"
00159 #include "EmcCluster.h"
00160
00161
00162 #include "PHGeometry.h"
00163
00164 using namespace std;
00165
00166
00167
00168
00169 float const EmcSectorRec::fgMinShowerEnergy=0.1;
00170
00171
00172 int const EmcSectorRec::fgMaxLen=1000;
00173
00174
00175
00176 float EmcSectorRec::fgChi2Level[50]={
00177 6.634899, 4.605171, 3.780564, 3.318915, 3.017103,
00178 2.801872, 2.639259, 2.511249, 2.407341, 2.320967,
00179 2.247720, 2.184744, 2.129863, 2.081515, 2.038526,
00180 1.999994, 1.965214, 1.933627, 1.904781, 1.878311,
00181 1.853912, 1.831334, 1.810365, 1.790825, 1.772564,
00182 1.755449, 1.739367, 1.724222, 1.709926, 1.696406,
00183 1.683593, 1.671430, 1.659864, 1.648850, 1.638344,
00184 1.628311, 1.618716, 1.609528, 1.600721, 1.592268,
00185 1.584148, 1.576338, 1.568822, 1.561579, 1.554596,
00186 1.547856, 1.541346, 1.535055, 1.528968, 1.523077 };
00187
00188
00189 float EmcSectorRec::fgChi2Level1[50]={
00190 6.634899, 4.605171, 3.780564, 3.318915, 3.017103,
00191 2.801872, 2.639259, 2.511249, 2.407341, 2.320967,
00192 2.247720, 2.184744, 2.129863, 2.081515, 2.038526,
00193 1.999994, 1.965214, 1.933627, 1.904781, 1.878311,
00194 1.853912, 1.831334, 1.810365, 1.790825, 1.772564,
00195 1.755449, 1.739367, 1.724222, 1.709926, 1.696406,
00196 1.683593, 1.671430, 1.659864, 1.648850, 1.638344,
00197 1.628311, 1.618716, 1.609528, 1.600721, 1.592268,
00198 1.584148, 1.576338, 1.568822, 1.561579, 1.554596,
00199 1.547856, 1.541346, 1.535055, 1.528968, 1.523077 };
00200
00201
00202 float EmcSectorRec::fgChi2Level2[50]={
00203 5.411895, 3.912024, 3.278443, 2.916812, 2.677547,
00204 2.505458, 2.374582, 2.271008, 2.186567, 2.116065,
00205 2.056169, 2.004491, 1.959343, 1.919481, 1.883964,
00206 1.852072, 1.823237, 1.797008, 1.773021, 1.750981,
00207 1.730640, 1.711795, 1.694274, 1.677931, 1.662643,
00208 1.648301, 1.634814, 1.622101, 1.610093, 1.598727,
00209 1.587948, 1.577709, 1.567968, 1.558684, 1.549824,
00210 1.541357, 1.533256, 1.525494, 1.518051, 1.510903,
00211 1.504033, 1.497424, 1.491059, 1.484924, 1.479006,
00212 1.473292, 1.467771, 1.462433, 1.457267, 1.452265 };
00213
00214
00215
00216
00217 EmcSectorRec::EmcSectorRec()
00218 {
00219 fModules=new vector<EmcModule>;
00220 fClusters=new vector<EmcCluster>;
00221 SetPeakThreshold(0.08);
00222 SetChi2Limit(2);
00223 }
00224
00225
00226
00227 EmcSectorRec::~EmcSectorRec()
00228 {
00229
00230 if(fModules){
00231
00232 fModules->clear();
00233 delete fModules;
00234
00235 }
00236
00237 if(fClusters){
00238
00239 fClusters->clear();
00240 delete fClusters;
00241
00242 }
00243 }
00244
00245
00246
00247 void EmcSectorRec::SetGeometry(SecGeom const &geom, PHMatrix * rm, PHVector * tr )
00248 {
00249
00250
00251
00252
00253
00254 emcrm = *rm;
00255 emctr = *tr;
00256 PHFrame local;
00257 PHFrame global=PHGeometry::MatrixAndVector2frames(local,emcrm,emctr);
00258 PHGeometry::frames2MatrixAndVector(global,local,invemcrm,invemctr);
00259
00260
00261 fNx = geom.nx;
00262 fNy = geom.ny;
00263
00264
00265 fModSizex = geom.Tower_xSize;
00266 fModSizey = geom.Tower_ySize;
00267
00268 }
00269
00270
00271
00272 void EmcSectorRec::SetModules(vector<EmcModule> const *modules)
00273 {
00274
00275 *fModules=*modules;
00276
00277 #if 0
00278
00279 vector<EmcModule>::iterator listIter;
00280 for(listIter=fModules->begin(); listIter!=fModules->end(); listIter++)
00281 listIter->fOwner=this;
00282 #endif
00283
00284 }
00285
00286
00287
00288 int EmcSectorRec::FindClusters()
00289 {
00290
00291
00292
00293 int nhit, nCl;
00294 int LenCl[fgMaxLen];
00295 int next, ib, ie, iab, iae, last, LastCl, leng, ich;
00296 int ia = 0;
00297
00298 EmcModule *vv;
00299 EmcModule *vhit, *vt;
00300 EmcCluster Clt(this);
00301 vector<EmcModule>::iterator ph;
00302 vector<EmcModule> hl;
00303
00304 (*fClusters).erase( (*fClusters).begin(), (*fClusters).end() );
00305 nhit = (*fModules).size();
00306
00307 if( nhit <= 0 ) return 0;
00308 if( nhit == 1 ) {
00309 Clt.ReInitialize( (*fModules) );
00310 fClusters->push_back(Clt);
00311 return 1;
00312 }
00313
00314 vt = new EmcModule[nhit];
00315 vhit = new EmcModule[nhit];
00316
00317 ph = (*fModules).begin();
00318 vv = vhit;
00319 while( ph != (*fModules).end() ) *vv++ = *ph++;
00320
00321 qsort( vhit, nhit, sizeof(EmcModule), HitNCompare );
00322
00323 nCl=0;
00324 next = 0;
00325 for( ich=1; ich<nhit+1; ich++ ){
00326 if( ich<nhit ) ia=vhit[ich].ich;
00327
00328
00329 if( (ia-vhit[ich-1].ich > 1) || (ich >= nhit)
00330 ||(ia-ia/fNx*fNx == 0) ){
00331 ib=next;
00332 ie=ich-1;
00333 next=ich;
00334 if( nCl >= fgMaxLen ) {
00335 return -1;
00336 }
00337 nCl++;
00338 LenCl[nCl-1]=next-ib;
00339 if( nCl > 1 ) {
00340
00341 iab=vhit[ib].ich;
00342 iae=vhit[ie].ich;
00343 last=ib-1;
00344 LastCl=nCl-2;
00345 for( int iCl=LastCl; iCl>=0; iCl-- ){
00346 leng=LenCl[iCl];
00347
00348 #ifdef GLUE_CLUSTER_CORNER
00349
00350
00351 if( (iab-vhit[last].ich > fNx+1) ||
00352
00353 ( (iab-vhit[last].ich == fNx+1) &&
00354 (iab-iab/fNx*fNx == 0) ) ) goto new_ich;
00355 for( int ichc=last; ichc >= last-leng+1; ichc-- ) {
00356
00357 if( (iab-vhit[ichc].ich > fNx+1) ||
00358
00359 ( (iab-vhit[ichc].ich == fNx+1) &&
00360 (iab-iab/fNx*fNx == 0) ) ) goto new_icl;
00361
00362 if( (iae-vhit[ichc].ich >= fNx-1) &&
00363
00364 ( (iae-vhit[ichc].ich != fNx-1) ||
00365 ((iae+1)-(iae+1)/fNx*fNx != 0) ) ) {
00366
00367 #else
00368
00369 if( iab-vhit[last].ich > fNx ) goto new_ich;
00370 for( int ichc=last; ichc >= last-leng+1; ichc-- ) {
00371 if( iab-vhit[ichc].ich > fNx ) goto new_icl;
00372 if( iae-vhit[ichc].ich >= fNx ) {
00373
00374 #endif
00375 CopyVector( &vhit[last+1-leng], vt, leng );
00376 CopyVector( &vhit[last+1], &vhit[last+1-leng], ib-1-last )
00377 ;
00378 CopyVector( vt, &vhit[ib-leng], leng );
00379 for( int i=iCl; i<nCl-2; i++ ) LenCl[i]=LenCl[i+1];
00380 ib -= leng;
00381 LenCl[nCl-2]=LenCl[nCl-1]+leng;
00382 nCl--;
00383 goto new_icl;
00384 }
00385 }
00386 new_icl: last=last-leng;
00387 }
00388 }
00389 }
00390 new_ich: continue;
00391 }
00392 if( nCl > 0 ) {
00393 ib=0;
00394 for( int iCl=0; iCl<nCl; iCl++ ) {
00395 leng=LenCl[iCl];
00396 hl.erase( hl.begin(), hl.end() );
00397 for( ich=0; ich<leng; ich++ ) hl.push_back(vhit[ib+ich]);
00398 Clt.ReInitialize(hl);
00399 ib += LenCl[iCl];
00400 fClusters->push_back(Clt);
00401 }
00402 }
00403 delete [] vhit;
00404 delete [] vt;
00405
00406 return nCl;
00407
00408 }
00409
00410
00411 void EmcSectorRec::GetImpactAngle(float x, float y, float *sinT )
00412
00413 {
00414 float xVert, yVert, zVert;
00415 float vx, vy, vz;
00416
00417 GlobalToSector( fVx, fVy, fVz, &xVert, &yVert, &zVert );
00418 vz = -zVert;
00419 vy = y - yVert;
00420 vx = x - xVert;
00421
00422 *sinT = sqrt((vx*vx+vy*vy)/(vx*vx+vy*vy+vz*vz));
00423 }
00424
00425
00426 void EmcSectorRec::GlobalToSector(float xgl, float ygl, float zgl, float* px,
00427 float* py, float* pz)
00428 {
00429
00430 PHPoint phnxHit(xgl, ygl, zgl);
00431 PHPoint emcHit = PHGeometry::transformPoint(invemcrm, invemctr, phnxHit);
00432 *px = emcHit.getX();
00433 *py = emcHit.getY();
00434 *pz = emcHit.getZ();
00435
00436 }
00437
00438
00439
00440 void EmcSectorRec::SectorToGlobal(float xsec, float ysec, float zsec,
00441 float* px, float* py, float* pz )
00442 {
00443 PHPoint emcHit(xsec, ysec, zsec);
00444 PHPoint phnxHit = PHGeometry::transformPoint(emcrm, emctr, emcHit);
00445 *px = phnxHit.getX();
00446 *py = phnxHit.getY();
00447 *pz = phnxHit.getZ();
00448
00449 }
00450
00451
00452
00453
00454 void EmcSectorRec::SectorToGlobalErr( float dxsec, float dysec, float dzsec,
00455 float* pdx, float* pdy, float* pdz )
00456 {
00457 *pdx = 0.;
00458 *pdy = 0.;
00459 *pdz = 0.;
00460 }
00461
00462
00463
00464 void EmcSectorRec::Gamma(int nh, EmcModule* phit, float* pchi, float* pchi0,
00465 float* pe1, float* px1, float* py1, float* pe2,
00466 float* px2, float* py2, int &ndf)
00467 {
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 float e1, x1, y1, e2, x2, y2;
00480 float chi, chi0, chi00, chisq0, chisave;
00481 float chir, chil, chiu, chid;
00482 int dof;
00483 float x0, y0, d2, xm2;
00484 float stepx, stepy, parx, pary;
00485 const float dxy=0.06;
00486 const float stepmin=0.01;
00487 const float zTG=100;
00488 const float xmcut=0.0015;
00489
00490 *pe1=0;
00491 *px1=0;
00492 *py1=0;
00493 *pe2=0;
00494 *px2=0;
00495 *py2=0;
00496 if( nh <= 0 ) return;
00497 Mom1(nh,phit,&e1,&x1,&y1);
00498 *pe1=e1;
00499 if( e1 <= 0 ) return;
00500
00501 SetProfileParameters(0, e1,x1,y1);
00502
00503 chisave = *pchi;
00504 chi = *pchi;
00505
00506 chi0 = ClusterChisq(nh, phit, e1, x1, y1, ndf);
00507
00508 chisq0 = chi0;
00509 dof = ndf;
00510
00511
00512 if( dof < 1 ) dof=1;
00513 chi = chisq0/dof;
00514 x0 = x1;
00515 y0 = y1;
00516 for(;;){
00517
00518 chir = ClusterChisq(nh, phit, e1, x0+dxy, y0, ndf);
00519 chil = ClusterChisq(nh, phit, e1, x0-dxy, y0, ndf);
00520 chiu = ClusterChisq(nh, phit, e1, x0, y0+dxy, ndf);
00521 chid = ClusterChisq(nh, phit, e1, x0, y0-dxy, ndf);
00522
00523 if( (chi0 > chir) || (chi0 > chil) ) {
00524 stepx = dxy;
00525 if( chir > chil ) stepx = -stepx;
00526 }
00527 else {
00528 stepx = 0;
00529 parx = chir+chil-2*chi0;
00530 if( parx > 0 ) stepx = -dxy*(chir-chil)/2/parx;
00531 }
00532
00533 if( (chi0 > chiu) || (chi0 > chid) ) {
00534 stepy = dxy;
00535 if( chiu > chid ) stepy = -stepy;
00536 }
00537 else {
00538 stepy = 0;
00539 pary = chiu+chid-2*chi0;
00540 if( pary > 0 ) stepy = -dxy*(chiu-chid)/2/pary;
00541 }
00542 if( (EmcCluster::ABS(stepx) < stepmin) && (EmcCluster::ABS(stepy) < stepmin) ) break;
00543 chi00 = ClusterChisq(nh, phit, e1, x0+stepx, y0+stepy, ndf);
00544
00545 if( chi00 >= chi0 ) break;
00546 chi0 = chi00;
00547 x0 += stepx;
00548 y0 += stepy;
00549 }
00550 if( chi0 < chisq0 ) {
00551 x1 = x0;
00552 y1 = y0;
00553 chi = chi0/dof;
00554 }
00555
00556 *pchi0 = chi;
00557 *pchi = chi;
00558 *px1 = x1;
00559 *py1 = y1;
00560
00561 if( e1 <= fgMinShowerEnergy ) return;
00562
00563 if( chi > chisave ) {
00564 TwoGamma(nh,phit,&chi,&e1,&x1,&y1,&e2,&x2,&y2);
00565 if( e2 > 0 ) {
00566 d2 = ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))/zTG/zTG;
00567 xm2 = e1*e2*d2;
00568 if( xm2 > 0 ) xm2 = sqrt(xm2);
00569 if( xm2 > xmcut && e1 > fgMinShowerEnergy && e2 > fgMinShowerEnergy) {
00570 *pe1 = e1;
00571 *px1 = x1;
00572 *py1 = y1;
00573 *pe2 = e2;
00574 *px2 = x2;
00575 *py2 = y2;
00576 *pchi = chi;
00577 }
00578 }
00579 }
00580 }
00581
00582
00583
00584 void EmcSectorRec::Mom1(int nh, EmcModule* phit, float* pe, float* px,
00585 float* py)
00586 {
00587
00588
00589 float a, xw, yw, e;
00590 int ix, iy;
00591 EmcModule* p;
00592
00593 *pe=0;
00594 *px=0;
00595 *py=0;
00596 if( nh <= 0 ) return;
00597 p=phit;
00598 xw=0;
00599 yw=0;
00600 e=0;
00601 for( int i=0; i<nh; i++ ) {
00602 a = p->amp;
00603 iy = p->ich / fNx;
00604 ix = p->ich - iy*fNx;
00605 e += a;
00606 xw += ix*a;
00607 yw += iy*a;
00608 p++;
00609 }
00610 *pe = e;
00611 if( e <= 0 ) return;
00612 *px = xw/e;
00613 *py = yw/e;
00614
00615 }
00616
00617
00618
00619 void EmcSectorRec::Momenta(int nh, EmcModule* phit, float* pe, float* px,
00620 float* py, float* pxx, float* pyy, float* pyx )
00621 {
00622
00623
00624 float a, x, y, e, xx, yy, yx;
00625 int ix, iy, i;
00626 EmcModule* p;
00627
00628 *pe=0;
00629 *px=0;
00630 *py=0;
00631 *pxx=0;
00632 *pyy=0;
00633 *pyx=0;
00634 if( nh <= 0 ) return;
00635
00636 p=phit;
00637 x=0;
00638 y=0;
00639 e=0;
00640 xx=0;
00641 yy=0;
00642 yx=0;
00643 for( i=0; i<nh; i++ ) {
00644 a = p->amp;
00645 iy = p->ich / fNx;
00646 ix = p->ich - iy*fNx;
00647 e += a;
00648 x += ix*a;
00649 y += iy*a;
00650 xx += a*ix*ix;
00651 yy += a*iy*iy;
00652 yx += a*ix*iy;
00653 p++;
00654 }
00655 *pe = e;
00656 if( e <= 0 ) return;
00657 x /= e;
00658 y /= e;
00659 xx = xx/e - x*x;
00660 yy = yy/e - y*y;
00661 yx = yx/e - y*x;
00662
00663 *px = x;
00664 *py = y;
00665 *pxx = xx;
00666 *pyy = yy;
00667 *pyx = yx;
00668
00669 }
00670
00671
00672
00673 int EmcSectorRec::HitNCompare(const void* h1, const void* h2)
00674 {
00675
00676 return ( ((EmcModule*)h1)->ich - ((EmcModule*)h2)->ich );
00677
00678 }
00679
00680
00681
00682 int EmcSectorRec::HitACompare(const void* h1, const void* h2)
00683 {
00684
00685 float amp1 = ((EmcModule*)h1)->amp;
00686 float amp2 = ((EmcModule*)h2)->amp;
00687 return (amp1<amp2) ? 1: (amp1>amp2) ? -1 : 0;
00688
00689 }
00690
00691
00692
00693 void EmcSectorRec::ZeroVector(int* v, int N)
00694 {
00695
00696 int* p = v;
00697 for(int i=0; i<N; i++) *p++ = 0;
00698
00699 }
00700
00701
00702
00703 void EmcSectorRec::ZeroVector(float* v, int N)
00704 {
00705
00706 float* p = v;
00707 for(int i=0; i<N; i++) *p++ = 0;
00708
00709 }
00710
00711
00712
00713 void EmcSectorRec::ZeroVector(EmcModule* v, int N)
00714 {
00715 memset(v, 0, N*sizeof(EmcModule));
00716 }
00717
00718
00719
00720 void EmcSectorRec::ResizeVector(int* Vector, int OldSize, int NewSize)
00721 {
00722
00723 int* vsave;
00724
00725 if( OldSize <= 0 ) { Vector = new int[NewSize]; return; }
00726 vsave = new int[OldSize];
00727 CopyVector( Vector, vsave, OldSize );
00728 delete [] Vector;
00729 Vector = new int[NewSize];
00730 if( NewSize > OldSize ) CopyVector( vsave, Vector, OldSize );
00731 else CopyVector( vsave, Vector, NewSize );
00732 delete [] vsave;
00733 return;
00734
00735 }
00736
00737
00738
00739 void EmcSectorRec::CopyVector(int* from, int* to, int N)
00740 {
00741
00742 if( N <= 0 ) return;
00743 for( int i=0; i<N; i++ ) to[i]=from[i];
00744
00745 }
00746
00747
00748
00749 void EmcSectorRec::CopyVector(EmcModule* from, EmcModule* to, int N)
00750 {
00751
00752 if( N <= 0 ) return;
00753 for( int i=0; i<N; i++ ) to[i]=from[i];
00754
00755 }
00756
00757
00758
00759 void EmcSectorRec::c3to5(float e0, float x0, float y0, float eps,
00760 float dx, float dy,
00761 float* pe1, float* px1, float* py1,
00762 float* pe2, float* px2, float* py2)
00763 {
00764
00765
00766
00767 *pe1 = e0*(1+eps)/2;
00768 *pe2 = e0 - *pe1;
00769 *px1 = x0 + dx*(1-eps)/2;
00770 *py1 = y0 + dy*(1-eps)/2;
00771 *px2 = x0 - dx*(1+eps)/2;
00772 *py2 = y0 - dy*(1+eps)/2;
00773
00774 }
00775
00776
00777
00778 void EmcSectorRec::SetChi2Limit(int limit)
00779 {
00780
00781
00782
00783
00784
00785 int i;
00786
00787 switch ( limit ) {
00788
00789 case 0:
00790 for( i=0; i<50; i++ ) fgChi2Level[i]=9999.;
00791 break;
00792 case 1:
00793 for( i=0; i<50; i++ ) fgChi2Level[i]=fgChi2Level1[i];
00794 break;
00795 case 2:
00796 for( i=0; i<50; i++ ) fgChi2Level[i]=fgChi2Level2[i];
00797 break;
00798 default:
00799 for( i=0; i<50; i++ ) fgChi2Level[i]=fgChi2Level1[i];
00800 break;
00801
00802 }
00803 }
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815