13#include <TStopwatch.h>
50#include "GPUParam.inc"
74 : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(
src), mUseTPCCl(useTPCCl), mUseMC(useMC) {}
80 void process(
o2::globaltracking::RecoContainer& recoData);
81 o2::dataformats::V0Ext
processV0(
int iv,
o2::globaltracking::RecoContainer& recoData);
85 bool refitV0(const
V0ID&
id,
o2::dataformats::
V0&
v0,
o2::globaltracking::RecoContainer& recoData);
87 std::shared_ptr<
o2::base::GRPGeomRequest> mGGCCDBRequest;
89 std::unique_ptr<o2::utils::TreeStreamRedirector> mDBGOut;
92 bool mUseTPCCl =
false;
96 int mNTPCOccBinLength = 0;
97 float mNTPCOccBinLengthInv;
98 float mTPCTBinMUSInv = 0.f;
101 std::vector<float> mTBinClOccAft, mTBinClOccBef;
102 std::unique_ptr<o2::steer::MCKinematicsReader> mcReader;
103 std::shared_ptr<o2::gpu::GPUParam> mParam =
nullptr;
109 mDBGOut = std::make_unique<o2::utils::TreeStreamRedirector>(
"svStudy.root",
"recreate");
114 mcReader = std::make_unique<o2::steer::MCKinematicsReader>(
"collisioncontext.root");
122 updateTimeDependentParams(pc);
125 gsl::span<const unsigned int> TPCRefitterOccMap = recoData.
occupancyMapTPC;
128 mTBinClOccBef.resize(1);
129 mTBinClOccAft.resize(1);
131 mNTPCOccBinLength = mParam->rec.tpc.occupancyMapTimeBins;
132 mTBinClOccBef.clear();
133 mTBinClOccAft.clear();
136 mNTPCOccBinLengthInv = 1. / mNTPCOccBinLength;
139 mTBinClOccAft.resize(nTPCOccBins);
140 mTBinClOccBef.resize(nTPCOccBins);
141 float sm = 0., tb = 0.5 * mNTPCOccBinLength;
142 std::vector<float> mltHistTB(nTPCOccBins);
143 for (
int i = 0;
i < nTPCOccBins;
i++) {
144 mltHistTB[
i] = mParam->GetUnscaledMult(tb);
145 tb += mNTPCOccBinLength;
147 for (
int i = nTPCOccBins;
i--;) {
149 if (
i + sumBins < nTPCOccBins) {
150 sm -= mltHistTB[
i + sumBins];
152 mTBinClOccAft[
i] = sm;
155 for (
int i = 0;
i < nTPCOccBins;
i++) {
157 if (
i - sumBins > 0) {
158 sm -= mltHistTB[
i - sumBins];
160 mTBinClOccBef[
i] = sm;
171 static bool initOnceDone =
false;
176 mFitterV0.setBz(mBz);
177 mFitterV0.setUseAbsDCA(svparam.useAbsDCA);
178 mFitterV0.setPropagateToPCA(
false);
179 mFitterV0.setMaxR(svparam.maxRIni);
180 mFitterV0.setMinParamChange(svparam.minParamChange);
181 mFitterV0.setMinRelChi2Change(svparam.minRelChi2Change);
182 mFitterV0.setMaxDZIni(svparam.maxDZIni);
183 mFitterV0.setMaxDXYIni(svparam.maxDXYIni);
184 mFitterV0.setMaxChi2(svparam.maxChi2);
186 mFitterV0.setUsePropagator(svparam.usePropagator);
187 mFitterV0.setRefitWithMatCorr(svparam.refitWithMatCorr);
188 mFitterV0.setMaxStep(svparam.maxStep);
189 mFitterV0.setMaxSnp(svparam.maxSnp);
190 mFitterV0.setMinXSeed(svparam.minXSeed);
198 mTPCTBinMUSInv = 1. / elParam.ZbinWidth;
201 mFitterV0.setBz(mBz);
209 auto v0s = recoData.
getV0s();
213 const auto& v0id = v0IDs[iv];
214 if (mRefit && !refitV0(v0id, v0ext.
v0, recoData)) {
218 const auto& v0sel = mRefit ? v0ext.
v0 : v0s[iv];
219 if (mMaxEta < std::abs(v0sel.getEta())) {
223 if (mSelK0 > 0 && std::abs(std::sqrt(v0sel.calcMass2AsK0()) - 0.497) > mSelK0) {
234 for (
int ip = 0; ip < 2; ip++) {
235 auto& prInfo = v0ext.
prInfo[ip];
239 if (lb[ip].isValid()) {
240 prInfo.corrGlo = !lb[ip].
isFake();
245 prInfo.trackTPC = tpcTr;
246 prInfo.nClTPC = tpcTr.getNClusters();
248 if (lb[ip].isValid()) {
249 prInfo.corrTPC = !lb[ip].
isFake();
251 if (mParam && mUseTPCCl) {
252 uint8_t clSect = 0, clRow = 0;
254 tpcTr.getClusterReference(clRefs, tpcTr.getNClusterReferences() - 1, clSect, clRow, clIdx);
256 prInfo.lowestRow = clRow;
257 int npads = mParam->tpcGeometry.NPads(clRow);
258 prInfo.padFromEdge = uint8_t(clus.getPad());
259 if (prInfo.padFromEdge > npads / 2) {
260 prInfo.padFromEdge = npads - 1 - prInfo.padFromEdge;
269 prInfo.nClITS = itsTr.getNClusters();
271 if (lb[ip].isValid()) {
272 prInfo.corrITS = !lb[ip].
isFake();
274 for (
int il = 0; il < 7; il++) {
275 if (itsTr.hasHitOnLayer(il)) {
276 prInfo.pattITS |= 0x1 << il;
281 prInfo.nClITS = itsTrf.getNClusters();
283 if (lb[ip].isValid()) {
284 prInfo.corrITS = !lb[ip].
isFake();
286 for (
int il = 0; il < 7; il++) {
287 if (itsTrf.hasHitOnLayer(il)) {
288 prInfo.pattITS |= 0x1 << il;
291 prInfo.pattITS |= 0x1 << 31;
296 prInfo.chi2ITSTPC = mtc.getChi2Match();
297 if (lb[ip].isValid()) {
298 prInfo.corrITSTPC = !lb[ip].
isFake();
302 if (mUseMC && lb[ip].isValid()) {
303 mcTrks[ip] = mcReader->getTrack(lb[ip]);
306 if (mUseMC && (mcTrks[0] !=
nullptr) && (mcTrks[1] !=
nullptr)) {
308 if (lb[0].getSourceID() == lb[1].getSourceID() && lb[0].getEventID() == lb[1].getEventID() &&
309 mcTrks[0]->getMotherTrackId() == mcTrks[1]->getMotherTrackId() && mcTrks[0]->getMotherTrackId() >= 0) {
310 const auto mother = mcReader->getTrack(lb[0].getSourceID(), lb[0].getEventID(), mcTrks[0]->getMotherTrackId());
311 v0ext.
mcPID = mother->GetPdgCode();
320 auto nv0 = v0IDs.size();
321 if (nv0 > recoData.
getV0s().size()) {
324 std::map<int, std::vector<int>> pv2sv;
326 for (
int iv = 0; iv < nv0; iv++) {
327 const auto v0id = v0IDs[iv];
328 pv2sv[v0id.getVertexID()].push_back(iv);
330 std::vector<o2::dataformats::V0Ext> v0extVec;
331 for (
auto it : pv2sv) {
333 auto& vv = it.second;
334 if (pvID < 0 || vv.size() == 0) {
340 if (v0ext.v0ID.getVertexID() < 0) {
343 v0extVec.push_back(v0ext);
345 if (v0extVec.size()) {
347 float tpcOccBef = 0., tpcOccAft = 0.;
348 int tb = pv.getTimeStamp().getTimeStamp() * mTPCTBinMUSInv * mNTPCOccBinLengthInv;
349 tpcOccBef = tb < 0 ? mTBinClOccBef[0] : (tb >= mTBinClOccBef.size() ? mTBinClOccBef.back() : mTBinClOccBef[tb]);
350 tpcOccAft = tb < 0 ? mTBinClOccAft[0] : (tb >= mTBinClOccAft.size() ? mTBinClOccAft.back() : mTBinClOccAft[tb]);
353 <<
"orbit=" << recoData.
startIR.
orbit <<
"tfID=" << tfID <<
"tpcOccBef=" << tpcOccBef <<
"tpcOccAft=" << tpcOccAft
354 <<
"v0Ext=" << v0extVec
368 if (svparam.mTPCTrackPhotonTune && isTPConly) {
369 mFitterV0.setMaxDZIni(svparam.mTPCTrackMaxDZIni);
370 mFitterV0.setMaxDXYIni(svparam.mTPCTrackMaxDXYIni);
371 mFitterV0.setMaxChi2(svparam.mTPCTrackMaxChi2);
372 mFitterV0.setCollinear(
true);
374 int nCand = mFitterV0.process(seedP, seedN);
375 if (svparam.mTPCTrackPhotonTune && isTPConly) {
377 mFitterV0.setMaxDZIni(svparam.maxDZIni);
378 mFitterV0.setMaxDXYIni(svparam.maxDXYIni);
379 mFitterV0.setMaxChi2(svparam.maxChi2);
380 mFitterV0.setCollinear(
false);
386 if (!mFitterV0.isPropagateTracksToVertexDone(cand) && !mFitterV0.propagateTracksToVertex(cand)) {
389 const auto& trPProp = mFitterV0.
getTrack(0, cand);
390 const auto& trNProp = mFitterV0.
getTrack(1, cand);
391 std::array<float, 3> pP{}, pN{};
392 trPProp.getPxPyPzGlo(pP);
393 trNProp.getPxPyPzGlo(pN);
394 std::array<float, 3> pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]};
395 auto p2V0 = pV0[0] * pV0[0] + pV0[1] * pV0[1] + pV0[2] * pV0[2];
397 const auto v0XYZ = mFitterV0.getPCACandidatePos(cand);
398 float dx = v0XYZ[0] - pv.getX(), dy = v0XYZ[1] - pv.getY(), dz = v0XYZ[2] - pv.getZ(), prodXYZv0 = dx * pV0[0] + dy * pV0[1] + dz * pV0[2];
399 float cosPA = prodXYZv0 / std::sqrt((dx * dx + dy * dy + dz * dz) * p2V0);
420 std::vector<OutputSpec> outputs;
421 auto dataRequest = std::make_shared<DataRequest>();
423 dataRequest->requestTracks(srcTracks, useMC);
424 dataRequest->requestClusters(srcCls,
false);
425 dataRequest->requestPrimaryVertices(useMC);
426 dataRequest->requestSecondaryVertices(useMC);
427 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
428 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
true,
441 AlgorithmSpec{adaptFromTask<SVStudySpec>(dataRequest, ggRequest, srcTracks, useTPCcl, useMC)},
443 {
"refit", VariantType::Bool,
false, {
"refit SVertices"}},
444 {
"sel-k0", VariantType::Float, -1.f, {
"If positive, select K0s with this mass margin"}},
445 {
"max-eta", VariantType::Float, 1.2f, {
"Cut on track eta"}},
Defintions for N-prongs secondary vertex fit.
Definition of the GeometryManager class.
Helper for geometry and GRP related CCDB requests.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the MCTrack class.
Utility functions for MC particles.
Definition of the Names Generator class.
Definition of the parameter class for the detector electronics.
Wrapper container for different reconstructed object types.
Configurable params for secondary vertexer.
Result of refitting TPC-ITS matched track.
Reference on ITS/MFT clusters set.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
static const SVertexerParams & Instance()
GIndex getProngID(int i) const
Static class with identifiers, bitmasks and names for ALICE detectors.
T get(const char *key) const
ConfigParamRegistry const & options()
static size_t fillOccupancyMapGetSize(uint32_t nHbfPerTf, const GPUParam *param=nullptr)
static void paramUseExternalOccupancyMap(GPUParam *param, uint32_t nHbfPerTf, const uint32_t *occupancymap, int32_t occupancyMapSize)
static std::shared_ptr< GPUParam > getFullParamShared(float solenoidBz, uint32_t nHbfPerTf=0, std::unique_ptr< GPUO2InterfaceConfiguration > *pConfiguration=nullptr, std::unique_ptr< GPUSettingsO2 > *pO2Settings=nullptr, bool *autoMaxTimeBin=nullptr)
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
SVStudySpec(std::shared_ptr< DataRequest > dr, std::shared_ptr< o2::base::GRPGeomRequest > gr, GTrackID::mask_t src, bool useTPCCl, bool useMC)
o2::dataformats::V0Ext processV0(int iv, o2::globaltracking::RecoContainer &recoData)
void init(InitContext &ic) final
~SVStudySpec() final=default
void process(o2::globaltracking::RecoContainer &recoData)
void endOfStream(EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void run(ProcessingContext &pc) final
o2::gpu::gpustd::array< float, 6 > calcPCACovMatrixFlat(int cand=0) const
Track & getTrack(int i, int cand=0)
float getChi2AtPCACandidate(int cand=0) const
constexpr int LHCMaxBunches
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ConfigParamSpec > Options
detail::Bracket< float > Bracketf_t
o2::framework::DataProcessorSpec getSVStudySpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcCls, bool useMC)
create a processor spec
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
GTrackID getITSContributorGID(GTrackID source) const
o2::InteractionRecord startIR
GlobalIDSet getSingleDetectorRefs(GTrackID gidx) const
const o2::tpc::TrackTPC & getTPCTrack(GTrackID id) const
const o2::tpc::ClusterNativeAccess & getTPCClusters() const
auto getITSABRefs() const
auto getTPCTracksClusterRefs() const
o2::MCCompLabel getTrackMCLabel(GTrackID id) const
const o2::track::TrackParCov & getTrackParam(GTrackID gidx) const
const o2::dataformats::TrackTPCITS & getTPCITSTrack(GTrackID gid) const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
const o2::dataformats::PrimaryVertex & getPrimaryVertex(int i) const
const o2::its::TrackITS & getITSTrack(GTrackID gid) const
std::unique_ptr< o2::tpc::internal::getWorkflowTPCInput_ret > inputsTPCclusters
gsl::span< const unsigned int > occupancyMapTPC
externally set TPC clusters occupancy map
const ClusterNative * clusters[constants::MAXSECTOR][constants::MAXGLOBALPADROW]