mEmcGeometryModule.C

Go to the documentation of this file.
00001 
00002 // EMC Geometry class.
00003 // Alexander Bazilevsky Sep-00
00004 // modifications by Julia Velkovska Jan 2002
00005 // -read geometry from DB 
00006 // -allow transformations
00007 // -added PHPanels as data members for cgl to use 
00008 
00009 #include <iostream>
00010 #include <cstdio>
00011 #include <ctype.h>
00012 #include <cstring>
00013 #include <cmath>
00014 #include <cstdlib>
00015 #include <cassert>
00016 #include "gsl/gsl_math.h"
00017 #include "mEmcGeometryModule.h"
00018 #include "emcGeometry.h"
00019 #include "emcDataManager.h"
00020 #include "KinPISAHit.h"
00021 #include "emcDBMS.h"
00022 //#include "EmcIndexer.h"
00023 
00024 #define ABSURD -999999.
00025 
00026 ClassImp(mEmcGeometryModule)
00027 
00028 using namespace PHGeometry;
00029 
00030 mEmcGeometryModule::mEmcGeometryModule(mEmcGeometryModule::ERealm type)
00031 {
00032   if ( type == kReal )
00033     {
00034       BuildGeometry(); 
00035     }
00036   else if ( type == kPISA ) 
00037     {
00038       BuildGeometryPISA();
00039     }
00040   else
00041     {
00042       assert(0==1);
00043     }
00044   BuildPanels();
00045 }
00046 
00047 void 
00048 mEmcGeometryModule::BuildGeometryPISA()
00049 {
00050   float deg = M_PI/180.0;
00051   // Sector dimensions
00052   int NxSc = 72;
00053   int NySc = 36;
00054   int NxGl = 96;
00055   int NyGl = 48;
00056   // Tower Size (cm)
00057   float TowerXSizeSc = 5.542;
00058   float TowerYSizeSc = 5.542;
00059   float TowerXSizeGl = 4.1040;
00060   float TowerYSizeGl = 4.1105;
00061 
00062   // Rotation angles (deg)
00063   float emcRA[8][2] =      
00064     {                   // SECTOR  ARM(*)   ARM(**)  SECTOR(*)=(**)  iS(***)  iS(****)
00065       {0.0,    22.632}, //  W0       1        0         0             0        0
00066       {0.0,     0.0},   //  W1       1        0         1             1        1
00067       {0.0,   -22.632}, //  W2       1        0         2             2        2
00068       {0.0,   -45.264}, //  W3       1        0         3             3        3
00069       
00070       {0.0,   -45.264}, //  E3       0        1         3             4        5
00071       {0.0,   -22.632}, //  E2       0        1         2             5        4
00072       {0.0,     0.0},   //  E1       0        1         1             6        7
00073       {0.0,    22.0}    //  E0       0        1         0             7        6
00074     };
00075   // (*) = PHENIX convention
00076   // (**) = EMC Offline convention (e.g. getters/setters of dEmcCalibTower or dEmcClusterLocal)
00077   // (***) = EMC mEmcGeometryModule convention (this module)
00078   // (****) = EMC Online convention
00079 
00080   // X position
00081   float emcX[8] = { 510.0,  510.0,  510.0,  510.0, 
00082                     510.0,  510.0,  543.2,  543.2 };
00083 
00084   PHVector perm(3, 1, 2);
00085 
00086   // loop over EMCal Sectors
00087   for (int iS = 0; iS<8; iS++){
00088     float sign = ((iS>=4)? -1. : 1.);
00089     nx[iS] = ( (iS<6) ? NxSc : NxGl );
00090     ny[iS] = ( (iS<6) ? NySc : NyGl );
00091     tower_xsize[iS] = ( (iS<6) ? TowerXSizeSc : TowerXSizeGl );
00092     tower_ysize[iS] = ( (iS<6) ? TowerYSizeSc : TowerYSizeGl );
00093     // Create rotation matrix
00094     PHMatrix mm( perm, 0., emcRA[iS][1]*deg, (emcRA[iS][0]+90.*sign)*deg );
00095     emcrm[iS] = mm;
00096     float z0 = (nx[iS]-1.)/2. * tower_xsize[iS] * sign;
00097     float y0 = -emcX[iS]*sinf(emcRA[iS][1]*deg) - 
00098       (ny[iS]-1.)/2. * tower_ysize[iS] * cosf(emcRA[iS][1]*deg);
00099     float x0 =  emcX[iS]*cosf(emcRA[iS][1]*deg) - 
00100       (ny[iS]-1.)/2. * tower_ysize[iS] * sinf(emcRA[iS][1]*deg);
00101     x0 *= sign;
00102     PHVector vv0(x0, y0, z0);
00103     emctr[iS] = vv0;
00104   }
00105 
00106   for( int is=0; is<MAX_SECTORS; is++ ) {
00107     PHFrame local;
00108     PHFrame global = MatrixAndVector2frames(local,emcrm[is],emctr[is]);
00109      frames2MatrixAndVector(global,local,invemcrm[is],invemctr[is]);
00110   }
00111 
00112   printf("<I> mEmcGeometryModule: PISA Geometry Initialized\n");
00113 
00114 }
00115 
00116 void 
00117 mEmcGeometryModule::printSectorNumberingConventions()
00118 {
00119 
00120   const char *name[] = {"W0","W1","W2","W3","E3","E2","E1","E0"};
00121   const char *type[] = {"PbSc","PbSc","PbSc","PbSc","PbSc","PbSc","PbGl","PbGl"};
00122 
00123   std::cout << "<I> mEmcGeometryModule::printSectorNumberingConventions() : " << std::endl;
00124   std::cout << "Sector   Type   (arm,sector)[PHENIX]   (arm,sector)[EMC-offline]   " 
00125             << "(sector)[EMC-online]   (sector)[EMC-mEmcGeometryModule] " << std::endl;
00126 
00127   short arm,sector;
00128 
00129   for( int is=0; is<MAX_SECTORS; is++ ) 
00130     {
00131       emcToPhenix(is,arm,sector);
00132       std::cout << "  " << name[is] << "      " << type[is] << "  ( " ;
00133       std::cout << arm << " ,   " << sector << "  ) " ;
00134       std::cout << "          ( " << 1-arm << " ,   " << sector << "  )" ;
00135       std::cout << "                    " << emcToEmcOnline(is);
00136       std::cout << "                      " << is << std::endl;
00137     }
00138 }
00139 
00140 void 
00141 mEmcGeometryModule::BuildGeometry()
00142 {
00143   readFromDB();
00144 
00145   // loop over EMCal Sectors
00146   for (int iS = 0; iS<MAX_SECTORS; iS++){
00147     // create the inverse matrices and vectors after reading from DB 
00148     // this is just to make sure that the inverse corresponds to the direct,
00149     // since it is possible to write into DB just one or the other
00150     PHFrame local;
00151     PHFrame global= MatrixAndVector2frames(local,emcrm[iS],emctr[iS]);
00152     frames2MatrixAndVector(global,local,invemcrm[iS],invemctr[iS]);
00153   }
00154 
00155 }
00156 
00157 void mEmcGeometryModule::readFromDB()
00158 {
00159   // create a data manager
00160   emcGeometry geom;
00161   emcDataManager *dm = emcDataManager::GetInstance();
00162 
00163   geom.SetSource(emcDBMS::get());
00164 
00165   PHTimeStamp now;
00166   bool ok = dm->Read(geom,now,1);
00167   if(!ok){
00168     BuildGeometryPISA();
00169   }
00170   else{
00171     assert(MAX_SECTORS==geom.NumberOfSectors());
00172     for(int is = 0; is <MAX_SECTORS; is ++){
00173       emcrm[is] = geom.Sector(is).RotationMatrix();
00174       emctr[is] = geom.Sector(is).TranslationVector();
00175       nx[is] = geom.Sector(is).nx();
00176       ny[is] = geom.Sector(is).ny();
00177       tower_xsize[is] = geom.Sector(is).Tower_xSize(); 
00178       tower_ysize[is] = geom.Sector(is).Tower_ySize(); 
00179     }
00180     printf("<I> mEmcGeometryModule: REAL Geometry Initialized\n");
00181   }
00182 }
00183 
00184 void 
00185 mEmcGeometryModule::Retract()
00186 {
00187   float west[]={+41,0,0};
00188   float east[]={-44,0,0};
00189   Retract( east, west );
00190 }
00191 
00192 void 
00193 mEmcGeometryModule::Retract( float* east, float* west )
00194 {
00195     int is;
00196     PHVector vv;
00197 
00198     PHVector veast(east[0], east[1], east[2]);
00199     PHVector vwest(west[0], west[1], west[2]);
00200     for( is=0; is<4; is++ ) {
00201       vv = emctr[is]+vwest;
00202       emctr[is] = vv;
00203     }
00204     for( is=4; is<8; is++ ) {
00205       vv = emctr[is]+veast;
00206       emctr[is] = vv;
00207     }
00208     printf("<I> mEmcGeometryModule::Retract: retracted geometry east=(%f,%f,%f) west=(%f,%f,%f)\n",
00209            east[0],east[1],east[2],west[0],west[1],west[2]);
00210 }
00211 
00212 void 
00213 mEmcGeometryModule::print()
00214 {
00215   printf("\nmEmcGeometryModule::print: Sector geometry\n\n");
00216   for (int is=0; is<8; is++ ) 
00217     {
00218       printf("Sec %d (Nx,Ny) = (%d,%d)\n",is,nx[is],ny[is]);
00219       printf("  Tower Size = (%f,%f)\n",tower_xsize[is],tower_ysize[is]);
00220       printf("  Zero Tower Pos = (%f,%f,%f)\n\n",
00221              emctr[is].getX(),
00222              emctr[is].getY(),
00223              emctr[is].getZ());
00224     }
00225 }
00226 
00227 void 
00228 mEmcGeometryModule::printCorners()
00229 {
00230   float xl, yl, zl;
00231   float xg, yg, zg;
00232   printf("\nmEmcGeometryModule::printCorners: Sector corner towers\n\n");
00233   for (int is=0; is<8; is++ ) 
00234     {
00235       printf("Sec %d\n",is);
00236       xl = 0 - tower_xsize[is]/2.;
00237       yl = 0 - tower_ysize[is]/2.;
00238       zl = 0;
00239       LocalToGlobal( is, xl, yl, zl, xg, yg, zg);
00240       printf("  (%7.2f,%7.2f,%7.2f)", xg, yg, zg);
00241       xl = 0 + (nx[is]-0.5)*tower_xsize[is];
00242       yl = 0 - tower_ysize[is]/2.;
00243       zl = 0;
00244       LocalToGlobal( is, xl, yl, zl, xg, yg, zg);
00245       printf("  (%7.2f,%7.2f,%7.2f)", xg, yg, zg);
00246       xl = 0 - tower_xsize[is]/2.;
00247       yl = 0 + (ny[is]-0.5)*tower_ysize[is];
00248       zl = 0;
00249       LocalToGlobal( is, xl, yl, zl, xg, yg, zg);
00250       printf("  (%7.2f,%7.2f,%7.2f)\n\n", xg, yg, zg);
00251       xl = 0 + (nx[is]-0.5)*tower_xsize[is];
00252       yl = 0 + (ny[is]-0.5)*tower_ysize[is];
00253       zl = 0;
00254       LocalToGlobal( is, xl, yl, zl, xg, yg, zg);
00255       printf("  (%7.2f,%7.2f,%7.2f)\n\n", xg, yg, zg);
00256 
00257     }
00258 }
00259 
00261 
00262 void 
00263 mEmcGeometryModule::SetSectorDim( int is, int nX, int nY )
00264 {
00265   if (is<0 || is >= MAX_SECTORS) 
00266     { 
00267       printf("!!! mEmcGeometry::SetSectorDim: Wrong sector index: %d\n",is);
00268       return;
00269     }
00270   nx[is] = nX;
00271   ny[is] = nY;
00272 }
00273 
00274 void 
00275 mEmcGeometryModule::SetTowerSize( int is, float xsz, float ysz )
00276 {
00277   if (is<0 || is >= MAX_SECTORS) 
00278     { 
00279       printf("!!! mEmcGeometry::SetTowerSize: Wrong sector index: %d\n",is);
00280       return;
00281   }
00282   tower_xsize[is] = xsz;
00283   tower_ysize[is] = ysz;
00284 }
00285 
00286 void 
00287 mEmcGeometryModule::SetMatrixVector( int is, PHMatrix mx, PHVector vt )
00288 {
00289   if (is<0 || is >= MAX_SECTORS) 
00290     { 
00291       printf("!!! mEmcGeometry::SetMatrixVector: Wrong sector index: %d\n",is);
00292       return;
00293     }
00294   emcrm[is] = mx;
00295   emctr[is] = vt;
00296   // we also need to set the inverse transformation and the panel geo
00297   PHFrame local;
00298   PHFrame global = MatrixAndVector2frames(local,emcrm[is],emctr[is]);
00299   frames2MatrixAndVector(global,local,invemcrm[is],invemctr[is]);
00300   short arm,sector;
00301   emcToPhenix(is,arm,sector);
00302   std::cout << " mEmcGeometryModule::SetMatrixVector -> Transformed Panels " << std::endl;
00303   BuildPanels();
00304 }
00305 
00306 void 
00307 mEmcGeometryModule::GetSectorDim( int is, int &nX, int &nY )
00308 {
00309   if (is < 0 || is >= MAX_SECTORS) 
00310     { 
00311       printf("!!! mEmcGeometry::GetSectorDim: Wrong sector index: %d\n",is);
00312       nX = 0;
00313       nY = 0;
00314       return;
00315     }
00316   nX = nx[is];
00317   nY = ny[is];
00318 }
00319 
00320 void 
00321 mEmcGeometryModule::GetTowerSize( int is, float &xsz, float &ysz )
00322 {
00323   if (is < 0 || is >= MAX_SECTORS) 
00324     { 
00325     printf("!!! mEmcGeometry::GetTowerSize: Wrong sector index: %d\n",is);
00326     xsz = 0;
00327     ysz = 0;
00328     return;
00329   }
00330   xsz = tower_xsize[is];
00331   ysz = tower_ysize[is];
00332 }
00333 
00334 void 
00335 mEmcGeometryModule::GetMatrixVector (int is, PHMatrix &mx, PHVector &vt)
00336 {
00337   if (is < 0 || is >= MAX_SECTORS) 
00338     { 
00339       printf("!!! mEmcGeometry::GetMatrixVector: Wrong sector index: %d\n",is);
00340       return;
00341     }
00342   mx = emcrm[is];
00343   vt = emctr[is];
00344 }
00345 
00346 int
00347 mEmcGeometryModule::GetTowerPosLocal (int is, int ind, 
00348                                       float &x, float &y, float &z)
00349   // Calculates tower position in Sector frame,
00350   // is - sector index (0-7)
00351   // ind - tower index (ix+iy*nx, ix=0,... ; iy=0,... )
00352 {
00353   x = ABSURD;
00354   y = ABSURD;
00355   z = ABSURD;
00356   if (is<0 || is >= MAX_SECTORS)  
00357     { 
00358       printf("mEmcGeometry::GetTowerPosLocal: Wrong sector index: %d\n",is);
00359       return 0;
00360     }
00361   z = 0;
00362   int ix = ind%nx[is];
00363   int iy = ind/nx[is];
00364   if (iy >= ny[is]) 
00365     {
00366       printf("mEmcGeometry::GetTowerPosLocal: Wrong tower index for sector %d: %d\n",is,ind);
00367       //return 0; // fixme: why not return 0 ?
00368     }
00369   x = tower_xsize[is] * ix;
00370   y = tower_ysize[is] * iy;
00371   return 1;
00372 }
00373 
00374 int
00375 mEmcGeometryModule::GetTowerPosLocal (int is, int ix, int iy, 
00376                                       float &x, float &y, float &z)
00377   // Calculates tower position in Sector frame,
00378   // is - sector index (0-7)
00379   // ix - x tower index (column number starting from the bottom right, front view)
00380   // iy - y tower index (row number starting from the bottom)
00381 {
00382   x = ABSURD;
00383   y = ABSURD;
00384   z = ABSURD;
00385   if (is<0 || is >= MAX_SECTORS)  
00386     { 
00387       printf("mEmcGeometry::GetTowerPosLocal: Wrong sector index: %d\n",is);
00388       return 0;
00389     }
00390   z = 0;
00391   if (iy >= ny[is]) 
00392     {
00393       printf("mEmcGeometry::GetTowerPosLocal: Wrong tower index (%d,%d) for sector %d\n",ix,iy,is);
00394       //return 0; // fixme: why not return 0 ?
00395     }
00396   x = tower_xsize[is] * ix;
00397   y = tower_ysize[is] * iy;
00398   return 1;
00399 }
00400 
00401 int 
00402 mEmcGeometryModule::GetTowerPosGlobal (int is, int ind, 
00403                                        float &x, float &y, float &z)
00404   // Calculates tower position in Sector frame,
00405   // is - sector index (0-7)
00406   // ind - tower index (ix+iy*nx, ix=0,... ; iy=0,... )
00407 {
00408   float xl, yl, zl;
00409   int st = GetTowerPosLocal( is, ind, xl, yl, zl );
00410   if( !st ) 
00411     { 
00412       x = ABSURD;
00413       y = ABSURD;
00414       z = ABSURD;
00415       return 0;
00416     }
00417 
00418   PHPoint emcHit(xl, yl, zl);
00419   PHPoint phnxHit  =  transformPoint(emcrm[is], emctr[is], emcHit);
00420   x =  phnxHit.getX();
00421   y =  phnxHit.getY();
00422   z =  phnxHit.getZ();
00423   return 1;
00424 }
00425 
00426 int 
00427 mEmcGeometryModule::GetTowerPosGlobal (int is, int ix, int iy, 
00428                                        float &x, float &y, float &z)
00429   // Calculates tower position in Sector frame,
00430   // is - sector index (0-7)
00431   // ix - x tower index
00432   // iy - y tower index
00433 {
00434   float xl, yl, zl;
00435   int st = GetTowerPosLocal( is, ix, iy, xl, yl, zl );
00436   if( !st ) 
00437     { 
00438       x = ABSURD;
00439       y = ABSURD;
00440       z = ABSURD;
00441       return 0;
00442     }
00443 
00444   PHPoint emcHit(xl, yl, zl);
00445   PHPoint phnxHit  =  transformPoint(emcrm[is], emctr[is], emcHit);
00446   x =  phnxHit.getX();
00447   y =  phnxHit.getY();
00448   z =  phnxHit.getZ();
00449   return 1;
00450 }
00451 
00452 double
00453 mEmcGeometryModule::GetSectorCenterInGlobalCoords( int is, int xyz )
00454 {
00455   assert(is>=0 && is<8);
00456   assert(xyz>=0 && xyz <3);
00457  
00458   short arm, sector;
00459   emcToPhenix(is,arm,sector);
00460 
00461   PHPanel panel = GetPanel(arm,sector);
00462 
00463   PHPoint center = panel.getCenter();
00464 
00465   double coord = 0;
00466 
00467   switch ( xyz )
00468     {
00469     case 0:
00470       coord = center.getX();
00471       break;
00472     case 1:
00473       coord = center.getY();
00474       break;
00475     case 2:
00476       coord = center.getZ();
00477       break;
00478     default:
00479       std::cerr << PHWHERE << " Improper xyz=" << xyz << " Expecting 0 (x),"
00480                 << " 1 (y) or 2 (z). Aborting."
00481                 << std::endl;
00482       exit(1);
00483     }
00484 
00485   return coord;
00486 }
00487 
00488 void 
00489 mEmcGeometryModule::LocalToGlobal (int is,
00490                                    float xl, float yl, float zl, 
00491                                    float &xg, float &yg, float &zg)
00492 {
00493   if (is < 0 || is >= MAX_SECTORS ) 
00494     { 
00495       printf("!!! mEmcGeometry::LocalToGlobal: Wrong sector index: %d\n",is);
00496       return;
00497     }
00498   PHPoint emcHit(xl, yl, zl);
00499   PHPoint phnxHit  =  transformPoint(emcrm[is], emctr[is], emcHit);
00500   xg =  phnxHit.getX();
00501   yg =  phnxHit.getY();
00502   zg =  phnxHit.getZ();
00503 }
00504 
00505 void 
00506 mEmcGeometryModule::GlobalToLocal (float xg, float yg, float zg, 
00507                                    int is, 
00508                                    float &xl, float &yl, float &zl)
00509 {
00510   if (is<0 || is >= MAX_SECTORS ) 
00511     { 
00512       printf("!!! mEmcGeometry::GlobalToLocal: Wrong sector index: %d\n",is);
00513       return;
00514     }
00515   PHPoint phnxHit(xg, yg, zg);
00516   PHPoint emcHit  = 
00517     transformPoint(invemcrm[is], invemctr[is], phnxHit);
00518   xl =  emcHit.getX();
00519   yl =  emcHit.getY();
00520   zl =  emcHit.getZ();
00521 }
00522 
00524 PHPanel mEmcGeometryModule::GetPanel(short arm, short sector)
00525 {
00526   PHPanel out;
00527   out = emcSectors[arm][sector];
00528   return out;
00529 }  
00530 
00531 //_____________________________________________________________________________
00532 void mEmcGeometryModule::emcToPhenix(int is,short &arm,short &sector)
00533 {
00534   if( is < 4 ) { // WEST!!
00535     arm = 1;
00536     sector = is;
00537   }
00538   else { // EAST
00539     arm =0; 
00540     sector = 7-is;
00541   }
00542 }
00543 
00544 //_____________________________________________________________________________
00545 int
00546 mEmcGeometryModule::emcToEmcOnline(int is)
00547 {
00548   assert(is>=0 && is<8);
00549 
00550   int iso=-1;
00551 
00552   if ( is < 4 )
00553     {
00554       iso=is;
00555     }
00556   else
00557     {
00558       if ( is==4 ) iso= 5;
00559       if ( is==5 ) iso= 4;
00560       if ( is==6 ) iso= 7;
00561       if ( is==7 ) iso= 6; 
00562     }
00563   return iso;
00564 }
00565 
00566 //_____________________________________________________________________________
00567 int
00568 mEmcGeometryModule::emcOfflineToEmc(short arm, short sector)
00569 {
00570   assert(arm>=0 && arm<=1 && sector>=0 && sector<=3);
00571   return PhenixToEmc(1-arm,sector);
00572 }
00573 
00574 //_____________________________________________________________________________
00575 int
00576 mEmcGeometryModule::emcOfflineToEmcOnline(short arm, short sector)
00577 {
00578   assert(arm>=0 && arm<=1 && sector>=0 && sector<=3);
00579   return emcToEmcOnline(emcOfflineToEmc(arm,sector));
00580 }
00581 
00582 //_____________________________________________________________________________
00583 int
00584 mEmcGeometryModule::emcOnlineToEmc(int is)
00585 {
00586   return emcToEmcOnline(is);
00587 }
00588 
00589 //_____________________________________________________________________________
00590 int 
00591 mEmcGeometryModule::PhenixToEmc(short arm, short sector)
00592 {
00593   assert(arm>=0 && arm<=1 && sector>=0 && sector<=3);
00594 
00595   int iS=-1;
00596 
00597   if ( arm == 1 ) 
00598     {
00599       // WEST ARM
00600       iS = sector;
00601     }
00602   else if ( arm == 0 )
00603     {
00604       // EAST ARM
00605       iS = 7 - sector;
00606     }
00607   return iS;
00608 }
00609 
00610 void 
00611 mEmcGeometryModule::BuildPanels()
00612 {
00613   // West arm
00614 
00615   short arm,sec;
00616   float xl, yl, zl;
00617   float xg, yg, zg;
00618   PHPoint p0,p1,p2;
00619 
00620   zl = 0;
00621   for (int is=0; is<8; is++ ) 
00622     {
00623       emcToPhenix(is,arm,sec);
00624       // West
00625       if(arm ==1){
00626         xl = 0 + (nx[is]-0.5)*tower_xsize[is];
00627         yl = 0 - tower_ysize[is]/2.;
00628         LocalToGlobal( is, xl, yl, zl, xg, yg, zg);
00629         p0.setX(xg);
00630         p0.setY(yg);
00631         p0.setZ(zg);
00632 
00633         xl = 0 + (nx[is]-0.5)*tower_xsize[is];
00634         yl = 0 + (ny[is]-0.5)*tower_ysize[is];
00635         LocalToGlobal( is, xl, yl, zl, xg, yg, zg);
00636         p1.setX(xg);
00637         p1.setY(yg);
00638         p1.setZ(zg);
00639 
00640         xl = 0 - tower_xsize[is]/2.;
00641         yl = 0 - tower_ysize[is]/2.;
00642         LocalToGlobal( is, xl, yl, zl, xg, yg, zg);
00643         p2.setX(xg);
00644         p2.setY(yg);
00645         p2.setZ(zg);
00646 
00647         PHPanel temp(p0,p1,p2);
00648         emcSectors[arm][sec]=temp;
00649       }
00650       else {
00651         // EAST
00652         xl = 0 - tower_xsize[is]/2.;
00653         yl = 0 + (ny[is]-0.5)*tower_ysize[is];
00654         LocalToGlobal( is, xl, yl, zl, xg, yg, zg);
00655         p0.setX(xg);
00656         p0.setY(yg);
00657         p0.setZ(zg);
00658 
00659         xl = 0 - tower_xsize[is]/2.;
00660         yl = 0 - tower_ysize[is]/2.;
00661         LocalToGlobal( is, xl, yl, zl, xg, yg, zg);
00662         p1.setX(xg);
00663         p1.setY(yg);
00664         p1.setZ(zg);
00665 
00666         xl = 0 + (nx[is]-0.5)*tower_xsize[is];
00667         yl = 0 + (ny[is]-0.5)*tower_ysize[is];
00668         LocalToGlobal( is, xl, yl, zl, xg, yg, zg);
00669         p2.setX(xg);
00670         p2.setY(yg);
00671         p2.setZ(zg);
00672 
00673         PHPanel temp(p0,p1,p2);
00674         emcSectors[arm][sec]=temp;
00675 
00676       }
00677       //emcSectors[arm][sec].print();
00678     }
00679 }
00680 
00681 PHBoolean
00682 mEmcGeometryModule::isIntersection(PHLine &line,const short& is){
00683 
00684   PHPoint proj;
00685   return Intersection(line,is,proj);
00686 
00687 }
00688 
00689 PHBoolean
00690 mEmcGeometryModule::Intersection(PHLine &line,const short& is,PHPoint &proj){
00691 
00692   // CKB 
00693   // routine to decide wether a given PHLine
00694   // intersects with sector is (in EMC-mEmcGeometryModule convention)
00695   //        / 3   \  4
00696   // West  |  2    | 5 East
00697   //       |  1    | 6 
00698   //        \ 0   /  7
00699 
00700   short arm,sec;
00701 
00702   emcToPhenix(is,arm,sec);
00703 
00704   PHBoolean projectionFound = false;
00705 
00706 
00707   projectionFound = intersectionLinePanel(line,emcSectors[arm][sec],proj);
00708  
00709   return projectionFound;
00710 
00711 }
00712 
00713 //_____________________________________________________________________________
00714 //
00715 // If the particle of momentum p and vertex v heads into EMCal
00716 // return the sector number (iS = 0-7). Otherwise return -1.
00717 int
00718 mEmcGeometryModule::HitInEMCalAcceptance(const float *v, const float *p)
00719 {
00720 
00721   // Separate the "Directions" of the track
00722   // p[0] < 0 is East, p[0] > 0 is West  
00723   // This is important because a line has no starting point
00724   // like a track
00725 
00726   // this is a real Point
00727   PHPoint vtx(v[0],v[1],v[2]);
00728 
00729   // take care that p gives only the direction of the momentum vector
00730   PHVector hit(p[0],p[1],p[2]);
00731   PHLine line(vtx,hit);
00732 
00733   int is;
00734 
00735   // isIntersection routine tells you wether a given PHLine
00736   // intersects with sector is (in EMC-mEmcGeometryModule convention)
00737   //        / 3   \  4
00738   // West  |  2    | 5 East
00739   //       |  1    | 6 
00740   //        \ 0   /  7
00741 
00742   if(p[0]>0){
00743     for( is = 0; is<4; is++ ){ // loop over the west arm
00744       if(isIntersection(line,is)) return is;
00745     }
00746   }
00747   else if(p[0]<0){
00748     for( is = 4 ; is<8 ; is++ ){ // loop over the east arm
00749       if(isIntersection(line,is)) return is;
00750     }
00751   }
00752   
00753   return -1;
00754  
00755 }
00756 
00757 //_____________________________________________________________________________
00758 //
00759 // If the single direct gamma or the 2 decay-gammas from a pi0/eta decay
00760 // head into EMCal return 1. Otherwise, return 0.
00761 int 
00762 mEmcGeometryModule::EventInEMCalAcceptance(const PISAEvent *pisaEvent, 
00763                                            const int kevent, TTree *T)
00764 {
00765  
00766   T->GetEvent(kevent);
00767   int kpart = pisaEvent->GetKinNhit();
00768  
00769   float ptot;
00770   float pthet;
00771   float pphi;
00772 
00773   float p[3];
00774   float v[3];
00775 
00776   int GEANT_gamma_code = 1;
00777   int GEANT_pi0_code = 7;
00778   int GEANT_eta_code = 17;
00779 
00780   // loop on pisaEvent
00781   for( int ipart = 0; ipart<kpart; ipart++)
00782     {
00783       TClonesArray *fpisaKinHits = pisaEvent->GetKinHits();
00784       KinPISAHit *KinHit = (KinPISAHit*)fpisaKinHits->UncheckedAt(ipart);
00785       
00786       int idpart  = KinHit->GetIdpart();
00787       int idparent = KinHit->GetIdparent();
00788       int itparent = KinHit->GetItparent();
00789       
00790       int nGamma = 0;
00791       int nGamAcc = 0;
00792 
00793       // Found a primary photon
00794       if( idparent==0 && idpart==GEANT_gamma_code && itparent < 0 )
00795         {
00796           //std::cout << " <I> checking forced acceptance for gamma ..." << std::endl;
00797           v[0] = 0; // Pi0 decays instantly
00798           v[1] = 0;
00799           v[2] = KinHit->GetZvertex();
00800           
00801           ptot = KinHit->GetPtot() ;
00802           pphi = KinHit->GetPhi() * TMath::Pi()/180.;
00803           pthet = KinHit->GetPthet() * TMath::Pi()/180.;
00804           
00805           p[0] = ptot * sin (pthet) * cos (pphi);
00806           p[1] = ptot * sin (pthet) * sin (pphi);
00807           p[2] = ptot * cos (pthet);
00808       
00809           if (HitInEMCalAcceptance(v,p)>=0) nGamAcc++; // 0 is a valid sector: W0 !
00810           if ( nGamAcc!=1 ) return 0; // gamma not on detector
00811 
00812           //std::cout << " <I> gamma in EMCal acceptance ..." << std::endl;
00813           return 1;
00814 
00815         } // photon
00816       
00817       // Found a primary pion
00818       // We accept only Two-Photon Decays where
00819       // both can hit the detector
00820       if( idparent==0 && idpart==GEANT_pi0_code && itparent < 0 )
00821         {
00822           //std::cout << " <I> checking forced acceptance for pi0 ..." << std::endl;
00823           if(kpart<3) // at least one decay photon not even stored 
00824             { 
00825               return 0;  // ==> no hit on active surface so skip it
00826             }
00827  
00828           for(int i = 0;i < kpart;i++)
00829             {
00830               // Search for Decay gammas
00831               KinPISAHit *Hit = (KinPISAHit*)fpisaKinHits->UncheckedAt(i);
00832               if( Hit->GetIdparent () == GEANT_pi0_code && 
00833                   Hit->GetIdpart () == GEANT_gamma_code )
00834                 {
00835                   if(nGamma<2)
00836                     {
00837                       // std::cout << "Photon Nr " << nGamma << std::endl;
00838                       v[0] = 0; // Pi0 decays instantly
00839                       v[1] = 0;
00840                       v[2] = Hit->GetZvertex();
00841              
00842                       ptot = Hit->GetPtot() ;
00843                       pphi = Hit->GetPhi() * TMath::Pi()/180.;
00844                       pthet = Hit->GetPthet() * TMath::Pi()/180.;
00845                       
00846                       p[0] = ptot * sin (pthet) * cos (pphi);
00847                       p[1] = ptot * sin (pthet) * sin (pphi);
00848                       p[2] = ptot * cos (pthet);
00849                       
00850                       if (HitInEMCalAcceptance(v,p)>=0) nGamAcc++; // 0 is a valid sector: W0 !
00851                     }
00852                   nGamma++;         
00853                 }
00854             }
00855      
00856           if( nGamma!=2 ) { return 0; } // Not a 2-gamma Decay !
00857           if( nGamAcc!=2 ){ return 0; } // Not both gammas on Detector 
00858 
00859           //std::cout << " <I> pi0 in EMCal acceptance ..." << std::endl;
00860           return 1;
00861           
00862         } // pi0
00863   
00864       // Found a primary eta
00865       // We accept only Two-Photon Decays where
00866       // both head to the detector
00867       if( idparent==0 && idpart==GEANT_eta_code && itparent < 0)
00868         {
00869           //std::cout << " <I> checking forced acceptance for eta ..." << std::endl;
00870           if(kpart<3) // at  least one decay photon not even stored 
00871             {
00872               return 0;  // ==> no hit on active surface so skip it
00873             }
00874       
00875           for(int i = 0;i < kpart;i++)
00876             {
00877               // Search for Decay gammas
00878               KinPISAHit *Hit = (KinPISAHit*)fpisaKinHits->UncheckedAt(i);
00879               if( Hit->GetIdparent () == GEANT_eta_code && 
00880                   Hit->GetIdpart () == GEANT_gamma_code )
00881                 {
00882                   if(nGamma<2)
00883                     {
00884                       //std::cout << "Photon Nr " << nGamma << std::endl;
00885                       v[0] = 0; // eta decays instantly
00886                       v[1] = 0;
00887                       v[2] = Hit->GetZvertex();
00888                       
00889                       ptot = Hit->GetPtot() ;
00890                       pphi = Hit->GetPhi() * TMath::Pi()/180.;
00891                       pthet = Hit->GetPthet() * TMath::Pi()/180.;
00892                       
00893                       p[0] = ptot * sin (pthet) * cos (pphi);
00894                       p[1] = ptot * sin (pthet) * sin (pphi);
00895                       p[2] = ptot * cos (pthet);
00896                       
00897                       if (HitInEMCalAcceptance(v,p)>=0) nGamAcc++; // 0 is a valid sector: W0 !
00898                     }
00899                   nGamma++;                 
00900                 } 
00901             }
00902 
00903           if( nGamma!=2 )  { return 0; } // Not a 2-gamma Decay !
00904           if( nGamAcc!=2 ) { return 0; } // Not both gammas heading to the detector
00905           
00906           //std::cout << " <I> eta in EMCal acceptance ..." << std::endl;
00907           return 1;
00908 
00909         } // eta
00910 
00911     } // end loop on pisaEvent
00912 
00913   std::cout << "<W> EventInEMCalAcceptance: " 
00914             << "No primary gamma, pi0, eta found ... Event completely skipped !" << std::endl;
00915 
00916   return 0;
00917 }
00918 
00919 
00920 //_____________________________________________________________________________
00921 //
00922 // If the particle of momentum p and vertex v heads into PbSc
00923 // return true. Otherwise return false.
00924 bool
00925 mEmcGeometryModule::HitInPbSc(const float *v, const float *p, int& sector)
00926 {
00927 
00928   sector = HitInEMCalAcceptance(v,p);
00929 
00930   // PbSc sectors (in EMC-mEmcGeometryModule and EMC-Online conventions)
00931   if ( sector == 0 || sector == 1 || sector == 2 || sector == 3 || sector == 4 || sector == 5 ) 
00932     return true;
00933 
00934   return false; // case: -1 (outside EMCal) or 6,7 (PbGl)
00935 
00936 }
00937 
00938 //_____________________________________________________________________________
00939 //
00940 // If the particle of momentum p and vertex v heads into PbGl
00941 // return true. Otherwise return false.
00942 bool
00943 mEmcGeometryModule::HitInPbGl(const float *v, const float *p, int& sector)
00944 {
00945 
00946   sector = HitInEMCalAcceptance(v,p);
00947   if ( sector == 7 || sector == 6 ) return true; // PbGl sectors (in EMC-mEmcGeometryModule and EMC-Online conventions)
00948 
00949   return false; // case: -1 (outside EMCal) or 0-5 (PbSc)
00950 
00951 }