00001 #include "MessageService/MsgService.h"
00002 #include "NueAna/ParticlePID/ParticleFinder/ChainHelper.h"
00003 #include <math.h>
00004 #include <map>
00005 #include <algorithm>
00006
00007 #include <sstream>
00008
00009
00010
00011 CVSID("$Id: ChainHelper.cxx,v 1.3 2009/06/23 23:08:59 scavan Exp $");
00012
00013
00014 ClassImp(ChainHelper)
00015
00016
00017
00018 ChainHelper::ChainHelper() : parents(0),muonlikechains(0),emlikechains(0),totalchains(0), max_z_gap(0.3), max_slope(0.0),
00019 found_max_path(0)
00020 {
00021 Reset();
00022
00023 working.clear();
00024 finished.clear();
00025 pending_t.clear();
00026 pending_z.clear();
00027 pending_e.clear();
00028 pending_cluster_id.clear();
00029 maxpath.clear();
00030
00031
00032 Chain::ResetCounter();
00033
00034 idhelper.clear();
00035
00036 detector=Detector::kUnknown;
00037
00038 }
00039
00040 int ChainHelper::NewChain()
00041 {
00042 Chain c;
00043 AddFinishedChain(c);
00044 return c.myId;
00045
00046 }
00047
00048
00049 void ChainHelper::AddFinishedChain(Chain c)
00050 {
00051
00052 finished.push_back(c);
00053 idhelper[c.myId]= finished.size()-1 ;
00054 }
00055
00056
00057 ChainHelper::~ChainHelper()
00058 {
00059 working.clear();
00060 finished.clear();
00061 pending_t.clear();
00062 pending_z.clear();
00063 pending_e.clear();
00064 pending_cluster_id.clear();
00065 idhelper.clear();
00066 maxpath.clear();
00067 }
00068
00069
00070 Chain* ChainHelper::GetChain(int id)
00071 {
00072 for(unsigned int i=0;i<finished.size();i++)
00073 if(id == finished[i].myId)return &finished[i];
00074
00075
00076
00077
00078
00079
00080
00081
00082 return 0;
00083 }
00084
00085
00086 void ChainHelper::DeleteChain(int id)
00087 {
00088
00089
00090
00091 Chain* todel = GetChain(id);
00092 if(!todel)return;
00093
00094 if(todel->parentChain>-1)
00095 {
00096 Chain*p = GetChain(todel->parentChain);
00097
00098 for(unsigned int i=0;i<p->children.size();i++)
00099 {
00100 if(p->children[i]==id)
00101 {
00102 p->children.erase(p->children.begin()+i);
00103
00104
00105
00106 break;
00107 }
00108 }
00109 }
00110
00111
00112 for(unsigned int i=0;i<todel->children.size();i++)
00113 {
00114 Chain * child = GetChain(todel->children[i]);
00115 if(!child)continue;
00116 child->parentChain=-1;
00117 }
00118
00119
00120 for(unsigned int i=0;i<finished.size();i++)
00121 {
00122 if(finished[i].myId==id)
00123 {
00124 finished.erase(finished.begin()+i);
00125 break;
00126 }
00127 }
00128
00129
00130
00131
00132 idhelper.clear();
00133 for(unsigned int i=0;i<finished.size();i++)
00134 idhelper[finished[i].myId]=i;
00135
00136 found_max_path=0;
00137
00138 }
00139
00140
00141
00142 void ChainHelper::Reset()
00143 {
00144 working.clear();
00145 finished.clear();
00146 pending_t.clear();
00147 pending_z.clear();
00148 pending_e.clear();
00149 pending_cluster_id.clear();
00150
00151 Chain::ResetCounter();
00152
00153 found_max_path=0;
00154 parents=0;
00155 muonlikechains=0;
00156 emlikechains=0;
00157
00158 vtx_z=0;
00159 vtx_t=0;
00160
00161 }
00162
00163
00164 void ChainHelper::add_to_plane(double it, double iz, double ie, int cluster_id)
00165 {
00166 pending_t.push_back(it);
00167 pending_z.push_back(iz);
00168 pending_e.push_back(ie);
00169 pending_cluster_id.push_back(cluster_id);
00170
00171
00172 found_max_path=0;
00173
00174 }
00175
00176 void ChainHelper::matchChains()
00177 {
00178
00179 found_max_path=0;
00180
00181 std::vector<int> longs;
00182
00183 for(unsigned int i=0;i<finished.size();i++)
00184 {
00185 if(finished[i].entries>3) longs.push_back(i);
00186 }
00187
00188 for(unsigned int i=0;i<longs.size();i++)
00189 for(unsigned int j=i+1;j<longs.size();j++)
00190 {
00191 if(finished[longs[j]].start_z-finished[longs[i]].end_z > 1.0)continue;
00192 if(finished[longs[j]].end_z-finished[longs[j]].start_z <0.0)continue;
00193 if(finished[longs[i]].end_z-finished[longs[i]].start_z <0.0)continue;
00194 if(finished[longs[j]].parentChain>-1)continue;
00195
00196
00197
00198 double dz=finished[longs[j]].start_z-finished[longs[i]].end_z;
00199
00200
00201
00202
00203 double t1 = finished[longs[i]].interpolate(dz);
00204 double t2 = finished[longs[j]].interpolate(dz);
00205
00206
00207
00208 double dt1 = fabs(finished[longs[j]].start_t - t1);
00209 double dt2 = fabs(finished[longs[i]].end_t - t2);
00210
00211
00212 MSG("ChainHelper",Msg::kDebug) <<"matching ... " << dt1 <<" "<<dt2<<endl;
00213
00214 if(dz<1.0 && (dt1<0.1 || dt2<0.2) )
00215 {
00216 finished[longs[i]].children.push_back(finished[longs[j]].myId);
00217 finished[longs[j]].parentChain=finished[longs[i]].myId;
00218
00219 }
00220
00221 }
00222
00223
00224
00225
00226 }
00227
00228
00229 void ChainHelper::process_plane()
00230 {
00231
00232 int wsize=working.size();
00233
00234
00235 std::vector<int> todel(wsize);
00236 for(int i=0;i<wsize;i++)todel[i]=0;
00237
00238
00239 std::map<int, std::vector<int> > toadd;
00240
00241
00242
00243 std::vector<Chain> tmpchain;
00244
00245
00246
00247
00248
00249 for(unsigned int j=0;j<pending_t.size();j++)
00250 {
00251
00252 double iz=pending_z[j];
00253 double it=pending_t[j];
00254
00255
00256
00257 double max_z_gap_temp=max_z_gap;
00258 if(detector==Detector::kNear && iz > 6)
00259 {
00260 max_z_gap_temp*=5;
00261 }
00262
00263 double closest_d=100000;
00264 int closest_index=-1;
00265 int match=0;
00266
00267 double closest_t_unmatched=100000;
00268 double closest_t=100000;
00269
00270 int singlehitmatch=0;
00271 double singlehite=0;
00272
00273 for(unsigned int i=0;i<working.size();i++)
00274 {
00275 if(fabs(iz-working[i].end_z)<0.0001)
00276 {
00277
00278 continue;
00279 }
00280
00281
00282 if(fabs(iz-working[i].end_z)>max_z_gap_temp)
00283 {
00284
00285 todel[i]=1;
00286 continue;
00287 }
00288
00289 double tslope = (working[i].end_t-it)/(working[i].end_z-iz);
00290
00292 double ddist = sqrt((working[i].end_t-it)*(working[i].end_t-it) + (working[i].end_z-iz)*(working[i].end_z-iz));
00293
00294 if(ddist>max_z_gap_temp)continue;
00295
00296
00298
00299
00300
00301 closest_t_unmatched=closest_t_unmatched<fabs(working[i].end_t-it) ?closest_t_unmatched:fabs(working[i].end_t-it);
00302
00303
00304
00305 if(fabs(tslope-working[i].last_slope)<max_slope/(fabs(working[i].end_z-iz)/0.0708) || !working[i].good_slope() || working[i].entries<2 )
00306 {
00307 match=1;
00308
00309 if(working[i].good_slope() && fabs(working[i].last_slope)<10000)match=2;
00310
00311
00312 double dist = closest_t;
00313
00314
00315
00316
00317 dist = fabs(working[i].end_t-it);
00318
00319
00320
00321
00322 closest_t=closest_t<dist?closest_t:dist;
00323
00324
00325
00326 double ldt=(working[i].end_t-it)*(working[i].end_t-it)+(working[i].end_z-iz)*(working[i].end_z-iz);
00327
00328 double kinky=0.0;
00329 if(working[i].entries>1)
00330 {
00331 int a = working[i].entries-2;
00332
00333
00334 if (! fabs(working[i].z[a+1]-working[i].z[a]) < 0.00001)
00335 {
00336 double slope = (working[i].t[a+1]-working[i].t[a]) / (working[i].z[a+1]-working[i].z[a]);
00337 double off = working[i].t[a];
00338 double z = working[i].z[a];
00339 kinky = fabs ( ( (iz - z) * slope + off ) - it);
00340
00341 kinky = fabs ( working[i].interpolate(iz)-it);
00342
00343 }
00344
00345 }
00346
00347
00348 if(ldt<closest_d ||singlehitmatch==1)
00349 if(kinky < 0.1)
00350 {
00351
00352
00353
00354 if(working[i].entries==1)
00355 {
00356 if(singlehitmatch==0)
00357 {
00358 singlehitmatch=1;
00359 singlehite=working[i].e[0];
00360 closest_d=ldt;
00361 closest_index=i;
00362 }else{
00363 if(singlehite <working[i].e[0])
00364 {
00365 singlehite = working[i].e[0];
00366 closest_d=ldt;
00367 closest_index=i;
00368 }
00369 }
00370
00371 }else{
00372 closest_d=ldt;
00373 closest_index=i;
00374 singlehitmatch=0;
00375 }
00376 }
00377 }
00378
00379
00380 }
00381
00382
00383 int notyetdone=1;
00384
00385
00386
00387 if(closest_index>-1)
00388 {
00389 double zdist = fabs (working[closest_index].end_z-iz);
00390 double zplanedist = zdist / 0.035;
00391 if(zplanedist>1.4)
00392 {
00393 std::vector<int> matchidx;
00394 std::vector<int> matchentry;
00395 std::vector<double> matchdist;
00396
00397 for(unsigned int i=0;i<working.size();i++)
00398 {
00399 if(closest_index==(int)i)continue;
00400
00401
00402 if(working[i].entries<2)continue;
00403 if(fabs(iz-working[i].end_z) * 1.2 <zdist);
00404 {
00405
00406 for(int j=0;j<working[i].entries;j++)
00407 {
00408 if(fabs(working[i].z[j] - working[closest_index].end_z)< 0.0175)
00409 {
00410 matchidx.push_back(i);
00411 matchentry.push_back(j);
00412 double dist2 = (working[i].z[j]-iz)*(working[i].z[j]-iz) + (working[i].t[j]-it)*(working[i].t[j]-it) ;
00413 matchdist.push_back(dist2);
00414 }
00415
00416 }
00417
00418 }
00419 }
00420
00421 int tmpi=-1;
00422 for(unsigned int i =0 ;i<matchdist.size();i++)
00423 {
00424 if(matchdist[i]< closest_d)
00425 {
00426 tmpi=i;
00427 closest_d=matchdist[i];
00428 }
00429 }
00430
00431 if(tmpi>-1)
00432 {
00433
00434 Chain c;
00435 MSG("ChainHelper",Msg::kDebug) <<"starting new chain, attaching to old chain "<< c.myId << ", " << working[matchidx[tmpi]].myId <<endl;
00436 c.add_to_back(pending_t[j],pending_z[j],pending_e[j],pending_cluster_id[j]);
00437
00438
00439
00440 tmpchain.push_back(AttachAt(&working[matchidx[tmpi]], &c,working[matchidx[tmpi]].z[matchentry[tmpi]]));
00441 tmpchain.push_back(c);
00442
00443 notyetdone=0;
00444 }
00445
00446
00447
00448 }
00449 }
00450
00451
00452
00453
00454
00455
00456 double pdistr=1000;
00457 int tmp_closest_index=-1;
00458 for(unsigned int i=0;i<working.size();i++)
00459 {
00460 if(closest_index==(int)i)continue;
00461
00462
00463 if(working[i].entries<2)continue;
00464
00465
00466 double tpos =working[i].interpolate(iz);
00467
00468
00469 if(fabs(it-tpos)<0.025*1.5)
00470 {
00471 double rdist = (working[i].end_z-iz)*(working[i].end_z-iz)+(working[i].end_t-it)*(working[i].end_t-it);
00472
00473 if(rdist < pdistr)
00474 {
00475 tmp_closest_index=i;
00476 pdistr=rdist;
00477 }
00478 }
00479
00480 }
00481
00482
00483 if(pdistr<max_z_gap_temp && tmp_closest_index>-1)closest_index=tmp_closest_index;
00484
00485
00486
00487 if(notyetdone)
00488 {
00489
00490 if(closest_index>-1)
00491 {
00492 toadd[closest_index].push_back(j);
00493 }else{
00494
00495
00496
00497 if(vtx_z==0 || (fabs(pending_t[j]-vtx_t)<0.2 && fabs(pending_z[j]-vtx_z)<0.2)){
00498
00499 Chain c;
00500 MSG("ChainHelper",Msg::kDebug) <<"no match, starting new chain "<< c.myId <<endl;
00501 c.add_to_back(pending_t[j],pending_z[j],pending_e[j],pending_cluster_id[j]);
00502
00503
00504 tmpchain.push_back(c);
00505 }
00506 }
00507
00508 }
00509
00510 }
00511
00512
00513 for(unsigned int i=0;i<tmpchain.size();i++)
00514 working.push_back(tmpchain[i]);
00515
00516
00517
00518
00519
00520
00521
00522 std::map<int, std::vector<int> >::iterator iter;
00523 for(iter=toadd.begin();iter!=toadd.end();iter++)
00524 {
00525
00526
00527 int s = iter->second.size();
00528
00529
00530 if(s==1)
00531 {
00532 int item=iter->second[0];
00533
00534 if(working[iter->first].children.size()>0)
00535 {
00536 Chain *t=split(&working[iter->first]);
00537 t->add_to_back(pending_t[item],pending_z[item],pending_e[item],pending_cluster_id[item]);
00538 working.push_back(*t);
00539 delete t;t=0;
00540 MSG("ChainHelper",Msg::kDebug) <<"---splitting chain "<< working[iter->first].myId <<" to make "<< t->myId <<endl;
00541
00542 }else{
00543 working[iter->first].add_to_back(pending_t[item],pending_z[item],pending_e[item],pending_cluster_id[item]);
00544 }
00545
00546
00547 MSG("ChainHelper",Msg::kDebug)<< "adding to chain "<<working[iter->first].myId<<endl;
00548 }
00549
00550 if(s>1)
00551 {
00552
00553 for(int k=0;k<s;k++)
00554 {
00555 Chain *t=split(&working[iter->first]);
00556 int item=iter->second[k];
00557 t->add_to_back(pending_t[item],pending_z[item],pending_e[item],pending_cluster_id[item]);
00558 working.push_back(*t);
00559 delete t;t=0;
00560 MSG("ChainHelper",Msg::kDebug)<< "---splitting chain " << working[iter->first].myId << " to make " << t->myId <<endl;
00561 }
00562
00563
00564
00565 }
00566 }
00567
00568
00569
00570
00571 pending_t.clear();
00572 pending_z.clear();
00573 pending_e.clear();
00574 pending_cluster_id.clear();
00575 found_max_path=0;
00576
00577 }
00578
00579 Chain * ChainHelper::split(Chain * d){
00580
00581 Chain * r = new Chain();
00582 r->parentChain=d->myId;
00583 r->start_t=d->end_t;
00584 r->start_z=d->end_z;
00585 r->level=d->level+1;
00586
00587 int dsize=d->t.size()-1;
00588 r->add_to_back(d->t[dsize],d->z[dsize],d->e[dsize],d->cluster_id[dsize]);
00589
00590 d->children.push_back(r->myId);
00591
00592
00593
00594
00595 return r;
00596 }
00597
00598 Chain ChainHelper::AttachAt(Chain *c, Chain * daughter, double splitpointz)
00599 {
00600
00601
00602 if(c->entries<1 || splitpointz < c->start_z || splitpointz > daughter->end_z){
00603
00604 cout<<"!!!!!!!!!THIS SHOULDN'T HAPPEN --- CALL TO ATTACHAT IN CHAINHELPER WITH SPLITPOINT OUTSIDE OF PARENT CHAIN!!!!"<<endl;
00605 cout<<"requested to connect "<<daughter->myId <<" to "<<c->myId <<" at "<<splitpointz<<endl;
00606 cout<<"daughter\n";
00607 daughter->PrintChain();
00608 cout<<"parent\n";
00609 c->PrintChain();
00610 cout<<"\n\n";
00611 return Chain();
00612 }
00613 std::vector<double> t;
00614 for(unsigned int i=0;i<c->t.size();i++)t.push_back(c->t[i]);
00615 std::vector<double> e;
00616 for(unsigned int i=0;i<c->e.size();i++)e.push_back(c->e[i]);
00617 std::vector<double> z;
00618 for(unsigned int i=0;i<c->z.size();i++)z.push_back(c->z[i]);
00619
00620 std::vector<int> cid;
00621 for(unsigned int i=0;i<c->cluster_id.size();i++)cid.push_back(c->cluster_id[i]);
00622
00623
00624 std::vector<int> children;
00625 for(unsigned int i=0;i<c->children.size();i++)children.push_back(c->children[i]);
00626
00627
00628
00629
00630 double close = fabs(z[0]-splitpointz);
00631 int cidx=0;
00632
00633 for(unsigned int i=1;i<z.size();i++)
00634 {
00635 if(fabs(z[i]-splitpointz)<close)
00636 {
00637 close = fabs(z[i]-splitpointz);
00638 cidx=i;
00639 }
00640 }
00641
00642 Chain newc;
00643
00644 c->ClearHits();
00645 for(int i=0;i<=cidx;i++)
00646 {
00647 c->add_to_back(t[i],z[i],e[i],cid[i]);
00648 }
00649
00650 c->children.clear();
00651 c->children.push_back(newc.myId);
00652
00653 for(unsigned int i=cidx;i<z.size();i++)
00654 {
00655 newc.add_to_back(t[i],z[i],e[i],cid[i]);
00656 }
00657
00658 newc.parentChain = c->myId;
00659 newc.children = children;
00660
00661 newc.level = c->level+1;
00662
00663 AttachAsChild(c, daughter);
00664
00665
00666
00667 return newc;
00668
00669
00670 }
00671
00672
00673 Chain * ChainHelper::SplitAt(Chain * c, double splitpointz)
00674 {
00675
00676
00677
00678
00679 if(c->end_z < splitpointz || c->start_z > splitpointz || c->entries<1)
00680 {
00681 printf("CANT SPLIT CHAIN - split point out of chain range\n");
00682 return c;
00683 }
00684
00685 std::vector<double> t;
00686 for(unsigned int i=0;i<c->t.size();i++)t.push_back(c->t[i]);
00687 std::vector<double> e;
00688 for(unsigned int i=0;i<c->e.size();i++)e.push_back(c->e[i]);
00689 std::vector<double> z;
00690 for(unsigned int i=0;i<c->z.size();i++)z.push_back(c->z[i]);
00691
00692 std::vector<int> cid;
00693 for(unsigned int i=0;i<c->cluster_id.size();i++)cid.push_back(c->cluster_id[i]);
00694
00695
00696 std::vector<int> children;
00697 for(unsigned int i=0;i<c->children.size();i++)children.push_back(c->children[i]);
00698
00699
00700
00701
00702
00703 double close = fabs(z[0]-splitpointz);
00704 int cidx=0;
00705
00706 for(unsigned int i=0;i<z.size();i++)
00707 {
00708 if(fabs(z[i]-splitpointz)<close)
00709 {
00710 close = fabs(z[i]-splitpointz);
00711 cidx=i;
00712 }
00713 }
00714
00715
00716 if (cidx==0 || cidx == (int)z.size()-1)return c;
00717
00718
00719
00720
00721
00722
00723 Chain newc;
00724
00725 c->ClearHits();
00726 for(int i=0;i<=cidx;i++)
00727 {
00728 c->add_to_back(t[i],z[i],e[i],cid[i]);
00729 }
00730
00731
00732
00733
00734
00735
00736 c->children.clear();
00737 c->children.push_back(newc.myId);
00738
00739
00740 for(unsigned int i=cidx;i<z.size();i++)
00741 {
00742 newc.add_to_back(t[i],z[i],e[i],cid[i]);
00743 }
00744
00745 newc.parentChain = c->myId;
00746 for(unsigned int child = 0;child < children.size();child++)
00747 newc.children.push_back(children[child]);
00748
00749 newc.level=c->level+1;
00750
00751
00752
00753
00754 int retid = c->myId;
00755 AddFinishedChain(newc);
00756
00757
00758
00759
00760 return GetChain(retid);
00761
00762 }
00763
00764
00765 void ChainHelper::finish()
00766 {
00767 for(unsigned int i=0;i<working.size();i++)
00768 {
00769 AddFinishedChain(working[i]);
00770
00771 }
00772
00773
00774 for(unsigned int i=0;i<finished.size();i++)
00775 {
00776 if(finished[i].parentChain<0)parents++;
00777 if(finished[i].muonfrac>0.8)muonlikechains++;
00778 if(finished[i].emlike>0.7)emlikechains++;
00779 }
00780 working.clear();
00781
00782 std::sort(finished.begin(), finished.end(), LTId() );
00783
00784
00785
00786 totalchains=finished.size();
00787
00788
00789 }
00790
00791
00792
00793
00794 void ChainHelper::print_finished()
00795 {
00796
00797 if(!MsgService::Instance()->IsActive("ChainHelper",Msg::kDebug))return;
00798
00799 cout<<"chain helper print_finished()\n";
00800
00801
00802 for(unsigned int i=0;i<finished.size();i++)
00803 {
00804
00805 std::ostringstream os;
00806
00807
00808 os <<"\n chain " <<finished[i].myId <<", parent " <<finished[i].parentChain <<", level " << finished[i].level <<", children ";
00809
00810
00811 for (unsigned int j=0;j<finished[i].children.size();j++)
00812 os<< finished[i].children[j] << " ";
00813 os << "\n";
00814
00815 os << " muonfrac " << finished[i].muonfrac <<", emlike " << finished[i].emlike <<", numpeaks " <<finished[i].num_peaks <<" strick inc " << finished[i].strict_increasing<<" dec " << finished[i].strict_decreasing<<" entries " << finished[i].entries<<endl;
00816
00817
00818
00819
00820 os << "start (t,z) (" << finished[i].start_t <<", "<< finished[i].start_z <<") end (t,z) (" << finished[i].end_t <<", "<< finished[i].end_z <<") avg slope " << finished[i].avg_slope<< " avg offset " << finished[i].avg_offset<<" last slope " << finished[i].last_slope<<" sum_e " <<finished[i].sum_e <<" avg_e " << finished[i].sum_e/finished[i].entries << "\n\t";
00821
00822 os << "front slope " << finished[i].front_slope << " front offset " << finished[i].front_offset << " back slope " << finished[i].back_slope << " back offset " << finished[i].back_offset<<"\n\t";
00823
00824
00825 for(unsigned int k=0;k<finished[i].t.size();k++)
00826 {
00827 os << "( " << finished[i].t[k] <<", "<< finished[i].z[k] << ", "<< finished[i].e[k] <<" - "<< finished[i].cluster_id[k]<<") ";
00828 }
00829
00830
00831
00832 cout<< os.str() << endl<<endl;
00833
00834 }
00835
00836
00837 }
00838
00839
00840
00841
00842 std::vector<int> ChainHelper::FindMaxPath()
00843 {
00844 if(found_max_path)return maxpath;
00845
00846
00847
00848
00849 double maxe=0;
00850 std::pair< std::vector<int>, double > maxp;
00851 for(unsigned int i=0;i<finished.size();i++)
00852 {
00853 if(finished[i].parentChain<0)
00854 {
00855
00856 std::pair< std::vector<int>, double > f = FindMaxPath(GetChain(finished[i].myId));
00857 if(f.second>maxe)
00858 {
00859 maxe=f.second;
00860 maxp=f;
00861 }
00862 }
00863 }
00864
00865
00866 ostringstream os;
00867
00868 os << "\nmaxpath found with energy "<< maxe <<endl;
00869
00870 os << "\t Chains : ";
00871 for(int i=maxp.first.size()-1;i>-1;i--)
00872 {
00873 int idx = maxp.first[i];
00874 os << idx <<" ";
00875 }
00876 os<<endl;
00877
00878 os << "\t Chain path : ";
00879
00880 for(int i=maxp.first.size()-1;i>-1;i--)
00881 {
00882 int idx = maxp.first[i];
00883
00884 os << " from (" << GetChain(idx)->start_z << " " << GetChain(idx)->start_t <<") to (" <<GetChain(idx)->end_z<< " " <<GetChain(idx)->end_t<< ") - ";
00885 }
00886
00887 os << "\n\t Chain energies : ";
00888
00889 if(maxp.first.size()>0)
00890 os <<" "<< GetChain(maxp.first[maxp.first.size()-1])->e[0] << " - ";
00891
00892 for(int i=maxp.first.size()-1;i>-1;i--)
00893 {
00894 int idx = maxp.first[i];
00895
00896
00897 for(unsigned int a=1;a<GetChain(idx)->e.size();a++)
00898 os << " " << GetChain(idx)->e[a] << " - ";
00899
00900 os << " --- ";
00901
00902
00903 }
00904
00905 MSG("ChainHelper",Msg::kDebug) << os.str() << endl;
00906
00907
00908
00909
00910 std::vector<int> rev;
00911 for(int i=maxp.first.size()-1;i>-1;i--)
00912 rev.push_back(maxp.first[i]);
00913
00914
00915 found_max_path=1;
00916
00917 maxpath = rev;
00918
00919 return rev;
00920 }
00921
00922
00923
00924 std::pair< std::vector<int>, double> ChainHelper::FindMaxPath(Chain *c)
00925 {
00926
00927
00928
00929 std::vector<int> v;
00930 double e;
00931
00932 if (c->children.size()<1)
00933 {
00934 v.push_back(c->myId);
00935 e=c->sum_e;
00936 return std::make_pair(v,e);
00937 }else{
00938
00939
00940 double maxe=0;
00941 std::pair< std::vector<int>, double > maxp;
00942 for(unsigned int i=0;i<c->children.size();i++)
00943 {
00944 Chain *nextchain = GetChain(c->children[i]);
00945 if(!nextchain)
00946 {
00947 MSG("ChainHelper",Msg::kWarning)<<"Call to child chain that does not exists!...."<<endl;
00948 continue;
00949 }
00950 std::pair< std::vector<int>, double > f = FindMaxPath(nextchain);
00951
00952 if(f.second>maxe)
00953 {
00954 maxe=f.second;
00955 maxp=f;
00956 }
00957 }
00958
00959
00960 maxp.first.push_back(c->myId);
00961 maxp.second+=c->sum_e;
00962
00963
00964
00965
00966 return maxp;
00967 }
00968
00969 }
00970
00971
00972 void ChainHelper::insert(double it, double iz, double ie, int my_cluster_id)
00973 {
00974
00975 int match=0;
00976
00977
00978 double closest_dt=100000;
00979 double closest_index=-1;
00980
00981
00982 double max_z_gap_temp=max_z_gap;
00983
00984 if(detector==Detector::kNear && iz > 6)
00985 {
00986 max_z_gap_temp*=5;
00987 }
00988
00989 std::vector<int> todel;
00990 for(unsigned int i=0;i<working.size();i++)
00991 {
00992 if(fabs(iz-working[i].end_z)>max_z_gap_temp)
00993 {
00994
00995 AddFinishedChain(working[i]);
00996 todel.push_back(i);
00997 continue;
00998 }
00999
01000
01001 double tslope = (working[i].end_t-it)/(working[i].end_z-iz);
01002
01003 if(fabs(tslope-working[i].last_slope)<max_slope)
01004 {
01005 match=1;
01006 double ldt=fabs(working[i].end_t-it);
01007 if(ldt<closest_dt)
01008 {
01009 closest_dt=ldt;
01010 closest_index=i;
01011 }
01012 }
01013 }
01014
01015
01019
01020
01021 for(unsigned int i=0;i<todel.size();i++)
01022 {
01023 working.erase(working.begin()+todel[i]-i);
01024 }
01025
01026
01027
01028
01029
01030
01031 if(!match)
01032 {
01033 Chain c;
01034 c.add_to_back(it,iz,ie,my_cluster_id);
01035 working.push_back(c);
01036 }
01037
01038 }
01039
01040
01041
01042 void ChainHelper::AttachAsChild(Chain * parent, Chain * child)
01043 {
01044 child->parentChain = parent->myId;
01045 parent->children.push_back(child->myId);
01046 MSG("ChainHelper",Msg::kDebug)<<"attaching "<<parent->myId<<" to "<< child->myId <<"setting child level from "<<child->level<<" to "<<1+parent->level <<endl;
01047 AdjustLevel(child, 1 + parent->level);
01048
01049 found_max_path=0;
01050 }
01051
01052
01053 void ChainHelper::AdjustLevel(Chain * c, int level)
01054 {
01055 if(!c)return;
01056 c->level=level;
01057 for(unsigned int i=0;i<c->children.size();i++)
01058 {
01059 Chain *d=GetChain(c->children[i]);
01060 if(d)
01061 AdjustLevel(d,level+1);
01062 else
01063 MSG("ChainHelper",Msg::kError)<<"bogus children list - parent id " << c->myId << " request for child with id "<< c->children[i]<<endl;
01064 }
01065 }
01066
01067
01068
01069
01070 std::vector<int> ChainHelper::GetAllChildren(Chain *c){
01071
01072 std::vector<int>ret;
01073 for(unsigned int i=0;i<c->children.size();i++)
01074 {
01075 Chain *me = GetChain(c->children[i]);
01076 if(!me)continue;
01077 std::vector<int> t= GetAllChildren(me);
01078 for(unsigned int j=0;j<t.size();j++)
01079 {
01080 ret.push_back(t[j]);
01081 }
01082 }
01083
01084 ret.push_back(c->myId);
01085 return ret;
01086
01087 }
01088
01089
01090 void ChainHelper::ChangeHitId(int oldid, int newid)
01091 {
01092 for(unsigned int i=0;i<finished.size();i++)
01093 {
01094 Chain *c = &(finished[i]);
01095 for(unsigned int j=0;j<c->cluster_id.size();j++)
01096 {
01097 if(c->cluster_id[j]==oldid)c->cluster_id[j]=newid;
01098 }
01099 }
01100 }
01101
01102
01103
01104 std::vector<foundpath> ChainHelper::FindPaths(Chain*c)
01105 {
01106 std::vector<foundpath> a;
01107 if(!c)
01108 {
01109
01110 return a;
01111 }
01112
01113
01114
01115
01116 if(c==0)return a;
01117
01118 if(c->children.size()<1)
01119 {
01120 foundpath b;
01121 b.end_t=c->end_t;
01122 b.end_z=c->end_z;
01123 b.energy=c->sum_e;
01124 b.muonlike=c->muonfrac;
01125 b.start_t=c->start_t;
01126 b.start_z=c->start_z;
01127 b.path.push_back(c->myId);
01128 b.entries=c->entries;
01129 a.push_back(b);
01130 return a;
01131 }
01132
01133 int foundsingle=0;
01134
01135 for(unsigned int i=0;i<c->children.size();i++)
01136 {
01137
01138 std::vector<foundpath> d = FindPaths(GetChain(c->children[i]));
01139
01140
01141
01142
01143 int issingle=0;
01144
01145 if(d.size()==1)
01146 if(d[0].path.size()==1)
01147 if(GetChain(d[0].path[0])->entries<3)
01148 issingle=1;
01149
01150
01151 if(issingle && ! foundsingle)
01152 a.push_back(d[0]);
01153 else if(!issingle)
01154 for(unsigned int j=0;j<d.size();j++)
01155 a.push_back(d[j]);
01156 if(issingle)foundsingle=1;
01157 }
01158
01159
01160 for(unsigned int i=0;i<a.size();i++)
01161 {
01162 a[i].start_t = c->start_t;
01163 a[i].start_z = c->start_z;
01164 a[i].energy+=c->sum_e;
01165 a[i].muonlike = (a[i].muonlike*a[i].entries + c->muonfrac*c->entries) / (a[i].entries+c->entries);
01166 a[i].entries+=c->entries -1;
01167 a[i].path.insert(a[i].path.begin(),c->myId);
01168 }
01169
01170 return a;
01171 }
01172
01173
01174