Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RDisplay.hxx
Go to the documentation of this file.
1// Author: Enrico Guiraud, Danilo Piparo CERN, Massimo Tumolo Politecnico di Torino 08/2018
2
3/*************************************************************************
4 * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11#ifndef ROOT_RDFDISPLAYER
12#define ROOT_RDFDISPLAYER
13
14#include "ROOT/RDF/Utils.hxx" // IsDataContainer, InterpreterCalc
15#include "ROOT/RVec.hxx"
16#include "ROOT/TypeTraits.hxx"
17#include "TClassEdit.h"
18
19#include <vector>
20#include <string>
21#include <iostream>
22#include <sstream>
23
24namespace ROOT {
25namespace Internal {
26namespace RDF {
27
28template<typename T>
30std::string PrettyPrintAddr(const void *const addr);
31
33private:
35 std::string fRepresentation;
37
38public:
39 RDisplayElement(const std::string &representation);
41 void SetPrint();
42 void SetIgnore();
43 void SetDots();
44 bool IsPrint() const;
45 bool IsIgnore() const;
46 bool IsDot() const;
47 const std::string &GetRepresentation() const;
48 bool IsEmpty() const;
49};
50} // namespace RDF
51} // namespace Internal
52
53namespace RDF {
54
55/**
56 * \class ROOT::RDF::RDisplay
57 * \ingroup dataframe
58 * This class is the textual representation of the content of a columnar dataset.
59 *
60 * This class is provided to the user, and it can be used to print on screen
61 * the entries of the dataset requested through the Display action in a compact
62 * representation or to return the full representation of the events as a string.
63 * In order to apply proper formatting the content is buffered in memory as strings.
64 */
65class RDisplay {
66 template<typename T>
68private:
69 using VecStr_t = std::vector<std::string>;
71 static constexpr char fgSeparator = ' '; ///< Spacing used to align the table entries
72 static constexpr unsigned fgMaxWidth = 100; ///< Maximum width of the table that Print() displays
73
74 VecStr_t fTypes; ///< This attribute stores the type of each column. It is needed by the interpreter to print it.
75 std::vector<bool> fIsCollection; ///< True if the column contains a collection. Collections are treated differently
76 ///< during the printing.
77 std::vector<std::vector<DElement_t>> fTable; ///< String representation of the data to be printed.
78 std::vector<unsigned short> fWidths; ///< Tracks the maximum width of each column, based on the largest element.
79
80 VecStr_t fRepresentations; ///< Used by the JITted code to store the string representation of the data.
81 std::vector<VecStr_t> fCollectionsRepresentations; ///< Used by the JITted code to store the string representation of
82 ///< the data in case of collection. Each row corresponds to a
83 ///< column, each column to a value of the collection.
84
85 size_t fNColumns; ///< Number of columns to be printed
86
87 size_t fCurrentRow = 0; ///< Row that is being filled
88 size_t fNextRow = 1; ///< Next row to be filled.
89 size_t fCurrentColumn = 0; ///< Column that is being filled.
90
91 size_t fNMaxCollectionElements = 10; // threshold on number of elements in collections to be Print()
92
93 ////////////////////////////////////////////////////////////////////////////
94 /// Appends a cling::printValue call to the stringstream.
95 /// \tparam T the type of the event to convert
96 /// \param[in] stream Where the conversion function call will be chained.
97 /// \param[in] element The event to convert to its string representation
98 /// \param[in] index To which column the event belongs to
99 /// \return false, the event is not a collection
100 template <typename T, std::enable_if_t<!ROOT::Internal::RDF::IsDataContainer<T>::value, int> = 0>
101 bool AddInterpreterString(std::stringstream &stream, T &element, const int &index)
102 {
103 stream << "*((std::string*)" << ROOT::Internal::RDF::PrettyPrintAddr(&(fRepresentations[index]))
104 << ") = cling::printValue((" << fTypes[index] << "*)" << ROOT::Internal::RDF::PrettyPrintAddr(&element) << ");";
105 return false;
106 }
107
108 ////////////////////////////////////////////////////////////////////////////
109 /// Appends collection.size() cling::printValue calls to the stringstream.
110 /// \tparam T the type of the event to convert
111 /// \param[in] stream Where the conversion function call will be chained.
112 /// \param[in] collection The event to convert to its string representation
113 /// \param[in] index To which column the event belongs to
114 /// \return true, the event is a collection
115 /// This function chains a sequence of call to cling::printValue, one for each element of the collection.
116 template <typename T, std::enable_if_t<ROOT::Internal::RDF::IsDataContainer<T>::value, int> = 0>
117 bool AddInterpreterString(std::stringstream &stream, T &collection, const int &index)
118 {
119 size_t collectionSize = std::distance(std::begin(collection), std::end(collection));
120 // Prepare the row to contain as many elements as the number of elements in the collection
121 fCollectionsRepresentations[index] = VecStr_t(collectionSize);
122
123 // Use GetSplit to get the encapsulated type of the collection. For example, GetSplit on
124 // std::vector<std::vector<int>> will return std::vector<int>
126 int nestedLoc = 0;
127 TClassEdit::GetSplit(fTypes[index].c_str(), output, nestedLoc);
128
129 // For each element, append a call and feed the proper type returned by GetSplit
130 for (size_t i = 0; i < collectionSize; ++i) {
131 stream << "*((std::string*)" << ROOT::Internal::RDF::PrettyPrintAddr(&(fCollectionsRepresentations[index][i]))
132 << ") = cling::printValue((" << output[1] << "*)"
133 << ROOT::Internal::RDF::PrettyPrintAddr(&(collection[i])) << ");";
134 }
135 return true;
136 }
137
138 ////////////////////////////////////////////////////////////////////////////
139 /// AddInterpreterString overload for arrays of chars.
140 ///
141 /// \param[in] charArr The character array to convert to string representation
142 /// \param[in] index To which column the event belongs
143 /// \return false, the event is not a collection
144 ///
145 /// This specialization for arrays of characters skips the cling::printValue
146 /// (i.e. appends nothing to the stream) and directly writes to fRepresentations the
147 /// string representation of the array of chars.
148 bool AddInterpreterString(std::stringstream &, ROOT::RVec<char> &charArr, const int &index)
149 {
150 // if null-terminated char array, do not copy the null terminator into std::string, it makes columns misaligned.
151 const auto length = charArr[charArr.size()-1] == '\0' ? charArr.size() - 1 : charArr.size();
152 const std::string arrAsStr(charArr.data(), length); // also works for non-null-terminated strings
153 fRepresentations[index] = arrAsStr;
154 return false; // do not treat this as a collection
155 }
156
157 ////////////////////////////////////////////////////////////////////////////
158 /// AddInterpreterString overload for arrays of booleans.
159 ///
160 /// \param[in] boolArr The bool array to convert to string representation
161 /// \param[in] index To which column the event belongs
162 /// \return true, the event is a collection
163 ///
164 /// This specialization for arrays of booleans skips the cling::printValue
165 /// (i.e. appends nothing to the stream) and directly writes to fCollectionsRepresentations the
166 /// string representation of the array of chars.
167 bool AddInterpreterString(std::stringstream &, ROOT::RVec<bool> &boolArr, const int &index)
168 {
169 fCollectionsRepresentations[index].reserve(boolArr.size());
170 for (bool b : boolArr)
171 fCollectionsRepresentations[index].push_back(b ? "true" : "false");
172
173 return true; // treat this as a collection
174 }
175
176
177 ////////////////////////////////////////////////////////////////////////////
178 /// Adds a single element to the next slot in the table
179 void AddToRow(const std::string &stringEle);
180
181 ////////////////////////////////////////////////////////////////////////////
182 /// Adds a collection to the table
183 ///
184 /// Starting from the slot, the elements are added one under the other, each
185 /// one using a single cell of an entire row
186 void AddCollectionToRow(const VecStr_t &collection);
187
188 ////////////////////////////////////////////////////////////////////////////
189 /// Moves to the next cell
190 ///
191 /// Moves to the next cell, and if the row is full moves to the next row.
192 void MovePosition();
193
194 ////////////////////////////////////////////////////////////////////////////
195 /// Get the number of columns that do NOT fit in the characters limit
196 size_t GetNColumnsToShorten() const;
197
198 ////////////////////////////////////////////////////////////////////////////
199 /// Generate dashes between entries in Print() and AsString() Methods
200 std::string DashesBetweenLines(size_t lastColToPrint, bool allColumnsFit) const;
201
202 ////////////////////////////////////////////////////////////////////////////
203 /// Adds a row of events to the table
204 template <typename... Columns>
205 void AddRow(Columns &... columns)
206 {
207 std::stringstream calc; // JITted code
208 int columnIndex = 0;
209 // Unwrapping the parameters to create the JITted code.
210 fIsCollection = {AddInterpreterString(calc, columns, columnIndex++)...};
211
212 // Let cling::printValue handle the conversion. This can be done only through cling-compiled code.
213 const std::string toJit = calc.str();
214 if (!toJit.empty())
215 ROOT::Internal::RDF::InterpreterCalc(calc.str(), "Display");
216
217 // Populate the fTable using the results of the JITted code.
218 for (size_t i = 0; i < fNColumns; ++i) {
219 if (fIsCollection[i]) {
221 } else {
223 }
224 }
225 }
226
227 void EnsureCurrentColumnWidth(size_t w);
228
229public:
230 ////////////////////////////////////////////////////////////////////////////
231 /// Creates an RDisplay to print the event values
232 /// \param[in] columnNames Columns to print
233 /// \param[in] types The type of each column
234 /// \param[in] nMaxCollectionElements Number of maximum elements in collection.
235 RDisplay(const VecStr_t &columnNames, const VecStr_t &types, size_t nMaxCollectionElements);
236
237 ////////////////////////////////////////////////////////////////////////////
238 /// Prints the representation to the standard output
239 ///
240 /// Collections are shortened to the first and last element. The overall width
241 /// is shortened to a fixed number of columns that should fit the screen width.
242 void Print() const;
243
244 ////////////////////////////////////////////////////////////////////////////
245 /// Returns the representation as a string
246 std::string AsString() const;
247};
248
249} // namespace RDF
250} // namespace ROOT
251
252#endif
#define b(i)
Definition RSha256.hxx:100
Helper class to let Display print compact tabular representations of the events.
Definition RDisplay.hxx:32
bool IsIgnore() const
Return if the cell has to be skipped.
bool IsDot() const
Return if the cell has to be replaced by "...".
const std::string & GetRepresentation() const
bool IsPrint() const
Return if the cell has to be printed.
void SetDots()
Flag this cell to be replaced by "...".
void SetPrint()
Flag this cell as to be printed.
void SetIgnore()
Flag this cell as to be skipped.
RDisplayElement()
Constructor assuming an empty representation to be printed.
pointer data() noexcept
Return a pointer to the vector's buffer, even if empty().
Definition RVec.hxx:268
This class is the textual representation of the content of a columnar dataset.
Definition RDisplay.hxx:65
bool AddInterpreterString(std::stringstream &, ROOT::RVec< bool > &boolArr, const int &index)
AddInterpreterString overload for arrays of booleans.
Definition RDisplay.hxx:167
void AddRow(Columns &... columns)
Adds a row of events to the table.
Definition RDisplay.hxx:205
void AddCollectionToRow(const VecStr_t &collection)
Adds a collection to the table.
size_t fCurrentColumn
Column that is being filled.
Definition RDisplay.hxx:89
size_t fNMaxCollectionElements
Definition RDisplay.hxx:91
std::vector< std::vector< DElement_t > > fTable
String representation of the data to be printed.
Definition RDisplay.hxx:77
std::vector< bool > fIsCollection
True if the column contains a collection.
Definition RDisplay.hxx:75
std::string AsString() const
Returns the representation as a string.
void AddToRow(const std::string &stringEle)
Adds a single element to the next slot in the table.
size_t fCurrentRow
Row that is being filled.
Definition RDisplay.hxx:87
VecStr_t fRepresentations
Used by the JITted code to store the string representation of the data.
Definition RDisplay.hxx:80
void MovePosition()
Moves to the next cell.
std::vector< unsigned short > fWidths
Tracks the maximum width of each column, based on the largest element.
Definition RDisplay.hxx:78
bool AddInterpreterString(std::stringstream &stream, T &collection, const int &index)
Appends collection.size() cling::printValue calls to the stringstream.
Definition RDisplay.hxx:117
static constexpr unsigned fgMaxWidth
Maximum width of the table that Print() displays.
Definition RDisplay.hxx:72
void EnsureCurrentColumnWidth(size_t w)
size_t fNextRow
Next row to be filled.
Definition RDisplay.hxx:88
bool AddInterpreterString(std::stringstream &, ROOT::RVec< char > &charArr, const int &index)
AddInterpreterString overload for arrays of chars.
Definition RDisplay.hxx:148
std::string DashesBetweenLines(size_t lastColToPrint, bool allColumnsFit) const
Generate dashes between entries in Print() and AsString() Methods.
std::vector< std::string > VecStr_t
Definition RDisplay.hxx:69
void Print() const
Prints the representation to the standard output.
std::vector< VecStr_t > fCollectionsRepresentations
Used by the JITted code to store the string representation of the data in case of collection.
Definition RDisplay.hxx:81
size_t GetNColumnsToShorten() const
Get the number of columns that do NOT fit in the characters limit.
static constexpr char fgSeparator
Spacing used to align the table entries.
Definition RDisplay.hxx:71
bool AddInterpreterString(std::stringstream &stream, T &element, const int &index)
Appends a cling::printValue call to the stringstream.
Definition RDisplay.hxx:101
VecStr_t fTypes
This attribute stores the type of each column. It is needed by the interpreter to print it.
Definition RDisplay.hxx:74
size_t fNColumns
Number of columns to be printed.
Definition RDisplay.hxx:85
A "std::vector"-like collection of values implementing handy operation to analyse them.
Definition RVec.hxx:1455
std::string PrettyPrintAddr(const void *const addr)
Long64_t InterpreterCalc(const std::string &code, const std::string &context="")
Jit code in the interpreter with TInterpreter::Calc, throw in case of errors.
Definition RDFUtils.cxx:329
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
static void output(int code)
Definition gifencode.c:226