ROOT Version: 6.40.02
I’m trying to use a RNTupleParallelWriter to write a custom class. When I try doing this in the full framework we have (way too big to post here), it fails at the step of calling MakeField<myClass>("Hit"). I tried reproducing this using the ntpl014_framework.C tutorial, but using that it works fine.
What does work within our framework is to manually add a field for each member of the custom class and write those fields. So this pseudo-code works:
WriterClass::Constructor()
{
ROOT::RNTupleWriteOptions options;
options.SetUseBufferedWrite(true);
auto model = ROOT::RNTupleModel::CreateBare();
model->MakeField<UInt_t>("Address");
model->MakeField<Float_t>("Charge");
model->MakeField<Short_t>("KValue");
model->MakeField<Float_t>("Cfd");
model->MakeField<Long64_t>("TimeStamp");
fTokens.push_back(model->GetToken("Address"));
fTokens.push_back(model->GetToken("Charge"));
fTokens.push_back(model->GetToken("KValue"));
fTokens.push_back(model->GetToken("Cfd"));
fTokens.push_back(model->GetToken("TimeStamp"));
{
std::lock_guard guard(fFileMutex);
fEventWriter = ROOT::RNTupleParallelWriter::Append(std::move(model), "Hits", *fOutputFile, options);
}
fSlots.resize(fNumberOfSlots);
for(auto& slot : fSlots) {
slot.fillContext = fEventWriter->CreateFillContext();
slot.entry = slot.fillContext->GetModel().CreateRawPtrWriteEntry();
}
}
void WriterClass::Iteration(data from other part of the framework)
{
UInt_t address = data->GetAddress();
Float_t charge = data->GetCharge();
Short_t kValue = data->GetKValue();
Float_t cfd = data->GetCfd();
Long64_t timeStamp = data->GetTimeStamp();
fSlots[fCurrentSlot].entry->BindRawPtr(fTokens[0], &address);
fSlots[fCurrentSlot].entry->BindRawPtr(fTokens[1], &charge);
fSlots[fCurrentSlot].entry->BindRawPtr(fTokens[2], &kValue);
fSlots[fCurrentSlot].entry->BindRawPtr(fTokens[3], &cfd);
fSlots[fCurrentSlot].entry->BindRawPtr(fTokens[4], &timeStamp);
code to call FillNoFlush on fillcontext and only FlushColumns and FlushCluster if asked to
}
But if I add a new class
class TSimpleHit {
public:
explicit TSimpleHit(data* hit) :
fAddress(hit->GetAddress()), fCharge(hit->GetCharge()),
fKValue(hit->GetKValue()), fCfd(hit->GetCfd()),
fTimeStamp(hit->GetTimeStamp()) {}
private:
UInt_t fAddress{0};
Float_t fCharge{0.};
Short_t fKValue{0};
Float_t fCfd{0};
Long64_t fTimeStamp{0};
};
and replace the five MakeField calls with a single one model->MakeField<TSimpleHit>("Hit"); the program fails at this step with
terminate called without an active exception
Aborted (core dumped)
I understand that it is hard to say what causes this since it works when using the tutorial, but maybe someone has encountered this before or has an idea what could cause this?