Privacy and Security Notice

treematch.cc Source File

treematch.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include "treematch.h"
00003 #include "treecombine.h"
00004 
00005 #include <fstream>
00006 using namespace std;
00007 
00013 extern Det *rcDETRegion[2][3][4];
00014 
00015 
00016 
00017 
00018 //________________________________________________________________________
00019 double rcPEval( double vz, double te, double ph, double bend){
00020 cerr << "ERROR : THIS FUNCTION IS ONLY A STUB rcPEval " << endl;
00021 return -1000;
00022 }
00023 //________________________________________________________________________
00024 double rcZEval( double vz, double te, double ph, double mom, int idx){
00025 cerr << "ERROR : THIS FUNCTION IS ONLY A STUB rcZEval " << endl;
00026 return -1000;
00027 }
00028 //________________________________________________________________________
00029 Hit *bestWireHit(TreeLine *walk,double bestpos=0){//returns the best measured wire hit
00030   double pos=9999,newpos;
00031   int ibest;
00032   for(int i =0;i<walk->numhits;i++){//get the best measured hit in the back
00033     newpos = walk->hits[i]->rPos-bestpos;
00034     if(newpos < 0)newpos = -newpos;
00035     if(newpos < pos){
00036       pos = newpos;
00037       ibest = i;
00038     }
00039   }
00040 return walk->hits[ibest];
00041 }
00042 //________________________________________________________________________
00043 
00044 treematch::treematch(){
00045 
00046 }
00047 //________________________________________________________________________
00048 treematch::~treematch(){
00049 
00050 }
00051 //________________________________________________________________________
00052 // This function requires the wire planes to be parallel
00053 /* VDC reference frame : The center of the upstream u or v wire plane is placed at the origin.  The u or v wire plane is in the y-z plane.  The center of the downstream u or v plane is at (d,d2,0).  The line slopes are calculated with a different reference frame: distance between wires representing dy and distance from wire representing dx.
00054 */
00055 TreeLine *treematch::MatchR3(TreeLine *front,TreeLine *back,EUppLow up_low,ERegion region, Edir dir){
00056   //###############
00057   // DECLARATIONS #
00058   //###############
00059   //cerr << "trelin rpos = " << front->hits[0]->rPos << endl;
00060   TreeLine *combined,*fwalk,*bwalk;
00061   double x[2],y[2],z[3],zp[2];
00062   Hit *fpos,*bpos;
00063   double d,d2,d_uv,xp,B,A;
00064   double pi = acos(-1),theta;
00065   double wirespacingf,wirespacingb,d_to_1st_wire_f,d_to_1st_wire_b;
00066   Det *rd;
00067   int i,j,k;
00068   double slope,intercept,fslope,bslope;
00069   int numflines=0,numblines=0;
00070   double fsloperes,bsloperes;
00071   double bestmatch;
00072   TreeLine  *lineptr;
00073   double mx,cx,cov[3],chi;
00074   int nhits,fhits,bhits;
00075   treecombine TreeCombine;
00076   Hit *DetecHits[2*TLAYERS];
00077 
00078   ofstream gnu1,gnu2;
00079   gnu1.open("gnu1.dat");
00080   gnu2.open("gnu2.dat");
00081   //###################################
00082   // Get distance between planes, etc #
00083   //###################################
00084   rd = rcDETRegion[up_low][region-1][dir];
00085   theta = rd->Rot/360*2*pi;
00086   //get the u value for the first wire.
00087   d_to_1st_wire_f = rd->rSin * rd->PosOfFirstWire;
00088   // due to reverse order
00089   d_to_1st_wire_f = d_to_1st_wire_f - rd->NumOfWires * rd->WireSpacing;   
00090   wirespacingf = rd->WireSpacing;
00091   fsloperes = rd->SlopeMatching;
00092   x[0]= rd->center[0];
00093   y[0]= rd->center[1]; 
00094   z[0]= rd->Zpos;
00095   zp[0] = z[0]-y[0]/tan(theta);
00096 
00097   rd = rd->nextsame;  
00098   x[1]= rd->center[0];
00099   y[1]= rd->center[1];
00100   z[1]= rd->Zpos; 
00101   zp[1] = z[1]-y[1]/tan(theta);
00102 
00103   d = (zp[1]-zp[0])*sin(theta);//<-distance between planes
00104   //cerr << "d = " << d << endl;
00105   wirespacingb = rd->WireSpacing;
00106   bsloperes = rd->SlopeMatching;
00107   //get the u value for the first wire.
00108   d_to_1st_wire_b = rd->rSin * rd->PosOfFirstWire;
00109   // due to reverse order
00110   d_to_1st_wire_b = d_to_1st_wire_b - rd->NumOfWires * rd->WireSpacing;  
00111 
00112   if(dir == v_dir){//get the distance between the u and v planes
00113     d_uv = (rcDETRegion[up_low][region-1][v_dir]->Zpos-rcDETRegion[up_low][region-1][u_dir]->Zpos);  
00114     d_uv*= rcDETRegion[up_low][region-1][u_dir]->rRotCos;
00115   }
00116   //######################################
00117   // Get the radial offset of the planes #
00118   //######################################
00119   //warning : this assumes the planes are parallel.
00120   
00121   z[2] = z[0]+d*sin(theta);
00122   //d2 = (z[2]-z[1])/cos(theta);
00123   d2 = (y[1]-y[0])/sin(theta)+(zp[1]-zp[0])*cos(theta);
00124   //cerr << "d2 = " << d2 << endl;
00125   //##########################
00126   //Revise the hit positions #
00127   //##########################
00128 
00129   for(int i =0;i<282;i++){
00130         gnu2 << "0 " << d_to_1st_wire_f + i*wirespacingf << " " << d << " " << d_to_1st_wire_b + i*rd->WireSpacing +d2 << endl;  
00131   } 
00132   for(fwalk = front;fwalk;fwalk = fwalk->next){
00133     numflines++;
00134     //cerr << "isvoid = " << fwalk->isvoid << "," << fwalk->numhits << endl;
00135     for(i=0;i<fwalk->numhits;i++){
00136       fwalk->hits[i]->Zpos = fwalk->hits[i]->wire * wirespacingf + d_to_1st_wire_f;
00137       if(dir == v_dir)fwalk->hits[i]->rPos+= d_uv;
00138     }
00139   }
00140   for(bwalk = back;bwalk;bwalk = bwalk->next){
00141     numblines++;
00142     for(i=0;i<bwalk->numhits;i++){
00143       bwalk->hits[i]->Zpos = (bwalk->hits[i]->wire - rd->NumOfWires) * wirespacingb + d_to_1st_wire_b + d2;
00144       bwalk->hits[i]->rPos = bwalk->hits[i]->rPos + d;
00145       if(dir == v_dir)bwalk->hits[i]->rPos+= d_uv;
00146     }
00147   }
00148   fwalk = front;
00149   bwalk = back;
00150   
00151   for(i=0;i<fwalk->numhits;i++){
00152     gnu1 << fwalk->hits[i]->Zpos << " " << fwalk->hits[i]->rPos << endl;
00153   }
00154   for(i=0;i<bwalk->numhits;i++){
00155     gnu1 << bwalk->hits[i]->Zpos << " " << bwalk->hits[i]->rPos << endl;
00156   }
00157   
00158 
00159   int matches[numflines];
00160   int bmatches[numblines];
00161   double bestmatches[numblines];
00162   //###############################
00163   // Find matching track segments #
00164   //###############################
00165   for(i=0;i<numblines;i++)bestmatches[i]=99;
00166   i=0;
00167   for(fwalk = front;fwalk;fwalk = fwalk->next){//loop over front track segments
00168     matches[i]=-1;
00169     if(fwalk->isvoid == 0){//skip it if it's no good
00170       fpos = bestWireHit(fwalk);
00171       j=0;
00172       bestmatch=99;
00173       for(bwalk = back;bwalk;bwalk = bwalk->next){
00174         j++;
00175         if(bwalk->isvoid !=0)continue;
00176         bpos = bestWireHit(bwalk,d);
00177 
00178         y[0]=fpos->Zpos;
00179         y[1]=bpos->Zpos;        
00180         x[0]=fpos->rPos;
00181         x[1]=bpos->rPos;
00182 
00183         slope = (y[1]-y[0])/(x[1]-x[0]);
00184         intercept = y[1]-slope*x[1];
00185 
00186         fslope = wirespacingf/fwalk->mx;
00187         bslope = wirespacingb/bwalk->mx;
00188         if(fabs(fslope-slope)<=fsloperes && fabs(bslope-slope)<=bsloperes
00189            && fabs(fslope-slope)+fabs(bslope-slope)<bestmatch){//if it's a good match
00190           if(bestmatches[j-1]!=99){// if the back segment has been matched already
00191                 bestmatch = fabs(fslope-slope)+fabs(bslope-slope);
00192                 if(bestmatch > bestmatches[j-1])continue;//check if it's better
00193                 else matches[bmatches[j-1]]=-1;//if so, remove the bad match
00194           }
00195           matches[i]=j-1;//set the match on both match arrays
00196           bmatches[j-1]=i;
00197           bestmatch = bestmatches[j-1] = fabs(fslope-slope)+fabs(bslope-slope);
00198           //cerr << "match = " << i << "->" << j-1 << endl;
00199           
00200         }
00201 
00202         //cerr << x[0] << "," << y[0] << "," << x[1] << "," << y[1] << endl;
00203 
00204         //cerr << "slope = " << fslope << "," << slope << "," << bslope << endl;
00205         //cerr << "line = " << slope << "*x + " << intercept << endl;
00206         //cerr << "fline = " << wirespacingf/fwalk->mx << "*x + " << -wirespacingf*fwalk->cx/fwalk->mx + d_to_1st_wire_f<< endl;
00207       }
00208     }
00209     i++;
00210   }
00211   //################################
00212   // Create the combined treelines #
00213   //################################ 
00214   lineptr = (TreeLine*)malloc(sizeof(TreeLine));
00215   assert(lineptr);
00216 
00217   for(fwalk = front,i=0;fwalk;fwalk = fwalk->next,i++){
00218     for(bwalk = back,j=0;bwalk;bwalk = bwalk->next,j++){
00219       if(matches[i]==j){//if this front segment was matched to this back segment
00220         //set the hits
00221         fhits = fwalk->numhits;
00222         bhits = bwalk->numhits;
00223         for(k=0;k<fhits;k++){
00224           DetecHits[k]=fwalk->hits[k];
00225           lineptr->hits[k]=fwalk->hits[k];
00226         }
00227         for(k=0;k<bhits;k++){
00228           DetecHits[k+fhits]=bwalk->hits[k];
00229           lineptr->hits[k+fhits]=bwalk->hits[k];
00230         }
00231         nhits = fhits + bhits;
00232 
00233 
00234         for(k=0;k<nhits;k++){
00235          // cerr << DetecHits[k]->Zpos << " " << DetecHits[k]->rPos << endl;
00236         }
00237         //fit a line to the hits
00238         TreeCombine.weight_lsq_r3(&mx,&cx,cov,&chi,DetecHits,nhits,0,-1,2*TLAYERS);
00239         lineptr->mx = mx;
00240         lineptr->cx = cx;
00241         lineptr->chi = chi;
00242         lineptr->numhits = nhits;
00243         lineptr->nummiss = 2*TLAYERS - nhits;
00244         lineptr->isvoid = false;
00245 
00246         //cerr << "line = " << 1/mx << "x + (" << -cx/mx << ")" << endl;
00247         //string the tracks together
00248         lineptr->next = combined;
00249         combined = lineptr;
00250       }
00251     }
00252   }
00253 
00254 
00255 
00256   
00257   gnu1.close();
00258   gnu2.close();
00259   combined->next = 0;
00260   return combined;
00261 }
00262 //________________________________________________________________________
00263 void treematch::TgTrackPar( PartTrack *front, PartTrack *back,double *theta, double *phi, double *bending, double *ZVertex )
00264 {
00265         *theta = atan( front->mx);
00266         *phi   = atan( front->my);
00267         if( bending && back )
00268                 *bending = atan( back->mx) - *theta;
00269         *ZVertex =  - ( ( front->mx * front->x  + front->my * front->y )
00270                         /( front->mx * front->mx + front->my * front->my));
00271 }
00272 
00273 
00274 //________________________________________________________________________
00275 Track * treematch::TgPartMatch( PartTrack *front, PartTrack *back, Track *tracklist,
00276              enum EUppLow upplow/*, enum Emethod method*/)
00277 {
00278   double bestchi = 1e10, chi;
00279   double v1,v2, v3;
00280   Track *ret = 0, *newtrack = 0, *besttrack = 0, *trackwalk, *ytrackwalk;
00281   Bridge *bridge;
00282   //int m = method == meth_std ? 0 : 1;
00283   double theta, ZVertex, phi, bending, P;
00284 
00285   
00286 
00287 
00288   while( back) {
00289     /* --------- check for the cuts on magnetic bridging ------------ */ 
00290     if(   back->isvoid == false
00291          //removed all the following cuts
00292           /*&& (fabs(front->y-back->y))            < rcSET.rMagnMatchY[m]*3.0 
00293           && (fabs(front->x-back->x ))           < rcSET.rMagnMatchX[m]*3.0
00294           && ( (front->method != meth_std && ! bNoForceBridge) ||
00295                (fabs(front->my - back->my ))     < rcSET.rMagnMatchYSl[m]*2.0 )
00296           && (fabs( front->x+front->mx*
00297                     (target_center-magnet_center) )) < target_width 
00298           && (fabs( front->y+front->my*
00299                     (target_center-magnet_center) )) < target_width*/ ) {
00300 
00301       newtrack = new Track;//QCnew(1,Track); /*  a new track */
00302       assert(newtrack);
00303       //TgInit( newtrack );
00304       
00305       /* ----- keep bridging information ----- */
00306       if( front->bridge )       /* do we have front brigding info (mcheck) */
00307         bridge = front->bridge;
00308       else if( back->bridge )   /* or back one (mckalman) ? */
00309         bridge = back->bridge;
00310       else
00311         bridge = new Bridge;//QCnew( 1, Bridge );
00312       assert( bridge );
00313       TgTrackPar( front, back, &theta, &phi, &bending, &ZVertex);
00314 
00315       ZVertex *= 0.01;
00316       if( ZVertex < DZA )
00317         ZVertex = DZA;
00318       if( ZVertex > DZA + DZW )
00319         ZVertex = DZA+DZW;
00320       P = rcPEval( ZVertex, theta, phi, bending);
00321       if( P > 0.0 ) {
00322         bridge->Momentum = P;
00323         if( bending < 0 )
00324           P = -P;
00325         bridge->xOff  = rcZEval( ZVertex, theta, phi, P, 0);
00326         bridge->yOff  = rcZEval( ZVertex, theta, phi, P, 1);
00327         bridge->ySOff = rcZEval( ZVertex, theta, phi, P, 2);
00328       } else
00329         bridge->Momentum = 0.0;
00330       bridge->ySlopeMatch = back->my - front->my;
00331       bridge->xMatch      = v2 = back->x  - front->x  + bridge->xOff;
00332       bridge->yMatch      = v1 = back->y  - front->y  + bridge->yOff;
00333       bridge->ySMatch     = v3 = back->my - front->my + bridge->ySOff;
00334 
00335 
00336         double rcSET_rMagnMatchYSl0 = 0.03;//INSERTED FROM HRCSET.C FUNCTION
00337         double rcSET_rMagnMatchY0 = 1.0;//THESE ARE BOGUS VALUES TO MAKE THE PROG WORK
00338         double rcSET_rMagnMatchX0 = 3.0;
00339         cerr << "ERROR : INVALID MAGNETIC FIELD VALUES USED " << endl;
00340 
00341       if( fabs(v3) > rcSET_rMagnMatchYSl0/*rcSET.rMagnMatchYSl[m] && front->method == meth_std*/)
00342         v3 = 1e12;              /* reject */
00343 
00344       if( fabs( v2) > rcSET_rMagnMatchY0 ||
00345           fabs( v1) > rcSET_rMagnMatchX0 )
00346         v1 = v2 = 1e12;
00347 
00348       
00349       newtrack->bridge = bridge;
00350       //newtrack->method = method;
00351       newtrack->front  = front;
00352       newtrack->back = back;
00353 /*NOT SURE WHAT THIS BPHOTOSEARCH IS FOR, BUT IT SEEMS USELESS AT THIS POINT
00354       if( bPhotoSearch )
00355         newtrack->Used = true;
00356       else
00357         newtrack->Used = false;
00358 */     
00359 
00360       /* ------ a weighted measure for the quality of bridging ------ */
00361       
00362       chi = v1 * v1 + v2 * v2 + v3 * v3;
00363       newtrack->chi  = sqrt(chi + front->chi*front->chi + back->chi*back->chi);
00364       if(bestchi > chi) {
00365         besttrack = newtrack;
00366         bestchi = chi;
00367       }
00368       newtrack->ynext = ret;
00369       ret = newtrack;
00370     }
00371     back = back->next;
00372   }
00373 
00374   /* --- for the best track ... */
00375   if( besttrack ) {
00376     int mtch = 1;
00377     besttrack->Used = true;     /* set the parttrack used flags */
00378     besttrack->front->Used = true;
00379     besttrack->back->Used = true;
00380         double rcSET_rXSlopeSep = 0.01;//INSERTED FROM HRCSET
00381         cerr << "Error : bogus value used" << endl;
00382     for( trackwalk = ret; trackwalk ; trackwalk = trackwalk->next ) {
00383       if( fabs( newtrack->back->mx - besttrack->back->mx ) > rcSET_rXSlopeSep )
00384         mtch ++;
00385     }
00386     besttrack->yTracks = mtch;
00387 /*
00388     if( bDebugMatch )
00389       printf("%f %f %f %f %f %f XXmatXX\n",
00390              besttrack->front->x, besttrack->back->x, besttrack->bridge->xOff,
00391              besttrack->front->y, besttrack->back->y, besttrack->bridge->yOff);
00392 */
00393   }
00394   /* --- check for found back parttracks in other tracks
00395      --- we only keep the best match --- */
00396   for( newtrack = ret; newtrack; newtrack = newtrack->ynext ) {
00397     if( !newtrack->Used )
00398       continue;
00399     for( trackwalk = tracklist; trackwalk; trackwalk = trackwalk->next ) {
00400       for( ytrackwalk = trackwalk; ytrackwalk;
00401            ytrackwalk = ytrackwalk->ynext ) {
00402         /*
00403         if( ytrackwalk->method != method )
00404           continue;
00405         */
00406         if(ytrackwalk->Used && ytrackwalk->back == newtrack->back ) {
00407           if( ytrackwalk->chi > newtrack->chi ) {
00408             ytrackwalk->Used = 0;
00409           } else {
00410             newtrack->Used = 0;
00411           }
00412         }
00413       }
00414     }
00415   }
00416   
00417   return ret;
00418 }
00419 
00420 

Generated on Fri Jan 11 22:34:00 2008 by  doxygen 1.4.6