11 #ifndef ROOT_TDF_TINTERFACE 12 #define ROOT_TDF_TINTERFACE 32 #include <initializer_list> 37 #include <type_traits> 41 namespace Experimental {
73 template <
typename... BranchTypes,
typename ActionType,
typename ActionResultType,
typename PrevNodeType>
75 const unsigned int nSlots,
TLoopManager &loopManager, PrevNodeType &prevNode, ActionType *)
77 using Helper_t = FillTOHelper<ActionResultType>;
78 using Action_t =
TAction<Helper_t, PrevNodeType, TTraits::TypeList<BranchTypes...>>;
79 auto action = std::make_shared<Action_t>(Helper_t(h, nSlots), bl, prevNode);
80 loopManager.
Book(action);
85 template <
typename... BranchTypes,
typename PrevNodeType>
87 TLoopManager &loopManager, PrevNodeType &prevNode, ActionTypes::Histo1D *)
89 auto hasAxisLimits = HistoUtils<::TH1D>::HasAxisLimits(*h);
93 using Helper_t = FillTOHelper<::TH1D>;
94 using Action_t =
TAction<Helper_t, PrevNodeType, TTraits::TypeList<BranchTypes...>>;
95 auto action = std::make_shared<Action_t>(Helper_t(h, nSlots), bl, prevNode);
96 loopManager.
Book(action);
97 actionBase = action.get();
99 using Helper_t = FillHelper;
100 using Action_t =
TAction<Helper_t, PrevNodeType, TTraits::TypeList<BranchTypes...>>;
101 auto action = std::make_shared<Action_t>(Helper_t(h, nSlots), bl, prevNode);
102 loopManager.
Book(action);
103 actionBase = action.get();
110 template <
typename BranchType,
typename PrevNodeType,
typename ActionResultType>
112 BuildAndBook(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &minV,
const unsigned int nSlots,
115 using Helper_t = MinHelper<ActionResultType>;
117 auto action = std::make_shared<Action_t>(Helper_t(minV, nSlots), bl, prevNode);
118 loopManager.
Book(action);
123 template <
typename BranchType,
typename PrevNodeType,
typename ActionResultType>
125 BuildAndBook(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &maxV,
const unsigned int nSlots,
128 using Helper_t = MaxHelper<ActionResultType>;
130 auto action = std::make_shared<Action_t>(Helper_t(maxV, nSlots), bl, prevNode);
131 loopManager.
Book(action);
136 template <
typename BranchType,
typename PrevNodeType,
typename ActionResultType>
138 BuildAndBook(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &sumV,
const unsigned int nSlots,
139 TLoopManager &loopManager, PrevNodeType &prevNode, ActionTypes::Sum *)
141 using Helper_t = SumHelper<ActionResultType>;
143 auto action = std::make_shared<Action_t>(Helper_t(sumV, nSlots), bl, prevNode);
144 loopManager.
Book(action);
149 template <
typename BranchType,
typename PrevNodeType>
153 using Helper_t = MeanHelper;
155 auto action = std::make_shared<Action_t>(Helper_t(meanV, nSlots), bl, prevNode);
156 loopManager.
Book(action);
167 const std::map<std::string, std::string> &aliasMap,
const ColumnNames_t &
branches,
168 const std::vector<std::string> &customColumns,
169 const std::map<std::string, TmpBranchBasePtr_t> &tmpBookedBranches, TTree *
tree,
172 std::string
JitBuildAndBook(
const ColumnNames_t &bl,
const std::string &prevNodeTypename,
void *prevNode,
173 const std::type_info &art,
const std::type_info &at,
const void *
r, TTree *
tree,
174 const unsigned int nSlots,
const std::map<std::string, TmpBranchBasePtr_t> &customColumns,
175 TDataSource *ds,
const std::shared_ptr<TActionBase *> *
const actionPtrPtr);
183 template <
typename T>
186 return new std::shared_ptr<T>(shPtr);
193 std::shared_ptr<TFilterBase>
UpcastNode(
const std::shared_ptr<TFilterBase> ptr);
194 std::shared_ptr<TCustomColumnBase>
UpcastNode(
const std::shared_ptr<TCustomColumnBase> ptr);
195 std::shared_ptr<TRangeBase>
UpcastNode(
const std::shared_ptr<TRangeBase> ptr);
196 std::shared_ptr<TLoopManager>
UpcastNode(
const std::shared_ptr<TLoopManager> ptr);
199 const ColumnNames_t &validCustomColumns,
TDataSource *ds);
201 std::vector<bool>
FindUndefinedDSColumns(
const ColumnNames_t &requestedCols,
const ColumnNames_t &definedDSCols);
204 template <
typename T>
208 auto getValue = [readers](
unsigned int slot) {
return *readers[slot]; };
210 lm.
Book(std::make_shared<NewCol_t>(name, std::move(getValue), ColumnNames_t{}, &lm,
true));
215 template <
typename... ColumnTypes,
int...
S>
217 TTraits::TypeList<ColumnTypes...>,
TDataSource &ds)
220 if (std::none_of(mustBeDefined.begin(), mustBeDefined.end(), [](
bool b) {
return b; })) {
225 std::initializer_list<int> expander{
226 (mustBeDefined[
S] ? DefineDSColumnHelper<ColumnTypes>(columns[
S], lm, ds) : ((
void)0), 0)...};
232 template <
typename ActionType,
typename... BranchTypes,
typename PrevNodeType,
typename ActionResultType>
233 void CallBuildAndBook(PrevNodeType &prevNode,
const ColumnNames_t &bl,
const unsigned int nSlots,
234 const std::shared_ptr<ActionResultType> *rOnHeap,
235 const std::shared_ptr<TActionBase *> *actionPtrPtrOnHeap)
238 auto &loopManager = *prevNode.GetImplPtr();
239 using ColTypes_t =
TypeList<BranchTypes...>;
240 constexpr
auto nColumns = ColTypes_t::list_size;
241 auto ds = loopManager.GetDataSource();
245 BuildAndBook<BranchTypes...>(bl, *rOnHeap, nSlots, loopManager, prevNode, (ActionType *)
nullptr);
246 **actionPtrPtrOnHeap = actionPtr;
248 delete actionPtrPtrOnHeap;
252 template <typename T, bool Container = TTraits::IsContainer<T>::value>
262 template <
typename T>
274 template <
typename T>
277 template <
typename T>
280 template <
typename T>
283 template <
typename T,
typename COLL = std::vector<T>>
290 static constexpr
auto isAB = TDFInternal::IsTArrayBranch_t<T>::value;
291 using RealT_t =
typename TDFInternal::ValueType<T>::value_type;
295 typename std::conditional<isAB && TDFInternal::IsVector_t<COLL>::value, std::vector<VTColl_t>, COLL>
::type;
297 typename std::conditional<isAB && TDFInternal::IsList_t<NewC0_t>::value, std::list<VTColl_t>,
NewC0_t>
::type;
299 typename std::conditional<isAB && TDFInternal::IsDeque_t<NewC1_t>::value, std::deque<VTColl_t>,
NewC1_t>
::type;
302 template <
typename T,
typename C>
307 namespace Experimental {
320 namespace Experimental {
332 template <
typename Proxied>
340 template <
typename T>
356 template <
typename NewProxied>
359 static_assert(std::is_base_of<NewProxied, Proxied>::value,
360 "TInterface<T> can only be converted to TInterface<BaseOfT>");
397 template <typename F, typename std::enable_if<!std::is_convertible<F, std::string>::value,
int>
::type = 0>
400 TDFInternal::CheckFilter(f);
401 auto loopManager = GetDataFrameChecked();
403 constexpr
auto nColumns = ColTypes_t::list_size;
404 const auto validColumnNames =
408 ColTypes_t(), *fDataSource);
410 auto FilterPtr = std::make_shared<F_t>(std::move(f), validColumnNames, *fProxiedPtr,
name);
411 loopManager->Book(FilterPtr);
412 return TInterface<F_t>(FilterPtr, fImplWeakPtr, fValidCustomColumns, fDataSource);
422 template <typename F, typename std::enable_if<!std::is_convertible<F, std::string>::value,
int>::type = 0>
427 return Filter(f, {},
name);
437 template <
typename F>
455 auto retVal = CallJitTransformation(
"Filter", name, expression,
"ROOT::Detail::TDF::TFilterBase");
479 template <typename F, typename std::enable_if<!std::is_convertible<F, std::string>::value,
int>::type = 0>
482 return DefineImpl<F, TDFDetail::TCCHelperTypes::TNothing>(
name, std::move(expression), columns);
507 template <
typename F>
510 return DefineImpl<F, TDFDetail::TCCHelperTypes::TSlot>(
name, std::move(expression), columns);
536 template <
typename F>
539 return DefineImpl<F, TDFDetail::TCCHelperTypes::TSlotAndEntry>(
name, std::move(expression), columns);
555 auto loopManager = GetDataFrameChecked();
559 auto retVal = CallJitTransformation(
"Define", name, expression, TInterfaceJittedDefine::GetNodeTypeName());
560 auto retInterface =
reinterpret_cast<TInterfaceJittedDefine *
>(retVal);
561 return *retInterface;
574 auto loopManager = GetDataFrameChecked();
583 fValidCustomColumns, fDataSource)[0];
585 loopManager->AddColumnAlias(std::string(alias), validColumnName);
586 TInterface<Proxied> newInterface(fProxiedPtr, fImplWeakPtr, fValidCustomColumns, fDataSource);
600 template <
typename... BranchTypes>
605 return SnapshotImpl<BranchTypes...>(treename, filename, columnList, options);
623 if (columnList.empty()) {
624 auto nEntries = *this->Count();
628 auto df = GetDataFrameChecked();
629 auto tree = df->GetTree();
630 std::stringstream snapCall;
633 fValidCustomColumns, fDataSource);
636 snapCall <<
"reinterpret_cast<ROOT::Experimental::TDF::TInterface<" << upcastInterface.
GetNodeTypeName() <<
">*>(" 637 << &upcastInterface <<
")->Snapshot<";
639 for (
auto &
b : columnList) {
645 snapCall <<
">(\"" << treename <<
"\", \"" << filename <<
"\", " 646 <<
"*reinterpret_cast<std::vector<std::string>*>(" 647 << &columnList <<
")," 648 <<
"*reinterpret_cast<ROOT::Experimental::TDF::TSnapshotOptions*>(" << &options <<
"));";
651 auto newTDFPtr =
gInterpreter->Calc(snapCall.str().c_str(), &errorCode);
652 if (TInterpreter::EErrorCode::kNoError != errorCode) {
653 std::string msg =
"Cannot jit Snapshot call. Interpreter error code is " + std::to_string(errorCode) +
".";
654 throw std::runtime_error(msg);
673 auto selectedColumns = ConvertRegexToColumns(columnNameRegexp,
"Snapshot");
674 return Snapshot(treename, filename, selectedColumns, options);
685 template <
typename... BranchTypes>
688 auto staticSeq = TDFInternal::GenStaticSeq_t<
sizeof...(BranchTypes)>();
689 return CacheImpl<BranchTypes...>(columnList, staticSeq);
703 if (columnList.empty()) {
704 auto nEntries = *this->Count();
709 auto df = GetDataFrameChecked();
710 auto tree = df->GetTree();
711 std::stringstream snapCall;
714 fValidCustomColumns, fDataSource);
717 snapCall <<
"reinterpret_cast<ROOT::Experimental::TDF::TInterface<" << upcastInterface.
GetNodeTypeName() <<
">*>(" 718 << &upcastInterface <<
")->Cache<";
720 for (
auto &
b : columnList) {
726 snapCall <<
">(*reinterpret_cast<std::vector<std::string>*>(" 727 << &columnList <<
"));";
730 auto newTDFPtr =
gInterpreter->Calc(snapCall.str().c_str(), &errorCode);
731 if (TInterpreter::EErrorCode::kNoError != errorCode) {
732 std::string msg =
"Cannot jit Cache call. Interpreter error code is " + std::to_string(errorCode) +
".";
733 throw std::runtime_error(msg);
746 auto selectedColumns = ConvertRegexToColumns(columnNameRegexp,
"Cache");
747 return Cache(selectedColumns);
760 if (stride == 0 || (stop != 0 && stop < start))
761 throw std::runtime_error(
"Range: stride must be strictly greater than 0 and stop must be greater than start.");
763 throw std::runtime_error(
"Range was called with ImplicitMT enabled. Multi-thread ranges are not supported.");
765 auto df = GetDataFrameChecked();
767 auto RangePtr = std::make_shared<Range_t>(start, stop, stride, *fProxiedPtr);
791 template <
typename F>
796 ForeachSlot(TDFInternal::AddSlotParameter<ret_type>(f, arg_types()), columns);
815 template <
typename F>
818 auto loopManager = GetDataFrameChecked();
820 constexpr
auto nColumns = ColTypes_t::list_size;
821 const auto validColumnNames =
825 ColTypes_t(), *fDataSource);
826 using Helper_t = TDFInternal::ForeachSlotHelper<F>;
828 loopManager->Book(std::make_shared<Action_t>(Helper_t(std::move(f)), validColumnNames, *fProxiedPtr));
854 template <typename F, typename T = typename TTraits::CallableTraits<F>::ret_type>
858 std::is_default_constructible<T>::value,
859 "reduce object cannot be default-constructed. Please provide an initialisation value (redIdentity)");
860 return Reduce(std::move(f), columnName,
T());
872 template <typename F, typename T = typename TTraits::CallableTraits<F>::ret_type>
876 TDFInternal::CheckReduce(f, arg_types());
877 auto loopManager = GetDataFrameChecked();
879 constexpr
auto nColumns = arg_types::list_size;
880 const auto validColumnNames =
884 arg_types(), *fDataSource);
885 auto redObjPtr = std::make_shared<T>(redIdentity);
886 using Helper_t = TDFInternal::ReduceHelper<F, T>;
888 auto action = std::make_shared<Action_t>(Helper_t(std::move(f), redObjPtr, fProxiedPtr->GetNSlots()),
889 validColumnNames, *fProxiedPtr);
890 loopManager->Book(action);
902 auto df = GetDataFrameChecked();
903 const auto nSlots = fProxiedPtr->GetNSlots();
904 auto cSPtr = std::make_shared<ULong64_t>(0);
905 using Helper_t = TDFInternal::CountHelper;
907 auto action = std::make_shared<Action_t>(Helper_t(cSPtr, nSlots),
ColumnNames_t({}), *fProxiedPtr);
923 template <
typename T,
typename COLL = std::vector<T>>
926 auto loopManager = GetDataFrameChecked();
928 const auto validColumnNames =
932 TTraits::TypeList<T>(), *fDataSource);
937 using Helper_t = TDFInternal::TakeHelper<RealT_t, T, RealColl_t>;
939 auto valuesPtr = std::make_shared<RealColl_t>();
940 const auto nSlots = fProxiedPtr->
GetNSlots();
941 auto action = std::make_shared<Action_t>(Helper_t(valuesPtr, nSlots), validColumnNames, *fProxiedPtr);
942 loopManager->Book(action);
959 template <
typename V = TDFDetail::TInferType>
962 const auto userColumns = vName.empty() ? ColumnNames_t() : ColumnNames_t({std::string(vName)});
963 std::shared_ptr<::TH1D>
h(
nullptr);
965 ROOT::Internal::TDF::TIgnoreErrorLevelRAII iel(
kError);
970 TDFInternal::HistoUtils<::TH1D>::SetCanExtendAllAxes(*
h);
971 return CreateAction<TDFInternal::ActionTypes::Histo1D, V>(userColumns,
h);
974 template <
typename V = TDFDetail::TInferType>
977 return Histo1D<V>({
"",
"", 128u, 0., 0.}, vName);
989 template <
typename V = TDFDetail::TInferType,
typename W = TDFDetail::TInferType>
992 auto columnViews = {vName, wName};
996 std::shared_ptr<::TH1D>
h(
nullptr);
998 ROOT::Internal::TDF::TIgnoreErrorLevelRAII iel(
kError);
1001 return CreateAction<TDFInternal::ActionTypes::Histo1D, V, W>(userColumns,
h);
1013 template <
typename V = TDFDetail::TInferType,
typename W = TDFDetail::TInferType>
1016 return Histo1D<V, W>({
"",
"", 128u, 0., 0.}, vName, wName);
1027 template <
typename V,
typename W>
1030 return Histo1D<V, W>(
model,
"",
"");
1048 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType>
1051 std::shared_ptr<::TH2D>
h(
nullptr);
1053 ROOT::Internal::TDF::TIgnoreErrorLevelRAII iel(
kError);
1056 if (!TDFInternal::HistoUtils<::TH2D>::HasAxisLimits(*h)) {
1057 throw std::runtime_error(
"2D histograms with no axes limits are not supported yet.");
1059 auto columnViews = {v1Name, v2Name};
1063 return CreateAction<TDFInternal::ActionTypes::Histo2D, V1, V2>(userColumns,
h);
1079 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
1080 typename W = TDFDetail::TInferType>
1084 std::shared_ptr<::TH2D>
h(
nullptr);
1086 ROOT::Internal::TDF::TIgnoreErrorLevelRAII iel(
kError);
1089 if (!TDFInternal::HistoUtils<::TH2D>::HasAxisLimits(*h)) {
1090 throw std::runtime_error(
"2D histograms with no axes limits are not supported yet.");
1092 auto columnViews = {v1Name, v2Name, wName};
1096 return CreateAction<TDFInternal::ActionTypes::Histo2D, V1, V2, W>(userColumns,
h);
1099 template <
typename V1,
typename V2,
typename W>
1102 return Histo2D<V1, V2, W>(
model,
"",
"",
"");
1118 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
1119 typename V3 = TDFDetail::TInferType>
1123 std::shared_ptr<::TH3D>
h(
nullptr);
1125 ROOT::Internal::TDF::TIgnoreErrorLevelRAII iel(
kError);
1128 if (!TDFInternal::HistoUtils<::TH3D>::HasAxisLimits(*h)) {
1129 throw std::runtime_error(
"3D histograms with no axes limits are not supported yet.");
1131 auto columnViews = {v1Name, v2Name, v3Name};
1135 return CreateAction<TDFInternal::ActionTypes::Histo3D, V1, V2, V3>(userColumns,
h);
1153 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
1154 typename V3 = TDFDetail::TInferType,
typename W = TDFDetail::TInferType>
1158 std::shared_ptr<::TH3D>
h(
nullptr);
1160 ROOT::Internal::TDF::TIgnoreErrorLevelRAII iel(
kError);
1163 if (!TDFInternal::HistoUtils<::TH3D>::HasAxisLimits(*h)) {
1164 throw std::runtime_error(
"3D histograms with no axes limits are not supported yet.");
1166 auto columnViews = {v1Name, v2Name, v3Name, wName};
1170 return CreateAction<TDFInternal::ActionTypes::Histo3D, V1, V2, V3, W>(userColumns,
h);
1173 template <
typename V1,
typename V2,
typename V3,
typename W>
1176 return Histo3D<V1, V2, V3, W>(
model,
"",
"",
"",
"");
1190 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType>
1194 std::shared_ptr<::TProfile>
h(
nullptr);
1196 ROOT::Internal::TDF::TIgnoreErrorLevelRAII iel(
kError);
1200 if (!TDFInternal::HistoUtils<::TProfile>::HasAxisLimits(*h)) {
1201 throw std::runtime_error(
"Profiles with no axes limits are not supported yet.");
1203 auto columnViews = {v1Name, v2Name};
1207 return CreateAction<TDFInternal::ActionTypes::Profile1D, V1, V2>(userColumns,
h);
1223 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
1224 typename W = TDFDetail::TInferType>
1228 std::shared_ptr<::TProfile>
h(
nullptr);
1230 ROOT::Internal::TDF::TIgnoreErrorLevelRAII iel(
kError);
1234 if (!TDFInternal::HistoUtils<::TProfile>::HasAxisLimits(*h)) {
1235 throw std::runtime_error(
"Profile histograms with no axes limits are not supported yet.");
1237 auto columnViews = {v1Name, v2Name, wName};
1241 return CreateAction<TDFInternal::ActionTypes::Profile1D, V1, V2, W>(userColumns,
h);
1244 template <
typename V1,
typename V2,
typename W>
1247 return Profile1D<V1, V2, W>(
model,
"",
"",
"");
1263 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
1264 typename V3 = TDFDetail::TInferType>
1268 std::shared_ptr<::TProfile2D>
h(
nullptr);
1270 ROOT::Internal::TDF::TIgnoreErrorLevelRAII iel(
kError);
1274 if (!TDFInternal::HistoUtils<::TProfile2D>::HasAxisLimits(*h)) {
1275 throw std::runtime_error(
"2D profiles with no axes limits are not supported yet.");
1277 auto columnViews = {v1Name, v2Name, v3Name};
1281 return CreateAction<TDFInternal::ActionTypes::Profile2D, V1, V2, V3>(userColumns,
h);
1299 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
1300 typename V3 = TDFDetail::TInferType,
typename W = TDFDetail::TInferType>
1304 std::shared_ptr<::TProfile2D>
h(
nullptr);
1306 ROOT::Internal::TDF::TIgnoreErrorLevelRAII iel(
kError);
1310 if (!TDFInternal::HistoUtils<::TProfile2D>::HasAxisLimits(*h)) {
1311 throw std::runtime_error(
"2D profiles with no axes limits are not supported yet.");
1313 auto columnViews = {v1Name, v2Name, v3Name, wName};
1317 return CreateAction<TDFInternal::ActionTypes::Profile2D, V1, V2, V3, W>(userColumns,
h);
1320 template <
typename V1,
typename V2,
typename V3,
typename W>
1323 return Profile2D<V1, V2, V3, W>(
model,
"",
"",
"",
"");
1342 template <
typename FirstColumn,
typename... OtherColumns,
typename T>
1345 auto h = std::make_shared<T>(std::move(
model));
1346 if (!TDFInternal::HistoUtils<T>::HasAxisLimits(*
h)) {
1347 throw std::runtime_error(
"The absence of axes limits is not supported yet.");
1349 return CreateAction<TDFInternal::ActionTypes::Fill, FirstColumn, OtherColumns...>(columnList,
h);
1363 template <
typename T>
1366 auto h = std::make_shared<T>(std::move(
model));
1367 if (!TDFInternal::HistoUtils<T>::HasAxisLimits(*
h)) {
1368 throw std::runtime_error(
"The absence of axes limits is not supported yet.");
1370 return CreateAction<TDFInternal::ActionTypes::Fill, TDFDetail::TInferType>(bl,
h, bl.size());
1384 template <
typename T = TDFDetail::TInferType>
1389 auto minV = std::make_shared<RetType_t>(std::numeric_limits<RetType_t>::max());
1390 return CreateAction<TDFInternal::ActionTypes::Min, T>(userColumns, minV);
1404 template <
typename T = TDFDetail::TInferType>
1409 auto maxV = std::make_shared<RetType_t>(std::numeric_limits<RetType_t>::lowest());
1410 return CreateAction<TDFInternal::ActionTypes::Max, T>(userColumns, maxV);
1423 template <
typename T = TDFDetail::TInferType>
1427 auto meanV = std::make_shared<double>(0);
1428 return CreateAction<TDFInternal::ActionTypes::Mean, T>(userColumns, meanV);
1444 template <
typename T = TDFDetail::TInferType>
1450 auto sumV = std::make_shared<TDFDetail::SumReturnType_t<T>>(initValue);
1451 return CreateAction<TDFInternal::ActionTypes::Sum, T>(userColumns, sumV);
1470 if (std::is_same<Proxied, TLoopManager>::value && fValidCustomColumns.size() > 2)
1473 auto df = GetDataFrameChecked();
1476 if (df->MustRunNamedFilters())
1478 fProxiedPtr->Report();
1492 allColumns.emplace_back(colName);
1495 std::for_each(fValidCustomColumns.begin(), fValidCustomColumns.end(), addIfNotInternal);
1497 auto df = GetDataFrameChecked();
1498 auto tree = df->GetTree();
1501 allColumns.insert(allColumns.end(), branchNames.begin(), branchNames.end());
1506 allColumns.insert(allColumns.end(), dsColNames.begin(), dsColNames.end());
1515 auto lm = GetDataFrameChecked();
1519 auto entryColGen = [](
unsigned int,
ULong64_t entry) {
return entry; };
1520 const auto entryColName =
"tdfentry_";
1522 lm->Book(std::make_shared<EntryCol_t>(entryColName, std::move(entryColGen), validColNames, lm.get()));
1523 fValidCustomColumns.emplace_back(entryColName);
1526 auto slotColGen = [](
unsigned int slot) {
return slot; };
1527 const auto slotColName =
"tdfslot_";
1529 lm->Book(std::make_shared<SlotCol_t>(slotColName, std::move(slotColGen), validColNames, lm.get()));
1530 fValidCustomColumns.emplace_back(slotColName);
1535 const auto theRegexSize = columnNameRegexp.size();
1536 std::string theRegex(columnNameRegexp);
1538 const auto isEmptyRegex = 0 == theRegexSize;
1540 if (theRegexSize > 0 && theRegex[0] !=
'^')
1541 theRegex =
"^" + theRegex;
1542 if (theRegexSize > 0 && theRegex[theRegexSize - 1] !=
'$')
1543 theRegex = theRegex +
"$";
1546 selectedColumns.reserve(32);
1552 for (
auto &&
branchName : fValidCustomColumns) {
1559 auto df = GetDataFrameChecked();
1560 auto tree = df->GetTree();
1572 for (
auto &dsColName : dsColNames) {
1573 if (isEmptyRegex || -1 != regexp.
Index(dsColName, &dummy)) {
1574 selectedColumns.emplace_back(dsColName);
1579 if (selectedColumns.empty()) {
1580 std::string
text(callerName);
1581 if (columnNameRegexp.empty()) {
1582 text =
": there is no column available to match.";
1584 text =
": regex \"" + columnNameRegexp +
"\" did not match any column.";
1586 throw std::runtime_error(text);
1588 return selectedColumns;
1594 auto df = GetDataFrameChecked();
1595 auto &aliasMap = df->GetAliasMap();
1596 auto tree = df->GetTree();
1598 const auto &customColumns = df->GetCustomColumnNames();
1599 auto tmpBookedBranches = df->GetBookedColumns();
1602 upcastNode, fImplWeakPtr, fValidCustomColumns, fDataSource);
1603 const auto thisTypeName =
"ROOT::Experimental::TDF::TInterface<" + upcastInterface.
GetNodeTypeName() +
">";
1605 aliasMap,
branches, customColumns, tmpBookedBranches,
tree, returnTypeName,
1612 inline static std::string GetNodeTypeName();
1615 template <
typename ActionType,
typename... BranchTypes,
typename ActionResultType,
1616 typename std::enable_if<!TDFInternal::TNeedJitting<BranchTypes...>::value,
int>::type = 0>
1619 auto lm = GetDataFrameChecked();
1620 constexpr
auto nColumns =
sizeof...(BranchTypes);
1621 const auto selectedCols =
1625 TDFInternal::TypeList<BranchTypes...>(), *fDataSource);
1626 const auto nSlots = fProxiedPtr->GetNSlots();
1635 template <
typename ActionType,
typename... BranchTypes,
typename ActionResultType,
1636 typename std::enable_if<TDFInternal::TNeedJitting<BranchTypes...>::value,
int>::type = 0>
1640 auto lm = GetDataFrameChecked();
1641 auto realNColumns = (nColumns > -1 ? nColumns :
sizeof...(BranchTypes));
1642 const auto validColumnNames =
1644 const unsigned int nSlots = fProxiedPtr->GetNSlots();
1645 const auto &customColumns = lm->GetBookedColumns();
1646 auto tree = lm->GetTree();
1650 upcastNode, fImplWeakPtr, fValidCustomColumns, fDataSource);
1652 auto &resultProxy = resultProxyAndActionPtrPtr.first;
1655 typeid(std::shared_ptr<ActionResultType>),
typeid(ActionType), rOnHeap,
1656 tree, nSlots, customColumns, fDataSource, actionPtrPtrOnHeap);
1661 template <
typename F,
typename ExtraArgs>
1662 typename std::enable_if<std::is_default_constructible<typename TTraits::CallableTraits<F>::ret_type>::value,
1666 auto loopManager = GetDataFrameChecked();
1671 using ColTypesTmp_t =
1672 typename TDFInternal::RemoveFirstParameterIf<std::is_same<ExtraArgs, TDFDetail::TCCHelperTypes::TSlot>::value,
1674 using ColTypes_t =
typename TDFInternal::RemoveFirstTwoParametersIf<
1675 std::is_same<ExtraArgs, TDFDetail::TCCHelperTypes::TSlotAndEntry>::value, ColTypesTmp_t>
::type;
1677 constexpr
auto nColumns = ColTypes_t::list_size;
1678 const auto validColumnNames =
1682 ColTypes_t(), *fDataSource);
1687 loopManager->Book(std::make_shared<NewCol_t>(name, std::move(expression), validColumnNames, loopManager.get()));
1688 TInterface<Proxied> newInterface(fProxiedPtr, fImplWeakPtr, fValidCustomColumns, fDataSource);
1690 return newInterface;
1697 typename F,
typename ExtraArgs,
1698 typename std::enable_if<!std::is_convertible<F, std::string>::value &&
1699 !std::is_default_constructible<typename TTraits::CallableTraits<F>::ret_type>::value,
1704 "Error in `Define`: type returned by expression is not default-constructible");
1718 template <
typename... BranchTypes>
1724 auto df = GetDataFrameChecked();
1730 TTraits::TypeList<BranchTypes...>(), *fDataSource);
1732 const std::string fullTreename(treename);
1734 const auto lastSlash = treename.rfind(
'/');
1736 if (std::string_view::npos != lastSlash) {
1737 dirname = treename.substr(0, lastSlash);
1738 treename = treename.substr(lastSlash + 1, treename.size());
1742 std::shared_ptr<TDFInternal::TActionBase> actionPtr;
1745 using Helper_t = TDFInternal::SnapshotHelper<BranchTypes...>;
1747 actionPtr.reset(
new Action_t(Helper_t(filename, dirname, treename, validCols, columnList, options), validCols,
1751 using Helper_t = TDFInternal::SnapshotHelperMT<BranchTypes...>;
1753 actionPtr.reset(
new Action_t(
1754 Helper_t(fProxiedPtr->GetNSlots(), filename, dirname, treename, validCols, columnList, options), validCols,
1757 df->Book(std::move(actionPtr));
1765 auto chain = std::make_shared<TChain>(fullTreename.c_str());
1766 chain->Add(std::string(filename).c_str());
1774 template <
typename... BranchTypes,
int...
S>
1779 constexpr
bool areCopyConstructible =
1780 TDFInternal::TEvalAnd<std::is_copy_constructible<BranchTypes>::value...>::value;
1781 static_assert(areCopyConstructible,
"Columns of a type which is not copy constructible cannot be cached yet.");
1787 auto lm = GetDataFrameChecked();
1795 std::initializer_list<int> expander0{(
1797 std::get<S>(colHolders).fContent = std::move(
1798 Take<
typename std::decay<decltype(std::get<S>(colHolders))>::type::value_type>(columnList[
S]).GetValue()),
1802 auto nEntries = std::get<0>(colHolders).fContent.size();
1809 std::initializer_list<int> expander1{(
1813 TDFDetail::TCCHelperTypes::TSlotAndEntry>>(
1814 columnList[
S], std::move(std::get<S>(colHolders)), noCols, lm.get(),
true)),
1820 vc.insert(vc.end(), columnList.begin(), columnList.end());
1828 auto df = fImplWeakPtr.lock();
1830 throw std::runtime_error(
"The main TDataFrame is not reachable: did it go out of scope?");
1835 TInterface(
const std::shared_ptr<Proxied> &proxied,
const std::weak_ptr<TLoopManager> &impl,
1837 : fProxiedPtr(proxied), fImplWeakPtr(impl), fValidCustomColumns(validColumns), fDataSource(ds)
1842 template <typename T = Proxied, typename std::enable_if<std::is_same<T, TLoopManager>::value,
int>::type = 0>
1844 : fProxiedPtr(proxied), fImplWeakPtr(proxied->GetSharedPtr()), fValidCustomColumns(),
1845 fDataSource(proxied->GetDataSource())
1847 AddDefaultColumns();
1856 return "ROOT::Detail::TDF::TFilterBase";
1862 return "ROOT::Detail::TDF::TLoopManager";
1868 return "ROOT::Detail::TDF::TRangeBase";
1875 #endif // ROOT_TDF_INTERFACE ColumnNames_t ConvertRegexToColumns(std::string_view columnNameRegexp, std::string_view callerName)
TResultProxy< TDFDetail::SumReturnType_t< T > > Sum(std::string_view columnName="", const TDFDetail::SumReturnType_t< T > &initValue=TDFDetail::SumReturnType_t< T >{})
Return the sum of processed column values (lazy action)
typename RemoveFirstParameter< T >::type RemoveFirstParameter_t
TInterface(const std::shared_ptr< Proxied > &proxied, const std::weak_ptr< TLoopManager > &impl, const ColumnNames_t &validColumns, TDataSource *ds)
TTraits::TakeFirstParameter_t< T > type
std::vector< bool > FindUndefinedDSColumns(const ColumnNames_t &requestedCols, const ColumnNames_t &definedDSCols)
Return a bitset each element of which indicates whether the corresponding element in selectedColumns ...
The contained type alias is double if T == TInferType, U if T == std::container<U>, T otherwise.
TResultProxy< T > Reduce(F f, std::string_view columnName, const T &redIdentity)
Execute a user-defined reduce operation on the values of a column.
A collection of options to steer the creation of the dataset on file.
std::shared_ptr<::TH1D > GetHistogram() const
A struct which stores the parameters of a TH2D.
std::enable_if< std::is_default_constructible< typename TTraits::CallableTraits< F >::ret_type >::value, TInterface< Proxied > >::type DefineImpl(std::string_view name, F &&expression, const ColumnNames_t &columns)
std::vector< value_type > fContent
TInterface< TLoopManager > CacheImpl(const ColumnNames_t &columnList, TDFInternal::StaticSeq< S... > s)
Implementation of cache.
basic_string_view< char > string_view
Namespace for new ROOT classes and functions.
TInterface< TLoopManager > Cache(std::string_view columnNameRegexp="")
Save selected columns in memory.
typename TDFInternal::ValueType< T >::value_type RealT_t
TDFDetail::ColumnNames_t ColumnNames_t
const std::shared_ptr< Proxied > & GetProxiedPtr() const
std::shared_ptr<::TH3D > GetHistogram() const
TResultProxy< ULong64_t > Count()
Return the number of entries processed (lazy action)
typename TakeFirstParameter< T >::type TakeFirstParameter_t
TResultProxy< T > MakeResultProxy(const std::shared_ptr< T > &r, const std::shared_ptr< TLoopManager > &df, TDFInternal::TActionBase *actionPtr)
Create a TResultProxy and set its pointer to the corresponding TAction This overload is invoked by no...
std::pair< Double_t, Double_t > Range_t
bool AtLeastOneEmptyString(const std::vector< std::string_view > strings)
TInterface< TLoopManager > Cache(const ColumnNames_t &columnList)
Save selected columns in memory.
TResultProxy< T > Reduce(F f, std::string_view columnName="")
Execute a user-defined reduce operation on the values of a column.
void CheckCustomColumn(std::string_view definedCol, TTree *treePtr, const ColumnNames_t &customCols, const ColumnNames_t &dataSourceColumns)
TResultProxy< ActionResultType > CreateAction(const ColumnNames_t &columns, const std::shared_ptr< ActionResultType > &r)
TInterface< TLoopManager > Snapshot(std::string_view treename, std::string_view filename, std::string_view columnNameRegexp="", const TSnapshotOptions &options=TSnapshotOptions())
Save selected columns to disk, in a new TTree treename in file filename.
Regular expression class.
std::shared_ptr< TLoopManager > UpcastNode(const std::shared_ptr< TLoopManager > ptr)
Long_t CallJitTransformation(std::string_view transformation, std::string_view nodeName, std::string_view expression, std::string_view returnTypeName)
TActionBase * BuildAndBook(const ColumnNames_t &bl, const std::shared_ptr< double > &meanV, const unsigned int nSlots, TLoopManager &loopManager, PrevNodeType &prevNode, ActionTypes::Mean *)
TResultProxy< T > Fill(T &&model, const ColumnNames_t &columnList)
Return an object of type T on which T::Fill will be called once per event (lazy action) ...
Short_t Min(Short_t a, Short_t b)
void ForeachSlot(F f, const ColumnNames_t &columns={})
Execute a user-defined function requiring a processing slot index on each entry (instant action) ...
TInterface< Proxied > DefineSlotEntry(std::string_view name, F expression, const ColumnNames_t &columns={})
Creates a custom column with a value dependent on the processing slot and the current entry...
A struct which stores the parameters of a TProfile2D.
void DefineDSColumnHelper(std::string_view name, TLoopManager &lm, TDataSource &ds)
Helper function to be used by DefineDataSourceColumns
TResultProxy<::TProfile > Profile1D(const TProfile1DModel &model)
A struct which stores the parameters of a TH3D.
void Book(const ActionBasePtr_t &actionPtr)
TInterface< Proxied > Alias(std::string_view alias, std::string_view columnName)
Allow to refer to a column with a different name.
std::vector< std::string > FindUsedColumnNames(std::string_view, TObjArray *, const std::vector< std::string > &)
void AddDataSourceColumn(std::string_view name)
MinReturnType_t< T > MaxReturnType_t
TInterface< TLoopManager > SnapshotImpl(std::string_view treename, std::string_view filename, const ColumnNames_t &columnList, const TSnapshotOptions &options)
Implementation of snapshot.
typename TDFInternal::TMinReturnType< T >::type MinReturnType_t
The aliased type is double if T == TInferType, U if T == container<U>, T otherwise.
TInterface< TLoopManager > Snapshot(std::string_view treename, std::string_view filename, const ColumnNames_t &columnList, const TSnapshotOptions &options=TSnapshotOptions())
Save selected columns to disk, in a new TTree treename in file filename.
void DefineDataSourceColumns(const std::vector< std::string > &columns, TLoopManager &lm, StaticSeq< S... >, TTraits::TypeList< ColumnTypes... >, TDataSource &ds)
Take a list of data-source column names and define the ones that haven't been defined yet...
static std::string GetNodeTypeName()
Return string containing fully qualified type name of the node pointed by fProxied.
unsigned int GetNSlots() const
ColumnNames_t GetColumnNames()
Returns the names of the available columns.
std::string JitBuildAndBook(const ColumnNames_t &bl, const std::string &prevNodeTypename, void *prevNode, const std::type_info &art, const std::type_info &at, const void *r, TTree *tree, const unsigned int nSlots, const std::map< std::string, TmpBranchBasePtr_t > &customColumns, TDataSource *ds, const std::shared_ptr< TActionBase *> *const actionPtrPtr)
TResultProxy<::TH2D > Histo2D(const TH2DModel &model, std::string_view v1Name, std::string_view v2Name, std::string_view wName)
Fill and return a weighted two-dimensional histogram (lazy action)
TResultProxy<::TH1D > Histo1D(const TH1DModel &model={"", "", 128u, 0., 0.})
Fill and return a one-dimensional histogram with the weighted values of a column (lazy action) ...
const ColumnNames_t & GetCustomColumnNames() const
std::vector< RealT_t > VTColl_t
typename std::conditional< isAB &&TDFInternal::IsVector_t< COLL >::value, std::vector< VTColl_t >, COLL >::type NewC0_t
bool IsInternalColumn(std::string_view colName)
ColumnNames_t GetValidatedColumnNames(TLoopManager &lm, const unsigned int nColumns, const ColumnNames_t &columns, const ColumnNames_t &validCustomColumns, TDataSource *ds)
Given the desired number of columns and the user-provided list of columns:
TInterface< TDFDetail::TFilter< F, Proxied > > Filter(F f, const std::initializer_list< std::string > &columns)
Append a filter to the call graph.
TResultProxy< TDFDetail::MaxReturnType_t< T > > Max(std::string_view columnName="")
Return the maximum of processed column values (lazy action)
typename std::conditional< isAB &&TDFInternal::IsList_t< NewC0_t >::value, std::list< VTColl_t >, NewC0_t >::type NewC1_t
TResultProxy< double > Mean(std::string_view columnName="")
Return the mean of processed column values (lazy action)
RooArgSet S(const RooAbsArg &v1)
Smart pointer for the return type of actions.
std::shared_ptr< T > * MakeSharedOnHeap(const std::shared_ptr< T > &shPtr)
std::string printValue(const TDatime *val)
Print a TDatime at the prompt.
TResultProxy< TDFDetail::MinReturnType_t< T > > Min(std::string_view columnName="")
Return the minimum of processed column values (lazy action)
TResultProxy<::TH1D > Histo1D(std::string_view vName, std::string_view wName)
Fill and return a one-dimensional histogram with the weighted values of a column (lazy action) ...
TInterface< TLoopManager > Cache(const ColumnNames_t &columnList)
Save selected columns in memory.
TDataSource defines an API that TDataFrame can use to read arbitrary data formats.
TInterface< TDFDetail::TRange< Proxied > > Range(unsigned int start, unsigned int stop, unsigned int stride=1)
Creates a node that filters entries based on range.
TResultProxy<::TH1D > Histo1D(const TH1DModel &model={"", "", 128u, 0., 0.}, std::string_view vName="")
Fill and return a one-dimensional histogram with the values of a column (lazy action) ...
TResultProxy<::TH3D > Histo3D(const TH3DModel &model)
TInterface< TDFDetail::TFilter< F, Proxied > > Filter(F f, const ColumnNames_t &columns={}, std::string_view name="")
Append a filter to the call graph.
TResultProxy<::TH1D > Histo1D(const TH1DModel &model, std::string_view vName, std::string_view wName)
Fill and return a one-dimensional histogram with the weighted values of a column (lazy action) ...
Double_t Mean(Long64_t n, const T *a, const Double_t *w=0)
std::shared_ptr<::TProfile > GetProfile() const
TResultProxy<::TProfile2D > Profile2D(const TProfile2DModel &model, std::string_view v1Name, std::string_view v2Name, std::string_view v3Name, std::string_view wName)
Fill and return a two-dimensional profile (lazy action)
TInterface< Proxied > Define(std::string_view name, F expression, const ColumnNames_t &columns={})
Creates a custom column.
A struct which stores the parameters of a TProfile.
std::shared_ptr< TLoopManager > GetDataFrameChecked()
Get the TLoopManager if reachable. If not, throw.
TInterface< TDFDetail::TFilter< F, Proxied > > Filter(F f, std::string_view name)
Append a filter to the call graph.
TResultProxy<::TH3D > Histo3D(const TH3DModel &model, std::string_view v1Name="", std::string_view v2Name="", std::string_view v3Name="")
Fill and return a three-dimensional histogram (lazy action)
TResultProxy<::TProfile2D > Profile2D(const TProfile2DModel &model)
const std::shared_ptr< Proxied > fProxiedPtr
Smart pointer to the graph node encapsulated by this TInterface.
TResultProxy<::TH1D > Histo1D(std::string_view vName)
TResultProxy<::TProfile2D > Profile2D(const TProfile2DModel &model, std::string_view v1Name="", std::string_view v2Name="", std::string_view v3Name="")
Fill and return a two-dimensional profile (lazy action)
Lightweight storage for a collection of types.
TResultProxy< T > Fill(T &&model, const ColumnNames_t &bl)
Return an object of type T on which T::Fill will be called once per event (lazy action) ...
TResultProxy<::TProfile > Profile1D(const TProfile1DModel &model, std::string_view v1Name="", std::string_view v2Name="")
Fill and return a one-dimensional profile (lazy action)
TInterface< TFilterBase > Filter(std::string_view expression, std::string_view name="")
Append a filter to the call graph.
Ssiz_t Index(const TString &str, Ssiz_t *len, Ssiz_t start=0) const
Find the first occurrence of the regexp in string and return the position, or -1 if there is no match...
unsigned long long ULong64_t
Print a TSeq at the prompt:
void Run(unsigned int slot, Long64_t entry) final
typename TTakeRealTypes< T, C >::RealColl_t ColType_t
void Report()
Print filtering statistics on screen.
const std::weak_ptr< TLoopManager > fImplWeakPtr
Weak pointer to the TLoopManager at the root of the graph.
static RooMathCoreReg dummy
ROOT type_traits extensions.
static constexpr double s
Extract types from the signature of a callable object. See CallableTraits.
TResultProxy<::TH2D > Histo2D(const TH2DModel &model, std::string_view v1Name="", std::string_view v2Name="")
Fill and return a two-dimensional histogram (lazy action)
Binding & operator=(OUT(*fun)(void))
TResultProxy< ActionResultType > CreateAction(const ColumnNames_t &columns, const std::shared_ptr< ActionResultType > &r, const int nColumns=-1)
TResultProxy<::TH3D > Histo3D(const TH3DModel &model, std::string_view v1Name, std::string_view v2Name, std::string_view v3Name, std::string_view wName)
Fill and return a three-dimensional histogram (lazy action)
typedef void((*Func_t)())
void CheckSnapshot(unsigned int nTemplateParams, unsigned int nColumnNames)
std::string ColumnName2ColumnTypeName(const std::string &colName, TTree *tree, TCustomColumnBase *tmpBranch, TDataSource *ds)
Return a string containing the type of the given branch.
std::vector< T ** > GetColumnReaders(std::string_view columnName)
Called at most once per column by TDF.
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
std::shared_ptr<::TProfile2D > GetProfile() const
ROOT's TDataFrame offers a high level interface for analyses of data stored in TTrees.
Short_t Max(Short_t a, Short_t b)
A struct which stores the parameters of a TH1D.
ColumnNames_t fValidCustomColumns
Names of columns Defined for this branch of the functional graph.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
TInterfaceJittedDefine Define(std::string_view name, std::string_view expression)
Creates a custom column.
void Foreach(F f, const ColumnNames_t &columns={})
Execute a user-defined function on each entry (instant action)
typename std::conditional< isAB &&TDFInternal::IsDeque_t< NewC1_t >::value, std::deque< VTColl_t >, NewC1_t >::type NewC2_t
std::shared_ptr<::TH2D > GetHistogram() const
std::shared_ptr< TCustomColumnBase > TmpBranchBasePtr_t
TInterface< Proxied > DefineImpl(std::string_view, F, const ColumnNames_t &={})
void CallBuildAndBook(PrevNodeType &prevNode, const ColumnNames_t &bl, const unsigned int nSlots, const std::shared_ptr< ActionResultType > *rOnHeap, const std::shared_ptr< TActionBase *> *actionPtrPtrOnHeap)
Convenience function invoked by jitted code to build action nodes at runtime.
Long_t JitTransformation(void *thisPtr, std::string_view methodName, std::string_view interfaceTypeName, std::string_view name, std::string_view expression, const std::map< std::string, std::string > &aliasMap, const ColumnNames_t &branches, const std::vector< std::string > &customColumns, const std::map< std::string, TmpBranchBasePtr_t > &tmpBookedBranches, TTree *tree, std::string_view returnTypeName, TDataSource *ds)
virtual const std::vector< std::string > & GetColumnNames() const =0
Returns a reference to the collection of the dataset's column names.
value_type * operator()(unsigned int, ULong64_t iEvent)
TInterface< TDFDetail::TRange< Proxied > > Range(unsigned int stop)
Creates a node that filters entries based on range.
MinReturnType_t< T > SumReturnType_t
ColumnNames_t GetBranchNames(TTree &t)
Get all the branches names, including the ones of the friend trees.
The public interface to the TDataFrame federation of classes.
TInterface< TLoopManager > Snapshot(std::string_view treename, std::string_view filename, const ColumnNames_t &columnList, const TSnapshotOptions &options=TSnapshotOptions())
Save selected columns to disk, in a new TTree treename in file filename.
TInterface< Proxied > DefineSlot(std::string_view name, F expression, const ColumnNames_t &columns={})
Creates a custom column with a value dependent on the processing slot.
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
TResultProxy<::TH2D > Histo2D(const TH2DModel &model)
TResultProxy< typename TDFDetail::ColType_t< T, COLL > > Take(std::string_view column="")
Return a collection of values of a column (lazy action, returns a std::vector by default) ...
TResultProxy<::TProfile > Profile1D(const TProfile1DModel &model, std::string_view v1Name, std::string_view v2Name, std::string_view wName)
Fill and return a one-dimensional profile (lazy action)
TInterface(const std::shared_ptr< Proxied > &proxied)
Only enabled when building a TInterface<TLoopManager>