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 
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     
00027     
00028     set_interface_ptrs(top_node);
00029     
00030     
00031     
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    
00048   _mod_par = TMutNode<mMuiClusterFinderPar>::find_node(top_node,"mMuiClusterFinderPar");
00049 
00050   
00051   _muihitmap = TMutNode<TMuiHitMapO>::find_node(top_node,"TMuiHitMapO");
00052 
00053   
00054   _muiclustermap = TMutNode<TMuiClusterMapO>::find_node(top_node,"TMuiClusterMapO");
00055 
00056   return;
00057 }
00058 
00059 
00060 void
00061 mMuiClusterFinder::find_clusters()
00062 {
00063   
00064   
00065   
00066   
00067   
00068   
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         
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               
00083               make_new_cluster(hit_ptr);
00084             }
00085             else {
00086               
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                   { 
00092                     
00093                     hit_is_added = associate_hit(clus_ptr,hit_ptr); 
00094                   }
00095               }
00096               
00097               
00098               if(!hit_is_added){
00099                 make_new_cluster(hit_ptr);
00100               }
00101             }            
00102           }
00103 
00104           
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         }
00111       }
00112     }
00113   }
00114   
00115   return;
00116 }
00117 
00123 bool
00124 mMuiClusterFinder::associate_hit(TMuiClusterMapO::pointer clus_ptr, 
00125                                  TMuiHitMapO::pointer hit_ptr)
00126 {  
00127   
00128   
00129   TMuiHitMapO::key_iterator hit_iter = 
00130     clus_ptr->get()->get_associated<TMuiHitO>();
00131   
00132   
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       
00140       
00141       PHKey::associate(hit_ptr,clus_ptr);
00142       return true;
00143     }
00144   }
00145   
00146   
00147   return false;
00148 }
00149 
00153 void
00154 mMuiClusterFinder::calc_position(TMuiClusterMapO::pointer clus_ptr,
00155                                  TMuiPanelGeo *fpMuiPanelGeo)
00156 {  
00157   
00158   
00159   TMuiHitMapO::key_iterator hit_iter = 
00160     clus_ptr->get()->get_associated<TMuiHitO>();
00161   
00162   
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     
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       
00200       
00201       
00202       
00203       if (orient == kHORIZ)
00204         { 
00205           clerr.setX(clerr.getX() *( 1.0/clnhit) );
00206           clerr.setZ(clerr.getZ() *( 1.0/clnhit) );
00207         }
00208       else
00209         { 
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       
00218       
00219       
00220       PHPoint startpoint = PHPoint(clpos);
00221       PHPoint endpoint = startpoint;
00222       
00223       
00224       double convfactor = sqrt(12.0)*0.5;
00225       PHPoint diff = PHPoint(clerr)*convfactor;
00226 
00227       
00228       if (orient == kHORIZ)
00229         { 
00230           startpoint.setX(startpoint.getX() - diff.getX());
00231           endpoint.setX(endpoint.getX() + diff.getX());
00232         }
00233       else
00234         { 
00235           startpoint.setY(startpoint.getY() - diff.getY());
00236           endpoint.setY(endpoint.getY() + diff.getY());
00237         }
00238       
00239       clus_ptr->get()->set_coord_end(endpoint);
00240       clus_ptr->get()->set_coord_begin(startpoint);
00241     }
00242   else
00243     { 
00244       
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   
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   
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     
00275     
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 }