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

mMuiRoadFinder1.cxx

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <cmath>
00003 
00004 #include "PHNode.h"
00005 #include "PHCompositeNode.h"
00006 #include "PHDataNode.h"
00007 #include "PHIODataNode.h"
00008 #include "PHNodeIterator.h"
00009 
00010 #include "mMuiRoadFinder1.h"
00011 #include "utiLineFit.h"
00012 #include "TMuiRoadOGroup.h"
00013 #include "MuiGeomClasses.hh"
00014 
00015 #include <list>
00016 #include <algorithm>
00017 #include <vector>
00018 
00019 //MUIOO interfaces
00020 #include <TMutNode.h>
00021 
00022 struct muioo_cluster_distance
00023 {
00024   TMuiClusterMapO::pointer pCluster;
00025   float distance;
00026 };
00027 
00028 class muioo_cluster_distance_sort{  //sort in order of distance
00029 public:
00030   bool operator() (const muioo_cluster_distance&, const muioo_cluster_distance&) const;
00031 };
00032 
00033 bool muioo_cluster_distance_sort::operator()(const muioo_cluster_distance& a, const muioo_cluster_distance& b) const
00034 {
00035   if(a.distance<b.distance) return true;
00036   if(a.distance>b.distance) return false;
00037   if(a.distance==b.distance){
00038     if(a.distance<b.distance) return true;
00039   }
00040   return false;
00041 }
00042 
00043 
00044 // Default constructor and destructor to pacify CINT
00045 mMuiRoadFinder1::mMuiRoadFinder1() :
00046    _roadmap(0),
00047    _road1dmap(0),
00048    _clustermap(0),
00049    _timer( PHTimeServer::get()->insert_new("mMuiRoadFinder1") )
00050 
00051 {
00052   name = "mMuiRoadFinder1";
00053 }
00054 
00055 mMuiRoadFinder1::~mMuiRoadFinder1(){}
00056 
00057 PHBoolean
00058 mMuiRoadFinder1::event(PHCompositeNode *top_node) {
00059 
00060   _timer.get()->restart();
00061 
00062 #ifdef MUIOO_DEBUG
00063   cout<<"Begin mMuiRoadFinder1."<<endl;
00064 #endif
00065   set_interface_ptrs(top_node);
00066 
00067   find_1droads();
00068 
00069   cut_1droads();
00070 
00071   find_2droads();
00072 
00073   flag_golden();
00074   
00075 #ifdef MUIOO_DEBUG  
00076   TMui1DRoadMapO::iterator iroad = _road1dmap->get(0);
00077   cout<<" Finished road finding with "<< iroad.count() << " 1d roads.\n";  
00078   while(TMui1DRoadMapO::pointer roadptr = iroad.next())
00079   {
00080     roadptr->get()->print();
00081   }
00082 
00083   TMuiRoadMapO::iterator iroad2 = _roadmap->get(0);
00084   cout<<" Finished road finding with "<< iroad2.count() << " 2d roads.\n";
00085   while(TMuiRoadMapO::pointer roadptr = iroad2.next())
00086   {
00087     roadptr->get()->print();
00088   }
00089 #endif
00090 
00091   _timer.get()->stop();
00092   return 0;
00093 }
00094 
00095 PHBoolean
00096 mMuiRoadFinder1::cut_1droads()
00097 {
00098   for(int iArm = 0; iArm < TMuiChannelId::kArmsTotal; iArm++)
00099   {
00100   //Now we have a list of roads tracked all the way through the
00101   //detector. Before we add them to the 1D Road Container
00102   //perform all the 1DRoad Cuts except the Duplicate cut.
00103 
00104 
00105     TMui1DRoadMapO::iterator iRoad1 = _road1dmap->get(iArm);
00106 
00107     while(TMui1DRoadMapO::pointer pRoad1 = iRoad1.next())
00108     {
00109 
00110       // Ok we found a road already, we need to know
00111       // whether we should save it or not
00112       // check road quality...
00113       //
00114 #ifdef MUIOO_DEBUG
00115       cout<<"Checking Road: "<<endl;
00116       pRoad1->get()->print();
00117 #endif
00118       // 1. last plane of the road
00119       bool LastPlaneOK = false;
00120       if ( pRoad1->get()->get_depth() >= _mod_par->get_min_last_gap_1d() )
00121       {
00122         LastPlaneOK = true;
00123       }
00124 
00125       // 2. positon at reference plane
00126       bool VertexCutOK = false;
00127 
00128       TMutFitPar roadfit = pRoad1->get()->get_fit_par();
00129      if(pRoad1->get()->get_orientation()==0)
00130       {
00131         if ( fabs(roadfit.get_y()) <= _mod_par->get_max_yref_1d() )
00132         {
00133           VertexCutOK = true;
00134         }
00135       } else {
00136         if ( fabs(roadfit.get_x()) <= _mod_par->get_max_xref_1d() )
00137         {
00138           VertexCutOK = true;
00139         }
00140       }
00141 
00142      // 3. number of gaps contain hits
00143      bool FiredGapsOK = false;
00144 #ifdef MUIOO_DEBUG
00145      cout<<"Testing FiredGaps: G "
00146          << pRoad1->get()->get_gapbit()
00147        << " N " << pRoad1->get()->get_numfired() <<endl;
00148 #endif
00149       if ( pRoad1->get()->get_numfired() > _mod_par->get_min_fired_gaps())
00150       {
00151         FiredGapsOK = true;
00152       }
00153 
00154       // Here is our criteria for a candidate road
00155       // at this stage.
00156       // i.e. 1) There are at least two gaps containing hits
00157       //      2) LastPlane of the road passes last plane cut
00158       //      3) Reference position passes vertex cut
00159 
00160 
00161       // At this point we are only cutting exact duplicates
00162       // resulting from the multiple seed loops
00163 
00164       if ( LastPlaneOK && VertexCutOK&& FiredGapsOK ){
00165         int NumHits1 = 0;
00166         int NumHits2 = 0;
00167         TMui1DRoadMapO::iterator iRoad2 = iRoad1;
00168         while(TMui1DRoadMapO::pointer pRoad2 = iRoad2.next()){
00169           if(pRoad1->get()->get_orientation() != pRoad2->get()->get_orientation()){
00170             continue;
00171           }
00172           TMuiClusterMapO::const_key_iterator iclust1
00173             =pRoad1->get()->get_associated<TMuiClusterO>();
00174           TMuiClusterMapO::const_key_iterator iclust2
00175             =pRoad2->get()->get_associated<TMuiClusterO>();
00176           
00177           NumHits1 = iclust1.count();
00178           NumHits2 = iclust2.count();
00179           
00180           if(NumHits1!=NumHits2){
00181             continue;
00182           }
00183           short SharedHits1D = 0;  
00184           while(TMuiClusterMapO::const_pointer clust1 = iclust1.next()){
00185 #ifdef MUIOO_DEBUG
00186             clust1->get()->get_key().print();
00187 #endif
00188             iclust2.reset(); 
00189             while(TMuiClusterMapO::const_pointer clust2 = iclust2.next()){
00190 #ifdef MUIOO_DEBUG
00191               clust2->get()->get_key().print();
00192 #endif
00193               if(clust1->get()->get_key()==clust2->get()->get_key()) {
00194                 SharedHits1D++;
00195               }
00196             }
00197           }
00198 #ifdef MUIOO_DEBUG          
00199           if(pRoad1->get()->get_panel()==pRoad1->get()->get_panel()){
00200             cout<<"Checked for duplicate: SharedHits("<<SharedHits1D<<") "
00201                 <<NumHits1<<"/"<<NumHits2<<endl;
00202             pRoad1->get()->print();
00203             pRoad2->get()->print();         
00204           }
00205 #endif          
00206           if(SharedHits1D==NumHits1){
00207 #ifdef MUIOO_DEBUG
00208             cout<<"Duplicate road found with "<<SharedHits1D<<" shared hits"<<endl;
00209             pRoad1->get()->print();
00210             pRoad2->get()->print();
00211 #endif
00212             // Instead of erasing now.  Lets flagit by
00213             // setting its depth to 0.
00214             // Later we'll come back and erase all.
00215             pRoad2->get()->set_depth(0);
00216           }// if SharedHits1D==NumHits1
00217         }//while(pRoad2
00218       }else{//if(VtxOk ...)
00219 #ifdef MUIOO_DEBUG        
00220         cout<<"Cutting 1d road: " << "LastPlaneOK "<<LastPlaneOK
00221             <<" VertexCutOK " << VertexCutOK
00222             <<" FiredGapsOK " <<FiredGapsOK
00223             <<endl;
00224 #endif
00225         // Instead of erasing now.  Lets flagit by
00226         // setting its depth to 0.
00227         // Later we'll come back and erase all.
00228         pRoad1->get()->set_depth(0);
00229       }
00230       
00231     }//while(pRoad1
00232     iRoad1 = _road1dmap->get(iArm);
00233     while(TMui1DRoadMapO::pointer pRoad1 = iRoad1.next())
00234     {
00235       if(pRoad1->get()->get_depth()==0)
00236       {
00237         _road1dmap->erase(pRoad1->get()->get_key());
00238       }
00239     }
00240   }//for(iArm..
00241   return 0;
00242 }
00243 
00244 PHBoolean
00245 mMuiRoadFinder1::find_1droads() {
00246   
00247   // We have all of the input and output parameters now, so do
00248   // something useful with them!
00249 
00250   //
00251   // Now find some roads!
00252   //
00253 
00254   short Count0,iPlane0, iPlane1;
00255   EOrient_t orient;
00256  int rawcountperarm[2] = {0};
00257 
00258   rawcountperarm[0] = _clustermap->get(0).count();
00259   // JLN - the index below is now fixed 07/25/03
00260   rawcountperarm[1] = _clustermap->get(1).count();
00261 
00262   for (short iArm=0; iArm<TMuiChannelId::kArmsTotal; iArm++) {
00263 
00264     if(rawcountperarm[iArm]>_mod_par->get_max_occupancy_per_arm())
00265     {
00266       cout<<PHWHERE<<" Skipping analysis of arm "<<iArm<<" with too many hits "<<rawcountperarm[iArm]<<endl;
00267       continue;
00268     }
00269     
00270     for (short iorient=0; iorient<TMuiChannelId::kOrientations; iorient++){
00271 
00272       if(iorient==0)
00273         orient = kHORIZ;
00274       else
00275         orient = kVERT;
00276 
00277       for( short iLoop=0; iLoop<_mod_par->get_num_seed_loops(); iLoop++){
00278 
00279         // checkout the seed gap(s) from search order
00280         
00281         iPlane0 = _mod_par->get_search_order(iLoop,0);
00282         iPlane1 = _mod_par->get_search_order(iLoop,1);
00283 
00284         //Create a temporary list of roads for this search order.
00285         //list<TMui1DRoad*> roadList;
00286 
00287         short TotalPanel0;
00288         if (iPlane0 == -1){
00289           // one-seed-gap method, by pass iPlane0
00290           TotalPanel0 = 1;
00291         } else {
00292           // two-seed-gap method
00293           TotalPanel0 = TMuiChannelId::kPanelsPerPlane;
00294         }
00295 
00296         for (short iPanel0=0; iPanel0<TotalPanel0; iPanel0++) {
00297 
00298           TMuiClusterMapO::iterator iclust0;
00299           if (iPlane0 != -1){
00300             iclust0 = _clustermap->get(iArm,iPlane0,iPanel0,orient);
00301           }
00302           Count0 = (iPlane0 == -1)? (1) : iclust0.count();
00303           
00304           for (short idClust0=0; idClust0<Count0; idClust0++) {
00305             TMuiClusterMapO::pointer clust0ptr = iclust0.next();
00306             //iclust0->current() will either point to the first cluster or nothing
00307             
00308             for (short iPanel1=0; 
00309                  iPanel1<TMuiChannelId::kPanelsPerPlane; iPanel1++) {
00310 
00311               TMuiClusterMapO::iterator iclust1
00312                      = _clustermap->get(iArm,iPlane1,iPanel1,orient);;
00313        
00314               while(TMuiClusterMapO::pointer pC1 = iclust1.next()) {
00315           
00316                 if (!(pC1->get())) {
00317                   cout << PHWHERE << " plane " << iPlane1 
00318                        << " null pointer" << endl;
00319                 } else {
00320 
00321                   // Found seed cluster(s), create a new 1D road
00322                   // object, and attach cluster pC1 (and pC0, if 2 seed gaps)
00323 
00324                   TMui1DRoadMapO::pointer road1D = 
00325                     (_road1dmap->insert_new(iArm,iPanel1,orient)).current();
00326 
00327                   if (!(road1D->get())) {
00328                     cout << PHWHERE
00329                          << ":failed to create 1D road!"  << endl;
00330                     continue;
00331                   }
00332 
00333                   if (iPlane0 != -1 ) {
00334                     //If Two Gap seed set vertex weight to 0
00335                     PHKey::associate(road1D, clust0ptr);
00336                     road1D->get()->set_fitweight(0, 0.0);
00337                   }else{
00338                     //If One Seed gap method use vertex in fits.
00339                     road1D->get()->set_fitweight(0, 1.0);
00340                   }
00341 
00342                   PHKey::associate(road1D, pC1);
00343 #ifdef MUIOO_DEBUG
00344                   cout<<"Begin tracking seed: iLoop("<< iLoop
00345                     << ") Panel ("<<iPanel1
00346                     <<")"<<endl;
00347                   road1D->get()->print();
00348                   pC1->get()->print();
00349 #endif                  
00350                   track_seed(road1D,iLoop,2);
00351 
00352                   fit1d(road1D);                  
00353                 } // if (!pC1)
00354               }//for (iClust1)
00355             }//for(iPanel1)
00356           }//for(iClust0)
00357         }//for(iPanel0)        
00358       } //short (short iLoop ...)      
00359     } // for (short iorient ...)
00360   }  // for(iArm ...)
00361   return True;
00362 }
00363 
00364 PHBoolean
00365 mMuiRoadFinder1::find_2droads() {
00366 
00367   // We found all possible horizontal and vertical roads in both arms
00368   // and now it is time to construct 2D roads base on those 1D roads
00369   for (short iArm=0; iArm<TMuiChannelId::kArmsTotal; iArm++)
00370   {
00371     
00372     TMui1DRoadMapO::iterator iRoadH = _road1dmap->get(iArm);
00373     while(TMui1DRoadMapO::pointer pRoadH = iRoadH.next())
00374     {
00375       if(pRoadH->get()->get_orientation()==1) continue;
00376       TMui1DRoadMapO::iterator iRoadV = _road1dmap->get(iArm);
00377       while(TMui1DRoadMapO::pointer pRoadV = iRoadV.next())
00378       {
00379         if(pRoadV->get()->get_orientation()==0) continue;
00380 
00381 
00382         // What are our criteria for accepting a road
00383         // as valid?  Check them here.
00384         // 1. difference of total number clusters in vRoad and in hRoad
00385         // 2. difference of last gaps in vRoad and hRoad
00386         // 3. InterSection OK or not (if X Y clusters in each gap are
00387         //                            in same panel or overlap region)
00388         // 4. Reference position check
00389         // 5. Chisquare check
00390         // 6. Last Plane check
00391         // 7. Duplicate road check
00392 
00393         // JLN - bug fix - added fabs around the depth differenece 07/25/03
00394         bool LastGapDeltaOK = false;
00395         if (abs(pRoadH->get()->get_depth() - pRoadV->get()->get_depth()) <= _mod_par->get_max_del_last_gap() )
00396         {
00397           LastGapDeltaOK = true;
00398         }
00399         // JLN - bug fix - added fabs around the hits differenece 07/25/03
00400         bool TotalHitsDeltaOK = false;
00401         if(abs(pRoadH->get()->get_nhit() - pRoadV->get()->get_nhit()) <= _mod_par->get_max_del_total_hits() )
00402         {
00403           TotalHitsDeltaOK = true;
00404         }
00405 
00406         bool IntersectionOK = true;
00407         TMuiClusterMapO::const_key_iterator iClustH
00408           =pRoadH->get()->get_associated<TMuiClusterO>();
00409         while(TMuiClusterMapO::const_pointer pClustH = iClustH.next())
00410         {
00411           TMuiClusterMapO::const_key_iterator iClustV
00412             =pRoadV->get()->get_associated<TMuiClusterO>();
00413           while(TMuiClusterMapO::const_pointer pClustV = iClustV.next())
00414           {
00415             if(pClustH->get()->get_plane()!=pClustV->get()->get_plane())
00416             {
00417               continue;
00418             }
00419             
00420             if( !(intersectionOK(pClustH,pClustV)) ){
00421               IntersectionOK = false;
00422               break;
00423             }
00424           }
00425         }
00426 
00427         bool VertexCutOK = false;
00428         TMutFitPar fitH = pRoadH->get()->get_fit_par();
00429         TMutFitPar fitV = pRoadV->get()->get_fit_par();
00430         
00431         if ( fabs(fitH.get_y()) <= _mod_par->get_max_yref_2d() &&
00432              fabs(fitV.get_x()) <= _mod_par->get_max_xref_2d() ) VertexCutOK = true;
00433 
00434         bool ChiSquareCutOK = false;
00435         if ( fitV.get_chi_square() <= _mod_par->get_max_xchisq()
00436              &&  fitH.get_chi_square() <= _mod_par->get_max_ychisq() )
00437         {
00438           ChiSquareCutOK = true;
00439         }
00440         
00441         bool minLastGapOK = false;
00442         if (pRoadH->get()->get_depth() >= _mod_par->get_min_last_gap_2d()
00443             || pRoadV->get()->get_depth() >= _mod_par->get_min_last_gap_2d())
00444         {
00445           minLastGapOK = true;
00446         }
00447         if ( LastGapDeltaOK &&
00448              TotalHitsDeltaOK &&
00449              IntersectionOK &&
00450              VertexCutOK &&
00451              ChiSquareCutOK &&
00452              minLastGapOK
00453              ) {
00454           TMuiRoadMapO::iterator iRoad = _roadmap->insert_new(iArm);
00455           make2d(iRoad.current(),pRoadH,pRoadV);
00456         }// if(pass cuts ..
00457       } // for ( vRoad ..
00458     } // for ( hRoad ..
00459   }//for(iArm ...
00460   return 0;
00461 }
00462 
00463 int mMuiRoadFinder1::track_seed(TMui1DRoadMapO::pointer road1dptr,
00464                                 int iLoop, int iSearch)
00465 {
00466 
00467   double Win = _mod_par->get_mui_window();
00468   if(road1dptr->get()->get_associated<TMuiClusterO>().count() == 1)
00469     Win = 2.0 * Win;
00470   
00471   //Invalid iLoop
00472   if(iLoop>=_mod_par->get_num_seed_loops()) return 0;
00473 
00474   // End this recursion loop over search planes
00475   if(iSearch>=_mod_par->get_search_length(iLoop)) return 0;
00476 #ifdef MUIOO_DEBUG
00477   cout<<"Tracking seed: iLoop("<<iLoop<<") iSearch("<<iSearch<<")\n";
00478 #endif
00479   //First get list of clusters in panel
00480   // and order them by their distance from seed projection
00481   TMuiClusterMapO::iterator iclusts =
00482     _clustermap->get(road1dptr->get()->get_arm(),
00483                      _mod_par->get_search_order(iLoop, iSearch),
00484                      road1dptr->get()->get_panel(),
00485                      road1dptr->get()->get_orientation()
00486                      );
00487 
00488 
00489 
00490   fit1d(road1dptr);
00491   
00492   // Loop over all clusters in the panel
00493   // and project the road to the current panel;
00494   // if in the window append to local copy
00495   // then sort by distance
00496   std::vector<muioo_cluster_distance> clusterList;
00497   muioo_cluster_distance tmp_cd;
00498   double clust_dist = 0.0;
00499   bool clustInPanel = false;
00500 
00501   while(TMuiClusterMapO::pointer clustptr = iclusts.next())
00502 
00503   {
00504     clust_dist = ClusterDistance(road1dptr,clustptr);
00505     // JLN - this was MuidWindow, but changed to use Win (as defined above to double in case of first hit) - 07/25/03
00506     if(clust_dist < Win)
00507     {
00508       tmp_cd.distance = clust_dist;
00509       tmp_cd.pCluster = clustptr;
00510       clusterList.push_back(tmp_cd);
00511     }
00512   }
00513   
00514   // If there's no cluster found
00515   // lets look for clusters in the adjacent panels, but
00516   // continue to consider a candidate with no hit in the
00517   // current panel, ie Hardware Inefficiency
00518 #ifdef MUIOO_DEBUG
00519   cout<<"Found "<<clusterList.size()<<" in the current panel "<<endl;
00520 #endif
00521   if(clusterList.size()>0)
00522   {
00523     clustInPanel=true;
00524   }
00525 
00526   if(!clustInPanel)
00527   {
00528     for (short iPanel=0;
00529          iPanel<TMuiChannelId::kPanelsPerPlane; iPanel++) {
00530 
00531       if(!(
00532          (iPanel = ((iPanel + 1)% TMuiChannelId::kPanelsPerPlane))
00533          ||((iPanel + TMuiChannelId::kPanelsPerPlane - 1)% TMuiChannelId::kPanelsPerPlane)
00534         )) continue; //Skip non-adjacent panels
00535       
00536       TMuiClusterMapO::iterator iclustsNA =
00537         _clustermap->get(road1dptr->get()->get_arm(),
00538                          _mod_par->get_search_order(iLoop, iSearch),
00539                          iPanel,
00540                          road1dptr->get()->get_orientation()
00541                          );
00542 
00543       while(TMuiClusterMapO::pointer clustptr = iclustsNA.next())
00544       {
00545 
00546         if(!clustptr)
00547         {
00548           cout <<PHWHERE << ": null "
00549                << "cluster pointer"   << endl;
00550           break;
00551         }else{
00552 
00553           // Get the displacement of cluster pc to road1D
00554           clust_dist  = ClusterDistance(road1dptr,clustptr);
00555 
00556           // Consider all of the clusters within the window
00557           // JLN - again MuidWindow -> Win - 07/25/03
00558           if ( clust_dist < Win )
00559           {
00560             tmp_cd.pCluster=clustptr;
00561             tmp_cd.distance = clust_dist;
00562             clusterList.push_back(tmp_cd);
00563           }
00564         }//if(!pC)
00565       } //while(iClust)
00566     }//if(iPanel ...
00567   }//  if(!clustInPanel)
00568   
00569   //Let's sort the list by the distance from projection
00570   sort(clusterList.begin(), clusterList.end(), muioo_cluster_distance_sort());
00571 
00572   // First case: No clusters in any panel so go to next search gap
00573   if((!clustInPanel&& (clusterList.size()==0)))
00574   {
00575     track_seed(road1dptr , iLoop, iSearch+1);
00576   }else if(!clustInPanel)
00577   {
00578     //Second case: no clust in current panel but in adjacent
00579     // track a copy without clusters
00580     TMui1DRoadMapO::pointer new1droadptr = (_road1dmap->insert_new(road1dptr)).current();
00581 #ifdef MUIOO_DEBUG
00582     cout<<"Copied 1DRoad\n";
00583     cout<<"Original:\n";
00584     road1dptr->get()->print();
00585     cout<<"Copy:\n";
00586     new1droadptr->get()->print();
00587 #endif    
00588     track_seed(new1droadptr, iLoop, iSearch+1);
00589   }
00590 
00591   // In any case,
00592   // Loop over all clusters up to maxClustersPerGapSearch
00593   // Create a copy (if not last)
00594   // Add cluster to copy and track_seed
00595   int newRoadCount = 0;
00596   vector<muioo_cluster_distance>::iterator lastEntry =
00597     clusterList.end();
00598   lastEntry--;
00599   for(vector<muioo_cluster_distance>::iterator iClustCand = clusterList.begin();
00600       iClustCand != clusterList.end(); iClustCand++){
00601     if(iClustCand == lastEntry ||
00602        (newRoadCount == _mod_par->get_max_clusters_per_gap_search()-1)){
00603       PHKey::associate(road1dptr,(*iClustCand).pCluster);
00604       track_seed(road1dptr, iLoop, iSearch+1);
00605       break;
00606     }else{
00607       TMui1DRoadMapO::pointer new1droadptr = (_road1dmap->insert_new(road1dptr)).current();
00608 #ifdef MUIOO_DEBUG
00609       cout<<"Copied 1DRoad\n";
00610       cout<<"Original:\n";
00611       road1dptr->get()->print();
00612       cout<<"Copy:\n";
00613       new1droadptr->get()->print();
00614       return 0;
00615 #endif
00616       PHKey::associate(new1droadptr,(*iClustCand).pCluster);
00617       track_seed(road1dptr, iLoop, iSearch+1);
00618       newRoadCount++;
00619     }
00620   }
00621   clusterList.clear();
00622   return 0;
00623 }
00624 
00625 int mMuiRoadFinder1::make2d(TMuiRoadMapO::pointer cRoad,
00626                            TMui1DRoadMapO::pointer pRoadH,
00627                            TMui1DRoadMapO::pointer pRoadV)
00628 {
00629 
00630   TMutFitPar fitH = pRoadH->get()->get_fit_par();
00631   TMutFitPar fitV = pRoadV->get()->get_fit_par();
00632 
00633   TMuiClusterMapO::key_iterator iClustH
00634     =pRoadH->get()->get_associated<TMuiClusterO>();
00635   while(TMuiClusterMapO::pointer pClust = iClustH.next())
00636   {
00637     PHKey::associate(pClust, cRoad);
00638   }
00639   TMuiClusterMapO::key_iterator iClustV
00640     =pRoadV->get()->get_associated<TMuiClusterO>();
00641   while(TMuiClusterMapO::pointer pClust = iClustV.next())
00642   {
00643     PHKey::associate(pClust,cRoad);
00644   }
00645   cRoad->get()->set_nhit(pRoadH->get()->get_nhit() + pRoadV->get()->get_nhit());
00646   //Combine the FitPar of the 1D roads
00647   TMutFitPar fit2d;
00648   fit2d.set_x(fitV.get_x());
00649   fit2d.set_y(fitH.get_y());
00650   fit2d.set_z(fitH.get_z());
00651   fit2d.set_dxdz(fitV.get_dxdz());
00652   fit2d.set_dydz(fitH.get_dydz());
00653   if(pRoadV->get()->get_depth()>pRoadH->get()->get_depth())
00654   {
00655     cRoad->get()->set_depth(pRoadV->get()->get_depth());
00656     fit2d.set_z_end(fitV.get_z_end());
00657   }else{
00658     cRoad->get()->set_depth(pRoadH->get()->get_depth());
00659     fit2d.set_z_end(fitH.get_z_end());
00660   }
00661   if(abs(fitH.get_z_begin())<abs(fitV.get_z_begin()))
00662   {
00663     fit2d.set_z_begin(fitH.get_z_begin());
00664   }else{
00665     fit2d.set_z_begin(fitV.get_z_begin());
00666   }
00667   int vDOF = pRoadV->get()->get_nhit() + (int)(pRoadV->get()->get_fitweight(0)) - 2;
00668   int hDOF = pRoadH->get()->get_nhit() + (int)(pRoadH->get()->get_fitweight(0)) - 2 ;
00669   cRoad->get()->set_freedom(vDOF+hDOF);
00670   // JLN - fix bug - should be OR of H and V
00671   cRoad->get()->set_gapbit(pRoadH->get()->get_gapbit() | (pRoadV->get()->get_gapbit() << 5));
00672   Float_t chisq = 0.0;
00673   if((vDOF + hDOF) >=0) {
00674 
00675     chisq = (fitV.get_chi_square()*vDOF
00676              +fitH.get_chi_square()*hDOF
00677              )/(vDOF + hDOF);
00678   }
00679   fit2d.set_chi_square(chisq);
00680 
00681   cRoad->get()->set_fit_par(fit2d);
00682   // previously not set parameters
00683   cRoad->get()->set_road_quality(chisq);
00684   UShort_t gapmatch = pRoadH->get()->get_gapbit() & 
00685     pRoadV->get()->get_gapbit();
00686   if (gapmatch != 0) {
00687     cRoad->get()->set_max_hit_plane(2);
00688   }
00689   else {
00690     cRoad->get()->set_max_hit_plane(1);
00691   }
00692 
00693   return 0;
00694 }
00695 
00696 int mMuiRoadFinder1::fit1d(TMui1DRoadMapO::pointer road1dptr)
00697 {
00698 
00699   float z[mMuiRoadFinder1Par::NUMFITPOINTS+1]={0.0};
00700   float x[mMuiRoadFinder1Par::NUMFITPOINTS+1]={0.0};
00701   float w[mMuiRoadFinder1Par::NUMFITPOINTS+1]={0.0};
00702   int npoints = 0;
00703   float slope = 0.0,
00704     intercept = 0.0,
00705     chisq = 0.0,
00706     sigma_slope = 0.0,
00707     sigma_intercept = 0.0,
00708     hit_zmin = 1E10,
00709     hit_zmax = 0.0;
00710 
00711   z[npoints] = _mod_par->get_zvert();
00712   x[npoints] = (road1dptr->get()->get_orientation()==0)
00713                  ? _mod_par->get_yvert() : _mod_par->get_xvert();
00714   w[npoints] = _mod_par->get_weight_par_1d(0);
00715   npoints++;
00716   
00717   TMuiClusterMapO::const_key_iterator iclust
00718      =road1dptr->get()->get_associated<TMuiClusterO>();
00719 #ifdef MUIOO_DEBUG
00720   cout << "mMuiRoadFinder1::fit1d" <<endl;
00721   road1dptr->get()->print();
00722   cout << "Associated cluster count("
00723        << iclust.count() <<")"<<endl;
00724 #endif 
00725   road1dptr->get()->set_nhit(iclust.count());
00726   
00727   while(TMuiClusterMapO::const_pointer clustptr = iclust.next())
00728   {
00729     PHPoint centroid = clustptr->get()->get_centroidpos();
00730     PHPoint sigma = clustptr->get()->get_centroidsigma();
00731     road1dptr->get()->set_gapbit( road1dptr->get()->get_gapbit() | (0x1<<clustptr->get()->get_plane()));
00732 
00733     if(road1dptr->get()->get_depth() < clustptr->get()->get_plane())
00734     {
00735       road1dptr->get()->set_depth(clustptr->get()->get_plane());
00736     }
00737       
00738     z[npoints]  = centroid.getZ();
00739     if(abs(z[npoints])<abs(hit_zmin))
00740     {
00741       hit_zmin = z[npoints];
00742     }
00743     if(abs(z[npoints])>abs(hit_zmax))
00744     {
00745       hit_zmax = z[npoints];
00746     }
00747     if (road1dptr->get()->get_orientation() == 0) {
00748       x[npoints] = centroid.getY();
00749       w[npoints] = 1.0/(sigma.getY()*sigma.getY());
00750     } else {
00751       x[npoints] = centroid.getX();
00752       w[npoints] = 1.0/(sigma.getX()*sigma.getX());
00753     }
00754     npoints++;
00755     if(npoints>6) break;
00756   }
00757 
00758   // DS: kludge to remove vertex point from fit if we have enough points to make a line without it
00759   if (npoints > 2) {
00760     for (int ipoint = 1; ipoint<npoints; ipoint++) {
00761       x[ipoint-1] = x[ipoint];
00762       z[ipoint-1] = z[ipoint];
00763       w[ipoint-1] = w[ipoint];
00764     }
00765     npoints--;
00766   }
00767   // end kludge
00768 
00769   int status = utiLineFit(z,x,w,npoints,&slope,&intercept,&chisq,
00770                           &sigma_slope,&sigma_intercept);
00771   if(status!= 0 )
00772   {
00773     cout<<PHWHERE<<" Unable to fit MuID road." << endl;
00774     return -1;
00775   }
00776   double dydz, dxdz, xint, yint;
00777   if (road1dptr->get()->get_orientation() == 0)
00778   {
00779     dydz = slope;
00780     dxdz = 0.0;
00781     yint = intercept;
00782     xint = 0.0;
00783   } else {
00784     dydz = 0.0;
00785     dxdz = slope;
00786     yint = 0.0;
00787     xint = intercept;
00788   }
00789   TMutFitPar fitpar1d(xint,yint,0.0,dxdz,dydz,chisq);
00790   fitpar1d.set_z_begin(hit_zmin);
00791   fitpar1d.set_z_end(hit_zmax);
00792   road1dptr->get()->set_fit_par(fitpar1d);
00793   
00794   return 0;
00795 }
00796 
00797 double mMuiRoadFinder1::ClusterDistance(TMui1DRoadMapO::pointer road1dptr, TMuiClusterMapO::pointer clustptr)
00798 {
00799   PHVector dirV = road1dptr->get()->get_fit_par().get_tangent();
00800   dirV.normalize();
00801   PHPoint panelX
00802   = TMuiGeometry::Geom()->FindIntersection(
00803                                            road1dptr->get()->get_arm(),
00804                                            clustptr->get()->get_plane(),
00805                                            clustptr->get()->get_panel(),
00806                                            road1dptr->get()->get_fit_par().get_point(),
00807                                            dirV
00808                                            );
00809 
00810   double distance = (road1dptr->get()->get_orientation()==0)
00811     ? abs(panelX.getY() - clustptr->get()->get_centroidpos().getY())
00812     : abs(panelX.getX() - clustptr->get()->get_centroidpos().getX());
00813 
00814   return distance;
00815 }
00816 
00817 void mMuiRoadFinder1::set_interface_ptrs(PHCompositeNode* top_node)
00818 {
00819   // module runtime parameters
00820   try {
00821     _mod_par = TMutNode<mMuiRoadFinder1Par>::find_node(top_node,"mMuiRoadFinder1Par");
00822   }
00823   catch(std::exception& e){
00824     MUIOO::TRACE(e.what());
00825     return;
00826   }
00827 
00828   //Find the TMuiRoadO IOC
00829   try{
00830     _roadmap = TMutNode<TMuiRoadMapO>::find_node(top_node,"TMuiRoadMapO");
00831   } catch(std::exception& e){
00832 MUIOO::TRACE(e.what());
00833     return;
00834 //    TMutNode<TMuiRoadMapO>::new_node(muiNode,"TMuiRoadMapO");
00835 //    _roadmap = TMutNode<TMuiRoadMapO>::find_node(muiNode,"TMuiRoadMapO");
00836 //    _roadmap->make_persistent(dstNode,"TMuiRoadO");
00837   }
00838 
00839   //Find the TMui1DRoadO IOC
00840   try{
00841     _road1dmap = TMutNode<TMui1DRoadMapO>::find_node(top_node,"TMui1DRoadMapO");
00842   } catch(std::exception& e){
00843 MUIOO::TRACE(e.what());
00844     return;
00845 //    TMutNode<TMui1DRoadMapO>::new_node(muiNode,"TMui1DRoadMapO");
00846 //    _road1dmap = TMutNode<TMui1DRoadMapO>::find_node(muiNode,"TMui1DRoadMapO");
00847 //    _road1dmap->make_persistent(dstNode,"TMui1DRoadO");
00848   }
00849 
00850   //Find the new TMuiClusterO IOC
00851   try{
00852     _clustermap = TMutNode<TMuiClusterMapO>::find_node(top_node,"TMuiClusterMapO");
00853   } catch(std::exception& e){
00854 MUIOO::TRACE(e.what());
00855     return;
00856  //   TMutNode<TMuiClusterMapO>::new_node(muiNode,"TMuiClusterMapO");
00857  //   _clustermap = TMutNode<TMuiClusterMapO>::find_node(muiNode,"TMuiClusterMapO");
00858  //   _clustermap->make_persistent(dstNode,"TMuiClusterO");
00859   }
00860   
00861 }
00862 
00863 bool mMuiRoadFinder1::intersectionOK(TMuiClusterMapO::const_pointer clustH,
00864                                      TMuiClusterMapO::const_pointer clustV) const
00865 {
00866   TMuiGeometry* geom = TMuiGeometry::Geom();
00867   // Is the intersection point inside the panel(s) containing the H and
00868   // V clusters?
00869   TMuiPanelGeo* ph = geom->getPanel(clustH->get()->get_arm(),
00870                                     clustH->get()->get_plane(),
00871                                     clustH->get()->get_panel());
00872   TMuiPanelGeo* pv = geom->getPanel(clustV->get()->get_arm(),
00873                                     clustV->get()->get_plane(),
00874                                     clustV->get()->get_panel());
00875 
00876   PHPoint hpoint = clustH->get()->get_centroidpos();
00877   PHPoint vpoint = clustV->get()->get_centroidpos();
00878 
00879   PHPoint h1_local = ph->TransformToPanel(hpoint);
00880   PHPoint v1_local = ph->TransformToPanel(vpoint);
00881 
00882   PHPoint h2_local = pv->TransformToPanel(hpoint);
00883   PHPoint v2_local = pv->TransformToPanel(vpoint);
00884 
00885   return (ph->IsInPanel(v1_local.getX(), h1_local.getY(), 0.0) &&
00886           pv->IsInPanel(v2_local.getX(), h2_local.getY(), 0.0)   );
00887   
00888 }
00889 
00890 int mMuiRoadFinder1::flag_golden()
00891 {
00892   //Loop over arms
00893   for (short iArm=0; iArm<TMuiChannelId::kArmsTotal; iArm++)
00894   {
00895     // Reject ghost by grouping the roads
00896     vector<TMuiRoadOGroup*> pGroup;
00897     vector<TMuiRoadOGroup*>::iterator ig;
00898     
00899     TMuiRoadOGroup* iGroup;
00900     TMuiRoadMapO::iterator iRoad = _roadmap->get(iArm);
00901     while(TMuiRoadMapO::pointer road2D = iRoad.next())
00902     {
00903       bool InGroup = false;
00904       iGroup=NULL;
00905       for(ig=pGroup.begin();ig!=pGroup.end();ig++){
00906         if ((*ig)->IsGroup(road2D)){
00907           if(!InGroup)
00908           {
00909             //This is the first group associated with the road
00910             (*ig)->AttachRoad(road2D);
00911             iGroup = (*ig);
00912           }else{
00913             // This road has already been associated with a road
00914             // Instead of adding it to two groups lets merge this into the first
00915             // then remove the first group
00916             // cout<<"Merging MuidGroups ..."<<endl;
00917             iGroup->MergeGroup(*ig);
00918             TMuiRoadOGroup* removedGroup = (*ig);
00919             delete removedGroup;  // Delete the new TMuiRoadOGroup object
00920             pGroup.erase(ig);  // Remove the Group pointer from the list.
00921             ig--; // Decrement the iterator since erase incremented
00922           }
00923           InGroup = true;
00924         }
00925       }
00926       if( !InGroup){
00927         // This road doesn't belong to any group, create a new group
00928         float MutrZ;
00929         if(iArm == 0){
00930           MutrZ = _mod_par->get_mut_z_south();
00931         } else {
00932           MutrZ = _mod_par->get_mut_z_north();
00933         }
00934         iGroup = new TMuiRoadOGroup(iArm,MutrZ,_mod_par->get_mut_window(),_mod_par->get_mui_window());
00935         iGroup->AttachRoad(road2D);
00936         pGroup.push_back(iGroup);
00937       }
00938     }
00939     
00940 #ifdef MUIOO_DEBUG
00941   cout<<PHWHERE<<" Mark Golden Roads"<< endl;
00942 #endif
00943 
00944     // set group index and golden mark for each road object
00945     // The golden flags are saved in the TMui2DRoads
00946     short ngroup = pGroup.size();
00947     for(short i=0; i<ngroup; i++){
00948       iGroup = pGroup[i];
00949       iGroup->SetGroup(i);
00950     }
00951 
00952 #ifdef MUIOO_DEBUG
00953     cout<<PHWHERE<<" Destroy Group Objects"<< endl;
00954 #endif
00955 
00956     // destroy the all group objects
00957     for(short i=0; i<ngroup; i++){
00958       delete pGroup[i];
00959     }
00960 
00961   }//for(iArm...
00962   return 0;
00963 }
00964 

MUIOO: PHENIX Muon Identifier Analysis Framework. Documentation by doxygen

James L. Nagle, Los Alamos National Laboratory
David Silvermyr, University of Colorado
Last modified: