Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

mMuiFastRoadFinder.cxx

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <math.h>
00003 
00004 #include "PHNode.h"
00005 #include "PHCompositeNode.h"
00006 #include "PHDataNode.h"
00007 #include "PHIODataNode.h"
00008 #include "PHNodeIterator.h"
00009 
00010 #include "mMuiFastRoadFinder.h"
00011 #include "MuiGeomClasses.hh"
00012 
00013 #include <fstream>
00014 
00015 //MUIOO interfaces
00016 #include <TMutNode.h>
00017 
00018 // some LVL2 stuff; from lvl2_distribution/primitives
00019 #include "Lvl2_MUIOO_MuiTriggerVars.hh"
00020 
00021 static bool falseSignal = false;
00022 static bool init_done = false;
00023 
00024 const short NVIRT_PANELS = 8;
00025 
00026 // Default constructor and destructor to pacify CINT
00027 mMuiFastRoadFinder::mMuiFastRoadFinder() :
00028   _roadmap(0),
00029   _hitmap(0),
00030   _timer( PHTimeServer::get()->insert_new( "mMuiFastRoadFinder" ) )
00031 {
00032   name = "mMuiFastRoadFinder";
00033 }
00034 
00035 PHBoolean 
00036 mMuiFastRoadFinder::init()
00037 {
00038   // Initialize signal array to zero.
00039   // ================================
00040   for (short logical = 0; logical < TMuiChannelId::kTwoPacksPerPlaneMax; logical++) {
00041     for (short gap = 0; gap < MUIOO::MAX_ARM; gap++) {
00042       _signal[logical][gap] = false;
00043     }
00044   }
00045   
00046   // Location pointed to by all symset members that don't have an 
00047   // actual tube to point to.
00048   // ============================================================
00049   for (short symset = 0; symset <  TMuiChannelId::kTwoPacksPerPlaneMax; 
00050        symset++) {
00051     for (short i = 0; i < mMuiFastRoadFinderPar::MAX_SYMSET; i++) {
00052       _trigger_signal[symset][i] = &falseSignal;
00053       short logical = symset + _mod_par->get_symset_logical_offset(i);
00054       if (logical >= 0 && 
00055           logical <  TMuiChannelId::kTwoPacksPerPlaneMax) {
00056         short gap = _mod_par->get_symset_plane(i);
00057         _trigger_signal[symset][i] = &(_signal[logical][gap]);
00058       }         
00059     }
00060   }
00061   // read the mapping files 
00062   // hardcode in default filenames for now
00063   read_idx_XoZ_map("/phenix/workarea/silvermy/offline/packages/mui/wrk/lvl2cosines.adb");
00064   read_twopack_idx_map("/phenix/workarea/silvermy/offline/packages/mui/wrk/muioomap.adb");
00065   return 0;
00066 }
00067 
00068 mMuiFastRoadFinder::~mMuiFastRoadFinder(){}
00069 
00070 PHBoolean
00071 mMuiFastRoadFinder::event(PHCompositeNode *top_node) 
00072 {
00073   _timer.get()->restart();
00074   try {
00075     // Reset IOC pointers
00076     //
00077     set_interface_ptrs(top_node);
00078 
00079     if (!init_done)
00080       {
00081         init();
00082         init_done = true;
00083       }
00084     // Try to reconstruct some tracks
00085     //
00086     find_tracks();
00087 
00088   } catch(std::exception& e) {
00089     MUIOO::TRACE(e.what());
00090     return False;
00091   }
00092   _timer.get()->stop();
00093   return 0;
00094 }
00095 
00096 void 
00097 mMuiFastRoadFinder::set_interface_ptrs(PHCompositeNode* top_node)
00098 {
00099   // module runtime parameters
00100   _mod_par = TMutNode<mMuiFastRoadFinderPar>::find_node(top_node,"mMuiFastRoadFinderPar");
00101   // dump parameter listing
00102   //_mod_par->print();
00103 
00104   //Find the TMuiRoadO IOC
00105   _roadmap = TMutNode<TMuiRoadMapO>::find_node(top_node,"TMuiRoadMapO");
00106    
00107   //Find the TMuiHitO IOC
00108   _hitmap = TMutNode<TMuiHitMapO>::find_node(top_node,"TMuiHitMapO");
00109     
00110  return;  
00111 }
00112 
00113 void 
00114 mMuiFastRoadFinder::read_idx_XoZ_map(const char* filename)
00115 {
00116  // Read in Mui cosine/slope info from a file
00117   ifstream fin(filename);
00118   if (!fin)
00119     {
00120       cerr << PHWHERE << " - can't open " << filename
00121            << "for input" << endl;
00122       return;
00123     }  
00124   int nlines = 0;
00125 
00126   int idx = 0;
00127   int arm = 0;
00128   int orient = 0;
00129   float XoZ = 0.0;
00130 
00131   // read from the file as long as we can
00132   while ( fin.good() )
00133     {
00134       fin >> idx >> arm >> orient >> XoZ;
00135 
00136       if (! fin.good() ) 
00137         {
00138           break;
00139         }
00140         _idx_XoZ[arm][orient][idx] = XoZ;
00141         nlines++;
00142     }
00143   cout << PHWHERE << " XoZ nlines " << nlines << " read " << endl;
00144   return;
00145 }
00146 
00147 
00148 void 
00149 mMuiFastRoadFinder::read_twopack_idx_map(const char* filename)
00150 {
00151  // Read in Mui twopack->logical mapping from a file
00152   ifstream fin(filename);
00153   if (!fin)
00154     {
00155       cerr << PHWHERE << " - can't open " << filename
00156            << "for input" << endl;
00157       return;
00158     }  
00159   int nlines = 0;
00160 
00161   int arm = 0;
00162   int plane = 0;
00163   int panel = 0;
00164   int orient = 0;
00165   int twopack = 0;
00166   int idx = 0;
00167 
00168 
00169   // read from the file as long as we can
00170   while ( fin.good() )
00171     {
00172       fin >> arm >> plane >> panel >> orient >> twopack >> idx;
00173 
00174       if (! fin.good() ) 
00175         {
00176           break;
00177         }
00178         _twopack_idx[arm][plane][panel][orient][twopack] = idx;
00179         nlines++;
00180     }
00181   cout << PHWHERE << " twopack-idx nlines " << nlines << " read " << endl;
00182   return;
00183 }
00184 
00185 void
00186 mMuiFastRoadFinder::find_tracks() 
00187 {
00188   for (UShort_t arm = 0; arm < MUIOO::MAX_ARM; arm++)
00189     {
00190       for (UShort_t orient = 0; orient < MUIOO::MAX_ORIENTATION; orient++)
00191         {
00192           // diff in symset calc between original and simplified is hidden in 
00193           // a call in calc_symset method.
00194           _symsets[arm][orient].clear();
00195 
00196           if( _mod_par->get_mode() == mMuiFastRoadFinderPar::SIMPLIFIED ) {
00197             hit_to_logical(arm, orient); // fill signal variables
00198             calc_symset(arm, orient);
00199           }
00200           else if ( _mod_par->get_mode() == mMuiFastRoadFinderPar::ORIGINAL ) {
00201             // loop over virtual panels
00202             for (UShort_t ip = 0; ip<NVIRT_PANELS; ip++) {
00203               hit_to_logical_per_panel(arm, orient, ip); // fill signal variables
00204               calc_symset(arm, orient);
00205             }
00206           }
00207           else { // unknown mode - shouldn't be possible
00208             MUIOO::TRACE("mMuiFastRoadFinder::find_tracks - unknown alg. mode selected");
00209           }
00210         }
00211 
00212       //Make 2D tracks of all 1D combinations/symsets for this arm
00213       unsigned int hid = 0;
00214       unsigned int vid = 0;
00215       int depth = 0;
00216       mui_symset hsymset, vsymset;
00217 
00218       for(hid=0; hid<_symsets[arm][kHORIZ].size(); hid++) 
00219         {
00220           for(vid=0; vid<_symsets[arm][kVERT].size(); vid++) 
00221             {
00222               hsymset = _symsets[arm][kHORIZ][hid];
00223               vsymset = _symsets[arm][kVERT][vid];
00224               //Only construct if depth difference between orientations <= depthmatch
00225               if( abs(hsymset.depth - vsymset.depth) <= _mod_par->get_depth_match() )
00226                 {
00227                   //The depth of the combination is the larger of the 1D depths
00228                   if (hsymset.depth > vsymset.depth)
00229                     {
00230                       depth = hsymset.depth;
00231                     }
00232                   else
00233                     {
00234                       depth = vsymset.depth;
00235                     }
00236 
00237                   // Note: maxmisshits cut and maxmisstotal cut based on gapbits are
00238                   // not included.
00239 
00240                   //Calculate direction of 2D Road. These are slopes not cosines
00241                   float cx1 = vsymset.cos;
00242                   float cy1 = hsymset.cos;
00243                   float invmag = 1.0/sqrt( cx1*cx1 + cy1*cy1 + 1 );
00244 
00245                   float dx = cx1*invmag; 
00246                   float dy = cy1*invmag; 
00247                   float dz = invmag;     
00248 
00249                   float slope = sqrt((dx*dx+dy*dy)/(dz*dz));
00250                   //float pmin = _mod_par->get_min_momentum(arm, depth)/invmag;
00251 
00252                   //Add the track to the list, if it passes cuts
00253                   if( depth >= _mod_par->get_min_depth() &&
00254                       slope >= _mod_par->get_min_slope() )
00255                     {
00256                       TMutFitPar fit2d;
00257                       TMuiRoadMapO::iterator iRoad = _roadmap->insert_new(arm);
00258                       TMuiRoadMapO::pointer cRoad = iRoad.current();
00259 
00260                       // Things to be set for real road:
00261                       // associated clusters are not really kept for now
00262                       
00263                       // nhit, depth, freedom, chi_square, gapbit 
00264                       cRoad->get()->set_nhit(hsymset.nhit + vsymset.nhit);
00265                                           
00266                       cRoad->get()->set_depth(depth);
00267 
00268                       cRoad->get()->set_freedom(hsymset.dof + vsymset.dof);
00269 
00270                       cRoad->get()->set_gapbit(hsymset.gapbit | 
00271                                                (vsymset.gapbit << MUIOO::MAX_PLANE));
00272                                           
00273                       //Combine the FitPar of the 1D roads                    
00274                       fit2d.set_x(vsymset.x);
00275                       fit2d.set_y(hsymset.y);
00276                       fit2d.set_z(hsymset.z);
00277                       fit2d.set_dxdz(cx1);
00278                       fit2d.set_dydz(cy1);
00279                       fit2d.set_z_end(hsymset.z);
00280                       fit2d.set_z_begin(hsymset.z);
00281                       Float_t chisq = (hsymset.chisq * hsymset.dof +
00282                                        vsymset.chisq * vsymset.dof)/
00283                         (hsymset.dof + vsymset.dof); 
00284                       fit2d.set_chi_square(chisq);
00285 
00286                       cRoad->get()->set_fit_par(fit2d);
00287                       // previously not set parameters
00288                       cRoad->get()->set_road_quality(chisq);
00289                       UShort_t gapmatch = hsymset.gapbit & 
00290                         vsymset.gapbit;
00291                       if (gapmatch != 0) {
00292                         cRoad->get()->set_max_hit_plane(2);
00293                       }
00294                       else {
00295                         cRoad->get()->set_max_hit_plane(1);
00296                       }
00297                     }
00298                 } // depth_match
00299             } // vid
00300         } // hid
00301     } // arm
00302 
00303   return;
00304 }
00305 
00306 void 
00307 mMuiFastRoadFinder::hit_to_logical(UShort_t arm, UShort_t orient)
00308 { // first clear the signal array
00309   memset(_signal,false,sizeof(_signal));
00310   
00311   UShort_t idx;
00312   
00313   TMuiHitMapO::iterator hit_iter = _hitmap->get(arm);
00314   while(TMuiHitMapO::pointer hit_ptr = hit_iter.next()) {
00315     if (hit_ptr->get()->get_orientation() == orient) {
00316       // right orientation selected
00317       
00318       // here we should get the 'logical tube'/twopack value
00319       // Check this again !!!
00320       idx = _twopack_idx[arm][hit_ptr->get()->get_plane()][hit_ptr->get()->get_panel()][orient][hit_ptr->get()->get_twopack()]; 
00321 
00322       _signal[idx][hit_ptr->get()->get_plane()] = true;
00323     }
00324   }
00325 }
00326 
00327 void 
00328 mMuiFastRoadFinder::calc_symset(UShort_t arm, UShort_t orient)
00329 {
00330   // Symset variables.
00331   // =================
00332   bool gap0bit[TMuiChannelId::kTwoPacksPerPlaneMax];
00333   bool gap1bit[TMuiChannelId::kTwoPacksPerPlaneMax];
00334   bool gap2bit[TMuiChannelId::kTwoPacksPerPlaneMax];
00335   bool gap3bit[TMuiChannelId::kTwoPacksPerPlaneMax];
00336   bool gap4bit[TMuiChannelId::kTwoPacksPerPlaneMax];
00337   
00338   // Loop over symsets; see if they contain a trigger road.
00339   // =====================================================
00340   for (short symset = 0; symset < TMuiChannelId::kTwoPacksPerPlaneMax; symset++) 
00341     {
00342       // Call the roadfinder, return bits that define tracking
00343       // status to each gap for each symset.
00344       // =====================================================
00345       gap0bit[symset]=false;
00346       gap1bit[symset]=false;
00347       gap2bit[symset]=false;
00348       gap3bit[symset]=false;
00349       gap4bit[symset]=false;
00350       
00351       //Only execute the road finder if there is a hit
00352       // in the (Note: middle of!) first two gaps
00353       if((*(_trigger_signal[symset][2]))
00354          ||(*(_trigger_signal[symset][10]))){
00355         bool** p = _trigger_signal[symset];
00356         gap0bit[symset]= *(_trigger_signal[symset][2]);
00357 
00358         if( _mod_par->get_mode() == mMuiFastRoadFinderPar::SIMPLIFIED ) {
00359           simple_trigger_road_finder(p, 
00360                                      gap1bit[symset], gap2bit[symset], 
00361                                      gap3bit[symset], gap4bit[symset]);
00362         }
00363         else if ( _mod_par->get_mode() == mMuiFastRoadFinderPar::ORIGINAL ) {
00364           orig_trigger_road_finder(p,
00365                                    gap1bit[symset], gap2bit[symset], 
00366                                    gap3bit[symset], gap4bit[symset]);
00367         }
00368         else { // unknown mode - shouldn't be possible
00369           MUIOO::TRACE("mMuiFastRoadFinder::calc_symset - unknown alg. mode selected");
00370         }
00371       } // one of 1st two gaps hit.
00372     } // symset 
00373 
00374   float idxXoZ[TMuiChannelId::kTwoPacksPerPlaneMax];
00375   for (short symset = 0; symset < TMuiChannelId::kTwoPacksPerPlaneMax; symset++) 
00376     {
00377       idxXoZ[symset] = _idx_XoZ[arm][orient][symset];
00378     }
00379 
00380   // Now let's summarize the results of the symset calculations
00381   // This includes rejecting adjacent, duplicate tracks
00382   mui_trigger_edge_finder(TMuiChannelId::kTwoPacksPerPlaneMax, idxXoZ,
00383                           gap0bit, gap1bit, gap2bit, gap3bit, gap4bit, 
00384                           arm, orient);
00385 }
00386 
00387 // Per-Panel stuff/Orig. alg.
00388 void 
00389 mMuiFastRoadFinder::hit_to_logical_per_panel(UShort_t arm, UShort_t orient,
00390                                              UShort_t virt_panel)
00391 { // first clear the signal array
00392   memset(_signal,false,sizeof(_signal));
00393   
00394   UShort_t idx;
00395   //We will populate hits per virtual panel which means. Panels:
00396   // 0 => Panel 0
00397   // 1 => Panel 0,1
00398   // 2 => Panel 1,2
00399   // 3 => Panel 2
00400   // 4 => Panel 3
00401   // 5 => Panel 3,4
00402   // 6 => Panel 4,5
00403   // 7 => Panel 5
00404   // In addition, we only want vertical tracks in panels 2,4 that have 
00405   //  slopes of appopriate sign.
00406   const short panel1[NVIRT_PANELS] = { 0, 1, 1, 2, 3, 4, 4, 5 };
00407   const short panel2[NVIRT_PANELS] = { 0, 0, 2, 2, 3, 3, 5, 5 };
00408   const float quadsign[NVIRT_PANELS] = { 1.0, 1.0, -1.0, -1.0, 
00409                                          -1.0, -1.0, 1.0, 1.0 };
00410 
00411   TMuiHitMapO::iterator hit_iter = _hitmap->get(arm);
00412   while(TMuiHitMapO::pointer hit_ptr = hit_iter.next()) {
00413     if (hit_ptr->get()->get_orientation() == orient) {
00414       // right orientation selected
00415       
00416       UShort_t hit_panel = hit_ptr->get()->get_panel();
00417       idx = _twopack_idx[arm][hit_ptr->get()->get_plane()][hit_ptr->get()->get_panel()][orient][hit_ptr->get()->get_twopack()]; 
00418       
00419       float hitslope = _idx_XoZ[arm][orient][idx];
00420       
00421       if( (hit_panel==panel1[virt_panel] || hit_panel==panel2[virt_panel]) 
00422           //Hit in virtual panel
00423          && ( (hit_ptr->get()->get_plane()>1) 
00424               // Accept all hits deeper than gap 1
00425               || (orient==1 && hitslope*quadsign[virt_panel]>0.0 &&
00426                   hit_panel==panel1[virt_panel])
00427               // Accept only Vertical with correct slope
00428               || (orient==0 && hit_panel==panel1[virt_panel])
00429               ) ) {
00430         //cout<<"Accepted\n";
00431         _signal[idx][hit_ptr->get()->get_plane()] = true;
00432       }
00433     }
00434   }
00435 }
00436 
00437 void 
00438 mMuiFastRoadFinder::mui_trigger_edge_finder(int nsymsets, 
00439                     const float idx_XoZ[TMuiChannelId::kTwoPacksPerPlaneMax],
00440                                             bool *gap0bit,
00441                                             bool *gap1bit, bool *gap2bit, 
00442                                             bool *gap3bit, bool *gap4bit,
00443                                             UShort_t arm, UShort_t orient)
00444 {
00445   // Zeroth elements have no previous bit to
00446   // negate them.
00447   // =======================================
00448   bool prev4 = gap4bit[0];
00449   bool prev3 = gap3bit[0];
00450   bool prev2 = gap2bit[0];
00451   bool prev1 = gap1bit[0];
00452   int i = 0;
00453   
00454   for (i = 1; i < nsymsets; i++) {
00455     bool curr4 = gap4bit[i];
00456     bool curr3 = gap3bit[i];
00457     bool curr2 = gap2bit[i];
00458     bool curr1 = gap1bit[i];
00459     gap4bit[i] = gap4bit[i] && !prev4;
00460     gap3bit[i] = gap3bit[i] && !prev3;
00461     gap2bit[i] = gap2bit[i] && !prev2;
00462     gap1bit[i] = gap1bit[i] && !prev1;
00463     prev4 = curr4;
00464     prev3 = curr3;
00465     prev2 = curr2;
00466     prev1 = curr1;
00467   }
00468   
00469   int nhit = 0;
00470   int gapbit = 0;
00471 
00472   // dummy values for now, for the degree of freedom and chisq
00473   int dof = 1;
00474   float chisq = 1.0; 
00475   // and for the coordinates
00476   float x = 0.0, y= 0.0, z= 0.0;
00477 
00478   for (i = 0; i < nsymsets; i++) {
00479     gapbit = 0;
00480     nhit = 0;
00481     if (gap0bit[i]) { gapbit |= 1; nhit++; }
00482     if (gap1bit[i]) { gapbit |= 2; nhit++; }
00483     if (gap2bit[i]) { gapbit |= 4; nhit++; }
00484     if (gap3bit[i]) { gapbit |= 8; nhit++; }
00485     if (gap4bit[i]) { gapbit |= 0x10; nhit++; }
00486 
00487     gap3bit[i] = gap3bit[i] || gap4bit[i];
00488     gap2bit[i] = gap2bit[i] || gap3bit[i];
00489     gap1bit[i] = gap1bit[i] || gap2bit[i];
00490     if(gap1bit[i])
00491       {
00492         mui_symset tmpSymset;
00493         tmpSymset.idx=i;
00494         tmpSymset.cos = idx_XoZ[i];
00495         tmpSymset.depth = 1;
00496         if(gap2bit[i])
00497           {
00498             tmpSymset.depth = 2;
00499           }
00500         if(gap3bit[i])
00501           {
00502             tmpSymset.depth = 3;
00503           }
00504         if(gap4bit[i])
00505           {
00506             tmpSymset.depth = 4;
00507           }
00508         // set all other values too
00509         tmpSymset.nhit= nhit;  
00510         tmpSymset.gapbit = gapbit;
00511         // even the dummies
00512         tmpSymset.dof = dof;   
00513         tmpSymset.chisq = chisq; 
00514         tmpSymset.x = x;     
00515         tmpSymset.y = y;     
00516         tmpSymset.z = z;     
00517 
00518         _symsets[arm][orient].push_back(tmpSymset);                
00519       }
00520   }
00521 }
00522 
00523 void 
00524 mMuiFastRoadFinder::simple_trigger_road_finder(bool **p,
00525                                                bool& gap1bit, bool& gap2bit, 
00526                                                bool& gap3bit, bool& gap4bit)
00527 {
00528   static const short search_width = 3;
00529 
00530   // these are counters for the indices in the gaps
00531   short i0 = 0, i1 = 0, i2 = 0, i3 = 0, i4 = 0;
00532   // gap 0:      0- 4; m = 2, 5 numbers
00533   // gap 1: 5  + 0-10; m = 10-5 = 5, 11 numbers
00534   // gap 2: 16 + 0-16; m = 24-16 = 8, 17 numbers
00535   // gap 3: 33 + 0-22; m = 44-33 = 11, 23 numbers
00536   // gap 4: 56 + 0-28; m = 70-56 = 14, 29 numbers
00537   // this info is stored in the mMuiFastRoadFinderPar.h file
00538   
00539   // negate the gapbits to start with
00540   gap1bit = false;
00541   gap2bit = false;
00542   gap3bit = false;
00543   gap4bit = false;
00544   short ngapsbest = 0;
00545   bool locgap0bit = false;
00546   bool locgap1bit = false;
00547   bool locgap2bit = false;
00548   bool locgap3bit = false;
00549   bool locgap4bit = false;
00550   bool candidateFound = false;
00551   
00552   //---------------------------------------------------------------------
00553   // The (software) algorithm works as follows:
00554   // loop over gap0 indices and see if we have something there or in gap1
00555   // for that index.
00556   // If so, we'll continue by looking at gaps 3 and 4.
00557   // we'll look X=3 wide in those last two gaps, i.e. -1,0,+1 + gap0-index
00558   // - i.e. use _mod_par->get_search_width() = 3; as default, to limit this
00559   // If we find something there also, we'll do the full OR between
00560   // -1,0,+1 + gap0-index in gaps 1 and 2 also. If the sum of these OR's
00561   // is larger or equal to 3, this is a validCandidate
00562   // - use const _mod_par->get_min_valid_hits() = 3;
00563   // we will then exit the search (gapbits should be filled properly)
00564   //
00565   // if we didn't find a valid candidate: set all gapbits to false
00566   //
00567   // New (Oct 31, 2003) implemented shallow check if no deep was found
00568   //---------------------------------------------------------------------
00569   
00570   i0 = 0; // start from the beginning
00571   short distFromMiddle; // help variable
00572   // start one below middle, by default
00573   short low_offset = 1;
00574   // go to one above middle
00575   // short high_offset = 1;
00576   // and search all
00577   short nsearch = search_width;
00578   int i;
00579 
00580   while ( i0<=_mod_par->get_symset_upper(0) )
00581     {
00582       distFromMiddle = i0 - _mod_par->get_symset_middle(0); // [-2,2]; 0 in the middle
00583       i1 = _mod_par->get_symset_middle(1) + distFromMiddle; // same index in gap1
00584 
00585       if ( *(p[i0]) || *(p[i1]) )
00586         { // ok, we have something in either gap 0 or 1
00587           // let's now get the OR's for gap 3 and 4.
00588 
00589           // Now, go through all the gaps..
00590 
00591           // gap 0
00592           locgap0bit = *(p[i0]);
00593 
00594           // gap 1
00595           i1 = _mod_par->get_symset_middle(1) + distFromMiddle - low_offset; 
00596           locgap1bit = false; 
00597           for (i = 0; i<nsearch; i++)
00598             {
00599               locgap1bit = locgap1bit || *(p[i1+i]);
00600             }
00601 
00602           // gap 2
00603           i2 = _mod_par->get_symset_middle(2) + distFromMiddle - low_offset; 
00604           locgap2bit = false; 
00605           for (i = 0; i<nsearch; i++)
00606             {
00607               locgap2bit = locgap2bit || *(p[i2+i]);
00608             }
00609 
00610           // gap 3
00611           i3 = _mod_par->get_symset_middle(3) + distFromMiddle - low_offset; 
00612           locgap3bit = false; 
00613           for (i = 0; i<nsearch; i++)
00614             {
00615               locgap3bit = locgap3bit || *(p[i3+i]);
00616             }
00617 
00618           // gap 4
00619           i4 = _mod_par->get_symset_middle(4) + distFromMiddle - low_offset; 
00620           locgap4bit = false;
00621           for (i = 0; i<nsearch; i++)
00622             {
00623               locgap4bit = locgap4bit || *(p[i4+i]);
00624             }
00625 
00626           // Requirement for sheep/deep:
00627           // if we have something either gap 3 or gap 4, we'll do the full OR
00628           // for gaps 1 and 2 also
00629           if (locgap3bit || locgap4bit)
00630             {
00631               short ngapsum = 0;
00632               if (locgap0bit) ngapsum++; 
00633               if (locgap1bit) ngapsum++;
00634               if (locgap2bit) ngapsum++;
00635               if (locgap3bit) ngapsum++;
00636               if (locgap4bit) ngapsum++;
00637 
00638               if (ngapsum >=_mod_par->get_min_valid_hits())
00639                 {
00640                   candidateFound = true;
00641                   if (ngapsum > ngapsbest)
00642                     {
00643                       gap1bit = locgap1bit;
00644                       gap2bit = locgap2bit;
00645                       gap3bit = locgap3bit;
00646                       gap4bit = locgap4bit;
00647                     } // best so far
00648                 } // ok
00649             } // fulfilled deep requirement
00650           else 
00651             { // could still perhaps be accepted as shallow
00652               // nothing in gap3 or 4, but we could perhaps still have enough
00653               // in gap0,1,2
00654               short ngapsum = 0;
00655               if (locgap0bit) ngapsum++; 
00656               if (locgap1bit) ngapsum++;
00657               if (locgap2bit) ngapsum++;
00658               if (ngapsum >=_mod_par->get_min_valid_hits())
00659                 {
00660                   candidateFound = true;
00661                   if (ngapsum > ngapsbest)
00662                     {
00663                       gap1bit = locgap1bit;
00664                       gap2bit = locgap2bit;
00665                       gap3bit = locgap3bit;
00666                       gap4bit = locgap4bit;
00667                     } // best so far
00668                 } // ok
00669             } // shallow test
00670         } // something in gap 0 or 1
00671       i0++;
00672     }
00673 
00674   // if we didn't find any candidate, we'll make sure that the
00675   // gapbits are all negated
00676   if (!candidateFound)
00677     {
00678       gap1bit = false;
00679       gap2bit = false;
00680       gap3bit = false;
00681       gap4bit = false;
00682     }
00683 
00684   // Return 4-bit value, the i^th bit indicates that a candidate made it
00685   // to the i^th gap
00686   // What we need to do is thus just go thru the lower gaps and see if
00687   // higher gaps were already set
00688   //
00689   // Outcommented this overwriting for now: DS, July 31, 2003 
00690   //
00691   /*
00692   gap3bit = gap3bit || gap4bit;
00693   gap2bit = gap2bit || gap3bit;
00694   gap1bit = gap1bit || gap2bit;
00695   */
00696 
00697   return;
00698 }
00699 
00700 
00701 void 
00702 mMuiFastRoadFinder::orig_trigger_road_finder(bool **p,
00703                                              bool& gap1bit, bool& gap2bit, 
00704                                              bool& gap3bit, bool& gap4bit)
00705 {
00706   short showermax[5][5]; // 1st index is maxdepth, 2nd is gap.
00707   bool roadfound[5][5];  // 1st index is maxdepth, 2nd is gap.
00708   // Search gap 0 for a shower (same code no matter the max depth).
00709   // ==============================================================
00710   gap0(p, &showermax[0][0]);
00711   roadfound[1][0] = *(p[m0]);
00712   roadfound[2][0] = *(p[m0]);
00713   roadfound[3][0] = *(p[m0]);
00714   roadfound[4][0] = *(p[m0]);
00715   // Search gap 1 for road, shower with maxdepth=1 cuts.
00716   // ===================================================
00717   gap1(p, _mod_par->get_swi(1,1), &showermax[1][1], &roadfound[1][1]);
00718           
00719   // Search gaps 1,2 for road, shower with maxdepth=2 cuts.
00720   // Gap 1 called again because of possible cut differences.
00721   // =======================================================
00722   gap1(p, _mod_par->get_swi(2,1), &showermax[2][1], &roadfound[2][1]);
00723   gap2(p, _mod_par->get_swi(2,2), &showermax[2][2], &roadfound[2][2]);
00724   
00725   // Search gaps 1,2,3 for road, shower with maxdepth=3 cuts.
00726   // Gap2 1,2 called again because of possible cut differences.
00727   // ==========================================================
00728   gap1(p, _mod_par->get_swi(3,1), &showermax[3][1], &roadfound[3][1]);
00729   gap2(p, _mod_par->get_swi(3,2), &showermax[3][2], &roadfound[3][2]);
00730   gap3(p, _mod_par->get_swi(3,3), &showermax[3][3], &roadfound[3][3]);
00731   
00732   // Search gaps 1-4 for road, shower with maxdepth=4 cuts.
00733   // Gaps 1-3 called again because of possible cut differences.
00734   // ==========================================================
00735   gap1(p, _mod_par->get_swi(4,1), &showermax[4][1], &roadfound[4][1]);
00736   gap2(p, _mod_par->get_swi(4,2), &showermax[4][2], &roadfound[4][2]);
00737   gap3(p, _mod_par->get_swi(4,3), &showermax[4][3], &roadfound[4][3]);
00738   gap4(p, _mod_par->get_swi(4,4), &showermax[4][4], &roadfound[4][4]);
00739 
00740   // We need to count the skipped gaps that were needed to generate 
00741   // each track candidate.
00742   // ==============================================================
00743   int nskip[5][5];      // 1st index is maxdepth, 2nd is gap.
00744 
00745   nskip[4][4] = 5 - bsum(&roadfound[4][0], 5);
00746 
00747   nskip[3][3] = 4 - bsum(&roadfound[3][0], 4);
00748   nskip[4][3] = 4 - bsum(&roadfound[4][0], 4);
00749 
00750   nskip[2][2] = 3 - bsum(&roadfound[2][0], 3);
00751   nskip[3][2] = 3 - bsum(&roadfound[3][0], 3);
00752   nskip[4][2] = 3 - bsum(&roadfound[4][0], 3);
00753 
00754   nskip[1][1] = 2 - bsum(&roadfound[1][0], 2);
00755   nskip[2][1] = 2 - bsum(&roadfound[2][0], 2);
00756   nskip[3][1] = 2 - bsum(&roadfound[3][0], 2);
00757   nskip[4][1] = 2 - bsum(&roadfound[4][0], 2);
00758 
00759   // Each maximum-depth=i candidate can find a road in any
00760   // gap j, for i>=j. Note that skipped gaps are handled in the 
00761   // assignment of *gapibits below.
00762   // ==========================================================
00763   bool road[5];
00764 
00765   road[4] = roadfound[4][4] && (nskip[4][4] <= _mod_par->get_maxskip(4,4));
00766 
00767   road[3] = (roadfound[3][3] && (nskip[3][3] <= _mod_par->get_maxskip(3,3))) ||
00768             (roadfound[4][3] && (nskip[4][3] <= _mod_par->get_maxskip(4,3))) ;
00769                                                          
00770   road[2] = (roadfound[2][2] && (nskip[2][2] <= _mod_par->get_maxskip(2,2))) ||
00771             (roadfound[3][2] && (nskip[3][2] <= _mod_par->get_maxskip(3,2))) ||
00772             (roadfound[4][2] && (nskip[4][2] <= _mod_par->get_maxskip(4,2))) ;
00773                                                          
00774   road[1] = (roadfound[1][1] && (nskip[1][1] <= _mod_par->get_maxskip(1,1))) ||
00775             (roadfound[2][1] && (nskip[2][1] <= _mod_par->get_maxskip(2,1))) ||
00776             (roadfound[3][1] && (nskip[3][1] <= _mod_par->get_maxskip(3,1))) ||
00777             (roadfound[4][1] && (nskip[4][1] <= _mod_par->get_maxskip(4,1)));
00778 
00779   // Conditions for setting showered bits:
00780   // 1. Kill any road candidate for which there is a more deeply
00781   //      reconstructed road that showers.
00782   // 2. Don't negate a more deeply reconstructed track, except by
00783   //      its own showermax cuts.
00784   // =============================================================
00785   bool showered[5];
00786 
00787   showered[4] = showermax[0][0] > _mod_par->get_showercut(4,0) ||
00788                 showermax[4][1] > _mod_par->get_showercut(4,1) ||
00789                 showermax[4][2] > _mod_par->get_showercut(4,2) ||
00790                 showermax[4][3] > _mod_par->get_showercut(4,3) ||
00791                 showermax[4][4] > _mod_par->get_showercut(4,4);
00792 
00793   showered[3] = showered[4] ||
00794                 showermax[0][0] > _mod_par->get_showercut(3,0) ||
00795                 showermax[3][1] > _mod_par->get_showercut(3,1) ||
00796                 showermax[3][2] > _mod_par->get_showercut(3,2) ||
00797                 showermax[3][3] > _mod_par->get_showercut(3,3);
00798 
00799   showered[2] = showered[3] ||
00800                 showermax[0][0] > _mod_par->get_showercut(2,0) ||
00801                 showermax[2][1] > _mod_par->get_showercut(2,1) ||
00802                 showermax[2][2] > _mod_par->get_showercut(2,2);
00803 
00804   showered[1] = showered[2] ||
00805                 showermax[0][0] > _mod_par->get_showercut(1,0) ||
00806                 showermax[1][1] > _mod_par->get_showercut(1,1);
00807 
00808   // Return 4-bit value, the i^th bit indicates that a candidate made it
00809   // to the i^th gap w/o showering.
00810   // ===================================================================
00811   gap4bit =  road[4] && !showered[4];
00812   gap3bit = (road[3] && !showered[3]) || gap4bit;
00813   gap2bit = (road[2] && !showered[2]) || gap3bit;
00814   gap1bit = (road[1] && !showered[1]) || gap2bit;
00815 
00816   return;
00817 }
00818 
00820 
00821 void 
00822 mMuiFastRoadFinder::gap0(bool **p, short *showermax)
00823 {
00824   bool st[5];
00825   st[0] = *(p[k0]);
00826   st[1] = *(p[l0]);
00827   st[2] = *(p[m0]);
00828   st[3] = *(p[n0]);
00829   st[4] = *(p[o0]);
00830   
00831   *showermax = bsum(&st[0],5);
00832   m0c = *(p[m0]);
00833   m_0 = m0c;
00834  
00835   return;
00836 }
00837 
00839 
00840 void 
00841 mMuiFastRoadFinder::gap1(bool **p, 
00842                          short swi, short *showermax, bool *roadfound)
00843 {
00844 
00845   // These variables indicate whether a tube in the current gap is
00846   // pointed to by a tube in the previous gap. 
00847   // Note: The way this is done is repetitious for gap1, but
00848   //       I did it because it made it easier
00849   //       for me to get the pattern for subsequent gaps.
00850   // =============================================================
00851   bool j1m0 = m_0 && swi==3; bool j1m0c = m0c && swi==3;
00852   bool k1m0 = m_0 && swi>=2; bool k1m0c = m0c && swi>=2;
00853   bool l1m0 = m_0;           bool l1m0c = m0c;            
00854   bool m1m0 = m_0;           bool m1m0c = m0c;            
00855   bool n1m0 = m_0;           bool n1m0c = m0c;            
00856   bool o1m0 = m_0 && swi>=2; bool o1m0c = m0c && swi>=2;
00857   bool p1m0 = m_0 && swi==3; bool p1m0c = m0c && swi==3;
00858 
00859   bool j1pre = j1m0; 
00860   bool k1pre = k1m0; 
00861   bool l1pre = l1m0;   
00862   bool m1pre = true ; // Allow skipped gap0.   
00863   bool n1pre = n1m0;   
00864   bool o1pre = o1m0; 
00865   bool p1pre = p1m0; 
00866   
00867   // Search for road in current gap.
00868   // ===============================
00869   j1c = *(p[musj1]) && j1pre;
00870   k1c = *(p[k1]) && k1pre;
00871   l1c = *(p[l1]) && l1pre;
00872   m1c = *(p[m1]) && m1pre;
00873   n1c = *(p[n1]) && n1pre;
00874   o1c = *(p[o1]) && o1pre;
00875   p1c = *(p[p1]) && p1pre;
00876   
00877   *roadfound = j1c || k1c || l1c || m1c 
00878                    || n1c || o1c || p1c;
00879   
00880   // Find shower size.
00881   // =================
00882   static const short nInShower = 5;
00883   static const short nShowerSums = 7;
00884   bool st[nShowerSums+nInShower-1];
00885   st[0]  = *(p[h1]) && j1pre;
00886   st[1]  = *(p[i1]) && k1pre;
00887   st[2]  = *(p[musj1]) && l1pre;
00888   st[3]  = *(p[k1]) && m1pre;
00889   st[4]  = *(p[l1]) && m1pre;
00890   st[5]  = *(p[m1]) && m1pre;
00891   st[6]  = *(p[n1]) && m1pre;
00892   st[7]  = *(p[o1]) && m1pre;
00893   st[8]  = *(p[p1]) && n1pre;
00894   st[9]  = *(p[q1]) && o1pre;
00895   st[10] = *(p[r1]) && p1pre;
00896   
00897   *showermax = 0;
00898   for (short i = 0; i < nShowerSums; i++) {
00899     short shower = (short) bsum(&st[i],nInShower);
00900     if (shower > *showermax)
00901       *showermax = shower;
00902   }
00903 
00904   // We need to find out if this gap was skipped.
00905   // The first step is to define variables which indicate
00906   // whether the set tubes on this gap which are projected 
00907   // to by each tube on the previous gap are MT.
00908   // Note: The way this is done is repetitious for gap1, but
00909   //       I did it because it made it easier
00910   //       for me to get the pattern for subsequent gaps.
00911   // ==========================================================
00912   bool m0sl = *(p[l1]) || *(p[m1]) || *(p[n1]) ||
00913     (swi == 2 && (*(p[k1]) || *(p[o1]))) ||
00914     (swi == 3 && (*(p[musj1]) || *(p[p1])));
00915 
00916   // If a tube on the current gap is pointed to by a tube 
00917   // the previous gap, then the current-gap tube's signal projects forward to 
00918   // the next gap iff all tubes pointed to by the previous-gap tube are MT.
00919   // ========================================================================
00920   bool j1m0skip1 = j1m0c && !m0sl;
00921   bool k1m0skip1 = k1m0c && !m0sl;
00922   bool l1m0skip1 = l1m0c && !m0sl;
00923   bool m1m0skip1 = m1m0c && !m0sl;
00924   bool n1m0skip1 = n1m0c && !m0sl;
00925   bool o1m0skip1 = o1m0c && !m0sl;
00926   bool p1m0skip1 = p1m0c && !m0sl;
00927 
00928   bool j1skip1 = j1m0skip1;
00929   bool k1skip1 = k1m0skip1;
00930   bool l1skip1 = l1m0skip1;
00931   bool m1skip1 = m1m0skip1;
00932   bool n1skip1 = n1m0skip1;
00933   bool o1skip1 = o1m0skip1;
00934   bool p1skip1 = p1m0skip1;
00935 
00936   // Projection to the next gap.
00937   // ===========================
00938   j_1 = j1c || j1skip1;
00939   k_1 = k1c || k1skip1;
00940   l_1 = l1c || l1skip1;
00941   m_1 = m1c || m1skip1;
00942   n_1 = n1c || n1skip1;
00943   o_1 = o1c || o1skip1;
00944   p_1 = p1c || p1skip1;
00945   
00946   return;
00947 }
00948 
00950 
00951 void 
00952 mMuiFastRoadFinder::gap2(bool **p, 
00953                          short swi, short *showermax, bool *roadfound)
00954 {
00955 
00956   // These variables indicate whether a tube in this gap is
00957   // pointed to by a tube in the previous gap. 
00958   // ======================================================
00959   bool g2j1 = j_1 && swi==3;   bool g2j1c = j1c && swi==3;
00960   bool h2j1 = j_1 && swi>=2;   bool h2j1c = j1c && swi>=2;
00961   bool i2j1 = j_1;             bool i2j1c = j1c;            
00962   bool j2j1 = j_1;             bool j2j1c = j1c;            
00963   bool k2j1 = j_1;             bool k2j1c = j1c;            
00964   bool l2j1 = j_1 && swi>=2;   bool l2j1c = j1c && swi>=2;
00965   bool m2j1 = j_1 && swi==3;   bool m2j1c = j1c && swi==3;
00966                                                          
00967   bool h2k1 = k_1 && swi==3;   bool h2k1c = k1c && swi==3;
00968   bool i2k1 = k_1 && swi>=2;   bool i2k1c = k1c && swi>=2;
00969   bool j2k1 = k_1;             bool j2k1c = k1c;            
00970   bool k2k1 = k_1;             bool k2k1c = k1c;            
00971   bool l2k1 = k_1;             bool l2k1c = k1c;            
00972   bool m2k1 = k_1 && swi>=2;   bool m2k1c = k1c && swi>=2;
00973   bool n2k1 = k_1 && swi==3;   bool n2k1c = k1c && swi==3;
00974                                                          
00975   bool i2l1 = l_1 && swi==3;   bool i2l1c = l1c && swi==3;
00976   bool j2l1 = l_1 && swi>=2;   bool j2l1c = l1c && swi>=2;
00977   bool k2l1 = l_1;             bool k2l1c = l1c;            
00978   bool l2l1 = l_1;             bool l2l1c = l1c;            
00979   bool m2l1 = l_1;             bool m2l1c = l1c;            
00980   bool n2l1 = l_1 && swi>=2;   bool n2l1c = l1c && swi>=2;
00981   bool o2l1 = l_1 && swi==3;   bool o2l1c = l1c && swi==3;
00982                                                          
00983   bool j2m1 = m_1 && swi==3;   bool j2m1c = m1c && swi==3;
00984   bool k2m1 = m_1 && swi>=2;   bool k2m1c = m1c && swi>=2;
00985   bool l2m1 = m_1;             bool l2m1c = m1c;            
00986   bool m2m1 = m_1;             bool m2m1c = m1c;            
00987   bool n2m1 = m_1;             bool n2m1c = m1c;            
00988   bool o2m1 = m_1 && swi>=2;   bool o2m1c = m1c && swi>=2;
00989   bool p2m1 = m_1 && swi==3;   bool p2m1c = m1c && swi==3;
00990                                                          
00991   bool k2n1 = n_1 && swi==3;   bool k2n1c = n1c && swi==3;
00992   bool l2n1 = n_1 && swi>=2;   bool l2n1c = n1c && swi>=2;
00993   bool m2n1 = n_1;             bool m2n1c = n1c;            
00994   bool n2n1 = n_1;             bool n2n1c = n1c;            
00995   bool o2n1 = n_1;             bool o2n1c = n1c;            
00996   bool p2n1 = n_1 && swi>=2;   bool p2n1c = n1c && swi>=2;
00997   bool q2n1 = n_1 && swi==3;   bool q2n1c = n1c && swi==3;
00998                                                          
00999   bool l2o1 = o_1 && swi==3;   bool l2o1c = o1c && swi==3;
01000   bool m2o1 = o_1 && swi>=2;   bool m2o1c = o1c && swi>=2;
01001   bool n2o1 = o_1;             bool n2o1c = o1c;            
01002   bool o2o1 = o_1;             bool o2o1c = o1c;            
01003   bool p2o1 = o_1;             bool p2o1c = o1c;            
01004   bool q2o1 = o_1 && swi>=2;   bool q2o1c = o1c && swi>=2;
01005   bool r2o1 = o_1 && swi==3;   bool r2o1c = o1c && swi==3;
01006                                                          
01007   bool m2p1 = p_1 && swi==3;   bool m2p1c = p1c && swi==3;
01008   bool n2p1 = p_1 && swi>=2;   bool n2p1c = p1c && swi>=2;
01009   bool o2p1 = p_1;             bool o2p1c = p1c;            
01010   bool p2p1 = p_1;             bool p2p1c = p1c;            
01011   bool q2p1 = p_1;             bool q2p1c = p1c;            
01012   bool r2p1 = p_1 && swi>=2;   bool r2p1c = p1c && swi>=2;
01013   bool s2p1 = p_1 && swi==3;   bool s2p1c = p1c && swi==3;
01014 
01015   bool g2pre = g2j1; 
01016   bool h2pre = h2j1 || h2k1;
01017   bool i2pre = i2j1 || i2k1 || i2l1;
01018   bool j2pre = j2j1 || j2k1 || j2l1 || j2m1;
01019   bool k2pre = k2j1 || k2k1 || k2l1 || k2m1 || k2n1;
01020   bool l2pre = l2j1 || l2k1 || l2l1 || l2m1 || l2n1 || l2o1;
01021   bool m2pre = m2j1 || m2k1 || m2l1 || m2m1 || m2n1 || m2o1 || m2p1;
01022   bool n2pre = n2k1 || n2l1 || n2m1 || n2n1 || n2o1 || n2p1;
01023   bool o2pre = o2l1 || o2m1 || o2n1 || o2o1 || o2p1;       
01024   bool p2pre = p2m1 || p2n1 || p2o1 || p2p1;
01025   bool q2pre = q2n1 || q2o1 || q2p1;
01026   bool r2pre = r2o1 || r2p1;
01027   bool s2pre = s2p1;
01028   
01029   // Search for road in current gap.
01030   // ===============================
01031   g2c = *(p[g2]) && g2pre;
01032   h2c = *(p[h2]) && h2pre;
01033   i2c = *(p[i2]) && i2pre;
01034   j2c = *(p[j2]) && j2pre;
01035   k2c = *(p[k2]) && k2pre;
01036   l2c = *(p[l2]) && l2pre;
01037   m2c = *(p[m2]) && m2pre;
01038   n2c = *(p[n2]) && n2pre;
01039   o2c = *(p[o2]) && o2pre;
01040   p2c = *(p[p2]) && p2pre;
01041   q2c = *(p[q2]) && q2pre;
01042   r2c = *(p[r2]) && r2pre;
01043   s2c = *(p[s2]) && s2pre;
01044   
01045   *roadfound = g2c || h2c || i2c || j2c || k2c || l2c || m2c 
01046                    || n2c || o2c || p2c || q2c || r2c || s2c;
01047   
01048   // Find shower size.
01049   // =================
01050   static const short nInShower = 5;
01051   static const short nShowerSums = 13;
01052   bool st[nShowerSums+nInShower-1];
01053   st[0]  = *(p[e2]) && g2pre;
01054   st[1]  = *(p[f2]) && h2pre;
01055   st[2]  = *(p[g2]) && i2pre;
01056   st[3]  = *(p[h2]) && j2pre;
01057   st[4]  = *(p[i2]) && k2pre;
01058   st[5]  = *(p[j2]) && l2pre;
01059   st[6]  = *(p[k2]) && m2pre;
01060   st[7]  = *(p[l2]) && m2pre;
01061   st[8]  = *(p[m2]) && m2pre;
01062   st[9]  = *(p[n2]) && m2pre;
01063   st[10] = *(p[o2]) && m2pre;
01064   st[11] = *(p[p2]) && n2pre;
01065   st[12] = *(p[q2]) && o2pre;
01066   st[13] = *(p[r2]) && p2pre;
01067   st[14] = *(p[s2]) && q2pre;
01068   st[15] = *(p[t2]) && r2pre;
01069   st[16] = *(p[u2]) && s2pre;
01070   
01071   *showermax = 0;
01072   for (short i = 0; i < nShowerSums; i++) {
01073     short shower = (short) bsum(&st[i],nInShower);
01074     if (shower > *showermax)
01075       *showermax = shower;
01076   }
01077 
01078   // We need to find out if this gap was skipped.
01079   // The first step is to define variables which indicate
01080   // whether the set tubes on this gap which are projected 
01081   // to by each tube on the previous gap are MT.
01082   // =====================================================
01083   bool j1sl = *(p[i2]) || *(p[j2]) || *(p[k2]) ||
01084     (swi == 2 && (*(p[h2]) || *(p[l2]))) ||
01085     (swi == 3 && (*(p[g2]) || *(p[m2])));
01086 
01087   bool k1sl = *(p[j2]) || *(p[k2]) || *(p[l2]) ||
01088     (swi == 2 && (*(p[i2]) || *(p[m2]))) ||
01089     (swi == 3 && (*(p[h2]) || *(p[n2])));
01090 
01091   bool l1sl = *(p[k2]) || *(p[l2]) || *(p[m2]) ||
01092     (swi == 2 && (*(p[j2]) || *(p[n2]))) ||
01093     (swi == 3 && (*(p[i2]) || *(p[o2])));
01094 
01095   bool m1sl = *(p[l2]) || *(p[m2]) || *(p[n2]) ||
01096     (swi == 2 && (*(p[k2]) || *(p[o2]))) ||
01097     (swi == 3 && (*(p[j2]) || *(p[p2])));
01098 
01099   bool n1sl = *(p[m2]) || *(p[n2]) || *(p[o2]) ||
01100     (swi == 2 && (*(p[l2]) || *(p[p2]))) ||
01101     (swi == 3 && (*(p[k2]) || *(p[q2])));
01102 
01103   bool o1sl = *(p[n2]) || *(p[o2]) || *(p[p2]) ||
01104     (swi == 2 && (*(p[m2]) || *(p[q2]))) ||
01105     (swi == 3 && (*(p[l2]) || *(p[r2])));
01106 
01107   bool p1sl = *(p[o2]) || *(p[p2]) || *(p[q2]) ||
01108     (swi == 2 && (*(p[n2]) || *(p[r2]))) ||
01109     (swi == 3 && (*(p[m2]) || *(p[s2])));
01110 
01111   // If a tube on the current gap is pointed to by a tube 
01112   // the previous gap, then the current-gap tube's signal projects forward to 
01113   // the next gap iff all tubes pointed to by the previous-gap tube are MT.
01114   // ========================================================================
01115   bool g2j1skip2 = g2j1c && !j1sl;
01116   bool h2j1skip2 = h2j1c && !j1sl;
01117   bool i2j1skip2 = i2j1c && !j1sl;
01118   bool j2j1skip2 = j2j1c && !j1sl;
01119   bool k2j1skip2 = k2j1c && !j1sl;
01120   bool l2j1skip2 = l2j1c && !j1sl;
01121   bool m2j1skip2 = m2j1c && !j1sl;
01122                               
01123   bool h2k1skip2 = h2k1c && !k1sl;
01124   bool i2k1skip2 = i2k1c && !k1sl;
01125   bool j2k1skip2 = j2k1c && !k1sl;
01126   bool k2k1skip2 = k2k1c && !k1sl;
01127   bool l2k1skip2 = l2k1c && !k1sl;
01128   bool m2k1skip2 = m2k1c && !k1sl;
01129   bool n2k1skip2 = n2k1c && !k1sl;
01130                               
01131   bool i2l1skip2 = i2l1c && !l1sl;
01132   bool j2l1skip2 = j2l1c && !l1sl;
01133   bool k2l1skip2 = k2l1c && !l1sl;
01134   bool l2l1skip2 = l2l1c && !l1sl;
01135   bool m2l1skip2 = m2l1c && !l1sl;
01136   bool n2l1skip2 = n2l1c && !l1sl;
01137   bool o2l1skip2 = o2l1c && !l1sl;
01138                               
01139   bool j2m1skip2 = j2m1c && !m1sl;
01140   bool k2m1skip2 = k2m1c && !m1sl;
01141   bool l2m1skip2 = l2m1c && !m1sl;
01142   bool m2m1skip2 = m2m1c && !m1sl;
01143   bool n2m1skip2 = n2m1c && !m1sl;
01144   bool o2m1skip2 = o2m1c && !m1sl;
01145   bool p2m1skip2 = p2m1c && !m1sl;
01146                               
01147   bool k2n1skip2 = k2n1c && !n1sl;
01148   bool l2n1skip2 = l2n1c && !n1sl;
01149   bool m2n1skip2 = m2n1c && !n1sl;
01150   bool n2n1skip2 = n2n1c && !n1sl;
01151   bool o2n1skip2 = o2n1c && !n1sl;
01152   bool p2n1skip2 = p2n1c && !n1sl;
01153   bool q2n1skip2 = q2n1c && !n1sl;
01154                               
01155   bool l2o1skip2 = l2o1c && !o1sl;
01156   bool m2o1skip2 = m2o1c && !o1sl;
01157   bool n2o1skip2 = n2o1c && !o1sl;
01158   bool o2o1skip2 = o2o1c && !o1sl;
01159   bool p2o1skip2 = p2o1c && !o1sl;
01160   bool q2o1skip2 = q2o1c && !o1sl;
01161   bool r2o1skip2 = r2o1c && !o1sl;
01162                               
01163   bool m2p1skip2 = m2p1c && !p1sl;
01164   bool n2p1skip2 = n2p1c && !p1sl;
01165   bool o2p1skip2 = o2p1c && !p1sl;
01166   bool p2p1skip2 = p2p1c && !p1sl;
01167   bool q2p1skip2 = q2p1c && !p1sl;
01168   bool r2p1skip2 = r2p1c && !p1sl;
01169   bool s2p1skip2 = s2p1c && !p1sl;
01170 
01171   bool g2skip2 = g2j1skip2;
01172   bool h2skip2 = h2j1skip2 || h2k1skip2;
01173   bool i2skip2 = i2j1skip2 || i2k1skip2 || i2l1skip2;
01174   bool j2skip2 = j2j1skip2 || j2k1skip2 || j2l1skip2 || j2m1skip2;
01175   bool k2skip2 = k2j1skip2 || k2k1skip2 || k2l1skip2 || k2m1skip2 || k2n1skip2;
01176   bool l2skip2 = l2j1skip2 || l2k1skip2 || l2l1skip2 || l2m1skip2 || l2n1skip2 || l2o1skip2;
01177   bool m2skip2 = m2j1skip2 || m2k1skip2 || m2l1skip2 || m2m1skip2 || m2n1skip2 || m2o1skip2 || m2p1skip2;
01178   bool n2skip2 = n2k1skip2 || n2l1skip2 || n2m1skip2 || n2n1skip2 || n2o1skip2 || n2p1skip2;
01179   bool o2skip2 = o2l1skip2 || o2m1skip2 || o2n1skip2 || o2o1skip2 || o2p1skip2;       
01180   bool p2skip2 = p2m1skip2 || p2n1skip2 || p2o1skip2 || p2p1skip2;
01181   bool q2skip2 = q2n1skip2 || q2o1skip2 || q2p1skip2;
01182   bool r2skip2 = r2o1skip2 || r2p1skip2;
01183   bool s2skip2 = s2p1skip2;
01184   
01185   // Projection to the next gap.
01186   // ===========================
01187   g_2 = g2c || g2skip2;
01188   h_2 = h2c || h2skip2;
01189   i_2 = i2c || i2skip2;
01190   j_2 = j2c || j2skip2;
01191   k_2 = k2c || k2skip2;
01192   l_2 = l2c || l2skip2;
01193   m_2 = m2c || m2skip2;
01194   n_2 = n2c || n2skip2;
01195   o_2 = o2c || o2skip2;
01196   p_2 = p2c || p2skip2;
01197   q_2 = q2c || q2skip2;
01198   r_2 = r2c || r2skip2;
01199   s_2 = s2c || s2skip2;
01200   
01201   return;
01202 }
01203 
01204 
01206 
01207 void 
01208 mMuiFastRoadFinder::gap3(bool **p, 
01209                          short swi, short *showermax, bool *roadfound)
01210 {
01211 
01212   // These variables indicate whether a tube in this gap is
01213   // pointed to by a tube in the previous gap. 
01214   // ======================================================
01215   bool d3g2 = g_2 && swi==3;   bool d3g2c = g2c && swi==3;
01216   bool e3g2 = g_2 && swi>=2;   bool e3g2c = g2c && swi>=2;
01217   bool f3g2 = g_2;             bool f3g2c = g2c;            
01218   bool g3g2 = g_2;             bool g3g2c = g2c;            
01219   bool h3g2 = g_2;             bool h3g2c = g2c;            
01220   bool i3g2 = g_2 && swi>=2;   bool i3g2c = g2c && swi>=2;
01221   bool j3g2 = g_2 && swi==3;   bool j3g2c = g2c && swi==3;
01222                                                          
01223   bool e3h2 = h_2 && swi==3;   bool e3h2c = h2c && swi==3;
01224   bool f3h2 = h_2 && swi>=2;   bool f3h2c = h2c && swi>=2;
01225   bool g3h2 = h_2;             bool g3h2c = h2c;            
01226   bool h3h2 = h_2;             bool h3h2c = h2c;            
01227   bool i3h2 = h_2;             bool i3h2c = h2c;            
01228   bool j3h2 = h_2 && swi>=2;   bool j3h2c = h2c && swi>=2;
01229   bool k3h2 = h_2 && swi==3;   bool k3h2c = h2c && swi==3;
01230                                                          
01231   bool f3i2 = i_2 && swi==3;   bool f3i2c = i2c && swi==3;
01232   bool g3i2 = i_2 && swi>=2;   bool g3i2c = i2c && swi>=2;
01233   bool h3i2 = i_2;             bool h3i2c = i2c;            
01234   bool i3i2 = i_2;             bool i3i2c = i2c;            
01235   bool j3i2 = i_2;             bool j3i2c = i2c;            
01236   bool k3i2 = i_2 && swi>=2;   bool k3i2c = i2c && swi>=2;
01237   bool l3i2 = i_2 && swi==3;   bool l3i2c = i2c && swi==3;
01238                                                          
01239   bool g3j2 = j_2 && swi==3;   bool g3j2c = j2c && swi==3;
01240   bool h3j2 = j_2 && swi>=2;   bool h3j2c = j2c && swi>=2;
01241   bool i3j2 = j_2;             bool i3j2c = j2c;            
01242   bool j3j2 = j_2;             bool j3j2c = j2c;            
01243   bool k3j2 = j_2;             bool k3j2c = j2c;            
01244   bool l3j2 = j_2 && swi>=2;   bool l3j2c = j2c && swi>=2;
01245   bool m3j2 = j_2 && swi==3;   bool m3j2c = j2c && swi==3;
01246                                                          
01247   bool h3k2 = k_2 && swi==3;   bool h3k2c = k2c && swi==3;
01248   bool i3k2 = k_2 && swi>=2;   bool i3k2c = k2c && swi>=2;
01249   bool j3k2 = k_2;             bool j3k2c = k2c;            
01250   bool k3k2 = k_2;             bool k3k2c = k2c;            
01251   bool l3k2 = k_2;             bool l3k2c = k2c;            
01252   bool m3k2 = k_2 && swi>=2;   bool m3k2c = k2c && swi>=2;
01253   bool n3k2 = k_2 && swi==3;   bool n3k2c = k2c && swi==3;
01254                                                          
01255   bool i3l2 = l_2 && swi==3;   bool i3l2c = l2c && swi==3;
01256   bool j3l2 = l_2 && swi>=2;   bool j3l2c = l2c && swi>=2;
01257   bool k3l2 = l_2;             bool k3l2c = l2c;            
01258   bool l3l2 = l_2;             bool l3l2c = l2c;            
01259   bool m3l2 = l_2;             bool m3l2c = l2c;            
01260   bool n3l2 = l_2 && swi>=2;   bool n3l2c = l2c && swi>=2;
01261   bool o3l2 = l_2 && swi==3;   bool o3l2c = l2c && swi==3;
01262                                                          
01263   bool j3m2 = m_2 && swi==3;   bool j3m2c = m2c && swi==3;
01264   bool k3m2 = m_2 && swi>=2;   bool k3m2c = m2c && swi>=2;
01265   bool l3m2 = m_2;             bool l3m2c = m2c;            
01266   bool m3m2 = m_2;             bool m3m2c = m2c;            
01267   bool n3m2 = m_2;             bool n3m2c = m2c;            
01268   bool o3m2 = m_2 && swi>=2;   bool o3m2c = m2c && swi>=2;
01269   bool p3m2 = m_2 && swi==3;   bool p3m2c = m2c && swi==3;
01270                                                          
01271   bool k3n2 = n_2 && swi==3;   bool k3n2c = n2c && swi==3;
01272   bool l3n2 = n_2 && swi>=2;   bool l3n2c = n2c && swi>=2;
01273   bool m3n2 = n_2;             bool m3n2c = n2c;            
01274   bool n3n2 = n_2;             bool n3n2c = n2c;            
01275   bool o3n2 = n_2;             bool o3n2c = n2c;            
01276   bool p3n2 = n_2 && swi>=2;   bool p3n2c = n2c && swi>=2;
01277   bool q3n2 = n_2 && swi==3;   bool q3n2c = n2c && swi==3;
01278                                                          
01279   bool l3o2 = o_2 && swi==3;   bool l3o2c = o2c && swi==3;
01280   bool m3o2 = o_2 && swi>=2;   bool m3o2c = o2c && swi>=2;
01281   bool n3o2 = o_2;             bool n3o2c = o2c;            
01282   bool o3o2 = o_2;             bool o3o2c = o2c;            
01283   bool p3o2 = o_2;             bool p3o2c = o2c;            
01284   bool q3o2 = o_2 && swi>=2;   bool q3o2c = o2c && swi>=2;
01285   bool r3o2 = o_2 && swi==3;   bool r3o2c = o2c && swi==3;
01286                                                          
01287   bool m3p2 = p_2 && swi==3;   bool m3p2c = p2c && swi==3;
01288   bool n3p2 = p_2 && swi>=2;   bool n3p2c = p2c && swi>=2;
01289   bool o3p2 = p_2;             bool o3p2c = p2c;            
01290   bool p3p2 = p_2;             bool p3p2c = p2c;            
01291   bool q3p2 = p_2;             bool q3p2c = p2c;            
01292   bool r3p2 = p_2 && swi>=2;   bool r3p2c = p2c && swi>=2;
01293   bool s3p2 = p_2 && swi==3;   bool s3p2c = p2c && swi==3;
01294                                                          
01295   bool n3q2 = q_2 && swi==3;   bool n3q2c = q2c && swi==3;
01296   bool o3q2 = q_2 && swi>=2;   bool o3q2c = q2c && swi>=2;
01297   bool p3q2 = q_2;             bool p3q2c = q2c;            
01298   bool q3q2 = q_2;             bool q3q2c = q2c;            
01299   bool r3q2 = q_2;             bool r3q2c = q2c;            
01300   bool s3q2 = q_2 && swi>=2;   bool s3q2c = q2c && swi>=2;
01301   bool t3q2 = q_2 && swi==3;   bool t3q2c = q2c && swi==3;
01302                                                          
01303   bool o3r2 = r_2 && swi==3;   bool o3r2c = r2c && swi==3;
01304   bool p3r2 = r_2 && swi>=2;   bool p3r2c = r2c && swi>=2;
01305   bool q3r2 = r_2;             bool q3r2c = r2c;            
01306   bool r3r2 = r_2;             bool r3r2c = r2c;            
01307   bool s3r2 = r_2;             bool s3r2c = r2c;            
01308   bool t3r2 = r_2 && swi>=2;   bool t3r2c = r2c && swi>=2;
01309   bool u3r2 = r_2 && swi==3;   bool u3r2c = r2c && swi==3;
01310                                                          
01311   bool p3s2 = s_2 && swi==3;   bool p3s2c = s2c && swi==3;
01312   bool q3s2 = s_2 && swi>=2;   bool q3s2c = s2c && swi>=2;
01313   bool r3s2 = s_2;             bool r3s2c = s2c;            
01314   bool s3s2 = s_2;             bool s3s2c = s2c;            
01315   bool t3s2 = s_2;             bool t3s2c = s2c;            
01316   bool u3s2 = s_2 && swi>=2;   bool u3s2c = s2c && swi>=2;
01317   bool v3s2 = s_2 && swi==3;   bool v3s2c = s2c && swi==3;
01318 
01319   bool d3pre = d3g2; 
01320   bool e3pre = e3g2 || e3h2;
01321   bool f3pre = f3g2 || f3h2 || f3i2;
01322   bool g3pre = g3g2 || g3h2 || g3i2 || g3j2;
01323   bool h3pre = h3g2 || h3h2 || h3i2 || h3j2 || h3k2;
01324   bool i3pre = i3g2 || i3h2 || i3i2 || i3j2 || i3k2 || i3l2;
01325   bool j3pre = j3g2 || j3h2 || j3i2 || j3j2 || j3k2 || j3l2 || j3m2;
01326   bool k3pre = k3h2 || k3i2 || k3j2 || k3k2 || k3l2 || k3m2 || k3n2;
01327   bool l3pre = l3i2 || l3j2 || l3k2 || l3l2 || l3m2 || l3n2 || l3o2;
01328   bool m3pre = m3j2 || m3k2 || m3l2 || m3m2 || m3n2 || m3o2 || m3p2;
01329   bool n3pre = n3k2 || n3l2 || n3m2 || n3n2 || n3o2 || n3p2 || n3q2;
01330   bool o3pre = o3l2 || o3m2 || o3n2 || o3o2 || o3p2 || o3q2 || o3r2;
01331   bool p3pre = p3m2 || p3n2 || p3o2 || p3p2 || p3q2 || p3r2 || p3s2;
01332   bool q3pre = q3n2 || q3o2 || q3p2 || q3q2 || q3r2 || q3s2;
01333   bool r3pre = r3o2 || r3p2 || r3q2 || r3r2 || r3s2;       
01334   bool s3pre = s3p2 || s3q2 || s3r2 || s3s2;
01335   bool t3pre = t3q2 || t3r2 || t3s2;
01336   bool u3pre = u3r2 || u3s2;
01337   bool v3pre = v3s2;
01338   
01339   // Search for road in current gap.
01340   // ===============================
01341   d3c = *(p[d3]) && d3pre;
01342   e3c = *(p[e3]) && e3pre;
01343   f3c = *(p[f3]) && f3pre;
01344   g3c = *(p[g3]) && g3pre;
01345   h3c = *(p[h3]) && h3pre;
01346   i3c = *(p[i3]) && i3pre;
01347   j3c = *(p[j3]) && j3pre;
01348   k3c = *(p[k3]) && k3pre;
01349   l3c = *(p[l3]) && l3pre;
01350   m3c = *(p[m3]) && m3pre;
01351   n3c = *(p[n3]) && n3pre;
01352   o3c = *(p[o3]) && o3pre;
01353   p3c = *(p[p3]) && p3pre;
01354   q3c = *(p[q3]) && q3pre;
01355   r3c = *(p[r3]) && r3pre;
01356   s3c = *(p[s3]) && s3pre;
01357   t3c = *(p[t3]) && t3pre;
01358   u3c = *(p[u3]) && u3pre;
01359   v3c = *(p[v3]) && v3pre;
01360 
01361   *roadfound = d3c || e3c || f3c || g3c || h3c || i3c || j3c || k3c || l3c || m3c 
01362                    || n3c || o3c || p3c || q3c || r3c || s3c || t3c || u3c || v3c;
01363   
01364   // Find shower size.
01365   // =================
01366   static const short nInShower = 5;
01367   static const short nShowerSums = 19;
01368   bool st[nShowerSums+nInShower-1];
01369   st[0]  = *(p[b3]) && d3pre;
01370   st[1]  = *(p[c3]) && e3pre;
01371   st[2]  = *(p[d3]) && f3pre;
01372   st[3]  = *(p[e3]) && g3pre;
01373   st[4]  = *(p[f3]) && h3pre;
01374   st[5]  = *(p[g3]) && i3pre;
01375   st[6]  = *(p[h3]) && j3pre;
01376   st[7]  = *(p[i3]) && k3pre;
01377   st[8]  = *(p[j3]) && l3pre;
01378   st[9]  = *(p[k3]) && m3pre;
01379   st[10] = *(p[l3]) && m3pre;
01380   st[11] = *(p[m3]) && m3pre;
01381   st[12] = *(p[n3]) && m3pre;
01382   st[13] = *(p[o3]) && m3pre;
01383   st[14] = *(p[p3]) && n3pre;
01384   st[15] = *(p[q3]) && o3pre;
01385   st[16] = *(p[r3]) && p3pre;
01386   st[17] = *(p[s3]) && q3pre;
01387   st[18] = *(p[t3]) && r3pre;
01388   st[19] = *(p[u3]) && s3pre;
01389   st[20] = *(p[v3]) && t3pre;
01390   st[21] = *(p[w3]) && u3pre;
01391   st[22] = *(p[x3]) && v3pre;
01392   
01393   *showermax = 0;
01394   for (short i = 0; i < nShowerSums; i++) {
01395     short shower = (short) bsum(&st[i], nInShower);
01396     if (shower > *showermax)
01397       *showermax = shower;
01398   }
01399 
01400   // We need to find out if this gap was skipped.
01401   // The first step is to define variables which indicate
01402   // whether the set tubes on this gap which are projected 
01403   // to by each tube on the previous gap are MT.
01404   // =====================================================
01405   bool g2sl = *(p[f3]) || *(p[g3]) || *(p[h3]) ||
01406     (swi == 2 && (*(p[e3]) || *(p[i3]))) ||
01407     (swi == 3 && (*(p[d3]) || *(p[j3])));
01408          
01409   bool h2sl = *(p[g3]) || *(p[h3]) || *(p[i3]) ||
01410     (swi == 2 && (*(p[f3]) || *(p[j3]))) ||
01411     (swi == 3 && (*(p[e3]) || *(p[k3])));
01412          
01413   bool i2sl = *(p[h3]) || *(p[i3]) || *(p[j3]) ||
01414     (swi == 2 && (*(p[g3]) || *(p[k3]))) ||
01415     (swi == 3 && (*(p[f3]) || *(p[l3])));
01416          
01417   bool j2sl = *(p[i3]) || *(p[j3]) || *(p[k3]) ||
01418     (swi == 2 && (*(p[h3]) || *(p[l3]))) ||
01419     (swi == 3 && (*(p[g3]) || *(p[m3])));
01420          
01421   bool k2sl = *(p[j3]) || *(p[k3]) || *(p[l3]) ||
01422     (swi == 2 && (*(p[i3]) || *(p[m3]))) ||
01423     (swi == 3 && (*(p[h3]) || *(p[n3])));
01424          
01425   bool l2sl = *(p[k3]) || *(p[l3]) || *(p[m3]) ||
01426     (swi == 2 && (*(p[j3]) || *(p[n3]))) ||
01427     (swi == 3 && (*(p[i3]) || *(p[o3])));
01428          
01429   bool m2sl = *(p[l3]) || *(p[m3]) || *(p[n3]) ||
01430     (swi == 2 && (*(p[k3]) || *(p[o3]))) ||
01431     (swi == 3 && (*(p[j3]) || *(p[p3])));
01432          
01433   bool n2sl = *(p[m3]) || *(p[n3]) || *(p[o3]) ||
01434     (swi == 2 && (*(p[l3]) || *(p[p3]))) ||
01435     (swi == 3 && (*(p[k3]) || *(p[q3])));
01436          
01437   bool o2sl = *(p[n3]) || *(p[o3]) || *(p[p3]) ||
01438     (swi == 2 && (*(p[m3]) || *(p[q3]))) ||
01439     (swi == 3 && (*(p[l3]) || *(p[r3])));
01440          
01441   bool p2sl = *(p[o3]) || *(p[p3]) || *(p[q3]) ||
01442     (swi == 2 && (*(p[n3]) || *(p[r3]))) ||
01443     (swi == 3 && (*(p[m3]) || *(p[s3])));
01444          
01445   bool q2sl = *(p[p3]) || *(p[q3]) || *(p[r3]) ||
01446     (swi == 2 && (*(p[o3]) || *(p[s3]))) ||
01447     (swi == 3 && (*(p[n3]) || *(p[t3])));
01448          
01449   bool r2sl = *(p[q3]) || *(p[r3]) || *(p[s3]) ||
01450     (swi == 2 && (*(p[p3]) || *(p[t3]))) ||
01451     (swi == 3 && (*(p[o3]) || *(p[u3])));
01452          
01453   bool s2sl = *(p[r3]) || *(p[s3]) || *(p[t3]) ||
01454     (swi == 2 && (*(p[q3]) || *(p[u3]))) ||
01455     (swi == 3 && (*(p[p3]) || *(p[v3])));
01456 
01457   // If a tube on the current gap is pointed to by a tube 
01458   // the previous gap, then the current-gap tube's signal projects forward to 
01459   // the next gap iff all tubes pointed to by the previous-gap tube are MT.
01460   // ========================================================================
01461   bool d3g2skip3 = d3g2c && !g2sl;
01462   bool e3g2skip3 = e3g2c && !g2sl;
01463   bool f3g2skip3 = f3g2c && !g2sl;
01464   bool g3g2skip3 = g3g2c && !g2sl;
01465   bool h3g2skip3 = h3g2c && !g2sl;
01466   bool i3g2skip3 = i3g2c && !g2sl;
01467   bool j3g2skip3 = j3g2c && !g2sl;
01468                              
01469   bool e3h2skip3 = e3h2c && !h2sl;
01470   bool f3h2skip3 = f3h2c && !h2sl;
01471   bool g3h2skip3 = g3h2c && !h2sl;
01472   bool h3h2skip3 = h3h2c && !h2sl;
01473   bool i3h2skip3 = i3h2c && !h2sl;
01474   bool j3h2skip3 = j3h2c && !h2sl;
01475   bool k3h2skip3 = k3h2c && !h2sl;
01476                              
01477   bool f3i2skip3 = f3i2c && !i2sl;
01478   bool g3i2skip3 = g3i2c && !i2sl;
01479   bool h3i2skip3 = h3i2c && !i2sl;
01480   bool i3i2skip3 = i3i2c && !i2sl;
01481   bool j3i2skip3 = j3i2c && !i2sl;
01482   bool k3i2skip3 = k3i2c && !i2sl;
01483   bool l3i2skip3 = l3i2c && !i2sl;
01484                              
01485   bool g3j2skip3 = g3j2c && !j2sl;
01486   bool h3j2skip3 = h3j2c && !j2sl;
01487   bool i3j2skip3 = i3j2c && !j2sl;
01488   bool j3j2skip3 = j3j2c && !j2sl;
01489   bool k3j2skip3 = k3j2c && !j2sl;
01490   bool l3j2skip3 = l3j2c && !j2sl;
01491   bool m3j2skip3 = m3j2c && !j2sl;
01492                              
01493   bool h3k2skip3 = h3k2c && !k2sl;
01494   bool i3k2skip3 = i3k2c && !k2sl;
01495   bool j3k2skip3 = j3k2c && !k2sl;
01496   bool k3k2skip3 = k3k2c && !k2sl;
01497   bool l3k2skip3 = l3k2c && !k2sl;
01498   bool m3k2skip3 = m3k2c && !k2sl;
01499   bool n3k2skip3 = n3k2c && !k2sl;
01500                              
01501   bool i3l2skip3 = i3l2c && !l2sl;
01502   bool j3l2skip3 = j3l2c && !l2sl;
01503   bool k3l2skip3 = k3l2c && !l2sl;
01504   bool l3l2skip3 = l3l2c && !l2sl;
01505   bool m3l2skip3 = m3l2c && !l2sl;
01506   bool n3l2skip3 = n3l2c && !l2sl;
01507   bool o3l2skip3 = o3l2c && !l2sl;
01508                              
01509   bool j3m2skip3 = j3m2c && !m2sl;
01510   bool k3m2skip3 = k3m2c && !m2sl;
01511   bool l3m2skip3 = l3m2c && !m2sl;
01512   bool m3m2skip3 = m3m2c && !m2sl;
01513   bool n3m2skip3 = n3m2c && !m2sl;
01514   bool o3m2skip3 = o3m2c && !m2sl;
01515   bool p3m2skip3 = p3m2c && !m2sl;
01516                              
01517   bool k3n2skip3 = k3n2c && !n2sl;
01518   bool l3n2skip3 = l3n2c && !n2sl;
01519   bool m3n2skip3 = m3n2c && !n2sl;
01520   bool n3n2skip3 = n3n2c && !n2sl;
01521   bool o3n2skip3 = o3n2c && !n2sl;
01522   bool p3n2skip3 = p3n2c && !n2sl;
01523   bool q3n2skip3 = q3n2c && !n2sl;
01524                              
01525   bool l3o2skip3 = l3o2c && !o2sl;
01526   bool m3o2skip3 = m3o2c && !o2sl;
01527   bool n3o2skip3 = n3o2c && !o2sl;
01528   bool o3o2skip3 = o3o2c && !o2sl;
01529   bool p3o2skip3 = p3o2c && !o2sl;
01530   bool q3o2skip3 = q3o2c && !o2sl;
01531   bool r3o2skip3 = r3o2c && !o2sl;
01532                              
01533   bool m3p2skip3 = m3p2c && !p2sl;
01534   bool n3p2skip3 = n3p2c && !p2sl;
01535   bool o3p2skip3 = o3p2c && !p2sl;
01536   bool p3p2skip3 = p3p2c && !p2sl;
01537   bool q3p2skip3 = q3p2c && !p2sl;
01538   bool r3p2skip3 = r3p2c && !p2sl;
01539   bool s3p2skip3 = s3p2c && !p2sl;
01540                               
01541   bool n3q2skip3 = n3q2c && !q2sl;
01542   bool o3q2skip3 = o3q2c && !q2sl;
01543   bool p3q2skip3 = p3q2c && !q2sl;
01544   bool q3q2skip3 = q3q2c && !q2sl;
01545   bool r3q2skip3 = r3q2c && !q2sl;
01546   bool s3q2skip3 = s3q2c && !q2sl;
01547   bool t3q2skip3 = t3q2c && !q2sl;
01548                              
01549   bool o3r2skip3 = o3r2c && !r2sl;
01550   bool p3r2skip3 = p3r2c && !r2sl;
01551   bool q3r2skip3 = q3r2c && !r2sl;
01552   bool r3r2skip3 = r3r2c && !r2sl;
01553   bool s3r2skip3 = s3r2c && !r2sl;
01554   bool t3r2skip3 = t3r2c && !r2sl;
01555   bool u3r2skip3 = u3r2c && !r2sl;
01556                              
01557   bool p3s2skip3 = p3s2c && !s2sl;
01558   bool q3s2skip3 = q3s2c && !s2sl;
01559   bool r3s2skip3 = r3s2c && !s2sl;
01560   bool s3s2skip3 = s3s2c && !s2sl;
01561   bool t3s2skip3 = t3s2c && !s2sl;
01562   bool u3s2skip3 = u3s2c && !s2sl;
01563   bool v3s2skip3 = v3s2c && !s2sl;
01564 
01565   bool d3skip3 = d3g2skip3; 
01566   bool e3skip3 = e3g2skip3 || e3h2skip3;
01567   bool f3skip3 = f3g2skip3 || f3h2skip3 || f3i2skip3;
01568   bool g3skip3 = g3g2skip3 || g3h2skip3 || g3i2skip3 || g3j2skip3;
01569   bool h3skip3 = h3g2skip3 || h3h2skip3 || h3i2skip3 || h3j2skip3 || h3k2skip3;
01570   bool i3skip3 = i3g2skip3 || i3h2skip3 || i3i2skip3 || i3j2skip3 || i3k2skip3 || i3l2skip3;
01571   bool j3skip3 = j3g2skip3 || j3h2skip3 || j3i2skip3 || j3j2skip3 || j3k2skip3 || j3l2skip3 || j3m2skip3;
01572   bool k3skip3 = k3h2skip3 || k3i2skip3 || k3j2skip3 || k3k2skip3 || k3l2skip3 || k3m2skip3 || k3n2skip3;
01573   bool l3skip3 = l3i2skip3 || l3j2skip3 || l3k2skip3 || l3l2skip3 || l3m2skip3 || l3n2skip3 || l3o2skip3;
01574   bool m3skip3 = m3j2skip3 || m3k2skip3 || m3l2skip3 || m3m2skip3 || m3n2skip3 || m3o2skip3 || m3p2skip3;
01575   bool n3skip3 = n3k2skip3 || n3l2skip3 || n3m2skip3 || n3n2skip3 || n3o2skip3 || n3p2skip3 || n3q2skip3;
01576   bool o3skip3 = o3l2skip3 || o3m2skip3 || o3n2skip3 || o3o2skip3 || o3p2skip3 || o3q2skip3 || o3r2skip3;
01577   bool p3skip3 = p3m2skip3 || p3n2skip3 || p3o2skip3 || p3p2skip3 || p3q2skip3 || p3r2skip3 || p3s2skip3;
01578   bool q3skip3 = q3n2skip3 || q3o2skip3 || q3p2skip3 || q3q2skip3 || q3r2skip3 || q3s2skip3;
01579   bool r3skip3 = r3o2skip3 || r3p2skip3 || r3q2skip3 || r3r2skip3 || r3s2skip3;       
01580   bool s3skip3 = s3p2skip3 || s3q2skip3 || s3r2skip3 || s3s2skip3;
01581   bool t3skip3 = t3q2skip3 || t3r2skip3 || t3s2skip3;
01582   bool u3skip3 = u3r2skip3 || u3s2skip3;
01583   bool v3skip3 = v3s2skip3;
01584   
01585   // Projection to the next gap.
01586   // ===========================
01587   d_3 = d3c || d3skip3;
01588   e_3 = e3c || e3skip3;
01589   f_3 = f3c || f3skip3;
01590   g_3 = g3c || g3skip3;
01591   h_3 = h3c || h3skip3;
01592   i_3 = i3c || i3skip3;
01593   j_3 = j3c || j3skip3;
01594   k_3 = k3c || k3skip3;
01595   l_3 = l3c || l3skip3;
01596   m_3 = m3c || m3skip3;
01597   n_3 = n3c || n3skip3;
01598   o_3 = o3c || o3skip3;
01599   p_3 = p3c || p3skip3;
01600   q_3 = q3c || q3skip3;
01601   r_3 = r3c || r3skip3;
01602   s_3 = s3c || s3skip3;
01603   t_3 = t3c || t3skip3;
01604   u_3 = u3c || u3skip3;
01605   v_3 = v3c || v3skip3;
01606   
01607   return;
01608 }
01609 
01610 
01612 
01613 void 
01614 mMuiFastRoadFinder::gap4(bool **p, 
01615                          short swi, short *showermax, bool *roadfound)
01616 {
01617 
01618   // These variables indicate whether a tube in this gap is
01619   // pointed to by a tube in the previous gap. 
01620   // ======================================================
01621   bool a4d3 = d_3 && swi==3;
01622   bool b4d3 = d_3 && swi>=2;
01623   bool c4d3 = d_3;             
01624   bool d4d3 = d_3;             
01625   bool e4d3 = d_3;             
01626   bool f4d3 = d_3 && swi>=2;
01627   bool g4d3 = d_3 && swi==3;
01628                    
01629   bool b4e3 = e_3 && swi==3;
01630   bool c4e3 = e_3 && swi>=2;
01631   bool d4e3 = e_3;             
01632   bool e4e3 = e_3;             
01633   bool f4e3 = e_3;             
01634   bool g4e3 = e_3 && swi>=2;
01635   bool h4e3 = e_3 && swi==3;
01636                    
01637   bool c4f3 = f_3 && swi==3;
01638   bool d4f3 = f_3 && swi>=2;
01639   bool e4f3 = f_3;             
01640   bool f4f3 = f_3;             
01641   bool g4f3 = f_3;             
01642   bool h4f3 = f_3 && swi>=2;
01643   bool i4f3 = f_3 && swi==3;
01644                    
01645   bool d4g3 = g_3 && swi==3;
01646   bool e4g3 = g_3 && swi>=2;
01647   bool f4g3 = g_3;             
01648   bool g4g3 = g_3;             
01649   bool h4g3 = g_3;             
01650   bool i4g3 = g_3 && swi>=2;
01651   bool j4g3 = g_3 && swi==3;
01652                    
01653   bool e4h3 = h_3 && swi==3;
01654   bool f4h3 = h_3 && swi>=2;
01655   bool g4h3 = h_3;             
01656   bool h4h3 = h_3;             
01657   bool i4h3 = h_3;             
01658   bool j4h3 = h_3 && swi>=2;
01659   bool k4h3 = h_3 && swi==3;
01660                    
01661   bool f4i3 = i_3 && swi==3;
01662   bool g4i3 = i_3 && swi>=2;
01663   bool h4i3 = i_3;             
01664   bool i4i3 = i_3;             
01665   bool j4i3 = i_3;             
01666   bool k4i3 = i_3 && swi>=2;
01667   bool l4i3 = i_3 && swi==3;
01668                    
01669   bool g4j3 = j_3 && swi==3;
01670   bool h4j3 = j_3 && swi>=2;
01671   bool i4j3 = j_3;             
01672   bool j4j3 = j_3;             
01673   bool k4j3 = j_3;             
01674   bool l4j3 = j_3 && swi>=2;
01675   bool m4j3 = j_3 && swi==3;
01676                    
01677   bool h4k3 = k_3 && swi==3;
01678   bool i4k3 = k_3 && swi>=2;
01679   bool j4k3 = k_3;             
01680   bool k4k3 = k_3;             
01681   bool l4k3 = k_3;             
01682   bool m4k3 = k_3 && swi>=2;
01683   bool n4k3 = k_3 && swi==3;
01684                    
01685   bool i4l3 = l_3 && swi==3;
01686   bool j4l3 = l_3 && swi>=2;
01687   bool k4l3 = l_3;             
01688   bool l4l3 = l_3;             
01689   bool m4l3 = l_3;             
01690   bool n4l3 = l_3 && swi>=2;
01691   bool o4l3 = l_3 && swi==3;
01692                    
01693   bool j4m3 = m_3 && swi==3;
01694   bool k4m3 = m_3 && swi>=2;
01695   bool l4m3 = m_3;             
01696   bool m4m3 = m_3;             
01697   bool n4m3 = m_3;             
01698   bool o4m3 = m_3 && swi>=2;
01699   bool p4m3 = m_3 && swi==3;
01700                    
01701   bool k4n3 = n_3 && swi==3;
01702   bool l4n3 = n_3 && swi>=2;
01703   bool m4n3 = n_3;             
01704   bool n4n3 = n_3;             
01705   bool o4n3 = n_3;             
01706   bool p4n3 = n_3 && swi>=2;
01707   bool q4n3 = n_3 && swi==3;
01708                    
01709   bool l4o3 = o_3 && swi==3;
01710   bool m4o3 = o_3 && swi>=2;
01711   bool n4o3 = o_3;             
01712   bool o4o3 = o_3;             
01713   bool p4o3 = o_3;             
01714   bool q4o3 = o_3 && swi>=2;
01715   bool r4o3 = o_3 && swi==3;
01716                    
01717   bool m4p3 = p_3 && swi==3;
01718   bool n4p3 = p_3 && swi>=2;
01719   bool o4p3 = p_3;             
01720   bool p4p3 = p_3;             
01721   bool q4p3 = p_3;             
01722   bool r4p3 = p_3 && swi>=2;
01723   bool s4p3 = p_3 && swi==3;
01724 
01725   bool n4q3 = q_3 && swi==3;
01726   bool o4q3 = q_3 && swi>=2;
01727   bool p4q3 = q_3;             
01728   bool q4q3 = q_3;             
01729   bool r4q3 = q_3;             
01730   bool s4q3 = q_3 && swi>=2;
01731   bool t4q3 = q_3 && swi==3;
01732                    
01733   bool o4r3 = r_3 && swi==3;
01734   bool p4r3 = r_3 && swi>=2;
01735   bool q4r3 = r_3;             
01736   bool r4r3 = r_3;             
01737   bool s4r3 = r_3;             
01738   bool t4r3 = r_3 && swi>=2;
01739   bool u4r3 = r_3 && swi==3;
01740                    
01741   bool p4s3 = s_3 && swi==3;
01742   bool q4s3 = s_3 && swi>=2;
01743   bool r4s3 = s_3;             
01744   bool s4s3 = s_3;             
01745   bool t4s3 = s_3;             
01746   bool u4s3 = s_3 && swi>=2;
01747   bool v4s3 = s_3 && swi==3;
01748 
01749   bool q4t3 = t_3 && swi==3;
01750   bool r4t3 = t_3 && swi>=2;
01751   bool s4t3 = t_3;             
01752   bool t4t3 = t_3;             
01753   bool u4t3 = t_3;             
01754   bool v4t3 = t_3 && swi>=2;
01755   bool w4t3 = t_3 && swi==3;
01756                    
01757   bool r4u3 = u_3 && swi==3;
01758   bool s4u3 = u_3 && swi>=2;
01759   bool t4u3 = u_3;             
01760   bool u4u3 = u_3;             
01761   bool v4u3 = u_3;             
01762   bool w4u3 = u_3 && swi>=2;
01763   bool x4u3 = u_3 && swi==3;
01764                    
01765   bool s4v3 = v_3 && swi==3;
01766   bool t4v3 = v_3 && swi>=2;
01767   bool u4v3 = v_3;             
01768   bool v4v3 = v_3;             
01769   bool w4v3 = v_3;             
01770   bool x4v3 = v_3 && swi>=2;
01771   bool y4v3 = v_3 && swi==3;
01772                    
01773   bool a4pre = a4d3; 
01774   bool b4pre = b4d3 || b4e3;
01775   bool c4pre = c4d3 || c4e3 || c4f3;
01776   bool d4pre = d4d3 || d4e3 || d4f3 || d4g3;
01777   bool e4pre = e4d3 || e4e3 || e4f3 || e4g3 || e4h3;
01778   bool f4pre = f4d3 || f4e3 || f4f3 || f4g3 || f4h3 || f4i3;
01779   bool g4pre = g4d3 || g4e3 || g4f3 || g4g3 || g4h3 || g4i3 || g4j3;
01780   bool h4pre = h4e3 || h4f3 || h4g3 || h4h3 || h4i3 || h4j3 || h4k3;
01781   bool i4pre = i4f3 || i4g3 || i4h3 || i4i3 || i4j3 || i4k3 || i4l3;
01782   bool j4pre = j4g3 || j4h3 || j4i3 || j4j3 || j4k3 || j4l3 || j4m3;
01783   bool k4pre = k4h3 || k4i3 || k4j3 || k4k3 || k4l3 || k4m3 || k4n3;
01784   bool l4pre = l4i3 || l4j3 || l4k3 || l4l3 || l4m3 || l4n3 || l4o3;
01785   bool m4pre = m4j3 || m4k3 || m4l3 || m4m3 || m4n3 || m4o3 || m4p3;
01786   bool n4pre = n4k3 || n4l3 || n4m3 || n4n3 || n4o3 || n4p3 || n4q3;
01787   bool o4pre = o4l3 || o4m3 || o4n3 || o4o3 || o4p3 || o4q3 || o4r3;
01788   bool p4pre = p4m3 || p4n3 || p4o3 || p4p3 || p4q3 || p4r3 || p4s3;
01789   bool q4pre = q4n3 || q4o3 || q4p3 || q4q3 || q4r3 || q4s3 || q4t3;
01790   bool r4pre = r4o3 || r4p3 || r4q3 || r4r3 || r4s3 || r4t3 || r4u3;
01791   bool s4pre = s4p3 || s4q3 || s4r3 || s4s3 || s4t3 || s4u3 || s4v3;
01792   bool t4pre = t4q3 || t4r3 || t4s3 || t4t3 || t4u3 || t4v3;
01793   bool u4pre = u4r3 || u4s3 || u4t3 || u4u3 || u4v3;       
01794   bool v4pre = v4s3 || v4t3 || v4u3 || v4v3;
01795   bool w4pre = w4t3 || w4u3 || w4v3;
01796   bool x4pre = x4u3 || x4v3;
01797   bool y4pre = y4v3;
01798   
01799   // Search for road in current gap.
01800   // ===============================
01801   bool a4c = *(p[a4]) && a4pre;
01802   bool b4c = *(p[b4]) && b4pre;
01803   bool c4c = *(p[c4]) && c4pre;
01804   bool d4c = *(p[d4]) && d4pre;
01805   bool e4c = *(p[e4]) && e4pre;
01806   bool f4c = *(p[f4]) && f4pre;
01807   bool g4c = *(p[g4]) && g4pre;
01808   bool h4c = *(p[h4]) && h4pre;
01809   bool i4c = *(p[i4]) && i4pre;
01810   bool j4c = *(p[j4]) && j4pre;
01811   bool k4c = *(p[k4]) && k4pre;
01812   bool l4c = *(p[l4]) && l4pre;
01813   bool m4c = *(p[m4]) && m4pre;
01814   bool n4c = *(p[n4]) && n4pre;
01815   bool o4c = *(p[o4]) && o4pre;
01816   bool p4c = *(p[p4]) && p4pre;
01817   bool q4c = *(p[q4]) && q4pre;
01818   bool r4c = *(p[r4]) && r4pre;
01819   bool s4c = *(p[s4]) && s4pre;
01820   bool t4c = *(p[t4]) && t4pre;
01821   bool u4c = *(p[u4]) && u4pre;
01822   bool v4c = *(p[v4]) && v4pre;
01823   bool w4c = *(p[w4]) && w4pre;
01824   bool x4c = *(p[x4]) && x4pre;
01825   bool y4c = *(p[y4]) && y4pre;
01826 
01827   *roadfound = a4c || b4c || c4c || d4c || e4c || f4c || g4c || h4c || i4c || j4c || k4c || l4c || m4c 
01828                    || n4c || o4c || p4c || q4c || r4c || s4c || t4c || u4c || v4c || w4c || x4c || y4c;
01829   
01830   // Find shower size.
01831   // =================
01832   static const short nInShower = 5;
01833   static const short nShowerSums = 25;
01834   bool st[nShowerSums+nInShower-1];
01835   st[0]  = *(p[aaa4]) && a4pre;
01836   st[1]  = *(p[aa4])  && b4pre;
01837   st[2]  = *(p[a4])   && c4pre;
01838   st[3]  = *(p[b4])   && d4pre;
01839   st[4]  = *(p[c4])   && e4pre;
01840   st[5]  = *(p[d4])   && f4pre;
01841   st[6]  = *(p[e4])   && g4pre;
01842   st[7]  = *(p[f4])   && h4pre;
01843   st[8]  = *(p[g4])   && i4pre;
01844   st[9]  = *(p[h4])   && j4pre;
01845   st[10] = *(p[i4])   && k4pre;
01846   st[11] = *(p[j4])   && l4pre;
01847   st[12] = *(p[k4])   && m4pre;
01848   st[13] = *(p[l4])   && m4pre;
01849   st[14] = *(p[m4])   && m4pre;
01850   st[15] = *(p[n4])   && m4pre;
01851   st[16] = *(p[o4])   && m4pre;
01852   st[17] = *(p[p4])   && n4pre;
01853   st[18] = *(p[q4])   && o4pre;
01854   st[19] = *(p[r4])   && p4pre;
01855   st[20] = *(p[s4])   && q4pre;
01856   st[21] = *(p[t4])   && r4pre;
01857   st[22] = *(p[u4])   && s4pre;
01858   st[23] = *(p[v4])   && t4pre;
01859   st[24] = *(p[w4])   && u4pre;
01860   st[25] = *(p[x4])   && v4pre;
01861   st[26] = *(p[y4])   && w4pre;
01862   st[27] = *(p[z4])   && x4pre;
01863   st[28] = *(p[zz4])  && y4pre;
01864   
01865   *showermax = 0;
01866   for (short i = 0; i < nShowerSums; i++) {
01867     short shower = (short) bsum(&st[i], nInShower);
01868     if (shower > *showermax)
01869       *showermax = shower;
01870   }
01871 
01872   return;
01873 }
01874 
01876 
01877 short 
01878 mMuiFastRoadFinder::bsum (bool *st, long n) 
01879 {
01880   short sum = 0;
01881   for (short i = 0; i < n; i++) {
01882     if (st[i])
01883       sum++;
01884   }
01885   return sum;
01886 }
01887 
01888 
01889 
01890 
01891 

MUIOO: PHENIX Muon Identifier Analysis Framework. Documentation by doxygen
Last modified: