00001 #include "MessageService/MsgService.h"
00002
00003 #include "NueAna/ParticlePID/ParticleFinder/Finder.h"
00004
00005 #include "NueAna/ParticlePID/ParticleFinder/Particle3D.h"
00006
00007 #include "NueAna/ParticlePID/ParticleFinder/ParticleType.h"
00008 #include "NueAna/ParticlePID/ParticleFinder/LongMuonFinder.h"
00009 #include "NueAna/ParticlePID/ParticleFinder/PrimaryShowerFinder.h"
00010 #include "Conventions/Detector.h"
00011
00012 #include "TPolyLine.h"
00013 #include "TMarker.h"
00014 #include "TMath.h"
00015 #include <algorithm>
00016
00017 #include <sstream>
00018 #include <math.h>
00019 #include "ShwFit.h"
00020
00021 #include <limits>
00022
00023
00024
00025
00026
00027 CVSID("$Id: Finder.cxx,v 1.9 2009/09/11 05:00:40 gmieg Exp $");
00028
00029
00030
00031
00032
00033
00034
00035 Finder::Finder(): vtx_u(0.0), vtx_v(0.0), vtx_z(0.0)
00036 {
00037
00038 sorter_map.clear();
00039 DoMRCC=0;
00040
00041
00042
00043
00044
00045
00046
00047 meupergev=0;
00048 }
00049
00050 Finder::~Finder()
00051 {
00052
00053 sorter_map.clear();
00054
00055
00056 }
00057
00058 void Finder::Reset()
00059 {
00060 sorter_map.clear();
00061
00062
00063 loc_map.clear();
00064 plane.clear();
00065 strip.clear();
00066 energy.clear();
00067 particles.clear();
00068 t.clear();
00069 z.clear();
00070 view.clear();
00071
00072
00073 true_vtx_u=0.0;
00074 true_vtx_v=0.0;
00075 true_vtx_z=0.0;
00076
00077
00078 vtx_u=0.0;
00079 vtx_v=0.0;
00080 vtx_z=0.0;
00081 shareholder.Reset();
00082 }
00083
00084
00085 void Finder::AddStrip(int myplane, int mystrip, double myenergy, double st, double sz, int myview)
00086 {
00087 mypoh->event.nstrips++;
00088
00089
00090 mypoh->strips.AddStrip(myplane,mystrip,myenergy,st,sz,myview);
00091
00092 plane.push_back(myplane);
00093 strip.push_back(mystrip);
00094 energy.push_back(myenergy);
00095 t.push_back(st);
00096 z.push_back(sz);
00097 view.push_back(myview);
00098
00099 mypoh->event.large_minz = (mypoh->event.large_minz < sz) ? mypoh->event.large_minz : sz;
00100 mypoh->event.large_maxz = (mypoh->event.large_maxz > sz) ? mypoh->event.large_maxz : sz;
00101 if(myview==2)
00102 {
00103 mypoh->event.large_minu = (mypoh->event.large_minu < st) ? mypoh->event.large_minu : st;
00104 mypoh->event.large_maxu = (mypoh->event.large_maxu > st) ? mypoh->event.large_maxu : st;
00105 }else if(myview==3){
00106 mypoh->event.large_minv = (mypoh->event.large_minv < st) ? mypoh->event.large_minv : st;
00107 mypoh->event.large_maxv = (mypoh->event.large_maxv > st) ? mypoh->event.large_maxv : st;
00108 }
00109
00110
00111
00112 sorter_map.insert(std::pair <double,int>(myenergy, (int)energy.size()-1))
00113 ;
00114
00115 loc_map[myplane][mystrip]=plane.size()-1;
00116
00117
00118
00119
00120 }
00121
00122
00123 void Finder::ClearXTalk()
00124 {
00125 printf("DONT USE Finder::ClearXTalk()!\n");
00126 exit(1);
00127
00128 double thresh = 3;
00129
00130 for(unsigned int i=0;i<plane.size();i++)
00131 {
00132 sorter_map.insert(std::pair <double,int>(energy[i],i));
00133 loc_map[plane[i]][strip[i]]=i;
00134 }
00135
00136
00137
00138 double reassignedxtalke=0.0;
00139
00140 int foundxtalk=0;
00141 std::map<int, std::map<int, int> >::iterator p_iter;
00142 for(p_iter=loc_map.begin();p_iter!=loc_map.end(); p_iter++)
00143 {
00144 std::map<int, int>::iterator s_iter;
00145 for(s_iter=p_iter->second.begin();s_iter!=p_iter->second.end(); s_iter++)
00146 {
00147 if (energy[s_iter->second]<thresh)continue;
00148
00149 std::map<int, int>::iterator s_iter2;
00150 for(s_iter2=p_iter->second.begin();s_iter2!=p_iter->second.end(); s_iter2++)
00151 {
00152 if(s_iter==s_iter2)continue;
00153 int sp=abs(s_iter->first-s_iter2->first);
00154
00155
00156 if( sp>9 && sp<14)
00157 {
00158 if(energy[s_iter2->second] < 0.3 * energy[s_iter->second])
00159 {
00160 reassignedxtalke+=energy[s_iter2->second];
00161
00162 energy[s_iter->second]+=energy[s_iter2->second];
00163 energy[s_iter2->second]=0.0;
00164 foundxtalk=1;
00165 }
00166 }
00167
00168 }
00169 }
00170 }
00171
00172
00173
00174
00175
00176 if(foundxtalk)
00177 {
00178 std::vector<int>tplane;
00179 std::vector<int>tstrip;
00180 std::vector<int>tview;
00181 std::vector<double>tt;
00182 std::vector<double>tz;
00183 std::vector<double>tenergy;
00184
00185
00186 for(unsigned int i=0;i<energy.size();i++)
00187 {
00188 if(energy[i]>0.001)
00189 {
00190 tplane.push_back(plane[i]);
00191 tstrip.push_back(strip[i]);
00192 tenergy.push_back(energy[i]);
00193 tt.push_back(t[i]);
00194 tz.push_back(z[i]);
00195 tview.push_back(view[i]);
00196 }
00197 }
00198
00199 plane=tplane;
00200 strip=tstrip;
00201 view=tview;
00202 t=tt;
00203 z=tz;
00204 energy=tenergy;
00205
00206 }
00207
00208
00209 sorter_map.clear();
00210 loc_map.clear();
00211
00212 }
00213
00214
00215
00216 void Finder::SetStatus(Chain *c, int status)
00217 {
00218
00219 for(unsigned int i=0;i<c->cluster_id.size();i++)
00220 {
00221 mypoh->clusterer.GetCluster(c->cluster_id[i])->SetStatus(status);
00222
00223 }
00224 }
00225
00226
00227 void Finder::Process(ParticleObjectHolder & p)
00228 {
00229 if(!meupergev)
00230 {
00231 cout <<"At Finder::Process... meupergev has not been set!\n";
00232 exit(1);
00233 }
00234
00235
00236 mypoh=&p;
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 mypoh->clusterer=clustermanager_v;
00258
00259
00260
00261
00262 mypoh->event.nclusters = mypoh->clusterer.clusters.size();
00263
00264
00265
00266 std::vector<Managed::ManagedCluster> clusters = mypoh->clusterer.clusters;
00267
00268
00269
00270
00271
00272
00273
00274
00275 mypoh->clusterer.FillClusterMap(&mypoh->cluster_map);
00276 mypoh->clusterer.FillClusterMap(&mypoh->cluster_map);
00277
00278
00279
00280 mypoh->clusterer.MakeClusters(0.02,0.05,0.01);
00281
00282 LongMuonFinder lmf(mypoh->GetHeader().GetVldContext().GetDetector());
00283 int foundlongmuon = lmf.FindLongMuon(&mypoh->clusterer);
00284
00285 int didMRCC=0;
00286
00287 if(foundlongmuon )
00288 {
00289 mypoh->eventquality.foundlongmuon=1;
00290 Particle3D *lp=lmf.GetParticle3D();
00291
00292 if(lp)
00293 {
00294 std::vector<Particle3D*> pout1;
00295 pout1.push_back(lp);
00296
00297 FinalizeParticles3D(pout1);
00298
00299 if(!DoMRCC)
00300 {
00301 for(unsigned int i=0;i<pout1.size();i++)
00302 {
00303 mypoh->AddParticle3D(*(pout1[i]));
00304 }
00305 }else{
00306 MRCCInfo * mrccinfo = mypoh->GetMRCCInfo();
00307 mrccinfo->removedmuon = *(pout1[0]);
00308 mrccinfo->stage=1;
00309 didMRCC=1;
00310
00311 }
00312 }
00313
00314
00315
00316 int cu = mypoh->chu.NewChain();
00317 Chain * tempcu = mypoh->chu.GetChain(cu);
00318 *tempcu = *lmf.GetChain(2);
00319
00320 int cv = mypoh->chv.NewChain();
00321 Chain * tempcv = mypoh->chv.GetChain(cv);
00322 *tempcv = *lmf.GetChain(3);
00323
00324 if(DoMRCC)
00325 {
00326 SetStatus(tempcu,-10);
00327 SetStatus(tempcv,-10);
00328 }
00329
00330 }
00331
00332
00333
00334 if(DoMRCC)foundlongmuon=0;
00335
00336 if(lmf.FoundSingleViewLongMuon())
00337 {
00338 mypoh->eventquality.single_view_long_muon=1;
00339
00340
00341 }
00342
00343
00344
00345
00346 mypoh->clusterer.MakeClusters(0.2,0.05,0.05);
00347
00348
00349 mypoh->clusterer.DumpClusters();
00350
00351 int foundprimaryshower =0;
00352
00353 PrimaryShowerFinder*psf = &mypoh->psf;
00354 psf->chu=&mypoh->chu;
00355 psf->chv=&mypoh->chv;
00356
00357
00358 if(foundlongmuon)
00359 {
00360 Particle3D *lp=lmf.GetParticle3D();
00361
00362
00363
00364 psf->SetVertex(lp->start_u, lp->start_v, lp->start_z);
00365 }
00366
00367 foundprimaryshower = psf->FindPrimaryShower(&mypoh->clusterer);
00368
00369
00370 if(foundprimaryshower)
00371 {
00372 mypoh->eventquality.foundprimaryshower=1;
00373
00374 Particle3D *lp=psf->GetParticle3D();
00375
00376 if(lp)
00377 {
00378 std::vector<Particle3D*> pout1;
00379 pout1.push_back(lp);
00380
00381 FinalizeParticles3D(pout1);
00382
00383
00384 if(!DoMRCC || (pout1.size()>0 && pout1[0]->particletype != Particle3D::muon) || didMRCC)
00385 {
00386 for(unsigned int i=0;i<pout1.size();i++)
00387 {
00388 mypoh->AddParticle3D(*(pout1[i]));
00389 }
00390 }else{
00391 MRCCInfo * mrccinfo = mypoh->GetMRCCInfo();
00392 mrccinfo->removedmuon = *(pout1[0]);
00393 mrccinfo->stage=2;
00394
00395 }
00396
00397 }
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 }
00411
00412
00413 if(psf->FoundSingleViewPrimaryShower())
00414 {
00415 mypoh->eventquality.single_view_primary_shower=1;
00416
00417
00418 }
00419
00420
00421
00422
00423
00424 if(foundprimaryshower)
00425 {
00426 Particle3D *lp=psf->GetParticle3D();
00427 vtx_u = lp->start_u;
00428 vtx_v = lp->start_v;
00429 vtx_z = lp->start_z;
00430 }
00431
00432
00433 if(foundlongmuon)
00434 {
00435 Particle3D *lp=lmf.GetParticle3D();
00436
00437 if(foundprimaryshower)
00438 {
00439 Particle3D *lpe=psf->GetParticle3D();
00440 if(lpe->start_z > lp->start_z)
00441 {
00442 vtx_u = lp->start_u;
00443 vtx_v = lp->start_v;
00444 vtx_z = lp->start_z;
00445 }
00446 }else{
00447 vtx_u = lp->start_u;
00448 vtx_v = lp->start_v;
00449 vtx_z = lp->start_z;
00450
00451 }
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00462
00463
00464
00465 MSG("Finder",Msg::kInfo) <<"----U----"<<endl;
00466
00467
00468
00469 ChainHelper * chu= &mypoh->chu;
00470
00471
00472
00473
00474
00475
00476 MSG("Finder",Msg::kInfo) <<"----V----"<<endl;
00477
00478 ChainHelper * chv= &mypoh->chv;
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 chu->print_finished();
00493 chv->print_finished();
00494
00495
00496
00497 MergeChains(chu);
00498 MergeChains(chv);
00499
00500
00501
00502
00503 FindVertex(chu,chv);
00504
00505
00506
00507 if(foundprimaryshower)
00508 {
00509 Particle3D *lp=psf->GetParticle3D();
00510 vtx_u = lp->start_u;
00511 vtx_v = lp->start_v;
00512 vtx_z = lp->start_z;
00513
00514 }
00515
00516
00517 if(foundlongmuon)
00518 {
00519 Particle3D *lp=lmf.GetParticle3D();
00520
00521 if(foundprimaryshower)
00522 {
00523 Particle3D *lpe=psf->GetParticle3D();
00524 if(lpe->start_z > lp->start_z)
00525 {
00526 vtx_u = lp->start_u;
00527 vtx_v = lp->start_v;
00528 vtx_z = lp->start_z;
00529 }
00530 }else{
00531
00532 vtx_u = lp->start_u;
00533 vtx_v = lp->start_v;
00534 vtx_z = lp->start_z;
00535 }
00536 }
00537
00538
00539 MSG("Finder",Msg::kInfo) << "vertex at (u,v,z) ("<< vtx_u <<", "<< vtx_v <<", "<< vtx_z <<")"<<endl;
00540 MSG("Finder",Msg::kInfo) << "true vertex at (u,v,z) ("<<true_vtx_u <<", "<< true_vtx_v <<", "<< true_vtx_z <<")"<<endl;
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 chu->print_finished();
00551 chv->print_finished();
00552
00553
00554
00555
00556 Weave(chu,chv);
00557
00558
00559
00560 std::vector<Particle3D * > p3d;
00561
00562
00563
00564
00565 p3d.clear();
00566 for(unsigned int i=0;i<mypoh->particles3d.size();i++)
00567 p3d.push_back(&mypoh->particles3d[i]);
00568
00569 DumpParticle3D(p3d);
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 mypoh->cluster_saver.recomputeBounds();
00586 mypoh->event.minu=mypoh->cluster_saver.minu;
00587 mypoh->event.maxu=mypoh->cluster_saver.maxu;
00588 mypoh->event.minv=mypoh->cluster_saver.minv;
00589 mypoh->event.maxv=mypoh->cluster_saver.maxv;
00590
00591 mypoh->event.minz=mypoh->cluster_saver.minz;
00592 mypoh->event.maxz=mypoh->cluster_saver.maxz;
00593
00594
00595
00596 std::map<std::pair<int,int>, double> stripmap =mypoh->cluster_saver.GetStripEnergy();
00597 std::map<std::pair<int,int>, double>::iterator it;
00598
00599 int stripcount=0;
00600 double stripe=0;
00601
00602 for(it = stripmap.begin();it!=stripmap.end();it++)
00603 {
00604 if(it->second<1e-6)continue;
00605 stripcount++;
00606 stripe+=it->second;
00607
00608 }
00609
00610 double olde = mypoh->event.visenergy;
00611 mypoh->event.nstrips=stripcount;
00612 mypoh->event.visenergy=stripe;
00613 mypoh->event.nclusters = mypoh->cluster_saver.nClusters;
00614
00615
00616
00617
00618
00619 if(stripe - olde > 1)
00620 {
00621 MSG("Finder",Msg::kError) << "Event Energy MISMATCH! Strip SumE = "<<olde<<" new ClusterSaver Energy "<<stripe<<"\n";
00622
00623 }
00624 }
00625
00626
00627
00628 void Finder::MergeChains(ChainHelper *ch)
00629 {
00630
00631 std::vector<std::pair<int,int> >match;
00632
00633
00634 for(int i=0;i<(int)ch->finished.size();i++)
00635 {
00636 if(ch->finished[i].parentChain>-1)continue;
00637 if(ch->finished[i].entries<2)continue;
00638
00639
00640 double bestdist=10000;
00641
00642 int bestid=-1;
00643 double bestzdist=10000;
00644
00645
00646 for(int j=0;j<(int)ch->finished.size();j++)
00647 {
00648 if(i==j)continue;
00649 if(ch->finished[j].children.size()>0)continue;
00650 if(ch->finished[j].entries<2)continue;
00651
00652 Chain *e = &ch->finished[j];
00653 Chain *b = &ch->finished[i];
00654
00655 if(b->start_z-e->end_z < 0.035*2)continue;
00656
00657
00658 double d = e->end_t - (e->end_z * b->front_slope + b->front_offset);
00659
00660
00661
00662
00663
00664
00665
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00690
00691
00692
00693
00694
00695 double totdist = sqrt( d*d + (e->end_z-b->start_z)*(e->end_z-b->start_z));
00696
00697 double zdist = fabs(e->end_z-b->start_z);
00698 if(totdist<bestdist || zdist < bestzdist)
00699 {
00700 int points=0;
00701 double canslope=b->front_slope;
00702 double canoffset=b->front_offset;
00703 double vpslope=e->back_slope;
00704 double vpoffset=e->back_offset;
00705 double t = 0;
00706 double z = 0;
00707
00708 if(canslope-vpslope>1e-10)
00709 {
00710 t = ( vpoffset * canslope - vpslope *canoffset ) / (canslope - vpslope);
00711 z = (canoffset - vpoffset) / (vpslope - canslope);
00712 }else{
00713 continue;
00714 }
00715
00716
00717
00718 if(fabs(e->back_slope - b->front_slope)<0.5)points=1;
00719
00720
00721
00722
00723 double maxtotdist=0.5;
00724 if(mypoh->GetHeader().GetVldContext().GetDetector() == Detector::kFar && fabs(e->end_z - 14.6)<0.2 && fabs(b->start_z-16)<0.2)maxtotdist+=16-14.6;
00725
00726
00727 if(mypoh->GetHeader().GetVldContext().GetDetector() == Detector::kNear && e->end_z >6 && b->start_z>6)maxtotdist*=4.;
00728
00729
00730
00731 if(points)
00732 {
00733 if((e->end_z-b->start_z)==0)continue;
00734 double connecting_slope = (e->end_t-b->start_t) / (e->end_z-b->start_z);
00735
00736 if(fabs(connecting_slope - b->front_slope)>=0.5)points=0;
00737 if(fabs(e->back_slope - connecting_slope)>=0.5)points=0;
00738 }
00739
00740
00741
00742 if(!points )
00743 {
00744 MSG("Finder",Msg::kDebug) << "failing on points "<<e->myId <<" to "<< b->myId<<" totdist "<< totdist<<" zdist "<<zdist <<" tdist "<<d <<" intersection at z t"<<z<<" "<<t<<"\n";
00745 continue;
00746 }
00747
00748
00749
00750 bestdist=totdist;
00751 bestid=e->myId;
00752 bestzdist=zdist;
00753
00754 MSG("Finder",Msg::kDebug) << "found better match "<<e->myId <<" to "<< b->myId<<" totdist "<< totdist<<" zdist "<<zdist <<" tdist "<<d <<"\n";
00755
00756 }
00757 }
00758
00759
00760
00761
00762 if(bestid>-1)
00763 {
00764 match.push_back(std::pair<int,int>(bestid,ch->finished[i].myId));
00765
00766 MSG("Finder",Msg::kDebug) <<"!!!matched "<<bestid<<" "<<ch->finished[i].myId<<"\n";
00767
00768 }
00769 }
00770
00771
00772 for(int i=0;i<(int)match.size();i++)
00773 {
00774 ch->AttachAsChild(ch->GetChain(match[i].first),ch->GetChain(match[i].second));
00775
00776 }
00777
00778
00779
00780 }
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 void Finder::RemoveNonVertexPointingChains(ChainHelper *ch, int view)
00794 {
00795
00796 double max_dt = 0.1;
00797
00798 double vt =0.0;
00799 if(view==2) vt=vtx_u;
00800 if(view==3) vt=vtx_v;
00801
00802
00803 std::vector<int> marked;
00804 std::vector<int> vtxpointing;
00805 std::vector<int> head;
00806
00807
00808
00809 for(unsigned int i=0;i<ch->finished.size();i++)
00810 {
00811 ostringstream os;
00812
00813
00814
00815
00816
00817
00818
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 int close_enough=0;
00841 double diff = fabs(vt - (ch->finished[i].front_slope * vtx_z + ch->finished[i].front_offset) );
00842 close_enough = max_dt > diff;
00843
00844 os << "Chain id " << ch->finished[i].myId << " entries: " << ch->finished[i].entries<< " extrap posvtx: " << ch->finished[i].front_slope * vtx_z + ch->finished[i].front_offset << " vtxt " << vt<<" diff "<<diff<<endl;
00845
00846
00847 diff = fabs(vt - ch->finished[i].interpolate(vtx_z) );
00848 if(!close_enough)close_enough = max_dt > diff;
00849
00850 os << "Chain id " << ch->finished[i].myId << " entries: " << ch->finished[i].entries<< " extrap posvtx: " << ch->finished[i].interpolate(vtx_z) << " vtxt " << vt<<" diff "<<diff<<endl;
00851
00852
00853 diff = fabs(vt - (ch->finished[i].avg_slope * vtx_z + ch->finished[i].avg_offset) );
00854 if(!close_enough)close_enough = max_dt > diff;
00855
00856
00857
00858
00859 os << "Chain id " << ch->finished[i].myId << " entries: " << ch->finished[i].entries<< " extrap posvtx: " << (ch->finished[i].avg_slope * vtx_z + ch->finished[i].avg_offset) << " vtxt " << vt <<" diff "<<diff;
00860
00861 if(ch->finished[i].entries>1)
00862 if(ch->finished[i].parentChain<0 || (ch->finished[i].level==1 && ch->GetChain(ch->finished[i].parentChain)->entries==1) )
00863 if(!close_enough)
00864 {
00865
00866
00867 marked.push_back(ch->finished[i].myId);
00868
00869 os << " not pointing to vertex ";
00870
00871 }else{
00872 vtxpointing.push_back(ch->finished[i].myId);
00873 }
00874 MSG("Finder",Msg::kInfo) << os.str() << endl;
00875
00876
00877 }
00878
00879
00880 std::vector<int> todel;
00881
00882 for (unsigned int i=0;i<marked.size();i++)
00883 {
00884
00885
00886
00887 Chain * can = ch->GetChain(marked[i]);
00888
00889 if(can->entries<2)continue;
00890
00891
00892 double bestdist = 100000;
00893 int bestpid = -1;
00894 double attachpoint=0;
00895
00896 for(unsigned int j=0;j<vtxpointing.size();j++)
00897 {
00898
00899
00900 Chain *vp = ch->GetChain(vtxpointing[j]);
00901
00902 if(vp->entries<2)continue;
00903
00904
00905 if(fabs(vp->a - can->a) < 0.000001)continue;
00906
00907 if(can->start_z < vp->start_z)continue;
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917 double canslope=can->front_slope;
00918 double canoffset=can->front_offset;
00919 double vpslope=vp->front_slope;
00920 double vpoffset=vp->front_offset;
00921
00922
00923 double t = ( vpoffset * canslope - vpslope *canoffset ) / (canslope - vpslope);
00924 double z = (canoffset - vpoffset) / (vpslope - canslope);
00925
00926
00927
00928
00929
00930
00931
00932
00933 if( z > vp->start_z && z < can->start_z)
00934 {
00935
00936
00937
00938 double bd = bestdist+1 ;
00939
00940 attachpoint =z;
00941
00942 if( z < vp->end_z)
00943 {
00944
00945 bd = sqrt ( (can->start_z-z)*(can->start_z-z) + (can->start_t - t)*(can->start_t - t));
00946 bestpid = vp->myId;
00947
00948 }else{
00949
00950 bd = sqrt ( (vp->end_z-can->start_z)*(vp->end_z-can->start_z) + (vp->end_t - can->start_t)*(vp->end_t - can->start_t));
00951 }
00952 if(bd<bestdist)
00953 {
00954 bestdist=bd;
00955 bestpid = vp->myId;
00956 }
00957 }
00958 }
00959
00960
00961
00962
00963
00964 if(bestpid>-1)
00965 {
00966 if(attachpoint < ch->GetChain(bestpid)->end_z)
00967 {
00968 Chain * np = ch->SplitAt(ch->GetChain(bestpid),attachpoint);
00969
00970 ch->AttachAsChild(np,can);
00971
00972
00973
00974 }else{
00975
00976 ch->AttachAsChild(ch->GetChain(bestpid),can);
00977
00978
00979 }
00980 }else{
00981 todel.push_back(marked[i]);
00982 }
00983 }
00984
00985
00986
00987
00988
00989 for(unsigned int i=0;i<todel.size();i++)
00990 ch->DeleteChain(todel[i]);
00991
00992
00993
00994
00995 ostringstream os;
00996 os << "remaing chains: ";
00997 for(unsigned int i=0;i<ch->finished.size();i++)
00998 {
00999 os << ch->finished[i].myId<< " ";
01000 }
01001
01002 MSG("Finder",Msg::kInfo) << os.str() << endl;
01003 }
01004
01005
01006
01007
01008
01009 void Finder::FindMuons(ChainHelper *ch)
01010 {
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020 std::vector<int> path = ch->FindMaxPath();
01021 if(path.size()<1)return;
01022
01023
01024 std::vector< std::pair<int,int> > muonlike;
01025 std::vector<double> muonlikee;
01026
01027 int lastconsec=0;
01028
01029 double avgmuon=0;
01030 int amuon=0;
01031
01032 for(int i=0;i<(int)path.size();i++)
01033 {
01034
01035 MSG("Finder",Msg::kDebug) <<"path chain "<<path[i]<<endl;
01036 int head=(i>0)?1:0;
01037 for(int j=head;j<ch->GetChain(path[i])->entries;j++)
01038 {
01039 double e = ch->GetChain(path[i])->e[j];
01040 if(e<2 && e>0.5){
01041 if((i!=(int)path.size()-1 || j!=ch->GetChain(path[i])->entries-1) || amuon>0)
01042
01043
01044 {
01045 muonlike.push_back(std::make_pair(path[i],j));
01046 muonlikee.push_back(e);
01047 avgmuon+=e;
01048 amuon++;
01049 lastconsec++;
01050 }
01051
01052 }else{
01053
01054 if(i==(int)path.size()-1 && j>0)
01055 if(e<6.0*ch->GetChain(path[i])->e[j-1])
01056 {
01057 if(lastconsec>0)
01058 {
01059 muonlike.push_back(std::make_pair(path[i],j));
01060 muonlikee.push_back(e);
01061 }
01062 }else{
01063 lastconsec=0;
01064 }
01065 }
01066 }
01067 }
01068
01069 if(amuon==0)return;
01070
01071
01072 avgmuon/=amuon;
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086 int cid = ch->NewChain();
01087 Chain * c = ch->GetChain(cid);
01088
01089
01090
01091
01092
01093 for(unsigned int i=0;i<path.size();i++)
01094 {
01095 int head=i>0?1:0;
01096
01097 Chain * d = ch->GetChain(path[i]);
01098
01099 if(d==0)
01100 {
01101 MSG("Finder",Msg::kError) <<"Bad path chain used - chain id "<<path[i]<<endl;
01102 continue;
01103
01104 }
01105
01106 for(int j=head;j<d->entries;j++)
01107 {
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135 int found =0;
01136 double e=0;
01137 for(unsigned int k=0;k<muonlike.size();k++)
01138 {
01139 if(muonlike[k].first==path[i] && muonlike[k].second==j)
01140 {
01141 e= muonlikee[k];
01142 found=1;
01143 break;
01144 }
01145 }
01146 if(found)
01147 {
01148
01149 d->e[j]=0;
01150 }else{
01151 e=avgmuon;
01152 d->e[j]-=avgmuon;
01153 }
01154
01155
01156
01157 if(e>0)
01158 { c->add_to_back(d->t[j],d->z[j],e,-1);
01159 MSG("Finder",Msg::kDebug) <<"muon adding "<< path[i] <<", "<< j<<" energy "<<e <<endl;
01160 }
01161 }
01162
01163
01164 d->Recalc();
01165 }
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180 c->particletype=Particle3D::muon;
01181
01182
01183
01184 ch->particles.push_back(*c);
01185 delete c;
01186
01187 }
01188
01189
01190
01191 void Finder::MakeChains(Managed::ClusterManager *cl, ChainHelper * ch, int view)
01192 {
01193
01194 if(mypoh->event.vtx_z>0)
01195 {
01196 ch->vtx_z=mypoh->event.vtx_z;
01197 ch->vtx_t=view==2?mypoh->event.vtx_u:mypoh->event.vtx_v;
01198
01199 }
01200
01201
01202 std::map<double, std::map<double, int> >::iterator p_iterr;
01203 std::map<double, int >::iterator s_iterr;
01204
01205 double lastz=-1;
01206 for(p_iterr=cl->GetClusterMap(view)->begin();p_iterr!=cl->GetClusterMap(view)->end(); p_iterr++)
01207 {
01208
01209 if(lastz==-1)lastz=p_iterr->first;
01210
01211
01212 if(fabs(p_iterr->first - lastz) > 0.01)
01213 {
01214 ch->process_plane();
01215 lastz=p_iterr->first;
01216
01217 }
01218
01219
01220 for(s_iterr=p_iterr->second.begin();s_iterr!=p_iterr->second.end(); s_iterr++)
01221 {
01222
01223
01224 Managed::ManagedCluster * c = cl->GetCluster(s_iterr->second);
01225 if(!c)
01226 {
01227
01228 continue;
01229 }
01230
01231 ch->add_to_plane(s_iterr->first, p_iterr->first, c->e,c->id);
01232 }
01233
01234
01235 }
01236
01237 ch->process_plane();
01238
01239 ch->finish();
01240 ch->print_finished();
01241 ch->FindMaxPath();
01242
01243 }
01244
01245
01246 void Finder::FindVertex(ChainHelper * cu, ChainHelper * cv)
01247 {
01248 std::vector<int> mpu = cu->FindMaxPath();
01249 std::vector<int> mpv = cv->FindMaxPath();
01250
01251 if(mpu.size() <1 || mpv.size() <1)return;
01252
01253
01254 double cu_t = cu->GetChain(mpu[0])->start_t;
01255 double cu_z = cu->GetChain(mpu[0])->start_z;
01256
01257 double cv_t = cv->GetChain(mpv[0])->start_t;
01258 double cv_z = cv->GetChain(mpv[0])->start_z;
01259
01260
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271 MSG("Finder",Msg::kDebug)<< "cuz " << cu_z <<" cvz "<< cv_z <<endl;
01272
01273
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293 if(cv_z<cu_z)
01294 cu_z=cv_z;
01295 else
01296 cv_z=cu_z;
01297
01298
01299 int chuid=0;
01300
01301
01302 for(unsigned int i=0;i<mpu.size();i++)
01303 {
01304 if ( ( cu->GetChain(mpu[i])->start_z <= cu_z && cu->GetChain(mpu[i])->end_z >= cu_z )
01305 || (cu->GetChain(mpu[i])->start_z >= cu_z && cu->GetChain(mpu[i])->end_z <= cu_z))
01306 {
01307 chuid=i;
01308
01309 }
01310 }
01311
01312 if(cu->GetChain(mpu[0])->entries<2 && mpu.size()>1)chuid=1;
01313
01314
01315 int chvid=0;
01316
01317
01318 for(unsigned int i=0;i<mpv.size();i++)
01319 {
01320 if ( ( cv->GetChain(mpv[i])->start_z <= cv_z && cv->GetChain(mpv[i])->end_z >= cv_z )
01321 || (cv->GetChain(mpv[i])->start_z >= cv_z && cv->GetChain(mpv[i])->end_z <= cv_z))
01322 {
01323 chvid=i;
01324
01325 }
01326 }
01327
01328 if(cv->GetChain(mpv[0])->entries<2 && mpv.size()>1)chvid=1;
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338 Chain * uuu = cu->GetChain(mpu[chuid]);
01339 Chain * vvv = cv->GetChain(mpv[chvid]);
01340
01341
01342
01343 cu_z = uuu->start_z;
01344 cv_z = vvv->start_z;
01345
01346 if(cv_z<cu_z)
01347 {
01348 cu_z=cv_z;
01349 }
01350 else
01351 {
01352 cv_z=cu_z;
01353
01354 }
01355
01356
01357 double tmpuz=0;
01358 double tmpvz=0;
01359
01360
01361
01362
01363
01364
01365
01366 if(uuu->entries>1 && uuu->e[0] < uuu->e[1]*0.2 )
01367 {
01368
01369
01370 tmpuz=uuu->z[1];
01371 cu_z=uuu->z[1];
01372 }
01373 else if(uuu->entries>2 && uuu->e[1] < uuu->e[2]*0.2 )
01374 {
01375
01376
01377 tmpuz=uuu->z[2];
01378 cu_z=uuu->z[1];
01379 }
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397 if(vvv->entries>1 && vvv->e[0] < vvv->e[1]*0.2 )
01398 {
01399
01400
01401 tmpvz=vvv->z[1];
01402 cv_z=vvv->z[1];
01403 }
01404 else if(vvv->entries>2 && vvv->e[1] < vvv->e[2]*0.2 )
01405 {
01406
01407
01408 tmpvz=vvv->z[2];
01409 cv_z=vvv->z[2];
01410 }
01411
01412
01413
01414
01416
01417
01418 vtx_z=cu_z<cv_z?cu_z:cv_z;
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429 if(fabs(vtx_z-uuu->z[0])<0.01)
01430 {
01431 cu_t = uuu->t[0];
01432 }else{
01433
01434 double oldcut=cu_t;
01435
01437
01438 cu_t = uuu->interpolate(vtx_z);
01439
01440
01441 MSG("Finder",Msg::kDebug) << "using chain "<< mpu[chuid]<<" "<<cu->GetChain(mpu[chuid])->myId <<" for slope, moving ut from "<< oldcut <<" to "<< cu_t <<endl;
01442 }
01443
01444
01445 if(fabs(vtx_z-vvv->z[0])<0.01)
01446 {
01447 cv_t = vvv->t[0];
01448 }else{
01449
01450 double oldcut=cv_t;
01451
01452
01453
01454
01455 cv_t = vvv->interpolate(vtx_z);
01456
01457
01458 MSG("Finder",Msg::kDebug) << "using chain "<< mpv[chvid]<<" "<<cv->GetChain(mpv[chvid])->myId <<" for slope, moving ut from "<< oldcut <<" to "<< cv_t <<endl;
01459 }
01460
01461
01462
01463
01464
01465
01466
01467
01468 for(int q=0;q<2;q++)
01469 {
01470
01471 ChainHelper * ch = q==0? cu:cv;
01472
01473 for(unsigned int i=0;i<ch->finished.size();i++)
01474 {
01475 if(ch->finished[i].start_z > vtx_z) continue;
01476 std::vector<foundpath> paths = ch->FindPaths(ch->GetChain(ch->finished[i].myId));
01477
01478
01479 for(unsigned int p =0;p<paths.size();p++)
01480 {
01481
01482
01483 if(! ( paths[p].start_z < vtx_z - 0.04 && paths[p].end_z > vtx_z + 0.04) )break;
01484
01485 int getp=-1;
01486 for(unsigned int j=0;j<paths[p].path.size();j++)
01487 {
01488 getp = paths[p].path[j];
01489 if(ch->GetChain(getp)->start_z < vtx_z -0.03 && ch->GetChain(getp)->end_z >= vtx_z+0.03)break;
01490 getp=-1;
01491 }
01492 if(getp<0)continue;
01493
01494
01495
01496
01497 Chain * m = ch->GetChain(getp);
01498
01499
01500 int pt_bef=-1;
01501 int pt_aft=-1;
01502 for(int j=1;j<m->entries;j++)
01503 {
01504 if(m->z[j-1]<=vtx_z && m->z[j]>=vtx_z)
01505 {
01506 pt_bef=j-1;
01507 pt_aft=j;
01508 break;
01509 }
01510 }
01511
01512
01513
01514 if(pt_bef>-1 && pt_aft>-1)
01515 {
01516 double dt = m->t[pt_aft]-m->t[pt_bef];
01517 double dz = m->z[pt_aft]-m->z[pt_bef];
01518
01519
01520
01521 double vt=0;
01522 if(dt<0.0001)vt=m->t[pt_aft];
01523
01524 else vt = (vtx_z-m->z[pt_bef]) * dt/dz + m->t[pt_bef];
01525
01526 double oldt = q==0?cu_t:cv_t;
01527
01528
01529
01530 if(fabs(oldt-vt)<0.05)
01531 {
01532 if(q==0)cu_t=vt;
01533 if(q==1)cv_t=vt;
01534 }
01535 }
01536
01537
01538
01539 Chain * d = ch->SplitAt(m,vtx_z);
01540
01541 if(d->children.size()<1)continue;
01542
01543
01544 d->level=0;
01545 for(unsigned int chi =0;chi<d->children.size();chi++)
01546 {
01547 Chain * cld = ch->GetChain(d->children[chi]);
01548 if(cld){
01549 cld->parentChain=-1;
01550 }
01551 }
01552
01553 Chain*p = ch->GetChain(d->parentChain);
01554 if(p){
01555 for(unsigned int i=0;i<p->children.size();i++)
01556 {
01557 if(p->children[i]==d->myId)
01558 {
01559 p->children.erase(p->children.begin()+i);
01560
01561
01562
01563 break;
01564 }
01565 }
01566 }
01567 d->parentChain=-1;
01568
01569 d->children.clear();
01570 d->Reverse();
01571
01572 }
01573
01574 }
01575
01576
01577 }
01578
01579
01580
01581
01582
01583 vtx_u=cu_t;
01584 vtx_v=cv_t;
01585
01586 }
01587
01588
01589
01590
01591 void Finder::FindIsolatedHits()
01592 {
01593
01594 printf("dont use Finder::FindIsolatedHits()\n");
01595 exit(1);
01596
01597 double minthreshold = 0.5;
01598 double peakfraction = 0.85;
01599
01600
01601
01602
01603
01604
01605 for(std::multimap<double,int>::reverse_iterator iter = sorter_map.rbegin(); iter!=sorter_map.rend();iter++)
01606 {
01607
01608
01609
01610 int maxi=-1;
01611 double maxe=0;
01612
01613 int p=0;
01614 int c=0;
01615
01616 double st=0;
01617 double sz=0;
01618
01619
01620
01621 double locale=iter->first;
01622
01623 maxi = iter->second;
01624 int i = maxi;
01625 maxe=energy[i];
01626 p=plane[i];
01627 c=strip[i];
01628 st=t[i];
01629 sz=z[i];
01630 MSG("Finder",Msg::kDebug) <<"isolated hit peak at plane, cell " << p << " "<< c << " with energy " << maxe <<endl;
01631
01632
01633
01634 if(maxe<minthreshold)break;
01635
01636
01637
01638
01639 for(unsigned int i=0;i<plane.size();i++)
01640 {
01641
01642
01643
01644 if(plane[i]==p && abs(strip[i]-c)==1)locale+=energy[i];
01645
01646
01647 }
01648
01649
01650
01651 MSG("Finder",Msg::kDebug) << "peak "<< maxe/locale << " "<< maxe << " "<< p << " "<< sz << " " << sz/(1.0*p) <<endl;
01652 if(maxe/locale>peakfraction)
01653 {
01654 Particle ptemp;
01655 ptemp.begPlane=p;
01656 ptemp.endPlane=p;
01657 ptemp.begStrip=c;
01658 ptemp.endStrip=c;
01659 ptemp.stripEnergy=maxe - (locale-maxe) /4;
01660 ptemp.type=2112;
01661 ptemp.endz=sz;
01662 ptemp.begz=sz;
01663 ptemp.endt=st;
01664 ptemp.begt=st;
01665
01666 ptemp.plane.push_back(p);
01667 ptemp.strip.push_back(c);
01668 ptemp.energy.push_back(ptemp.stripEnergy);
01669
01670
01671
01672 MSG("Finder",Msg::kDebug) <<"p at "<< p <<" "<< c <<" "<< st <<" "<< sz<<endl;
01673
01674 particles.push_back(ptemp);
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685 }else{continue;}
01686
01687
01688 }
01689
01690
01691 }
01692
01693
01694
01695 std::vector<std::pair<int,int> > Finder::matchViews(std::vector<foundpath> pu, std::vector<foundpath> pv)
01696 {
01697 std::vector<std::pair<int,int> >matches;
01698
01699
01700 for(unsigned int i=0;i<pu.size();i++)
01701 {
01702
01703 std::vector<std::pair<int,int> >zmatches;
01704
01705 MSG("Finder",Msg::kDebug) <<"--- "<<i<<endl;
01706
01707
01708
01709 std::vector<double> zoverlap;
01710
01711 for(unsigned int j=0;j<pv.size();j++)
01712 {
01713
01714 MSG("Finder",Msg::kDebug) <<"----- "<<j<<endl;
01715
01716
01717
01718 if((pu[i].entries==1 && pv[j].entries>2 )|| (pu[i].entries>2 && pv[j].entries==1 ))
01719 {
01720
01721 zoverlap.push_back(0.0);
01722 continue;
01723 }
01724
01725
01726 MSG("Finder",Msg::kDebug)<< "looking at "<<i << " "<<j<<endl;
01727 MSG("Finder",Msg::kDebug) << " pu ent " << pu[i].entries << " pv ent " << pv[j].entries<<endl;
01728
01729
01730 double o=0.0;
01731 if(pu[i].start_z>pv[j].end_z || pu[i].end_z < pv[j].start_z)
01732 {
01733 zoverlap.push_back(o);
01734
01735 MSG("Finder",Msg::kDebug) << "no overlap " << pu[i].start_z << " to " << pu[i].end_z << " vs " << pv[j].start_z << " to "<< pv[j].end_z <<endl;
01736
01737
01738 }else{
01739
01740 double start = pu[i].start_z < pv[j].start_z ? pv[j].start_z : pu[i].start_z;
01741 double end = pu[i].end_z< pv[j].end_z ? pu[i].end_z : pv[j].end_z;
01742
01743 o = fabs(end-start);
01744
01745 double sm1= fabs(pu[i].end_z - pu[i].start_z);
01746 double sm2= fabs(pv[j].end_z - pv[j].start_z);
01747 double sm=0;
01748 sm = sm1 > 0 ? sm1 : sm;
01749 sm = sm2 > 0 && (sm2 < sm || sm ==0)? sm2 : sm;
01750
01751 sm = sm1>sm2?sm1:sm2;
01752
01753 MSG("Finder",Msg::kDebug)<< "sm1 "<<sm1<<" sm2 "<<sm2<<" pl " << o << " sm " << sm <<endl;
01754
01755 if(sm<0.00001)continue;
01756
01757 if(o==0)
01758 o=sm=1;
01759
01760 zoverlap.push_back(o / sm);
01761
01762 MSG("Finder",Msg::kDebug)<< "overlap : " << o/sm<< " smallest path length "<<sm <<endl;
01763 }
01764 }
01765
01766
01767
01768 double bestz=0.0;
01769 for(unsigned int j=0;j<zoverlap.size();j++)
01770 bestz = bestz > zoverlap[j] ? bestz : zoverlap[j] > 0.999 ? bestz : zoverlap[j];
01771
01772
01773 if(bestz < 0.4 && bestz!=0.0) continue;
01774
01775
01776
01777 for(unsigned int j=0;j<zoverlap.size();j++)
01778 {
01779 if((bestz - zoverlap[j]) < 0.3 * bestz || zoverlap[j] > 0.999)
01780 {
01781 zmatches.push_back(std::pair<int,int>(i,j));
01782 MSG("Finder",Msg::kDebug)<< "\tkeeping "<<i<<" "<<j<<endl;
01783 }
01784 }
01785
01786 if(zmatches.size()==0)continue;
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813 if(zmatches.size()>1)
01814 {
01815 int closest=100000;
01816 int cidx=-1;
01817 for(unsigned int j=0;j<zmatches.size();j++)
01818 {
01819
01820
01821
01822
01823
01824 int d = (int)(TMath::Abs(pu[zmatches[j].first].entries - pv[zmatches[j].second].entries));
01825
01826 if(d<closest)
01827 {
01828 closest=d;
01829 cidx=j;
01830 }
01831
01832 }
01833
01834 if(cidx>-1)
01835 {
01836 matches.push_back(zmatches[cidx]);
01837 continue;
01838 }
01839
01840
01841 }
01842
01843
01844
01845
01846
01847
01848
01849 if(zmatches.size()>1)
01850 MSG("Finder",Msg::kWarning) << "Degeneracy not resolved in making 3d particle tracks!"<<endl;
01851
01852 for(unsigned int j=0;j<zmatches.size();j++)
01853 matches.push_back(zmatches[j]);
01854
01855 }
01856
01857
01858 return matches;
01859 }
01860
01861
01862 void Finder::Weave(ChainHelper * chu, ChainHelper * chv)
01863 {
01864 std::vector<foundpath> pu = GetPaths(chu);
01865 std::vector<foundpath> pv = GetPaths(chv);
01866
01867 if(pu.size()<1 || pv.size()<1)return;
01868
01869
01870 DumpPaths(pu);
01871 DumpPaths(pv);
01872
01874
01875
01876
01877 for(int i=0;i<2;i++){
01878
01879 std::vector<foundpath>::iterator it1;
01880 std::vector<foundpath>::iterator it2;
01881 std::vector<foundpath> paths=i==0?pu:pv;
01882 if(paths.size()<2)continue;
01883
01884 double minzlength=1.0;
01885
01886 it1 =paths.begin();
01887 while(it1!=paths.end())
01888
01889 {
01890 if(it1->path.size()<2)
01891 {
01892 it1++;
01893 continue;
01894 }
01895 int diddel=0;
01896
01897 it2=it1;
01898 it2++;
01899 while(it2!=paths.end())
01900
01901 {
01902 diddel=0;
01903 if(it2->path.size()<2)
01904 {
01905 it2++;
01906 continue;
01907 }
01908
01909
01910
01911
01912
01913
01914
01915
01916 int close=1;
01917
01918
01919 int larger=it1->end_z-it1->start_z > it2->end_z-it2->start_z ? 0:1;
01920
01921
01922 std::vector<int> maxpi = larger==0?it1->path:it2->path;
01923 std::vector<int> maxpj = larger==1?it1->path:it2->path;
01924
01925 for(unsigned int k=0;k<maxpj.size()-1;k++)
01926 {
01927 MSG("Finder",Msg::kDebug)<<"chains "<<maxpi[k]<<" "<<maxpj[k]<<endl;
01928 if(maxpi[k]!=maxpj[k])
01929 {
01930 close=0;
01931 break;
01932 }
01933 }
01934
01935
01936 std::vector<foundpath>::iterator itsmall=larger==0?it2:it1;
01937 double dist = itsmall->end_z-itsmall->start_z;
01938 if(close && dist > minzlength)
01939 {
01940
01941
01942
01943
01944
01945
01946
01947
01948 int both=it1==it2?1:0;
01949 if(larger==1)
01950 {
01951 it1=paths.erase(it1);
01952 if(both)it2=it1;
01953 }
01954 if(larger==0)
01955 {
01956 it2=paths.erase(it2);
01957 if(both)it2=it1;
01958 }
01959
01960
01961
01962 diddel=1;
01963
01964
01965 }
01966
01967 if(diddel)
01968 {
01969 it1=paths.begin();
01970 it2=it1;
01971 }
01972 it2++;
01973
01974 }
01975 it1++;
01976
01977 }
01978 if(i==0)pu=paths;
01979 if(i==1)pv=paths;
01980 }
01982
01983 if(pu.size()<1 || pv.size()<1)
01984 {
01985 MSG("Finder",Msg::kError)<<"Removal of similar paths results in empty view!\n";
01986 return;
01987 }
01988
01989
01990
01991
01992 DumpPaths(pu);
01993 DumpPaths(pv);
01994
01995
01996
01997 std::vector<std::pair<int,int> >matches = matchViews(pu,pv);
01998 for(unsigned int i=0;i<matches.size();i++)
01999 {
02000 MSG("Finder",Msg::kDebug) << "found pair " << matches[i].first << " " <<matches[i].second<<endl;
02001 }
02002
02003
02004 std::vector<std::pair<int,int> >matcheso = matchViews(pv,pu);
02005 for(unsigned int i=0;i<matcheso.size();i++)
02006 {
02007 MSG("Finder",Msg::kDebug) << "found pair " << matcheso[i].second << " " <<matcheso[i].first<<endl;
02008 }
02009 for(unsigned int i=0;i<matcheso.size();i++)
02010 {
02011 int found =0;
02012 std::pair<int,int> tmp = make_pair(matcheso[i].second, matcheso[i].first);
02013 for(unsigned int j=0;j<matches.size();j++)
02014 {
02015
02016 if(matches[j]==tmp)
02017 {
02018 found=1;
02019 break;
02020 }
02021 }
02022 if(!found)matches.push_back(tmp);
02023
02024 }
02025
02026
02027
02028
02029
02030
02031 if(matches.size()<1)return;
02032
02033 ostringstream os;
02034 os << "Candidate matches on z overlap : ";
02035 for(unsigned int i=0;i<matches.size();i++)
02036 {
02037 os << matches[i].first <<"-"<<matches[i].second<<" ";
02038 }
02039 MSG("Finder",Msg::kDebug) << os.str()<<endl;
02040
02041
02042
02043
02044
02045 std::vector<std::pair<int,int> >matchestmp;
02046 std::vector<int>multu;
02047 std::vector<int>multv;
02048 for(unsigned int i=0;i<matches.size();i++)
02049 {
02050 int mult0=0;
02051 int mult1=0;
02052 for(unsigned int j=0;j<matches.size();j++)
02053 {
02054 if(i==j)continue;
02055 if(matches[i].first==matches[j].first)mult0++;
02056 if(matches[i].second==matches[j].second)mult1++;
02057 }
02058 if(! ( mult0>0 && mult1>0 ))
02059 {
02060 matchestmp.push_back(matches[i]);
02061 multu.push_back(mult0);
02062 multv.push_back(mult1);
02063 }else if( mult0>0 && mult1>0 )
02064 {
02065
02066
02067
02068 int pass=1;
02069
02070 for(unsigned int k=0;k<matches.size();k++)
02071 {
02072 if(matches[i].second!=matches[k].second)continue;
02073 if(pu[matches[i].first].end_z-pu[matches[i].first].start_z < pu[matches[k].first].end_z-pu[matches[k].first].start_z)
02074 {
02075 pass=0;
02076 break;
02077 }
02078 }
02079 for(unsigned int k=0;k<matches.size();k++)
02080 {
02081 if(matches[i].first!=matches[k].first)continue;
02082 if(pv[matches[i].second].end_z-pv[matches[i].second].start_z < pv[matches[k].second].end_z-pv[matches[k].second].start_z)
02083 {
02084 pass=0;
02085 break;
02086 }
02087 }
02088
02089 if(pass)
02090 {
02091 matchestmp.push_back(matches[i]);
02092 multu.push_back(mult0);
02093 multv.push_back(mult1);
02094 }
02095 }
02096
02097 MSG("Finder",Msg::kDebug) << "pair " << matches[i].first <<" " << matches[i].second << " matches " <<mult0 <<" "<< mult1<<"\n";
02098 }
02099 matches=matchestmp;
02100
02101
02102
02103
02104
02105
02106
02107 std::vector<Particle3D> p3v;
02108 for(unsigned int i=0;i<matches.size();i++)
02109 {
02110 MSG("Finder",Msg::kDebug) << "Making 3d particle with paths "<<matches[i].first<<" "<<matches[i].second<<"\n";
02111
02112 Particle3D p3 = Make3DParticle(pu[matches[i].first].path, pv[matches[i].second].path, chu, chv,multu[i],multv[i]) ;
02113
02114
02115
02116 for(unsigned int j=0;j<p3.view.size();j++)
02117 {
02118 Managed::ClusterManager * cluster_manager = &mypoh->clusterer;
02119 if(p3.chainhit[j]>-1)
02120 {
02121 ChainHelper *ch = p3.view[j]==2?chu:chv;
02122 int oldid = ch->GetChain(p3.chain[j])->cluster_id[p3.chainhit[j]];
02123 int newid = cluster_manager->SaveCluster(oldid,p3.e[j],3);
02124
02125 Managed::ManagedCluster * cluster = cluster_manager->GetCluster(newid);
02126 if(cluster)
02127 {
02128
02129
02130 p3.e[j]=cluster->e;
02131
02132 p3.chainhit[j]=newid;
02133
02134 ch->ChangeHitId(oldid,newid);
02135
02136 }else{
02137
02138 p3.e[j]=0;
02139 p3.chainhit[j]=-1;
02140
02141
02142 }
02143 }
02144
02145
02146
02147 }
02148
02149 if(p3.entries && p3.sum_e>1e-5)
02150 {
02151
02152 p3v.push_back(p3);
02153 }
02154 }
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166 std::vector<Particle3D* > p3d;
02167 for(unsigned int i=0;i<p3v.size();i++)
02168 p3d.push_back(&p3v[i]);
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277 std::vector<Particle3D*> pout1;
02278 for(unsigned int i=0;i<p3d.size();i++)
02279 {
02280 std::vector<Particle3D* > po = ProcessParticle3D1(p3d[i],0);
02281 for(unsigned int j=0;j<po.size();j++)
02282 {
02283 pout1.push_back(po[j]);
02284 }
02285
02286 }
02287
02288
02289
02290
02291
02292 FindNeutrons(pout1);
02293
02294
02295
02296 FinalizeParticles3D(pout1);
02297
02298
02299
02300 for(unsigned int i=0;i<pout1.size();i++)
02301 {
02302 if(pout1[i]->sum_e>0.01)
02303 mypoh->AddParticle3D(*(pout1[i]));
02304 }
02305
02306
02307
02308
02309 DumpParticle3D(pout1);
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326 double parte=0;
02327 for(unsigned int i=0;i<p3d.size();i++) parte+=p3d[i]->sum_e;
02328
02329 if(parte-mypoh->event.visenergy>.001)printf("!!!!!!!!!!!!!!!!!!\n********************\nenergy mismatch!!!! particle sum %f energy total %f\n!!!!!!!!!!!!!!!!!!\n********************\n",parte,mypoh->event.visenergy);
02330
02331
02332
02333
02334 }
02335
02336
02337
02338
02339 void Finder::FindNeutrons(std::vector<Particle3D*> & pout)
02340 {
02341 std::vector<Particle3D*> pout1=pout;
02342
02343 Managed::ClusterManager *clhu = &mypoh->clusterer;
02344 Managed::ClusterManager *clhv = &mypoh->clusterer;
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371 for(unsigned int i=0;i<clhu->clusters.size();i++)clhu->clusters[i].inuse=0;
02372 for(unsigned int i=0;i<clhv->clusters.size();i++)clhv->clusters[i].inuse=0;
02373
02374
02375
02376 for(unsigned int i=0;i<mypoh->particles3d.size();i++)pout1.push_back(&(mypoh->particles3d[i]));
02377
02378 for(unsigned int i=0;i<pout1.size();i++)
02379 {
02380 for(int j=0;j<pout1[i]->entries;j++)
02381 {
02382 ChainHelper *ch = pout1[i]->view[j]==2? &mypoh->chu : pout1[i]->view[j]==3?& mypoh->chv:0;
02383 if(!ch)continue;
02384
02385
02386
02387 Chain * c = ch->GetChain(pout1[i]->chain[j]);
02388 if(!c)
02389 {
02390
02391 continue;
02392 }
02393
02394 if(pout1[i]->chainhit[j]<0)continue;
02395
02396 int id = c->cluster_id[pout1[i]->chainhit[j]];
02397
02398
02399
02400 Managed::ClusterManager * clh = pout1[i]->view[j]==2? clhu : pout1[i]->view[j]==3? clhv:0;
02401 if(!clh)continue;
02402
02403 Managed::ManagedCluster *cluster=clh->GetCluster(id);
02404 if(cluster)cluster->inuse=1;
02405
02406
02407 }
02408
02409 }
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500 double neut_thresh=3.0;
02501
02502 for(int q=0;q<2;q++)
02503 {
02504
02505
02506 std::vector<int> chidx = clhu->GetViewIndex(q==0?2:3);
02507 std::vector<int> chidx_other = clhu->GetViewIndex(q==1?2:3);
02508
02509 for(unsigned int i=0;i<chidx.size();i++)
02510 {
02511 Managed::ManagedCluster *c = & clhu->clusters[chidx[i]];
02512 if(c->inuse)continue;
02513 if(c->e<neut_thresh)continue;
02514
02515
02516
02517 std::vector<int>other_view;
02518 for(unsigned int j=0;j<chidx_other.size();j++)
02519 {
02520 Managed::ManagedCluster *cother = & clhu->clusters[chidx_other[j]];
02521 if(TMath::Abs(cother->z - c->z)<0.06 && !cother->inuse)
02522 other_view.push_back(j);
02523 }
02524
02525 if(other_view.size()==0)
02526 {
02527 Particle3D * pnew = new Particle3D();
02528 pnew->particletype=Particle3D::neutron;
02529 double u = q==0? c->t : vtx_u;
02530 double v = q==1? c->t : vtx_v;
02531 pnew->add_to_back(u, v, c->z, c->e, -1,-1, q==0?2:3, 0);
02532 pout.push_back(pnew);
02533 c->inuse=1;
02534 }else{
02535
02536
02537 Managed::ManagedCluster *cother0 = & clhu->clusters[chidx_other[other_view[0]]];
02538
02539 double o_t = cother0->t;
02540 if(other_view.size()==2)
02541 {
02542 Managed::ManagedCluster *cother1 = & clhu->clusters[chidx_other[other_view[1]]];
02543
02544 o_t += cother1->t;
02545 o_t /=2.0;
02546 }
02547
02548
02549 double u = q==0? c->t : o_t;
02550 double v = q==1? c->t : o_t;
02551
02552
02553 Particle3D * pnew = new Particle3D();
02554 pnew->particletype=Particle3D::neutron;
02555 pnew->add_to_back(u, v, c->z, c->e, -1,-1, q==0?2:3, 0);
02556 c->inuse=1;
02557 pnew->add_to_back(u, v, cother0->z, cother0->e, -1,-1, q==1?2:3, 0);
02558 cother0->inuse=1;
02559 if(other_view.size()==2)
02560 {
02561 Managed::ManagedCluster *cother1 = & clhu->clusters[chidx_other[other_view[1]]];
02562 pnew->add_to_back(u, v, cother1->z, cother1->e, -1,-1, q==1?2:3, 0);
02563 cother1->inuse=1;
02564 }
02565
02566 pout.push_back(pnew);
02567 }
02568
02569
02570 }
02571
02572 }
02573
02574
02575 }
02576
02577
02578
02581 void Finder::RecordLostHits(std::vector<Particle3D*> p3d)
02582 {
02583 for(int i=0;i<2;i++)
02584 {
02585 Managed::ClusterManager * ch = i==0? &mypoh->clusterer : &mypoh->clusterer;
02586
02587 for(unsigned int j=0;j<ch->clusters.size();j++)ch->clusters[j].inuse=0;
02588 }
02589
02590 for(unsigned int i=0;i<p3d.size();i++)
02591 {
02592 Particle3D * p = p3d[i];
02593 for(unsigned int j=0;j<p->chain.size();j++)
02594 {
02595 Managed::ClusterManager * clh = p->view[j]==2 ? &mypoh->clusterer : &mypoh->clusterer ;
02596 ChainHelper * ch = p->view[j]==2 ? &mypoh->chu : &mypoh->chv ;
02597 Chain * chain = ch->GetChain(p->chain[j]);
02598 if(p->chainhit[j]>-1)
02599 clh->GetCluster(chain->cluster_id[p->chainhit[j]])->inuse=1;
02600 }
02601 }
02602
02603 for(int i=0;i<2;i++)
02604 {
02605 Managed::ClusterManager * ch = i==0? &mypoh->clusterer : &mypoh->clusterer;
02606
02607 for(unsigned int j=0;j<ch->clusters.size();j++)
02608 {
02609 if(ch->clusters[j].inuse)continue;
02610 for(unsigned int k=0;k<ch->clusters[j].hite.size();k++)
02611 {
02612 mypoh->event.unused_e +=ch->clusters[j].hite[k];
02613 mypoh->event.unused_strips++;
02614
02615 }
02616 }
02617 }
02618
02619 mypoh->event.unused_e_avg =0;
02620 if(mypoh->event.unused_strips>0)
02621 mypoh->event.unused_e_avg = mypoh->event.unused_e / mypoh->event.unused_strips;
02622
02623 for(int i=0;i<2;i++)
02624 {
02625 Managed::ClusterManager * ch = i==0? &mypoh->clusterer : &mypoh->clusterer;
02626
02627 for(unsigned int j=0;j<ch->clusters.size();j++)
02628 {
02629 if(ch->clusters[j].inuse)continue;
02630 for(unsigned int k=0;k<ch->clusters[j].hite.size();k++)
02631 {
02632 mypoh->event.unused_e_rms += (ch->clusters[j].hite[k] - mypoh->event.unused_e_avg)*(ch->clusters[j].hite[k] - mypoh->event.unused_e_avg);
02633
02634 }
02635 }
02636 }
02637
02638 mypoh->event.unused_e_rms=sqrt(mypoh->event.unused_e_rms);
02639 if(mypoh->event.unused_e_avg>0)mypoh->event.unused_e_rms/=mypoh->event.unused_e_avg;
02640
02641 }
02642
02643
02644
02650 void Finder::FinalizeParticles3D(std::vector<Particle3D*>pout)
02651 {
02652 for(unsigned int i=0;i<pout.size();i++)
02653 {
02654 Particle3D * p = pout[i];
02655 if(!p)continue;
02656
02657 p->Clean();
02658
02659
02660 if(p->entries>0)
02661 {
02662 double sum_z=0;
02663 double sum_z_z=0;
02664 double sum_u=0;
02665 double sum_z_u=0;
02666 double sum_v=0;
02667 double sum_z_v=0;
02668
02669
02670 double n = 5 <p->entries? 5:p->entries;
02671 if(n<1)continue;
02672 for(int j=0;j<n;j++)
02673 {
02674
02675 sum_z+=p->z[j];
02676 sum_z_z+=p->z[j]*p->z[j];
02677 sum_u+=p->u[j];
02678 sum_z_u+=p->z[j]*p->u[j];
02679 sum_v+=p->v[j];
02680 sum_z_v+=p->z[j]*p->v[j];
02681
02682 }
02683
02684 if(n==1)
02685 {
02686
02687 sum_z+=vtx_z;
02688 sum_z_z+=vtx_z*vtx_z;
02689 sum_u+=vtx_u;
02690 sum_z_u+=vtx_z*vtx_u;
02691 sum_v+=vtx_v;
02692 sum_z_v+=vtx_z*vtx_v;
02693 n++;
02694 }
02695
02696 double denom = (n*sum_z_z-(sum_z)*(sum_z)) < 1e-10 ? 0 : (n*sum_z_z-(sum_z)*(sum_z));
02697 double au=0;
02698 double bu=0;
02699 double av=0;
02700 double bv=0;
02701
02702 if(denom==0)
02703 {
02704 au=std::numeric_limits<double>::infinity();
02705 bu=std::numeric_limits<double>::infinity();
02706 av=std::numeric_limits<double>::infinity();
02707 bv=std::numeric_limits<double>::infinity();
02708
02709
02710
02711 }else{
02712 au=(sum_u*sum_z_z-sum_z*sum_z_u)/denom;
02713 bu=(n*sum_z_u-sum_z*sum_u)/denom;
02714 av=(sum_v*sum_z_z-sum_z*sum_z_v)/denom;
02715 bv=(n*sum_z_v-sum_z*sum_v)/denom;
02716 }
02717
02718
02719
02720
02721
02722
02723
02724
02725 double theta = TMath::ATan2(bv,bu);
02726 double phi = TMath::ATan(bu*bu+bv*bv);
02727
02728
02729 p->theta=theta;
02730 p->phi=phi;
02731
02732 }
02733
02734
02735
02736 p->calibrated_energy = p->sum_e * (1.46676) / 0.0241;
02737
02738
02739
02740 if(p->particletype!=Particle3D::muon && p->entries>2 && p->emfit_a==0 )
02741 {
02742
02743 ShwFit f;
02744
02745 double startz=0;
02746
02747 startz=p->z[0];
02748
02749 for(int i=0;i<p->entries;i++)
02750 {
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762 f.Insert3d(p->e[i],p->u[i],p->v[i],p->z[i]);
02763
02764
02765
02766
02767 }
02768
02769
02770
02771 f.Fit3d();
02772
02773 MSG("Finder",Msg::kDebug) <<"EM FIT! " << f.par_a << " " << f.par_b << " +- "<<f.par_b_err<<" "<<f.par_e0<<endl;
02774
02775 p->emfit_a=f.par_a;
02776 p->emfit_b=f.par_b;
02777 p->emfit_e0=f.par_e0;
02778 p->emfit_a_err=f.par_a_err;
02779 p->emfit_b_err=f.par_b_err;
02780 p->emfit_e0_err=f.par_e0_err;
02781 p->emfit_prob=f.prob;
02782 p->calibrated_energy=f.par_e0;
02783 p->emfit_chisq=f.chisq;
02784 p->emfit_ndf=f.ndf;
02785
02786
02787 p->pred_e_a=f.pred_e_a;
02788 p->pred_g_a=f.pred_g_a;
02789 p->pred_b=f.pred_b;
02790 p->pred_e0=f.pred_e0;
02791 p->pred_e_chisq=f.pred_e_chisq;
02792 p->pred_e_ndf=f.pred_e_ndf;
02793 p->pred_g_chisq=f.pred_g_chisq;
02794 p->pred_g_ndf=f.pred_g_ndf;
02795
02796 p->pre_over=f.pre_over;
02797 p->pre_under=f.pre_under;
02798 p->post_over=f.post_over;
02799 p->post_under=f.post_under;
02800
02801 p->pp_chisq=f.pp_chisq;
02802 p->pp_ndf=f.pp_ndf;
02803 p->pp_igood=f.pp_igood;
02804 p->pp_p=f.pp_p;
02805
02806 p->cmp_chisq = f.cmp_chisq;
02807 p->cmp_ndf = f.cmp_ndf;
02808 p->peakdiff = f.peakdiff;
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831 if(f.conv &&
02832 f.par_b - f.par_b_err*2.0 < 0.6 && f.par_b + f.par_b_err*2.0 > 0.4
02833 && f.par_b_err < f.par_b
02834 && f.par_e0/60./meupergev>0.25)
02835 {
02836 p->particletype=Particle3D::electron;
02837 }
02838 else
02839 {
02840 p->particletype=Particle3D::other;
02841
02842
02843 }
02844
02845 }
02846
02847
02848
02849 for(unsigned int i=0;i<p->types.size();i++)
02850 {
02851 if(p->types[i].type==ParticleType::prot)
02852 {
02853
02854
02855 if(p->sum_e<0.001)continue;
02856
02857 if(p->entries<3)continue;
02858
02859 double efrac =( p->e[p->entries-1] + p->e[p->entries-2] ) / p->sum_e;
02860
02861 if(efrac > 0.6)
02862 {
02863 p->particletype=Particle3D::proton;
02864
02865 p->calibrated_energy=p->sum_e*60.;
02866 break;
02867 }
02868 }
02869
02870 }
02871
02872
02873 }
02874 }
02875
02876
02877
02878
02879 std::vector<Particle3D> Finder::shareEnergy(std::vector<Particle3D> p3v)
02880 {
02881
02882
02883
02884
02885
02886 std::multimap< std::pair<int, std::pair<int,int> >, Particle3D* > pmap;
02887 for(int i=0;i<(int)p3v.size();i++)
02888 for(int j=0;j<p3v[i].entries;j++)
02889 {
02890 pmap.insert(make_pair( make_pair( p3v[i].view[j], make_pair(p3v[i].chain[j],p3v[i].chainhit[j])),&(p3v[i])) );
02891
02892
02893 }
02894
02895
02896 std::pair<int,int>last;
02897 int lastcount=0;
02898 int lastview=0;
02899 std::vector<Particle3D*> shared3ds;
02900 std::multimap< std::pair<int, std::pair<int,int> >, Particle3D* >::reverse_iterator it1;
02901 for(it1=pmap.rbegin();it1!=pmap.rend();it1++)
02902 {
02903 if(lastcount==0)
02904 {
02905 last=it1->first.second;
02906 lastcount=1;
02907 lastview=it1->first.first;
02908 shared3ds.clear();
02909 shared3ds.push_back(it1->second);
02910 continue;
02911 }
02912
02913 if(lastcount==1 && ( last!=it1->first.second || lastview!=it1->first.first))
02914 {
02915 last=it1->first.second;
02916 lastview=it1->first.first;
02917 shared3ds.clear();
02918 shared3ds.push_back(it1->second);
02919 continue;
02920 }
02921
02922 if(last==it1->first.second && lastview==it1->first.first)
02923 {
02924 lastcount++;
02925 shared3ds.push_back(it1->second);
02926 continue;
02927 }else{
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937 for(unsigned int i=0;i<shared3ds.size();i++)
02938 {
02939 shared3ds[i]->SetShared(last.first, last.second);
02940 }
02941
02942 ShareHit(lastview,last.first,last.second,shared3ds);
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952 lastcount=1;
02953 last=it1->first.second;
02954 lastview=it1->first.first;
02955 shared3ds.clear();
02956 shared3ds.push_back(it1->second);
02957 }
02958
02959
02960 }
02961
02962 if(lastcount>1)
02963 {
02964 for(unsigned int i=0;i<shared3ds.size();i++)
02965 {
02966 shared3ds[i]->SetShared(last.first, last.second);
02967 }
02968 ShareHit(lastview,last.first,last.second,shared3ds);
02969
02970 }
02971
02972 return p3v;
02973
02974 }
02975
02976
02977 std::vector<Particle3D*> Finder::SetShared(std::vector<Particle3D*> p3v)
02978 {
02979
02980
02981
02982
02983
02984 std::multimap< std::pair<int, std::pair<int,int> >, Particle3D* > pmap;
02985 for(int i=0;i<(int)p3v.size();i++)
02986 for(int j=0;j<p3v[i]->entries;j++)
02987 {
02988 pmap.insert(make_pair( make_pair( p3v[i]->view[j], make_pair(p3v[i]->chain[j],p3v[i]->chainhit[j])),p3v[i]) );
02989 p3v[i]->UnsetShared(p3v[i]->chain[j],p3v[i]->chainhit[j]);
02990
02991 }
02992
02993
02994 std::pair<int,int>last;
02995 int lastcount=0;
02996 int lastview=0;
02997 std::vector<Particle3D*> shared3ds;
02998 std::multimap< std::pair<int, std::pair<int,int> >, Particle3D* >::reverse_iterator it1;
02999 for(it1=pmap.rbegin();it1!=pmap.rend();it1++)
03000 {
03001
03002 if(it1->second->ShareLocked(it1->first.second.first, it1->first.second.second)>0)continue;
03003
03004 if(lastcount==0)
03005 {
03006 last=it1->first.second;
03007 lastcount=1;
03008 lastview=it1->first.first;
03009 shared3ds.clear();
03010 shared3ds.push_back(it1->second);
03011 continue;
03012 }
03013
03014 if(lastcount==1 && ( last!=it1->first.second || lastview!=it1->first.first))
03015 {
03016 last=it1->first.second;
03017 lastview=it1->first.first;
03018 shared3ds.clear();
03019 shared3ds.push_back(it1->second);
03020 continue;
03021 }
03022
03023 if(last==it1->first.second && lastview==it1->first.first )
03024 {
03025 lastcount++;
03026 shared3ds.push_back(it1->second);
03027 continue;
03028 }else{
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038 for(unsigned int i=0;i<shared3ds.size();i++)
03039 {
03040 shared3ds[i]->SetShared(last.first, last.second);
03041 }
03042
03043
03044
03045
03046
03047
03048 lastcount=1;
03049 last=it1->first.second;
03050 lastview=it1->first.first;
03051 shared3ds.clear();
03052 shared3ds.push_back(it1->second);
03053 }
03054
03055
03056 }
03057
03058 if(lastcount>1)
03059 {
03060 for(unsigned int i=0;i<shared3ds.size();i++)
03061 {
03062 shared3ds[i]->SetShared(last.first, last.second);
03063 }
03064
03065 }
03066
03067 return p3v;
03068
03069 }
03070
03071
03072 void Finder::ShareHit(int view, int chain, int chainhit, std::vector<Particle3D*> shared)
03073 {
03074
03075
03076
03077
03078
03079 std::vector<double> es;
03080 for(unsigned int i=0;i<shared.size();i++)
03081 {
03082 int inview = view == 2 ? 3 :2;
03083
03084 double n = shared[i]->GetNextEnergy(chain,chainhit,inview);
03085 double p = shared[i]->GetPreviousEnergy(chain,chainhit,inview);
03086
03087 if(n==0 && p >0)n=p;
03088 if(p==0 && n>0)p=n;
03089
03090
03091
03092 es.push_back(n+p);
03093 }
03094
03095 double total=0;;
03096 double totaln=0;
03097 for(unsigned int i=0;i<es.size();i++)
03098 {
03099 totaln++;
03100 total+=es[i];
03101 }
03102
03103 ChainHelper * ch = view == 2 ? &mypoh->chu : &mypoh->chv;
03104
03105 Chain *c =ch->GetChain(chain);
03106 double energy = c->e[chainhit];
03107
03108
03109
03110 if(total==0)return;
03111 for(unsigned int i=0;i<es.size();i++)
03112 {
03113 shared[i]->SetEnergy(chain,chainhit,view,energy*es[i]/total);
03114 }
03115
03116
03117 }
03118
03119
03120
03121
03122 std::vector<foundpath> Finder::GetPaths(ChainHelper*ch)
03123 {
03124
03125
03126 std::vector<foundpath> p;
03127 for(unsigned int i=0;i<ch->finished.size();i++)
03128 {
03129 if(ch->finished[i].parentChain<0 )
03130 {
03131 std::vector<foundpath> t = ch->FindPaths(&ch->finished[i]);
03132
03133
03134 for(unsigned int j=0;j<t.size();j++)
03135 p.push_back(t[j]);
03136
03137 }
03138 }
03139 return p;
03140 }
03141
03142 void Finder::DumpPaths(std::vector<foundpath> a)
03143 {
03144
03145 ostringstream os;
03146 os << "Dumping Paths\n";
03147 for(unsigned int i=0;i<a.size();i++)
03148 {
03149 os << "Path "<<i<<" : ";
03150 os << " start t,z "<<a[i].start_t<<", "<<a[i].start_z;
03151 os << " end t,z "<<a[i].end_t<<", "<<a[i].end_z;
03152 os << " entries " <<a[i].entries << " energy " << a[i].energy << " muonlike " << a[i].muonlike;
03153 os << "\n\t Chain Path : ";
03154 for(unsigned int j=0;j<a[i].path.size();j++)
03155 os<<a[i].path[j]<<" ";
03156 os <<"\n\n";
03157 }
03158
03159 MSG("Finder",Msg::kDebug) << os.str();
03160
03161 }
03162 struct point
03163 {
03164 int view;
03165 double z;
03166 double t;
03167 double e;
03168 int chain;
03169 int chainhit;
03170 double rms_t;
03171 };
03172
03173 bool pointgreater(point p1, point p2){return p1.z < p2.z;}
03174
03175
03176 Particle3D Finder::Make3DParticle(std::vector<int>upath, std::vector<int>vpath, ChainHelper * chu, ChainHelper * chv,int multu=0, int multv=0)
03177 {
03178 Particle3D p;
03179
03180
03181
03182 std::vector<point> points;
03183
03184 double start =0;
03185 double end =1000;
03186
03187 double endu=0;
03188 double endv=0;
03189
03190
03191
03192
03193 int type=0;
03194
03195
03196 for(unsigned int i=0;i<upath.size();i++)
03197 {
03198 Chain *c = chu->GetChain(upath[i]);
03199
03200
03201 if(c->particletype)
03202 type = c->particletype;
03203
03204 for(int j=0;j<c->entries;j++)
03205 {
03206 if(c->parentChain==-1 && j==0)
03207 start = start < c->z[j]? c->z[j] : start;
03208 if(i == upath.size()-1 && j == c->entries-1)
03209 {
03210 end = end < c->z[j] ? end : c->z[j];
03211 }
03212 endu=endu<c->z[j]?c->z[j]:endu;
03213
03214
03215 if(c->parentChain>-1 && j==0)
03216 {
03217 if(i==0)continue;
03218 Chain *cpast = chu->GetChain(upath[i-1]);
03219 if(cpast->cluster_id[cpast->entries-1] == c->cluster_id[0])
03220 continue;
03221 }
03222 Managed::ManagedCluster * clu = mypoh->clusterer.GetCluster(c->cluster_id[j]);
03223 if(!clu)continue;
03224
03225
03226 point a;
03227 a.z=c->z[j];
03228 a.t=c->t[j];
03229 if(c->available && clu->id>0)
03230 a.e=clu->e;
03231 else a.e=0;
03232 a.chain=c->myId;
03233 if(c->available && clu->id>0)
03234 a.chainhit=j;
03235 else
03236 a.chainhit=-1;
03237 a.view=2;
03238
03239
03240 if(clu)
03241 {
03242 a.rms_t=clu->rms_t;
03243 points.push_back(a);
03244 }
03245
03246
03247
03248
03249 }
03250
03251 }
03252 for(int i=0;i<(int)vpath.size();i++)
03253 {
03254 Chain *c = chv->GetChain(vpath[i]);
03255
03256
03257
03258 if(c->particletype)
03259 type = c->particletype;
03260 for(int j=0;j<c->entries;j++)
03261 {
03262 if(c->parentChain==-1 && j==0)
03263 start = start < c->z[j]? c->z[j] : start;
03264 if(i == (int)vpath.size()-1 && j == c->entries-1)
03265 {
03266 end = end < c->z[j] ? end : c->z[j];
03267 }
03268 endv=endv<c->z[j]?c->z[j]:endv;
03269
03270
03271 if(c->parentChain>-1 && j==0)
03272 {
03273 if(i==0)continue;
03274 Chain *cpast = chv->GetChain(vpath[i-1]);
03275 if(cpast->cluster_id[cpast->entries-1] == c->cluster_id[0])
03276 continue;
03277 }
03278
03279 Managed::ManagedCluster * clu = mypoh->clusterer.GetCluster(c->cluster_id[j]);
03280 if(!clu)continue;
03281
03282
03283 point a;
03284 a.z=c->z[j];
03285 a.t=c->t[j];
03286 if(c->available && clu->id>0)
03287 a.e=clu->e;
03288 else
03289 a.e=0;
03290 a.chain=c->myId;
03291 if(c->available && clu->id>0)
03292 a.chainhit=j;
03293 else
03294 a.chainhit=-1;
03295 a.view=3;
03296
03297
03298 if(clu){
03299 a.rms_t=clu->rms_t;
03300 points.push_back(a);
03301 }
03302
03303
03304
03305 }
03306
03307 }
03308
03309
03310 double stopend = endu<endv?endu:endv;
03311
03312 if(!multu && multv)stopend = stopend<endu?endu:stopend;
03313 if(!multv && multu)stopend = stopend<endv?endv:stopend;
03314 if(!multv && !multu)stopend = endu<endv?endv:endu;
03315
03316 std::sort(points.begin(), points.end(),pointgreater);
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03331
03332
03333 for(unsigned int i=0;i<points.size();i++)
03334 {
03335
03336
03337
03338
03339
03340
03341
03342
03343 int done=0;
03344 for(unsigned int j=i;j<points.size();j++)
03345 {
03346 if(points[j].e>0)break;
03347
03348 if(j==points.size()-1)done=1;
03349 }
03350 if(done)break;
03351
03352 if(points[i].z>stopend)continue;
03353
03354 int myview = points[i].view;
03355 int lower=-1;
03356 int upper=-1;
03357 for(int j=i-1;j>-1;j--)
03358 {
03359 if(points[j].view!=myview)
03360 {
03361 lower=j;
03362 break;
03363 }
03364 }
03365 for(unsigned int j=i+1;j<points.size();j++)
03366 {
03367 if(points[j].view!=myview)
03368 {
03369 upper=j;
03370 break;
03371 }
03372 }
03373
03374
03375
03376 double u = points[i].view==2 ? points[i].t : 0;
03377 double v = points[i].view==3 ? points[i].t : 0;
03378 double e = points[i].e;
03379 double z = points[i].z;
03380 int view = points[i].view;
03381
03382 double rms_t = points[i].rms_t;
03383
03384
03385
03386 if(lower>-1 && upper > -1 )
03387 {
03388 double s = (points[upper].t - points[lower].t) / ( points[upper].z - points[lower].z);
03389
03390 double t = s * (points[i].z-points[lower].z) + points[lower].t;
03391
03392 u = myview == 2 ? u : t;
03393 v = myview == 3 ? v : t;
03394
03395
03396 }else if(lower>-1 && upper < 0)
03397 {
03398
03399
03400
03401 int lower2=-1;
03402 for(int j=lower-1;j>-1;j--)
03403 {
03404 if(points[j].view!=myview && fabs(points[lower].z-points[j].z)>0.04)
03405 {
03406 lower2=j;
03407
03408 break;
03409 }
03410 }
03411
03412
03413 if(lower2>-1 && fabs( points[lower].z - points[lower2].z) >0)
03414 {
03415 double s = (points[lower].t - points[lower2].t) / ( points[lower].z - points[lower2].z);
03416
03417 double off = points[lower].t - points[lower].z*s;
03418
03419 double t = s * points[i].z + off;
03420 u = myview == 2 ? u : t;
03421 v = myview == 3 ? v : t;
03422
03423 }else{
03424 u = myview == 2 ? u : points[lower].t;
03425 v = myview == 3 ? v : points[lower].t;
03426
03427 }
03428
03429
03430 }
03431 else if(upper>-1 && lower < 0)
03432 {
03433
03434
03435
03436
03437 int upper2=-1;
03438 for(unsigned int j=upper+1;j<points.size();j++)
03439 {
03440 if(points[j].view!=myview && fabs(points[upper].z-points[j].z)>0.04)
03441 {
03442 upper2=j;
03443 break;
03444 }
03445 }
03446
03447 if(upper2>-1 && fabs( points[upper2].z - points[upper].z)>0)
03448 {
03449 double s = (points[upper2].t - points[upper].t) / ( points[upper2].z - points[upper].z);
03450 double off = points[upper].t - points[upper].z*s;
03451
03452 double t = s * points[i].z + off;
03453 u = myview == 2 ? u : t;
03454 v = myview == 3 ? v : t;
03455
03456
03457
03458 }else{
03459 u = myview == 2 ? u : points[upper].t;
03460 v = myview == 3 ? v : points[upper].t;
03461
03462 }
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474 double vz =vtx_z;
03475 double vt = 0;
03476 vt = points[upper].view == 2 ? vtx_u : vt;
03477 vt = points[upper].view == 3 ? vtx_v : vt;
03478
03479 double t =vt;
03480
03481
03482 if(fabs ( points[upper].z - vz)>0.001)
03483 {
03484
03485 double s = (points[upper].t - vt) / ( points[upper].z - vz);
03486 t = s * (points[i].z-vz) + vt;
03487
03488 }
03489
03490
03491
03492
03493
03494 u = myview == 2 ? u : t;
03495 v = myview == 3 ? v : t;
03496
03497
03498
03499 }
03500 else if(upper==-1 && lower==-1)
03501 {
03502
03503 u = myview == 2 ? u : 0;
03504 v = myview == 3 ? v : 0;
03505 }
03506
03507 p.add_to_back(u,v,z,e,points[i].chain,points[i].chainhit,view,rms_t);
03508
03509
03510 }
03511
03512
03513 if(type)
03514 p.particletype=(Particle3D::EParticle3DType)type;
03515
03516 p.finalize();
03517
03518 return p;
03519 }
03520
03521
03522
03523
03524
03525
03526 void Finder::DumpParticle3D(std::vector<Particle3D*> p3d)
03527 {
03528 ostringstream s;
03529
03530 s << "Dump of Particle3D's "<<endl;
03531 s << "Number of Particle3D : "<<p3d.size()<< endl<<endl;
03532
03533
03534 for (unsigned int i=0;i<p3d.size();i++)
03535 {
03536
03537
03538 Particle3D * p = p3d[i];
03539 if (p==0)continue;
03540
03541
03542
03543
03544 s << "\n---Particle3d " << i << "---\nstart, stop (u,v,z) (" << p->start_u << ", "<< p->start_v << ", " << p->start_z <<") (" <<p->end_u<<", "<< p->end_v << ", " << p->end_z <<")"<<endl;
03545 s << "entries "<< p->entries << " muonlike " << p->muonfrac <<endl;
03546
03547
03548
03549
03550 s<<"types: ";
03551 for(unsigned int j=0;j<p->types.size();j++)
03552 {
03553 switch( p->types[j].type)
03554 {
03555 case ParticleType::em:
03556 s<<"em ";
03557 break;
03558 case ParticleType::emshort:
03559 s<<"emshort ";
03560 break;
03561 case ParticleType::muon:
03562 s<<"muon ";
03563 break;
03564 case ParticleType::prot:
03565 s<<"prot ";
03566 break;
03567 case ParticleType::pi0:
03568 s<<"pi0 ";
03569 break;
03570 case ParticleType::uniquemuon:
03571 s<<"uniquemuon ";
03572 break;
03573
03574 }
03575
03576 }
03577 s<<endl;
03578
03579 s<<"particletype : "<<p->particletype<<endl;
03580
03581
03582 s<<"par a " << p->emfit_a << " par b "<< p->emfit_b << " par e0 "<< p->emfit_e0 << " cale "<<p->calibrated_energy<<" chisq " << p->emfit_chisq<<" ndf " << p->emfit_ndf<<endl;
03583 s<<"emprob " << p->emfit_prob <<" avg rms_t "<<p->avg_rms_t<<endl;
03584 s<<"vise "<<p->sum_e<<endl;
03585
03586 s << "points (u,v,z,e - chain, chainhit, chainview - shared - rms_t - view) : ";
03587 for(int j=0;j<p->entries;j++)
03588 s << "(" << p->u[j]<<", "<<p->v[j]<<", "<<p->z[j]<<", "<<p->e[j]<<" - " << p->chain[j] <<", "<<p->chainhit[j]<<", "<<p->view[j]<<" - "<<p->shared[j]<<" - "<< p->rms_t[j]<< " - " << p->view[j]<<") ";
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604 s<<endl<<endl;
03605
03606
03607 for(unsigned int q=0;q<p->u.size();q++)
03608 {
03609 if(p->e[q]<0)MSG("Finder",Msg::kDebug) <<"BAD E "<<p->e[q]<<" at "<<q<<"\n";
03610 if(p->z[q]<0||p->z[q]>30 ||isnan(p->z[q]))MSG("Finder",Msg::kDebug) <<"BAD Z "<<p->z[q]<<" at "<<q<<"\n";
03611
03612 if(p->u[q]<-10||p->u[q]>10 ||isnan(p->u[q]))MSG("Finder",Msg::kDebug) <<"BAD U "<<p->u[q]<<" at "<<q<<"\n";
03613 if(p->v[q]<-10||p->v[q]>10 ||isnan(p->v[q]))MSG("Finder",Msg::kDebug) <<"BAD U "<<p->v[q]<<" at "<<q<<"\n";
03614 }
03615
03616
03617
03618
03619 }
03620
03621 s << "\n!!! shareholder has "<<shareholder.GetTotRemaining() << " hits still shared!\n";
03622
03623
03624 MSG("Finder",Msg::kDebug) <<s.str();
03625
03626
03627
03628 }
03629
03630
03631
03632
03633
03634
03635
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652
03653
03654 std::vector<Particle3D*> Finder::ProcessParticle3D(Particle3D * p3d)
03655 {
03656
03657 std::vector<Particle3D*> pout;
03658
03659 ostringstream s;
03660 s<<"\nparticle types:\n";
03661
03662
03663
03664
03665 double lowm=0.2;
03666 double highm=3;
03667 int minm=2;
03668
03669
03670
03671 int lastemend=-1;
03672 int lastemlow=-1;
03673 if(p3d->entries>3)
03674 for(int i=0;i<p3d->entries-2;i++)
03675 {
03676 double p0 = p3d->e[i];
03677 double p1 = p3d->e[i+1];
03678 double p2 = p3d->e[i+2];
03679 if(p0<p1 && p1>p2 && p1 > highm)
03680 {
03681
03682 int low=i;
03683 int high=i+2;
03684
03685
03686 for(int h=i-1;h>-1;h--)
03687 {
03688 if(p3d->e[h]<p3d->e[h+1])
03689 {
03690 low=h;
03691 }else{
03692 break;
03693 }
03694 }
03695 for(int h=i+3;h<p3d->entries;h++)
03696 {
03697 if(p3d->e[h]<p3d->e[h-1])
03698 {
03699 high=h;
03700 }else{
03701 break;
03702 }
03703 }
03704 if(low==lastemend)
03705 {
03706
03707 s<<"pi0 like - found consecutive em like from "<<lastemlow<<" to "<<high<<endl;
03708 ParticleType a;
03709 a.type = ParticleType::pi0;
03710 a.start=lastemlow;
03711 a.stop=high;
03712 p3d->types.push_back(a);
03713 }
03714 s<<"em like from "<< low << " to " <<high<<endl;
03715 i=high;
03716 lastemend=high;
03717 lastemlow=low;
03718 ParticleType a;
03719 a.type = ParticleType::em;
03720 a.start=low;
03721 a.stop=high;
03722 p3d->types.push_back(a);
03723 }
03724 }
03725
03726
03727 if(p3d->entries>3)
03728 {
03729 double p0 = p3d->e[0];
03730 double p1 = p3d->e[1];
03731 double p2 = p3d->e[2];
03732 if(p0>p1 && p1>p2 && p0 > highm)
03733 {
03734
03735 s<<"shortem like"<<endl;
03736
03737 int high=2;
03738 for(int i=2;i<p3d->entries-1;i++)
03739 {
03740 if(p3d->e[i] > p3d->e[i+1])
03741 {
03742 high=i+1;
03743 }
03744 }
03745 ParticleType a;
03746 a.type = ParticleType::emshort;
03747 a.start=0;
03748 a.stop=high;
03749 p3d->types.push_back(a);
03750 }
03751 }
03752
03753
03754 if(p3d->entries>1)
03755 for(int i=0;i<p3d->entries;i++)
03756 {
03757 int low=i;
03758 int high=i;
03759 if(p3d->e[i] > lowm && p3d->e[i] < highm)
03760 {
03761 for(int j=i;j<p3d->entries;j++)
03762 {
03763 if(p3d->e[j] > lowm && p3d->e[j] < highm)
03764 {
03765 high=j;
03766 }else{
03767 if(j < p3d->entries-1 && high == j-1 && p3d->e[j] < highm*2 && p3d->e[j+1] > lowm && p3d->e[j+1] < highm)
03768 {
03769 high=j+1;
03770 j++;
03771 continue;
03772 }
03773 i=+1;
03774 break;
03775
03776 }
03777 }
03778 }
03779
03780 if(high-low+1>=minm)
03781 {
03782
03783 s<<"muon like from "<<low<<" to "<<high<<endl;
03784 ParticleType a;
03785 a.type = ParticleType::muon;
03786 a.start=low;
03787 a.stop=high;
03788 p3d->types.push_back(a);
03789 }
03790
03791 i=high+1;
03792 }
03793
03794
03795 double mc=0;
03796 double me=0;
03797 int c=0;
03798 for(int i=0;i<p3d->entries;i++)
03799 {
03800
03801 if(p3d->shared[i]==0)
03802 {
03803 c++;
03804 if(p3d->e[i] > lowm && p3d->e[i] < highm)
03805 {
03806 mc++;
03807 me+=p3d->e[i];
03808 }
03809 }
03810 }
03811
03812 if(mc/c>0.7)
03813 {
03814 s<<"unique muon found"<<endl;
03815 ParticleType a;
03816 a.type = ParticleType::uniquemuon;
03817 a.start=-1;
03818 a.stop=-1;
03819 p3d->types.push_back(a);
03820 }
03822
03823
03824
03825
03826
03827 int plow=p3d->entries-1;
03828 int phigh=p3d->entries-1;
03829 if(p3d->e[p3d->entries-1]>highm)
03830 for(int i=p3d->entries-2;i>-1;i--)
03831 {
03832 if(p3d->e[i]<p3d->e[i+1]) plow=i;
03833 else break;
03834 }
03835 if(phigh-plow>1)
03836 {
03837
03838 s<<"proton/stopping u+ found from "<<plow<<" to "<<phigh<<endl;
03839 ParticleType a;
03840 a.type = ParticleType::prot;
03841 a.start=plow;
03842 a.stop=phigh;
03843 p3d->types.push_back(a);
03844 }
03845
03846
03847
03848
03849 int emt=0;
03850
03851 p3d->particletype=Particle3D::other;
03852 for(unsigned int i=0;i<p3d->types.size();i++)
03853 {
03854
03855
03856 if(p3d->types[i].type==ParticleType::uniquemuon)
03857 {
03858 std::pair<Particle3D*,Particle3D*> a = StripMuon(p3d);
03859 if(a.first)
03860 {
03861 pout.push_back(a.first);
03862 if(a.second)
03863 {
03864 std::vector<Particle3D*> b =ProcessParticle3D(a.second);
03865 for(unsigned int j=0;j<b.size();j++)
03866 pout.push_back(b[j]);
03867 }
03868 return pout;
03869 }
03870 }
03871
03872
03873
03874
03875 if(p3d->types[i].type==ParticleType::muon && p3d->types[i].stop-p3d->types[i].start+1 == p3d->entries)
03876 {
03877 p3d->particletype=Particle3D::muon;
03878 break;
03879
03880 }
03881
03882
03883 if(p3d->types[i].type==ParticleType::em && p3d->types[i].stop-p3d->types[i].start+1 == p3d->entries)
03884 {
03885 p3d->particletype=Particle3D::electron;
03886 break;
03887 }
03888
03889 if(p3d->types[i].type==ParticleType::em && (double)( p3d->types[i].stop-p3d->types[i].start) / (double) p3d->entries > 0.8)
03890 {
03891 p3d->particletype=Particle3D::electron;
03892 break;
03893 }
03894
03895 if(p3d->types[i].type==ParticleType::em )
03896 {
03897 emt+= p3d->types[i].stop-p3d->types[i].start+1;
03898 }
03899
03900
03901
03902 }
03903
03904 if(p3d->particletype==0 && p3d->muonfrac>0.6)
03905 {
03906 p3d->particletype=Particle3D::muon;
03907
03908 }
03909
03910 if(p3d->particletype==0 && (double)emt / (double)p3d->entries > 40)
03911 {
03912 p3d->particletype=Particle3D::electron;
03913
03914 }
03915
03916
03917 MSG("Finder",Msg::kDebug) << s.str();
03918
03919 pout.push_back(p3d);
03920 return pout;
03921
03922 }
03923
03924
03925 std::pair<Particle3D*,Particle3D*> Finder::StripMuon(Particle3D * p3d)
03926 {
03927 std::pair<Particle3D*,Particle3D*> a;
03928 a.first=0;
03929 a.second=p3d;
03930
03931
03932 double lowm=0.0;
03933 double highm=3.5;
03934
03935 int u=0;
03936 int m=0;
03937 double me=0;
03938
03939 for(int i=0;i<p3d->entries;i++)
03940 {
03941 if(p3d->shared[i]==0)
03942 {
03943 u++;
03944 if(p3d->e[i] > lowm && p3d->e[i]<highm)
03945 {
03946 m++;
03947 me+=p3d->e[i];
03948 }
03949 }
03950 }
03951
03952 if(u==m)
03953 {
03954 a.second=0;
03955
03956 }
03957
03958
03959 Particle3D * c = new Particle3D();
03960 a.first=c;
03961
03962
03963 double eavg = me/m;
03964 for(int i=0;i<p3d->entries;i++)
03965 {
03966 double e = p3d->e[i] > lowm && p3d->e[i]<highm ? p3d->e[i] : eavg;
03967 e = e > p3d->e[i] ? p3d->e[i] : e;
03968
03969 c->add_to_back( p3d->u[i], p3d->v[i], p3d->z[i], e, p3d->chain[i], p3d->chainhit[i], p3d->view[i],0);
03970 c->lockshared[c->entries-1]=1;
03971
03972 if(a.second)
03973 {
03974 double reste=p3d->e[i]-e>0 ? p3d->e[i]-e : 0;
03975 a.second->e[i]= reste;
03976
03977
03978 }
03979 }
03980 c->particletype=Particle3D::muon;
03981
03982
03983
03984 if(a.second)
03985 {
03986 double sume=0;
03987 int num0=0;
03988 for(int i=0;i<a.second->entries;i++)
03989 {
03990 sume+=a.second->e[i];
03991 if(a.second->e[i]<0.01)num0++;
03992 }
03993
03994
03995 if(sume<0.0001 || (double)num0/(double)a.second->entries > 0.8)
03996 {
03997 a.second=0;
03998
03999 }
04000 }
04001
04002 return a;
04003
04004 }
04005
04006
04007
04008
04009
04010
04011 std::vector<Particle3D*> Finder::ProcessParticle3D1(Particle3D * p3d, int check_unique_muon)
04012 {
04013
04014 std::vector<Particle3D*> pout;
04015
04016 ostringstream s;
04017 s<<"\nparticle types:\n";
04018
04019
04020
04021
04022 double lowm=0.2;
04023 double highm=3;
04024 int minm=2;
04025
04026
04027
04028 int lastemend=-1;
04029 int lastemlow=-1;
04030 if(p3d->entries>3)
04031 for(int i=0;i<p3d->entries-2;i++)
04032 {
04033 double p0 = p3d->e[i];
04034 double p1 = p3d->e[i+1];
04035 double p2 = p3d->e[i+2];
04036 if(p0<p1 && p1>p2 && p1 > highm)
04037 {
04038
04039 int low=i;
04040 int high=i+2;
04041
04042
04043 for(int h=i-1;h>-1;h--)
04044 {
04045 if(p3d->e[h]<p3d->e[h+1])
04046 {
04047 low=h;
04048 }else{
04049 break;
04050 }
04051 }
04052 for(int h=i+3;h<p3d->entries;h++)
04053 {
04054 if(p3d->e[h]<p3d->e[h-1])
04055 {
04056 high=h;
04057 }else{
04058 break;
04059 }
04060 }
04061 if(low==lastemend)
04062 {
04063
04064 s<<"pi0 like - found consecutive em like from "<<lastemlow<<" to "<<high<<endl;
04065 ParticleType a;
04066 a.type = ParticleType::pi0;
04067 a.start=lastemlow;
04068 a.stop=high;
04069 p3d->types.push_back(a);
04070 }
04071 s<<"em like from "<< low << " to " <<high<<endl;
04072 i=high;
04073 lastemend=high;
04074 lastemlow=low;
04075 ParticleType a;
04076 a.type = ParticleType::em;
04077 a.start=low;
04078 a.stop=high;
04079 p3d->types.push_back(a);
04080 }
04081 }
04082
04083
04084 if(p3d->entries>3)
04085 {
04086 double p0 = p3d->e[0];
04087 double p1 = p3d->e[1];
04088 double p2 = p3d->e[2];
04089 if(p0>p1 && p1>p2 && p0 > highm)
04090 {
04091
04092 s<<"shortem like"<<endl;
04093
04094 int high=2;
04095 for(int i=2;i<p3d->entries-1;i++)
04096 {
04097 if(p3d->e[i] > p3d->e[i+1])
04098 {
04099 high=i+1;
04100 }
04101 }
04102 ParticleType a;
04103 a.type = ParticleType::emshort;
04104 a.start=0;
04105 a.stop=high;
04106 p3d->types.push_back(a);
04107 }
04108 }
04109
04110
04111 if(p3d->entries>1)
04112 for(int i=0;i<p3d->entries;i++)
04113 {
04114 int low=i;
04115 int high=i;
04116 if(p3d->e[i] > lowm && p3d->e[i] < highm)
04117 {
04118 for(int j=i;j<p3d->entries;j++)
04119 {
04120 if(p3d->e[j] > lowm && p3d->e[j] < highm)
04121 {
04122 high=j;
04123 }else{
04124 if(j < p3d->entries-1 && high == j-1 && p3d->e[j] < highm*2 && p3d->e[j+1] > lowm && p3d->e[j+1] < highm)
04125 {
04126 high=j+1;
04127 j++;
04128 continue;
04129 }
04130 i=+1;
04131 break;
04132
04133 }
04134 }
04135 }
04136
04137 if(high-low+1>=minm)
04138 {
04139
04140 s<<"muon like from "<<low<<" to "<<high<<endl;
04141 ParticleType a;
04142 a.type = ParticleType::muon;
04143 a.start=low;
04144 a.stop=high;
04145 p3d->types.push_back(a);
04146 }
04147
04148 i=high+1;
04149 }
04150
04151
04152
04153 if(check_unique_muon)
04154 {
04155 double mc=0;
04156 double me=0;
04157 int c=0;
04158 for(int i=0;i<p3d->entries;i++)
04159 {
04160
04161
04162
04163 c++;
04164 if(p3d->e[i] > lowm && p3d->e[i] < highm)
04165 {
04166 mc++;
04167 me+=p3d->e[i];
04168 }
04169
04170 }
04171
04172 if(mc>0.7*c)
04173 {
04174 s<<"unique muon found muonlike to all hits ratio "<<mc/c<<endl;
04175 ParticleType a;
04176 a.type = ParticleType::uniquemuon;
04177 a.start=-1;
04178 a.stop=-1;
04179 p3d->types.push_back(a);
04180 }
04181 }
04183
04184
04185
04186
04187
04188 int plow=p3d->entries-1;
04189 int phigh=p3d->entries-1;
04190 if(p3d->e[p3d->entries-1]>highm)
04191 for(int i=p3d->entries-2;i>-1;i--)
04192 {
04193 if(p3d->e[i]<p3d->e[i+1]) plow=i;
04194 else break;
04195 }
04196 if(phigh-plow>0)
04197 {
04198
04199 s<<"proton/stopping u+ found from "<<plow<<" to "<<phigh<<endl;
04200 ParticleType a;
04201 a.type = ParticleType::prot;
04202 a.start=plow;
04203 a.stop=phigh;
04204 p3d->types.push_back(a);
04205 }
04206
04207
04208
04209
04210 int emt=0;
04211
04212
04213 p3d->particletype=Particle3D::other;
04214
04215
04216
04217 std::vector<ParticleType>::iterator it;
04218
04219
04220
04221
04222 for(it=p3d->types.begin();it!=p3d->types.end();it++)
04223 {
04224
04225
04226 if(it->type==ParticleType::uniquemuon)
04227 {
04228 ostringstream s;
04229 s<<"ATTEMPTING TO STRIP MUON\n";
04230 std::pair<Particle3D*,Particle3D*> a = StripMuon1(p3d);
04231 if(a.first)
04232 {
04233 s << "STRIPPED MUON\n";
04234 pout.push_back(a.first);
04235 if(a.second)
04236 {
04237 s <<" OTHERS REMAIN!\n";
04238
04239 std::vector<Particle3D*> b =ProcessParticle3D1(a.second);
04240 for(unsigned int j=0;j<b.size();j++)
04241 pout.push_back(b[j]);
04242 }
04243
04244 break;
04245 }else{
04246 p3d->types.erase(it);
04247
04248 }
04249 }
04250
04251 MSG("Finder",Msg::kDebug)<<s;
04252
04253
04254
04255
04256 if(it->type==ParticleType::muon && it->stop - it->start+1 == p3d->entries)
04257 {
04258 p3d->particletype=Particle3D::muon;
04259
04260
04261 }
04262
04263
04264 if(it->type==ParticleType::em && it->stop - it->start+1 == p3d->entries)
04265 {
04266 p3d->particletype=Particle3D::electron;
04267
04268 }
04269
04270 if(it->type==ParticleType::em && (double)( it->stop - it->start) / (double) p3d->entries > 0.8)
04271 {
04272 p3d->particletype=Particle3D::electron;
04273
04274 }
04275
04276 if(it->type==ParticleType::em )
04277 {
04278 emt+= it->stop - it->start+1;
04279 }
04280
04281
04282
04283 }
04284
04285 if(p3d->particletype==0 && p3d->muonfrac>0.6)
04286 {
04287 p3d->particletype=Particle3D::muon;
04288
04289 }
04290
04291 if(p3d->particletype==0 && (double)emt / (double)p3d->entries > 40)
04292 {
04293 p3d->particletype=Particle3D::electron;
04294
04295 }
04296
04297
04298 MSG("Finder",Msg::kDebug) << s.str()<<endl;
04299
04300 pout.push_back(p3d);
04301 return pout;
04302
04303 }
04304
04305
04306
04307 std::pair<Particle3D*,Particle3D*> Finder::StripMuon1(Particle3D * p3d)
04308 {
04309 std::pair<Particle3D*,Particle3D*> a;
04310 a.first=0;
04311 a.second=p3d;
04312
04313
04314 double lowm=0.0;
04315 double highm=3.5;
04316
04317 int u=0;
04318 int m=0;
04319 double me=0;
04320
04321 for(int i=0;i<p3d->entries;i++)
04322 {
04323 if(p3d->shared[i]==0)
04324 {
04325 u++;
04326 if(p3d->e[i] > lowm && p3d->e[i]<highm)
04327 {
04328 m++;
04329 me+=p3d->e[i];
04330 }
04331 }
04332 }
04333
04334 if(u==m)
04335 {
04336 a.second=0;
04337
04338 }
04339
04340
04341 Particle3D * c = new Particle3D();
04342 a.first=c;
04343
04344
04345 double eavg = me/m;
04346 for(int i=0;i<p3d->entries;i++)
04347 {
04348 double e = p3d->e[i] > lowm && p3d->e[i]<highm ? p3d->e[i] : eavg;
04349 e = e > p3d->e[i] ? p3d->e[i] : e;
04350
04351 c->add_to_back( p3d->u[i], p3d->v[i], p3d->z[i], e, p3d->chain[i], p3d->chainhit[i], p3d->view[i],0);
04352 c->lockshared[c->entries-1]=1;
04353
04354 shareholder.Take(p3d->chain[i],p3d->chainhit[i],e);
04355
04356 if(a.second)
04357 {
04358 double reste=p3d->e[i]-e>0 ? p3d->e[i]-e : 0;
04359 a.second->e[i]= reste;
04360
04361 shareholder.Take(p3d->chain[i],p3d->chainhit[i],e);
04362
04363
04364 }
04365 }
04366 c->particletype=Particle3D::muon;
04367
04368 ParticleType pta;
04369 pta.type = ParticleType::muon;
04370 pta.start=0;
04371 pta.stop=p3d->entries;
04372 c->types.push_back(pta);
04373
04374
04375 if(a.second)
04376 {
04377 double sume=0;
04378 int num0=0;
04379 for(int i=0;i<a.second->entries;i++)
04380 {
04381 sume+=a.second->e[i];
04382 if(a.second->e[i]<0.01)num0++;
04383 }
04384 MSG("Finder",Msg::kDebug)<<"second e"<<sume<<endl;
04385
04386 if(sume<0.0001 || (double)num0/(double)a.second->entries > 0.8)
04387 {
04388 a.second=0;
04389
04390 }
04391 else
04392 {
04393
04394
04395
04396
04397 std::vector<ParticleType>::iterator it;
04398 for(it=a.second->types.begin();it!=a.second->types.end();it++)
04399 {
04400 if(it->type==ParticleType::uniquemuon)
04401 {
04402 a.second->types.erase(it);
04403 it=a.second->types.begin();
04404 MSG("Finder",Msg::kDebug)<<"removed uniquemuon indicator from particle3d "<<endl;
04405 }
04406
04407 }
04408
04409
04410
04411 a.second->types.clear();
04412
04413 }
04414 }
04415
04416
04417 return a;
04418
04419 }
04420
04421
04422 bool p3dsharedsort(Particle3D* a, Particle3D* b)
04423 {
04424 return a->numshared < b->numshared;
04425 }
04426
04427
04428 void Finder::RemoveSharedHits(std::vector<Particle3D*> pv)
04429 {
04430
04431 MSG("Finder",Msg::kDebug) <<"\ncleaning list\n";
04432 for (unsigned int i=0;i<pv.size();i++)
04433 {
04434 MSG("Finder",Msg::kDebug) << " removing with "<<pv[i]->numshared<<" shared \n";
04435
04436
04437 for(int j=0;j<pv[i]->entries;j++)
04438 {
04439 if(pv[i]->shared[j])
04440 {
04441 if(shareholder.GetNumShared(pv[i]->chain[j],pv[i]->chainhit[j])<2)
04442 pv[i]->UnsetShared(pv[i]->chain[j],pv[i]->chainhit[j]);
04443 if(shareholder.GetNumShared(pv[i]->chain[j],pv[i]->chainhit[j])==1)
04444 {
04445 int c=pv[i]->chain[j];
04446 int ch=pv[i]->chainhit[j];
04447 double e = shareholder.GetEShared(c,ch);
04448
04449
04450 pv[i]->e[j]=e;
04451 shareholder.Take(c,ch,e);
04452 }
04453 }
04454
04455 }
04456
04457 }
04458
04459
04460 sort(pv.begin(), pv.end(), p3dsharedsort);
04461
04462 MSG("Finder",Msg::kDebug) <<"\nremoving hits\n";
04463
04464 for (unsigned int i=0;i<pv.size();i++)
04465 {
04466 shareholder.dump();
04467
04468
04469 for(int j=0;j<pv[i]->entries;j++)
04470 {
04471 if(pv[i]->shared[j])
04472 {
04473 if(shareholder.GetNumShared(pv[i]->chain[j],pv[i]->chainhit[j])<2)
04474 pv[i]->UnsetShared(pv[i]->chain[j],pv[i]->chainhit[j]);
04475 if(shareholder.GetNumShared(pv[i]->chain[j],pv[i]->chainhit[j])==1)
04476 {
04477 int c=pv[i]->chain[j];
04478 int ch=pv[i]->chainhit[j];
04479 double e = shareholder.GetEShared(c,ch);
04480
04481
04482 pv[i]->e[j]=e;
04483 shareholder.Take(c,ch,e);
04484 }
04485 }
04486
04487 }
04488
04489
04490
04491
04492
04493 if (pv[i]->particletype==Particle3D::muon)
04494 {
04495 MSG("Finder",Msg::kDebug)<<"!!muon\n";
04496 }
04497 else if (pv[i]->particletype==Particle3D::electron)
04498 {
04499 MSG("Finder",Msg::kDebug)<<"!!elec\n";
04500 }
04501 else MSG("Finder",Msg::kDebug)<<"!!other "<<pv[i]->particletype<<"\n";
04502
04503
04504
04505
04506 for(int j=1;j<pv[i]->entries-2;j++)
04507 {
04508 if(pv[i]->shared[j] && !pv[i]->shared[j-1] && !pv[i]->shared[j+1])
04509 {
04510 int c=pv[i]->chain[j];
04511 int ch=pv[i]->chainhit[j];
04512 double e = shareholder.GetEShared(c,ch);
04513
04514 double totake=(pv[i]->e[j-1]+pv[i]->e[j+1])/2;
04515 totake=totake>e?e:totake;
04516
04517 pv[i]->e[j]=totake;
04518 shareholder.Take(c,ch,totake);
04519 pv[i]->UnsetShared(c,ch);
04520
04521 }
04522 }
04523
04524
04525 for(int j=0;j<pv[i]->entries;j++)
04526 {
04527 int foundupper=-1;
04528 int foundlower=-1;
04529 for(int k=j+1;k<pv[i]->entries;k++)
04530 {
04531
04532 if(pv[i]->shared[j]&&! pv[i]->shared[k])
04533 {
04534 foundupper=k;
04535 break;
04536 }
04537 }
04538
04539 for(int k=j-1;k>-1;k--)
04540 {
04541 if(pv[i]->shared[j]&&! pv[i]->shared[k])
04542 {
04543 foundlower=k;
04544 break;
04545 }
04546 }
04547
04548 double totake=0;
04549
04550 if(foundupper>-1 && foundlower>-1)
04551 {
04552 totake = (pv[i]->e[foundupper]+pv[i]->e[foundlower])/2;
04553 }
04554 else if(foundupper>-1)
04555 {
04556 totake = (pv[i]->e[foundupper]);
04557 }
04558 else if(foundlower>-1)
04559 {
04560 totake = (pv[i]->e[foundlower]);
04561 }else continue;
04562
04563 int c=pv[i]->chain[j];
04564 int ch=pv[i]->chainhit[j];
04565 double e = shareholder.GetEShared(c,ch);
04566 totake=totake>e?e:totake;
04567 pv[i]->e[j]=totake;
04568 MSG("Finder",Msg::kDebug)<<"taking from "<<c<<" "<<ch << " with shard "<<shareholder.GetNumShared(c,ch)<<"\n";
04569 shareholder.Take(c,ch,totake);
04570 MSG("Finder",Msg::kDebug)<<"now has "<<shareholder.GetNumShared(c,ch)<<" shared\n";
04571 pv[i]->UnsetShared(c,ch);
04572
04573 }
04574
04575 pv[i]->finalize();
04576
04577 }
04578
04579
04580 }