00001 #include <iostream>
00002 #include "treecombine.h"
00003 #include <math.h>
00004 #include "mathstd.h"
00005 #include <fstream>
00006
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
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;
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
00072
00073 chi_hash *new_chi_hash;
00074 new_chi_hash = (chi_hash*)malloc(sizeof(chi_hash));
00075
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
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 ) {
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
00123
00124
00125
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
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
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 int treecombine::bestx(double *xresult, double dist_cut, Hit *h, Hit **ha){
00168
00169
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
00182
00183
00184
00185
00186 cerr << "2";
00187 if( h )
00188 breakcut = h->detec->WireSpacing + dist_cut;
00189
00190 cerr << "3";
00191 while( h ) {
00192 doub = 0;
00193 for( j = 0; j < 2; j++ ) {
00194
00195 pos = j ? h->rPos2 : h->rPos1;
00196 distance = x - pos;
00197 adist = distance < 0 ? -distance : distance;
00198 if( adist < dist_cut) {
00199 if( good < MAXHITPERLINE ) {
00200
00201
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 {
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
00244
00245
00246
00247
00248
00249
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
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
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 ) {
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
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
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
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
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
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
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
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
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
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
00382 for( i = 0; i < tlayers; i++ ) {
00383 A[i][0] = -1.0;
00384 }
00385
00386
00387
00388 for( i = 0; i < n; i++ ) {
00389 if(offset == -1){
00390 A[i][1] = -hits[i]->Zpos;
00391 y[i] = -hits[i]->rPos;
00392 }
00393 else{
00394 A[i][1] = -(i+offset);
00395 y[i] = -hits[i]->rResultPos;
00396 }
00397 r = 1.0 / hits[i]->Resolution;
00398 if(!(hits[i]->Resolution))r = 1.0 / resolution;
00399 G[i][i] = r*r;
00400 }
00401
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
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
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
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
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
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
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
00480 if( !h->detec ||
00481 (h->detec != detec
00482 )) {
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
00505
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;
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
00538
00539
00540 if(
00541
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
00553
00554
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
00560
00561 Det *rd, *firstdet = 0, *lastdet;
00562 double org_x;
00563 double org_mx;
00564 double org_dx;
00565 double org_dmx;
00566 double thisX, thisZ;
00567 double startZ = 0.0, endZ = 0;
00568 Hit *DetecHits[DLAYERS][MAXHITPERLINE];
00569 Hit *UsedHits[DLAYERS];
00570 Hit **hitarray;
00571 double res,resnow;
00572 double mx,cx,dh,chi,minchi=1e8;
00573 double minweight = 1e10;
00574 double mmx=0,mcx=0;
00575 double cov[3], mcov[3];
00576 double stay_chi;
00577 int i,j;
00578 int nMult[DLAYERS];
00579 int nhits;
00580 int permutations = 1;
00581
00582 int besti = -1;
00583 int ret = 0;
00584 int first;
00585
00586
00587
00588
00589
00590 org_mx = (x2-x1)/dz;
00591 org_x = x1 + org_mx * (magnet_center-z1);
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));
00598
00599 org_mx = (x2-x1)/dz;
00600
00601 org_dmx = (dx2-dx1)/dz;
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 if(region == r3){
00612
00613 }
00614 else{
00615
00616
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
00631
00632
00633
00634 double rcSETrMaxRoad = 1.4;
00635 cerr << "ERROR : USING STUB VALUE FOR RCSET " << endl;
00636
00637
00638
00639
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
00645
00646 if( !iteration ){
00647 nMult[nhits] = bestx( &thisX, resnow,
00648 rd->hitbydet, DetecHits[nhits]);
00649 }
00650 else
00651 nMult[nhits] = selectx( &thisX, resnow,
00652 rd, treefill->hits, DetecHits[nhits]);
00653 cerr << "b";
00654 if( nMult[nhits] ) {
00655 permutations *= nMult[nhits];
00656 } else {
00657 nhits --;
00658 }
00659 nhits++;
00660 }
00661 }
00662
00663
00664
00665 if( !iteration ) {
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;
00675 }
00676
00677
00678
00679
00680
00681
00682
00683 int rcSETiMissingTL0 = 2;
00684 if( nhits >= dlayer - rcSETiMissingTL0) {
00685 for( i = 0; i < permutations; i++ ) {
00686
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
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;
00715 treefill->chi = minchi;
00716 treefill->numhits = nhits;
00717
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
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
00750
00751
00752
00753
00754
00755
00756
00757
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
00762
00763 double thisX, thisZ;
00764 Hit *h;
00765 Det *rd;
00766 double dx,slope,intercept;
00767 Hit DetecHits[tlayers];
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
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
00782 nhits = treefill->lastwire - treefill->firstwire + 1;
00783 if(nhits < 0) nhits = - nhits;
00784
00785
00786
00787
00788
00789 rd = rcDETRegion[up_low][region-1][dir];
00790 if(treefill->r3offset >=100){
00791 rd = rd->nextsame;
00792 }
00793 for(int i=treefill->firstwire;i<=treefill->lastwire;i++){
00794 for(h = rd->hitbydet;h;h = h->next){
00795 thisZ = treefill->r3offset+i;
00796 thisX = slope*thisZ + intercept;
00797 if(h->wire!=thisZ){
00798 continue;
00799 }
00800
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
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
00818
00819 chi = 0.0;
00820 weight_lsq_r3( &mx, &cx, cov, &chi,treefill->hits, j,z1,treefill->r3offset,tlayers);
00821
00822
00823
00824 treefill->cx = cx;
00825 treefill->mx = mx;
00826 treefill->chi = chi;
00827 treefill->numhits = nhits;
00828 memcpy(treefill->cov_cxmx, cov, sizeof cov);
00829 if(nhits>=7){
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
00845
00846
00847
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
00860
00861 for( walk = tl; walk; walk = walk->next ) {
00862 if( ! walk->isvoid ) {
00863 if(dlayer==1){
00864 walk->r3offset +=282;
00865 }
00866 z1 = (double)(walk->r3offset+walk->firstwire);
00867 z2 = (double)(walk->r3offset+walk->lastwire);
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
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];
00902 z2 = rcTreeRegion[up_low][region-1][type][dir]->rZPos[tlayer-1];
00903
00904 dx = rcTreeRegion[up_low][region-1][type][dir]->rWidth;
00905 dxh = 0.5*dx;
00906 dx /= (double)bins;
00907 dxb = dxh/(double)bins;
00908
00909
00910
00911
00912
00913 double rcSETrMaxRoad = 1.4;
00914 cerr << "ERROR : USING STUB VALUE FOR RCSET " << endl;
00915 for( walk = tl; walk; walk = walk->next ) {
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
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
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++) {
00961 B[ik] = 0;
00962 for(ij = 0; ij < 4; ij++)
00963 AA[ij][ik] = 0;
00964 }
00965
00966
00967
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
01018 M_A_mal_b( fit, cov, 4, 4, B);
01019
01020
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
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
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
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];
01071 xyz[i].rPos2=hit[i]->rPos1 * uv2xy[1][0] + hit[i]->rPos2 * uv2xy[1][1];
01072 xyz[i].Zpos=hit[i]->rPos;
01073
01074
01075 xyz[i].Resolution = 0;
01076 }
01077
01078
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
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
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
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
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
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
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
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
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];
01153
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
01159
01160
01161
01162
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
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;
01186 h->rPos1 = h->Zpos;
01187
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;
01194 h->rPos2 = h->Zpos;
01195
01196 }
01197
01198 if(h->used !=0){
01199 hits[hitc++] = h;
01200 }
01201 }
01202 }
01203
01204
01205
01206
01207
01208
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
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
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
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
01324
01325 TreeLine *wu,*wv,*wx, *bwx, wrx;
01326 PartTrack *ret = 0, *ta;
01327 int in_acceptance;
01328
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
01334 double rcSETrMaxXRoad = 0.25;
01335 chi_hashclear();
01336
01337 double uv_dz;
01338 double Rot;
01339 Det *rd;
01340 double wirecos,wiresin,x_[2],y_[2];
01341
01342
01343
01344
01345
01346
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);
01356 wirecos = rd->rCos;
01357 wiresin = rd->rSin;
01358
01359
01360
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));
01369
01370
01371
01372
01373 wu = uvl[u_dir];
01374 while(wu){
01375 if(wu->isvoid!=0){
01376 wu = wu->next;
01377 continue;
01378 }
01379
01380 mu = wu->mx;
01381 xu = wu->cx;
01382
01383 wv = uvl[v_dir];
01384 while(wv){
01385 if(wv->isvoid!=0){
01386 wv = wv->next;
01387 continue;
01388 }
01389
01390 mv = wv->mx;
01391 xv = wv->cx;
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
01401 ta->next = ret;
01402
01403 ta->bridge = 0;
01404
01405 ta->Used = 0;
01406 ta->pathlenoff = 0;
01407 ta->pathlenslo = 0;
01408 ta->next = ret;
01409 ret = ta;
01410 }
01411
01412
01413
01414 checkR3(ta,up_low);
01415
01416 wv = wv->next;
01417 }
01418 wu = wu->next;
01419 }
01420 return ret;
01421 }
01422
01423
01424
01425
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
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
01453 x1 = uv2x( u1, v1,1);
01454 x2 = uv2x( u2, v2,1);
01455
01456
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
01464
01465
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
01494
01495
01496
01497 if( TlCheckForX(x1,x2, rcSETrMaxXRoad,rcSETrMaxXRoad, zx1,zx2-zx1,
01498 &wrx,up_low,region,type,x_dir,dlayer,tlayer, 0,1)) {
01499
01500 wx = (TreeLine *)malloc( sizeof( TreeLine));
01501 assert( wx );
01502 *wx = wrx;
01503
01504 bwx = wx;
01505
01506 wx->next = uvl[x_dir];
01507 uvl[x_dir] = wx;
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
01520 >= bwx->numvcmiss + wu->numvcmiss + wv->numvcmiss
01521 && rcSETiMissingPT0
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
01532
01533
01534
01535
01536
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
01546 ta->next = ret;
01547
01548 ta->bridge = 0;
01549
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
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
01585 for( region = r1; region <= r3; region ++ ) {
01586
01587
01588
01589
01590
01591
01592
01593
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
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
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
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
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];
01823
01824
01825 trig[2] = rd->Zpos;
01826 trig[0] = pt->mx * trig[2] + pt->x;
01827 trig[1] = pt->my * trig[2] + pt->y;
01828
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];
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 }