Skip to content

Commit 2439bbe

Browse files
committed
Custom member streamer for CalArray<o2::tpc::PadFlags>::mData
This commit expands on #14427 and fixes the issue brought up in https://its.cern.ch/jira/browse/O2-4671. After debugging/testing it turns out that the approach taken via a customer streamer for std::vector<o2::tpc::PadFlags> does not take effect in the ROOT/IO because apparently ROOT still prefers to use the CollectionProxy for std::vector and does not employ the custom streamer. Instead, after discussion with @pcanal, this commit proposes to implement a custom stream just for the mData data member of CalArray<o2::tpc::PadFlags>. This is the only place where we use o2::tpc::PadFlags in IO and it fixes the problem when reading CCDB objects containing such data. I have verified that the following code ``` o2-ccdb-downloadccdbfile -p TPC/Calib/IDC_PadStatusMap_A -t 1731274461770 -d ./ -o tpc_idc.root --no-preserve-path root tpc_idc.root gFile->Get<o2::tpc::CalDet<o2::tpc::PadFlags>>("ccdb_object") ``` correctly executes the custom streamer function. Note that there is also no need to make the code ROOT version dependent. We need to fix the reading in any case and the writing will just stay the same. Concerning situations, where future classes will write data containing std::vector<o2::tpc::PadFlags> we should be protected by the fact that this bug has been fixed >= ROOT 6.36 in any case. This commit relates also to root-project/root#17009 The commit also re-enables dictionary creation of related classes and adds a dictionary for CalArray<o2::tpc::PadFlags> previously missing.
1 parent 1d4bf48 commit 2439bbe

File tree

6 files changed

+83
-59
lines changed

6 files changed

+83
-59
lines changed

DataFormats/Detectors/TPC/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ o2_add_library(
4040

4141
o2_target_root_dictionary(
4242
DataFormatsTPC
43-
EXTRA_PATCH src/VectorPadflagsCustomStreamer.cxx
4443
HEADERS include/DataFormatsTPC/ClusterGroupAttribute.h
4544
include/DataFormatsTPC/ClusterNative.h
4645
include/DataFormatsTPC/ClusterNativeHelper.h

DataFormats/Detectors/TPC/src/DataFormatsTPCLinkDef.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@
2222
#pragma link C++ class o2::tpc::ClusterHardwareContainerFixedSize < 8192> + ;
2323
#pragma link C++ class o2::tpc::ClusterNativeContainer + ;
2424
#pragma link C++ class o2::tpc::Digit + ;
25-
// pragma link C++ enum o2::tpc::PadFlags +; // enum itself
25+
#pragma link C++ enum o2::tpc::PadFlags + ; // enum itself
2626
#pragma link C++ class o2::tpc::ZeroSuppressedContainer8kb + ;
2727
#pragma link C++ class std::vector < o2::tpc::ClusterNative> + ;
2828
#pragma link C++ class std::vector < o2::tpc::ClusterNativeContainer> + ;
2929
#pragma link C++ class std::vector < o2::tpc::ClusterHardware> + ;
3030
#pragma link C++ class std::vector < o2::tpc::ClusterHardwareContainerFixedSize < 8192>> + ;
3131
#pragma link C++ class std::vector < o2::tpc::ClusterHardwareContainer8kb> + ;
3232
#pragma link C++ class std::vector < o2::tpc::Digit> + ;
33-
// pragma link C++ class std::vector < o2::tpc::PadFlags> + ;
33+
#pragma link C++ class std::vector < o2::tpc::PadFlags> + ;
3434
#pragma link C++ class std::vector < o2::tpc::ZeroSuppressedContainer8kb> + ;
3535
#pragma link C++ class o2::tpc::TrackTPC + ;
3636
#pragma link C++ class o2::tpc::LaserTrack + ;

DataFormats/Detectors/TPC/src/VectorPadflagsCustomStreamer.cxx

Lines changed: 0 additions & 56 deletions
This file was deleted.

Detectors/TPC/base/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ o2_add_library(TPCBase
4343
O2::DetectorsRaw O2::CCDB FairRoot::Base)
4444

4545
o2_target_root_dictionary(TPCBase
46+
EXTRA_PATCH src/TPCFlagsMemberCustomStreamer.cxx
4647
HEADERS include/TPCBase/CalArray.h
4748
include/TPCBase/CalDet.h
4849
include/TPCBase/CDBInterface.h

Detectors/TPC/base/src/TPCBaseLinkDef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#pragma link C++ class o2::tpc::CalArray < unsigned> + ;
2222
#pragma link C++ class o2::tpc::CalArray < short> + ;
2323
#pragma link C++ class o2::tpc::CalArray < bool> + ;
24+
#pragma link C++ class o2::tpc::CalArray < o2::tpc::PadFlags> + ;
2425
#pragma link C++ class o2::tpc::CalDet < float> + ;
2526
#pragma link C++ class o2::tpc::CalDet < double> + ;
2627
#pragma link C++ class o2::tpc::CalDet < int> + ;
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#include "TPCBase/CalArray.h"
13+
#include <TMemberStreamer.h>
14+
#include <TBuffer.h>
15+
#include <DataFormatsTPC/Defs.h>
16+
#include <iostream>
17+
18+
// to enable assert statements
19+
#ifdef NDEBUG
20+
#undef NDEBUG
21+
#include <cassert>
22+
#endif
23+
24+
// The following code provides a specific ROOT I/O streaming method
25+
// for the mData member of CalArray<o2::tpc::PadFlags>
26+
// This member was written incorrectly to the TFile in ROOT versions < 6.36, causing
27+
// segfaults when reading on ARM64 (occassionally).
28+
// We continue to write it in the incorrect format and fix the reading back.
29+
30+
// See also:
31+
// - https://github.com/root-project/root/pull/17009
32+
// - https://its.cern.ch/jira/browse/O2-4671
33+
34+
void MemberVectorPadFlagsStreamer(TBuffer& R__b, void* objp, int n)
35+
{
36+
if (n != 1) {
37+
std::cerr << "Error in MemberVectorPadFlagsStreamer : Unexpected n " << n << std::endl;
38+
return;
39+
}
40+
std::vector<o2::tpc::PadFlags>* obj = static_cast<std::vector<o2::tpc::PadFlags>*>(objp);
41+
if (R__b.IsReading()) {
42+
std::vector<int> R__stl;
43+
R__stl.clear();
44+
int R__n;
45+
R__b >> R__n;
46+
R__stl.reserve(R__n);
47+
for (int R__i = 0; R__i < R__n; R__i++) {
48+
Int_t readtemp;
49+
R__b >> readtemp;
50+
R__stl.push_back(readtemp);
51+
}
52+
auto data = reinterpret_cast<unsigned short*>(R__stl.data());
53+
for (int i = 0; i < R__n; ++i) {
54+
obj->push_back(static_cast<o2::tpc::PadFlags>(data[i]));
55+
}
56+
} else {
57+
// We always save things with the old format.
58+
R__b << (int)obj->size() / 2;
59+
for (size_t i = 0; i < obj->size(); i++) {
60+
R__b << (short)obj->at(i);
61+
}
62+
}
63+
}
64+
65+
// register the streamer via static global initialization (on library load)
66+
namespace ROOT
67+
{
68+
static __attribute__((used)) int _R__dummyStreamer_3 =
69+
([]() {
70+
auto cl = TClass::GetClass<o2::tpc::CalArray<o2::tpc::PadFlags>>();
71+
if (cl) {
72+
cl->AdoptMemberStreamer("mData", new TMemberStreamer(MemberVectorPadFlagsStreamer));
73+
} else {
74+
// we should never come here ... and if we do we should assert/fail
75+
assert(false);
76+
}
77+
return 0;
78+
})();
79+
} // namespace ROOT

0 commit comments

Comments
 (0)