13#include <TStopwatch.h>
50#include "GPUParam.inc"
75 : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(
src), mUseTPCCl(useTPCCl), mUseMC(useMC) {}
81 void process(
o2::globaltracking::RecoContainer& recoData);
82 o2::dataformats::V0Ext
processV0(
int iv,
o2::globaltracking::RecoContainer& recoData);
86 bool refitV0(const
V0ID&
id,
o2::dataformats::
V0&
v0,
o2::globaltracking::RecoContainer& recoData);
88 std::shared_ptr<
o2::base::GRPGeomRequest> mGGCCDBRequest;
90 std::unique_ptr<o2::utils::TreeStreamRedirector> mDBGOut;
93 bool mUseTPCCl =
false;
97 int mNTPCOccBinLength = 0;
98 float mNTPCOccBinLengthInv;
99 float mTPCTBinMUSInv = 0.f;
102 std::vector<float> mTBinClOccAft, mTBinClOccBef;
103 std::unique_ptr<o2::steer::MCKinematicsReader> mcReader;
104 std::shared_ptr<o2::gpu::GPUParam> mParam =
nullptr;
110 mDBGOut = std::make_unique<o2::utils::TreeStreamRedirector>(
"svStudy.root",
"recreate");
115 mcReader = std::make_unique<o2::steer::MCKinematicsReader>(
"collisioncontext.root");
123 updateTimeDependentParams(pc);
126 gsl::span<const unsigned int> TPCRefitterOccMap = recoData.
occupancyMapTPC;
129 mTBinClOccBef.resize(1);
130 mTBinClOccAft.resize(1);
132 mNTPCOccBinLength = mParam->rec.tpc.occupancyMapTimeBins;
133 mTBinClOccBef.clear();
134 mTBinClOccAft.clear();
137 mNTPCOccBinLengthInv = 1. / mNTPCOccBinLength;
140 mTBinClOccAft.resize(nTPCOccBins);
141 mTBinClOccBef.resize(nTPCOccBins);
142 float sm = 0., tb = 0.5 * mNTPCOccBinLength;
143 std::vector<float> mltHistTB(nTPCOccBins);
144 for (
int i = 0;
i < nTPCOccBins;
i++) {
145 mltHistTB[
i] = mParam->GetUnscaledMult(tb);
146 tb += mNTPCOccBinLength;
148 for (
int i = nTPCOccBins;
i--;) {
150 if (
i + sumBins < nTPCOccBins) {
151 sm -= mltHistTB[
i + sumBins];
153 mTBinClOccAft[
i] = sm;
156 for (
int i = 0;
i < nTPCOccBins;
i++) {
158 if (
i - sumBins > 0) {
159 sm -= mltHistTB[
i - sumBins];
161 mTBinClOccBef[
i] = sm;
172 static bool initOnceDone =
false;
177 mFitterV0.setBz(mBz);
178 mFitterV0.
setOldMode(svparam.oldDCAFitterMode);
179 mFitterV0.setUseAbsDCA(svparam.useAbsDCA);
180 mFitterV0.setPropagateToPCA(
false);
181 mFitterV0.setMaxR(svparam.maxRIni);
182 mFitterV0.setMinParamChange(svparam.minParamChange);
183 mFitterV0.setMinRelChi2Change(svparam.minRelChi2Change);
184 mFitterV0.setMaxDZIni(svparam.maxDZIni);
185 mFitterV0.setMaxDXYIni(svparam.maxDXYIni);
186 mFitterV0.setMaxChi2(svparam.maxChi2);
188 mFitterV0.setUsePropagator(svparam.usePropagator);
189 mFitterV0.setRefitWithMatCorr(svparam.refitWithMatCorr);
190 mFitterV0.setMaxStep(svparam.maxStep);
191 mFitterV0.setMaxSnp(svparam.maxSnp);
192 mFitterV0.setMinXSeed(svparam.minXSeed);
200 mTPCTBinMUSInv = 1. / elParam.ZbinWidth;
203 mFitterV0.setBz(mBz);
211 auto v0s = recoData.
getV0s();
215 const auto& v0id = v0IDs[iv];
216 if (mRefit && !refitV0(v0id, v0ext.
v0, recoData)) {
220 const auto& v0sel = mRefit ? v0ext.
v0 : v0s[iv];
221 if (mMaxEta < std::abs(v0sel.getEta())) {
225 if (mSelK0 > 0 && std::abs(std::sqrt(v0sel.calcMass2AsK0()) - 0.497) > mSelK0) {
236 for (
int ip = 0; ip < 2; ip++) {
237 auto& prInfo = v0ext.
prInfo[ip];
242 prInfo.corrGlo = !lb[ip].
isFake();
247 prInfo.trackTPC = tpcTr;
248 prInfo.nClTPC = tpcTr.getNClusters();
251 prInfo.corrTPC = !lb[ip].
isFake();
253 if (mParam && mUseTPCCl) {
254 uint8_t clSect = 0, clRow = 0;
256 tpcTr.getClusterReference(clRefs, tpcTr.getNClusterReferences() - 1, clSect, clRow, clIdx);
258 prInfo.lowestRow = clRow;
259 int npads = o2::gpu::GPUTPCGeometry::NPads(clRow);
260 prInfo.padFromEdge = uint8_t(clus.getPad());
261 if (prInfo.padFromEdge > npads / 2) {
262 prInfo.padFromEdge = npads - 1 - prInfo.padFromEdge;
271 prInfo.nClITS = itsTr.getNClusters();
274 prInfo.corrITS = !lb[ip].
isFake();
276 for (
int il = 0; il < 7; il++) {
277 if (itsTr.hasHitOnLayer(il)) {
278 prInfo.pattITS |= 0x1 << il;
283 prInfo.nClITS = itsTrf.getNClusters();
286 prInfo.corrITS = !lb[ip].
isFake();
288 for (
int il = 0; il < 7; il++) {
289 if (itsTrf.hasHitOnLayer(il)) {
290 prInfo.pattITS |= 0x1 << il;
293 prInfo.pattITS |= 0x1 << 31;
298 prInfo.chi2ITSTPC = mtc.getChi2Match();
300 prInfo.corrITSTPC = !lb[ip].
isFake();
304 if (mUseMC && lb[ip].
isValid()) {
305 mcTrks[ip] = mcReader->getTrack(lb[ip]);
308 if (mUseMC && (mcTrks[0] !=
nullptr) && (mcTrks[1] !=
nullptr)) {
310 if (lb[0].getSourceID() == lb[1].getSourceID() && lb[0].getEventID() == lb[1].getEventID() &&
311 mcTrks[0]->getMotherTrackId() == mcTrks[1]->getMotherTrackId() && mcTrks[0]->getMotherTrackId() >= 0) {
312 const auto mother = mcReader->getTrack(lb[0].getSourceID(), lb[0].getEventID(), mcTrks[0]->getMotherTrackId());
313 v0ext.
mcPID = mother->GetPdgCode();
322 auto nv0 = v0IDs.size();
323 if (nv0 > recoData.
getV0s().size()) {
326 std::map<int, std::vector<int>> pv2sv;
328 for (
int iv = 0; iv < nv0; iv++) {
329 const auto v0id = v0IDs[iv];
330 pv2sv[v0id.getVertexID()].push_back(iv);
332 std::vector<o2::dataformats::V0Ext> v0extVec;
333 for (
auto it : pv2sv) {
335 auto& vv = it.second;
336 if (pvID < 0 || vv.size() == 0) {
342 if (v0ext.v0ID.getVertexID() < 0) {
345 v0extVec.push_back(v0ext);
347 if (v0extVec.size()) {
349 float tpcOccBef = 0., tpcOccAft = 0.;
350 int tb = pv.getTimeStamp().getTimeStamp() * mTPCTBinMUSInv * mNTPCOccBinLengthInv;
351 tpcOccBef = tb < 0 ? mTBinClOccBef[0] : (tb >= mTBinClOccBef.size() ? mTBinClOccBef.back() : mTBinClOccBef[tb]);
352 tpcOccAft = tb < 0 ? mTBinClOccAft[0] : (tb >= mTBinClOccAft.size() ? mTBinClOccAft.back() : mTBinClOccAft[tb]);
355 <<
"orbit=" << recoData.
startIR.
orbit <<
"tfID=" << tfID <<
"tpcOccBef=" << tpcOccBef <<
"tpcOccAft=" << tpcOccAft
356 <<
"v0Ext=" << v0extVec
370 if (svparam.mTPCTrackPhotonTune && isTPConly) {
371 mFitterV0.setMaxDZIni(svparam.mTPCTrackMaxDZIni);
372 mFitterV0.setMaxDXYIni(svparam.mTPCTrackMaxDXYIni);
373 mFitterV0.setMaxChi2(svparam.mTPCTrackMaxChi2);
374 mFitterV0.setCollinear(
true);
376 int nCand = mFitterV0.process(seedP, seedN);
377 if (svparam.mTPCTrackPhotonTune && isTPConly) {
379 mFitterV0.setMaxDZIni(svparam.maxDZIni);
380 mFitterV0.setMaxDXYIni(svparam.maxDXYIni);
381 mFitterV0.setMaxChi2(svparam.maxChi2);
382 mFitterV0.setCollinear(
false);
388 if (!mFitterV0.isPropagateTracksToVertexDone(cand) && !mFitterV0.propagateTracksToVertex(cand)) {
391 const auto& trPProp = mFitterV0.
getTrack(0, cand);
392 const auto& trNProp = mFitterV0.
getTrack(1, cand);
393 std::array<float, 3> pP{}, pN{};
394 trPProp.getPxPyPzGlo(pP);
395 trNProp.getPxPyPzGlo(pN);
396 std::array<float, 3> pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]};
397 auto p2V0 = pV0[0] * pV0[0] + pV0[1] * pV0[1] + pV0[2] * pV0[2];
399 const auto v0XYZ = mFitterV0.getPCACandidatePos(cand);
400 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];
401 float cosPA = prodXYZv0 / std::sqrt((dx * dx + dy * dy + dz * dz) * p2V0);
422 std::vector<OutputSpec> outputs;
423 auto dataRequest = std::make_shared<DataRequest>();
425 dataRequest->requestTracks(srcTracks, useMC);
426 dataRequest->requestClusters(srcCls,
false);
427 dataRequest->requestPrimaryVertices(useMC);
428 dataRequest->requestSecondaryVertices(useMC);
429 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
430 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
true,
443 AlgorithmSpec{adaptFromTask<SVStudySpec>(dataRequest, ggRequest, srcTracks, useTPCcl, useMC)},
445 {
"refit", VariantType::Bool,
false, {
"refit SVertices"}},
446 {
"sel-k0", VariantType::Float, -1.f, {
"If positive, select K0s with this mass margin"}},
447 {
"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
Track & getTrack(int i, int cand=0)
std::array< float, 6 > calcPCACovMatrixFlat(int cand=0) const
float getChi2AtPCACandidate(int cand=0) const
constexpr int LHCMaxBunches
Defining ITS Vertex 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 ...
bool isValid(std::string alias)
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]