Skip to content

Commit 6e34758

Browse files
authored
Merge 6178630 into sapling-pr-archive-ktf
2 parents 0c44b5d + 6178630 commit 6e34758

File tree

12 files changed

+218
-36
lines changed

12 files changed

+218
-36
lines changed

DataFormats/simulation/include/SimulationDataFormat/DigitizationContext.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ class DigitizationContext
113113
/// Check collision parts for vertex consistency.
114114
bool checkVertexCompatibility(bool verbose = false) const;
115115

116+
/// retrieves collision context for a single timeframe-id (which may be needed by simulation)
117+
/// (Only copies collision context without QED information. This can be added to the result with the fillQED method
118+
/// in a second step. As a pre-condition, one should have called finalizeTimeframeStructure)
119+
DigitizationContext extractSingleTimeframe(int timeframeid, std::vector<int> const& sources_to_offset);
120+
116121
/// function reading the hits from a chain (previously initialized with initSimChains
117122
/// The hits pointer will be initialized (what to we do about ownership??)
118123
template <typename T>
@@ -128,8 +133,9 @@ class DigitizationContext
128133
// apply collision number cuts and potential relabeling of eventID
129134
void applyMaxCollisionFilter(long startOrbit, long orbitsPerTF, int maxColl);
130135

131-
// finalize timeframe structure (fixes the indices in mTimeFrameStartIndex)
132-
void finalizeTimeframeStructure(long startOrbit, long orbitsPerTF);
136+
/// finalize timeframe structure (fixes the indices in mTimeFrameStartIndex)
137+
// returns the number of timeframes
138+
int finalizeTimeframeStructure(long startOrbit, long orbitsPerTF);
133139

134140
// Sample and fix interaction vertices (according to some distribution). Makes sure that same event ids
135141
// have to have same vertex, as well as event ids associated to same collision.
@@ -173,7 +179,7 @@ class DigitizationContext
173179
// for each collision we may record/fix the interaction vertex (to be used in event generation)
174180
std::vector<math_utils::Point3D<float>> mInteractionVertices;
175181

176-
// the collision records _with_ QED interleaved;
182+
// the collision records **with** QED interleaved;
177183
std::vector<o2::InteractionTimeRecord> mEventRecordsWithQED;
178184
std::vector<std::vector<o2::steer::EventPart>> mEventPartsWithQED;
179185

DataFormats/simulation/src/DigitizationContext.cxx

Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <numeric> // for iota
2020
#include <MathUtils/Cartesian.h>
2121
#include <DataFormatsCalibration/MeanVertexObject.h>
22+
#include <filesystem>
2223

2324
using namespace o2::steer;
2425

@@ -196,10 +197,52 @@ o2::parameters::GRPObject const& DigitizationContext::getGRP() const
196197

197198
void DigitizationContext::saveToFile(std::string_view filename) const
198199
{
200+
// checks if the path content of filename exists ... otherwise it is created before creating the ROOT file
201+
auto ensure_path_exists = [](std::string_view filename) {
202+
try {
203+
// Extract the directory path from the filename
204+
std::filesystem::path file_path(filename);
205+
std::filesystem::path dir_path = file_path.parent_path();
206+
207+
// Check if the directory path is empty (which means filename was just a name without path)
208+
if (dir_path.empty()) {
209+
// nothing to do
210+
return true;
211+
}
212+
213+
// Create directories if they do not exist
214+
if (!std::filesystem::exists(dir_path)) {
215+
if (std::filesystem::create_directories(dir_path)) {
216+
// std::cout << "Directories created successfully: " << dir_path.string() << std::endl;
217+
return true;
218+
} else {
219+
std::cerr << "Failed to create directories: " << dir_path.string() << std::endl;
220+
return false;
221+
}
222+
}
223+
return true;
224+
} catch (const std::filesystem::filesystem_error& ex) {
225+
std::cerr << "Filesystem error: " << ex.what() << std::endl;
226+
return false;
227+
} catch (const std::exception& ex) {
228+
std::cerr << "General error: " << ex.what() << std::endl;
229+
return false;
230+
}
231+
};
232+
233+
if (!ensure_path_exists(filename)) {
234+
LOG(error) << "Filename contains path component which could not be created";
235+
return;
236+
}
237+
199238
TFile file(filename.data(), "RECREATE");
200-
auto cl = TClass::GetClass(typeid(*this));
201-
file.WriteObjectAny(this, cl, "DigitizationContext");
202-
file.Close();
239+
if (file.IsOpen()) {
240+
auto cl = TClass::GetClass(typeid(*this));
241+
file.WriteObjectAny(this, cl, "DigitizationContext");
242+
file.Close();
243+
} else {
244+
LOG(error) << "Could not write to file " << filename.data();
245+
}
203246
}
204247

205248
DigitizationContext* DigitizationContext::loadFromFile(std::string_view filename)
@@ -391,13 +434,15 @@ void DigitizationContext::applyMaxCollisionFilter(long startOrbit, long orbitsPe
391434
mEventParts = newparts;
392435
}
393436

394-
void DigitizationContext::finalizeTimeframeStructure(long startOrbit, long orbitsPerTF)
437+
int DigitizationContext::finalizeTimeframeStructure(long startOrbit, long orbitsPerTF)
395438
{
396439
mTimeFrameStartIndex = getTimeFrameBoundaries(mEventRecords, startOrbit, orbitsPerTF);
397440
LOG(info) << "Fixed " << mTimeFrameStartIndex.size() << " timeframes ";
398441
for (auto p : mTimeFrameStartIndex) {
399442
LOG(info) << p.first << " " << p.second;
400443
}
444+
445+
return mTimeFrameStartIndex.size();
401446
}
402447

403448
std::unordered_map<int, int> DigitizationContext::getCollisionIndicesForSource(int source) const
@@ -483,3 +528,55 @@ void DigitizationContext::sampleInteractionVertices(o2::dataformats::MeanVertexO
483528
}
484529
}
485530
}
531+
532+
DigitizationContext DigitizationContext::extractSingleTimeframe(int timeframeid, std::vector<int> const& sources_to_offset)
533+
{
534+
DigitizationContext r; // make a return object
535+
if (mTimeFrameStartIndex.size() == 0) {
536+
LOG(error) << "No timeframe structure determined; Returning empty object. Please call ::finalizeTimeframeStructure before calling this function";
537+
return r;
538+
}
539+
r.mSimPrefixes = mSimPrefixes;
540+
r.mMuBC = mMuBC;
541+
try {
542+
auto startend = mTimeFrameStartIndex.at(timeframeid);
543+
544+
auto startindex = startend.first;
545+
auto endindex = startend.second;
546+
547+
std::copy(mEventRecords.begin() + startindex, mEventRecords.begin() + endindex, std::back_inserter(r.mEventRecords));
548+
std::copy(mEventParts.begin() + startindex, mEventParts.begin() + endindex, std::back_inserter(r.mEventParts));
549+
if (mInteractionVertices.size() > endindex) {
550+
std::copy(mInteractionVertices.begin() + startindex, mInteractionVertices.begin() + endindex, std::back_inserter(r.mInteractionVertices));
551+
}
552+
553+
// let's assume we want to fix the ids for source = source_id
554+
// Then we find the first index that has this source_id and take the corresponding number
555+
// as offset. Thereafter we subtract this offset from all known event parts.
556+
auto perform_offsetting = [&r](int source_id) {
557+
auto indices_for_source = r.getCollisionIndicesForSource(source_id);
558+
int minvalue = std::numeric_limits<int>::max();
559+
for (auto& p : indices_for_source) {
560+
if (p.first < minvalue) {
561+
minvalue = p.first;
562+
}
563+
}
564+
// now fix them
565+
for (auto& p : indices_for_source) {
566+
auto index_into_mEventParts = p.second;
567+
for (auto& part : r.mEventParts[index_into_mEventParts]) {
568+
if (part.sourceID == source_id) {
569+
part.entryID -= minvalue;
570+
}
571+
}
572+
}
573+
};
574+
for (auto source_id : sources_to_offset) {
575+
perform_offsetting(source_id);
576+
}
577+
578+
} catch (std::exception) {
579+
LOG(warn) << "No such timeframe id in collision context. Returing empty object";
580+
}
581+
return r;
582+
}

Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ namespace dataformats
2727
struct TrackInfoExt {
2828
o2::track::TrackParCov track;
2929
DCA dca{};
30+
DCA dcaTPC{};
3031
VtxTrackIndex gid;
3132
MatchInfoTOF infoTOF;
3233
float ttime = 0;

Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,10 +364,30 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData)
364364
continue;
365365
}
366366
{
367+
o2::dataformats::DCA dcaTPC;
368+
dcaTPC.set(-999.f, -999.f);
369+
if (tpcTr) {
370+
if (is == GTrackID::TPC) {
371+
dcaTPC = dca;
372+
} else {
373+
o2::track::TrackParCov tmpTPC(*tpcTr);
374+
if (iv < nv - 1 && is == GTrackID::TPC && tpcTr && !tpcTr->hasBothSidesClusters()) { // for unconstrained TPC tracks correct track Z
375+
float corz = vdrit * (tpcTr->getTime0() * mTPCTBinMUS - pvvec[iv].getTimeStamp().getTimeStamp());
376+
if (tpcTr->hasASideClustersOnly()) {
377+
corz = -corz; // A-side
378+
}
379+
tmpTPC.setZ(tmpTPC.getZ() + corz);
380+
}
381+
if (!prop->propagateToDCA(iv == nv - 1 ? vtxDummy : pvvec[iv], tmpTPC, prop->getNominalBz(), 2., o2::base::PropagatorF::MatCorrType::USEMatCorrLUT, &dcaTPC)) {
382+
dcaTPC.set(-999.f, -999.f);
383+
}
384+
}
385+
}
367386
auto& trcExt = trcExtVec.emplace_back();
368387
recoData.getTrackTime(vid, trcExt.ttime, trcExt.ttimeE);
369388
trcExt.track = trc;
370389
trcExt.dca = dca;
390+
trcExt.dcaTPC = dcaTPC;
371391
trcExt.gid = vid;
372392
trcExt.xmin = xmin;
373393
auto gidRefs = recoData.getSingleDetectorRefs(vid);

Framework/Core/include/Framework/DataRefUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ struct DataRefUtils {
122122
// object only depends on the state at serialization of the original object. However,
123123
// all objects created during deserialization are new and must be owned by the collection
124124
// to avoid memory leak. So we call SetOwner if it is available for the type.
125-
if constexpr (has_root_setowner<T>::value) {
125+
if constexpr (requires(T t) { t.SetOwner(true); }) {
126126
result->SetOwner(true);
127127
}
128128
});

Framework/Core/include/Framework/TypeTraits.h

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -147,22 +147,5 @@ class has_root_dictionary<T, typename std::enable_if<is_container<T>::value>::ty
147147
{
148148
};
149149

150-
// Detect whether a class is a ROOT class implementing SetOwner
151-
// This member detector idiom is implemented using SFINAE idiom to look for
152-
// a 'SetOwner()' method.
153-
template <typename T, typename _ = void>
154-
struct has_root_setowner : std::false_type {
155-
};
156-
157-
template <typename T>
158-
struct has_root_setowner<
159-
T,
160-
std::conditional_t<
161-
false,
162-
class_member_checker<
163-
decltype(std::declval<T>().SetOwner(true))>,
164-
void>> : public std::true_type {
165-
};
166-
167150
} // namespace o2::framework
168151
#endif // FRAMEWORK_TYPETRAITS_H

GPU/GPUTracking/Base/GPUReconstructionCPU.cxx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,9 @@ int32_t GPUReconstructionCPU::RunChains()
216216

217217
timerTotal.Start();
218218
if (mProcessingSettings.doublePipeline) {
219-
if (EnqueuePipeline()) {
220-
return 1;
219+
int32_t retVal = EnqueuePipeline();
220+
if (retVal) {
221+
return retVal;
221222
}
222223
} else {
223224
if (mThreadId != GetThread()) {

GPU/GPUTracking/Definitions/GPUSettingsList.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ AddOptionRTC(extraClusterErrorSplitPadSharedSingleY2, float, 0.03f, "", 0, "Addi
8989
AddOptionRTC(extraClusterErrorFactorSplitPadSharedSingleY2, float, 3.0f, "", 0, "Multiplicative extra cluster error for Y2 if splitpad, shared, or single set")
9090
AddOptionRTC(extraClusterErrorSplitTimeSharedSingleZ2, float, 0.03f, "", 0, "Additive extra cluster error for Z2 if splittime, shared, or single set")
9191
AddOptionRTC(extraClusterErrorFactorSplitTimeSharedSingleZ2, float, 3.0f, "", 0, "Multiplicative extra cluster error for Z2 if splittime, shared, or single set")
92-
AddOptionArray(errorsCECrossing, float, 5, (0.f, 0.f, 0.f, 0.f, 0.f), "", 0, "Extra errors to add to track when crossing CE, depending on addErrorsCECrossing") // BUG: CUDA cannot yet hand AddOptionArrayRTC
92+
AddOptionArray(errorsCECrossing, float, 5, (0.f, 0.f, 0.f, 0.f, 0.f), "", 0, "Extra errors to add to track when crossing CE, depending on addErrorsCECrossing") // BUG: CUDA cannot yet handle AddOptionArrayRTC
9393
AddOptionRTC(globalTrackingYRangeUpper, float, 0.85f, "", 0, "Inner portion of y-range in slice that is not used in searching for global track candidates")
9494
AddOptionRTC(globalTrackingYRangeLower, float, 0.85f, "", 0, "Inner portion of y-range in slice that is not used in searching for global track candidates")
9595
AddOptionRTC(trackFollowingYFactor, float, 4.f, "", 0, "Weight of y residual vs z residual in tracklet constructor")

GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ void GPUChainTracking::SanityCheck()
302302
void GPUChainTracking::RunTPCClusterFilter(o2::tpc::ClusterNativeAccess* clusters, std::function<o2::tpc::ClusterNative*(size_t)> allocator, bool applyClusterCuts)
303303
{
304304
GPUTPCClusterFilter clusterFilter(*clusters);
305-
o2::tpc::ClusterNative* outputBuffer;
305+
o2::tpc::ClusterNative* outputBuffer = nullptr;
306306
for (int32_t iPhase = 0; iPhase < 2; iPhase++) {
307307
uint32_t countTotal = 0;
308308
for (uint32_t iSector = 0; iSector < GPUCA_NSLICES; iSector++) {

GPU/Workflow/src/GPUWorkflowSpec.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc)
851851
}
852852
createEmptyOutput = !mConfParam->partialOutputForNonFatalErrors;
853853
} else {
854-
throw std::runtime_error("tracker returned error code " + std::to_string(retVal));
854+
throw std::runtime_error("GPU Reconstruction error: error code " + std::to_string(retVal));
855855
}
856856
}
857857

0 commit comments

Comments
 (0)