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

mMuiClusterFinder.cxx

Go to the documentation of this file.
00001 #include <iostream>
00002 #include "PHNode.h"
00003 #include "PHIODataNode.h"
00004 #include "PHNodeIterator.h"
00005 
00006 #include "mMuiClusterFinder.h"
00007 
00008 typedef PHIODataNode<PHTable> TableNode_t;
00009 // STL hit list iterator
00010 typedef list<TMuiHitO>::iterator hit_list_iterator;
00011 
00013 mMuiClusterFinder::mMuiClusterFinder():
00014   _timer( PHTimeServer::get()->insert_new("mMuiClusterFinder") )
00015   {}
00016 
00018 mMuiClusterFinder::~mMuiClusterFinder(){}
00019 
00021 PHBoolean
00022 mMuiClusterFinder::event(PHCompositeNode *top_node)
00023 {
00024   _timer.get()->restart();
00025   try {     
00026     // Reset IOC pointers
00027     //
00028     set_interface_ptrs(top_node);
00029     
00030     // Associate groups of contiguous hits with 
00031     // TMutClus objects
00032     //
00033     find_clusters();
00034         
00035   } catch(std::exception& e) {
00036     MUIOO::TRACE(e.what());
00037     return False;
00038   }
00039   _timer.get()->stop();  
00040   return True;  
00041 }
00042 
00044 void
00045 mMuiClusterFinder::set_interface_ptrs(PHCompositeNode* top_node)
00046 {
00047    // module runtime parameters
00048   _mod_par = TMutNode<mMuiClusterFinderPar>::find_node(top_node,"mMuiClusterFinderPar");
00049 
00050   //Find the new TMuiHitO objects
00051   _muihitmap = TMutNode<TMuiHitMapO>::find_node(top_node,"TMuiHitMapO");
00052 
00053   //Find the new TMuiClusterO objects
00054   _muiclustermap = TMutNode<TMuiClusterMapO>::find_node(top_node,"TMuiClusterMapO");
00055 
00056   return;
00057 }
00058 
00059 /* Find clusters from raw hits */
00060 void
00061 mMuiClusterFinder::find_clusters()
00062 {
00063   // ===================================================================
00064   // Find clusters and fill the cluster container.
00065   // ===================================================================
00066   
00067   // For now just one hit per cluster
00068   // Let's make it optional though, to merge isolated neighboring hits into single clusters
00069   for (short arm=0; arm<TMuiChannelId::kArmsTotal; arm++) {    
00070     for (short plane=0; plane<TMuiChannelId::kPlanesPerArm; plane++) {
00071       for (short panel=0; panel<TMuiChannelId::kPanelsPerPlane; panel++) {
00072 
00073         //Lets get a pointer to this panel's geometry object
00074         TMuiChannelId pPanelId(arm,plane,panel);
00075         TMuiPanelGeo* fpMuiPanelGeo   = TMuiGeometry::Geom()->getPanel(pPanelId);
00076         
00077         for (short orient=0; orient<TMuiChannelId::kOrientations; orient++) {
00078           
00079           TMuiHitMapO::iterator hit_iter = _muihitmap->get(arm,plane,panel,orient);
00080           while(TMuiHitMapO::pointer hit_ptr = hit_iter.next()) {
00081             if (_mod_par->get_clustering_mode() == mMuiClusterFinderPar::NONE) {
00082               // no clustering, just make each hit into its own cluster
00083               make_new_cluster(hit_ptr);
00084             }
00085             else {
00086               // iterator to all clusters with same location as hit
00087               TMuiClusterMapO::iterator clus_iter = _muiclustermap->get(arm, plane, panel, orient);
00088               bool hit_is_added = false;
00089               while(TMuiClusterMapO::pointer clus_ptr = clus_iter.next()){
00090                 if (!hit_is_added || _mod_par->get_clustering_mode() == mMuiClusterFinderPar::NORMAL)
00091                   { // in the 'NORMAL' mode, we can try to add the hit to as many clusters as possible
00092                     // attempt to add hit to cluster
00093                     hit_is_added = associate_hit(clus_ptr,hit_ptr); 
00094                   }
00095               }
00096               // hit was not associated with existing cluster so make
00097               // a new cluster and associate this hit
00098               if(!hit_is_added){
00099                 make_new_cluster(hit_ptr);
00100               }
00101             }            
00102           }//loop over hits in panel/orient
00103 
00104           // Now, the clustering is done. Let's calculate the positions if we found any
00105           TMuiClusterMapO::iterator clus_iter = _muiclustermap->get(arm, plane, panel, orient);
00106           while(TMuiClusterMapO::pointer clus_ptr = clus_iter.next()){
00107             calc_position(clus_ptr, fpMuiPanelGeo);
00108           }
00109 
00110         }//orient
00111       }//panel
00112     }//plane
00113   }//arm
00114   
00115   return;
00116 }
00117 
00123 bool
00124 mMuiClusterFinder::associate_hit(TMuiClusterMapO::pointer clus_ptr, 
00125                                  TMuiHitMapO::pointer hit_ptr)
00126 {  
00127   // iterator to hits associated with this cluster
00128   //
00129   TMuiHitMapO::key_iterator hit_iter = 
00130     clus_ptr->get()->get_associated<TMuiHitO>();
00131   
00132   // loop over associated hits
00133   //
00134   while(TMuiHitMapO::pointer clus_hit_ptr = hit_iter.next()){
00135 
00136     UShort_t distance = std::abs(clus_hit_ptr->get()->get_twopack() - 
00137                                  hit_ptr->get()->get_twopack()); 
00138     if(distance == 1) {
00139       // strips are adjacent so associate hit with cluster
00140       //      
00141       PHKey::associate(hit_ptr,clus_ptr);
00142       return true;
00143     }
00144   }
00145   // hit was not associated return false
00146   //
00147   return false;
00148 }
00149 
00153 void
00154 mMuiClusterFinder::calc_position(TMuiClusterMapO::pointer clus_ptr,
00155                                  TMuiPanelGeo *fpMuiPanelGeo)
00156 {  
00157   // iterator to hits associated with this cluster
00158   //
00159   TMuiHitMapO::key_iterator hit_iter = 
00160     clus_ptr->get()->get_associated<TMuiHitO>();
00161   
00162   // loop over associated hits and get their positions
00163   //
00164   PHVector clpos;
00165   PHVector clerr;
00166   int clnhit = 0;
00167   EOrient_t orient = kHORIZ;
00168   while(TMuiHitMapO::pointer clus_hit_ptr = hit_iter.next()){
00169     
00170     TMuiChannelId pTPID(clus_hit_ptr->get()->get_arm(),
00171                         clus_hit_ptr->get()->get_plane(),
00172                         clus_hit_ptr->get()->get_panel(),
00173                         (EOrient_t)clus_hit_ptr->get()->get_orientation(),
00174                         clus_hit_ptr->get()->get_twopack());
00175 
00176     orient = (EOrient_t)clus_hit_ptr->get()->get_orientation();
00177     TMuiTwoPackGeo* fpMuiTwoPackGeo = TMuiGeometry::Geom()->getTwoPack(pTPID);
00178     
00179     //Now we need to find the centroid of this tube
00180     if (fpMuiPanelGeo && fpMuiTwoPackGeo) {
00181       float x, y, z, sx, sy, sz;
00182       
00183       fpMuiTwoPackGeo->CenterPos(x, y, z);
00184       fpMuiTwoPackGeo->CenterSigma(sx, sy, sz);
00185       PHVector pos(x, y, z);
00186       PHVector sigma(sx, sy, sz);
00187       PHVector fCentroidPos = fpMuiPanelGeo->TransformToGlobal(pos);
00188       PHVector fCentroidErr = fpMuiPanelGeo->RotateToGlobal(sigma);
00189 
00190       clpos = clpos + fCentroidPos;
00191       clerr = clerr + fCentroidErr;
00192       clnhit++;
00193     }
00194   }
00195 
00196   if (clnhit > 0)
00197     {
00198       clpos = clpos * (1.0/clnhit);
00199       // we should scale the error also
00200       // if vert., the values/errors are the same for the two-packs in y,z 
00201       // if horiz., the values/errors are the same for the two-packs in x,z 
00202       //
00203       if (orient == kHORIZ)
00204         { // horizontal, don't scale y-value
00205           clerr.setX(clerr.getX() *( 1.0/clnhit) );
00206           clerr.setZ(clerr.getZ() *( 1.0/clnhit) );
00207         }
00208       else
00209         { // vertical, don't scale x-value
00210           clerr.setY(clerr.getY() *( 1.0/clnhit) );
00211           clerr.setZ(clerr.getZ() *( 1.0/clnhit) );
00212         }
00213       clus_ptr->get()->set_centroidpos(PHPoint(clpos));
00214       clus_ptr->get()->set_centroidsigma(PHPoint(clerr));
00215       clus_ptr->get()->set_size(clnhit);
00216 
00217       // figure out what the start and end points are also
00218       // using the centroid and sigma info
00219       //
00220       PHPoint startpoint = PHPoint(clpos);
00221       PHPoint endpoint = startpoint;
00222       // from sigma to total range of uncertainty: sqrt(12) conv. factor
00223       // and then we want half the length
00224       double convfactor = sqrt(12.0)*0.5;
00225       PHPoint diff = PHPoint(clerr)*convfactor;
00226 
00227       //
00228       if (orient == kHORIZ)
00229         { // horizontal
00230           startpoint.setX(startpoint.getX() - diff.getX());
00231           endpoint.setX(endpoint.getX() + diff.getX());
00232         }
00233       else
00234         { // vertical
00235           startpoint.setY(startpoint.getY() - diff.getY());
00236           endpoint.setY(endpoint.getY() + diff.getY());
00237         }
00238       // and store the values
00239       clus_ptr->get()->set_coord_end(endpoint);
00240       clus_ptr->get()->set_coord_begin(startpoint);
00241     }
00242   else
00243     { // couldn't locate coordinates of any hits.
00244       // That must be bad. We might as well remove this cluster
00245       _muiclustermap->erase(clus_ptr->get()->get_key());
00246     }
00247   return;
00248 }
00249 
00250 void
00251 mMuiClusterFinder::make_new_cluster(TMuiHitMapO::pointer hit_ptr)  
00252 {
00253   // make a new cluster with same location as hit
00254   //
00255   TMuiClusterMapO::iterator clus_iter = 
00256     _muiclustermap->insert_new(hit_ptr->get()->get_arm(),
00257                                hit_ptr->get()->get_plane(),
00258                                hit_ptr->get()->get_panel(),
00259                                hit_ptr->get()->get_orientation());
00260   
00261   // Associate new cluster with hit
00262   //
00263   PHKey::associate(hit_ptr,clus_iter.current());
00264 }
00265 
00269 void mMuiClusterFinder::apply_cluster_cuts()
00270 {
00271   TMuiClusterMapO::iterator clus_iter = _muiclustermap->range();
00272   while(TMuiClusterMapO::pointer clus_ptr = clus_iter.next()){
00273     
00274     // If cluster contains less than the required number of
00275     // strips remove from map
00276     //
00277     if(clus_ptr->get()->get_size() < _mod_par->get_min_cluster_width() ) {
00278       _muiclustermap->erase(clus_ptr->get()->get_key());
00279       continue;
00280     }
00281     
00282     if(clus_ptr->get()->get_size() > _mod_par->get_max_cluster_width() ) {
00283       _muiclustermap->erase(clus_ptr->get()->get_key());
00284       continue;
00285     }
00286   }
00287 }

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