Privacy and Security Notice

treecombine.cc Source File

treecombine.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include "treecombine.h"
00003 #include <math.h>
00004 #include "mathstd.h"
00005 #include <fstream>
00006 //#include "mathdefs.h"
00007 #define PI 3.141592653589793
00008 #define DBL_EPSILON 2.22045e-16
00009 using namespace std;
00024 extern Det *rcDETRegion[2][3][4];
00025 extern treeregion *rcTreeRegion[2][3][4][4];
00026 extern int parttrackanz;
00027 
00028 extern EUppLow operator++(enum EUppLow &rs, int );
00029 extern ERegion operator++(enum ERegion &rs, int );
00030 extern Etype operator++(enum Etype &rs, int );
00031 extern Edir operator++(enum Edir &rs, int );
00032 /*extern Eorientation operator++(enum Eorientation &rs, int );*/
00033 
00034 double UNorm( double *A, int n, int m);
00035 double *M_Cholesky (double  *B, double *q, int n);
00036 double * M_InvertPos (double *B, int n);
00037 double * M_A_mal_b (double *y,double *A, int n, int m,double b[4]);
00038 
00039 //__________________________________________________________________
00040 treecombine::treecombine(){
00041 
00042 }//__________________________________________________________________
00043 chi_hash::chi_hash(){
00044   hits = 0;
00045 }
00046 //___________________________________________________________________
00047 treecombine::~treecombine(){
00048 
00049 }
00050 //__________________________________________________________________
00051 int treecombine::chi_hashval( int n, Hit **hit ){
00052   int i;
00053   double hash = 389.0;//WTF IS THIS?!?
00054   for( i = 0; i < n; i++ ) {
00055     hash *= hit[i]->rResultPos;
00056   }
00057   i = (((((*(unsigned*)&hash))) & HASHMASK)^
00058        ((((*(unsigned*)&hash))>>22) & HASHMASK)) ;
00059   return i;
00060 }
00061 //__________________________________________________________________
00062 void treecombine::chi_hashclear(void)
00063 {
00064   memset( hasharr, 0, sizeof(hasharr));
00065 }
00066 
00067 //__________________________________________________________________
00068 void treecombine::chi_hashinsert(Hit **hits, int n, double slope, double xshift, double cov[3],double chi)
00069 {
00070   int val = chi_hashval( n, hits), i;
00071 //Got rid of a Qmalloc in the following line
00072 
00073     chi_hash *new_chi_hash;
00074     new_chi_hash = (chi_hash*)malloc(sizeof(chi_hash));
00075   //chi_hash *new = (chi_hash*)malloc( sizeof(chi_hash));
00076   if( new_chi_hash ) {
00077     new_chi_hash->next = hasharr[val];
00078     hasharr[val] = new_chi_hash;
00079     new_chi_hash->x  = xshift;
00080     new_chi_hash->mx = slope;
00081     new_chi_hash->cov[0] = cov[0];
00082     new_chi_hash->cov[1] = cov[1];
00083     new_chi_hash->cov[2] = cov[2];
00084     new_chi_hash->chi    = chi;
00085     new_chi_hash->hits   = n;
00086     for( i = 0; i < n; i++ ) {
00087       new_chi_hash->hit[i] = hits[i]->rResultPos;
00088     }
00089   }
00090 
00091 }
00092 //__________________________________________________________________
00093 int treecombine::chi_hashfind( Hit **hits, int n, double *slope, double *xshift, double cov[3],double *chi)
00094 {
00095   int val = chi_hashval( n, hits), i;
00096   chi_hash *new_chi_hash;
00097   new_chi_hash = new chi_hash;
00098 //  new_chi_hash = (chi_hash*)malloc(sizeof(chi_hash));
00099   for( new_chi_hash = hasharr[val]; new_chi_hash; new_chi_hash = new_chi_hash->next) {
00100     if(!new_chi_hash->hits)break;
00101     if( new_chi_hash->hits == n ) {
00102       for( i = 0; i < n; i++ ){
00103         if( new_chi_hash->hit[i] != hits[i]->rResultPos ){
00104           break;
00105         }
00106       }
00107       if( i == n ) {            /* HIT! */
00108         *xshift = new_chi_hash->x;
00109         *slope  = new_chi_hash->mx;
00110         cov[0]  = new_chi_hash->cov[0];
00111         cov[1]  = new_chi_hash->cov[1]; 
00112         cov[2]  = new_chi_hash->cov[2]; 
00113         *chi    = new_chi_hash->chi;
00114         return 1;
00115       }
00116     }
00117   }
00118   return 0;
00119 }
00120 //__________________________________________________________________
00121 /*-------------------------------
00122    BESTX : This is a much simplified
00123    version of bestx.  It simply 
00124    matches the left/right wire hits
00125    in r3 to the pattern being used.
00126 --------------------------------*/
00127 int treecombine::bestx(double *xresult,Hit *h,Hit *ha){
00128         double pos,distance,bestx,resolution;
00129         double x = *xresult;
00130         pos = h->rPos1;
00131         resolution = h->Resolution;
00132         distance = x - pos;
00133         if(distance < 0)distance = -distance;
00134         bestx = pos;
00135         //cerr << "d1= " << distance << endl;
00136         pos = -h->rPos1;
00137         distance = x - pos;
00138         if(distance < 0)distance = -distance;
00139         if(distance < bestx){
00140                 bestx = pos;
00141         }
00142         *ha = *h;
00143         ha->next    = 0;
00144         ha->nextdet = 0;
00145         ha->used    = false;
00146         ha->rResultPos = 
00147           ha->rPos    = bestx;
00148         ha->Resolution = resolution;
00149         
00150 return 1;
00151 }
00152 //__________________________________________________________________
00153 
00154 /* ------------------------------
00155    BESTX : searches for the closed hit to
00156    to *xresult and writes it
00157    to *xresult. In addition the
00158    hitchain is searched for hits
00159    inbetween *xresult - dist_cut
00160    and *xresult + dist_cut. All
00161    corresponding hits that
00162    are found are stored in *ha
00163 
00164    Size of the arrays must be
00165    MAXHITPERLINE
00166    ------------------------------ */
00167 int treecombine::bestx(double *xresult, double dist_cut, Hit *h, Hit **ha){
00168 //##############
00169 //DECLARATIONS #
00170 //##############
00171 cerr << "1";
00172   int good = 0;
00173   double x = *xresult;
00174   double pos;
00175   double adist, distance, odist;
00176   double minim = dist_cut;
00177   int  igood, j, doub;
00178   double breakcut = 0;
00179 
00180 //###############################################
00181 //Find good hits up to a max of MAXHITPERLINE.  #  
00182 //Uses a hard maximum distance cut 'dist_cut'.  #
00183 //If MAXHITPERLINE good hits are reached,       #
00184 //replace good hits with better hits.           #
00185 //###############################################
00186 cerr << "2";
00187   if( h )
00188     breakcut = h->detec->WireSpacing + dist_cut;//wirespacing + bin resolution
00189   
00190 cerr << "3";
00191   while( h ) {
00192     doub = 0;
00193     for( j = 0; j < 2; j++ ) {
00194         //cerr << "x=" << x << endl;
00195       pos        = j ? h->rPos2 : h->rPos1;
00196       distance   = x - pos;
00197       adist      = distance < 0 ? -distance : distance;
00198       if( adist < dist_cut) {//<- distance cut applied
00199         if( good < MAXHITPERLINE ) {
00200           /* --- doublicate hits for calibration changes --- */
00201         //REMOVED A QMALLOC IN FOLLOWING LINE
00202           ha [good]   = (Hit*)malloc( sizeof(Hit));
00203           assert( ha[good] );
00204           *ha[good]  = *h;
00205           ha[good]->next    = 0;
00206           ha[good]->nextdet = 0;
00207           ha[good]->used    = false;
00208           ha[good]->rResultPos = 
00209             ha[good]->rPos    = pos;
00210           if( adist < minim ) {
00211             *xresult = pos;
00212             minim = adist;
00213           }
00214           good++;
00215         } else {                /* try to save it if better than others */
00216           for( igood = 0; igood < good; igood ++ ) {
00217             odist = x - ha[igood]->rPos;
00218             if( odist < 0 )
00219               odist = -odist;
00220             if( adist < odist ) {
00221               *ha[igood]   = *h;
00222               ha[igood]->next    = 0;
00223               ha[igood]->nextdet = 0;
00224               ha[igood]->used    = false;
00225               ha[igood]->rResultPos = 
00226                 ha[igood]->rPos    = pos;
00227               break;
00228             }
00229           }
00230         }
00231       }
00232       if( pos == h->rPos2 )
00233         break;
00234     }
00235     if( distance < -breakcut)
00236       break;
00237     h = h->nextdet;
00238   }
00239   return good;
00240 }
00241 //__________________________________________________________________
00242 /* --------------------------------------------------------------------------
00243  * creates permutations of hits
00244  * i   : a number from 0 to mul-1 (number of permutation)
00245  * mul : the number of permutations
00246  * l   : the length of r[l], bx[l][MAXHITPERLINE], xa[l]
00247  * r   : array of multiplicity in detectors
00248  * hx  : hits filled: ha[l][r[]]
00249  * ha  : array to write permutated hits in
00250  * ------------------------------------------------------------------------- */
00251 
00252 void treecombine::mul_do(int i,int mul,int l,int *r,Hit   *hx[DLAYERS][MAXHITPERLINE],  Hit **ha){
00253   int j,s;
00254   
00255   if( i == 0 ) {
00256     for( j = 0; j < l; j++ ) {
00257       ha[j] = hx[j][0];
00258     }
00259   } else {
00260     for( j = 0; j < l; j++ ) {
00261       if( r[j] == 1 )
00262         s = 0;
00263       else {
00264         s = i % r[j];
00265         i /= r[j];
00266       }
00267       ha[j] = hx[j][s];
00268     }
00269   }
00270   return;
00271 }
00272 //__________________________________________________________________
00273 /* ----------------------------------------------------------------------
00274  * we solve the linear equation with
00275  *
00276  * x = (x_offset, x_slope)
00277  * y = (hit positions)
00278  * A = - ( (1, zpos1), (1, zpos2), ... )
00279  * C = cov(hitpositions)
00280  * G = C^-1
00281  *
00282  * (A^T * G * A) x = -A^T G y
00283  *
00284  * to do a least square fit weighted with the hit resolutions and
00285  * get the covariance matrix for position and slope.
00286  */
00287 
00288 void treecombine::weight_lsq(double *slope, double *xshift, double cov[3],double *chi,Hit **hits, int n){
00289   cerr << "weight_lsq begin " << endl;
00290   static matrix A = 0, G, At, GA, AtGA;
00291   double  AtGy[2], y[DLAYERS], x[2];
00292   double r, s, sg, det, h;
00293   int i,j,k;
00294 
00295   if( !A ) {/* allocate matrices */
00296     A      = M_Init( DLAYERS, 2);
00297     G      = M_Init( DLAYERS, DLAYERS);
00298     At     = M_Init( 2, DLAYERS);
00299     GA     = M_Init( DLAYERS, 2);
00300     AtGA   = M_Init( 2, 2);
00301     for( i = 0; i < DLAYERS; i++ ) {
00302       At[0][i] = A[i][0] = -1.0;
00303     }
00304   }
00305   if( chi_hashfind(hits ,n, slope, xshift, cov, chi) )
00306     return;
00307   /* initialize the matrices and vectors */
00308   for( i = 0; i < n; i++ ) {
00309     A[i][1] = -(hits[i]->Zpos - magnet_center);
00310     y[i]     = -hits[i]->rResultPos;
00311     r = 1.0 / hits[i]->Resolution;
00312     G[i][i] = r*r;
00313   }
00314   /* calculate right hand side */
00315   for( i = 0; i < 2; i++ ) {
00316     s = 0;
00317     for( k = 0; k < n; k++ )
00318       s += A[k][i] * y[k] * G[k][k];
00319     AtGy[i] = s;
00320   }  
00321   /* and now the left hand side */
00322   for( i = 0; i < 2; i++ ) {
00323     for( k = 0; k < 2; k++ ) {
00324       s = 0;
00325       for( j = 0; j < n; j++ )
00326         s += G[j][j]*A[j][i]*A[j][k];
00327       AtGA[i][k] = s;
00328     }
00329   }
00330   /* calculate covariance */
00331   det = ( AtGA[0][0] * AtGA[1][1] - AtGA[1][0] * AtGA[0][1]);
00332   h          = AtGA[0][0];
00333   AtGA[0][0] = AtGA[1][1] / det;
00334   AtGA[1][1] = h / det;
00335   AtGA[0][1] /= -det;
00336   AtGA[1][0] /= -det;  
00337   /* solve equation */
00338   for( i = 0; i < 2; i++ ) 
00339     x[i] = AtGA[i][0] * AtGy[0] + AtGA[i][1] * AtGy[1];
00340   
00341   *slope  = x[1];
00342   *xshift = x[0];
00343   cov[0]  = AtGA[0][0];
00344   cov[1]  = AtGA[0][1];
00345   cov[2]  = AtGA[1][1];
00346 
00347   /* sqrt( chi^2) */
00348   for( sg = s = 0.0, i = 0; i < n; i++ ) {
00349     r  = (*slope*(hits[i]->Zpos - magnet_center) + *xshift
00350           - hits[i]->rResultPos);
00351     s  += G[i][i] * r * r;
00352     /* sg += G[i][i]; */
00353   }
00354   *chi   = sqrt( s/n );
00355 
00356   chi_hashinsert(hits,n, *slope, *xshift, cov, *chi);
00357   cerr << "weight_lsq end " << endl;
00358 }
00359 //__________________________________________________________________
00360 /* ----------------------------------------------------------------------
00361  * we solve the linear equation with
00362  *
00363  * x = (x_offset, x_slope)
00364  * y = (hit positions)
00365  * A = - ( (1, zpos1), (1, zpos2), ... )
00366  * C = cov(hitpositions)
00367  * G = C^-1
00368  *
00369  * (A^T * G * A) x = -A^T G y
00370  *
00371  * to do a least square fit weighted with the hit resolutions and
00372  * get the covariance matrix for position and slope.
00373  */
00374 
00375 void treecombine::weight_lsq_r3(double *slope, double *xshift, double cov[3],double *chi,Hit **hits, int n,double z1, int offset,int tlayers){
00376   double A[tlayers][2],G[tlayers][tlayers],AtGA[2][2];
00377   double  AtGy[2], y[tlayers], x[2];
00378   double r, s, sg, det, h;
00379   int i,j,k;
00380   double resolution = 0.1;
00381   /* initialize the matrices and vectors */
00382   for( i = 0; i < tlayers; i++ ) {
00383     A[i][0] = -1.0;
00384   }
00385   //###########
00386   // Set Hits #
00387   //###########
00388   for( i = 0; i < n; i++ ) {
00389     if(offset == -1){
00390       A[i][1] = -hits[i]->Zpos;//used by matchR3
00391       y[i] = -hits[i]->rPos;
00392     }
00393     else{
00394       A[i][1] = -(i+offset);//used by Tl MatchHits
00395       y[i] = -hits[i]->rResultPos;
00396     }
00397     r = 1.0 / hits[i]->Resolution;
00398     if(!(hits[i]->Resolution))r = 1.0 / resolution;// WARNING : this is a hack to make this fit work.  Hit resolutions needs to be set up.
00399     G[i][i] = r*r;
00400   }
00401   /* calculate right hand side */
00402   for( i = 0; i < 2; i++ ) {
00403     s = 0;
00404     for( k = 0; k < n; k++ )
00405       s += A[k][i] * y[k] * G[k][k];
00406     AtGy[i] = s;
00407   }  
00408   /* and now the left hand side */
00409   for( i = 0; i < 2; i++ ) {
00410     for( k = 0; k < 2; k++ ) {
00411       s = 0;
00412       for( j = 0; j < n; j++ )
00413         s += G[j][j]*A[j][i]*A[j][k];
00414       AtGA[i][k] = s;
00415     }
00416   }
00417   /* calculate covariance */
00418   det = ( AtGA[0][0] * AtGA[1][1] - AtGA[1][0] * AtGA[0][1]);
00419   h          = AtGA[0][0];
00420   AtGA[0][0] = AtGA[1][1] / det;
00421   AtGA[1][1] = h / det;
00422   AtGA[0][1] /= -det;
00423   AtGA[1][0] /= -det;  
00424   /* solve equation */
00425   for( i = 0; i < 2; i++ ) 
00426     x[i] = AtGA[i][0] * AtGy[0] + AtGA[i][1] * AtGy[1];
00427   *slope  = x[1];
00428   *xshift = x[0];
00429   cov[0]  = AtGA[0][0];
00430   cov[1]  = AtGA[0][1];
00431   cov[2]  = AtGA[1][1];
00432   for( sg = s = 0.0, i = 0; i < n; i++ ) {
00433     r  = (*slope*(hits[i]->Zpos - z1) + *xshift
00434           - hits[i]->rResultPos);
00435     s  += G[i][i] * r * r;
00436   }
00437   *chi   = sqrt( s/n );
00438   //chi_hashinsert(hits,n, *slope, *xshift, cov, *chi);
00439 }
00440 //__________________________________________________________________
00441 int treecombine::contains( double var, Hit **arr, int len) {
00442   int i;
00443   for( i = 0; i < len ; i++) {
00444     if( var == arr[i]->rResultPos )
00445       return 1;
00446   }
00447   return 0;
00448 }
00449 //__________________________________________________________________
00450 /* ------------------------------
00451    searches for the closest hit to
00452    to *xresult and writes it
00453    to *xresult. In addition the
00454    hitarray is searched for hits
00455    in the detector detect and
00456    inbetween *xresult - dist_cut
00457    and *xresult + dist_cut. All
00458    the possible hits are stored
00459    in *ha
00460 
00461    Size of the arrays must be
00462    MAXHITPERLINE
00463    ------------------------------ */
00464 
00465 
00466 int treecombine::selectx(double *xresult,double dist_cut,Det *detec, Hit *hitarray[], Hit **ha)
00467 {
00468   int good = 0;
00469   double x = *xresult;
00470   double pos;
00471   double distance;
00472   double minim = dist_cut;
00473   Hit *h;
00474   int num;
00475 
00476 
00477   for( num = MAXHITPERLINE*DLAYERS; num--  && *hitarray; hitarray ++ ) {
00478     h = *hitarray;
00479 //comented out the rightwing/leftwing stuff from the following line
00480     if( !h->detec ||
00481         (h->detec != detec/* && h->detec != detec->leftwing &&
00482          h->detec != detec->rightwing */)) {
00483       continue;
00484     }
00485 
00486     pos        = h->rResultPos;
00487 
00488     if( !contains( pos, ha, good ) ) {
00489       distance   = x - pos;
00490       ha [good]   = h;
00491       if( fabs(distance) < minim ) {
00492         *xresult = pos;
00493         minim = fabs(distance);
00494       }
00495       good++;
00496       if( good == MAXHITPERLINE)
00497         break;
00498     }
00499   }
00500   return good;
00501 }
00502 //__________________________________________________________________
00503 /* ----------------------------------------------------------------------
00504  * returns the z position of a crossing point of a detector
00505  * and a line with track parameters x and slope_x
00506  */
00507 double treecombine::detZPosition( Det *det, double x, double slope_x, double *xval )
00508 {
00509   double t = 
00510     (( det->rRotSin * (det->center[0] - x) +
00511        det->rRotCos * (magnet_center - det->Zpos))) /
00512     ( slope_x * det->rRotSin - det->rRotCos);
00513 
00514   if( xval )
00515     *xval = x + slope_x * t;
00516   
00517   return t + magnet_center;
00518 }
00519 //__________________________________________________________________
00520 int treecombine::inAcceptance( enum EUppLow up_low,
00521               enum ERegion region,
00522               double cx, double mx,
00523               double cy, double my )
00524 {
00525 cerr << "This function needs to conform to Qweak acceptance" << endl;
00526 
00527   enum Edir dir;
00528   double z, x, y;
00529   Det *rd/*, *rds, *rde*/;
00530   for( dir = u_dir; dir <= x_dir; dir++) {
00531     for(rd = rcDETRegion[up_low][region-1][dir];
00532         rd; rd = rd->nextsame ) {
00533       z = rd->Zpos;
00534       x = cx + (z-magnet_center)*mx;
00535       y = cy + (z-magnet_center)*my;
00536 /*
00537       rde = rd->leftwing  ? rd->leftwing  : rd;
00538       rds = rd->rightwing ? rd->rightwing : rd;
00539 */
00540       if(/* rds->center[0] - 0.5*rds->width[0] > x ||
00541           rde->center[0] + 0.5*rde->width[0] < x ||*/
00542           rd ->center[1] - 0.5*rd ->width[1] > y ||
00543           rd ->center[1] + 0.5*rd ->width[1] < y) {
00544         return 0;
00545       }
00546     }
00547   }
00548   return 1;
00549 }
00550 //__________________________________________________________________
00551 /* -------------------------------------------------------------------------
00552  * TLCHECKFORX :
00553  * checks for x hits on a line given by values in (RENAMED VARIABLE) and (RENAMED VARIABLE)
00554  * dlayer: number of detector layers to search in
00555  * ------------------------------------------------------------------------- */
00556 int treecombine::TlCheckForX(double x1, double x2, double dx1, double dx2,double z1, double dz,TreeLine *treefill,enum EUppLow up_low,enum ERegion region,enum Etype type,enum Edir dir,int  dlayer, int tlayer,int  iteration,int  stay_tuned)
00557 {
00558 //################
00559 // DECLARATIONS  #
00560 //################
00561   Det *rd, *firstdet = 0, *lastdet;/* detector loop variable                 */
00562   double org_x;                 /* x at center of magnet                  */
00563   double org_mx;                /* slope                                  */
00564   double org_dx;
00565   double org_dmx;               /* the same for the error                 */
00566   double thisX, thisZ;          /* X and Z at a given plane               */
00567   double startZ = 0.0, endZ = 0;
00568   Hit   *DetecHits[DLAYERS][MAXHITPERLINE]; /* Hits at a detector         */
00569   Hit   *UsedHits[DLAYERS];                 /* Hits for this line         */
00570   Hit   **hitarray;             /* temporary                              */
00571   double res,resnow;            /* resultion of a plane                   */
00572   double mx,cx,dh,chi,minchi=1e8;
00573   double minweight = 1e10;
00574   double mmx=0,mcx=0; /* least square fit parameters     */
00575   double cov[3], mcov[3];
00576   double stay_chi;
00577   int i,j;
00578   int nMult[DLAYERS];           /* # of hits at a detector                */
00579   int nhits;                    /* number of hits per line                */
00580   int permutations = 1;         /* multiplicity for permutations          */
00581   //int vcmiss = 0;
00582   int besti = -1;               /* best permutation index                 */
00583   int ret   = 0;                /* return value (pessimistic)             */
00584   int first;
00585   //int missidx = fr_back + 2* (method == meth_std? 0 : 1);
00586 
00587 //##################
00588 //DEFINE VARIABLES #
00589 //################## 
00590   org_mx  = (x2-x1)/dz;//calculate slope
00591   org_x   = x1 + org_mx * (magnet_center-z1);//calculate x at center of magnet
00592   org_dmx = (dx2-dx1)/dz; 
00593   org_dx  = dx1 + org_dmx * (magnet_center-z1);
00594 
00595   int rcSETiLevels0 = 4;
00596   cerr << "ERROR: static rcSETiLevels0 needs read in from Qset" << endl;
00597   res = rcTreeRegion[up_low][region-1][type][dir]->rWidth /(1<<(rcSETiLevels0-1));//bin 'resolution'
00598 
00599   org_mx = (x2-x1)/dz;
00600   //org_x = ?
00601   org_dmx = (dx2-dx1)/dz;
00602   //org_dmx = ?
00603   
00604 
00605 
00606 //###################################
00607 //LOOP OVER DETECTORS IN THE REGION #
00608 //###################################
00609         // uses BESTX & SELECTX     #
00610         //###########################
00611   if(region == r3){
00612         
00613   }
00614   else{
00615 
00616   /* --- loop over the detectors of the region --- */
00617   first = 1;
00618   for(nhits = 0, rd = rcDETRegion[up_low][region-1][dir];
00619       rd; rd = rd->nextsame) {
00620     thisZ = rd->Zpos;
00621     thisX = org_mx * (thisZ - magnet_center) + org_x;
00622     cerr << thisX << "," << dz << endl;
00623     if( !firstdet ) {
00624       firstdet = rd;
00625       startZ = thisZ;
00626     }
00627     lastdet = rd;
00628     endZ = thisZ;
00629 /*        
00630     visdir = dir;
00631     viswer = up_low;
00632     vispar = region;
00633 */
00634     double rcSETrMaxRoad          = 1.4;
00635     cerr << "ERROR : USING STUB VALUE FOR RCSET " << endl;
00636 
00637 
00638     /* --- search this road width for hits --- */
00639     //set 'resnow'
00640     resnow =  org_dmx * (thisZ - magnet_center) + org_dx;
00641     if( !iteration && !stay_tuned && (first || !rd->nextsame) && tlayer == dlayer)
00642       resnow -= res*(rcSETrMaxRoad-1.0);
00643 
00644     //bestx finds the hits which occur closest to the path through the first and last detectors 
00645     //nMult is the number of good hits at each detector layer
00646     if( !iteration ){           /* first track finding process */
00647       nMult[nhits] = bestx( &thisX, resnow,
00648                             rd->hitbydet, DetecHits[nhits]);
00649     }
00650     else                        /* in iteration process (not used by TlTreeLineSort)*/
00651       nMult[nhits] = selectx( &thisX, resnow,
00652                               rd, treefill->hits, DetecHits[nhits]);
00653     cerr << "b";
00654     if( nMult[nhits] ) {        /* there are hits in this detector         */
00655       permutations *= nMult[nhits];
00656     } else {
00657       nhits --;                 /* this detector did not fire              */
00658     }
00659     nhits++;    
00660   }
00661   }
00662 //############################
00663 //RETURN HITS FOUND IN BESTX #
00664 //############################
00665   if( !iteration ) {            /* return the hits found in bestx()        */
00666     hitarray = treefill->hits;
00667     for( j = 0; j < nhits; j++ ) {
00668       for( i = 0; i < nMult[j]; i++ ) {
00669         *hitarray = DetecHits[j][i]; 
00670         hitarray ++;
00671       }
00672     }
00673     if( hitarray - treefill->hits < DLAYERS*MAXHITPERLINE + 1) 
00674       *hitarray = 0;            /* add a terminating 0 for later selectx()*/
00675   }
00676 
00677 //#####################################################
00678 //DETERMINE THE BEST SET OF HITS FOR THE TREELINE    #
00679 //#####################################################
00680 // uses : MUL_DO     #
00681 //        WEIGHT_LSQ #
00682 //####################    
00683   int rcSETiMissingTL0 = 2;
00684   if( nhits >= dlayer - rcSETiMissingTL0/*rcSET.iMissingTL[missidx]*/) {  /* allow missing hits */
00685     for( i = 0; i < permutations; i++ ) {
00686       //mul_do is used to create hit arrays for every possible hit combination with one hit per layer.
00687       mul_do(i,permutations,nhits,nMult,
00688              DetecHits,UsedHits);
00689       
00690       chi = 0.0;
00691       weight_lsq( &mx, &cx, cov, &chi, UsedHits, nhits);
00692 
00693       stay_chi = 0.0;
00694       if( stay_tuned ) {
00695         dh = (cx+mx*(startZ-magnet_center)-
00696               (org_x+org_mx*(startZ-magnet_center)));
00697         stay_chi += dh*dh;
00698         dh = (cx+mx*(endZ-magnet_center)-
00699               (org_x+org_mx*(endZ-magnet_center)));
00700         stay_chi += dh*dh;
00701       }
00702       if( stay_chi + chi + dlayer-nhits < minweight ) {
00703         /* has this been the best track so far? */
00704         minweight = stay_chi + chi + dlayer-nhits;
00705         minchi = chi;
00706         mmx    = mx;
00707         memcpy( mcov, cov, sizeof cov );
00708         mcx    = cx;
00709         besti  = i;
00710       }
00711     }
00712     
00713     treefill->cx  = mcx;
00714     treefill->mx  = mmx;     /* return track parameters: x, slope, chi */
00715     treefill->chi = minchi;
00716     treefill->numhits    = nhits;
00717     //treefill->numvcmiss  = vcmiss;/* return the number of missing vc-hits */
00718     
00719     memcpy(treefill->cov_cxmx, mcov, sizeof mcov);
00720     
00721     if( besti != -1 ) {
00722       mul_do( besti, permutations,
00723               nhits, nMult, DetecHits, UsedHits);
00724       for( j = 0 ; j < MAXHITPERLINE*DLAYERS && treefill->hits[j]; j ++ ) 
00725         treefill->hits[j]->used = false;
00726       for( j = 0; j < nhits; j++ ) {
00727         if( UsedHits[j] ) 
00728           UsedHits[j]->used = true;
00729       }
00730     }
00731     ret = (besti != -1);
00732   }
00733 
00734 //################
00735 //SET PARAMATERS #
00736 //################
00737   if( !ret ) {
00738     treefill->isvoid  = true;
00739     treefill->nummiss = dlayer;
00740   } else {
00741     treefill->isvoid  = false;
00742     treefill->nummiss = dlayer - nhits;
00743   }
00744   return ret;
00745 }
00746 
00747 //__________________________________________________________________
00748 /* -------------------------------
00749 This function replaces TlCheckForX for region 3.  It matches one of
00750 the two wire hits to the hit in the pattern.  It then calculates a 
00751 chi_square for the matching of the hits to the pattern.  This may
00752 be misleading due to the currently low resolution (8 bins@5/7/07) of 
00753 the pattern database.  It should however, be able to distinguish the
00754 right/left ambiguity for each wire.
00755 
00756 OUTPUT : the best hits are added to treefill's hit list and treefill's
00757         line parameters are set.
00758 --------------------------------*/
00759 int treecombine::TlMatchHits(double x1,double x2,double z1, double dz,TreeLine *treefill,enum EUppLow up_low,enum ERegion region,enum Etype type,enum Edir dir,int tlayers){
00760 //################
00761 // DECLARATIONS  #
00762 //################
00763   double thisX, thisZ;          /* X and Z for the pattern's wire hit */
00764   Hit *h;
00765   Det *rd;
00766   double dx,slope,intercept;
00767   Hit   DetecHits[tlayers]; /* Hits at a detector         */
00768   Hit  *DHits = DetecHits;
00769 
00770   double mx=0,cx=0,chi;
00771   double cov[3];
00772   int ret=0;
00773   int nhits,j=0;
00774 //##################
00775 //DEFINE VARIABLES #
00776 //##################
00777   dx = x2 - x1;
00778   slope = dx/dz;
00779   intercept = 0.5*((x2 + x1) + slope*(z1 + z1 + dz));
00780   intercept = x1 - slope*z1;
00781   //cerr << "(" << slope << "," << intercept << "," << z1 << "," << x1 << ")" << endl;
00782   nhits = treefill->lastwire - treefill->firstwire + 1;
00783   if(nhits < 0) nhits = - nhits;
00784 //########################
00785 //MATCH HITS TO TREELINE #
00786 //########################
00787   //cerr << "matchhits" << endl;
00788 //STEP 1 : Match left/right wire hits to the pattern hits
00789   rd = rcDETRegion[up_low][region-1][dir];
00790   if(treefill->r3offset >=100){//get the correct plane for this treeline
00791         rd = rd->nextsame;
00792   }
00793   for(int i=treefill->firstwire;i<=treefill->lastwire;i++){//loop over pattern positions
00794     for(h = rd->hitbydet;h;h = h->next){//loop over the hits
00795         thisZ = treefill->r3offset+i;
00796         thisX = slope*thisZ + intercept;
00797         if(h->wire!=thisZ){
00798                 continue;
00799         }
00800         //cerr << "Z=" << thisZ << endl;
00801         bestx( &thisX,h, DHits);
00802         DHits++;
00803         j++;
00804         
00805     }
00806   }
00807 if(j!=nhits) cerr << "WARNING NHITS != NGOODHITS " << nhits << "," << j << endl;
00808 //############################
00809 //RETURN HITS FOUND IN BESTX #
00810 //############################
00811   for(int i = 0; i < j; i++ ) {
00812         DetecHits[i].used = true;
00813         treefill->thehits[i] = DetecHits[i];
00814         treefill->hits[i] = &treefill->thehits[i];
00815   }
00816 //######################
00817 //CALCULATE CHI SQUARE #
00818 //######################
00819   chi = 0.0;
00820   weight_lsq_r3( &mx, &cx, cov, &chi,treefill->hits, j,z1,treefill->r3offset,tlayers);
00821 //################
00822 //SET PARAMATERS #
00823 //################
00824   treefill->cx  = cx;
00825   treefill->mx  = mx;     /* return track parameters: x, slope, chi */
00826   treefill->chi = chi;
00827   treefill->numhits    = nhits;   
00828   memcpy(treefill->cov_cxmx, cov, sizeof cov);
00829   if(nhits>=7){//CUT TRACKS MISSING MORE THAN 1 HIT
00830     ret =1;
00831   }
00832 
00833   if( !ret ) {
00834     treefill->isvoid  = true;
00835     treefill->nummiss = tlayers-nhits;
00836   } else {
00837     treefill->isvoid  = false;
00838     treefill->nummiss = tlayers-nhits;
00839   }
00840   return ret;
00841 }
00842 
00843 /* ------------------------------
00844    Marks TreeLines close to
00845    other Lines as being good
00846    / bad in respect to their
00847    chi^2
00848    ------------------------------ */
00849 void treecombine::TlTreeLineSort(TreeLine *tl,enum EUppLow up_low,enum ERegion region,enum Etype type,enum Edir dir,unsigned long bins,int tlayer,int dlayer)
00850 {
00851 if(region == r3){
00852   double z1,z2,dx;
00853   double x1,x2;
00854   TreeLine *walk;
00855   TreeLine *owalk;
00856   chi_hashclear();
00857   
00858   /* --------------------------------------------------
00859   calculate line parameters first
00860   -------------------------------------------------- */
00861   for( walk = tl; walk; walk = walk->next ) {//for each matching treeline
00862     if( ! walk->isvoid ) {
00863       if(dlayer==1){
00864                 walk->r3offset +=282;//<-282 should be a read-in variable
00865       }
00866       z1 = (double)(walk->r3offset+walk->firstwire);//first z position
00867       z2 = (double)(walk->r3offset+walk->lastwire);//last z position
00868       dx = rcTreeRegion[up_low][region-1][type][dir]->rWidth;
00869       dx /= (double)bins;
00870 
00871       x1 = (walk->a_beg - (double)bins/2)*dx + dx/2;
00872       x2 = (walk->b_end - (double)bins/2)*dx + dx/2;
00873       TlMatchHits(x1,x2,z1,z2-z1,walk,up_low,region,type,dir,TLAYERS);
00874     }
00875   }
00876   /* --------------------------------------------------
00877      now sort again for identical treelines
00878      -------------------------------------------------- */
00879   for( walk = tl; walk; walk = walk->next ) {
00880     if( walk->isvoid == false ) {
00881       for( owalk = walk->next; owalk; owalk = owalk->next) {
00882         if(owalk->isvoid == false &&  walk->cx == owalk->cx
00883            && walk->mx == owalk->mx ) {
00884           owalk->isvoid = true;
00885         }
00886       }
00887     }
00888   }
00889   treesort ts;
00890   ts.rcTreeConnSort( tl,region);
00891 }
00892 else{
00893 
00894 
00895   double z1,z2,dx,dxh,dxb,dx_2;
00896   double x1,x2, dx1, dx2;
00897   TreeLine *walk = tl;
00898   TreeLine *owalk;
00899   chi_hashclear();
00900  
00901   z1  = rcTreeRegion[up_low][region-1][type][dir]->rZPos[0];//first z position
00902   z2  = rcTreeRegion[up_low][region-1][type][dir]->rZPos[tlayer-1];// last z position
00903 
00904   dx  = rcTreeRegion[up_low][region-1][type][dir]->rWidth;//detector width
00905   dxh = 0.5*dx; //detector half-width
00906   dx /= (double)bins;//width of each bin
00907   dxb = dxh/(double)bins;//half-width of each bin
00908 
00909   
00910   /* --------------------------------------------------
00911      calculate line parameters first
00912      -------------------------------------------------- */
00913   double rcSETrMaxRoad          = 1.4;
00914   cerr << "ERROR : USING STUB VALUE FOR RCSET " << endl;
00915   for( walk = tl; walk; walk = walk->next ) {//for each matching treeline
00916     if( ! walk->isvoid ) {
00917       dx_2 =  dxh - dxb;
00918       x1 = 0.5*((walk->a_beg+walk->a_end) * dx) - dx_2;
00919       x2 = 0.5*((walk->b_beg+walk->b_end) * dx) - dx_2;
00920       dx1 = ((walk->a_end-walk->a_beg) * dx) + dx*rcSETrMaxRoad;
00921       dx2 = ((walk->b_end-walk->b_beg) * dx) + dx*rcSETrMaxRoad;
00922       TlCheckForX(x1, x2, dx1, dx2, z1, z2-z1, walk,up_low,region,type,dir, dlayer, tlayer, 0, 0);
00923     }
00924   }
00925 
00926 
00927   /* --------------------------------------------------
00928      now sort again for identical treelines
00929      -------------------------------------------------- */
00930   for( walk = tl; walk; walk = walk->next ) {
00931     if( walk->isvoid == false ) {
00932       for( owalk = walk->next; owalk; owalk = owalk->next) {
00933         if(owalk->isvoid == false &&  walk->cx == owalk->cx
00934            && walk->mx == owalk->mx ) {
00935           owalk->isvoid = true;
00936         }
00937       }
00938     }
00939   }
00940   treesort ts;
00941   ts.rcTreeConnSort( tl,region);
00942 }
00943 
00944 }
00945 //__________________________________________________________________
00946 int    rc_TrackFit( int No, Hit **Hit, double *fit, double *cov, double *chi,
00947                     double *addx, double *adde){
00948   //###############
00949   // Declarations #
00950   //###############
00951   int debug = 1;
00952 
00953   int ii, ij, ik;
00954   double AA[4][4];
00955   double B[4];
00956   double cff;
00957   double r[4];
00958   double x,y, uvx;
00959 
00960   for( ik = 0; ik < 4; ik++) {  /* reset the matrices to 0 */
00961     B[ik] = 0;
00962     for(ij = 0; ij < 4; ij++)
00963       AA[ij][ik] = 0;
00964   }
00965 
00966   //##############################
00967   // Calculate the metric matrix #
00968   //##############################
00969   for( ii=0; ii < No; ii++ ) {
00970     cerr << ii << " " << Hit[ii]->Zpos << " " << Hit[ii]->rPos << " ";
00971     cff  = 1.0/Hit[ii]->Resolution;
00972     cff *= cff;
00973     r[0] = Hit[ii]->detec->rCos;
00974     r[1] = Hit[ii]->detec->rSin;
00975     r[2] = Hit[ii]->detec->rCos*(Hit[ii]->Zpos);
00976     r[3] = Hit[ii]->detec->rSin*(Hit[ii]->Zpos);
00977 cerr << r[0] << " " << r[1] << endl;
00978     for(ik=0; ik<4; ik++) {
00979       B[ik] += cff*r[ik]*Hit[ii]->rPos;
00980       for(ij=0; ij<4; ij++) 
00981         AA[ik][ij] += cff*r[ik]*r[ij];
00982     }
00983   }
00984 
00985   double *AAp = &AA[0][0];
00986 if(debug){
00987   cerr << "AA = " << endl << "[";
00988   for(ik=0; ik<4; ik++) {
00989     for(ij=0; ij<4; ij++) {
00990       cerr << AA[ik][ij] << " ";
00991     }
00992     cerr << endl;
00993   }
00994   cerr << "]" << endl;
00995 }
00996 
00997 
00998   cov = M_InvertPos(AAp, 4);
00999 
01000   if (!cov){
01001     cerr << "Inversion failed" << endl;
01002     return -1;
01003   }
01004 if(debug){
01005  double *covp = cov;
01006   cerr << "AA Inverse = " << endl << "[";
01007   for(ik=0; ik<4; ik++) {
01008     for(ij=0; ij<4; ij++) {
01009       cerr << *covp++ << " ";
01010     }
01011     cerr << endl;
01012   }
01013   cerr << "]" << endl;
01014 }
01015  
01016   
01017   /* calculate the fit */
01018   M_A_mal_b( fit, cov, 4, 4, B);
01019 
01020   /* calculate chi^2 */
01021   *chi = 0;
01022   for(ii=0; ii<No; ii++) {
01023     cff  = 1.0/Hit[ii]->Resolution;
01024     cff *= cff;
01025     x    = fit[0] + fit[2]*(Hit[ii]->Zpos);
01026     y    = fit[1] + fit[3]*(Hit[ii]->Zpos);
01027     uvx  = Hit[ii]->detec->rCos*x + Hit[ii]->detec->rSin * y;
01028     *chi += (uvx-Hit[ii]->rPos)* (uvx-Hit[ii]->rPos)*cff;
01029   }
01030   *chi = *chi / (No - 4);
01031 
01032 return 0;
01033 }
01034 //__________________________________________________________________
01035 int    rc_TrackFit( int No, Hit **Hit, vektor fit, matrix cov, double *chi,
01036                     double *addx, double *adde){
01037 cerr << "This function is a stub, it needs to be written" << endl;
01038 return -1;
01039 }
01040 //__________________________________________________________________
01041 int treecombine::r3_TrackFit( int Num, Hit **hit, double *fit, double *cov, double *chi,double uv2xy[2][2]){
01042   //###############
01043   // Declarations #
01044   //###############
01045 
01046   int i,j,k;
01047   Hit xyz[Num];
01048   double wcov[3],wchi,mx,bx,my,by;
01049   Hit *chihits[Num];
01050   double P1[3],P2[3],Pp1[3],Pp2[3];
01051   double ztrans,ytrans,xtrans,costheta,sintheta;
01052 
01053   //get some detector information
01054   if(hit[0]->detec->dir ==  u_dir){
01055     costheta = hit[0]->detec->rRotCos;
01056     sintheta = hit[0]->detec->rRotSin;
01057     xtrans = hit[0]->detec->center[0];
01058     ytrans = hit[0]->detec->center[1];
01059     ztrans = hit[0]->detec->Zpos;
01060         
01061   }
01062   else{
01063     cerr << "Error : first hit is not in 1st u-plane" << endl;
01064     return -1;
01065   }
01066   //#################################################
01067   // Calculate the x,y coordinates in the VDC frame #
01068   //#################################################
01069   for(i=0;i<Num;i++){
01070     xyz[i].rPos1=xyz[i].rPos=hit[i]->rPos1 * uv2xy[0][0] + hit[i]->rPos2 * uv2xy[0][1];//x
01071     xyz[i].rPos2=hit[i]->rPos1 * uv2xy[1][0] + hit[i]->rPos2 * uv2xy[1][1];//y
01072     xyz[i].Zpos=hit[i]->rPos;//z     
01073 
01074     //cerr << i << " 0 " << xyz[i].rPos1 << " " << xyz[i].rPos2 << " " << xyz[i].Zpos << " " << hit[i]->rPos1 << " " << hit[i]->rPos2 << endl;
01075     xyz[i].Resolution = 0;
01076   }
01077   //####################
01078   // Calculate the fit #
01079   //####################
01080 
01081   for(i=0;i<Num;i++)chihits[i]=&xyz[i];
01082   weight_lsq_r3(&mx,&bx,wcov,&wchi,chihits,Num,0,-1,Num);
01083   //cerr << "x = " << mx << "z+"<<bx << endl;
01084   for(i=0;i<Num;i++)xyz[i].rPos = xyz[i].rPos2;
01085   weight_lsq_r3(&my,&by,wcov,&wchi,chihits,Num,0,-1,Num);
01086   //cerr << "y = " << my << "z+"<<by << endl;
01087 
01088   //#################
01089   // Calculate chi2 #
01090   //#################
01091   // Note : without resolutions, chi2 is meaningless
01092 
01093   //##########################
01094   // Rotate to the lab frame #
01095   //##########################
01096 
01097 
01098 
01099   //get two points on the line
01100   P1[2] = xyz[0].Zpos;
01101   P1[0] = mx * P1[2] + bx;
01102   P1[1] = my * P1[2] + by;
01103   P2[2] = xyz[Num-1].Zpos;
01104   P2[0] = mx * P2[2] + bx;
01105   P2[1] = my * P2[2] + by;
01106 
01107   //rotate the points into the lab orientation
01108   Pp1[1] = P1[1]*costheta - P1[2]*sintheta;
01109   Pp1[2] = P1[1]*sintheta + P1[2]*costheta;
01110   Pp2[1] = P2[1]*costheta - P2[2]*sintheta;
01111   Pp2[2] = P2[1]*sintheta + P2[2]*costheta;
01112 
01113   //translate the points into the lab frame
01114   Pp1[0]+=xtrans;
01115   Pp1[1]+=ytrans;
01116   Pp1[2]+=ztrans;
01117   Pp2[0]+=xtrans;
01118   Pp2[1]+=ytrans;
01119   Pp2[2]+=ztrans;
01120 
01121   //calculate the new line
01122   mx = (Pp2[0]-Pp1[0])/(Pp2[2]-Pp1[2]);
01123   my = (Pp2[1]-Pp1[1])/(Pp2[2]-Pp1[2]);
01124   bx = Pp2[0]-mx*Pp2[2];
01125   by = Pp2[1]-my*Pp2[2];
01126 
01127   //and we're done :)
01128   fit[0]=bx;
01129   fit[1]=by;
01130   fit[2]=mx;
01131   fit[3]=my;
01132 
01133   cerr << "x = " << mx << "z+"<<bx << endl;
01134   cerr << "y = " << my << "z+"<<by << endl;
01135   return 0;
01136 }
01137 //__________________________________________________________________
01138 int treecombine::TcTreeLineCombine(TreeLine *wu,TreeLine *wv,PartTrack *pt, int tlayer )
01139 {
01140   //###############
01141   // Declarations #
01142   //###############
01143   Hit *hits[tlayer*2], **hitarray, *h;
01144   int hitc,num,i,j;
01145   static double cov[4][4];
01146   double *covp = &cov[0][0];
01147   double fit[4],chi;
01148   double *fitp = &fit[0];
01149   enum Edir dir;
01150   extern int iEvent;
01151   double m,b;
01152   double uv2xy[2][2];//2 by 2 projection matrix
01153   //initialize cov,uv2xy
01154   for(i=0;i<4;i++){for(j=0;j<4;j++){cov[i][j]=0;}}
01155   for(i=0;i<2;i++){for(j=0;j<2;j++){uv2xy[i][j]=0;}}
01156 
01157  //####################################
01158   //Get the v/u-coordinate for each hit 
01159   //on the u/v plane in the VDC frame
01160   //Note : need to implement some kind 
01161   //of resolution values at this point 
01162   //in the code.
01163   //####################################
01164   for(hitc = 0, dir = u_dir;dir<=v_dir;dir++){
01165     if(dir == u_dir){
01166       hitarray = wu->hits;
01167       num = wu->numhits;
01168       m = 1/wv->mx;
01169       b = -wv->cx/wv->mx;
01170     }
01171     else{
01172       hitarray = wv->hits;
01173       num = wv->numhits;
01174       m = 1/wu->mx;
01175       b = -wu->cx/wv->mx;
01176     }
01177     //cerr << "line = " << m << "x+" << b << endl;
01178     for(i=0;i<num;i++,hitarray++){
01179       h = *hitarray;
01180       if(dir == u_dir){
01181         if(!uv2xy[0][0]){
01182           uv2xy[0][0]=h->detec->rSin;
01183           uv2xy[1][0]=-h->detec->rCos;
01184         }
01185         h->rPos2 = m * h->rPos + b;//v
01186         h->rPos1 = h->Zpos;//u
01187         //z is rPos
01188       }else{
01189         if(!uv2xy[0][1]){
01190           uv2xy[0][1]=-h->detec->rSin;
01191           uv2xy[1][1]=h->detec->rCos;
01192         }
01193         h->rPos1 = m * h->rPos + b;//u
01194         h->rPos2 = h->Zpos;//v
01195         //z is rPos
01196       }
01197       //string all the hits together 
01198       if(h->used !=0){   
01199         hits[hitc++] = h;
01200       }
01201     }
01202   }
01203   //########################
01204   // Perform the track fit #
01205   //########################
01206 /*  if( rc_TrackFit( hitc, hits, fitp, covp, &chi, 0,0)  == -1) {
01207     fprintf(stderr,"hrc: Event: %d - PartTrack Fit Failed\n", iEvent);
01208     return 0;
01209   }*/
01210   if(r3_TrackFit(hitc,hits,fitp,covp,&chi,uv2xy) == -1){
01211     fprintf(stderr,"hrc: Event: %d - PartTrack Fit Failed\n", iEvent);
01212     return 0;
01213   }
01214   //#########################
01215   // Record the fit results #
01216   //#########################
01217   pt->x  = fit[0];
01218   pt->y  = fit[1];
01219   pt->mx = fit[2];
01220   pt->my = fit[3];
01221   pt->isvoid  = false;
01222 
01223   pt->chi = sqrt( chi);
01224   for( i = 0; i < 4; i++ )
01225     for( j = 0; j < 4; j++ ) 
01226       pt->Cov_Xv[i][j] = cov[i][j];
01227     
01228   pt->numhits = wu->numhits + wv->numhits;
01229   pt->tline[0] = wu;
01230   pt->tline[1] = wv;
01231 
01232 return 1;
01233 }
01234 //__________________________________________________________________
01235 int treecombine::TcTreeLineCombine( TreeLine *wu, TreeLine *wv, TreeLine *wx,
01236                     PartTrack *pt, int tlayer )
01237 {
01238   Hit *hits[DLAYERS*3], **hitarray, *h;
01239   int hitc, num, i, j;
01240   static matrix cov = 0;
01241   double fit[4], chi;
01242   enum Edir dir;
01243   extern int iEvent;
01244 
01245   if( !cov ) {
01246     cov = M_Init( 4,4);
01247   }
01248 
01249   for( hitc = 0, dir = u_dir; dir <= x_dir; dir++ ) {
01250     switch( dir ) {
01251     case u_dir: hitarray = wu->hits; break;
01252     case v_dir: hitarray = wv->hits; break;
01253     case x_dir: hitarray = wx->hits; break;
01254     default: hitarray = 0; break;
01255     }
01256       
01257     for( num = MAXHITPERLINE*DLAYERS; num--  && *hitarray; hitarray ++ ) {
01258       h = *hitarray;
01259       if( h->used != 0 && hitc < DLAYERS*3) 
01260         hits[hitc++] = h;
01261     }
01262   }
01263 
01264   if( rc_TrackFit( hitc, hits, fit, cov, &chi, 0,0)  == -1) {
01265     fprintf(stderr,"hrc: Event: %d - PartTrack Fit Failed\n", iEvent);
01266     return 0;
01267   }
01268   
01269   pt->x  = fit[0];
01270   pt->y  = fit[1];
01271   pt->mx = fit[2];
01272   pt->my = fit[3];
01273   pt->isvoid  = false;
01274 
01275   pt->chi = sqrt( chi);
01276   
01277   for( i = 0; i < 4; i++ )
01278     for( j = 0; j < 4; j++ ) 
01279       pt->Cov_Xv[i][j] = cov[i][j];
01280     
01281   pt->nummiss = wu->nummiss + wv->nummiss + wx->nummiss;
01282   pt->numhits = wu->numhits + wv->numhits + wx->numhits;
01283   pt->tline[0] = wu;
01284   pt->tline[1] = wv;
01285   pt->tline[2] = wx;
01286   return 1;
01287 }  
01288 //__________________________________________________________________
01289 double uv2x(double u,double v,double wirecos){
01290   return (u-v)*fabs(wirecos);
01291 }
01292 double uv2y(double u,double v,double wiresin){
01293   return (u+v)*fabs(wiresin);
01294 }
01295 double xy2u(double x,double y){
01296 cerr << "This function is just a stub" << endl;
01297 return -1000;
01298 }
01299 double xy2v(double x,double y){
01300 cerr << "This function is just a stub" << endl;
01301 return -1000;
01302 }
01303 //__________________________________________________________________
01304 /* ------------------------------
01305    Combines u v and x to tracks
01306    in space.
01307    ------------------------------ */
01308 /*INPUT:
01309         treelines : u and v direction
01310         bins : number of bins in one layer
01311         
01312   OUTPUT:
01313         (old) uvl gets new treelines for the front x direction
01314         parttrackanz : increased accordingly
01315         uvl : is used in TcTreeLineCombine
01316         PartTrack ret: a 3-D track
01317         
01318 
01319 */
01320 PartTrack *treecombine::TlTreeCombine(TreeLine *uvl[2],long bins,enum EUppLow up_low,enum ERegion region,enum Etype type,int tlayer,int dlayer)
01321 {
01322 //################
01323 // DECLARATIONS  #
01324 //################
01325   TreeLine *wu,*wv,*wx, *bwx, wrx;
01326   PartTrack *ret = 0, *ta;
01327   int in_acceptance;
01328   //int partmissidx = part + (method == meth_std? 0 : 1 )*2;
01329 
01330   double mu,xu,mv,xv, zx1, zx2, xx1, xx2,z1,z2;
01331   double x,y,mx,my,v1,v2,u1,u2, y1, y2;
01332   double x1, x2, d, maxd = 1e10, d1, d2;
01333   //double z;
01334   double rcSETrMaxXRoad         = 0.25;
01335   chi_hashclear();
01336 
01337   double uv_dz;//distance between u and v planes
01338   double Rot;//rotation of planes about the lab x-axis
01339   Det *rd;
01340   double wirecos,wiresin,x_[2],y_[2];
01341 //###############
01342 // DO STUFF     #
01343 //###############
01344 
01345   //################
01346   // REGION 3      #
01347   //################
01348   if(region == r3 && type == d_drift){
01349 
01350     rd = rcDETRegion[up_low][region-1][u_dir];
01351     z1 = rd->Zpos;
01352     rd = rcDETRegion[up_low][region-1][v_dir];
01353     z2 = rd->Zpos;
01354     Rot = rd->Rot;
01355     uv_dz = (z2-z1)/sin(Rot);//assuming the planes have the same rot angle about the lab x-axis.
01356     wirecos = rd->rCos;
01357     wiresin = rd->rSin;
01358 
01359     //###################################
01360     // Get distance between planes, etc #
01361     //###################################
01362     rd = rcDETRegion[up_low][region-1][u_dir];
01363     x_[0]= rd->center[0];
01364     y_[0]= rd->center[1]; 
01365     rd = rcDETRegion[up_low][region-1][u_dir]->nextsame;  
01366     x_[1]= rd->center[0];
01367     y_[1]= rd->center[1]; 
01368     d = sqrt(pow(x_[1]-x_[0],2)+pow(y_[1]-y_[0],2));//<-distance between first u and last v planes
01369 
01370     //#########################
01371     // Get the u and v tracks #
01372     //#########################
01373     wu = uvl[u_dir];//get the u track
01374     while(wu){
01375       if(wu->isvoid!=0){//skip this treeline if it was no good
01376         wu = wu->next;
01377         continue;
01378       }
01379       //get wu's line parameters
01380       mu = wu->mx;//slope
01381       xu = wu->cx;//constant
01382 
01383       wv = uvl[v_dir];//get the v track
01384       while(wv){
01385         if(wv->isvoid!=0){
01386           wv = wv->next;
01387           continue;
01388         }
01389         //get wv's line parameters
01390         mv = wv->mx;//slope
01391         xv = wv->cx;//constant
01392 
01393         PartTrack *ta = new PartTrack();
01394 
01395         parttrackanz ++;
01396 
01397         if( TcTreeLineCombine( wu, wv, ta, tlayer) ) {
01398             ta->ID = 0;
01399             ta->isvoid  = false;
01400             //ta->trdcol  = 0;
01401             ta->next   = ret;
01402             //ta->method = method;
01403             ta->bridge = 0;
01404             //ta->cluster  = 0;
01405             ta->Used     = 0;
01406             ta->pathlenoff = 0;
01407             ta->pathlenslo = 0;
01408             ta->next = ret;//string together the
01409             ret = ta;//      good tracks
01410         }
01411 
01412         // Check whether this track went through the trigger and/or
01413         // the Cerenkov bar. 
01414         checkR3(ta,up_low);
01415 
01416         wv = wv->next;
01417       }
01418       wu = wu->next;
01419     }
01420   return ret;
01421   }
01422   //#################
01423   // OTHER REGIONS  #
01424   //#################
01425   //all that follows is useful legacy junk
01426   else{
01427   wu = uvl[u_dir];      
01428   zx1 = rcTreeRegion[up_low][region-1][type][x_dir]->rZPos[0];
01429   zx2 = rcTreeRegion[up_low][region-1][type][x_dir]->rZPos[tlayer-1];
01430   while( wu) {
01431     if( wu->isvoid != 0 ) {
01432       wu = wu->next;
01433       continue;
01434     }
01435     mu = wu->mx;
01436     xu = wu->cx;
01437     wv = uvl[v_dir];
01438     while(wv) {
01439       if( wv->isvoid != 0 ) {
01440         wv = wv->next;
01441         continue;
01442       }
01443       
01444       mv = wv->mx;
01445       xv = wv->cx;
01446       /* --- get u/v at the x detectors --- */
01447       u1 = xu + (zx1 - magnet_center) * mu;
01448       u2 = xu + (zx2 - magnet_center) * mu;
01449       v1 = xv + (zx1 - magnet_center) * mv;
01450       v2 = xv + (zx2 - magnet_center) * mv;
01451       
01452       /* ------ for x -------- */
01453       x1 = uv2x( u1, v1,1);
01454       x2 = uv2x( u2, v2,1);
01455 
01456       /* ------ for y -------- */
01457       y1 = uv2y( u1, v1,1);
01458       y2 = uv2y( u2, v2,1);
01459         
01460       my = (y2-y1)/(zx2-zx1);
01461       y  = 0.5*(y1+y2) + my * (magnet_center - 0.5*(zx1+zx2));
01462 
01463       /* --- for the back region we now loop over the x treelines,
01464          too. For the front region there are no x tree lines, yet.
01465          they have to be calculated first --- */
01466 
01467       maxd = 1e10;
01468       if( rcTreeRegion[up_low][region-1][type][x_dir]->searchable != 0){
01469         wx = uvl[x_dir];
01470         bwx = 0;
01471 
01472         while( wx ) {
01473           if( wx->isvoid != 0 ) {
01474             wx = wx->next;
01475             continue;
01476           }
01477           mx = wx->mx;
01478           x  = wx->cx;
01479           xx1 = x + (zx1 - magnet_center) * mx;
01480           xx2 = x + (zx2 - magnet_center) * mx;
01481           d1 = x1-xx1;
01482           if( d1 < 0 ) d1 = -d1;
01483           d2 = x2-xx2;
01484           if( d2 < 0 ) d2 = -d2;
01485           d = d1+d2;      
01486           if( d < maxd ) {
01487             bwx = wx;
01488             maxd = d;
01489           }
01490           wx = wx->next;
01491         }
01492       } else {
01493         /* for the front region we have to find the x treelines now --- */
01494         
01495         //visdir = x_dir;       
01496         
01497         if( TlCheckForX(x1,x2, rcSETrMaxXRoad,rcSETrMaxXRoad, zx1,zx2-zx1,
01498                         &wrx,up_low,region,type,x_dir,dlayer,tlayer, 0,1)) {
01499         //replaced a Qmalloc below
01500           wx = (TreeLine *)malloc( sizeof( TreeLine));
01501           assert( wx );
01502           *wx = wrx;
01503 
01504           bwx = wx;
01505           //wx->method = meth_std;
01506           wx->next = uvl[x_dir]; /* chain the link to the  */
01507           uvl[x_dir] = wx;       /* event treeline list */
01508           maxd  = fabs( x1 - (wx->cx + wx->mx*(zx1-magnet_center)));
01509           maxd += fabs( x2 - (wx->cx + wx->mx*(zx2-magnet_center)));
01510         } else
01511           bwx = 0;
01512       }
01513       
01514       int rcSETiMissingVC0     = 6;
01515       int rcSETiMissingPT0     = 5;
01516       cerr << "ERROR : USING STUB VALUE FOR RCSET " << endl;
01517       if( maxd < 2 * rcSETrMaxXRoad
01518           && bwx
01519           && rcSETiMissingVC0/*rcSETiMissingVC[0]*/
01520           >= bwx->numvcmiss + wu->numvcmiss + wv->numvcmiss
01521           && rcSETiMissingPT0/*rcSET.iMissingPT[partmissidx]*/
01522           >= bwx->nummiss + wu->nummiss + wv->nummiss) {
01523         in_acceptance = inAcceptance( up_low, region, bwx->cx, bwx->mx, y, my);
01524         if( in_acceptance ) {
01525 
01526           wx = bwx;
01527           x  = wx->cx;
01528           mx = wx->mx;
01529           
01530           wx->Used = wu->Used = wv->Used = 1;
01531           //visdir = x_dir;
01532 
01533           //Statist[method].PartTracksGenerated[where][part] ++;
01534           
01535           /* ---- form a new PartTrack ---- */
01536           //replaced a Qmalloc below
01537           ta = (PartTrack *)malloc( sizeof(PartTrack));
01538 
01539           parttrackanz ++;
01540           assert(ta);
01541 
01542           if( TcTreeLineCombine( wu, wv, wx, ta, tlayer) ) {
01543             ta->ID = 0;
01544             ta->isvoid  = false;
01545             //ta->trdcol  = 0;
01546             ta->next   = ret;
01547             //ta->method = method;
01548             ta->bridge = 0;
01549             //ta->cluster  = 0;
01550             ta->Used     = 0;
01551             ta->pathlenoff = 0;
01552             ta->pathlenslo = 0;
01553             ret = ta;
01554           }
01555         } 
01556       }   
01557       wv = wv->next;
01558     }
01559     wu = wu->next;
01560   }
01561   return ret;
01562   }
01563 }
01564 //__________________________________________________________________
01565 void treecombine::ResidualWrite( Event *event)
01566 {
01567   cerr << "This function may need a 'for loop' for orientation" << endl;
01568 
01569   enum EUppLow up_low;
01570   enum ERegion region;
01571   enum Edir dir;
01572   enum Etype type;
01573   //enum Eorientation orient;
01574   int allmiss, num;
01575   Track *tr;
01576   PartTrack *pt;
01577   TreeLine *tl;
01578   double x, y, v, mx, my, mv;
01579   Hit **hitarr, *hit;
01580   void mcHitCord( int, double* , double *);
01581 
01582   for( up_low = w_upper; up_low <= w_lower; up_low ++ ) {
01583     for( tr = event->usedtrack[up_low]; tr; tr=tr->next ) {
01584       //type = tr->type;
01585       for( region = r1; region <= r3; region ++ ) {
01586         /*
01587         if( region == f_front)
01588           pt = tr->front;
01589         else
01590           pt = tr->back;
01591         
01592         allmiss = ( pt->tline[0]->nummiss +
01593                     pt->tline[1]->nummiss +  pt->tline[2]->nummiss);
01594         */
01595         for( dir = u_dir; dir <= x_dir; dir ++ ) {
01596           tl = pt->tline[dir];
01597           hitarr = tl->hits;
01598         
01599           for( num = MAXHITPERLINE*DLAYERS; num--&&*hitarr; hitarr ++ ) {
01600             hit = *hitarr;
01601             if( hit->used ) {
01602               x = pt->mx*( hit->Zpos - magnet_center ) + pt->x;
01603               y = pt->my*( hit->Zpos - magnet_center ) + pt->y;
01604               //mcHitCord( hit->mcId, &mx, &my);
01605               switch(dir) {
01606               case u_dir: v = xy2u( x,y ); mv = xy2u(mx,my); break;
01607               case v_dir: v = xy2v( x,y ); mv = xy2v(mx,my); break;
01608               case x_dir: v = x; mv = mx; break;
01609               default:    mv = v = 0;break;
01610               }
01611               printf("%d %d %d %d %d "
01612                      "%d "
01613                      "%f "
01614                      "%f %f %f "
01615                      "%f %f %f %f "
01616                      "%d %d %f %f %f "
01617                      "%f "
01618                      "XXptresXX\n",
01619                      hit->detec->ID, type, up_low, region,dir,
01620                      hit->wire,
01621                      0.5*(hit->rPos1+hit->rPos2), 
01622                      hit->rPos, v, hit->rResultPos,
01623                      tl->chi, pt->chi,x, y,
01624                      tl->nummiss, allmiss, mx, my, mv,
01625                      tr->P);
01626             }
01627           }
01628         }
01629       }
01630     }
01631   }
01632   return;
01633 }
01634 //__________________________________________________________________
01635 matrix  M_Init (int Zeilen, int Spalten)
01636 {
01637 
01638   matrix ret;
01639   int n;
01640 
01641   n = Zeilen;
01642   ret = (matrix) calloc (1, 0x10 + Zeilen * (sizeof (vektor) + 
01643                                              Spalten * sizeof (double)));
01644   if(!ret)
01645         exit(0);
01646   while (n--)
01647     *(ret + n) = (vektor) (((char *) ret) +
01648                            (( (Zeilen * sizeof (vektor)) & ~0xf ) +0x10) +
01649                            n * Spalten * sizeof (double));
01650 
01651   return ret;
01652 }
01653 //__________________________________________________________________
01654 // Least upper bound standard
01655 double UNorm ( double *A, int n, int m)
01656 {
01657   double Max = 0.0, help;
01658   int counter;
01659   double *B = A;
01660   while (n--) {
01661     counter = m;
01662     while (counter--){
01663       B = A + n + counter;
01664       if (Max < (help = fabs (*(B))))
01665         Max = help;
01666       }
01667   }
01668   return Max;
01669 }
01670 //__________________________________________________________________
01671 double *M_Cholesky (double  *B, double *q, int n)
01672 {
01673   register int i, j, k;
01674   double sum, min;
01675   double *C = B;
01676   double A[n][n];
01677   double p[n],*pp;
01678 
01679   for(i=0;i<n;i++){
01680     for(j=0;j<n;j++){
01681       A[i][j]=*C;
01682       C++;
01683     }
01684   }
01685 
01686   min = UNorm (B, n, n)  * n * DBL_EPSILON;
01687   for( i = 0; i < n; i++ ) {
01688     for( j = i; j < n; j++ ) {
01689       sum = A[i][j];
01690       for( k = i-1; k >= 0; k-- ) 
01691         sum -= A[i][k] * A[j][k];
01692       if( i == j ) {
01693         if( sum < min ) {
01694           return 0;
01695         }
01696         p[i] = sqrt(sum);
01697       } else
01698         A[j][i] = sum/p[i];
01699     }
01700   }
01701   C = B;
01702   pp=q;
01703   for(i=0;i<n;i++){
01704     *p = p[i];
01705     pp++;
01706     for(j=0;j<n;j++){
01707       *C = A[i][j];
01708       C++;
01709     }
01710   }
01711   C = B;
01712   pp = q;
01713   return B;
01714 }
01715 //__________________________________________________________________
01716 double *M_InvertPos (double *B, int n)
01717 {
01718 
01719   int i,j, k;
01720   double sum;
01721   double p[n];
01722   double q[n];
01723   double inv[n][n]; 
01724   double *pp;
01725   double A[n][n],*C;
01726   /* first we need the cholesky decomposition */
01727   
01728   if( M_Cholesky( B, pp, n) ) {
01729 
01730     C = B;
01731     for( i = 0; i < n; i++) {
01732       p[i]=*q;
01733       for( j = 0; j < n; j++ ) {
01734         A[i][j]= *C;
01735         C++;
01736       }
01737     }
01738 
01739 
01740 
01741     for( i = 0; i < n; i++) { 
01742       A[i][i] = 1.0/p[i];
01743       for( j = i+1; j < n; j++ ) {
01744         sum = 0;
01745         for( k = i; k < j; k++ )
01746           sum -= A[j][k] * A[k][i];
01747         A[j][i] = sum / p[j];
01748       }
01749     }
01750     
01751     for( i = 0; i < n; i++ ) {
01752       for( j = i; j < n; j++ ) {
01753         sum = 0;
01754         for( k = j; k < n; k++ ) 
01755           sum += A[k][i] * A[k][j];
01756         inv[i][j] = inv[j][i] = sum;
01757       }
01758     }    
01759 
01760     C = B;
01761     for( i = 0; i < n; i++) {
01762       for( j = 0; j < n; j++ ) {
01763         *C = inv[i][j];
01764         C++;
01765       }
01766     }
01767 
01768   } else{ 
01769     B = 0;
01770     cerr << "Cholesky failed" << endl;
01771   }
01772   C = B;
01773 
01774   return B;
01775 }
01776 //__________________________________________________________________
01777 /*--------------------------*
01778   Multiplication of Matrix A with vector b
01779  *--------------------------*/
01780 double * 
01781 M_A_mal_b (double *y,double *A, int n, int m,double b[4])
01782 {
01783 
01784   double AA[n][m],*Ap=A;
01785   double yy[n],*z = y;
01786   int n2 = n;
01787   for(int i=0;i<n;i++){
01788     yy[i]=*z;
01789     z++;
01790     for(int j=0;j<m;j++){
01791       AA[i][j]=*Ap;
01792       Ap++;
01793     }
01794   }
01795   Ap = A;
01796   z = y;
01797   int counter;
01798   double Sum;
01799   double *yp = y;
01800   while (n--) {
01801     counter = m;
01802     Sum = 0.0;
01803     while (counter--)
01804       Sum += AA[n][m]*b[m];
01805     yy[n] = Sum;
01806   }
01807   
01808   for(int i=0;i<n2;i++){
01809     *z = y[i];
01810     z++;
01811   }
01812   z = y;
01813 
01814 
01815 
01816   return y;
01817 }
01818 //__________________________________________________________________
01819 int treecombine::checkR3(PartTrack *pt,enum EUppLow up_low){
01820   double trig[3],cc[3];
01821   double lim_trig[2][2],lim_cc[2][2];
01822   Det *rd = rcDETRegion[up_low][2][x_dir];//get the trig scint
01823   
01824   //get the point where the track intersects the detector planes
01825   trig[2] = rd->Zpos;
01826   trig[0] = pt->mx * trig[2] + pt->x;
01827   trig[1] = pt->my * trig[2] + pt->y;
01828   //get the detector boundaries
01829   lim_trig[0][0] = rd->center[0]+rd->width[0];
01830   lim_trig[0][1] = rd->center[0]-rd->width[0];
01831   lim_trig[1][0] = rd->center[1]+rd->width[1];
01832   lim_trig[1][1] = rd->center[1]-rd->width[1];
01833   
01834   if(trig[0]<lim_trig[0][0] 
01835      && trig[0]>lim_trig[0][1]
01836      && trig[1]<lim_trig[1][0] 
01837      && trig[1]>lim_trig[1][1]){
01838         pt->triggerhit=1;
01839         pt->trig[0] = trig[0];
01840         pt->trig[1] = trig[1];
01841   }else pt->triggerhit=0;
01842 
01843   rd = rcDETRegion[up_low][2][y_dir];//get the CC
01844   cc[2] = rd->Zpos;
01845   cc[0] = pt->mx * cc[2] + pt->x;
01846   cc[1] = pt->my * cc[2] + pt->y;
01847   lim_cc[0][0] = rd->center[0]+rd->width[0];
01848   lim_cc[0][1] = rd->center[0]-rd->width[0];
01849   lim_cc[1][0] = rd->center[1]+rd->width[1];
01850   lim_cc[1][1] = rd->center[1]-rd->width[1];
01851   
01852   if(cc[0]<lim_cc[0][0] 
01853      && cc[0]>lim_cc[0][1]
01854      && cc[1]<lim_cc[1][0] 
01855      && cc[1]>lim_cc[1][1]){
01856         pt->cerenkovhit=1;
01857         pt->cerenkov[0] = cc[0];
01858         pt->cerenkov[1] = cc[1];
01859   }else pt->cerenkovhit=0;
01860 
01861 return 0;
01862 }

Generated on Fri Jan 11 22:33:59 2008 by  doxygen 1.4.6