File indexing completed on 2025-08-06 08:18:35
0001
0002
0003
0004
0005
0006
0007 #include "PrelimDistortionCorrectionAuAu.h"
0008
0009 #include "ALICEKF.h"
0010
0011 #include <ffamodules/CDBInterface.h>
0012
0013 #include <fun4all/Fun4AllReturnCodes.h>
0014
0015 #include <g4detectors/PHG4TpcCylinderGeom.h>
0016 #include <g4detectors/PHG4TpcCylinderGeomContainer.h>
0017
0018 #include <phfield/PHField.h>
0019 #include <phfield/PHFieldUtility.h>
0020 #include <phfield/PHFieldConfig.h>
0021 #include <phfield/PHFieldConfigv1.h>
0022
0023 #include <phool/PHTimer.h>
0024 #include <phool/getClass.h>
0025 #include <phool/phool.h> // for PHWHERE
0026
0027
0028 #include <tpc/TpcDistortionCorrectionContainer.h>
0029
0030 #include <trackbase/TrackFitUtils.h>
0031 #include <trackbase/TrkrCluster.h>
0032 #include <trackbase/TrkrClusterContainer.h>
0033 #include <trackbase/TrkrDefs.h>
0034 #include <trackbase/ActsGeometry.h>
0035
0036 #include <trackbase_historic/ActsTransformations.h>
0037 #include <trackbase_historic/TrackSeedContainer.h>
0038 #include <trackbase_historic/TrackSeed_v2.h>
0039 #include <trackbase_historic/TrackSeedHelper.h>
0040
0041 #include <Geant4/G4SystemOfUnits.hh>
0042
0043 #include <Eigen/Core>
0044 #include <Eigen/Dense>
0045
0046 #include <iostream> // for operator<<, basic_ostream
0047 #include <vector>
0048
0049
0050 PrelimDistortionCorrectionAuAu::PrelimDistortionCorrectionAuAu(const std::string& name)
0051 : SubsysReco(name)
0052 {}
0053
0054
0055 PrelimDistortionCorrectionAuAu::~PrelimDistortionCorrectionAuAu()
0056 {
0057 if( m_own_fieldmap )
0058 { delete _field_map; }
0059 }
0060
0061
0062 int PrelimDistortionCorrectionAuAu::End(PHCompositeNode* )
0063 {
0064 return Fun4AllReturnCodes::EVENT_OK;
0065 }
0066
0067
0068 int PrelimDistortionCorrectionAuAu::InitRun(PHCompositeNode* topNode)
0069 {
0070
0071 int ret = get_nodes(topNode);
0072 if (ret != Fun4AllReturnCodes::EVENT_OK) { return ret; }
0073
0074 PHFieldConfigv1 fcfg;
0075 fcfg.set_field_config(PHFieldConfig::FieldConfigTypes::Field3DCartesian);
0076
0077
0078 auto magField = CDBInterface::instance()->getUrl("FIELDMAP_TRACKING");
0079 fcfg.set_filename(magField);
0080
0081
0082
0083
0084
0085
0086
0087 const auto node_fcfg = PHFieldUtility::GetFieldConfigNode(&fcfg, topNode);
0088 if( fcfg == *node_fcfg )
0089 {
0090
0091 std::cout << "PrelimDistortionCorrectionAuAu::InitRun - using field map found from node tree" << std::endl;
0092 _field_map = PHFieldUtility::GetFieldMapNode(&fcfg, topNode);
0093 m_own_fieldmap = false;
0094 } else {
0095
0096 std::cout << "PrelimDistortionCorrectionAuAu::InitRun - using own field map" << std::endl;
0097 _field_map = PHFieldUtility::BuildFieldMap(&fcfg);
0098 m_own_fieldmap = true;
0099 }
0100
0101 fitter = std::make_unique<ALICEKF>(topNode,_cluster_map,_field_map, _fieldDir,
0102 _min_clusters_per_track,_max_sin_phi,Verbosity());
0103 fitter->setNeonFraction(Ne_frac);
0104 fitter->setArgonFraction(Ar_frac);
0105 fitter->setCF4Fraction(CF4_frac);
0106 fitter->setNitrogenFraction(N2_frac);
0107 fitter->setIsobutaneFraction(isobutane_frac);
0108 fitter->useConstBField(_use_const_field);
0109 fitter->setConstBField(_const_field);
0110 fitter->useFixedClusterError(_use_fixed_clus_err);
0111 fitter->setFixedClusterError(0,_fixed_clus_err.at(0));
0112 fitter->setFixedClusterError(1,_fixed_clus_err.at(1));
0113 fitter->setFixedClusterError(2,_fixed_clus_err.at(2));
0114
0115
0116
0117 return Fun4AllReturnCodes::EVENT_OK;
0118 }
0119
0120
0121 int PrelimDistortionCorrectionAuAu::get_nodes(PHCompositeNode* topNode)
0122 {
0123
0124
0125
0126
0127 _tgeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
0128 if(!_tgeometry)
0129 {
0130 std::cout << "No Acts tracking geometry, exiting." << std::endl;
0131 return Fun4AllReturnCodes::ABORTEVENT;
0132 }
0133
0134
0135
0136 m_dcc_module_edge = findNode::getClass<TpcDistortionCorrectionContainer>(topNode, "TpcDistortionCorrectionContainerModuleEdge");
0137 if (m_dcc_module_edge)
0138 {
0139 std::cout << "PrelimDistortionCorrectionAuAu::get_nodes - found TPC distortion correction container module edge" << std::endl;
0140 }
0141
0142
0143 m_dcc_static = findNode::getClass<TpcDistortionCorrectionContainer>(topNode, "TpcDistortionCorrectionContainerStatic");
0144 if (m_dcc_static)
0145 {
0146 std::cout << "PrelimDistortionCorrectionAuAu::get_nodes - found TPC distortion correction container static" << std::endl;
0147 }
0148
0149
0150 m_dcc_average = findNode::getClass<TpcDistortionCorrectionContainer>(topNode, "TpcDistortionCorrectionContainerAverage");
0151 if (m_dcc_average)
0152 {
0153 std::cout << "PrelimDistortionCorrectionAuAu::get_nodes - found TPC distortion correction container average" << std::endl;
0154 }
0155
0156
0157 if(_use_truth_clusters) {
0158 _cluster_map = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER_TRUTH");
0159 } else {
0160 _cluster_map = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
0161 }
0162
0163 if (!_cluster_map)
0164 {
0165 std::cerr << PHWHERE << "PrelimDistortionCorrectionAuAu::get_nodes - ERROR: Can't find node TRKR_CLUSTER" << std::endl;
0166 return Fun4AllReturnCodes::ABORTEVENT;
0167 }
0168
0169 _track_map = findNode::getClass<TrackSeedContainer>(topNode, "TpcTrackSeedContainer");
0170 if (!_track_map)
0171 {
0172 std::cerr << PHWHERE << "PrelimDistortionCorrectionAuAu::get_nodes - ERROR: Can't find TrackSeedContainer " << std::endl;
0173 return Fun4AllReturnCodes::ABORTEVENT;
0174 }
0175
0176 PHG4TpcCylinderGeomContainer *geom_container =
0177 findNode::getClass<PHG4TpcCylinderGeomContainer>(topNode, "CYLINDERCELLGEOM_SVTX");
0178 if (!geom_container)
0179 {
0180 std::cerr << PHWHERE << "PrelimDistortionCorrectionAuAu::get_nodes - ERROR: Can't find node CYLINDERCELLGEOM_SVTX" << std::endl;
0181 return Fun4AllReturnCodes::ABORTRUN;
0182 }
0183
0184 for(int i=7;i<=54;i++)
0185 {
0186 radii.push_back(geom_container->GetLayerCellGeom(i)->get_radius());
0187 }
0188
0189 return Fun4AllReturnCodes::EVENT_OK;
0190 }
0191
0192
0193 int PrelimDistortionCorrectionAuAu::process_event(PHCompositeNode* )
0194 {
0195 if(_pp_mode)
0196 {
0197 std::cout << "PrelimDistortionCorrectionAuAu called but in pp_mode, do nothing!" << std::endl;
0198 return Fun4AllReturnCodes::EVENT_OK;
0199 }
0200
0201 PHTimer timer("PrelimDistortionCorrectionAuAuTimer");
0202 timer.stop();
0203 timer.restart();
0204
0205 if(Verbosity()>0)
0206 {
0207 std::cout << "starting PrelimDistortionCorrectionAuAu process_event" << std::endl;
0208 }
0209
0210
0211
0212 std::vector<std::vector<TrkrDefs::cluskey>> keylist_A;
0213 PositionMap correctedOffsetTrackClusPositions;
0214
0215 for(unsigned int track_it = 0; track_it != _track_map->size(); ++track_it )
0216 {
0217 if(Verbosity()>0) { std::cout << "TPC seed " << track_it << std::endl; }
0218
0219 TrackSeed* track = _track_map->get(track_it);
0220 if(!track)
0221 {
0222 continue;
0223 }
0224
0225 if(Verbosity() > 0)
0226 {
0227 std::cout << "Input seed pars for " << track_it
0228 << " q " << track->get_charge()
0229 << " qOverR " << fabs(track->get_qOverR()) * track->get_charge()
0230 << " X0 " << TrackSeedHelper::get_x(track)
0231 << " Y0 " << TrackSeedHelper::get_y(track)
0232 << " Z0 " << TrackSeedHelper::get_z(track)
0233 << " eta " << track->get_eta()
0234 << " phi " << track->get_phi()
0235 << std::endl;
0236 }
0237
0238 const bool is_tpc = std::any_of(
0239 track->begin_cluster_keys(),
0240 track->end_cluster_keys(),
0241 []( const TrkrDefs::cluskey& key ) { return TrkrDefs::getTrkrId(key) == TrkrDefs::tpcId; } );
0242
0243 if(is_tpc)
0244 {
0245
0246
0247 float Z0 = 0;
0248 float offset_Z = 0.0 - Z0;
0249
0250 if(Verbosity() > 0)
0251 {
0252 std::cout << " processing seed with offset_Z " << offset_Z
0253 << " eta " << track->get_eta()
0254 << " x " << TrackSeedHelper::get_x(track)
0255 << " y " << TrackSeedHelper::get_y(track)
0256 << " z " << TrackSeedHelper::get_z(track)
0257 << std::endl;
0258 }
0259
0260
0261 std::vector<TrkrDefs::cluskey> dumvec;
0262 for(TrackSeed::ConstClusterKeyIter iter = track->begin_cluster_keys();
0263 iter != track->end_cluster_keys();
0264 ++iter)
0265 {
0266 TrkrDefs::cluskey cluskey = *iter;
0267 TrkrCluster *cluster = _cluster_map->findCluster(cluskey);
0268
0269
0270 const Acts::Vector3 pos = _tgeometry->getGlobalPosition(cluskey, cluster);
0271
0272
0273 Acts::Vector3 offsetpos(pos.x(), pos.y(), pos.z() + offset_Z);
0274
0275
0276 if (m_dcc_module_edge)
0277 {
0278 offsetpos = m_distortionCorrection.get_corrected_position(offsetpos, m_dcc_module_edge);
0279 }
0280
0281 if (m_dcc_static)
0282 {
0283 offsetpos = m_distortionCorrection.get_corrected_position(offsetpos, m_dcc_static);
0284 }
0285
0286 if (m_dcc_average)
0287 {
0288 offsetpos = m_distortionCorrection.get_corrected_position(offsetpos, m_dcc_average);
0289 }
0290
0291
0292 const Acts::Vector3 corrpos(offsetpos(0), offsetpos(1), offsetpos(2) - offset_Z);
0293 correctedOffsetTrackClusPositions.emplace(cluskey,corrpos);
0294 dumvec.push_back(cluskey);
0295
0296 if(Verbosity() > 0)
0297 {
0298 std::cout << " cluskey " << cluskey << " input pos " << pos(0) << " " << pos(1) << " " << pos(2)
0299 << " corr. pos " << corrpos(0) << " " << corrpos(1) << " " << corrpos(2) << std::endl
0300 << "distortion correction " << corrpos(0) - pos(0) << " " << corrpos(1) - pos(1) << " " << corrpos(2) - pos(2)
0301 << std::endl;
0302
0303 }
0304 }
0305
0306
0307 if(dumvec.size() < 3)
0308 { continue; }
0309 keylist_A.push_back(dumvec);
0310
0311 if(Verbosity() > 0)
0312 {
0313 std::cout << "Added input seed " << track_it << " becomes output seed " << keylist_A.size() - 1 << std::endl;
0314 }
0315
0316 }
0317
0318 }
0319
0320
0321 _track_map->Reset();
0322
0323
0324 std::vector<float> trackChi2;
0325 auto seeds = fitter->ALICEKalmanFilter(keylist_A, true, correctedOffsetTrackClusPositions, trackChi2);
0326
0327
0328
0329 publishSeeds(seeds.first, correctedOffsetTrackClusPositions);
0330
0331 return Fun4AllReturnCodes::EVENT_OK;
0332 }
0333
0334
0335 void PrelimDistortionCorrectionAuAu::publishSeeds(std::vector<TrackSeed_v2>& seeds, PositionMap& positions)
0336 {
0337 int seed_index = 0;
0338 for(auto& seed: seeds )
0339 {
0340 if(seed.size_cluster_keys() < 3)
0341 {
0342 continue;
0343 }
0344
0345
0346 int q = seed.get_charge();
0347 TrackSeedHelper::circleFitByTaubin(&seed,positions, 7, 55);
0348 TrackSeedHelper::lineFit(&seed,positions, 7, 55);
0349
0350 seed.set_qOverR(fabs(seed.get_qOverR()) * q);
0351 seed.set_phi(TrackSeedHelper::get_phi(&seed,positions));
0352 _track_map->insert(&seed);
0353
0354 if(Verbosity() > 0)
0355 {
0356 std::cout << "Publishing seed " << seed_index
0357 << " q " << q
0358 << " qOverR " << fabs(seed.get_qOverR()) * q
0359 << " x " << TrackSeedHelper::get_x(&seed)
0360 << " y " << TrackSeedHelper::get_y(&seed)
0361 << " z " << TrackSeedHelper::get_z(&seed)
0362 << " pT " << seed.get_pt()
0363 << " eta " << seed.get_eta()
0364 << " phi " << seed.get_phi()
0365 << std::endl;
0366 }
0367 if(Verbosity() > 5)
0368 {
0369 TrackSeed* readseed = _track_map->get(seed_index);
0370 readseed->identify();
0371 }
0372
0373 seed_index++;
0374 }
0375 }