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

Chain.cxx

Go to the documentation of this file.
00001 #include "NueAna/ParticlePID/ParticleFinder/Chain.h"
00002 #include "MessageService/MsgService.h"
00003 
00004 #include <math.h>
00005 
00006 CVSID("$Id: Chain.cxx,v 1.2 2009/06/23 22:42:24 scavan Exp $");
00007 
00008 ClassImp(Chain)
00009 
00010 
00011 int Chain::lastid = 0;
00012 
00013 Chain::Chain()
00014 {
00015 
00016         start_t=0.0;
00017         end_t=0.0;
00018         start_z=0.0;
00019         end_z=0.0;
00020         particletype=0;
00021         sum_e=0.0;
00022         weighted_t=0.0;
00023         entries=0;
00024         avg_slope=0.0;
00025         avg_offset=0.0;
00026         last_slope=0.0;
00027         front_slope=0.0;
00028         back_slope=0.0;
00029         front_offset=0.0;
00030         back_offset=0.0;
00031         parentChain=-1;
00032         myId=-1;
00033         level=0;
00034         muonfrac=0.0;
00035         interior_muonfrac=0.0;
00036         emlike=0.0;
00037         num_peaks=0;
00038         strict_decreasing=1;
00039         strict_increasing=1;
00040         lastpeake=0.0;
00041         lastpeakprob=0;
00042         sum_z=0.0;
00043         sum_t=0.0;
00044         sum_z_z=0.0;
00045         sum_z_t=0.0;
00046         muonlike=0;
00047         a=0.0;
00048         b=0.0;
00049 
00050 
00051 
00052 
00053         t.clear();
00054         z.clear();
00055         e.clear();
00056         cluster_id.clear();
00057         children.clear();
00058 
00059         myId=lastid++;
00060         
00061         
00062         muon_threshold_max=2;
00063         muon_threshold_min=0.5;
00064         muon_min_hits=2; 
00065         
00066         available=1;
00067         
00068 }
00069 
00070 Chain::~Chain()
00071 {
00072         t.clear();
00073         z.clear();
00074         e.clear();
00075         cluster_id.clear();
00076         children.clear();
00077 }
00078 
00079 void Chain::ResetCounter()
00080 {
00081         lastid=0;
00082 }
00083 
00084 
00085 //interpolate the front of the chain....
00086 double Chain::interpolate(double test_z)
00087 {
00088         double int_t=0;
00089         if(z.size()<1)return 0;
00090 /*
00091         printf("nentries %d\n",z.size());
00092         for(unsigned int i=0;i<z.size();i++)
00093         {
00094                 printf("zt %f %f\n",z[i],t[i]);
00095         
00096         }
00097 */      
00098         
00099         //hack to remove entries with the same z position.... we should really be merging clusters.....
00100         
00101         std::vector<double>z;
00102         std::vector<double>t;
00103         std::vector<double>e;
00104 
00105 
00106 /*
00107         printf("raw nentries %d\n",this->z.size());
00108         for(unsigned int i=0;i<this->z.size();i++)
00109         {
00110                 printf("zt %f %f\n",this->z[i],this->t[i]);
00111         
00112         }       */
00113         
00114         
00115         z.push_back(this->z[0]);
00116         t.push_back(this->t[0]*this->e[0]);
00117         e.push_back(this->e[0]);
00118         int cnt=0;
00119         for(unsigned int i=1;i<this->z.size();i++)
00120         {
00121                 if(fabs(this->z[i]-this->z[i-1])>0.001)
00122                 {
00123                         cnt++;          
00124                         z.push_back(this->z[i]);
00125                         t.push_back(this->t[i]*this->e[i]);
00126                         e.push_back(this->e[i]);        
00127                 }else{
00128                         t[cnt]+=this->t[i]*this->e[i];
00129                         e[cnt]+=this->e[i];
00130                 }       
00131         }       
00132         
00133         for(unsigned int i=0;i<z.size();i++)
00134         {       
00135                 t[i]/=e[i];
00136         }
00137 
00138 /*      
00139         printf("clean nentries %d\n",z.size());
00140         for(unsigned int i=0;i<z.size();i++)
00141         {
00142                 printf("zt %f %f\n",z[i],t[i]);
00143         
00144         }       */
00145 
00146         
00147 
00148         if(z.size()>2)
00149         {       
00150         
00151                 if(test_z>=end_z)
00152                 {
00153                         int i=z.size()-1;
00154                         if(i>1)
00155                                 int_t = interpolate(z[i],t[i],z[i-1],t[i-1],z[i-2],t[i-2],test_z);
00156                 }else if(test_z<=start_z)
00157                 {
00158                         if(z.size()>2)
00159                                 int_t = interpolate(z[0],t[0],z[1],t[1],z[2],t[2],test_z);
00160                 }else{
00161                         int i=z.size()-1;
00162                         if(i>1)
00163                                 int_t = interpolate(z[i],t[i],z[i-1],t[i-1],z[i-2],t[i-2],test_z);
00164                         if(z.size()>2)
00165                                 int_t += interpolate(z[0],t[0],z[1],t[1],z[2],t[2],test_z);
00166                                 
00167                         int_t /=2;      
00168                 }
00169 
00170         }else if(z.size()>1)
00171         {
00172                 int end = z.size()-1;
00173                 double dz = z[end]-z[end-1];
00174                 double dt = t[end]-t[end-1];
00175                 if(dz!=0)
00176                 {
00177                         double slope = dt/dz;
00178                         int_t = (test_z-z[end-1])*slope+t[end-1];
00179                 }
00180         }else if(z.size()==1)
00181         {
00182                 int_t = t[0];
00183         }
00184 
00185 
00186         
00187 
00188         return int_t;
00189 }
00190 
00191 
00192 double Chain::interpolate(double z0, double t0, double z1, double t1, double z2, double t2, double z)
00193 {
00194         double int_t=0;
00195   
00196     //for quadratic     
00197         double L0 = (z-z1)*(z-z2)/( (z0-z1)*(z0-z2));
00198         double L1 = (z-z0)*(z-z2)/( (z1-z0)*(z1-z2));   
00199         double L2 = (z-z0)*(z-z1)/( (z2-z0)*(z2-z1));
00200 
00201         int_t = t0*L0 + t1*L1 + t2*L2;
00202 
00203 //      printf("quad inter L0 %f L1 %f L2 %f   z0 %f z1 %f z2 %f  t0 %f t1 %f t2 %f\n",L0,L1,L2,z0,z1,z2,t0,t1,t2);
00204 
00205         return int_t;
00206 }
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 void Chain::Recalc()
00219 {
00220 
00221                 std::vector<double>mt=t;
00222                 std::vector<double>mz=z;
00223                 std::vector<double>me=e;
00224                 std::vector<int>mc=cluster_id;
00225                 
00226                 ClearHits();
00227                 
00228                 for(unsigned int i=0;i<mt.size();i++)
00229                         if(me[i]>0)insert(mt[i],mz[i],me[i],cluster_id[i]);
00230 
00231 
00232 
00233 }
00234 
00235 
00236 //cause the chain to reverse itself... 
00237 //care must be taken with parent, children, which are not effected by this function
00238 void Chain::Reverse()
00239 {
00240 
00241         //printf("reversing\n");
00242 
00243                 std::vector<double>mt;
00244                 for(unsigned int i=0;i<t.size();i++)mt.push_back(t[i]);
00245                 std::vector<double>mz;
00246                 for(unsigned int i=0;i<z.size();i++)mz.push_back(z[i]);
00247                 std::vector<double>me;
00248                 for(unsigned int i=0;i<e.size();i++)me.push_back(e[i]);
00249                 
00250                 std::vector<int>mc;
00251                 for(unsigned int i=0;i<cluster_id.size();i++)mc.push_back(cluster_id[i]);
00252                 
00253                 //printf("sv\n");
00254                 
00255                 ClearHits();
00256                 
00257                 //printf("cleared hits\n");
00258                 
00259                 for(int i=mt.size()-1;i>-1;i--)
00260                         add_to_back(mt[i],mz[i],me[i],cluster_id[i]);
00261 
00262 
00263                 //printf("done\n");
00264 
00265 }
00266 
00267 //for clearing information about hits....
00268 //does not reset id, parent, or children information
00269 void Chain::ClearHits()
00270 {
00271         start_t=0.0;
00272         end_t=0.0;
00273         start_z=0.0;
00274         end_z=0.0;
00275         sum_e=0.0;
00276         weighted_t=0.0; 
00277         entries=0;
00278         avg_slope=0.0;
00279         avg_offset=0.0;
00280         last_slope=0.0;
00281         front_slope=0.0;
00282         back_slope=0.0;
00283         muonfrac=0.0;
00284         interior_muonfrac=0.0;
00285         emlike=0.0;
00286         num_peaks=0;
00287         strict_decreasing=1;
00288         strict_increasing=1;
00289         lastpeake=0.0;
00290         lastpeakprob=0;
00291         sum_z=0.0;
00292         sum_t=0.0;
00293         sum_z_z=0.0;
00294         sum_z_t=0.0;
00295         muonlike=0;
00296         a=0.0;
00297     b=0.0;
00298 
00299 
00300         z.clear();
00301         e.clear();
00302         t.clear();
00303         cluster_id.clear();
00304 
00305 }
00306 
00307 
00308 void Chain::PrintChain()
00309 {
00310 
00311         if(!MsgService::Instance()->IsActive("Chain",Msg::kDebug))return;
00312 
00313         printf("Chain %d \n",myId);
00314         printf("%d entries    start_t %f start_z %f  end_t %f end_z %f\n",entries,start_t,start_z,end_t,end_z);
00315         printf("sume %f   avg_slope %f lastslope %f  frontslope %f backslope %f\n",sum_e,avg_slope,last_slope,front_slope,back_slope);
00316         printf("muonfrac %f, intmf %f, emlike %f, peaks %d, sdec %d, sinc %d\n",muonfrac, interior_muonfrac, emlike, num_peaks,strict_decreasing, strict_increasing);
00317         
00318         printf(" hits (t,z,e) : ");
00319         for(unsigned int i=0;i<t.size();i++)
00320                 printf(" (%f, %f, %f - %d)", t[i],z[i],e[i],cluster_id[i]);
00321         printf("\n");
00322 
00323 
00324 }
00325 
00326 
00327 void Chain::updateMuonFrac(double /*it*/, double /*iz*/, double ie)
00328 {
00329         if(ie < muon_threshold_max && ie > muon_threshold_min)
00330         {
00331         
00332                 if(entries>2)
00333                 {
00334                         int cntfirst=0;
00335                         if ( e[0] <  muon_threshold_max && e[0] > muon_threshold_min ) cntfirst=1;
00336                         interior_muonfrac = (double)(muonlike - cntfirst) / (double)(entries-2);
00337                 }
00338                 
00339                 muonlike++;
00340                 if (muon_min_hits <= entries ) muonfrac = (double)muonlike / (double)entries;
00341         }
00342 
00343 }
00344 
00345 void Chain::updateNumPeaks(double /*it*/, double /*iz*/, double ie)
00346 {
00347         if(entries>1)
00348         if(ie < lastpeake && lastpeakprob)
00349         {
00350                 num_peaks++;
00351                 lastpeakprob = 0;
00352         }else if(ie > lastpeake)
00353         {
00354                 lastpeakprob = 1;
00355         }
00356 
00357 
00358         if(entries>1)
00359         {
00360                 if(ie <= lastpeake) strict_increasing=0;
00361                 if(ie >= lastpeake) strict_decreasing=0;
00362         }
00363         
00364 
00365         lastpeake = ie;
00366         
00367 }
00368 
00369 void Chain::updateEMLike(double /*it*/, double /*iz*/, double /*ie*/)
00370 {
00371         //for now its emlike if it has 1 peak.... make it better later...
00372         emlike = num_peaks==1;
00373 }
00374 
00375 
00376 int Chain::good_slope()
00377 {
00378         //tell us if we have enough points to believe the slope value
00379         
00380         int good=0;
00381         
00382         if(t.size()>1)good=1;
00383         
00384         return good;
00385 }
00386 
00387 
00388 //insert a cluster in the proper position, keeping the beginning upstream
00389 void Chain::insert(double it, double iz, double ie, int my_cluster_id)
00390 {
00391 
00392         double lastt = 0.0;
00393         double lastz = 0.0;
00394         double laste = 0.0;
00395 
00396         if(t.size()>0)
00397         {
00398                 lastt=t.back();
00399                 lastz=z.back();
00400                 laste=e.back();
00401         }
00402         
00403         int insert_idx=-1;
00404         for(unsigned int i=0;i<t.size();i++)
00405         {
00406                 if(iz<z[i])
00407                 {
00408                         insert_idx=i;
00409                         break;
00410                 }
00411         }
00412         
00413         if(t.size()==0)
00414         {
00415                 start_t=it;
00416                 start_z=iz;
00417                 end_t=it;
00418                 end_z=iz;       
00419         }       
00420 /*      
00421         if(insert_idx==0)
00422         {
00423                 start_t=it;
00424                 start_z=iz;
00425         }
00426         
00427         if(insert_idx==t.size()-1)
00428         {
00429                 end_t=it;
00430                 end_z=iz;
00431         }
00432 */
00433 
00434         if(start_z>iz)
00435         {
00436                 start_z=iz;
00437                 start_t=it;
00438         }
00439         
00440         if(end_z<iz)
00441         {
00442                 end_z=iz;
00443                 end_t=it;
00444         }
00445         
00446         weighted_t*=sum_e;
00447         weighted_t +=it*ie;
00448         
00449         sum_e+=ie;
00450         
00451         weighted_t /=sum_e;
00452         
00453         entries++;
00454         if(insert_idx>-1)
00455         {
00456                 std::vector<double>::iterator itr_f=t.begin();
00457                 itr_f+=insert_idx;
00458                 t.insert(itr_f,it);
00459                 itr_f=z.begin();
00460                 itr_f+=insert_idx;
00461                 z.insert(itr_f,iz);
00462                 itr_f=e.begin();
00463                 itr_f+=insert_idx;
00464                 e.insert(itr_f,ie);
00465                 std::vector<int>::iterator itr_i=cluster_id.begin();
00466                 itr_i+=insert_idx;
00467                 cluster_id.insert(itr_i,my_cluster_id);
00468         }else{
00469                 t.push_back(it);
00470                 z.push_back(iz);
00471                 e.push_back(ie);
00472                 cluster_id.push_back(my_cluster_id);
00473         }
00474         //printf("added %f %f %f %d\n",it,iz,ie,my_cluster_id);
00475                 
00476         sum_z+=iz;
00477         sum_t+=it;
00478         sum_z_z+=iz*iz;
00479         sum_z_t+=iz*it;
00480         
00481                 
00482         double n=(double)entries;
00483         if(n>1 && (n*sum_z_z-(sum_z)*(sum_z))!=0) 
00484         {
00485                 a=(sum_t*sum_z_z-sum_z*sum_z_t)/(n*sum_z_z-(sum_z)*(sum_z));
00486                 b=(n*sum_z_t-sum_z*sum_t)/(n*sum_z_z-(sum_z)*(sum_z));  
00487         }
00488         
00489         avg_slope = b;
00490         avg_offset = a;
00491         
00492         if(entries>1 && lastz-iz)last_slope =(lastt-it)/(lastz-iz);
00493         
00494         
00495         if(entries>1 && entries<=4)
00496         {
00497                 front_slope=b;
00498                 front_offset=a;
00499                 back_slope=b;
00500                 back_offset=a;
00501         }
00502         if(entries>4)
00503         {
00504                 //back slope
00505                 int n=4;
00506                 double sum_z_t=0;
00507                 double sum_z=0;
00508                 double sum_t=0;
00509                 double sum_z_z=0;
00510                 
00511                 for(unsigned int i=e.size()-1;i>e.size()-5;i--)
00512                 {
00513                         sum_z+=z[i];
00514                         sum_t+=t[i];
00515                         sum_z_t+=z[i]*t[i];
00516                         sum_z_z+=z[i]*z[i];
00517                 }
00518                 
00519         
00520                 if(fabs(n*sum_z_z-(sum_z)*(sum_z))>1e-10)
00521                 {       
00522                         back_slope=(n*sum_z_t-sum_z*sum_t)/(n*sum_z_z-(sum_z)*(sum_z));
00523                         back_offset=(sum_t*sum_z_z-sum_z*sum_z_t)/(n*sum_z_z-(sum_z)*(sum_z));
00524                 }
00525                 
00526                 //front slope
00527                 n=4;
00528                 if(entries>12)n=entries/3;
00529                 if(n>10)n=10;
00530                 sum_z_t=0;
00531                 sum_z=0;
00532                 sum_t=0;
00533                 sum_z_z=0;
00534                 
00535                 for(int i=0;i<n;i++)
00536                 {
00537                         sum_z+=z[i];
00538                         sum_t+=t[i];
00539                         sum_z_t+=z[i]*t[i];
00540                         sum_z_z+=z[i]*z[i];
00541                 }
00542                 
00543                 if(fabs(n*sum_z_z-(sum_z)*(sum_z))>1e-10)
00544                 {       
00545                         front_slope=(n*sum_z_t-sum_z*sum_t)/(n*sum_z_z-(sum_z)*(sum_z));
00546                         front_offset=(sum_t*sum_z_z-sum_z*sum_z_t)/(n*sum_z_z-(sum_z)*(sum_z));         
00547                 }
00548         }
00549         
00550                 
00551         updateMuonFrac(it, iz, ie);
00552         updateNumPeaks(it, iz, ie);
00553         updateEMLike(it, iz, ie);
00554 
00555 }
00556 
00557 
00558 void Chain::add_to_back(double it, double iz, double ie, int my_cluster_id)
00559 {
00560 
00561         double lastt = 0.0;
00562         double lastz = 0.0;
00563         double laste = 0.0;
00564 
00565         if(t.size()>0)
00566         {
00567                 lastt=t.back();
00568                 lastz=z.back();
00569                 laste=e.back();
00570         }else{
00571                 start_t=it;
00572                 start_z=iz;
00573         }
00574         
00575         weighted_t*=sum_e;
00576         weighted_t +=it*ie;
00577         
00578         sum_e+=ie;
00579         
00580         weighted_t /=sum_e;
00581         
00582         entries++;
00583 
00584         t.push_back(it);
00585         z.push_back(iz);
00586         e.push_back(ie);
00587         cluster_id.push_back(my_cluster_id);
00588         
00589         //printf("added %f %f %f %d\n",it,iz,ie,my_cluster_id);
00590                 
00591         sum_z+=iz;
00592         sum_t+=it;
00593         sum_z_z+=iz*iz;
00594         sum_z_t+=iz*it;
00595         
00596         end_t=it;
00597         end_z=iz;
00598         
00599         
00600         double n=(double)entries;
00601         if(n>1 && fabs(n*sum_z_z-(sum_z)*(sum_z))>1e-10 )
00602         {
00603                 a=(sum_t*sum_z_z-sum_z*sum_z_t)/(n*sum_z_z-(sum_z)*(sum_z));
00604                 b=(n*sum_z_t-sum_z*sum_t)/(n*sum_z_z-(sum_z)*(sum_z));  
00605         }
00606         
00607         avg_slope = b;
00608         avg_offset = a;
00609         
00610         if(entries>1 && lastz-iz)last_slope =(lastt-it)/(lastz-iz);
00611         
00612         
00613         if(entries>1 && entries<=4)
00614         {
00615                 front_slope=b;
00616                 front_offset=a;
00617                 back_slope=b;
00618                 back_offset=a;
00619         }
00620         if(entries>4)
00621         {
00622                 int n=4;
00623                 double sum_z_t=0;
00624                 double sum_z=0;
00625                 double sum_t=0;
00626                 double sum_z_z=0;
00627                 
00628                 for(unsigned int i=e.size()-1;i>e.size()-5;i--)
00629                 {
00630                         sum_z+=z[i];
00631                         sum_t+=t[i];
00632                         sum_z_t+=z[i]*t[i];
00633                         sum_z_z+=z[i]*z[i];
00634                 }
00635                 
00636                 if(fabs(n*sum_z_z-(sum_z)*(sum_z))>1e-10)
00637                 {       
00638                         back_slope=(n*sum_z_t-sum_z*sum_t)/(n*sum_z_z-(sum_z)*(sum_z));
00639                         back_offset=(sum_t*sum_z_z-sum_z*sum_z_t)/(n*sum_z_z-(sum_z)*(sum_z));
00640                 }
00641         }
00642         
00643         
00644         updateMuonFrac(it, iz, ie);
00645         updateNumPeaks(it, iz, ie);
00646         updateEMLike(it, iz, ie);
00647 
00648 }

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