00001 #include "mEmcClusterizerv0.h"
00002
00003 #include <cstdio>
00004 #include <cmath>
00005 #include <cstdlib>
00006 #include <iostream>
00007 #include <cassert>
00008 #include <memory>
00009
00010 #include "PHNode.h"
00011 #include "PHCompositeNode.h"
00012 #include "PHIODataNode.h"
00013 #include "PHNodeIterator.h"
00014 #include "PHTable.hh"
00015
00016 #include "PHCompositeNode.h"
00017
00018 #include "EmcIndexer.h"
00019 #include "EmcCluster.h"
00020 #include "EmcScSectorRec.h"
00021 #include "EmcGlSectorRec.h"
00022
00023 #include "mEmcGeometryModule.h"
00024
00025 #include "VtxOut.h"
00026
00027 #include "emcTowerContainer.h"
00028 #include "emcTowerContent.h"
00029 #include "EmcIndexer.h"
00030
00031 #include "emcClusterContainer.h"
00032 #include "emcClusterContent.h"
00033
00034 using namespace std;
00035
00036 typedef PHIODataNode<PHTable> TableNode_t;
00037
00038 namespace {
00039
00040
00041 void computeCorrectedDispersion(float ycg, float zcg,
00042 float dispy, float dispz,
00043 float yModSize, float zModSize,
00044 float& corrdispy, float& corrdispz)
00045 {
00046 float zpos = zcg/zModSize;
00047 float ypos = ycg/yModSize;
00048
00049 corrdispy = dispy/(yModSize*yModSize);
00050 corrdispz = dispz/(zModSize*zModSize);
00051
00052 float zposmod = zpos - floor(zpos);
00053 float yposmod = ypos - floor(ypos);
00054 corrdispz -= ( zposmod - zposmod*zposmod);
00055 corrdispy -= ( yposmod - yposmod*yposmod);
00056 }
00057
00058 }
00059
00060
00061 mEmcClusterizerv0::mEmcClusterizerv0(mEmcGeometryModule* geom) :
00062 fClusters(0)
00063 {
00064 name = "mEmcClusterizerv0";
00065 int arm, sector;
00066 int nx, ny;
00067 float txsz, tysz;
00068 PHMatrix emcrm;
00069 PHVector emctr;
00070 float towerThresh = 0.003;
00071 float peakThresh = 0.08;
00072 float eClMin = 0.02;
00073 EmcSectorRec* SectorRec;
00074 SecGeom* SecGeometry;
00075
00076 for (int is = 0; is < MAX_SECTORS_PROCESS; is++)
00077 {
00078 if ( is < 6 )
00079 {
00080 SectorRec = new EmcScSectorRec;
00081 fScSector.push_back(SectorRec);
00082 }
00083 else
00084 {
00085 SectorRec = new EmcGlSectorRec;
00086 fGlSector.push_back(SectorRec);
00087 }
00088
00089
00090 SectorRec->SetTowerThreshold(towerThresh);
00091 SectorRec->SetPeakThreshold(peakThresh);
00092 SectorRec->SetChi2Limit(2);
00093
00094 if (is <= 3)
00095 {
00096 arm = 0;
00097 sector = is;
00098 }
00099 else
00100 {
00101 arm = 1;
00102 sector = 7 - is;
00103 }
00104
00105 geom->GetSectorDim(is, nx, ny);
00106 geom->GetTowerSize(is, txsz, tysz);
00107 geom->GetMatrixVector(is, emcrm, emctr);
00108
00109 SecGeometry = new SecGeom;
00110 fSectorGeometries.push_back(SecGeometry);
00111 SecGeometry->nx = nx;
00112 SecGeometry->ny = ny;
00113 SecGeometry->Tower_xSize = txsz;
00114 SecGeometry->Tower_ySize = tysz;
00115
00116 SectorRec->SetGeometry(*SecGeometry, &emcrm, &emctr);
00117 }
00118
00119 SetMinClusterEnergy(eClMin);
00120
00121 for (int is = 0; is < MAX_SECTORS_PROCESS; is++)
00122 {
00123 if (is < 6)
00124 {
00125 SectorRec = fScSector[is];
00126 }
00127 else
00128 {
00129 SectorRec = fGlSector[is-6];
00130 }
00131 TowerThresh[is] = SectorRec->GetTowerThreshold();
00132 Nx[is] = SectorRec->GetNx();
00133 }
00134 fHVect = new EmcModule[HVECTSIZE];
00135 }
00136
00137
00138 mEmcClusterizerv0::~mEmcClusterizerv0()
00139 {
00140 for ( size_t i = 0; i < fScSector.size(); ++i )
00141 {
00142 delete fScSector[i];
00143 }
00144 for ( size_t i = 0; i < fGlSector.size(); ++i )
00145 {
00146 delete fGlSector[i];
00147 }
00148 for ( size_t i = 0; i < fSectorGeometries.size(); ++i )
00149 {
00150 delete fSectorGeometries[i];
00151 }
00152
00153 delete[] fHVect;
00154 }
00155
00156
00157 void
00158 mEmcClusterizerv0::SetTowerThreshold(float Thresh)
00159 {
00160 for (int is = 0; is < MAX_SECTORS_PROCESS; is++)
00161 {
00162 if (is < 6)
00163 {
00164 fScSector[is]->SetTowerThreshold(Thresh);
00165 }
00166 else
00167 {
00168 fGlSector[is - 6]->SetTowerThreshold(Thresh);
00169 }
00170 }
00171 }
00172
00173
00174 void
00175 mEmcClusterizerv0::SetTowerThreshold(int is, float Thresh)
00176 {
00177 if (is < 0 || is >= MAX_SECTORS_PROCESS)
00178 {
00179 cout << PHWHERE << "Wrong sector index:" << is << endl;
00180 return;
00181 }
00182 if (is < 6)
00183 {
00184 fScSector[is]->SetTowerThreshold(Thresh);
00185 }
00186 else
00187 {
00188 fGlSector[is - 6]->SetTowerThreshold(Thresh);
00189 }
00190 }
00191
00192
00193 void
00194 mEmcClusterizerv0::SetTowerThresholdPbSc(float Thresh)
00195 {
00196 for (int is = 0; is < 6; is++)
00197 {
00198 fScSector[is]->SetTowerThreshold(Thresh);
00199 }
00200 }
00201
00202
00203 void mEmcClusterizerv0::SetTowerThresholdPbGl(float Thresh)
00204 {
00205 for (int is = 0; is < 2; is++)
00206 {
00207 fGlSector[is]->SetTowerThreshold(Thresh);
00208 }
00209 }
00210
00211
00212 void
00213 mEmcClusterizerv0::SetPeakThreshold(float Thresh)
00214 {
00215 for (int is = 0; is < MAX_SECTORS_PROCESS; is++)
00216 {
00217 if (is < 6)
00218 {
00219 fScSector[is]->SetPeakThreshold(Thresh);
00220 }
00221 else
00222 {
00223 fGlSector[is - 6]->SetPeakThreshold(Thresh);
00224 }
00225 }
00226 }
00227
00228
00229 void
00230 mEmcClusterizerv0::SetPeakThreshold(int is, float Thresh)
00231 {
00232 if (is < 0 || is >= MAX_SECTORS_PROCESS)
00233 {
00234 cout << PHWHERE << "Wrong sector index:" << is << endl;
00235 return;
00236 }
00237 if (is < 6)
00238 {
00239 fScSector[is]->SetPeakThreshold(Thresh);
00240 }
00241 else
00242 {
00243 fGlSector[is - 6]->SetPeakThreshold(Thresh);
00244 }
00245 }
00246
00247
00248 void
00249 mEmcClusterizerv0::fillHitList(const emcTowerContainer& towers)
00250 {
00251 for (int is = 0; is < MAX_SECTORS_PROCESS; is++)
00252 {
00253
00254 HitList[is].erase(HitList[is].begin(), HitList[is].end());
00255
00256 EmcSectorRec* SectorRec;
00257
00258 if ( is < 6 )
00259 {
00260 SectorRec = fScSector[is];
00261 }
00262 else
00263 {
00264 SectorRec = fGlSector[is-6];
00265 }
00266
00267
00268 TowerThresh[is] = SectorRec->GetTowerThreshold();
00269 Nx[is] = SectorRec->GetNx();
00270 }
00271
00272 for ( size_t i = 0; i < towers.size(); ++i )
00273 {
00274 const emcTowerContent* t = towers.getTower(i);
00275 int towerID = t->TowerID();
00276 int iarm,isector,iy,iz;
00277 EmcIndexer::TowerLocation(towerID,iarm,isector,iy,iz);
00278
00279 if ( iarm == 1 )
00280 {
00281 isector = 7 - isector;
00282 }
00283
00284 float de = t->Energy();
00285
00286
00287 if ( de<= TowerThresh[isector] ) continue;
00288
00289 float adc=0.0;
00290 float tac=0.0;
00291
00292 if ( t->hasDC() )
00293 {
00294 adc = t->ADC();
00295 tac = t->TDC();
00296 }
00297
00298 EmcModule vhit(iy * Nx[isector] + iz,
00299 0,
00300 de,
00301 t->ToF(),
00302 t->ErrorNeighbours(),
00303 t->WarnNeighbours(),
00304 adc,
00305 tac);
00306
00307 HitList[isector].push_back(vhit);
00308 }
00309 }
00310
00311
00312 void
00313 mEmcClusterizerv0::fillPeakArea(EmcPeakarea& pp, EmcCluster& cluster,
00314 int arm, int sector)
00315 {
00316 EmcModule hmax = pp.GetMaxTower();
00317 int ndead = pp.GetNDead();
00318 float qual = ndead ? 1.0 : -ndead;
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 float e,ecorr,ecore,ecorecorr;
00329 float xcg,ycg,xcgm,ycgm;
00330 float xc,yc,xgl,ygl,zgl;
00331 float xx,xy,yy;
00332 float chi2;
00333 float de,dx,dy,dz;
00334
00335 pp.GetChar(&e, &ecorr, &ecore, &ecorecorr,
00336 &xcg, &ycg, &xcgm, &ycgm,
00337 &xc, &yc, &xgl, &ygl, &zgl,
00338 &xx, &xy, &yy, &chi2, &de, &dx, &dy, &dz);
00339
00340 float e9 = pp.GetE9(hmax.ich);
00341
00342
00343 int nh = pp.GetNofHits();
00344 assert(nh<=HVECTSIZE);
00345 pp.GetHits(fHVect, nh);
00346
00347 float e_max_cl = cluster.GetTowerEnergy(hmax.ich);
00348
00349
00350 float padisp[2];
00351 float pahelp = (xx + yy) * (xx + yy) - 4.0 * (xx * yy - xy * xy);
00352 pahelp = sqrt(abs(pahelp));
00353 padisp[0] = (xx + yy + pahelp) / 2.0;
00354 padisp[1] = (xx + yy - pahelp) / 2.0;
00355
00356 float vx = fVertex[0]-xgl;
00357 float vy = fVertex[1]-ygl;
00358 float vz = fVertex[2]-zgl;
00359
00360 float lactual = sqrt( vx*vx + vy*vy + vz*vz );
00361 float lnominal = sqrt(xgl * xgl + ygl * ygl + zgl * zgl);
00362 float dd = lactual - lnominal;
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 float etof, etofmin, etofmax;
00375 float tof, tofcorr, dtof, tofmin, tofmax, tofmincorr, tofmaxcorr;
00376 float tofdisp=0;
00377
00378 ToF_Process(fHVect, nh,
00379 dd, hmax,
00380 &tof, &etof, &tofcorr, &dtof,
00381 &tofmin, &etofmin, &tofmincorr,
00382 &tofmax, &etofmax, &tofmaxcorr,
00383 tofdisp);
00384
00385 size_t id = fClusters->size();
00386
00387 emcClusterContent* clus =
00388 fClusters->addCluster(id);
00389
00390 clus->set_multiplicity(nh);
00391
00392 clus->set_id(id);
00393 clus->set_arm(arm);
00394 clus->set_sector(sector);
00395
00396 int is = EmcIndexer::sectorOfflineToOnline(arm,sector);
00397
00398 if (is < 6)
00399 {
00400 clus->set_type(1);
00401 }
00402 else
00403 {
00404 clus->set_type(2);
00405 }
00406
00407 clus->set_xyz(xgl,ygl,zgl);
00408 clus->set_dxyz(dx,dy,dz);
00409 clus->set_e(e);
00410 clus->set_e9(e9);
00411
00412 if (is<6)
00413 {
00414 clus->set_ecore(ecorecorr);
00415 }
00416 else
00417 {
00418 clus->set_ecore(ecorr);
00419 }
00420 clus->set_ecent(e_max_cl);
00421 clus->set_chi2(chi2);
00422 clus->set_tof(tof);
00423 clus->set_tofcorr(tofcorr);
00424 clus->set_tofdisp(tofdisp);
00425
00426 clus->set_quality(qual);
00427 clus->set_pid(0);
00428 clus->set_prob_photon(pp.GetCL());
00429
00430 float phi = ( xgl == 0.0 && ygl == 0.0 ? 0.0 : atan2(ygl,xgl) );
00431 float theta = ( xgl == 0.0 && ygl == 0.0 && zgl == 0.0 ? 0.0 :
00432 atan2(sqrt(xgl*xgl+ygl*ygl),zgl) );
00433
00434 clus->set_theta(theta);
00435 clus->set_phi(phi);
00436 int iy = hmax.ich / Nx[is];
00437 int iz = hmax.ich - iy * Nx[is];
00438 clus->set_ipos(iy,iz);
00439 clus->set_tofmin(tofmin);
00440 clus->set_etofmin(etofmin);
00441 clus->set_tofcorrmin(tofmincorr);
00442 clus->set_tofmax(tofmax);
00443 clus->set_etofmax(etofmax);
00444 clus->set_tofcorrmax(tofmaxcorr);
00445
00446 float dispy = yy;
00447 float dispz = xx;
00448 clus->set_disp(dispy,dispz);
00449 clus->set_padisp(padisp[1],padisp[0]);
00450
00451 if ( clus->has_yz_cg() )
00452 {
00453 clus->set_yz_cg(ycg,xcg);
00454
00455 float corrdispy=-9999;
00456 float corrdispz=-9999;
00457
00458 float zModSize = fSectorGeometries[is]->Tower_xSize;
00459 float yModSize = fSectorGeometries[is]->Tower_ySize;
00460
00461 computeCorrectedDispersion(ycg,xcg,
00462 dispy,dispz,
00463 yModSize,zModSize,
00464 corrdispy,corrdispz);
00465
00466 clus->set_corrdisp(corrdispy,corrdispz);
00467 }
00468
00469 float esum = 0;
00470 for (int ih = 0; ih < nh; ++ih)
00471 {
00472 if (fHVect[ih].amp <= 0)
00473 {
00474 clus->set_towerid(ih,-1);
00475 clus->set_partesum(ih,0);
00476
00477 }
00478 else
00479 {
00480 int ich = fHVect[ih].ich;
00481 int iy = ich / Nx[is];
00482 int iz = ich - iy * Nx[is];
00483 int swkey = iz + iy * 100 + 10000 * sector
00484 + 100000 * arm;
00485 int towerid = EmcIndexer::TowerID(swkey);
00486 clus->set_towerid(ih, towerid);
00487 esum += fHVect[ih].amp;
00488 clus->set_partesum(ih, esum);
00489 }
00490 }
00491
00492 clus->set_maps(hmax.deadmap,hmax.warnmap);
00493
00494 if ( clus->has_rawtdc() )
00495 {
00496 clus->set_rawtdc(hmax.tac);
00497 }
00498 }
00499
00500
00501 PHBoolean
00502 mEmcClusterizerv0::event(PHCompositeNode *root)
00503 {
00504 PHNodeIterator it(root);
00505
00506
00507
00508
00509
00510 PHIODataNode<PHObject>* emcTowerContainerNode =
00511 (PHIODataNode<PHObject>*)it.findFirst("PHIODataNode","emcTowerContainer");
00512 if ( !emcTowerContainerNode )
00513 {
00514 cerr << __FILE__ << ":" << __LINE__ << " cannot find emcTowerContainer "
00515 << "node." << endl;
00516 return false;
00517 }
00518 emcTowerContainer* towers =
00519 static_cast<emcTowerContainer*>(emcTowerContainerNode->getData());
00520 if (!towers)
00521 {
00522 cerr << __FILE__ << ":" << __LINE__ << " cannot find emcTowerContainer "
00523 << "object." << endl;
00524 return false;
00525 }
00526
00527 if ( !towers->isValid() ) return false;
00528
00529 PHIODataNode<PHObject>* emcClusterContainerNode =
00530 (PHIODataNode<PHObject>*)it.findFirst("PHIODataNode",
00531 "emcClusterContainer");
00532 if ( !emcClusterContainerNode )
00533 {
00534 cerr << __FILE__ << ":" << __LINE__
00535 << " cannot find emcClusterContainer node." << endl;
00536 return false;
00537 }
00538
00539 fClusters =
00540 static_cast<emcClusterContainer*>(emcClusterContainerNode->getData());
00541 if (!fClusters)
00542 {
00543 cerr << __FILE__ << ":" << __LINE__
00544 << " cannot find emcClusterContainer object." << endl;
00545 return false;
00546 }
00547 else
00548 {
00549 fClusters->Reset();
00550 }
00551
00552 PHIODataNode<PHObject>* vtxoutnode =
00553 (PHIODataNode<PHObject>*)it.findFirst("PHIODataNode", "VtxOut");
00554
00555 VtxOut* vtxout = 0;
00556
00557 if ( vtxoutnode )
00558 {
00559 vtxout = static_cast<VtxOut*>(vtxoutnode->getData());
00560 }
00561
00562 fVertex.resize(3,0);
00563
00564 if ( !vtxoutnode || !vtxout )
00565 {
00566 cout << PHWHERE << " No information (vtxout) about vertex. Assuming "
00567 << "(0,0,0)" << endl;
00568
00569 for ( int i = 0; i < 3; ++i )
00570 {
00571 fVertex[i] = 0.0;
00572 }
00573 }
00574 else
00575 {
00576 PHPoint vertex = vtxout->get_Vertex();
00577 fVertex[0] = vertex.getX();
00578 fVertex[1] = vertex.getY();
00579 fVertex[2] = vertex.getZ();
00580 }
00581
00582 if (!(fabs(fVertex[0]) < 10.0 &&
00583 fabs(fVertex[1]) < 10.0 &&
00584 fabs(fVertex[2]) < 100.0))
00585 {
00586
00587 for ( int i = 0; i < 3; ++i )
00588 {
00589 fVertex[i] = 0.0;
00590 }
00591
00592
00593
00594
00595
00596
00597 }
00598
00599
00600
00601
00602 fillHitList(*towers);
00603
00604 EmcPeakarea pPList[MAX_NUMBER_OF_PEAKS];
00605 EmcModule peaks[MAX_NUMBER_OF_PEAKS];
00606
00607
00608 for ( int is = 0; is < MAX_SECTORS_PROCESS; ++is )
00609 {
00610 EmcSectorRec* SectorRec = (is < 6) ? fScSector[is] : fGlSector[is - 6];
00611 int arm, sector;
00612
00613 if (is <= 3)
00614 {
00615 arm = 0;
00616 sector = is;
00617 }
00618 else
00619 {
00620 arm = 1;
00621 sector = 7 - is;
00622 }
00623
00624 float MinClusterEnergy = (is < 6) ? fMinClusterEnergySc :
00625 fMinClusterEnergyGl;
00626
00627 SectorRec->SetVertex(&fVertex[0]);
00628 SectorRec->SetModules(&HitList[is]);
00629 int nCl = SectorRec->FindClusters();
00630 vector<EmcCluster>* ClusterList = SectorRec->GetClusters();
00631
00632 if (nCl < 0)
00633 {
00634 cerr << " ?????? " << name << ": Increase parameter MaxLen !!!"
00635 << endl;
00636 return false;
00637 }
00638
00639
00640
00641
00642 vector<EmcCluster>::iterator pc;
00643
00644 for ( pc = ClusterList->begin(); pc != ClusterList->end(); ++pc )
00645 {
00646 int npk = (*pc).GetPeaks(pPList, peaks);
00647 EmcPeakarea* pp = pPList;
00648 assert(pp!=0);
00649
00650 for ( int ip = 0; ip < npk; ++ip )
00651 {
00652 if (pp->GetTotalEnergy() > MinClusterEnergy)
00653 {
00654 fillPeakArea(*pp,(*pc), arm, sector);
00655 }
00656 pp++;
00657 }
00658 }
00659 }
00660
00661 return true;
00662 }
00663
00664 void
00665 mEmcClusterizerv0::ToF_Process(EmcModule* phit, size_t nhits,
00666 float dist, EmcModule& hmax,
00667 float* ptof, float* petof, float* ptofcorr,
00668 float* pdtof,
00669 float* ptofmin, float* petofmin,
00670 float* ptofmincorr,
00671 float* ptofmax, float* petofmax,
00672 float* ptofmaxcorr,
00673 float& tofdisp)
00674 {
00675 float tof, tofcorr, etof, tflash;
00676 float tofmin, tofmincorr, etofmin, tofmax, tofmaxcorr, etofmax;
00677 EmcModule* ph;
00678
00679 tof = hmax.tof;
00680 etof = hmax.amp;
00681
00682 tofmax = 0;
00683 tofmin = 999;
00684 etofmax = 0;
00685 etofmin = 0;
00686 ph = phit;
00687
00688 float tofsum=0;
00689 float tofsum2=0;
00690 int nsum = 0;
00691
00692 for ( size_t i = 0; i < nhits; i++)
00693 {
00694 if (ph->amp > 0)
00695 {
00696 if (ph->tof > tofmax)
00697 {
00698 tofmax = ph->tof;
00699 etofmax = ph->amp;
00700 }
00701 if (ph->tof < tofmin)
00702 {
00703 tofmin = ph->tof;
00704 etofmin = ph->amp;
00705 }
00706 tofsum += ph->tof;
00707 tofsum2 += ph->tof * ph->tof;
00708 ++nsum;
00709 }
00710 ph++;
00711 }
00712
00713 if ( nsum > 1 )
00714 {
00715 float tofmean = tofsum/nsum;
00716 tofdisp = sqrt((tofsum2 - nsum*tofmean*tofmean)/(nsum-1));
00717 }
00718 else
00719 {
00720 tofdisp = 0;
00721 }
00722
00723 tflash = dist / 30.0;
00724
00725 tof = tof - tflash;
00726 tofmin = tofmin - tflash;
00727 tofmax = tofmax - tflash;
00728
00729 tofcorr = tof;
00730 tofmincorr = tofmin;
00731 tofmaxcorr = tofmax;
00732
00733 *ptof = tof;
00734 *petof = etof;
00735 *ptofcorr = tofcorr;
00736 *pdtof = 0;
00737 *ptofmax = tofmax;
00738 *petofmax = etofmax;
00739 *ptofmaxcorr = tofmaxcorr;
00740 *ptofmin = tofmin;
00741 *petofmin = etofmin;
00742 *ptofmincorr = tofmincorr;
00743 }