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 #include "EmcScSectorRec.h"
00088 #include "EmcCluster.h"
00089
00090
00091
00092
00093
00094 float EmcScSectorRec::fgEpar00 = 0.005;
00095 float EmcScSectorRec::fgEpar0 = 0.0014;
00096 float EmcScSectorRec::fgEpar1 = 0.03;
00097 float EmcScSectorRec::fgEpar2 = -0.03;
00098
00099 float EmcScSectorRec::fgEpar3 = 0.;
00100 float EmcScSectorRec::fgEpar4 = 4.0;
00101
00102
00103
00104
00105 void EmcScSectorRec::CorrectEnergy(float Energy, float x, float y,
00106 float* Ecorr)
00107 {
00108
00109
00110
00111
00112
00113 float sinT;
00114 float att, leak, corr;
00115 const float leakPar = 0.0033;
00116 const float attPar = 120;
00117 const float X0 = 2;
00118
00119 *Ecorr = Energy;
00120 if( Energy < 0.01 ) return;
00121
00122 GetImpactAngle(x, y, &sinT);
00123 leak = 2-sqrt(1+leakPar*log(1+Energy)*log(1+Energy));
00124 att = exp(log(Energy)*X0/attPar);
00125 corr = leak*att;
00126 *Ecorr = Energy/corr;
00127 }
00128
00130
00131 void EmcScSectorRec::CorrectECore(float Ecore, float x, float y, float* Ecorr)
00132 {
00133
00134
00135
00136
00137
00138 float ec, ec2, corr;
00139 float sinT;
00140 const float par1 = 0.918;
00141 const float par2 = 1.35;
00142 const float par3 = 0.003;
00143
00144 *Ecorr = Ecore;
00145 if( Ecore < 0.01 ) return;
00146
00147 GetImpactAngle(x, y, &sinT );
00148 corr = par1 * ( 1 - par2*sinT*sinT*sinT*sinT*(1 - par3*log(Ecore)) );
00149 ec = Ecore/corr;
00150
00151 CorrectEnergy( ec, x, y, &ec2);
00152 *Ecorr = ec2;
00153 }
00154
00156
00157 void EmcScSectorRec::CorrectPosition(float Energy, float x, float y,
00158 float* pxc, float* pyc, bool callSetPar)
00159 {
00160
00161
00162
00163
00164
00165
00166 float xShift, yShift, xZero, yZero, bx, by;
00167 float t, x0, y0;
00168 int ix0, iy0;
00169 int signx, signy;
00170
00171 SetProfileParameters( 0, Energy, x/GetModSizex(), y/GetModSizey() );
00172 if( fSinTx > 0 ) signx = 1;
00173 else signx = -1;
00174 if( fSinTy > 0 ) signy = 1;
00175 else signy = -1;
00176 t = 1.93+0.383*log(Energy);
00177 xShift = t*fSinTx;
00178 yShift = t*fSinTy;
00179 xZero=xShift-(0.417*EmcCluster::ABS(fSinTx)+1.500*fSinTx*fSinTx)*signx;
00180 yZero=yShift-(0.417*EmcCluster::ABS(fSinTy)+1.500*fSinTy*fSinTy)*signy;
00181 t = 0.98 + 0.98*sqrt(Energy);
00182 bx = 0.16 + t*fSinTx*fSinTx;
00183 by = 0.16 + t*fSinTy*fSinTy;
00184
00185 x0 = x/GetModSizex();
00186 x0 = x0 - xShift + xZero;
00187 ix0 = EmcCluster::lowint(x0 + 0.5);
00188 if( EmcCluster::ABS(x0-ix0) <= 0.5 ) {
00189 x0 = (ix0-xZero)+bx*asinh( 2.*(x0-ix0)*sinh(0.5/bx) );
00190 *pxc = x0*GetModSizex();
00191 }
00192 else {
00193 *pxc = x - xShift*GetModSizex();
00194 printf("????? Something wrong in CorrectPosition of EMCalClusterChi2: x=%f dx=%f\n", x, x0-ix0);
00195 }
00196
00197 y0 = y/GetModSizey();
00198 y0 = y0 - yShift + yZero;
00199 iy0 = EmcCluster::lowint(y0 + 0.5);
00200
00201 if( EmcCluster::ABS(y0-iy0) <= 0.5 ) {
00202
00203 y0 = (iy0-yZero)+by*asinh( 2.*(y0-iy0)*sinh(0.5/by) );
00204 *pyc = y0*GetModSizey();
00205
00206 }
00207 else {
00208
00209 *pyc = y - yShift*GetModSizey();
00210 printf("????? Something wrong in CorrectPosition of EMCalClusterChi2: y=%f dy=%f\n", y, y0-iy0);
00211
00212 }
00213
00214 }
00215
00216
00217
00218 void EmcScSectorRec::CalculateErrors( float e, float x, float y, float* pde,
00219 float* pdx, float* pdy, float* pdz)
00220 {
00221
00222
00223
00224
00225 float de, dy, dz, dxg, dyg, dzg;
00226 static float ae = 0.076, be = 0.022;
00227 static float a = 0.57, b = 0.155, d = 1.6;
00228 static float dx = 0.1;
00229
00230 de = sqrt( ae*ae*e + be*be*e*e );
00231 dz = a/sqrt(e) + b;
00232 dy = dz;
00233 dz = sqrt( dz*dz + d*d*fSinTx*fSinTx );
00234 dy = sqrt( dy*dy + d*d*fSinTy*fSinTy );
00235
00236 SectorToGlobalErr( dx, dy, dz, &dxg, &dyg, &dzg );
00237
00238 *pde = de;
00239 *pdx = dxg;
00240 *pdy = dyg;
00241 *pdz = dzg;
00242
00243 }
00244
00245
00246
00247 void EmcScSectorRec::SetProfileParameters(int sec, float Energy, float x,
00248 float y )
00249 {
00250
00251
00252
00253
00254
00255 float t;
00256 static float sin2ax, sin2ay, sin2a, lgE;
00257 float vx, vy, vz;
00258 float xVert, yVert, zVert;
00259 int sign;
00260
00261 if( sec >= 0 ) {
00262
00263 GlobalToSector( fVx, fVy, fVz, &xVert, &yVert, &zVert );
00264 vz = -zVert;
00265
00266 vy = y*fModSizey - yVert;
00267 vx = x*fModSizex - xVert;
00268
00269 fSinTx = vx/sqrt(vx*vx+vz*vz);
00270 fSinTy = vy/sqrt(vy*vy+vz*vz);
00271 if( EmcCluster::ABS(fSinTx) > 0.7 || EmcCluster::ABS(fSinTy) > 0.7 )
00272 printf("!!!!! Something strange in SetProfileParmeters of mEmcClusterChi2: fSinTx=%f fSinTy=%f\n",fSinTx, fSinTy);
00273 t = (vx*vx+vy*vy)/(vx*vx+vy*vy+vz*vz);
00274 sin2a=t;
00275 fSin4T=t*t;
00276 sin2ax=fSinTx*fSinTx;
00277 sin2ay=fSinTy*fSinTy;
00278 }
00279
00280 if( Energy <= 1.e-10 ) lgE=0;
00281 else lgE=log(Energy);
00282
00283 fPpar1=0.59-(1.45+0.13*lgE)*sin2a;
00284 fPpar2=0.265+(0.80+0.32*lgE)*sin2a;
00285 fPpar3=0.25+(0.45-0.036*lgE)*sin2a;
00286 fPpar4=0.42;
00287
00288 if( fSinTx > 0 ) sign = 1;
00289 else sign = -1;
00290 fPshiftx = (1.05+0.12*lgE) * sin2ax * sign;
00291
00292 if( fSinTy > 0 ) sign = 1;
00293 else sign = -1;
00294 fPshifty = (1.05+0.12*lgE) * sin2ay * sign;
00295 }
00296
00297
00298
00299 float EmcScSectorRec::PredictEnergy(float xc, float yc, float en)
00300 {
00301
00302
00303
00304
00305
00306 float dx, dy, r1, r2, r3, e;
00307
00308 if( en > 0 ) SetProfileParameters(-1,en,xc,yc);
00309 dx=fabs(xc-fPshiftx);
00310 dy=EmcCluster::ABS(yc-fPshifty);
00311 e=0;
00312 r2=dx*dx+dy*dy;
00313 r1=sqrt(r2);
00314 r3=r2*r1;
00315 e=fPpar1*exp(-r3/fPpar2)+fPpar3*exp(-r1/fPpar4);
00316
00317 return e;
00318
00319 }
00320
00321
00322
00323 void EmcScSectorRec::TwoGamma(int nh, EmcModule* phit, float* pchi, float* pe1,
00324 float* px1, float* py1, float* pe2, float* px2,
00325 float* py2)
00326 {
00327
00328 float e0, x0, y0, xx, yy, yx;
00329 float dxy, rsg2, rsq;
00330 float dxc, dyc, r, epsc;
00331 int ix, iy, ixy, in, iter, dof;
00332 float step, cosi, chisq2, u;
00333 float e1c, x1c, y1c, e2c, x2c, y2c;
00334 float eps0 = 0.0;
00335 float eps1, eps2, chisqc, ex;
00336 float dx1, dy1, dx2, dy2, a0, d;
00337 float dchi, dchi0, dd, dchida, a1, a2;
00338 float gr = 0.0;
00339 float grec, grxc, gryc, grc, gx1, gx2, gy1, gy2;
00340 float gre = 0.0;
00341 float grx = 0.0;
00342 float gry = 0.0;
00343 float scal;
00344 float dx0 = 0.0;
00345 float dy0 = 0.0;
00346
00347 const float epsmax=0.9999;
00348 const float stpmin=0.025;
00349 const float delch=2;
00350
00351 Momenta(nh,phit,&e0,&x0,&y0,&xx,&yy,&yx);
00352 *pe2 = 0;
00353 *px2 = 0;
00354 *py2 = 0;
00355 if( nh <= 0 ) return;
00356
00357 dxy = xx-yy;
00358 rsg2 = dxy*dxy + 4*yx*yx;
00359 if( rsg2 < 1e-20 ) rsg2 = 1e-20;
00360 rsq = sqrt(rsg2);
00361 dxc = -sqrt((rsq+dxy)*2);
00362 dyc = sqrt((rsq-dxy)*2);
00363 if( yx >= 0 ) dyc = -dyc;
00364 r = sqrt(dxc*dxc + dyc*dyc);
00365 epsc = 0;
00366 for( in=0; in<nh; in++ ) {
00367 ixy = phit[in].ich;
00368 iy = ixy/fNx;
00369 ix = ixy - iy*fNx;
00370 u = (ix-x0)*dxc/r + (iy-y0)*dyc/r;
00371 epsc -= phit[in].amp * u * EmcCluster::ABS(u);
00372 }
00373 epsc /= (e0*rsq);
00374 if( epsc > 0.8 ) epsc = 0.8;
00375 if( epsc < -0.8 ) epsc =-0.8;
00376 dxc /= sqrt(1-epsc*epsc);
00377 dyc /= sqrt(1-epsc*epsc);
00378
00379 step = 0.1;
00380 cosi = 0;
00381 chisq2 = 1.e35;
00382 for( iter=0; iter<100; iter++)
00383 {
00384 c3to5(e0,x0,y0,epsc,dxc,dyc,&e1c,&x1c,&y1c,&e2c,&x2c,&y2c);
00385 eps1 = (1+epsc)/2;
00386 eps2 = (1-epsc)/2;
00387 chisqc = 0;
00388 for( in=0; in<nh; in++ ) {
00389 ex = phit[in].amp;
00390 ixy = phit[in].ich;
00391 iy = ixy/fNx;
00392 ix = ixy - iy*fNx;
00393 dx1 = x1c - ix;
00394 dy1 = y1c - iy;
00395 dx2 = x2c - ix;
00396 dy2 = y2c - iy;
00397 a0 = e1c*PredictEnergy(dx1, dy1, e1c) + e2c*PredictEnergy(dx2, dy2, e2c);
00398 d = fgEpar00*fgEpar00 + e0*( fgEpar1*a0/e0 + fgEpar2*a0*a0/e0/e0 +fgEpar3*a0*a0*a0/e0/e0/e0 ) + e0*sqrt(e0)*fgEpar4*a0/e0*(1-a0/e0)*fSin4T + e0*e0*fgEpar0*fgEpar0;
00399 chisqc += (a0-ex)*(a0-ex)/d;
00400 }
00401 if( chisqc >= chisq2 ) {
00402 if( iter > 0 ) {
00403 dchi = chisqc-chisq2;
00404 dchi0 = gr*step;
00405 step /= (2*sqrt(1+dchi/dchi0));
00406 }
00407 step /= 2;
00408 }
00409 else {
00410
00411 grec = 0;
00412 grxc = 0;
00413 gryc = 0;
00414 for( in=0; in<nh; in++ ) {
00415 ex = phit[in].amp;
00416 ixy = phit[in].ich;
00417 iy = ixy/fNx;
00418 ix = ixy - iy*fNx;
00419 dx1 = x1c - ix;
00420 dy1 = y1c - iy;
00421 dx2 = x2c - ix;
00422 dy2 = y2c - iy;
00423 a1 = e1c*PredictEnergy(dx1,dy1,e1c);
00424 a2 = e2c*PredictEnergy(dx2,dy2,e2c);
00425 a0 = a1 + a2;
00426 d = fgEpar00*fgEpar00 + e0*( fgEpar1*a0/e0 + fgEpar2*a0*a0/e0/e0 +fgEpar3*a0*a0*a0/e0/e0/e0 ) + e0*sqrt(e0)*fgEpar4*a0/e0*(1-a0/e0)*fSin4T + e0*e0*fgEpar0*fgEpar0;
00427 dd = (a0-ex)/d;
00428 dchida = dd*( 2 - dd*(fgEpar1 + 2*fgEpar2*a0/e0 + 3*fgEpar3*a0*a0/e0/e0 + e0*sqrt(e0)*fgEpar4*fSin4T*(1-2*a0/e0) + 2*fgEpar0*fgEpar0*a0) );
00429 gx1 = ( e1c*PredictEnergy(x1c+0.05-ix,dy1,e1c) - a1 )*20;
00430 gx2 = ( e2c*PredictEnergy(x2c+0.05-ix,dy2,e2c) - a2 )*20;
00431 gy1 = ( e1c*PredictEnergy(dx1, y1c+0.05-iy,e1c) - a1 )*20;
00432 gy2 = ( e2c*PredictEnergy(dx2, y2c+0.05-iy,e2c) - a2 )*20;
00433 grec += (dchida*((a1/e1c-a2/e2c)*e0 - (gx1+gx2)*dxc -(gy1+gy2)*dyc)/2);
00434 grxc += (dchida*(gx1*eps2-gx2*eps1));
00435 gryc += (dchida*(gy1*eps2-gy2*eps1));
00436 }
00437 grc = sqrt(grec*grec + grxc*grxc + gryc*gryc);
00438 if( grc < 1e-10 ) grc = 1e-10;
00439 if( iter > 0 ) {
00440 cosi = (gre*grec + grx*grxc + gry*gryc ) / (gr*grc);
00441 scal = EmcCluster::ABS(gr/grc - cosi);
00442 if( scal < 0.1 ) scal = 0.1;
00443 step /= scal;
00444 }
00445 chisq2 = chisqc;
00446 eps0 = epsc;
00447 dx0 = dxc;
00448 dy0 = dyc;
00449 gre = grec;
00450 grx = grxc;
00451 gry = gryc;
00452 gr = grc;
00453 }
00454 epsc = eps0 - step*gre/gr;
00455 while( EmcCluster::ABS(epsc) >= epsmax ) {
00456 step /= 2;
00457 epsc = eps0 - step*gre/gr;
00458 }
00459 dxc = dx0 - step*grx/gr;
00460 dyc = dy0 - step*gry/gr;
00461 if( step*gr < stpmin ) break;
00462 }
00463 if( (*pchi)*nh-chisq2 < delch ) return;
00464 dof = nh;
00465 if( dof < 1 ) dof = 1;
00466 *pchi = chisq2/dof;
00467 c3to5(e0,x0,y0,eps0,dx0,dy0,pe1,px1,py1,pe2,px2,py2);
00468
00469 }
00470
00471
00472
00473 float EmcScSectorRec::ClusterChisq(int nh, EmcModule* phit, float e, float x,
00474 float y, int &ndf)
00475 {
00476
00477 float chi=0;
00478 int ixy, ix, iy;
00479 float et, a, d;
00480
00481 for( int in=0; in<nh; in++ ) {
00482 ixy = phit[in].ich;
00483 iy = ixy/fNx;
00484 ix = ixy - iy*fNx;
00485 et = phit[in].amp;
00486 a = PredictEnergy(x-ix, y-iy, -1);
00487 d = fgEpar00*fgEpar00 + e*(fgEpar1*a + fgEpar2*a*a + fgEpar3*a*a*a) +
00488 e*sqrt(e)*fgEpar4*a*(1-a)*fSin4T + e*e*fgEpar0*fgEpar0;
00489 a *= e;
00490 chi += (et-a)*(et-a)/d;
00491 }
00492
00493 ndf=nh;
00494 return chi;
00495
00496 }
00497
00498
00499
00500
00501 float EmcScSectorRec::Chi2Limit(int ND)
00502 {
00503
00504
00505 float rn, a, b, chi2;
00506
00507 if( ND < 1 ) return 9999.;
00508
00509 chi2 = fgChi2Level[EmcCluster::min(ND,50)-1];
00510 if( chi2 > 100 ) return 9999.;
00511
00512 rn = ND;
00513 b = 0.072*sqrt(rn);
00514 a = 6.21/(sqrt(rn)+4.7);
00515
00516 return chi2*a/(1.-chi2*b);
00517
00518 }
00519
00520
00521
00522 float EmcScSectorRec::Chi2Correct(float Chi2, int ND)
00523 {
00524
00525
00526
00527
00528 float rn, a, b, c;
00529
00530 if( ND < 1 ) return 9999.;
00531
00532 rn = ND;
00533 b = 0.072*sqrt(rn);
00534 a = 6.21/(sqrt(rn)+4.7);
00535 c = a + b*Chi2;
00536 if( c < 1 ) c=1;
00537
00538 return Chi2/c;
00539
00540 }
00541
00542
00543
00544 void EmcScSectorRec::SetTowerThreshold(float Thresh)
00545 {
00546 fgTowerThresh = Thresh;
00547 fgEpar0 = Thresh*0.07;
00548 fgEpar00 = EmcCluster::max( (double)Thresh/3, 0.005 );
00549 }
00550
00551
00552
00553 void EmcScSectorRec::getTowerPos(int ix, int iy, float &x, float & y){
00554 x = 2.859+5.562*ix+int(ix/12)*0.256;
00555 y = 2.859+5.562*iy+int(iy/12)*0.156;
00556 }
00557
00558
00559
00560
00562 void EmcScSectorRec::TowersToSector(float xT, float yT, float & xS, float & yS){
00563 int x = int(xT);
00564 float dx = xT - x;
00565 int y = int(yT);
00566 float dy = yT - y;
00567 xS = fModSizex*(x+0.5) + int(xT/12)*0.256 + fModSizex*dx;
00568 yS = fModSizey*(y+0.5) + int(yT/12)*0.156 + fModSizey*dy;
00569 }
00570
00571
00573 void EmcScSectorRec::TowersToSector(int xT, int yT, float & xS, float & yS){
00574 xS = fModSizex*(xT+0.5) + int(xT/12)*0.256;
00575 yS = fModSizey*(yT+0.5) + int(yT/12)*0.156;
00576 }
00577
00578
00580 void EmcScSectorRec::SectorToTowers(float xS, float yS, int & xT, int & yT){
00581
00582 xT = int(((xS-int(xS/67.0)*67.0)-0.078)/fModSizex) + 12*int(xS/67.0);
00583 yT = int(((yS-int(yS/66.9)*66.9)-0.078)/fModSizey) + 12*int(yS/66.9);
00584
00585 }
00586
00587