00001 #include<TMuiRoadFinder.h>
00002 #include<TMuiChannelId.hh>
00003 #include<PHGeometry.h>
00004 #include<gsl/gsl_fit.h>
00005 #include<boost/array.hpp>
00006 #include<cmath>
00007 #include<TROOT.h>
00008 #include<TMuiClusterMapO.h>
00009 #include<TMuiHitMapO.h>
00010 #include<TMuiMCHitMapO.h>
00011
00012
00013
00014 bool TMuiRoadFinder::_verbose = false;
00015 bool TMuiRoadFinder::_reverse_algo = false;
00016
00017 UShort_t TMuiRoadFinder::_min_cluster = 4;
00018 UShort_t TMuiRoadFinder::_min_point = 2;
00019
00020 UShort_t TMuiRoadFinder::_max_cluster_share = 4;
00021
00022 bool TMuiRoadFinder::_evaluation = false;
00023 TNtuple* TMuiRoadFinder::_ntuple = 0;
00024 TFile* TMuiRoadFinder::_file = 0;
00025
00026
00027
00028 bool TMuiRoadFinder::Road::_verbose = false;
00029
00030 double TMuiRoadFinder::Road::_dca_cut = 4.0;
00031 double TMuiRoadFinder::Road::_prox_cut = 4.0;
00032
00033
00034 double TMuiRoadFinder::Road::_orient_z_dist = 2.0;
00035 double TMuiRoadFinder::Road::_tube_width = 8.35;
00036
00037 bool TMuiRoadFinder::Road::_evaluation = false;
00038 bool TMuiRoadFinder::Road::_use_slope_cuts = false;
00039 TFile* TMuiRoadFinder::Road::_file = 0;
00040 TNtuple* TMuiRoadFinder::Road::_ntuple = 0;
00041 boost::array<float,20> TMuiRoadFinder::Road::_eval_data;
00042
00043
00044
00045
00046
00047 void
00048 TMuiRoadFinder::find(TMuiClusterMapO* cluster_map)
00049 {
00050
00051
00052 if(!cluster_map) throw std::logic_error(DESCRIPTION("TMuiClusterMapO pointer is null"));
00053
00054 for(int arm=0; arm<MUIOO::NumberOfArms;++arm){
00055 find(cluster_map, arm);
00056 }
00057 }
00058
00059
00060
00061 void
00062 TMuiRoadFinder::find(TMuiClusterMapO* cluster_map,
00063 UShort_t arm,
00064 bool use_window,
00065 const road_window& theta_window,
00066 const road_window& phi_window)
00067 {
00068 if(_verbose) {
00069 std::cout << " TMuiRoadFinder::find: location: " << " arm: " << arm << std::endl;
00070 }
00071
00072
00073 if(!cluster_map) throw std::logic_error(DESCRIPTION("TMuiClusterMapO pointer is null"));
00074
00075
00076
00077 typedef std::list<TMuiClusterMapO::value_type> local_list_type;
00078 local_list_type local_list;
00079
00080
00081
00082 TMuiClusterMapO::iterator cluster_iter = cluster_map->get(arm);
00083 while(TMuiClusterMapO::pointer cluster_ptr = cluster_iter.next()){
00084 local_list.push_back(*cluster_ptr);
00085 }
00086
00087
00088
00089 local_list_type::iterator iter = local_list.begin();
00090 for(;iter!=local_list.end();++iter){
00091
00092
00093 bool was_appended = append_to_road(&(*iter));
00094 if(!was_appended){
00095 start_new_road(&(*iter), use_window, theta_window, phi_window);
00096 }
00097 if(_verbose) print_roads();
00098 }
00099
00100
00101
00102
00103 set_complete_tag();
00104
00105
00106
00107 remove_includes();
00108
00109
00110
00111 if(!_reverse_algo) return;
00112
00113
00114
00115 local_list.reverse();
00116
00117
00118
00119 iter = local_list.begin();
00120 for(;iter!=local_list.end();++iter){
00121
00122
00123 bool was_appended = append_to_road(&(*iter));
00124 if(!was_appended){
00125 start_new_road(&(*iter), use_window, theta_window, phi_window);
00126 }
00127 if(_verbose) print_roads();
00128 }
00129
00130
00131
00132 set_complete_tag();
00133
00134 size_t n_road = _road_list.size();
00135 _road_list.sort(road_less_ftor());
00136 _road_list.unique(road_equal_ftor());
00137
00138
00139
00140 remove_includes();
00141
00142 if(_verbose) {
00143 std::cout << " removed " << n_road - _road_list.size() << " duplicate roads" << std::endl;
00144 }
00145 }
00146
00147 void
00148 TMuiRoadFinder::remove_includes()
00149 {
00150 road_list::iterator iter1 = _road_list.begin();
00151 for(;iter1!=_road_list.end();++iter1){
00152 if (!iter1->get_status()) continue;
00153 road_list::iterator iter2 = iter1;
00154 ++iter2;
00155 for(;iter2!=_road_list.end();++iter2){
00156 if (!iter2->get_status()) continue;
00157
00158 road_list::iterator big = (iter1->get_n_cluster() >= iter2->get_n_cluster()) ? iter1 : iter2;
00159 road_list::iterator little = (iter1->get_n_cluster() >= iter2->get_n_cluster()) ? iter2 : iter1;
00160
00161
00162
00163 if(std::includes(big->get_cluster_list().begin(),
00164 big->get_cluster_list().end(),
00165 little->get_cluster_list().begin(),
00166 little->get_cluster_list().end())) {
00167 little->set_status(false);
00168 }
00169
00170
00171
00172
00173 UShort_t nshare = 0;
00174
00175 Road::cluster_list::const_iterator big_iter =
00176 big->get_cluster_list().begin();
00177 Road::cluster_list::const_iterator little_iter =
00178 little->get_cluster_list().begin();
00179 for(;big_iter!=big->get_cluster_list().end();++big_iter){
00180 bool match = false;
00181 little_iter = little->get_cluster_list().begin();
00182 for(;little_iter!=little->get_cluster_list().end();++little_iter){
00183 if(big_iter->get()->get_key().get_obj_key()
00184 == little_iter->get()->get_key().get_obj_key()) {
00185 match = true;
00186 }
00187 }
00188 if (match) nshare++;
00189 }
00190 if (nshare > _max_cluster_share) {
00191 little->set_status(false);
00192 }
00193 }
00194 }
00195
00196
00197 _road_list.remove_if(road_bad_status_ftor());
00198 }
00199
00200 void
00201 TMuiRoadFinder::set_complete_tag()
00202 {
00203 road_list::iterator road_iter = _road_list.begin();
00204 road_iter = _road_list.begin();
00205 for(;road_iter!=_road_list.end();++road_iter) {
00206 if(road_iter->get_cluster_list().size() < _min_cluster ||
00207 road_iter->get_point_list().size() < _min_point) {
00208 road_iter->set_status(false);
00209 } else {
00210 road_iter->set_complete(true);
00211 }
00212 }
00213 _road_list.remove_if(road_bad_status_ftor());
00214 }
00215
00216 bool
00217 TMuiRoadFinder::append_to_road(TMuiClusterMapO::pointer cluster_ptr)
00218 {
00219
00220
00221
00222
00223
00224
00225
00226
00227 bool sticky_appended = false;
00228 road_list::iterator road_iter = _road_list.begin();
00229 for(;road_iter!=_road_list.end();++road_iter){
00230
00231
00232
00233 if(road_iter->is_complete()) continue;
00234
00235
00236
00237 bool was_appended = road_iter->add_cluster(cluster_ptr);
00238 sticky_appended = (sticky_appended) ? sticky_appended : was_appended;
00239 }
00240 return sticky_appended;
00241 }
00242
00243 void
00244 TMuiRoadFinder::print_roads() const
00245 {
00246 MUIOO::PRINT(std::cout,"**");
00247 std::for_each(_road_list.begin(), _road_list.end(), road_print_ftor());
00248 MUIOO::PRINT(std::cout,"**");
00249 }
00250
00251 void
00252 TMuiRoadFinder::abort_new_road()
00253 {
00254 _road_list.pop_front();
00255 }
00256
00257 TMuiRoadFinder::Road*
00258 TMuiRoadFinder::start_new_road(TMuiClusterMapO::pointer cluster_ptr,
00259 bool use_window,
00260 const road_window& theta_window,
00261 const road_window& phi_window)
00262 {
00263 _road_list.push_front(Road(this, cluster_ptr, use_window,
00264 theta_window, phi_window));
00265
00266
00267
00268 return &(*_road_list.begin());
00269 }
00270
00271
00272
00273
00274 bool
00275 TMuiRoadFinder::Road::add_cluster(TMuiClusterMapO::pointer cluster_ptr)
00276 {
00277 bool was_added=false;
00278 if(_evaluation) _eval_data.assign(0);
00279
00280
00281
00282
00283 if(!unique_check(cluster_ptr)) {
00284 if(_clusters.size()>1) {
00285 was_added = bifurcate(cluster_ptr);
00286 return was_added;
00287 } else {
00288 return false;
00289 }
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 if(_points.size() != 0){
00310
00311 PHPoint point = project(cluster_ptr->get()->get_centroidpos().getZ());
00312 if(test_window(point) &&
00313 check_dca(cluster_ptr,point) &&
00314 check_proximity(cluster_ptr)){
00315 update_road(cluster_ptr);
00316 was_added = true;
00317 }
00318
00319 }
00320 else {
00321
00322
00323 if(!check_parallel(cluster_ptr)) {
00324
00325
00326 if (has_window()) {
00327 PHPoint point = make_point(cluster_ptr);
00328
00329
00330 if(test_window(point)){
00331 update_road(cluster_ptr);
00332 was_added = true;
00333 }
00334 }
00335 else {
00336 update_road(cluster_ptr);
00337 was_added = true;
00338 }
00339 }
00340 else {
00341
00342
00343
00344 if (check_proximity(cluster_ptr)) {
00345 update_road(cluster_ptr);
00346 was_added = true;
00347 }
00348 }
00349 }
00350
00351 if(_clusters.size() >= 3){
00352 check_slope();
00353 }
00354 if(_evaluation) {
00355 _eval_data[0] = _arm;
00356 _eval_data[1] = cluster_ptr->get()->get_plane();
00357 _eval_data[2] = cluster_ptr->get()->get_panel();
00358 _eval_data[3] = cluster_ptr->get()->get_orientation();
00359 _eval_data[4] = _clusters.size();
00360 _eval_data[5] = was_added ? 1 : 0;
00361 _ntuple->Fill(&(_eval_data[0]));
00362 }
00363 return was_added;
00364 }
00365
00366 bool
00367 TMuiRoadFinder::Road::check_parallel(const TMuiClusterMapO::pointer cluster_ptr) const
00368 {
00369
00370
00371 cluster_list::const_iterator cluster_iter = _clusters.begin();
00372 for(;cluster_iter!=_clusters.end();++cluster_iter){
00373 if ( (cluster_iter->get()->get_plane() == cluster_ptr->get()->get_plane()) &&
00374 (cluster_iter->get()->get_panel() == cluster_ptr->get()->get_panel()) &&
00375 (cluster_iter->get()->get_orientation() != cluster_ptr->get()->get_orientation()) ) {
00376 return false;
00377 }
00378 }
00379 return true;
00380 }
00381
00382 bool
00383 TMuiRoadFinder::Road::check_slope() const
00384 {
00385 return true;
00386 }
00387
00388 bool
00389 TMuiRoadFinder::Road::test_window(const PHPoint& point) const
00390 {
00391
00392
00393
00394 if (!has_window()) {
00395 return true;
00396 }
00397
00398
00399
00400
00401 if (_points.size() == 0) {
00402 return true;
00403 }
00404
00405 TMuiRoadFinder::WindowEnum phi_check =
00406 TMuiRoadFinder::check_phi_window(point,_phi_window);
00407
00408 TMuiRoadFinder::WindowEnum theta_check =
00409 TMuiRoadFinder::check_theta_window(point,_theta_window);
00410
00411 if(_evaluation) {
00412 _eval_data[6] = phi_check;
00413 _eval_data[7] = theta_check;
00414 _eval_data[10] = point.getX();
00415 _eval_data[11] = point.getY();
00416 _eval_data[12] = point.getZ();
00417 _eval_data[13] = _phi_window.first;
00418 _eval_data[14] = _phi_window.second;
00419 _eval_data[15] = _theta_window.first;
00420 _eval_data[16] = _theta_window.second;
00421 }
00422
00423 if(phi_check == TMuiRoadFinder::IN_WINDOW &&
00424 theta_check == TMuiRoadFinder::IN_WINDOW) {
00425 return true;
00426 }
00427 else {
00428 return false;
00429 }
00430 }
00431
00432 bool
00433 TMuiRoadFinder::Road::check_dca(const TMuiClusterMapO::pointer cluster_ptr,
00434 const PHPoint& point) const
00435 {
00436
00437 PHLine line = cluster_ptr->get()->get_coord();
00438 double distance = PHGeometry::distanceLinePoint(line, point);
00439
00440
00441 if (_tube_width > 0) distance /= _tube_width;
00442 else return false;
00443
00444 if(_evaluation) {
00445 _eval_data[8] = distance;
00446 }
00447
00448 if(distance < _dca_cut) {
00449
00450
00451
00452
00453 double projdist = PHGeometry::distancePointToPoint(cluster_ptr->get()->get_centroidpos(), point);
00454 double halflength = 0.5*line.length();
00455 if (projdist < halflength) {
00456 return true;
00457 }
00458 }
00459 return false;
00460 }
00461
00462 bool
00463 TMuiRoadFinder::Road::bifurcate(TMuiClusterMapO::pointer cluster_ptr)
00464 {
00465
00466
00467 if(_finder->_road_list.size() > 500) {
00468 throw std::runtime_error(DESCRIPTION("bifurcate: too many roads"));
00469 }
00470
00471
00472
00473 TMuiRoadFinder::Road* new_road_ptr = 0;
00474
00475
00476
00477
00478 cluster_list::iterator cluster_iter = _clusters.begin();
00479 for(;cluster_iter!=_clusters.end();++cluster_iter){
00480 if(cluster_ptr->get()->get_plane() != cluster_iter->get()->get_plane()) {
00481
00482
00483 TMuiClusterMapO::value_type old_cluster = *cluster_iter;
00484
00485
00486
00487 if(!new_road_ptr) {
00488 new_road_ptr = _finder->start_new_road(&old_cluster, _has_window, _theta_window, _phi_window);
00489 } else {
00490 new_road_ptr->update_road(&old_cluster);
00491 }
00492 }
00493 }
00494
00495
00496
00497 if(!new_road_ptr) {
00498 _finder->start_new_road(cluster_ptr, _has_window, _theta_window, _phi_window);
00499 return true;
00500 }
00501
00502
00503
00504
00505
00506
00507
00508 bool was_added = new_road_ptr->add_cluster(cluster_ptr);
00509 if(was_added) {
00510 return true;
00511 } else {
00512 _finder->abort_new_road();
00513 return false;
00514 }
00515 }
00516
00517
00518 bool
00519 TMuiRoadFinder::Road::check_proximity(TMuiClusterMapO::pointer cluster_ptr) const
00520 {
00521
00522
00523
00524
00525
00526
00527 if(!_clusters.size()) throw std::logic_error(DESCRIPTION("attempted comparison with null entry"));
00528
00529 PHPoint point1 = cluster_ptr->get()->get_centroidpos();
00530
00531
00532 double distance = DBL_MAX;
00533 cluster_list::const_iterator best_iter;
00534 cluster_list::const_iterator cluster_iter = _clusters.begin();
00535 for(;cluster_iter!=_clusters.end();++cluster_iter){
00536 if (cluster_iter->get()->get_orientation() == cluster_ptr->get()->get_orientation()) {
00537 PHPoint point2 = cluster_iter->get()->get_centroidpos();
00538 double thisdistance = std::fabs(point2.getZ() - point1.getZ());
00539 if (thisdistance < distance) {
00540 distance = thisdistance;
00541 best_iter = cluster_iter;
00542 }
00543 }
00544 }
00545
00546 if (distance == DBL_MAX) {
00547
00548 return false;
00549 }
00550
00551 PHPoint point2 = best_iter->get()->get_centroidpos();
00552 point1.setZ(0);
00553 point2.setZ(0);
00554 distance = PHGeometry::distancePointToPoint(point1,point2);
00555
00556 if (_tube_width > 0) distance /= _tube_width;
00557 else return false;
00558
00559 if(_evaluation) {
00560 _eval_data[9] = distance;
00561 }
00562
00563 if(distance < _prox_cut) {
00564 return true;
00565 }
00566 return false;
00567 }
00568
00569 void
00570 TMuiRoadFinder::Road::update_road(TMuiClusterMapO::pointer cluster_ptr)
00571 {
00572
00573
00574 _clusters.insert(*cluster_ptr);
00575
00576
00577
00578
00579 _points.clear();
00580
00581
00582
00583
00584 cluster_list::const_iterator iter1 = _clusters.begin();
00585 for(;iter1!=_clusters.end();++iter1){
00586
00587 PHLine line1 = iter1->get()->get_coord();
00588 cluster_list::const_iterator iter2 = iter1;
00589 ++iter2;
00590
00591 for(;iter2!=_clusters.end();++iter2){
00592
00593 if(iter1->get()->get_plane() == iter2->get()->get_plane() &&
00594 iter1->get()->get_panel() == iter2->get()->get_panel() &&
00595 iter1->get()->get_orientation() != iter2->get()->get_orientation() ){
00596
00597 PHLine line2 = iter2->get()->get_coord();
00598
00599
00600 double distance = PHGeometry::distanceLineLine(line1, line2);
00601
00602 if (distance <= _orient_z_dist)
00603 {
00604 PHPoint point = PHGeometry::closestApproachLineLine(line1, line2);
00605 _points.push_back(point);
00606 }
00607 }
00608 }
00609 }
00610
00611
00612
00613 if(_points.size()==0){
00614
00615
00616
00617
00618 iter1 = _clusters.begin();
00619 PHPoint mid_point = iter1->get()->get_centroidpos();
00620
00621
00622 _fit_par.set_x(mid_point.getX());
00623 _fit_par.set_y(mid_point.getY());
00624 _fit_par.set_z(mid_point.getZ());
00625 _fit_par.set_dxdz(0);
00626 _fit_par.set_dydz(0);
00627 }
00628 else if(_points.size()==1){
00629
00630
00631
00632 _fit_par.set_x(_points.begin()->getX());
00633 _fit_par.set_y(_points.begin()->getY());
00634 _fit_par.set_z(_points.begin()->getZ());
00635 _fit_par.set_dxdz(0);
00636 _fit_par.set_dydz(0);
00637
00638
00639 PHSphPoint spherepoint;
00640 PHGeometry::cartesianToSpherical(_points[0], spherepoint);
00641 double half_phi_window_size = 0.5*(_phi_window.second - _phi_window.first);
00642 double half_theta_window_size = 0.5*(_theta_window.second - _theta_window.first);
00643
00644 _phi_window.first = static_cast<double>(spherepoint.getPhi())
00645 - half_phi_window_size;
00646 _phi_window.second = static_cast<double>(spherepoint.getPhi())
00647 + half_phi_window_size;
00648 _theta_window.first = static_cast<double>(spherepoint.getTheta())
00649 - half_theta_window_size;
00650 _theta_window.second = static_cast<double>(spherepoint.getTheta())
00651 + half_theta_window_size;
00652 }
00653 else if(_points.size()>1) {
00654
00655
00656
00657
00658 boost::array<double,MUIOO::MAX_PLANE> x = {{0}};
00659 boost::array<double,MUIOO::MAX_PLANE> y = {{0}};
00660 boost::array<double,MUIOO::MAX_PLANE> z = {{0}};
00661
00662 double z0 = _points[0].getZ();
00663 size_t n_data = _points.size();
00664
00665
00666 double z_max = -DBL_MAX;
00667 double z_min = DBL_MAX;
00668
00669 PHSphPoint spherepoint;
00670 double phi_sum = 0.0;
00671 double theta_sum = 0.0;
00672 double half_phi_window_size = 0.5*(_phi_window.second - _phi_window.first);
00673 double half_theta_window_size = 0.5*(_theta_window.second - _theta_window.first);
00674
00675 for(size_t i=0;i<n_data;++i){
00676 PHGeometry::cartesianToSpherical(_points[i], spherepoint);
00677 phi_sum += spherepoint.getPhi();
00678 theta_sum += spherepoint.getTheta();
00679 x.at(i) = _points[i].getX();
00680 y.at(i) = _points[i].getY();
00681 z.at(i) = _points[i].getZ() - z0;
00682 z_min = std::min(z_min,_points[i].getZ());
00683 z_max = std::max(z_max,_points[i].getZ());
00684 }
00685
00686 phi_sum /= n_data;
00687 theta_sum /= n_data;
00688 _phi_window.first = phi_sum - half_phi_window_size;
00689 _phi_window.second = phi_sum + half_phi_window_size;
00690 _theta_window.first = theta_sum - half_theta_window_size;
00691 _theta_window.second = theta_sum + half_theta_window_size;
00692
00693 double x0=0,m_x=0, y0=0, m_y=0;
00694 double cov00=0, cov11=0, cov22=0,chi2x=0,chi2y=0;
00695
00696
00697
00698 gsl_fit_linear(z.begin(),1,x.begin(),1,n_data,
00699 &x0,&m_x,&cov00,&cov11,&cov22,&chi2x);
00700
00701
00702
00703 gsl_fit_linear(z.begin(),1,y.begin(),1,n_data,
00704 &y0,&m_y,&cov00,&cov11,&cov22,&chi2y);
00705
00706
00707
00708 if(std::fabs(m_x) > 10 || std::fabs(m_y) > 10) {
00709 _status = false;
00710 return;
00711 }
00712
00713 _fit_par.set_x(x0);
00714 _fit_par.set_y(y0);
00715 _fit_par.set_z(z0);
00716 _fit_par.set_dxdz(m_x);
00717 _fit_par.set_dydz(m_y);
00718
00719
00720
00721 if(_arm == MUIOO::South) {
00722 _fit_par.set_z_begin(z_max) ;
00723 _fit_par.set_z_end(z_min);
00724 } else {
00725 _fit_par.set_z_begin(z_min) ;
00726 _fit_par.set_z_end(z_max);
00727 }
00728 }
00729 }
00730
00731 PHPoint
00732 TMuiRoadFinder::Road::project(double z) const
00733 {
00734 return TMutTrackUtil::linear_track_model(&_fit_par,z);
00735 }
00736
00737 PHPoint
00738 TMuiRoadFinder::Road::make_point(const TMuiClusterMapO::pointer cluster_ptr) const
00739 {
00740
00741 PHLine line1 = cluster_ptr->get()->get_coord();
00742
00743
00744 cluster_list::const_iterator cluster_iter = _clusters.begin();
00745 for(;cluster_iter!=_clusters.end();++cluster_iter){
00746 if ( (cluster_iter->get()->get_plane() == cluster_ptr->get()->get_plane()) &&
00747 (cluster_iter->get()->get_panel() == cluster_ptr->get()->get_panel()) &&
00748 (cluster_iter->get()->get_orientation() != cluster_ptr->get()->get_orientation()) ) {
00749
00750 PHLine line2 = cluster_iter->get()->get_coord();
00751
00752 double distance = PHGeometry::distanceLineLine(line1, line2);
00753
00754 if (distance <= _orient_z_dist)
00755 {
00756 PHPoint point = PHGeometry::closestApproachLineLine(line1, line2);
00757 return point;
00758 }
00759 }
00760 }
00761 return PHPoint();
00762 }
00763
00764 bool
00765 TMuiRoadFinder::Road::unique_check(TMuiClusterMapO::pointer cluster_ptr) const
00766 {
00767
00768
00769
00770 cluster_list::const_iterator cluster_iter = _clusters.begin();
00771 for(;cluster_iter!=_clusters.end();++cluster_iter){
00772
00773 if(cluster_ptr->get()->get_plane() == cluster_iter->get()->get_plane() &&
00774 cluster_ptr->get()->get_orientation() == cluster_iter->get()->get_orientation()) {
00775 return false;
00776 }
00777 }
00778 return true;
00779 }
00780
00781 bool
00782 TMuiRoadFinder::Road::check_theta_window(const TMuiRoadFinder::road_window& theta_window) const
00783 {
00784 double theta = get_theta();
00785 return (theta > theta_window.first && theta < theta_window.second);
00786 }
00787
00788 bool
00789 TMuiRoadFinder::Road::check_phi_window(const TMuiRoadFinder::road_window& phi_window) const
00790 {
00791
00792
00793 double x1 = std::cos(phi_window.first);
00794 double x2 = std::cos(phi_window.second);
00795 double y1 = std::sin(phi_window.first);
00796 double y2 = std::sin(phi_window.second);
00797 double xp = std::cos(get_phi());
00798 double yp = std::sin(get_phi());
00799
00800 double r1 = std::sqrt(MUIOO::SQUARE(x1) + MUIOO::SQUARE(y1));
00801 double r2 = std::sqrt(MUIOO::SQUARE(x2) + MUIOO::SQUARE(y2));
00802 double rp = std::sqrt(MUIOO::SQUARE(xp) + MUIOO::SQUARE(yp));
00803
00804 double dphi_window = std::acos((x1*x2 + y1*y2)/(r1*r2));
00805 double dphi_left = std::acos((x1*xp + y1*yp)/(r1*rp));
00806 double dphi_right = std::acos((x2*xp + y2*yp)/(r2*rp));
00807
00808
00809
00810
00811 return (dphi_left < dphi_window && dphi_right < dphi_window);
00812 }
00813
00814 void
00815 TMuiRoadFinder::Road::initialize_evaluation()
00816 {
00817 if(_evaluation) return;
00818
00819 _file = (TFile*)gROOT->GetListOfFiles()->FindObject("muioo_eval_ntuple.root");
00820 if (_file) {
00821 MUIOO::TRACE("TMuiRoadFinder::Road::initialize_evaluation, creating eval root file");
00822 _file = new TFile("muioo_eval_ntuple.root", "RECREATE");
00823 }
00824
00825
00826
00827 _ntuple = new TNtuple("road_cluster","road_cluster","arm:plane:panel:orientation:ncoord:added:phi_check:theta_check:dca_dist:prox_dist:x:y:z:phi1:phi2:theta1:theta2");
00828 cout << " TMuiRoadFinder::Road::initialize_evaluation() ntuple created" << endl;
00829
00830 _evaluation = true;
00831
00832 return;
00833 }
00834 void
00835 TMuiRoadFinder::Road::finish_evaluation()
00836 {
00837 if(_ntuple) delete _ntuple;
00838 _evaluation = false;
00839 }
00840
00841
00842 std::list<TMuiClusterMapO::value_type>
00843 TMuiRoadFinder::get_coords_in_window(TMuiClusterMapO* cluster_map,
00844 UShort_t arm,
00845 const road_window& theta_window,
00846 const road_window& phi_window)
00847 {
00848
00849
00850 typedef std::list<TMuiClusterMapO::value_type> local_list_type;
00851 local_list_type local_list;
00852
00853 TMuiClusterMapO::iterator cluster_iter = cluster_map->get(arm);
00854
00855 while(TMuiClusterMapO::pointer cluster_ptr = cluster_iter.next()){
00856
00857 WindowEnum phi_begin =
00858 check_phi_window(cluster_ptr->get()->get_coord_begin(), phi_window);
00859 WindowEnum phi_end =
00860 check_phi_window(cluster_ptr->get()->get_coord_end(), phi_window);
00861
00862
00863
00864
00865 bool in_phi_window = false;
00866 if((phi_begin == IN_WINDOW || phi_end == IN_WINDOW) ||
00867 (phi_begin == HIGH_WINDOW && phi_end == LOW_WINDOW) ||
00868 (phi_begin == LOW_WINDOW && phi_end == HIGH_WINDOW)) {
00869 in_phi_window = true;
00870 }
00871
00872 WindowEnum theta_begin =
00873 check_theta_window(cluster_ptr->get()->get_coord_begin(), theta_window);
00874 WindowEnum theta_end =
00875 check_theta_window(cluster_ptr->get()->get_coord_end(), theta_window);
00876
00877
00878
00879
00880 bool in_theta_window = false;
00881 if((theta_begin == IN_WINDOW || theta_end == IN_WINDOW) ||
00882 (theta_begin == HIGH_WINDOW && theta_end == LOW_WINDOW) ||
00883 (theta_begin == LOW_WINDOW && theta_end == HIGH_WINDOW)) {
00884 in_theta_window = true;
00885 }
00886
00887 if(in_theta_window && in_phi_window) local_list.push_back(*cluster_ptr);
00888 }
00889 return local_list;
00890 }
00891
00892
00893 TMuiRoadFinder::WindowEnum
00894 TMuiRoadFinder::check_phi_window(const PHPoint& point,
00895 const TMuiRoadFinder::road_window&phi_window)
00896 {
00897
00898 PHSphPoint spherepoint;
00899 PHGeometry::cartesianToSpherical(point, spherepoint);
00900
00901
00902
00903 double thisphi = spherepoint.getPhi();
00904 double dphi_right = phi_window.second - thisphi;
00905 double dphi_left = thisphi - phi_window.first;
00906
00907
00908
00909
00910
00911
00912
00913 if (phi_window.second > 2*M_PI && point.getY() > 0) {
00914 dphi_right -= 2*M_PI;
00915 }
00916
00917
00918
00919
00920
00921
00922
00923
00924 if(dphi_left >= 0 && dphi_right >= 0){
00925 return IN_WINDOW;
00926 } else if(dphi_left < 0) {
00927 return LOW_WINDOW;
00928 } else if(dphi_right < 0) {
00929 return HIGH_WINDOW;
00930 } else {
00931 return HIGH_WINDOW;
00932 }
00933 }
00934
00935 TMuiRoadFinder::WindowEnum
00936 TMuiRoadFinder::check_theta_window(const PHPoint& point,
00937 const TMuiRoadFinder::road_window&
00938 theta_window)
00939 {
00940
00941 PHSphPoint spherepoint;
00942 PHGeometry::cartesianToSpherical(point, spherepoint);
00943 double theta_p = spherepoint.getTheta();
00944
00945 if(theta_p >= theta_window.first && theta_p <= theta_window.second){
00946 return IN_WINDOW;
00947 } else if(theta_p < theta_window.first) {
00948 return LOW_WINDOW;
00949 } else if(theta_p > theta_window.second) {
00950 return HIGH_WINDOW;
00951 } else {
00952 return HIGH_WINDOW;
00953 }
00954 }
00955
00956 void
00957 TMuiRoadFinder::initialize_evaluation()
00958 {
00959 if(_evaluation) return;
00960
00961 _file = (TFile*)gROOT->GetListOfFiles()->FindObject("muioo_eval_ntuple.root");
00962 if (_file) {
00963 MUIOO::TRACE("TMuiRoadFinder::initialize_evaluation, creating eval root file");
00964 _file = new TFile("muioo_eval_ntuple.root", "RECREATE");
00965 }
00966
00967
00968
00969 _ntuple = new TNtuple("road","road",
00970 "arm:iroad:iclust:mc_exist:mc_found:"
00971 "true_hit:bg_hit:th_true:phi_true:th_win:ph_win");
00972
00973 _evaluation = true;
00974 return;
00975 }
00976
00977 void TMuiRoadFinder::finish_evaluation()
00978 {
00979 if(_ntuple) delete _ntuple;
00980 _evaluation=false;
00981 return;
00982 }
00983
00984 void
00985 TMuiRoadFinder::evaluate(PHCompositeNode* top_node)
00986 {
00987 TMuiRoadFinder::road_list& road_list = get_road_list();
00988 TMuiRoadFinder::road_list::iterator road_list_iter = road_list.begin();
00989 for(;road_list_iter!=road_list.end();++road_list_iter){
00990 float ntvar[20] = {0};
00991
00992 ntvar[0] = road_list_iter->get_arm();
00993 ntvar[1] = road_list_iter->get_cluster_list().size();
00994
00995 typedef TMuiRoadFinder::Road::cluster_list road_cluster_list;
00996 road_cluster_list& cluster_list = road_list_iter->get_cluster_list();
00997 road_cluster_list::iterator cluster_iter = cluster_list.begin();
00998 for(;cluster_iter!=cluster_list.end();++cluster_iter){
00999 TMuiClusterMapO::const_key_iterator clus_iter = cluster_iter->get()->get_associated<TMuiClusterO>();
01000 if(!clus_iter.at_end()){
01001 TMuiHitMapO::const_key_iterator hit_iter = clus_iter->get()->get_associated<TMuiHitO>();
01002 while(TMuiHitMapO::const_pointer hit_ptr = hit_iter.next()){
01003 TMuiMCHitMapO::const_key_iterator mc_hit_iter = hit_ptr->get()->get_associated<TMuiMCHitO>();
01004 if(!mc_hit_iter.at_end()){
01005 }
01006 }
01007 }
01008 }
01009 }
01010 }
01011
01012
01013