diff --git a/Detectors/TPC/workflow/include/TPCWorkflow/TPCRefitter.h b/Detectors/TPC/workflow/include/TPCWorkflow/TPCRefitter.h index bec29a4883533..31a5ce756142a 100644 --- a/Detectors/TPC/workflow/include/TPCWorkflow/TPCRefitter.h +++ b/Detectors/TPC/workflow/include/TPCWorkflow/TPCRefitter.h @@ -23,7 +23,7 @@ struct CorrectionMapsLoaderGloOpts; namespace o2::trackstudy { /// create a processor spec -o2::framework::DataProcessorSpec getTPCRefitterSpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, bool useMC, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts); +o2::framework::DataProcessorSpec getTPCRefitterSpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, bool useMC, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts, bool requestCosmics = false); } // namespace o2::trackstudy diff --git a/Detectors/TPC/workflow/src/TPCRefitter.cxx b/Detectors/TPC/workflow/src/TPCRefitter.cxx index b30f2002083ee..338c55935a6e3 100644 --- a/Detectors/TPC/workflow/src/TPCRefitter.cxx +++ b/Detectors/TPC/workflow/src/TPCRefitter.cxx @@ -25,6 +25,7 @@ #include "DetectorsCommonDataFormats/DetID.h" #include "DetectorsBase/GRPGeomHelper.h" #include "TPCWorkflow/TPCRefitter.h" +#include "GPUTPCGMMergedTrackHit.h" #include "GPUO2InterfaceRefit.h" #include "TPCBase/ParameterElectronics.h" #include "CommonUtils/TreeStreamRedirector.h" @@ -91,7 +92,7 @@ class TPCRefitterSpec final : public Task bool mUseR = false; bool mEnableDCA = false; int mWriteTrackClusters = false; - bool mSampleTsallis{false}; ///< perform sampling of unbinned data + bool mDoSampling{false}; ///< perform sampling of unbinned data bool mDoRefit{true}; ///< perform refit of TPC track std::unique_ptr mDBGOutTPC; ///< per track streamer for TPC tracks std::unique_ptr mDBGOutITSTPC; ///< per track streamer for ITS-TPC tracks @@ -118,7 +119,7 @@ class TPCRefitterSpec final : public Task std::unique_ptr mTPCRefitter; ///< TPC refitter used for TPC tracks refit during the reconstruction std::vector mIntRecs; - bool processTPCTrack(int itr, o2::utils::TreeStreamRedirector* streamer); + bool processTPCTrack(int itr, o2::utils::TreeStreamRedirector* streamer, const o2::its::TrackITS* its = nullptr, const o2::dataformats::TrackTPCITS* itstpc = nullptr); }; void TPCRefitterSpec::init(InitContext& ic) @@ -134,7 +135,7 @@ void TPCRefitterSpec::init(InitContext& ic) mDCAMinNCl = ic.options().get("dcaMinNCl"); mSqrt = ic.options().get("sqrts"); mSamplingFactor = ic.options().get("sampling-factor"); - mSampleTsallis = ic.options().get("sample-unbinned-tsallis"); + mDoSampling = ic.options().get("do-sampling"); mDoRefit = ic.options().get("do-refit"); mStudyType = ic.options().get("study-type"); mWriterType = ic.options().get("writer-type"); @@ -275,19 +276,10 @@ void TPCRefitterSpec::process(o2::globaltracking::RecoContainer& recoData) for (const auto& tpcitsTrack : mITSTPCTracksArray) { const auto idxTPC = tpcitsTrack.getRefTPC().getIndex(); const auto idxITS = tpcitsTrack.getRefITS().getIndex(); - const bool useTPCTrack = processTPCTrack(idxTPC, mDBGOutITSTPC.get()); - if (useTPCTrack && mDBGOutITSTPC) { - if (idxITS >= mITSTracksArray.size()) { - LOGP(fatal, "ITS index {} out of array size {}", idxITS, mITSTracksArray.size()); - } - (*mDBGOutITSTPC) << "its" - << "its=" << mITSTracksArray[idxITS] - << "\n"; - - (*mDBGOutITSTPC) << "itstpc" - << "itstpc=" << tpcitsTrack - << "\n"; - }; + if (idxITS >= mITSTracksArray.size()) { + LOGP(fatal, "ITS index {} out of array size {}", idxITS, mITSTracksArray.size()); + } + processTPCTrack(idxTPC, mDBGOutITSTPC.get(), &mITSTracksArray[idxITS], &tpcitsTrack); } } } @@ -330,12 +322,13 @@ bool TPCRefitterSpec::getDCAs(const o2::track::TrackPar& track, float& dcar, flo return ok; } -bool TPCRefitterSpec::processTPCTrack(int itr, o2::utils::TreeStreamRedirector* streamer) +bool TPCRefitterSpec::processTPCTrack(int itr, o2::utils::TreeStreamRedirector* streamer, const o2::its::TrackITS* its, const o2::dataformats::TrackTPCITS* itstpc) { auto prop = o2::base::Propagator::Instance(); static long counter = -1; std::vector clSector, clRow; + std::vector flags; std::vector clX, clY, clZ, clXI, clYI, clZI, clQtot, clQmax; // *I are the uncorrected cluster positions float dcar, dcaz, dcarRef, dcazRef; @@ -344,10 +337,19 @@ bool TPCRefitterSpec::processTPCTrack(int itr, o2::utils::TreeStreamRedirector* return false; } - if (mSampleTsallis) { - float weight = 0; + bool sampleTsallis = false; + bool sampleMB = false; + float tsallisWeight = 0; + if (mDoSampling) { std::uniform_real_distribution<> distr(0., 1.); - if (!o2::math_utils::Tsallis::downsampleTsallisCharged(tr.getPt(), mSamplingFactor, mSqrt, weight, distr(mGenerator))) { + if (!o2::math_utils::Tsallis::downsampleTsallisCharged(tr.getPt(), mSamplingFactor, mSqrt, tsallisWeight, distr(mGenerator))) { + sampleTsallis = true; + } + if (distr(mGenerator) < mSamplingFactor) { + sampleMB = true; + } + + if (!sampleMB && !sampleTsallis) { return false; } } @@ -380,17 +382,27 @@ bool TPCRefitterSpec::processTPCTrack(int itr, o2::utils::TreeStreamRedirector* return true; }; - auto prepClus = [this, &tr, &clSector, &clRow, &clX, &clY, &clZ, &clXI, &clYI, &clZI, &clQtot, &clQmax](float t) { // extract cluster info + auto prepClus = [this, &tr, &clSector, &clRow, &clX, &clY, &clZ, &clXI, &clYI, &clZI, &clQtot, &clQmax, &flags](float t) { // extract cluster info int count = tr.getNClusters(); const auto* corrMap = this->mTPCCorrMapsLoader.getCorrMap(); const o2::tpc::ClusterNative* cl = nullptr; for (int ic = count; ic--;) { uint8_t sector, row; - cl = &tr.getCluster(this->mTPCTrackClusIdx, ic, *this->mTPCClusterIdxStruct, sector, row); + uint32_t clusterIndex; + o2::tpc::TrackTPC::getClusterReference(mTPCTrackClusIdx, ic, sector, row, clusterIndex, tr.getClusterRef()); + unsigned int absoluteIndex = mTPCClusterIdxStruct->clusterOffset[sector][row] + clusterIndex; + cl = &mTPCClusterIdxStruct->clusters[sector][row][clusterIndex]; + uint8_t clflags = cl->getFlags(); + // clMap[rowIndex] = true; + if (mTPCRefitterShMap[absoluteIndex] & GPUCA_NAMESPACE::gpu::GPUTPCGMMergedTrackHit::flagShared) { + clflags |= 0x10; + } + // cl = &tr.getCluster(this->mTPCTrackClusIdx, ic, *this->mTPCClusterIdxStruct, sector, row); clSector.emplace_back(sector); clRow.emplace_back(row); clQtot.emplace_back(cl->getQtot()); clQmax.emplace_back(cl->getQmax()); + flags.emplace_back(clflags); float x, y, z; // ideal transformation without distortions corrMap->TransformIdeal(sector, row, cl->getPad(), cl->getTime(), x, y, z, t); // nominal time of the track @@ -438,19 +450,28 @@ bool TPCRefitterSpec::processTPCTrack(int itr, o2::utils::TreeStreamRedirector* if (streamer) { (*streamer) << "tpc" << "counter=" << counter - << "iniTrack=" << tr; + << "tfCounter=" << mTFCount + << "tpc=" << tr; if (mDoRefit) { (*streamer) << "tpc" - << "iniTrackRef=" << trf + << "tpcRF=" << trf << "time=" << tr.getTime0() << "chi2refit=" << chi2refit; } + if (mDoSampling) { + (*streamer) << "tpc" + << "tsallisWeight=" << tsallisWeight + << "sampleTsallis=" << sampleTsallis + << "sampleMB=" << sampleMB; + } + if (mWriteTrackClusters) { (*streamer) << "tpc" << "clSector=" << clSector - << "clRow=" << clRow; + << "clRow=" << clRow + << "flags=" << flags; if ((mWriteTrackClusters & 0x1) == 0x1) { (*streamer) << "tpc" @@ -471,6 +492,15 @@ bool TPCRefitterSpec::processTPCTrack(int itr, o2::utils::TreeStreamRedirector* << "clYI=" << clYI // ideal (uncorrected) cluster positions << "clZI=" << clZI; // ideal (uncorrected) cluster positions } + + if (its) { + (*streamer) << "tpc" + << "its=" << *its; + } + if (itstpc) { + (*streamer) << "tpc" + << "itstpc=" << *itstpc; + } } if (mEnableDCA) { @@ -545,7 +575,7 @@ bool TPCRefitterSpec::processTPCTrack(int itr, o2::utils::TreeStreamRedirector* return true; } -DataProcessorSpec getTPCRefitterSpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, bool useMC, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts) +DataProcessorSpec getTPCRefitterSpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, bool useMC, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts, bool requestCosmics) { std::vector outputs; Options opts{ @@ -561,7 +591,7 @@ DataProcessorSpec getTPCRefitterSpec(GTrackID::mask_t srcTracks, GTrackID::mask_ {"dcaMinPt", VariantType::Float, 1.f, {"Min pT of tracks propagated to DCA"}}, {"dcaMinNCl", VariantType::Int, 80, {"Min number of clusters for tracks propagated to DCA"}}, {"sqrts", VariantType::Float, 13600.f, {"Centre of mass energy used for downsampling"}}, - {"sample-unbinned-tsallis", VariantType::Bool, false, {"Perform sampling of unbinned data based on Tsallis function"}}, + {"do-sampling", VariantType::Bool, false, {"Perform sampling, min. bias and on Tsallis function, using 'sampling-factor'"}}, {"sampling-factor", VariantType::Float, 0.001f, {"Sampling factor in case sample-unbinned-tsallis is used"}}, {"study-type", VariantType::Int, 1, {"Bitmask of study type: 0x1 = TPC only, 0x2 = TPC + ITS"}}, {"writer-type", VariantType::Int, 1, {"Bitmask of writer type: 0x1 = per track streamer, 0x2 = per TF vectors"}}, @@ -570,6 +600,9 @@ DataProcessorSpec getTPCRefitterSpec(GTrackID::mask_t srcTracks, GTrackID::mask_ dataRequest->requestTracks(srcTracks, useMC); dataRequest->requestClusters(srcClusters, useMC); + if (requestCosmics) { + dataRequest->requestCoscmicTracks(useMC); + } auto ggRequest = std::make_shared(false, // orbitResetTime true, // GRPECS=true false, // GRPLHCIF diff --git a/Detectors/TPC/workflow/src/tpc-refitter-workflow.cxx b/Detectors/TPC/workflow/src/tpc-refitter-workflow.cxx index 18bd0792cc9e4..bdeb6e23addf7 100644 --- a/Detectors/TPC/workflow/src/tpc-refitter-workflow.cxx +++ b/Detectors/TPC/workflow/src/tpc-refitter-workflow.cxx @@ -39,6 +39,7 @@ void customize(std::vector& workflowOptions) // option allowing to set parameters std::vector options{ {"enable-mc", o2::framework::VariantType::Bool, false, {"enable MC propagation"}}, + {"enable-cosmics", o2::framework::VariantType::Bool, false, {"enable reading cosmics"}}, {"track-sources", VariantType::String, std::string{GID::ALL}, {"comma-separated list of track sources to use"}}, {"cluster-sources", VariantType::String, std::string{GID::ALL}, {"comma-separated list of cluster sources to use"}}, {"disable-root-input", VariantType::Bool, false, {"disable root-files input reader"}}, @@ -77,8 +78,12 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) specs.emplace_back(o2::tpc::getTPCScalerSpec(enableIDCs, enableMShape)); } + const auto enableCosmics = !configcontext.options().get("enable-cosmics"); o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, useMC); o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, useMC); // P-vertex is always needed + if (enableCosmics) { + o2::globaltracking::InputHelper::addInputSpecsCosmics(configcontext, specs, useMC); + } specs.emplace_back(o2::trackstudy::getTPCRefitterSpec(srcTrc, srcCls, useMC, sclOpt)); // configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit