Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHTpcDeltaZCorrection.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHTpcDeltaZCorrection.cc
2 
4 
6 
7 #include <trackbase/TrkrCluster.h> // for TrkrCluster
11 
13 
14 #include <phool/getClass.h>
15 #include <phool/phool.h>
16 
17 #include <gsl/gsl_const_mksa.h> // for the speed of light
18 #include <cmath> // for sqrt, fabs, atan2, cos
19 #include <iostream> // for operator<<, basic_ostream
20 #include <map> // for map
21 #include <set> // for _Rb_tree_const_iterator
22 #include <utility> // for pair, make_pair
23 
24 namespace
25 {
27  template<class T> inline constexpr T square( const T& x ) { return x*x; }
28 
30  static constexpr double speed_of_light = GSL_CONST_MKSA_SPEED_OF_LIGHT*1e-7;
31 
32 }
33 
34 //____________________________________________________________________________..
36  : SubsysReco(name)
37  , PHParameterInterface(name)
39 
40 
41 //____________________________________________________________________________..
43 {
46 }
47 
48 //____________________________________________________________________________..
50 {
51  // load nodes
52  const auto res = load_nodes(topNode);
53  if( res != Fun4AllReturnCodes::EVENT_OK ) return res;
54 
57 }
58 
59 //_____________________________________________________________________
62 
63 //_____________________________________________________________________
65 {
66  // Data on gasses @20 C and 760 Torr from the following source:
67  // http://www.slac.stanford.edu/pubs/icfa/summer98/paper3/paper3.pdf
68  // diffusion and drift velocity for 400kV for NeCF4 50/50 from calculations:
69  // http://skipper.physics.sunysb.edu/~prakhar/tpc/HTML_Gases/split.html
70  return;
71 }
72 
73 //_____________________________________________________________________
75 {
76  // acts geometry
77  m_tGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
79 
80  // get necessary nodes
81  m_track_map = findNode::getClass<TrackSeedContainer>(topNode, "TpcTrackSeedContainer");
83 
84  m_cluster_map = findNode::getClass<TrkrClusterContainer>(topNode, "CORRECTED_TRKR_CLUSTER");
85  if(m_cluster_map)
86  {
87  if(Verbosity() > 0) std::cout << " Using CORRECTED_TRKR_CLUSTER node " << std::endl;
88  }
89  else
90  {
91  if(Verbosity() > 0) std::cout << " CORRECTED_TRKR_CLUSTER node not found, using TRKR_CLUSTER" << std::endl;
92  m_cluster_map = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
93  }
96 }
97 
98 //_____________________________________________________________________
100 {
101  if( !( m_track_map && m_cluster_map ) ) return;
102  for( unsigned int iter = 0; iter != m_track_map->size(); ++iter )
103  {
104  TrackSeed *seed = m_track_map->get(iter);
105  if(!seed)
106  { continue; }
107  process_track( iter, seed );
108  }
109 
110  m_corrected_clusters.clear();
111 }
112 
113 //_____________________________________________________________________
114 void PHTpcDeltaZCorrection::process_track( unsigned int key, TrackSeed* track )
115 {
116 
117  // keep track of the global position of previous cluster on track
118  const Acts::Vector3 origin = {track->get_x(), track->get_y(), track->get_z()};
119 
120  // radius
121  const double radius = fabs(1./track->get_qOverR()); // cm
122 
123  // helix center
124  const double center_x = track->get_X0();
125  const double center_y = track->get_Y0();
126 
127  // origin to center 2D vector
128  const Acts::Vector2 orig_vect = {origin.x()-center_x, origin.y()-center_y };
129 
130  // print
131  if( Verbosity() )
132  {
133  std::cout << "PHTpcDeltaZCorrection -"
134  << " track: " << key
135  << " positive: " << track->get_charge()
136  << " center: " << center_x << ", " << center_y
137  << " radius: " << radius
138  << std::endl;
139  }
140 
141  // loop over clusters. Assume they are ordered by layer
142  for( auto key_iter = track->begin_cluster_keys(); key_iter != track->end_cluster_keys(); ++key_iter)
143  {
144  // store cluster key
145  const auto& cluster_key = *key_iter;
146 
147  // consider TPC clusters only
148  if( TrkrDefs::getTrkrId(cluster_key) != TrkrDefs::tpcId ) continue;
149 
150  // skip if cluster was already corrected
151  if( !m_corrected_clusters.insert(cluster_key).second ) continue;
152 
153  // get cluster
154  auto cluster = m_cluster_map->findCluster( cluster_key );
155  if(!cluster) continue;
156 
157  // get cluster global position
158  const auto global = m_tGeometry->getGlobalPosition(cluster_key, cluster);
159 
160  // get delta z
161  const double delta_z = global.z() - origin.z();
162 
163  // cluster position to center
164  const Acts::Vector2 cluster_vect = {global.x()-center_x, global.y()-center_y};
165 
166  // delta phi
167  const double delta_phi = std::atan2(
168  cluster_vect.y()*orig_vect.x()-cluster_vect.x()*orig_vect.y(),
169  cluster_vect.x()*orig_vect.x() + cluster_vect.y()*orig_vect.y() );
170 
171  // helical path length
172  const double pathlength = std::sqrt( square( delta_z ) + square( radius*delta_phi ) );
173 
174  // adjust cluster position to account for particles propagation time
175  /*
176  * accounting for particles finite velocity results in reducing the electron drift time by pathlenght/c
177  * this in turn affects the cluster z, so that it is always closer to the readout plane
178  */
179  const double t_correction = pathlength /speed_of_light;
180  cluster->setLocalY( cluster->getLocalY() - t_correction);
181 
182  if( Verbosity() )
183  { std::cout << "PHTpcDeltaZCorrection::process_track - cluster: " << cluster_key
184  << " path length: " << pathlength << " t correction " << t_correction << std::endl; }
185  }
186 
187 }