00001 #include "StEEmc2x2ClusterMaker.h"
00002
00003 #include "StEEmcPool/StEEmcA2EMaker/StEEmcA2EMaker.h"
00004
00005 #include <algorithm>
00006
00007 #include "StMuDSTMaker/COMMON/StMuTrack.h"
00008
00009 #include "StMcEvent/StMcEvent.hh"
00010 #include "StMcEvent/StMcTrack.hh"
00011 #include "StMcEvent/StMcVertex.hh"
00012
00013 #include "StMessMgr.h"
00014
00015 ClassImp(StEEmc2x2ClusterMaker);
00016
00017
00018 StEEmc2x2ClusterMaker::StEEmc2x2ClusterMaker(const Char_t *name, const StEEmcA2EMaker *a2e, StMuDstMaker * )
00019 : StEEmcGenericClusterMaker(name,a2e), StEEmc2x2ClusterParams()
00020 {
00021 mSmdSeedEnergy = 4.0 / 1000.0;
00022 mSmdMinEnergy = 0.5 / 1000.0;
00023
00024 mMaxExtent = 40;
00025 mTruncateRatio = 1.2;
00026 mMinStrips = 3;
00027
00028 mSeedEnergy[0]=0.8; mMinEnergy[0]=0.1;
00029 mSeedEnergy[1]=1.0/1000.0; mMinEnergy[1]=0.1/1000.0;
00030 mSeedEnergy[2]=1.0/1000.0; mMinEnergy[2]=0.1/1000.0;
00031 mSeedEnergy[3]=1.0/1000.0; mMinEnergy[3]=0.1/1000.0;
00032
00033 mEtaCut = 999;
00034 mPhiCut = 999;
00035
00036
00037
00038
00039 setDoBreakInflection(0);
00040 setDoBreakTruncation(0);
00041 setDoBreakSize(0);
00042
00043 mUseFloor=false;
00044 mFloorParams[0]=0.;mFloorParams[1]=0.;
00045
00046 }
00047
00048
00049 Int_t StEEmc2x2ClusterMaker::Make()
00050 {
00051
00052 buildTowerClusters();
00053 buildPreshowerClusters();
00054
00055 buildPostshowerClusters();
00056 Int_t result = StEEmcGenericClusterMaker::Make();
00057 return result;
00058 }
00059
00060
00061 Int_t StEEmc2x2ClusterMaker::buildLayer(Int_t layer )
00062 {
00063
00064 const Char_t *clayers[]={"T","P","Q","R","U","V"};
00065
00066 LOG_INFO << " build clusters for layer=" << clayers[layer] << endm;
00067
00068
00069 StEEmcTowerVec_t hits=mEEanalysis->towers(layer);
00070
00071
00072 std::sort( hits.begin(), hits.end());
00073
00074 std::reverse( hits.begin(), hits.end());
00075
00076 LOG_DEBUG<<"searching for seeds in layer "<<clayers[layer]<<endm;
00077
00078
00079 StEEmcTowerVec_t seeds;
00080 for ( UInt_t i=0;i<hits.size();i++ )
00081 {
00082 if ( hits[i].fail() ) continue;
00083 if ( hits[i].energy() > mSeedEnergy[layer] )
00084 seeds.push_back(hits[i]);
00085 else
00086 break;
00087 LOG_DEBUG<<"+ "<<hits[i].name()<<" "<<hits[i].energy()<<endm;
00088 }
00089 LOG_DEBUG<<"clustering"<<endm;
00090
00091
00092
00093 struct Cluster {
00094 int quad;
00095 int *etabins;
00096 int *phibins;
00097 float et;
00098 };
00099
00100 int etaA[]={0, 0, 1, 1};
00101 int etaB[]={0, 0,-1,-1};
00102 int phiA[]={0, 1, 0, 1};
00103 int phiB[]={0,-1, 0,-1};
00104
00105 Cluster Cluster0 = { 0, etaA, phiA, 0. };
00106 Cluster Cluster1 = { 1, etaA, phiB, 0. };
00107 Cluster Cluster2 = { 2, etaB, phiB, 0. };
00108 Cluster Cluster3 = { 3, etaB, phiA, 0. };
00109 Cluster Quads[]={Cluster0,Cluster1,Cluster2,Cluster3};
00110
00111
00112
00113 Bool_t used[720];
00114 for ( Int_t i=0;i<720;i++ ) used[i]=false;
00115
00116 for ( UInt_t i=0;i<seeds.size();i++ )
00117 {
00118
00119 StEEmcTower tow=seeds[i];
00120 if ( tow.fail() ) continue;
00121 if ( used[tow.index()] ) continue;
00122
00123 Int_t etabin_seed = tow.etabin();
00124 Int_t phibin_seed = tow.phibin();
00125
00126
00127
00128 StEEmcCluster c;
00129 Int_t ntowers = 0;
00130
00131
00132
00133 for ( Int_t j=0;j<4;j++ )
00134 {
00135
00136 StEEmcCluster temp;
00137 Int_t ntow=0;
00138 for ( Int_t k=0;k<4;k++ )
00139 {
00140
00141 Int_t myeta = etabin_seed + Quads[j].etabins[k];
00142 Int_t myphi = phibin_seed + Quads[j].phibins[k];
00143 if ( myeta < 0 || myeta > 11 ) continue;
00144 Int_t myindex = myeta + 12 * ( ( myphi + 60 ) % 60 );
00145 if ( used[myindex] ) continue;
00146
00147 const StEEmcTower &t = mEEanalysis->tower(myindex,layer);
00148 if ( t.energy() > mMinEnergy[layer] ) {
00149 temp.add(t);
00150 ntow++;
00151 }
00152
00153 }
00154
00155 if ( ntow > 0 && temp.energy() > c.energy() )
00156 {
00157 c=temp;
00158 ntowers = ntow;
00159 }
00160
00161 }
00162
00163
00164
00165
00166 if ( ntowers ) {
00167 add(c);
00168 for ( Int_t ii=0;ii<c.numberOfTowers();ii++ )
00169 {
00170
00171 used[ c.tower(ii).index() ] = true;
00172 }
00173
00174 LOG_DEBUG<<"+ key="<<c.key()<<" seed="<<c.tower(0).name()<<" energy="<<c.energy()<<endm;
00175 }
00176
00177 }
00178
00179 return kStOk;
00180
00181 }
00182
00183
00184 Int_t StEEmc2x2ClusterMaker::buildTowerClusters()
00185 {
00186 return buildLayer(0);
00187 }
00188
00189
00190 Int_t StEEmc2x2ClusterMaker::buildPreshowerClusters()
00191 {
00192 buildLayer(1);
00193 buildLayer(2);
00194 return kStOK;
00195 }
00196
00197
00198 Int_t StEEmc2x2ClusterMaker::buildPostshowerClusters()
00199 {
00200 return buildLayer(3);
00201 }
00202
00203
00204 Int_t StEEmc2x2ClusterMaker::buildSmdClusters()
00205 {
00206
00207 LOG_INFO << " building SMD clusters" << endm;
00208
00209 for ( Int_t sector=0;sector<12;sector++ ) {
00210
00211 Float_t etmax = 0.;
00212 for ( UInt_t ii=0;ii<mTowerClusters[sector][0].size();ii++ )
00213 {
00214 const StEEmcCluster &c = mTowerClusters[sector][0][ii];
00215 if ( c.momentum().Perp() > etmax ) etmax = c.momentum().Perp();
00216 }
00217
00218
00219 if ( etmax >= 4.5 ) {
00220 mSmdSeedEnergy = ( seed_threshold + seed_slope * (etmax-4.5) ) / 1000.0;
00221 mSmdMinEnergy = 0.1 * mSmdSeedEnergy;
00222 }
00223 else {
00224 mSmdSeedEnergy = seed_threshold / 1000.0;
00225 mSmdMinEnergy = 0.1 * mSmdSeedEnergy;
00226 }
00227
00228 LOG_INFO<<GetName()<<" sector="<<sector<<" seed energy="<<mSmdSeedEnergy<<endm;
00229
00230 for ( Int_t plane=0;plane<2;plane++ )
00231 {
00232
00233
00234
00235 Int_t nstrips = (Int_t)mESmdGeom -> getEEmcSector( plane, sector ).stripPtrVec.size();
00236
00237
00238 Bool_t used[288]; for (Int_t i=0;i<288;i++ ) used[i]=false;
00239
00240
00241 Float_t floor[288]; for ( Int_t i=0;i<288;i++ ) floor[i]=0.;
00242
00243
00244 StEEmcStripVec_t strips=mEEanalysis->strips(sector,plane);
00245
00246 std::sort(strips.begin(),strips.end());
00247
00248 std::reverse(strips.begin(),strips.end());
00249
00250
00251 LOG_DEBUG << " sector=" << sector
00252 << " plane=" << plane
00253 << " nhit strips=" << strips.size()
00254 << endm;
00255
00256 StEEmcStripVec_t seeds;
00257
00258 Float_t emax_strip = 0.;
00259 for ( UInt_t i=0;i<strips.size();i++ )
00260 {
00261
00262
00263 Int_t myindex = strips[i].index();
00264
00265
00266 if ( strips[i].energy() < mSmdSeedEnergy ) break;
00267
00268
00269 if ( myindex < 4 || myindex > nstrips-4 ) continue;
00270
00271
00272 if ( strips[i].fail() ) continue;
00273
00274
00275 const StEEmcStrip *stripL = &mEEanalysis->strip(sector,plane,myindex-1);
00276 const StEEmcStrip *stripR = &mEEanalysis->strip(sector,plane,myindex+1);
00277 if ( stripL->fail() ) stripL=&mEEanalysis->strip(sector,plane,myindex-2);
00278 if ( stripR->fail() ) stripR=&mEEanalysis->strip(sector,plane,myindex+2);
00279 if ( stripL->energy() < mSmdMinEnergy || stripR->energy() < mSmdMinEnergy ) continue;
00280
00281
00282 seeds.push_back( strips[i] );
00283
00284 if ( strips[i].energy() > emax_strip )
00285 {
00286 emax_strip = strips[i].energy();
00287 }
00288
00289 }
00290
00291
00292
00293 LOG_DEBUG << " sector=" << sector
00294 << " plane=" << plane
00295 << " n seed strips=" << seeds.size()
00296 << endm;
00297
00298
00299
00300 StEEmcSmdClusterVec_t clusters;
00301
00302
00303 for ( UInt_t i=0;i<seeds.size(); i++ )
00304 {
00305
00306
00307 const StEEmcStrip &seed=seeds[i];
00308 Int_t myindex=seed.index();
00309
00310
00311
00312
00313 if ( used[myindex] ) continue;
00314 used[myindex]=true;
00315
00316
00317 if ( seed.energy() < mSmdSeedEnergy + floor[myindex] ) continue;
00318
00319 StEEmcSmdCluster cluster;
00320 cluster.add( seed );
00321
00322 Int_t break_inflection = 0;
00323
00324 Int_t break_energy = 0;
00325
00326
00327 for ( Int_t j=1;j<=mMaxExtent;j++ )
00328 {
00329
00330 Float_t ecluster = cluster.energy();
00331 Int_t fail_count = 0;
00332
00333 Int_t istrip;
00334
00335
00336
00337 istrip = myindex+j;
00338 if ( istrip < nstrips ) {
00339
00340 if ( used[istrip] ) break;
00341
00342 const StEEmcStrip &strip=mEEanalysis->strip(sector,plane,istrip);
00343 Float_t energy=strip.energy();
00344
00345
00346 if ( istrip > 1 && istrip < nstrips-1 ) {
00347 const StEEmcStrip &strip_left=mEEanalysis->strip(sector,plane,istrip-1);
00348 const StEEmcStrip &strip_right=mEEanalysis->strip(sector,plane,istrip+1);
00349 if ( strip_right.energy() > strip_left.energy() ) break_inflection++;
00350 }
00351
00352 if ( energy > mSmdMinEnergy )
00353 {
00354 if ( !strip.fail() ) {
00355 used[istrip]++;
00356 cluster.add(strip);
00357 }
00358 else
00359 fail_count++;
00360 }
00361 else
00362 break_energy++;
00363
00364
00365 }
00366
00367
00368
00369
00370
00371 istrip = myindex-j;
00372 if ( istrip >=0 ) {
00373
00374 if ( used[istrip] ) break;
00375
00376 const StEEmcStrip &strip=mEEanalysis->strip(sector,plane,istrip);
00377 Float_t energy=strip.energy();
00378
00379
00380 if ( istrip > 1 && istrip < nstrips-1 ) {
00381 const StEEmcStrip &strip_left=mEEanalysis->strip(sector,plane,istrip-1);
00382 const StEEmcStrip &strip_right=mEEanalysis->strip(sector,plane,istrip+1);
00383
00384 if ( strip_right.energy() < strip_left.energy() ) break_inflection++;
00385
00386 }
00387
00388 if ( energy > mSmdMinEnergy )
00389 {
00390 if ( !strip.fail() ) {
00391 used[istrip]++;
00392 cluster.add(strip);
00393 }
00394 else
00395 fail_count++;
00396 }
00397 else
00398 break_energy++;
00399
00400
00401 }
00402
00403 if ( break_energy ) break;
00404
00405
00406
00407
00408
00409 Float_t etruncate = ecluster;
00410 etruncate *= ( mTruncateRatio - ( mTruncateRatio-1.0 ) * ( fail_count ) );
00411 if ( cluster.energy() < etruncate && mBreakTruncation ) break;
00412
00413
00414
00415
00416 if ( mBreakInflection && break_inflection ) break;
00417
00418 }
00419
00420
00421
00422 if ( cluster.size() >= mMinStrips ) {
00423 add(cluster);
00424 LOG_INFO << " adding " << cluster << endm;
00425 Int_t index=seed.index();
00426
00427 for ( Int_t ii=index-3;ii<=index+3; ii++ )
00428 if ( ii>=0 && ii<288 ) used[ii]=1;
00429
00430
00431
00432 if ( mUseFloor )
00433 for ( Int_t ii=0;ii<288;ii++ )
00434 {
00435 Float_t f = mFloorParams[0] * cluster.energy() * TMath::Gaus( seed.index()-ii, 0., mFloorParams[1] * cluster.sigma(), true );
00436 floor[ii]+=f;
00437 }
00438
00439
00440 }
00441
00442 }
00443
00444
00445 }
00446 }
00447
00448
00449 return kStOK;
00450 }
00451
00452
00453
00454