Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ChainHelper.cxx

Go to the documentation of this file.
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() // for manually adding a chain to finished...
00041 {
00042         Chain c;
00043         AddFinishedChain(c);
00044         return c.myId;
00045 
00046 }
00047 
00048 
00049 void ChainHelper::AddFinishedChain(Chain c)
00050 {
00051         //printf("ChainHelper adding chain %d\n",c.myId);
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 /*      std::map<int,int>::iterator it;
00077         it = idhelper.find(id);
00078         
00079         if(it!=idhelper.end())
00080                 return &finished[it->second];   ///does not check to see if it is valid!!!!!
00081 */      
00082         return 0;
00083 }
00084 
00085 
00086 void ChainHelper::DeleteChain(int id)
00087 {
00088         
00089         //cout << "deleting "<<id<<endl;
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                                 //cout<<"\t removing child reference from parent "<<todel->parentChain<<endl;
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         //rebuild helper!!!!
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;  //in case we deleted a chain in the max path
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         //reset found items, since we have added data
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                 //else see if there is a match....
00197                 
00198                 double dz=finished[longs[j]].start_z-finished[longs[i]].end_z;
00199                 
00200 //              double t1 = finished[longs[i]].end_t+finished[longs[i]].back_slope*dz;
00201 //              double t2 = finished[longs[j]].start_t-finished[longs[j]].front_slope*dz;
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         //std::vector<int> toadd(wsize);
00241         //for(int i=0;i<wsize;i++) toadd[i]=0;
00242         
00243         std::vector<Chain> tmpchain;
00244         
00245 
00246 
00247         //printf("%d clusters for this plane\n",pending_t.size());
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                 //if we are in the near... and in the calorimeter, we should increaze the z gap size
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) //same plane
00276                         {
00277                         //      printf("same plane %f\n",iz);
00278                                 continue;
00279                         }
00280                 
00281                 
00282                         if(fabs(iz-working[i].end_z)>max_z_gap_temp)
00283                         {
00284                                 //printf("removing chain %d from working list - it's too far away\n",working[i].myId);
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                 //      if(working[i].children.size()>0)continue; //should be finalized...
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 )// || fabs(working[i].last_slope) > 100000)
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                 //              if(working[i].good_slope())
00315                 //               dist = sqrt((working[i].end_t-it)*(working[i].end_t-it)+(tslope-working[i].last_slope)*(tslope-working[i].last_slope) );
00316                 //               else
00317                                  dist = fabs(working[i].end_t-it);
00318                                 
00319                                 //closest_t=closest_t<fabs(working[i].end_t-it) ?closest_t:fabs(working[i].end_t-it);
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)  //|| match==2)
00349                                 if(kinky < 0.1)
00350                                 {
00351                                         //if this is a match to a single hit...
00352                                         //make sure that there is not a single hit match with greater energy!                           
00353                                         //is single hit match?
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                         //printf("chain id %d  cluster idx %d  match %d\n",working[i].myId,j,match);
00380                 }
00381 
00382                 
00383                 int notyetdone=1;
00384                 //see if best match is more than 1 plane away....
00385                 //if it is, see if there is a working chain that had its tail at 1 plane away....
00386                 //but a hit in that chain at the same distance as this match is a better candidate....
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                                 //iterate over working chains, look for hit in same plane as current best guess
00397                                 for(unsigned int i=0;i<working.size();i++)
00398                                 {
00399                                         if(closest_index==(int)i)continue;//we want to consider other chains...
00400                                 
00401                                         //consider chains with 2+ hits
00402                                         if(working[i].entries<2)continue;
00403                                         if(fabs(iz-working[i].end_z) * 1.2 <zdist);
00404                                         {
00405                                                 //see if chain has hit in same plane as current candidate
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) //half a plane difference....
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                                         //make a new chain with this hit.. and attach it to the chain
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                                         //printf("!!! %d\n",pending_cluster_id[j]);
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         //this should consider direct pointing over closest match....
00453         //      if(closest_index<0)
00454         //      {
00455                 //make sure that there are no chains clearly pointing to this hit
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;//we want to consider other chains...
00461                                 
00462                         //consider chains with 2+ hits
00463                         if(working[i].entries<2)continue;
00464                 
00465                         //double tpos = working[i].back_offset + working[i].back_slope*iz; 
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                                 //are we close to the vertex?
00496                                 //printf("pending z t %f %f vtx %f %f\n",pending_z[j],pending_t[j],vtx_z,vtx_t);
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                                 //printf("!!! %d\n",pending_cluster_id[j]);
00503                                 //working.push_back(c);
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 //      for(int i=0;i<wsize;i++)
00520 //      {
00521 
00522     std::map<int, std::vector<int> >::iterator iter;
00523         for(iter=toadd.begin();iter!=toadd.end();iter++)
00524         {
00525 
00526                 //int s = toadd[i].size()>0;
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                         //need to copy the chains
00553                         for(int k=0;k<s;k++) //s-1
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                 //      int item=iter->second[s-1];
00563         //              working[iter->first].add_to_back(pending_t[item],pending_z[item],pending_e[item],pending_cluster_id[item]);
00564 //                      MSG("ChainHelper",Msg::kDebug)<<"adding to chain"<<endl;
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 //cout <<"????????? new id "<<r->myId << " split from "<<d->myId<<endl;
00594 
00595         return r;
00596 }
00597 
00598 Chain  ChainHelper::AttachAt(Chain *c, Chain * daughter, double splitpointz)
00599 {
00600 //      if(c->end_z < splitpointz || c->start_z > splitpointz || c->entries<1)
00601 //      {
00602         if(c->entries<1 || splitpointz < c->start_z || splitpointz > daughter->end_z){  //its ok if the split point is past the parent chain... then we just attach to the end!
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(); // can't split up the chain if we are not in the 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         //int pid = c->parentChain;
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         //find the split point
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         //printf("Request to split chain %d\n",c->myId);
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; // can't split up the chain if we are not in the chain...
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         //int pid = c->parentChain;
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         //find the split point
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; //cant split a chain at the first or last hit
00717         
00718         //printf("splitting at %d\n",cidx);
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++) //duplicate the head cluster
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         //printf("storing....\n");
00752 
00753 
00754         int  retid = c->myId;
00755         AddFinishedChain(newc);
00756 
00757         
00758         
00759         //printf("done\n");
00760         return GetChain(retid);  //reget the pointer...... adding to the finished vector can change the addresses...
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         //matchChains();
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 //find the continguous set of chains with the largest energy
00842 std::vector<int> ChainHelper::FindMaxPath()
00843 {
00844         if(found_max_path)return maxpath; //dont rerun it if it is already done
00845 
00846         //make a list of all "parent" chains (not a daughter of another chain)
00847         //for each in the list, 
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++) //start with 2nd in each chain to avoid double printing of first hit!
00898                         os << " " << GetChain(idx)->e[a] << " - "; 
00899                         
00900                         os << " --- ";
00901                                         
00902                                         
00903         }
00904 
00905         MSG("ChainHelper",Msg::kDebug) << os.str() << endl;
00906                 
00907         
00908         //since this vector was made recursively, the entries are backwards (from the end of the path to the beginning...) so reverse it
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 //for recursively 
00924 std::pair< std::vector<int>, double> ChainHelper::FindMaxPath(Chain *c)
00925 {
00926 
00927 
00928 //      printf("find max path chain id %d\n",c->myId);  
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                         //printf("maxpath on %d has e %f\n",nextchain->myId,f.second);
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         //find best chain match, and attach it
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                         //too far away in z, so mark this chain as finished
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); //need the extra i because items past deletion point will be shifted by 1 to the left for each previous deletion
01024         }
01025         
01026         
01027         
01028         
01029         
01030         //if no match found, start new chain
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); //increase the level of children 
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         //      printf("ChainHelper::FindPaths called without a chain!\n");
01110                 return a;
01111         }
01112         //printf("finding paths for chain %d has %d children\n",c->myId,c->children.size());
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                 //see 2+ of these paths are childless
01140                 //if so, see if they have the same number of hits
01141                 //if so, remove one of these for now....
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) //only store one!
01152                         a.push_back(d[0]);
01153                 else if(!issingle)//store them all
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); //this may give unfair (2x) weight to duplicated head entries in children!
01166                 a[i].entries+=c->entries -1; //head entry is duplicated in child!
01167                 a[i].path.insert(a[i].path.begin(),c->myId);  //perhaps should replace with a queue!
01168         }
01169 
01170         return a;
01171 }
01172 
01173 
01174 

Generated on Mon Feb 15 11:06:31 2010 for loon by  doxygen 1.3.9.1