2323#include " SimulationDataFormat/MCEventLabel.h"
2424#include " SimulationDataFormat/MCCompLabel.h"
2525#include " MathUtils/Utils.h"
26- #include " ReconstructionDataFormats/TrackTPCITS.h"
2726#include " ReconstructionDataFormats/Track.h"
27+ #include " ReconstructionDataFormats/DCA.h"
2828#include " ReconstructionDataFormats/PrimaryVertex.h"
29- #include " DataFormatsFT0/RecPoints.h"
3029#include " DetectorsVertexing/PVertexerHelpers.h"
3130#include " DetectorsVertexing/PVertexerParams.h"
32- #include " FT0Reconstruction/InteractionTag .h"
31+ #include " ReconstructionDataFormats/GlobalTrackID .h"
3332#include " gsl/span"
33+ #include < numeric>
3434
3535namespace o2
3636{
@@ -50,11 +50,21 @@ class PVertexer
5050 OK };
5151
5252 void init ();
53- int process (gsl::span<const o2d::TrackTPCITS> tracksITSTPC, gsl::span<const o2::ft0::RecPoints> ft0Data,
53+
54+ template <typename TR, typename BC>
55+ int process (const TR& tracks, const gsl::span<o2d::GlobalTrackID> gids, const BC& bcData,
5456 std::vector<PVertex>& vertices, std::vector<o2d::VtxTrackIndex>& vertexTrackIDs, std::vector<V2TRef>& v2tRefs,
55- gsl::span<const o2::MCCompLabel> lblITS, gsl::span<const o2::MCCompLabel> lblTPC, std::vector<o2::MCEventLabel>& lblVtx);
57+ gsl::span<const o2::MCCompLabel> lblITS, gsl::span<const o2::MCCompLabel> lblTPC, std::vector<o2::MCEventLabel>& lblVtx)
58+ {
59+ auto nv = process (tracks, gids, bcData, vertices, vertexTrackIDs, v2tRefs);
60+ if (lblITS.size () && lblTPC.size ()) {
61+ createMCLabels (lblITS, lblTPC, vertices, vertexTrackIDs, v2tRefs, lblVtx);
62+ }
63+ return nv;
64+ }
5665
57- int process (gsl::span<const o2d::TrackTPCITS> tracksITSTPC, gsl::span<const o2::ft0::RecPoints> ft0Data,
66+ template <typename TR, typename BC>
67+ int process (const TR& tracks, const gsl::span<o2d::GlobalTrackID> gids, const BC& bcData,
5868 std::vector<PVertex>& vertices, std::vector<o2d::VtxTrackIndex>& vertexTrackIDs, std::vector<V2TRef>& v2tRefs);
5969
6070 static void createMCLabels (gsl::span<const o2::MCCompLabel> lblITS, gsl::span<const o2::MCCompLabel> lblTPC,
@@ -76,8 +86,8 @@ class PVertexer
7686 void setBunchFilling (const o2::BunchFilling& bf);
7787
7888 void setBz (float bz) { mBz = bz; }
79- void setValidateWithFT0 (bool v) { mValidateWithFT0 = v; }
80- bool getValidateWithFT0 () const { return mValidateWithFT0 ; }
89+ void setValidateWithIR (bool v) { mValidateWithIR = v; }
90+ bool getValidateWithIR () const { return mValidateWithIR ; }
8191
8292 auto & getTracksPool () const { return mTracksPool ; }
8393 auto & getTimeZClusters () const { return mTimeZClusters ; }
@@ -106,9 +116,14 @@ class PVertexer
106116 void initMeanVertexConstraint ();
107117 void applyConstraint (VertexSeed& vtxSeed) const ;
108118 bool upscaleSigma (VertexSeed& vtxSeed) const ;
109- void createTracksPool (gsl::span<const o2d::TrackTPCITS> tracksITSTPC);
119+
120+ template <typename TR>
121+ void createTracksPool (const TR& tracks, gsl::span<const o2d::GlobalTrackID> gids);
122+
110123 int findVertices (const VertexingInput& input, std::vector<PVertex>& vertices, std::vector<GTrackID>& vertexTrackIDs, std::vector<V2TRef>& v2tRefs);
111- std::pair<int , int > getBestFT0Trigger (const PVertex& vtx, gsl::span<const o2::ft0::RecPoints> ft0Data, int & currEntry) const ;
124+
125+ template <typename BC>
126+ std::pair<int , int > getBestIR (const PVertex& vtx, const BC& bcData, int & currEntry) const ;
112127
113128 int dbscan_RangeQuery (int idxs, std::vector<int >& cand, const std::vector<int >& status);
114129 void dbscan_clusterize ();
@@ -127,13 +142,12 @@ class PVertexer
127142 std::vector<int > mClusterTrackIDs ; // /< IDs of tracks making the clusters
128143
129144 float mBz = 0 .; // /< mag.field at beam line
130- bool mValidateWithFT0 = false ; // /< require vertex validation with FT0 (if available)
145+ bool mValidateWithIR = false ; // /< require vertex validation with InteractionRecords (if available)
131146
132147 o2::InteractionRecord mStartIR {0 , 0 }; // /< IR corresponding to the start of the TF
133148
134149 // /========== Parameters to be set externally, e.g. from CCDB ====================
135150 const PVertexerParams* mPVParams = nullptr ;
136- const o2::ft0::InteractionTag* mFT0Params = nullptr ;
137151 float mTukey2I = 0 ; // /< 1./[Tukey parameter]^2
138152 static constexpr float kDefTukey = 5 .0f ; // /< def.value for tukey constant
139153 static constexpr float kHugeF = 1 .e12 ; // /< very large float
@@ -166,6 +180,149 @@ inline bool PVertexer::upscaleSigma(VertexSeed& vtxSeed) const
166180 return false ;
167181}
168182
183+ // ___________________________________________________________________
184+ template <typename TR>
185+ void PVertexer::createTracksPool (const TR& tracks, gsl::span<const o2d::GlobalTrackID> gids)
186+ {
187+ // create pull of all candidate tracks in a global array ordered in time
188+ mTracksPool .clear ();
189+ mSortedTrackID .clear ();
190+
191+ auto ntGlo = tracks.size ();
192+ mTracksPool .reserve (ntGlo);
193+ // check all containers
194+ float vtxErr2 = 0.5 * (mMeanVertex .getSigmaX2 () + mMeanVertex .getSigmaY2 ());
195+ float pullIniCut = 9 .; // RS FIXME pullIniCut should be a parameter
196+ o2d::DCA dca;
197+
198+ for (uint32_t i = 0 ; i < ntGlo; i++) {
199+ o2::track::TrackParCov trc = tracks[i];
200+ if (!trc.propagateToDCA (mMeanVertex , mBz , &dca, mPVParams ->dcaTolerance ) ||
201+ dca.getY () * dca.getY () / (dca.getSigmaY2 () + vtxErr2) > mPVParams ->pullIniCut ) {
202+ continue ;
203+ }
204+ auto & tvf = mTracksPool .emplace_back (trc, tracks[i].getTimeMUS (), gids[i]);
205+ mStatZErr .add (std::sqrt (trc.getSigmaZ2 ()));
206+ mStatTErr .add (tvf.timeEst .getTimeStampError ());
207+ }
208+ // TODO: try to narrow timestamps using tof times
209+ auto [zerrMean, zerrRMS] = mStatZErr .getMeanRMS2 <float >();
210+
211+ auto [terrMean, terrRMS] = mStatTErr .getMeanRMS2 <float >();
212+
213+ if (mTracksPool .empty ()) {
214+ return ;
215+ }
216+ //
217+ mSortedTrackID .resize (mTracksPool .size ());
218+ std::iota (mSortedTrackID .begin (), mSortedTrackID .end (), 0 );
219+
220+ std::sort (mSortedTrackID .begin (), mSortedTrackID .end (), [this ](int i, int j) {
221+ return this ->mTracksPool [i].timeEst .getTimeStamp () < this ->mTracksPool [j].timeEst .getTimeStamp ();
222+ });
223+
224+ auto tMin = mTracksPool [mSortedTrackID .front ()].timeEst .getTimeStamp ();
225+ auto tMax = mTracksPool [mSortedTrackID .back ()].timeEst .getTimeStamp ();
226+ }
227+
228+ // ___________________________________________________________________
229+ template <typename TR, typename BC>
230+ int PVertexer::process (const TR& tracks, gsl::span<o2d::GlobalTrackID> gids, const BC& bcData,
231+ std::vector<PVertex>& vertices, std::vector<o2d::VtxTrackIndex>& vertexTrackIDs, std::vector<V2TRef>& v2tRefs)
232+ {
233+ createTracksPool (tracks, gids);
234+ dbscan_clusterize ();
235+
236+ std::vector<PVertex> verticesLoc;
237+ std::vector<GTrackID> vertexTrackIDsLoc;
238+ std::vector<V2TRef> v2tRefsLoc;
239+ std::vector<float > validationTimes;
240+
241+ for (auto tc : mTimeZClusters ) {
242+ VertexingInput inp;
243+ // inp.idRange = gsl::span<int>((int*)&mSortedTrackID[tc.first], tc.count);
244+ inp.idRange = gsl::span<int >((int *)&mClusterTrackIDs [tc.first ], tc.count );
245+ inp.scaleSigma2 = 3 . * estimateScale2 ();
246+ inp.timeEst = tc.timeEst ;
247+ findVertices (inp, verticesLoc, vertexTrackIDsLoc, v2tRefsLoc);
248+ }
249+
250+ // sort in time
251+ std::vector<int > vtTimeSortID (verticesLoc.size ());
252+ std::iota (vtTimeSortID.begin (), vtTimeSortID.end (), 0 );
253+ std::sort (vtTimeSortID.begin (), vtTimeSortID.end (), [&verticesLoc](int i, int j) {
254+ return verticesLoc[i].getTimeStamp ().getTimeStamp () < verticesLoc[j].getTimeStamp ().getTimeStamp ();
255+ });
256+
257+ vertices.clear ();
258+ v2tRefs.clear ();
259+ vertexTrackIDs.clear ();
260+ vertices.reserve (verticesLoc.size ());
261+ v2tRefs.reserve (v2tRefsLoc.size ());
262+ vertexTrackIDs.reserve (vertexTrackIDsLoc.size ());
263+
264+ int trCopied = 0 , count = 0 , vtimeID = 0 ;
265+ for (auto i : vtTimeSortID) {
266+ auto & vtx = verticesLoc[i];
267+
268+ bool irSet = setCompatibleIR (vtx);
269+ if (!irSet) {
270+ continue ;
271+ }
272+ // do we need to validate by Int. records ?
273+ if (mValidateWithIR ) {
274+ auto bestMatch = getBestIR (vtx, bcData, vtimeID);
275+ if (bestMatch.first >= 0 ) {
276+ vtx.setFlags (PVertex::TimeValidated);
277+ if (bestMatch.second == 1 ) {
278+ vtx.setIR (bcData[bestMatch.first ].getInteractionRecord ());
279+ }
280+ LOG (DEBUG) << " Validated with t0 " << bestMatch.first << " with " << bestMatch.second << " candidates" ;
281+ } else if (vtx.getNContributors () >= mPVParams ->minNContributorsForIRcut ) {
282+ LOG (DEBUG) << " Discarding " << vtx;
283+ continue ; // reject
284+ }
285+ }
286+ vertices.push_back (vtx);
287+ int it = v2tRefsLoc[i].getFirstEntry (), itEnd = it + v2tRefsLoc[i].getEntries (), dest0 = vertexTrackIDs.size ();
288+ for (; it < itEnd; it++) {
289+ auto & gid = vertexTrackIDs.emplace_back (vertexTrackIDsLoc[it]);
290+ gid.setPVContributor ();
291+ }
292+ v2tRefs.emplace_back (dest0, v2tRefsLoc[i].getEntries ());
293+ LOG (DEBUG) << " #" << count++ << " " << vertices.back () << " | " << v2tRefs.back ().getEntries () << " indices from " << v2tRefs.back ().getFirstEntry (); // RS REM
294+ }
295+
296+ return vertices.size ();
297+ }
298+
299+ // ___________________________________________________________________
300+ template <typename BC>
301+ std::pair<int , int > PVertexer::getBestIR (const PVertex& vtx, const BC& bcData, int & currEntry) const
302+ {
303+ // select best matching interaction record
304+ int best = -1 , n = bcData.size ();
305+ while (currEntry < n && bcData[currEntry].getInteractionRecord () < vtx.getIRMin ()) {
306+ currEntry++; // skip all times which have no chance to be matched
307+ }
308+ int i = currEntry, nCompatible = 0 ;
309+ float bestDf = 1e12 ;
310+ auto tVtxNS = (vtx.getTimeStamp ().getTimeStamp () + mPVParams ->timeBiasMS ) * 1e3 ; // time in ns
311+ while (i < n) {
312+ if (bcData[i].getInteractionRecord () > vtx.getIRMax ()) {
313+ break ;
314+ }
315+ nCompatible++;
316+ auto dfa = std::abs (bcData[i].getInteractionRecord ().differenceInBCNS (mStartIR ) - tVtxNS);
317+ if (dfa <= bestDf) {
318+ bestDf = dfa;
319+ best = i;
320+ }
321+ i++;
322+ }
323+ return {best, nCompatible};
324+ }
325+
169326} // namespace vertexing
170327} // namespace o2
171328#endif
0 commit comments