00001
00002
00003
00004
00005
00007
00008
00009
00010 #include <mMuiFindRoad.h>
00011 #include <mMuiFindRoadPar.h>
00012 #include <TMuiChannelId.hh>
00013 #include <TMutNode.h>
00014 #include <TMutGeo.h>
00015 #include <PHException.h>
00016 #include <PHGeometry.h>
00017
00018
00019
00020 #include <gsl/gsl_fit.h>
00021 #include <cmath>
00022 #include <iostream>
00023 #include <string>
00024 #include <list>
00025 #include <boost/array.hpp>
00026
00031 mMuiFindRoad::mMuiFindRoad() :
00032 _timer( PHTimeServer::get()->insert_new( "mMuiFindRoad" ) )
00033 {
00034 name = "mMuiFindRoad";
00035 MUIOO::TRACE("initializing module " + std::string(name.getString()));
00036 }
00037
00041 mMuiFindRoad::~mMuiFindRoad() { }
00042
00046 PHBoolean mMuiFindRoad::event(PHCompositeNode* top_node)
00047 {
00048
00049 _timer.get()->restart();
00050
00051 try {
00052
00053
00054
00055 set_interface_ptrs(top_node);
00056
00057
00058
00059 find_roads();
00060
00061
00062
00063 associate_clusters();
00064
00065
00066
00067 fit_roads();
00068
00069
00070
00071 set_road_parameters();
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 }
00082 catch(std::exception& e) {
00083
00084 MUIOO::TRACE(e.what());
00085 return False;
00086 }
00087
00088
00089
00090 _timer.get()->stop();
00091 if(_mod_par->get_verbosity() >= MUIOO::ALOT) _road_map->print();
00092 if(_mod_par->get_verbosity() >= MUIOO::SOME) _timer.get()->print();
00093
00094 return True;
00095 }
00096
00100 void mMuiFindRoad::set_interface_ptrs(PHCompositeNode* top_node){
00101
00102
00103
00104 _mod_par = TMutNode<mMuiFindRoadPar>::find_node(top_node,"mMuiFindRoadPar");
00105
00106
00107
00108 _cluster_map = TMutNode<TMuiClusterMapO>::find_node(top_node,"TMuiClusterMapO");
00109
00110
00111 _road_map = TMutNode<TMuiRoadMapO>::find_node(top_node,"TMuiRoadMapO");
00112 }
00113
00114 void
00115 mMuiFindRoad::find_roads()
00116 {
00117
00118
00119
00120
00121
00122
00123 TMuiRoadFinder road_finder;
00124
00125
00126
00127 road_finder.set_dca_cut(_mod_par->get_coord_dca_cut());
00128 road_finder.set_prox_cut(_mod_par->get_coord_proximity_cut());
00129 road_finder.set_min_cluster(_mod_par->get_min_cluster());
00130 road_finder.set_min_point(_mod_par->get_min_point());
00131 if (_mod_par->get_mode() == mMuiFindRoadPar::NO_REVERSE) {
00132 road_finder.set_reversed_algo(false);
00133 }
00134 else {
00135 road_finder.set_reversed_algo(true);
00136 }
00137
00138 bool use_window = _mod_par->get_use_window();
00139 TMuiRoadFinder::road_window phi_window = std::make_pair(0,0);
00140 TMuiRoadFinder::road_window theta_window = std::make_pair(0,0);
00141 if (use_window) {
00142
00143
00144
00145 phi_window.first -= 0.5 * _mod_par->get_phi_window();
00146 theta_window.first -= 0.5 * _mod_par->get_theta_window();
00147 phi_window.second += 0.5 * _mod_par->get_phi_window();
00148 theta_window.second += 0.5 * _mod_par->get_theta_window();
00149 }
00150
00151
00152
00153 _roads.clear();
00154
00155
00156
00157
00158 for(int arm=0; arm<MUIOO::NumberOfArms;++arm) {
00159 if(_cluster_map->get(arm).count()){
00160 road_finder.find(_cluster_map, arm,
00161 use_window, phi_window, theta_window);
00162
00163
00164 _roads.splice(_roads.end(), road_finder.get_road_list());
00165 }
00166 }
00167
00168
00169
00170
00171 TMuiRoadFinder::road_list::const_iterator road_list_iter = _roads.begin();
00172 for(;road_list_iter!=_roads.end();++road_list_iter){
00173
00174 if(_mod_par->get_verbosity() == MUIOO::ALOT) road_list_iter->print();
00175
00176 TMuiRoadMapO::iterator road_iter = _road_map->insert_new(road_list_iter->get_arm());
00177
00178
00179 road_iter->get()->set_fit_par(road_list_iter->get_fit_par());
00180 }
00181 }
00182
00183 void
00184 mMuiFindRoad::associate_clusters()
00185 {
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 TMuiRoadMapO::iterator road_iter = _road_map->range();
00196 while(TMuiRoadMapO::pointer road_ptr = road_iter.next()){
00197
00198 UShort_t arm = road_ptr->get()->get_arm();
00199
00200
00201
00202 TMuiClusterMapO::iterator cluster_iter = _cluster_map->get(arm);
00203 while(TMuiClusterMapO::pointer cluster_ptr = cluster_iter.next()){
00204
00205
00206 PHLine line = cluster_ptr->get()->get_coord();
00207 double z_cluster = cluster_ptr->get()->get_centroidpos().getZ();
00208 const TMutFitPar* fit_par = road_ptr->get()->get_const_fitpar();
00209
00210
00211
00212 PHPoint trk_point = TMutTrackUtil::linear_track_model(fit_par,z_cluster);
00213 double distance = PHGeometry::distanceLinePoint(line,trk_point);
00214
00215
00216
00217 if(distance < _mod_par->get_coord_proximity_cut()){
00218 associate_cluster(road_ptr,cluster_ptr,trk_point,distance);
00219 }
00220 }
00221 }
00222 }
00223
00224 void
00225 mMuiFindRoad::associate_cluster(TMuiRoadMapO::pointer road_ptr,
00226 TMuiClusterMapO::pointer in_cluster_ptr,
00227 const PHPoint& trk_point,
00228 double in_distance)
00229 {
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 TMuiClusterMapO::key_iterator cluster_iter = road_ptr->get()->get_associated<TMuiClusterO>();
00246 while(TMuiClusterMapO::pointer cluster_ptr = cluster_iter.next()){
00247
00248
00249
00250 if(cluster_ptr->get()->get_plane() == in_cluster_ptr->get()->get_plane()
00251 && cluster_ptr->get()->get_orientation() == in_cluster_ptr->get()->get_orientation()) {
00252
00253 double distance = PHGeometry::distanceLinePoint(cluster_ptr->get()->get_coord(),trk_point);
00254
00255
00256 if(distance < in_distance) {
00257 return;
00258 } else {
00259
00260
00261 PHKey::disassociate(road_ptr,cluster_ptr);
00262 PHKey::associate(road_ptr, in_cluster_ptr);
00263 return;
00264 }
00265 }
00266 }
00267
00268
00269 PHKey::associate(road_ptr, in_cluster_ptr);
00270 }
00271
00272 void
00273 mMuiFindRoad::fit_roads()
00274 {
00275
00276
00277
00278
00279 TMuiRoadMapO::iterator road_iter = _road_map->range();
00280 while(TMuiRoadMapO::pointer road_ptr = road_iter.next()) {
00281
00282 TMutFitPar fit_par = road_ptr->get()->get_fit_par();
00283
00284
00285 TMuiClusterMapO::const_key_iterator clust_iter =
00286 road_ptr->get()->get_associated<TMuiClusterO>();
00287
00288
00289
00290
00291 int n_h = 0;
00292 boost::array<double,MUIOO::MAX_PLANE> hx = {{0}};
00293 boost::array<double,MUIOO::MAX_PLANE> hy = {{0}};
00294 boost::array<double,MUIOO::MAX_PLANE> hz = {{0}};
00295
00296 int n_v = 0;
00297 boost::array<double,MUIOO::MAX_PLANE> vx = {{0}};
00298 boost::array<double,MUIOO::MAX_PLANE> vy = {{0}};
00299 boost::array<double,MUIOO::MAX_PLANE> vz = {{0}};
00300
00301 double z0 = road_ptr->get()->get_gap0_point().getZ();
00302
00303
00304 double z_max = -DBL_MAX;
00305 double z_min = DBL_MAX;
00306
00307 while(TMuiClusterMapO::const_pointer clust_ptr = clust_iter.next()) {
00308
00309 PHPoint cpos = clust_ptr->get()->get_centroidpos();
00310 z_min = std::min(z_min,cpos.getZ());
00311 z_max = std::max(z_max,cpos.getZ());
00312 if (clust_ptr->get()->get_orientation() == kHORIZ) {
00313 if (n_h >= MUIOO::MAX_PLANE) {
00314 MUIOO::TRACE(" too many horizontal clusters associated to road");
00315 }
00316 hx.at(n_h) = cpos.getX();
00317 hy.at(n_h) = cpos.getY();
00318 hz.at(n_h) = cpos.getZ() - z0;
00319 n_h++;
00320 }
00321 else {
00322 if (n_v >= MUIOO::MAX_PLANE) {
00323 MUIOO::TRACE(" too many vertical clusters associated to road");
00324 }
00325 vx.at(n_v) = cpos.getX();
00326 vy.at(n_v) = cpos.getY();
00327 vz.at(n_v) = cpos.getZ() - z0;
00328 n_v++;
00329 }
00330 }
00331
00332 double x0=0,m_x=0, y0=0, m_y=0;
00333 double hcov00=0, hcov11=0, hcov22=0;
00334 double vcov00=0, vcov11=0, vcov22=0;
00335 double chi2x=0, chi2y=0;
00336
00337
00338
00339 gsl_fit_linear(vz.begin(),1,vx.begin(),1,n_v,
00340 &x0,&m_x,&vcov00,&vcov11,&vcov22,&chi2x);
00341
00342
00343
00344 gsl_fit_linear(hz.begin(),1,hy.begin(),1,n_h,
00345 &y0,&m_y,&hcov00,&hcov11,&hcov22,&chi2y);
00346
00347
00348 fit_par.set_x(x0);
00349 fit_par.set_y(y0);
00350 fit_par.set_z(z0);
00351 fit_par.set_dxdz(m_x);
00352 fit_par.set_dydz(m_y);
00353
00354
00355
00356 fit_par.set_covar(kHORIZ, 0, hcov00);
00357 fit_par.set_covar(kHORIZ, 1, hcov11);
00358 fit_par.set_covar(kHORIZ, 2, hcov22);
00359 fit_par.set_covar(kVERT, 0, vcov00);
00360 fit_par.set_covar(kVERT, 1, vcov11);
00361 fit_par.set_covar(kVERT, 2, vcov22);
00362
00363
00364 double chisq = chi2x + chi2y;
00365 size_t ndof = n_h + n_v - 2*2;
00366 if (ndof > 0) {
00367 chisq /= ndof;
00368 road_ptr->get()->set_road_quality(chisq);
00369 }
00370 else {
00371 road_ptr->get()->set_road_quality(0.0);
00372 }
00373 road_ptr->get()->set_freedom(ndof);
00374 fit_par.set_chi_square(chisq);
00375
00376
00377
00378 if(road_ptr->get()->get_arm() == MUIOO::South) {
00379 fit_par.set_z_begin(z_max) ;
00380 fit_par.set_z_end(z_min);
00381 }
00382 else {
00383 fit_par.set_z_begin(z_min) ;
00384 fit_par.set_z_end(z_max);
00385 }
00386 road_ptr->get()->set_fit_par(fit_par);
00387 }
00388
00389 return;
00390 }
00391
00392 void
00393 mMuiFindRoad::set_road_parameters()
00394 {
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 TMuiRoadMapO::iterator road_iter = _road_map->range();
00415 while(TMuiRoadMapO::pointer road_ptr = road_iter.next()) {
00416
00417
00418 TMuiClusterMapO::const_key_iterator clust_iter =
00419 road_ptr->get()->get_associated<TMuiClusterO>();
00420
00421 road_ptr->get()->set_nhit(clust_iter.count());
00422
00423
00424 UShort_t depth = 0;
00425 UShort_t gapbit = 0;
00426 UShort_t hits_plane[MUIOO::MAX_PLANE] = {0};
00427
00428 while(TMuiClusterMapO::const_pointer clust_ptr = clust_iter.next()) {
00429
00430 if (depth < clust_ptr->get()->get_plane()) {
00431 depth = clust_ptr->get()->get_plane();
00432 }
00433 gapbit=gapbit | (clust_ptr->get()->get_plane() <<
00434 (MUIOO::MAX_PLANE*clust_ptr->get()->get_orientation()));
00435 hits_plane[clust_ptr->get()->get_plane()]++;
00436 }
00437 road_ptr->get()->set_depth(depth);
00438 road_ptr->get()->set_gapbit(gapbit);
00439 UShort_t max_hit_plane = 0;
00440 for (int plane = 0; plane<MUIOO::MAX_PLANE; plane++) {
00441 if (max_hit_plane < hits_plane[plane]) {
00442 max_hit_plane = hits_plane[plane];
00443 }
00444 }
00445 road_ptr->get()->set_max_hit_plane(max_hit_plane);
00446 }
00447 return;
00448 }
00449
00450 void
00451 mMuiFindRoad::apply_road_cuts()
00452 {
00453
00454
00455
00456 TMuiRoadMapO::iterator road_iter = _road_map->range();
00457 while(TMuiRoadMapO::pointer road_ptr = road_iter.next()){
00458
00459
00460 if(road_ptr->get()->get_nhit() < _mod_par->get_min_cluster()) {
00461 _road_map->erase(road_ptr->get()->get_key());
00462 }
00463 }
00464 }
00465
00466 void
00467 mMuiFindRoad::eliminate_duplicates()
00468 {
00469 typedef std::vector<TMuiRoadMapO::value_type> cluster_list;
00470 cluster_list remove_list;
00471 TMuiRoadMapO::iterator road_iter = _road_map->range();
00472 while(TMuiRoadMapO::pointer road_ptr = road_iter.next()){
00473 TMuiRoadMapO::iterator road_iter2 = road_iter;
00474 ++road_iter2;
00475 while(TMuiRoadMapO::pointer road_ptr2 = road_iter2.next()) {
00476 if(cluster_list_equal(road_ptr, road_ptr2)) {
00477 remove_list.push_back(*road_ptr2);
00478 }
00479 }
00480 }
00481
00482 cluster_list::iterator remove_iter = remove_list.begin();
00483 for(;remove_iter != remove_list.end(); ++remove_iter){
00484 _road_map->erase(remove_iter->get()->get_key());
00485 }
00486 }
00487
00488 bool
00489 mMuiFindRoad::cluster_list_equal(const TMuiRoadMapO::pointer road1,
00490 const TMuiRoadMapO::pointer road2)
00491 {
00492 TMuiClusterMapO::key_iterator road1_iter = road1->get()->get_associated<TMuiClusterO>();
00493 TMuiClusterMapO::key_iterator road2_iter = road1->get()->get_associated<TMuiClusterO>();
00494 if(road1_iter.count() != road2_iter.count()) return false;
00495 while(TMuiClusterMapO::pointer road1_ptr = road1_iter.next()){
00496 bool match = false;
00497 road2_iter = road2->get()->get_associated<TMuiClusterO>();
00498 while(TMuiClusterMapO::pointer road2_ptr = road2_iter.next()){
00499 if(road1_ptr->get()->get_key() == road2_ptr->get()->get_key()) {
00500 match = true;
00501 }
00502 }
00503 if(!match) return false;
00504 }
00505 return true;
00506 }
00507
00508
00509
00510
00511
00512