Privacy and Security Notice

treesort.cc Source File

treesort.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include "treesort.h"
00003 using namespace std;
00004 
00009 //________________________________________________________________________
00010 treesort::~treesort(void){
00011 
00012 }
00013 //________________________________________________________________________
00014 treesort::treesort(void){
00015   doubletrack = 0.2;
00016   good = 2;
00017 }
00018 //________________________________________________________________________
00019 /* ======================================================================
00020  * checks for connected lines on the connectivity array
00021  * ====================================================================== */
00022 
00023 int treesort::connectiv( char *ca, int *array, int *isvoid, char size, int idx )
00024 {
00025         int ret, j;
00026         idx *= size;
00027         for( ret = j = 0; j < size; j++ ) {
00028                 if( array[j+idx] && (!ca || ca[j]) && isvoid[j] != true)
00029                         ret ++;
00030         }
00031         return ret;
00032 }
00033 //________________________________________________________________________
00034 double treesort::chiweight( TreeLine *tl )
00035 {
00036         double fac;
00037   
00038         if( tl->numhits > tl->nummiss )
00039                 fac = (double)(tl->numhits+tl->nummiss)/(tl->numhits - tl->nummiss);
00040         else
00041                 return 100.0;
00042         return fac * tl->chi;
00043 }
00044 //________________________________________________________________________
00045 double treesort::ptchiweight( PartTrack *pt )
00046 {
00047         double fac;
00048 
00049         if( pt->numhits > pt->nummiss )
00050                 fac = (double)(pt->numhits+pt->nummiss)/(pt->numhits - pt->nummiss);
00051         else
00052                 return 100.0;
00053         return fac * fac * pt->chi;//why is 'fac' squared here, but not in chiweight?
00054 }
00055 //________________________________________________________________________
00056 int treesort::connectarray( char *ca, int *array, int *isvoid, char size, int idx )
00057 {
00058         int i;
00059         int j;
00060   
00061         memset( ca, 0, size);
00062         ca[idx] = 1;
00063         for( i = 0; i < size; i++ ) {
00064                 if( ca[i] ) {
00065                         for( j = i+1; j < size ; j++ ) {
00066                                 if( array[j+i*size]  && isvoid[j] == false )
00067                                         ca[j] = 1;
00068                         }
00069                 }
00070         }
00071         return 0;
00072 }
00073 //________________________________________________________________________
00074 void treesort::bestunconnected( char *ca, int *array, int *isvoid, double *chia,
00075                  int size, int idx)
00076 {
00077   int i,j;
00078   int besti = idx, bestj = -1;
00079   double bestchi = chia[idx], bestdchi;
00080 
00081   for(j = idx+1; j < size; j++ ) { /* search for the best single-track */
00082     if( !ca[j] )
00083       continue;
00084     if( chia[j] < bestchi ) {
00085       besti = j;
00086       bestchi = chia[j];
00087     }
00088   }
00089 
00090   bestdchi = (bestchi)*(2+doubletrack);// this will allow a double track, with the 2nd best chi
00091   //to be up to (doubletrack)% larger than the best chi.
00092   
00093   for( i = idx; i < size; i++ ) { /* is there a double track ? */
00094     if( !ca[i] )
00095       continue;
00096     for( j = i+1; j < size; j++ ) {
00097       if( !ca[j] )
00098         continue;
00099       if( array[i*size+j] )//if it's two tracks sharing a bunch of wires, don't worry about it
00100         continue;
00101       if( chia[j]+chia[i] < bestdchi ) {//but if there's two separate tracks, with good chi, then it's a double track
00102         besti = i;
00103         bestj = j;
00104         bestdchi = chia[j]+chia[i];
00105       }
00106     }
00107   }
00108 
00109   for(i = idx; i<size; i++ ) {
00110     if( !ca[i] )
00111       continue;
00112     if( i == besti || i == bestj || besti == -1) {
00113       isvoid[i] = good;//good
00114     } 
00115     else if( isvoid[i] == false ) {
00116       if( (besti >= 0 && array[i*size+besti] ) ||
00117           (bestj >= 0 && array[i*size+bestj])){
00118         isvoid[i] = true;
00119       }
00120     }
00121   }
00122 }
00123 //________________________________________________________________________
00124 int treesort::globalconnectiv( char *ca, int *array, int *isvoid, int size, int idx)
00125 {
00126         int i, max = 0, c;
00127         bool old;
00128   
00129         old = isvoid[idx];
00130         isvoid[idx] = false;
00131 
00132         for(i = 0; i < size; i++ ) {
00133                 if( isvoid[i] != true ) {
00134                         c = connectiv( ca, array, isvoid, size, i);
00135                         if( c > max )
00136                                 max = c;
00137                 }
00138         }
00139         isvoid[idx] = old;
00140         return max;
00141 }
00142 //________________________________________________________________________
00143 int treesort::bestconnected( char *ca, int *array, int *isvoid, double *chia,
00144                int size, int idx)
00145 {
00146   int i, besti = -1;
00147   double bestchi = 1e8, oworst = 0.0;
00148   double chi;
00149   
00150   for(i = idx; i<size; i++ ) {
00151     if( !ca[i] )      
00152       continue;
00153     chi = chia[i];
00154     if( isvoid[i] != true) {
00155 
00156       if( oworst < chi )
00157         oworst = chi;
00158       continue;
00159     }
00160     if( globalconnectiv( ca, array, isvoid, size, i) > 2 )
00161       continue;
00162 
00163     if( bestchi > chi ) {
00164       besti = i;
00165       bestchi = chi;
00166     }
00167   }
00168   if( besti >= 0 && (3.0 > bestchi || oworst + 3.0 > bestchi )) {
00169     isvoid[i] = good;//good
00170     return 1;
00171   }
00172   return 0;
00173 }
00174 //________________________________________________________________________
00175 int treesort::rcPTCommonWires(PartTrack *track1,PartTrack *track2){
00176   int i;
00177   int common = 0;
00178   for( i = 0; i < 3; i++)
00179     common += rcCommonWires( track1->tline[i], track2->tline[i]);
00180   common /= 3;
00181   return common;
00182 }
00183 //________________________________________________________________________
00184 /* This function simply counts the number of common wires
00185 shared between two treelines.  The only output is the integer
00186 return value
00187 */
00188 int treesort::rcCommonWires_r3(TreeLine *line1,TreeLine *line2 ){
00189 //################
00190 // DECLARATIONS  #
00191 //################
00192   int total1, total2, common, total;
00193   Hit **hits1, **hits2;
00194   int did1, did2;
00195   int  i1, i2, fw = 3;
00196 //##################
00197 //DEFINE VARIABLES #
00198 //##################
00199   common = total1 = total2 = total = 0;
00200   i1 = i2 = -1;
00201   hits1  = line1->hits;
00202   hits2  = line2->hits;
00203 //##############################################
00204 //Count the wires shared between the treelines #
00205 //##############################################
00206   i1 = i2 = 0;
00207   for(;i1<line1->numhits && i2<line2->numhits;)
00208     if(hits1[i1]->wire == hits2[i2]->wire){
00209         if(hits1[i1]->used && hits2[i2]->used)
00210                 common++;
00211         i1++;
00212         i2++;
00213         total++;
00214     }
00215     else if(hits1[i1]->wire > hits2[i2]->wire){
00216         i2++;
00217         total++;
00218     }
00219     else if(hits1[i1]->wire < hits2[i2]->wire){
00220         i1++;
00221         total++;
00222     }
00223     total += line1->numhits-i1 + line2->numhits-i2;
00224 /*
00225   for( ;; ) {
00226     // A
00227     if( fw & 1 ) {//Set i1 equal to the index of the next hit used in line1 
00228       i1++;
00229       for( ; i1 < TLAYERS && hits1[i1]; i1++)
00230         if( hits1[i1]->used ) {
00231           total1++;
00232           break;
00233         }
00234     }
00235     // B
00236     if( fw & 2 ) {//Set i2 equal to the index of the next hit used in line2 
00237       i2++;
00238       for( ; i2 < TLAYERS && hits2[i2]; i2++)
00239         if( hits2[i2]->used ) {
00240           total2++;
00241           break;
00242         }
00243     }
00244     // ---
00245     if( i1 == TLAYERS || ! hits1[i1] ||
00246         i2 == TLAYERS || ! hits2[i2] )
00247       break;//break if we reach the end of the hits in either line 
00248     //-----------------------------------------------------------
00249     //The following lines separate hits in different detectors
00250     did1 = hits1[i1]->detec->ID;//this line was altered
00251     did2 = hits2[i2]->detec->ID;//this line was altered
00252     
00253     cout << "dids = (" << did1 << "," << did2 << ")" << endl;
00254     if( did1 < did2 )
00255       fw = 1;// do only A in the next iteration
00256     else if( did1 > did2 ) 
00257       fw = 2;// do only B in the next iteration
00258     else {
00259       if( hits1[i1]->wire == hits2[i2]->wire )
00260         common ++;
00261       fw = 3;// do both A and B next iteration
00262     }
00263     //-----------------------------------------------------------
00264   }
00265 */
00266 //Check which line has more hits used
00267 //  total = total1 > total2 ? total2 : total1;
00268 
00269   if( !total )
00270     return 0;
00271 //Get a ratio and mulitply it to return an integer
00272   return (10000 * common / total + 50 ) / 100;//if 8 common out of 8, then this = 100
00273 }
00274 //________________________________________________________________________
00275 /* This function simply counts the number of common wires
00276 shared between two treelines.  The only output is the integer
00277 return value
00278 */
00279 int treesort::rcCommonWires(TreeLine *line1,TreeLine *line2 ){
00280   cerr << "ERROR : This function needs editing before use" << endl;
00281 //################
00282 // DECLARATIONS  #
00283 //################
00284   int total1, total2, common, total;
00285   Hit **hits1, **hits2;
00286   int did1, did2;
00287   int  i1, i2, fw = 3;
00288 //##################
00289 //DEFINE VARIABLES #
00290 //##################
00291   common = total1 = total2 = 0;
00292   i1 = i2 = -1;
00293   hits1  = line1->hits;
00294   hits2  = line2->hits;
00295 //##################
00296 //DO STUFF #
00297 //##################
00298   for( ;; ) {
00299     if( fw & 1 ) {/*Set i1 equal to the index of the next hit used in line1 */
00300       i1++;
00301       for( ; i1 < DLAYERS*MAXHITPERLINE && hits1[i1]; i1++)
00302         if( hits1[i1]->used ) {
00303           total1++;
00304           break;
00305         }
00306     }
00307     if( fw & 2 ) {/*Set i2 equal to the index of the next hit used in line2 */
00308       i2++;
00309       for( ; i2 < DLAYERS*MAXHITPERLINE && hits2[i2]; i2++)
00310         if( hits2[i2]->used ) {
00311           total2++;
00312           break;
00313         }
00314     }
00315     if( i1 == DLAYERS*MAXHITPERLINE || ! hits1[i1] ||
00316         i2 == DLAYERS*MAXHITPERLINE || ! hits2[i2] )
00317       break;/*break if we reach the end of the hits in either line */
00318     //-----------------------------------------------------------
00319     //The following lines separate hits in different detectors
00320     did1 = hits1[i1]->detec->ID;//this line was altered
00321     did2 = hits2[i2]->detec->ID;//this line was altered
00322 
00323     if( did1 < did2 )
00324       fw = 1;
00325     else if( did1 > did2 ) 
00326       fw = 2;
00327     else {
00328       if( hits1[i1]->wire == hits2[i2]->wire )
00329         common ++;
00330       fw = 3;
00331     }
00332     //-----------------------------------------------------------
00333   }
00334 //##################
00335 //DO STUFF #
00336 //##################
00337   total = total1 > total2 ? total2 : total1;
00338 
00339   if( !total )
00340     return 0;
00341 
00342   return (10000 * common / total + 50 ) / 100;
00343 }
00344 //________________________________________________________________________
00345 int treesort::rcTreeConnSort( TreeLine *head, enum ERegion region/*,
00346                 enum EUppLow up_low, enum Etype type,
00347                 enum Edir dir,enum Eorientation orient*/){
00348 
00349 
00350 //################
00351 // DECLARATIONS  #
00352 //################
00353   char     *connarr;
00354   int * array;
00355   TreeLine **tlarr, *walk;
00356   int num, idx, i, j, bestconn,common;
00357   int iteration = 0;
00358   int num_tl = 0;
00359   extern int iEvent;
00360   int  *isvoid;
00361   double   *chia, chi, maxch = 2000.0, nmaxch, nminch;
00362 
00363   cerr << endl;
00364   //DBG = DEBUG & D_GRAPH;
00365 
00366 /* ----------------------------------------------------------------------
00367  * find the number of used treelines
00368  * ---------------------------------------------------------------------- */
00369   
00370   do {                          /* filter out high chi2 if needed */
00371     nmaxch = 0.0;
00372     iteration++;
00373     
00374     nminch = maxch;
00375     for( idx = 0, walk = head; walk; walk = walk->next ) {
00376       if( iteration > 100 ) {   /* skip the event */
00377         walk->isvoid = true;
00378         num_tl++;
00379       }
00380       else if( walk->isvoid == false ) {
00381         chi = chiweight(walk);
00382         if( chi > maxch ) {
00383           walk->isvoid = true;
00384         } else {
00385           if( chi > nmaxch ) {
00386             nmaxch = chi;
00387           }
00388           if( chi < nminch ) {
00389             nminch = chi;
00390           }
00391           idx++;
00392         }
00393       }
00394     }
00395     maxch = nminch + (nmaxch-nminch) * 0.66;
00396   } while( idx > 30 );//30?!? should probably reduce this
00397 
00398   num = idx;
00399 
00400   if( num_tl )
00401     fprintf(stderr,"hrc: Skipping event %d because of 0 good treelines\n",
00402             iEvent);
00403   
00404   if( ! num )
00405     return 0;
00406 
00407   //the following mallocs replaced Qmallocs
00408   connarr = (char *)malloc( num );
00409   isvoid  = (int *)malloc( num * sizeof(int));
00410   chia    = (double *)malloc( num * sizeof(double));
00411   array   = (int *)malloc( num*num*sizeof(int));
00412   tlarr   = (TreeLine **)malloc( sizeof(TreeLine*)*num);
00413 
00414   assert( array && tlarr);
00415 
00416 /* ----------------------------------------------------------------------
00417 * find the used treelines
00418 * ---------------------------------------------------------------------- */
00419 
00420   for( idx = 0, walk = head; walk; walk = walk->next ) {
00421     if( walk->isvoid == false ) {
00422       tlarr[idx]  = walk;
00423       isvoid[idx] = walk->isvoid;
00424       chia[idx]   = chiweight(walk);
00425       idx++;
00426     }
00427   }
00428   
00429 /* ----------------------------------------------------------------------
00430 * build the graph array
00431 * ---------------------------------------------------------------------- */
00432   if(region == r3){
00433     for( i = 0; i < num; i++ ) {
00434       array[i*num+i] = 0;
00435       for( j = i+1; j < num; j++ ) {
00436         common = rcCommonWires_r3( tlarr[i], tlarr[j] );
00437         array[i*num+j] = array[j*num+i] = 
00438           (common > 25);// this is true if
00439 // one of the two lines shares at least 1/4 of its wires with the other line
00440       }
00441     }
00442   }
00443   else{
00444     for( i = 0; i < num; i++ ) {
00445       array[i*num+i] = 0;
00446       for( j = i+1; j < num; j++ ) {
00447         array[i*num+j] = array[j*num+i] = 
00448           (rcCommonWires( tlarr[i], tlarr[j] ) > 25);// 25?!?
00449       }
00450     }
00451   }
00452 
00453 /* --------------------------------------------------------------------
00454 * check connectivity
00455 * -------------------------------------------------------------------- */
00456   for( i = 0; i < num; ) {
00457     if( isvoid[i] == false ) {
00458       bestconn =  connectiv( 0, array, isvoid, num, i);
00459       if( bestconn > 0 ) {
00460         if( connectarray(connarr, array, isvoid, num, i) ){
00461           continue;
00462           }     
00463         bestunconnected( connarr, array, isvoid, chia, num, i);
00464       } else{
00465         isvoid[i] = good;//good
00466       }
00467     } else
00468       i++;
00469   } 
00470   for( i = 0; i < num; i++ ) {
00471     if( isvoid[i] == true ) {
00472       if( connectiv( 0, array, isvoid, num, i ) ) {
00473         connectarray( connarr, array, isvoid, num, i);
00474         bestconnected( connarr , array, isvoid, chia, num, i);
00475       }
00476     }
00477   }
00478   for( i = 0; i < num; i++ ) {
00479     if( isvoid[i] != true ) {
00480       tlarr[i]->isvoid = false;
00481     } else
00482       tlarr[i]->isvoid = true;
00483   }
00484   /* do not free Qalloc'ed things!!! */
00485   return 0;
00486 }
00487 //________________________________________________________________________
00488 int treesort::rcPartConnSort( PartTrack *head/*,
00489                 enum EUppLow up_low, enum ERegion region, enum Etype type,
00490                 enum Edir dir,enum Eorientation orient*/){
00491         char     *connarr;
00492         int *array;
00493         PartTrack **ptarr, *walk;
00494         int num, idx, i, j, bestconn;
00495         int  *isvoid;
00496         double   *chia, chi, maxch = 200.0, nmaxch, nminch;
00497         /* ----------------------------------------------------------------------
00498         * find the number of used PartTracks
00499         * ---------------------------------------------------------------------- */
00500         
00501         //DBG = DEBUG & D_GRAPHP;
00502 
00503         do {                            /* filter out high chi2 if needed */
00504                 nmaxch = 0.0;
00505                 nminch = maxch;
00506                 for( idx = 0, walk = head; walk; walk = walk->next ) {
00507                         if( walk->isvoid == false ) {
00508                                 chi = ptchiweight(walk);
00509                                 if( chi > maxch ) {
00510                                         walk->isvoid = true;
00511                                 } else {
00512                                         if( chi > nmaxch ) {
00513                                                 nmaxch = chi;
00514                                         }
00515                                         if( chi < nminch ) {
00516                                                 nminch = chi;
00517                                         }
00518                                         idx++;
00519                                 }
00520                         }
00521                 }
00522                 maxch = nminch + (nmaxch-nminch) * 0.66;
00523         } while( idx > 30 );
00524 
00525 
00526         num = idx;
00527   
00528         if( ! num )
00529                 return 0;
00530 
00531         //the following mallocs replaced Qmallocs
00532         connarr = (char *)malloc( num );
00533         isvoid  = (int *)malloc( num * sizeof(int));
00534         chia    = (double *)malloc( num * sizeof(double));
00535         array   = (int *)malloc( num*num);
00536         ptarr   = (PartTrack **)malloc( sizeof(PartTrack*)*num);
00537 
00538         if( !ptarr || ! array ) {
00539                 fprintf(stderr,"Cannot Allocate Sort Array for %d PartialTracks\n",num);
00540                 abort();
00541         }
00542         /*
00543         if( DE && (DEBUG & D_GRAPHP)) {
00544                 printf("----------SORT PT %c %c\n",
00545                 "FB"[vispar],"UL"[viswer]);
00546         }
00547 
00548         */
00549         /* ----------------------------------------------------------------------
00550         * find the used parttracks
00551         * ---------------------------------------------------------------------- */
00552 
00553         for( idx = 0, walk = head; walk; walk = walk->next ) {
00554                 if( walk->isvoid == false ) {
00555                         ptarr[idx]  = walk;
00556                         isvoid[idx] = walk->isvoid;
00557                         chia[idx]   = ptchiweight(walk);
00558                         idx++;
00559                 }
00560         }
00561 
00562         /* ----------------------------------------------------------------------
00563         * build the graph array
00564         * ---------------------------------------------------------------------- */
00565   
00566         for( i = 0; i < num; i++ ) {
00567                 array[i*num+i] = 0;
00568 
00569                 for( j = i+1; j < num; j++ ) {
00570                         array[i*num+j] = array[j*num+i] = 
00571                         (rcPTCommonWires( ptarr[i], ptarr[j] ) > 25);
00572                 }
00573         }
00574 /*
00575         if( DE && (DEBUG & D_GRAPHP)) {
00576                 for( i = 0; i < num; i++ ) {
00577                         if( isvoid[i] != true )
00578                                 printf("pthave (%d) %f,%f %f,%f - %f %d (%d)\n", i,
00579                                 ptarr[i]->x,
00580                                 ptarr[i]->y,
00581                                 ptarr[i]->mx,
00582                                 ptarr[i]->my,
00583                                 ptchiweight(ptarr[i]),
00584                                 ptarr[i]->nummiss,
00585                                 connectiv( 0, array, isvoid, num, i));
00586                 }
00587         }
00588 */ 
00589         /* --------------------------------------------------------------------
00590         * check connectivity
00591         * -------------------------------------------------------------------- */
00592   
00593         for( i = 0; i < num; ) {
00594                 if( isvoid[i] == false ) {
00595                         bestconn =  connectiv( 0, array, isvoid, num, i);
00596                         if( bestconn > 0 ) {
00597                                 if( connectarray(connarr, array, isvoid, num, i) )
00598                                         continue;
00599                                 /*
00600                                 if( DE && (DEBUG & D_GRAPHP)) {
00601                                         printf(" %d-connections:", i);
00602                                         for( j = 0; j < num; j++ ) {
00603                                                 if( connarr[j])
00604                                                         printf("%d ",j);
00605                                         }
00606                                         puts("");
00607                                 }
00608                                 */
00609                                 bestunconnected( connarr, array, isvoid, chia, num, i);
00610                                 /*
00611                                 if( DE && (DEBUG & D_GRAPHP)) 
00612                                         puts("");
00613                                 */
00614                         } else
00615                                 isvoid[i] = good;//good
00616                 } else
00617                         i++;
00618         }
00619 /*
00620   if( DE && (DEBUG & D_GRAPHP)) {
00621     for( i = 0; i < num; i++ ) {
00622       if( isvoid[i] != true )
00623         printf("ptkeep (%d) %f,%f %f,%f - %f %d (%d)\n", i,
00624                ptarr[i]->x,
00625                ptarr[i]->y,
00626                ptarr[i]->mx,
00627                ptarr[i]->my,
00628                ptchiweight(ptarr[i]),
00629                ptarr[i]->nummiss,
00630                connectiv( 0, array, isvoid, num, i));
00631     }
00632   }
00633 */
00634         for( i = 0; i < num; i++ ) {
00635                 if( isvoid[i] != true ) {
00636                          //Statist[method].PartTracksUsed[where][part] ++;
00637                          ptarr[i]->isvoid = false;
00638                 } else
00639                         ptarr[i]->isvoid = true;
00640         }
00641   
00642         /* do not free Qalloc'ed things!!! */
00643         return 0;
00644 
00645 }

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