00001 #include "StMyPointMaker.h"
00002
00003 #include "StMessMgr.h"
00004 #include <algorithm>
00005
00006 #include "StEEmcPool/StEEmcClusterMaker/StEEmcCluster.h"
00007 #include "StEEmcPool/StEEmcClusterMaker/StEEmcSmdCluster.h"
00008
00009 ClassImp(StMyPointMaker);
00010
00011
00012 StMyPointMaker::StMyPointMaker(const Char_t *name, const StEEmcA2EMaker *a2e, const StEEmcGenericClusterMaker *cl):
00013 StEEmcGenericPointMaker(name,a2e,cl)
00014 {
00015 mAllowSplitting=false;
00016 mSplitMinimumET=0.0;
00017 setSmdMinFraction(0.0);
00018 mMaxClusterId = 0;
00019 }
00020
00021
00022 Int_t StMyPointMaker::Init()
00023 {
00024
00025 return StEEmcGenericPointMaker::Init();
00026 }
00027
00028
00029 Int_t StMyPointMaker::Make()
00030 {
00031
00032 gMessMgr->Info() << GetName() << " -I- building points " << endm;
00033
00034 typedef StEEmcGenericClusterMaker::EEmatch EEmatch_t;
00035
00036 if (mEEclusters) mMaxClusterId = mEEclusters->maxClusterId();
00037
00039
00040
00041
00042
00044 for ( Int_t sector=0;sector<12;sector++ )
00045 {
00046
00047
00048 StEEmcClusterVec_t clusters = mEEclusters->clusters(sector, 0);
00049 std::sort( clusters.begin(), clusters.end() );
00050 std::reverse( clusters.begin(), clusters.end() );
00051
00052 LOG_INFO << GetName() << " sector "<<sector+1
00053 <<" nclusters="<<clusters.size()
00054 <<" nu="<<mEEclusters->numberOfClusters(sector,4)
00055 <<" nv=" <<mEEclusters->numberOfClusters(sector,5)
00056 << endm;
00057
00058
00059
00060
00061
00062 for ( UInt_t ic=0;ic<clusters.size();ic++ )
00063 {
00064
00065 StEEmcCluster cluster=clusters[ic];
00066 LOG_DEBUG<<GetName()<<" tower cluster at "<<cluster.tower(0).name()<<endm;
00067
00068 EEmatch_t matches = mEEclusters->clusterMatch( cluster );
00069
00070
00071
00072 StEEmcSmdClusterVec_t clusters1 =
00073 (matches.smdu.size()<matches.smdv.size()) ? matches.smdu : matches.smdv;
00074
00075
00076
00077 StEEmcSmdClusterVec_t clusters2 =
00078 (matches.smdu.size()<matches.smdv.size()) ? matches.smdv : matches.smdu;
00079
00080 if ( clusters1.size() == 0 ) continue;
00081 if ( clusters2.size() == 0 ) continue;
00082
00083
00084
00085
00086
00087
00088 AssociateClusters( clusters1, clusters2 );
00089
00090
00091
00092
00093 if ( mAllowSplitting && cluster.momentum().Perp() > mSplitMinimumET )
00094 {
00095 if ( SplitClusters( clusters1, clusters2 ) )
00096 {
00097 AssociateClusters( clusters1, clusters2 );
00098 }
00099 }
00100
00101
00102
00103
00104 StEEmcSmdClusterVec_t uclusters = ( clusters1[0].plane()==0 ) ? clusters1 : clusters2 ;
00105 StEEmcSmdClusterVec_t vclusters = ( clusters1[0].plane()==0 ) ? clusters2 : clusters1 ;
00106
00107
00108 UInt_t npoints = clusters1.size();
00109 for ( UInt_t ipoint = 0; ipoint < npoints; ipoint++ )
00110 {
00111
00112 StEEmcPoint p;
00113 p.cluster(cluster, 0 );
00114
00115 StEEmcSmdCluster u=uclusters[ipoint];
00116 StEEmcSmdCluster v=vclusters[ipoint];
00117 p.cluster( u, 0 );
00118 p.cluster( v, 1 );
00119
00120 Float_t energy = ( u.energy() + v.energy() ) / 0.014;
00121 p.energy( energy );
00122
00123 Float_t sigma = ( u.sigma() + v.sigma() ) / 2.0;
00124 p.sigma( sigma );
00125
00126 TVector3 position = mEEsmd->getIntersection( u.sector(), u.mean(), v.mean() );
00127 if ( position.Z() < 0. )
00128 {
00129 LOG_WARN<<GetName()<<" attempt to add point with invalid intersection: "<<Form(" X=%5.1f Y=%5.1f sec=%i %i u=%5.1f v=%5.1f",
00130 position.X(),position.Y(),u.sector(),v.sector(),u.mean(),v.mean())<<endm;
00131 continue;
00132 }
00133 p.position(position);
00134
00135
00136
00137
00138
00139
00140
00141 const StEEmcTower *tower = mEEanalysis->tower( position, 0 );
00142 if ( !tower )
00143 {
00144 LOG_WARN<<GetName()<<" attempt to add point which misses the EEMC towers: "<<Form(" X=%5.1f Y=%5.1f sec=%i %i u=%5.1f v=%5.1f",
00145 position.X(),position.Y(),u.sector(),v.sector(),u.mean(),v.mean())<<endm;
00146 continue;
00147 }
00148 p.tower(*tower);
00149
00150
00151
00152
00153
00154
00155
00156
00157 addSmdPoint( p );
00158
00159
00160
00161
00162
00163
00164
00165
00166 }
00167
00168
00169
00170 }
00171
00172
00173
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 Float_t sumw[720]; for ( Int_t ii=0;ii<720;ii++ ) sumw[ii]=0.;
00185 for ( Int_t ipoint=0;ipoint<numberOfSmdPoints();ipoint++ )
00186 {
00187
00188 StEEmcPoint point = smdPoint(ipoint);
00189 StEEmcTower tower = point.tower(0);
00190 sumw[ tower.index() ] += point.energy();
00191
00192 for ( Int_t jj=0;jj<tower.numberOfNeighbors();jj++ )
00193 {
00194 sumw[tower.neighbor(jj).index()] += point.energy();
00195 }
00196
00197 }
00198
00199
00200 for ( Int_t ipoint=0;ipoint<numberOfSmdPoints();ipoint++ )
00201 {
00202
00203 StEEmcPoint point = smdPoint(ipoint);
00204 StEEmcTower tower = point.tower(0);
00205 Float_t epoint = 0.;
00206 Float_t w = sumw[tower.index()];
00207 if ( !tower.fail() && w>0. ) epoint+=tower.energy() * point.energy()/w;
00208 for ( Int_t jj=0;jj<tower.numberOfNeighbors();jj++ )
00209 {
00210 StEEmcTower neighbor=tower.neighbor(jj);
00211 w = sumw[ neighbor.index() ];
00212 if ( !neighbor.fail() && w>0. ) epoint+=neighbor.energy() * point.energy()/w;
00213
00214 }
00215
00216 point.energy(epoint);
00217
00218
00219
00220
00221 Int_t index = tower.index();
00222 Float_t epre1 = mEEanalysis->tower(index,1).energy();
00223 Float_t epre2 = mEEanalysis->tower(index,2).energy();
00224 Float_t epost = mEEanalysis->tower(index,3).energy();
00225
00226 point.energy(epre1,1);
00227 point.energy(epre2,2);
00228 point.energy(epost,3);
00229
00230 addPoint( point );
00231
00232 }
00233
00234 return StEEmcGenericPointMaker::Make();
00235 }
00236
00237
00238 Bool_t StMyPointMaker::AssociateClusters( const StEEmcSmdClusterVec_t &list1, StEEmcSmdClusterVec_t &list2 )
00239 {
00240
00241
00242
00243
00244 if ( list1.size() == 1 && list2.size()==1 )
00245 return true;
00246
00247 if ( list1.size() > list2.size() )
00248 assert(2+2==5);
00249
00250 if ( list2.size() == 0 )
00251 return false;
00252
00253 LOG_DEBUG<<GetName()<<" associating smd clusters"<<endm;
00254
00255
00256
00257
00258
00259 std::vector<UInt_t> index1;
00260 std::vector<UInt_t> index2;
00261 for ( UInt_t i=0;i<list1.size();i++ ){ index1.push_back(i); }
00262 for ( UInt_t i=0;i<list2.size();i++ ){ index2.push_back(i); }
00263
00264 std::vector<UInt_t> best1;
00265 std::vector<UInt_t> best2;
00266
00267
00268
00269
00270 Bool_t go = true;
00271 Float_t ediff_min = 9.0E9;
00272
00273 Int_t count=0;
00274 while ( go )
00275 {
00276
00277 LOG_DEBUG<<GetName()<<" permutation = " << count++ << " ediff_min="<< ediff_min<< endm;
00278
00279
00280
00281 Float_t ediff_sum = 0.0;
00282 for ( UInt_t i=0;i<list1.size();i++ )
00283 {
00284
00285
00286 UInt_t i1 = index1[i];
00287 UInt_t i2 = index2[i];
00288 StEEmcSmdCluster cluster1 = list1[i1];
00289 StEEmcSmdCluster cluster2 = list2[i2];
00290
00291
00292 if ( cluster1.sector() != cluster2.sector() ) goto INVALID_PERM;
00293 if ( cluster1.plane () == cluster2.plane () ) goto INVALID_PERM;
00294
00295 Float_t mean1 = cluster1.mean();
00296 Float_t mean2 = cluster2.mean();
00297
00298 TVector3 hit = mEEsmd->getIntersection( cluster1.sector(), mean1, mean2 );
00299 if ( hit.Z() < -1.0 ) goto INVALID_PERM;
00300
00301 Float_t echi2 = energyChi2( cluster1, cluster2 );
00302 if ( echi2 < 0. ) goto INVALID_PERM;
00303
00304 ediff_sum += echi2;
00305
00306 }
00307
00308
00309 if ( ediff_sum < ediff_min )
00310 {
00311 best1 = index1;
00312 best2 = index2;
00313 ediff_min = ediff_sum;
00314 }
00315
00316
00317 INVALID_PERM:
00318 go = std::next_permutation( index2.begin(), index2.end() );
00319
00320 }
00321
00322
00323
00324
00325 if ( best1.size() == index1.size() )
00326 {
00327
00328 StEEmcSmdClusterVec_t temp2;
00329
00330 for ( UInt_t i=0;i<best2.size();i++ )
00331 {
00332
00333 temp2.push_back( list2[ best2[i] ] );
00334
00335 }
00336
00337 LOG_DEBUG<<GetName()<<Form(" ukey\tvkey\t\tvkey")<<endm;
00338 LOG_DEBUG<<GetName()<<Form(" \t(initial)\t(final)")<<endm;
00339 for ( UInt_t i=0;i<best1.size();i++ )
00340 {
00341 LOG_DEBUG<<GetName()<<Form(" %i\t%i\t\t%i", list1[i].key(), list2[i].key(), temp2[i].key() )<<endm;
00342 }
00343
00344 list2.clear();
00345 list2=temp2;
00346 return true;
00347
00348 }
00349
00350
00351
00352
00353
00354 return false;
00355
00356 }
00357
00358
00359 Bool_t StMyPointMaker::SplitClusters( StEEmcSmdClusterVec_t &list1,
00360 const StEEmcSmdClusterVec_t &list2 )
00361 {
00362
00363
00364
00365
00366
00367 if ( list2.size() != 2 ) return false;
00368
00369
00370
00371
00372 if ( list1.size() != 1 ) return false;
00373
00374
00375
00376
00377
00378 Float_t ediff12 = energyChi2( list1[0], list2[0] );
00379
00380
00381
00382
00383 Float_t ediff22 = energyChi2( list1[0], list2[0], list2[1] );
00384
00385
00386
00387
00388 if ( ediff12 <= ediff22 ) return false;
00389
00390 StEEmcSmdCluster tempa, tempb;
00391 Float_t chi2_a=9.0E9, chi2_b = 9.0E9;
00392
00393 StEEmcSmdCluster mergeda=list1[0];
00394 StEEmcSmdCluster mergedb=list1[0];
00395
00396 Bool_t a = split( list2[0], list2[1], mergeda, tempa, chi2_a );
00397 Bool_t b = split( list2[1], list2[0], mergedb, tempb, chi2_b );
00398
00399
00400 if ( a && b )
00401 {
00402 if ( chi2_a <= chi2_b ) {
00403 tempa.key( mMaxClusterId++ );
00404 mergeda.key( mMaxClusterId++ );
00405 list1[0]=mergeda;
00406 list1.push_back( tempa );
00407 return true;
00408 }
00409 else {
00410 tempb.key( mMaxClusterId++ );
00411 mergedb.key( mMaxClusterId++ );
00412 list1[0]=mergedb;
00413 list1.push_back( tempb );
00414 return true;
00415 }
00416
00417 }
00418
00419 else if ( a )
00420 {
00421 tempa.key( mMaxClusterId++ );
00422 mergeda.key( mMaxClusterId++ );
00423 list1[0]=mergeda;
00424 list1.push_back( tempa );
00425 return true;
00426 }
00427
00428 else if ( b )
00429 {
00430 tempb.key( mMaxClusterId++ );
00431 mergedb.key( mMaxClusterId++ );
00432 list1[0]=mergedb;
00433 list1.push_back( tempb );
00434 return true;
00435 }
00436
00437
00438
00439 return true;
00440 }
00441
00442
00443
00444 Float_t StMyPointMaker::energyChi2( const StEEmcSmdCluster &c1, const StEEmcSmdCluster &c2 ) const
00445 {
00446 Float_t e1 = c1.energy() * 1000.0;
00447 Float_t e2 = c2.energy() * 1000.0;
00448 Float_t esum = e1+e2;
00449 Float_t edif = e1-e2;
00450 Float_t nmip = esum/1.3;
00451 if ( esum <= 0. ) return -1.;
00452 return edif*edif/nmip;
00453 }
00454 Float_t StMyPointMaker::energyChi2( const StEEmcSmdCluster &c1, const StEEmcSmdCluster &c2, const StEEmcSmdCluster &c3 ) const
00455 {
00456 Float_t e1 = c1.energy() * 1000.0;
00457 Float_t e2 = c2.energy() * 1000.0;
00458 Float_t e3 = c3.energy() * 1000.0;
00459 Float_t esum = e1+e2+e3;
00460 Float_t edif = e1-e2-e3;
00461 Float_t nmip = esum/1.3;
00462 if ( esum <= 0. ) return -1.;
00463 return edif*edif/nmip;
00464 }
00465
00466
00467
00468 void StMyPointMaker::Clear(Option_t *opts)
00469 {
00470 return StEEmcGenericPointMaker::Clear(opts);
00471 }
00472
00473
00474 Bool_t StMyPointMaker::split( const StEEmcSmdCluster &in1,
00475 const StEEmcSmdCluster &in2,
00476 StEEmcSmdCluster &out1,
00477 StEEmcSmdCluster &out2,
00478 Float_t &chi2out
00479 )
00480 {
00481
00483 if ( in1.sector() != in2.sector() ) return false;
00484 if ( in1.plane() != in2.plane() ) return false;
00485 if ( in1.sector() != out1.sector() ) return false;
00486 if ( in1.plane() == out1.plane() ) return false;
00487
00489
00490
00491
00492
00493
00495 Int_t size = out1.size();
00496
00498 StEEmcStrip seed = out1.seed();
00499 Int_t id_min = seed.index() - size/2;
00500 Int_t id_max = seed.index() + size/2;
00501
00502
00514
00516 Int_t id_first = seed.index();
00517
00519 Int_t id_second = -1;
00520 Float_t min_chi2 = 9.0E9;
00521
00522 Float_t weight1[288]; for ( Int_t ii=0;ii<288;ii++ ) weight1[ii]=0.;
00523 Float_t weight2[288]; for ( Int_t ii=0;ii<288;ii++ ) weight2[ii]=0.;
00524
00526 for ( Int_t id_scan=id_min; id_scan<=id_max; id_scan++ )
00527 {
00528
00530 Float_t energy[288]; for ( Int_t ii=0;ii<288;ii++ ) energy[ii]=0.;
00531
00533 Int_t shift = seed.index() - in1.seed().index();
00534 for ( Int_t ii=0;ii<in1.size();ii++ )
00535 {
00536 StEEmcStrip strip = in1.strip(ii);
00537 Int_t index = strip.index() + shift;
00538 if ( index < 0 || index > 287 ) continue;
00539 energy[index] = strip.energy();
00540 }
00541
00543 shift = id_scan - in2.seed().index();
00544 for ( Int_t ii=0;ii<in2.size();ii++ )
00545 {
00546 StEEmcStrip strip = in2.strip(ii);
00547 Int_t index = strip.index() + shift;
00548 if ( index < 0 || index > 287 ) continue;
00549 energy[index] += strip.energy();
00550 }
00551
00552
00554 Float_t chi2 = 0.0;
00555 for ( Int_t ii=0;ii<size;ii++ )
00556 {
00557
00558 StEEmcStrip strip = out1.strip(ii);
00559 Int_t jj=strip.index();
00560 Float_t ediff = 1000.0 * ( strip.energy() - energy[jj] );
00561 Float_t esum = 1000.0 * ( strip.energy() + energy[jj] );
00562 Float_t nmip = esum / 1.3;
00563
00564 if ( nmip > 0. ) chi2+=ediff*ediff/nmip;
00565
00566 }
00567
00568 if ( chi2 < min_chi2 )
00569 {
00570
00571 min_chi2 = chi2;
00572 chi2out = chi2;
00573 id_second = id_scan;
00574
00575 }
00576
00577
00578 }
00579
00580
00581 if ( id_second < 0 ) return false;
00582
00583
00585 StEEmcSmdCluster my1, my2;
00586
00589 my1.key( out1.key() );
00590
00591 my2.key( mMaxClusterId++ );
00592
00593
00595 StEEmcStrip seed1 = mEEanalysis->strip( out1.sector(), out1.plane(), id_first );
00596 StEEmcStrip seed2 = mEEanalysis->strip( out1.sector(), out1.plane(), id_second );
00597
00598
00601 Float_t energy1[288], energy2[288];
00602 for ( Int_t ii=0;ii<288;ii++ ) { energy1[ii]=0.; energy2[ii]=0.; }
00603
00604 Int_t shift = id_first - in1.seed().index();
00605 for ( Int_t ii=0;ii<in1.size();ii++ )
00606 {
00607 StEEmcStrip strip=in1.strip(ii);
00608 Int_t index = strip.index() + shift;
00609 if ( !strip.fail() )
00610 energy1[index] = strip.energy();
00611 }
00612
00613 shift = id_second - in2.seed().index();
00614 for ( Int_t ii=0;ii<in2.size();ii++ )
00615 {
00616 StEEmcStrip strip=in2.strip(ii);
00617 Int_t index = strip.index()+shift;
00618 if ( !strip.fail() )
00619 energy2[index] = strip.energy();
00620 }
00621
00622
00624 {
00625 Float_t e1 = energy1[ seed1.index() ];
00626 Float_t e2 = energy2[ seed1.index() ];
00627 if ( e1==0. ) e1=0.5*( energy1[seed1.index()-1] + energy1[seed1.index()+1] );
00628 if ( e2==0. ) e2=0.5*( energy2[seed1.index()-1] + energy2[seed1.index()+1] );
00629 Float_t sumw = e1+e2;
00630 my1.add( seed1, e1/sumw );
00631 }
00632 {
00633 Float_t e1 = energy1[ seed2.index() ];
00634 Float_t e2 = energy2[ seed2.index() ];
00635 if ( e1==0. ) e1=0.5*( energy1[seed2.index()-1] + energy1[seed2.index()+1] );
00636 if ( e2==0. ) e2=0.5*( energy2[seed2.index()-1] + energy2[seed2.index()+1] );
00637 Float_t sumw = e1+e2;
00638 my2.add( seed2, e2/sumw );
00639 }
00640
00641 for ( Int_t ii=0;ii<out1.size();ii++ )
00642 {
00643
00644 StEEmcStrip strip = out1.strip(ii);
00645
00646 Float_t e1 = energy1[ strip.index() ];
00647 Float_t e2 = energy2[ strip.index() ];
00648 if ( e1==0. ) e1=0.5*( energy1[strip.index()-1] + energy1[strip.index()+1] );
00649 if ( e2==0. ) e2=0.5*( energy2[strip.index()-1] + energy2[strip.index()+1] );
00650
00651 Float_t sumw = e1+e2;
00652 if ( sumw==0. ) continue;
00653
00654 if ( strip.index() != seed1.index() ) my1.add( strip, e1/sumw );
00655 if ( strip.index() != seed2.index() ) my2.add( strip, e2/sumw );
00656
00657 }
00658
00659
00660 out1=my1;
00661 out2=my2;
00662
00663 return true;
00664
00665 }