00001
00026 #include "StEEmcPointMaker.h"
00027 #include "StEEmcPool/StEEmcA2EMaker/StEEmcA2EMaker.h"
00028 #include "StEEmcPool/StEEmcClusterMaker/StEEmcClusterMaker.h"
00029
00030 #include "StEEmcUtil/EEmcGeom/EEmcGeomDefs.h"
00031 #include "StEEmcUtil/EEmcGeom/EEmcGeomSimple.h"
00032 #include "StEEmcUtil/StEEmcSmd/EEmcSmdGeom.h"
00033
00034 #include <iostream>
00035 #include <algorithm>
00036 #include <map>
00037
00038 #include "eeTowerFunction.h"
00039
00040
00041 #include "StEvent/StEvent.h"
00042 #include "StEvent/StEmcCollection.h"
00043 #include "StEvent/StEmcPoint.h"
00044
00045
00046 #include "TMatrixF.h"
00047
00048
00049
00050 ClassImp(StEEmcPointMaker);
00051
00052
00053 StEEmcPointMaker::StEEmcPointMaker(const Char_t *name):StMaker(name)
00054 {
00055 std::cout << "StEEmcPointMaker("<<name<<")" << std::endl << std::flush;
00056
00060 mEEtow=new EEmcGeomSimple();
00061 mEEsmd=EEmcSmdGeom::instance();
00062 mEEmap=EEmcSmdMap::instance();
00063
00064 mTowerThreshold=0.;
00065 mFillStEvent=false;
00066 mEnergyMode=1;
00067 mLimit=10;
00068 mSmdMatch = 0.;
00069
00070 }
00071
00072
00073 Int_t StEEmcPointMaker::Init()
00074 {
00075 mEEanalysis=(StEEmcA2EMaker*)GetMaker(mNameAnalysis);
00076 mEEclusters=(StEEmcClusterMaker*)GetMaker(mNameClusters);
00077 assert(mEEanalysis);
00078 assert(mEEclusters);
00079 return StMaker::Init();
00080 }
00081
00082
00083 Int_t StEEmcPointMaker::Make()
00084 {
00085
00092
00093
00094 for ( Int_t sector=0; sector<12; sector++ )
00095 {
00096
00098 StEEmcSmdClusterVec_t uclusters=mEEclusters->smdclusters(sector,0);
00099 StEEmcSmdClusterVec_t vclusters=mEEclusters->smdclusters(sector,1);
00100
00102 std::sort( uclusters.begin(), uclusters.end(), inner );
00103 std::sort( vclusters.begin(), vclusters.end(), inner );
00104
00105 findPoints( sector, uclusters, vclusters, mPoints );
00106
00107 }
00108
00109
00116 for ( UInt_t i=0;i<mPoints.size();i++ )
00117 {
00118 mPoints[i].energy( (Float_t)(mPoints[i].energy()/0.007/2.) );
00119 }
00120
00121
00122
00123
00124 StEEmcPointVec_t orgpoints=mPoints;
00125
00127
00128
00129 if ( mEnergyMode == 1 )
00130 shareEnergySimple();
00131 else
00132 shareEnergySmd();
00133
00134
00136 countRelatives();
00137
00138
00139 if ( mFillStEvent )
00140 {
00141 fillStEvent();
00142 verifyStEvent();
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 return kStOK;
00154 }
00155
00156
00157
00158 StEEmcPointVec_t StEEmcPointMaker::buildSmdPoints( Int_t sector,
00159 StEEmcSmdClusterVec_t &u,
00160 StEEmcSmdClusterVec_t &v )
00161 {
00162
00163 StEEmcPointVec_t points;
00164
00165 for ( UInt_t i=0; i<u.size(); i++ )
00166 {
00167
00168 StEEmcSmdCluster uc=u[i];
00169 Float_t xu=uc.mean();
00170
00171 for ( UInt_t j=0;j<v.size(); j++ )
00172 {
00173
00174
00175 StEEmcSmdCluster vc=v[j];
00176 Float_t xv=vc.mean();
00177
00179 TVector3 direct = mEEsmd->getIntersection( sector, xu, xv );
00180
00181 Int_t sec,sub,eta;
00182 if ( !mEEtow->getTower(direct,sec,sub,eta) )
00183 {
00184 continue;
00185 }
00186 else
00187 {
00189 }
00190
00193 if ( sector != sec )
00194 continue;
00195
00196
00197
00201 Bool_t good = false;
00202 if ( mEEanalysis->tower(sec,sub,eta).energy() > mTowerThreshold )
00203 good=true;
00204 else if ( mEEanalysis->tower(sec,sub,eta).fail() )
00205 {
00206 for ( Int_t layer=1;layer<=3;layer++ )
00207 {
00208 if ( mEEanalysis->tower(sec,sub,eta,layer).energy() > 0. )
00209 good=true;
00210 }
00211 }
00212
00215
00216
00217
00218
00219
00220 Float_t Eu=uc.energy();
00221 Float_t Ev=vc.energy();
00222 if ( Eu < mSmdMatch * Ev || Ev < mSmdMatch * Eu ) good=false;
00223
00224 if ( good ) {
00225
00226 StEEmcPoint p;
00227 p.cluster( uc, 0 );
00228 p.cluster( vc, 1 );
00229 p.energy( uc.energy() + vc.energy() );
00230 p.tower( mEEanalysis->tower(sec,sub,eta) );
00231 TVector3 position=mEEsmd->getIntersection(sector,uc.mean(),vc.mean());
00232 p.position(position);
00233 points.push_back(p);
00234
00236 mSmdPoints.push_back(p);
00237
00238 }
00239
00240 }
00241
00242 }
00243
00244 return points;
00245
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 Bool_t StEEmcPointMaker::findPoints( Int_t sector,
00266 StEEmcSmdClusterVec_t uclusters,
00267 StEEmcSmdClusterVec_t vclusters,
00268 StEEmcPointVec_t &points )
00269 {
00270
00271
00273 StEEmcPointVec_t mypoints;
00274
00276 std::sort( uclusters.begin(), uclusters.end(), inner );
00277 std::sort( vclusters.begin(), vclusters.end(), inner );
00278
00280 StEEmcPointVec_t smdpoints = buildSmdPoints( sector, uclusters, vclusters );
00281
00282
00284 if ( smdpoints.size() < 1 ) return false;
00285
00287 std::sort( smdpoints.begin(), smdpoints.end(), chiSquare );
00288
00289
00293 std::map< Int_t, std::vector<Int_t> > u2p, v2p;
00294 for ( UInt_t i=0; i<smdpoints.size(); i++ )
00295 {
00296 u2p[ smdpoints[i].cluster(0).key() ].push_back( i );
00297 v2p[ smdpoints[i].cluster(1).key() ].push_back( i );
00298 }
00299
00304 Bool_t go = false;
00305 StEEmcSmdClusterVec_t::iterator uiter=uclusters.begin();
00306 StEEmcSmdClusterVec_t::iterator viter=vclusters.begin();
00307
00308
00309
00310
00311
00312
00313
00314 while ( uiter<uclusters.end() || viter<vclusters.end() )
00315 {
00316
00318 StEEmcSmdCluster ucl;ucl.key(-1);
00319 StEEmcSmdCluster vcl;vcl.key(-1);
00320 if ( uiter<uclusters.end() ) ucl=(*uiter);
00321 if ( viter<vclusters.end() ) vcl=(*viter);
00322 Int_t iUV=-1;
00323 if ( ucl.key()<0 )
00324 iUV=1;
00325 else if ( vcl.key()<0 )
00326 iUV=0;
00327 else if ( (*uiter).mean() < (*viter).mean() )
00328 iUV=0;
00329 else
00330 iUV=1;
00331
00333 StEEmcSmdCluster &cluster=(iUV==0)?ucl:vcl;
00334
00336 std::vector<Int_t> matched=(iUV==0)?
00337 u2p[cluster.key()]:
00338 v2p[cluster.key()];
00339
00340
00343 if ( matched.size()==0 || matched.size() >1 )
00344 {
00345 if ( iUV==0 ) uiter++;
00346 if ( iUV==1 ) viter++;
00347 continue;
00348 }
00349
00354 go=true;
00355
00358 StEEmcPoint p=smdpoints[matched.back()];
00359
00361 mypoints.push_back(p);
00362
00363 if ( iUV==0 ) uiter++;
00364 if ( iUV==1 ) viter++;
00365
00366 }
00367
00368
00371 Float_t chisq=9.0E9;
00372 Int_t imin=-1;
00373 for ( UInt_t i=0; i<mypoints.size(); i++ )
00374 {
00375 Float_t eu=mypoints[i].cluster(0).energy();
00376 Float_t ev=mypoints[i].cluster(1).energy();
00377 Float_t x2=(eu-ev)*(eu-ev);
00378 if ( x2 < chisq ) {
00379 imin=(Int_t)i;
00380 chisq=x2;
00381 }
00382 }
00383
00384
00391 if ( imin >= 0 ) {
00392
00393 StEEmcPoint p=mypoints[imin];
00394 removeCluster( uclusters, p.cluster(0).key() );
00395 removeCluster( vclusters, p.cluster(1).key() );
00396 points.push_back(p);
00397 findPoints(sector, uclusters, vclusters, points );
00398 return true;
00399
00400 }
00401
00402
00403
00404
00405
00407
00408
00415 uiter=uclusters.begin();
00416 viter=vclusters.begin();
00417 while ( uiter!=uclusters.end() || viter!=vclusters.end() )
00418 {
00419
00421 StEEmcSmdCluster ucl;ucl.key(-1);
00422 StEEmcSmdCluster vcl;vcl.key(-1);
00423 if ( uiter!=uclusters.end() ) ucl=(*uiter);
00424 if ( viter!=vclusters.end() ) vcl=(*viter);
00425 Int_t iUV=-1;
00426 if ( ucl.key()<0 )
00427 iUV=1;
00428 else if ( vcl.key()<0 )
00429 iUV=0;
00430 else if ( (*uiter).mean() < (*viter).mean() )
00431 iUV=0;
00432 else
00433 iUV=1;
00434
00436 StEEmcSmdCluster &cluster=(iUV==0)?ucl:vcl;
00437
00439 std::vector<Int_t> matched=(iUV==0)?
00440 u2p[cluster.key()]:
00441 v2p[cluster.key()];
00442
00445 if ( matched.size()==0 || matched.size()==1 )
00446 {
00447 if ( iUV==0 ) uiter++;
00448 if ( iUV==1 ) viter++;
00449 continue;
00450 }
00451
00454 StEEmcPoint p=smdpoints[matched.front()];
00455
00457 mypoints.push_back(p);
00458
00459 if ( iUV==0 ) uiter++;
00460 if ( iUV==1 ) viter++;
00461
00462 }
00463
00464
00467 chisq=9.0E9;
00468 imin=-1;
00469 for ( UInt_t i=0; i<mypoints.size(); i++ )
00470 {
00471 Float_t eu=mypoints[i].cluster(0).energy();
00472 Float_t ev=mypoints[i].cluster(1).energy();
00473 Float_t x2=(eu-ev)*(eu-ev);
00474 if ( x2 < chisq ) {
00475 imin=(Int_t)i;
00476 chisq=x2;
00477 }
00478 }
00479
00480
00481
00488 if ( imin >= 0 ) {
00489
00490 StEEmcPoint p=mypoints[imin];
00491 removeCluster( uclusters, p.cluster(0).key() );
00492 removeCluster( vclusters, p.cluster(1).key() );
00493 points.push_back(p);
00494 findPoints(sector, uclusters, vclusters, points );
00495 return true;
00496
00497 }
00498
00499
00500 return true;
00501
00502 }
00503
00504
00505
00506
00507 void StEEmcPointMaker::Clear( Option_t *opts )
00508 {
00509
00510 mEseen=0.;
00511 mPoints.clear();
00512 mSmdPoints.clear();
00513
00514 }
00515
00516
00517 void StEEmcPointMaker::removeCluster( StEEmcSmdClusterVec_t &clusters, Int_t k )
00518 {
00519 StEEmcSmdClusterVec_t::iterator iter=clusters.begin();
00520 while ( iter != clusters.end() )
00521 {
00522 if ( (*iter).key() == k ) {
00523 clusters.erase(iter);
00524 return;
00525 }
00526 iter++;
00527 }
00528 }
00529
00530
00531 void StEEmcPointMaker::shareEnergy()
00532 {
00533
00539
00540
00541
00542 Int_t nrow=(Int_t)mPoints.size();
00543 Int_t ncol=(Int_t)mPoints.size();
00544 if ( nrow < 1 ) return;
00545
00546 std::vector<Float_t> Ef(nrow,0.);
00547
00548 TMatrixF fractions(nrow,ncol);
00549
00551 for ( Int_t k=0; k<mEEanalysis->numberOfHitTowers(0); k++ )
00552 {
00553
00555 StEEmcTower tower=mEEanalysis->hittower(k,0);
00556
00558 for ( UInt_t i=0; i< mPoints.size(); i++ )
00559 {
00560
00563 Float_t fi=fracp2t( mPoints[i], tower );
00564 if ( fi<=0. ) continue;
00565
00567 Ef[i] += fi * tower.energy();
00568
00569 for ( UInt_t j=0; j<mPoints.size(); j++ )
00570 {
00571
00574 Float_t fj=fracp2t( mPoints[j], tower );
00575 if (fi*fj<=0.) continue;
00576
00577 fractions[i][j] += fi*fj;
00578
00579 }
00580
00581 }
00582
00583 }
00584
00585 fractions.Print();
00586
00588 Double_t det = 0.;
00589 TMatrixF invert= fractions;
00590 invert.Invert(&det);
00591
00592 invert.Print();
00593
00594 TMatrixF test= fractions * invert;
00595
00596 test.Print();
00597
00598
00600
00601 std::vector<Float_t> epoints(nrow,0.);
00602
00603 for ( Int_t i=0; i<nrow; i++ )
00604 {
00605 for ( Int_t j=0; j<ncol; j++ )
00606 {
00607 epoints[i] += invert[i][j] * Ef[j];
00608 }
00609
00610
00611 }
00612
00613
00614
00615
00616
00617
00618 }
00619
00620
00621
00622 Float_t StEEmcPointMaker::fracp2t( StEEmcPoint &p, StEEmcTower &t )
00623 {
00624
00626
00627
00630 if ( !t.isNeighbor( p.tower(0) ) ) return 0.;
00631
00632
00633
00635 Float_t xeta=(Float_t)t.etabin();
00636 Float_t xphi=(Float_t)t.phibin();
00637 Double_t X[]={xphi,xeta};
00638
00640 Float_t xeta0=(Float_t)p.tower(0).etabin();
00641 Float_t xphi0=(Float_t)p.tower(0).phibin();
00642
00645 Int_t sec,sub,eta;
00646 Float_t dphi,deta;
00647 if ( !mEEtow->getTower(p.position(), sec,sub,eta, dphi,deta ) ) return 0.;
00648 dphi/=2.0;
00649 deta/=2.0;
00650
00652 Float_t xetap=xeta0+deta;
00653 Float_t xphip=xphi0+dphi;
00654 Double_t P[]={xphip,xetap,1.0};
00655
00656 return eeTowerFunction( X, P );
00657
00658 }
00659
00660
00661
00662 void StEEmcPointMaker::shareEnergySimple()
00663 {
00664
00665 Int_t limit=mLimit;
00666 Int_t count=0;
00667
00668 while ( count++ < limit )
00669 {
00670
00673 Float_t sumw[720];
00674 for (Int_t i=0;i<720;i++) sumw[i]=0.;
00675
00678 for ( UInt_t i=0;i<mPoints.size();i++ )
00679 {
00680
00681 StEEmcPoint point=mPoints[i];
00682 StEEmcTower tower=point.tower(0);
00683
00684 sumw[ tower.index() ] += point.energy() * fracp2t( point, tower );
00685
00687 for ( Int_t i=0; i<tower.numberOfNeighbors(); i++ )
00688 {
00689 StEEmcTower neighbor=tower.neighbor(i);
00690 sumw[ neighbor.index() ] += point.energy() * fracp2t( point, neighbor );
00691 }
00692
00693 }
00694
00695
00699
00700 for ( UInt_t i=0;i<mPoints.size();i++ )
00701 {
00702
00703 StEEmcPoint &point=mPoints[i];
00704 StEEmcTower tower=point.tower(0);
00705 Float_t epoint=0.;
00706
00707 Float_t frac=0.;
00708 if ( !tower.fail() && !tower.stat() && sumw[tower.index()]>0. )
00709 frac = point.energy() * fracp2t(point,tower) / sumw[ tower.index() ];
00710
00711 epoint += tower.energy() * frac;
00712
00715 for ( Int_t i=0; i<tower.numberOfNeighbors(); i++ )
00716 {
00717 StEEmcTower neighbor=tower.neighbor(i);
00718 if ( neighbor.stat() || neighbor.fail() || sumw[neighbor.index()]<=0. ) continue;
00719 frac = point.energy() * fracp2t(point,neighbor) / sumw[ neighbor.index() ];
00720 epoint += frac * neighbor.energy();
00721 }
00722
00723
00725 point.energy( epoint );
00726
00727 }
00728
00729 }
00730
00731
00732
00733
00734 std::vector<Bool_t> seen(720,false);
00735 for ( UInt_t i=0;i<mPoints.size();i++ )
00736 {
00737
00738 StEEmcTower tow=mPoints[i].tower(0);
00739 if ( !seen[ tow.index() ] ) mEseen+=tow.energy();
00740 seen[ tow.index() ] = true;
00741
00742 for ( Int_t j=0;j<tow.numberOfNeighbors();j++ )
00743 {
00744 StEEmcTower nei=tow.neighbor(j);
00745 if ( !seen[ nei.index() ] ) mEseen += nei.energy();
00746 seen[ nei.index() ] = true;
00747 }
00748
00749 }
00750
00751
00752
00753
00754
00755
00756 }
00757
00758
00759
00760
00761
00762
00763 void StEEmcPointMaker::fillStEvent()
00764 {
00765
00766
00767 StEvent *stevent=(StEvent*)GetInputDS("StEvent");
00768 if ( !stevent ) {
00769 Warning("fillStEvent","called, but no StEvent to be found");
00770 return;
00771 }
00772
00773
00775 for ( UInt_t i=0; i<mPoints.size(); i++ )
00776 {
00777
00778 StEmcPoint *point=mPoints[i].stemc();
00779 stevent->emcCollection()->addEndcapPoint( point );
00780
00781 mEtoEE[ point ] = mPoints[i];
00782
00783
00784 }
00785
00786 }
00787
00788
00789
00790
00791 void StEEmcPointMaker::verifyStEvent()
00792 {
00793
00794 Float_t emc_sum_points = 0.;
00795 Float_t eemc_sum_points = 0.;
00796
00797 StEvent *stevent=(StEvent*)GetInputDS("StEvent");
00798 if ( !stevent ) {
00799 Warning("verifyStEvent","called, but no StEvent to be found");
00800 return;
00801 }
00802
00803 StSPtrVecEmcPoint& emcpts = stevent->emcCollection()->endcapPoints();
00804 for ( UInt_t i=0;i<emcpts.size();i++ )
00805 {
00806
00807 StEmcPoint *p=emcpts[i];
00808 assert(p);
00809 emc_sum_points += p->energy();
00810
00811 }
00812
00813 for ( UInt_t i=0;i<mPoints.size();i++ )
00814 {
00815
00816 StEEmcPoint p=mPoints[i];
00817 eemc_sum_points += p.energy();
00818
00819 }
00820
00821 std::cout << "StEEmcPointMaker point checksum: ";
00822 if ( emc_sum_points == eemc_sum_points )
00823 {
00824 std::cout << "passed";
00825 }
00826 else
00827 std::cout << "FAILED";
00828 std::cout << std::endl;
00829
00830
00831 }
00832
00833
00834
00835 void StEEmcPointMaker::countRelatives()
00836 {
00837
00839 Int_t npoints[720];
00840 for ( Int_t i=0;i<720;i++ ) npoints[i]=0;
00841
00842 for ( UInt_t i=0;i<mPoints.size();i++ )
00843 npoints[ mPoints[i].tower(0).index() ]++;
00844
00846 for ( UInt_t i=0;i<mPoints.size();i++ )
00847 {
00848
00849 StEEmcTower tower=mPoints[i].tower(0);
00850 Int_t nn=tower.numberOfNeighbors();
00851
00852 Int_t nrel=npoints[ tower.index() ] - 1;
00853 assert(nrel>=0);
00854
00855 for ( Int_t j=0;j<nn;j++ )
00856 {
00857 StEEmcTower t2=tower.neighbor(j);
00858 nrel+=npoints[ t2.index() ];
00859 }
00860
00861 mPoints[i].numberOfRelatives(nrel);
00862
00863 }
00864
00865
00866 }
00867
00868
00869
00870
00871
00872 void StEEmcPointMaker::shareEnergySmd()
00873 {
00874
00877 Float_t sumw[720];for ( Int_t i=0;i<720;i++ )sumw[i]=0.;
00878 Float_t sumw1[720];for ( Int_t i=0;i<720;i++ )sumw1[i]=0.;
00879
00880 for ( UInt_t ipoint=0;ipoint<mPoints.size();ipoint++ )
00881 {
00882
00883
00884 StEEmcPoint point=mPoints[ipoint];
00885 StEEmcTower tower=point.tower(0);
00886 sumw[tower.index()]+=point.energy();
00887 sumw1[tower.index()]+=point.energy();
00888
00889 for ( Int_t itow=0;itow<tower.numberOfNeighbors();itow++ )
00890 {
00891 StEEmcTower t=tower.neighbor(itow);
00892 Int_t index=t.index();
00893 sumw[index]+=point.energy();
00894 }
00895
00896 }
00897
00900
00901 for ( UInt_t ipoint=0;ipoint<mPoints.size();ipoint++ )
00902 {
00903
00904 StEEmcPoint point=mPoints[ipoint];
00905 StEEmcTower tower = point.tower(0);
00906 StEEmcTower pre1 = mEEanalysis->tower(tower.index(),1);
00907 StEEmcTower pre2 = mEEanalysis->tower(tower.index(),2);
00908 StEEmcTower post = mEEanalysis->tower(tower.index(),3);
00909
00910 Float_t epoint = 0.;
00911 Float_t epre1 = 0.;
00912 Float_t epre2 = 0.;
00913 Float_t epost = 0.;
00914
00915 Int_t index = tower.index();
00916 epoint += tower.energy() * point.energy() / sumw[index];
00917 epre1 += pre1.energy() * point.energy() / sumw1[index];
00918 epre2 += pre2.energy() * point.energy() / sumw1[index];
00919 epost += post.energy() * point.energy() / sumw[index];
00920
00921 for ( Int_t itow=0;itow<tower.numberOfNeighbors();itow++ )
00922 {
00923 StEEmcTower t=tower.neighbor(itow);
00924
00925
00926 StEEmcTower r=post.neighbor(itow);
00927
00928 index = t.index();
00929 epoint += t.energy() * point.energy() / sumw[index];
00930
00931
00932 epost += r.energy() * point.energy() / sumw[index];
00933 }
00934
00935
00936 mPoints[ipoint].energy(epoint);
00937 mPoints[ipoint].energy(epre1,1);
00938 mPoints[ipoint].energy(epre2,2);
00939 mPoints[ipoint].energy(epost,3);
00940
00941 }
00942
00943
00944 }
00945
00946