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 <sstream>
22
23namespace ROOT {
24namespace Internal {
25namespace RDF {
26
27template<typename T>
29std::string PrettyPrintAddr(const void *const addr);
30
32private:
34 std::string fRepresentation;
36
37public:
38 RDisplayElement(const std::string &representation);
40 void SetPrint();
41 void SetIgnore();
42 void SetDots();
43 bool IsPrint() const;
44 bool IsIgnore() const;
45 bool IsDot() const;
46 const std::string &GetRepresentation() const;
47 bool IsEmpty() const;
48};
49} // namespace RDF
50} // namespace Internal
51
52namespace RDF {
53
54/**
55 * \class ROOT::RDF::RDisplay
56 * \ingroup dataframe
57 * This class is the textual representation of the content of a columnar dataset.
58 *
59 * This class is provided to the user, and it can be used to print on screen
60 * the entries of the dataset requested through the Display action in a compact
61 * representation or to return the full representation of the events as a string.
62 * In order to apply proper formatting the content is buffered in memory as strings.
63 */
64class RDisplay {
65 template<typename T>
67private:
68 using VecStr_t = std::vector<std::string>;
70 static constexpr char fgSeparator = ' '; ///< Spacing used to align the table entries
71 static constexpr unsigned fgMaxWidth = 100; ///< Maximum width of the table that Print() displays
72
73 VecStr_t fTypes; ///< This attribute stores the type of each column. It is needed by the interpreter to print it.
74 std::vector<bool> fIsCollection; ///< True if the column contains a collection. Collections are treated differently
75 ///< during the printing.
76 std::vector<std::vector<DElement_t>> fTable; ///< String representation of the data to be printed.
77 std::vector<unsigned short> fWidths; ///< Tracks the maximum width of each column, based on the largest element.
78
79 VecStr_t fRepresentations; ///< Used by the JITted code to store the string representation of the data.
80 std::vector<VecStr_t> fCollectionsRepresentations; ///< Used by the JITted code to store the string representation of
81 ///< the data in case of collection. Each row corresponds to a
82 ///< column, each column to a value of the collection.
83
84 size_t fNColumns; ///< Number of columns to be printed
85
86 size_t fCurrentRow = 0; ///< Row that is being filled
87 size_t fNextRow = 1; ///< Next row to be filled.
88 size_t fCurrentColumn = 0; ///< Column that is being filled.
89
90 size_t fNMaxCollectionElements = 10; // threshold on number of elements in collections to be Print()
91
92 ////////////////////////////////////////////////////////////////////////////
93 /// Appends a cling::printValue call to the stringstream.
94 /// \tparam T the type of the event to convert
95 /// \param[in] stream Where the conversion function call will be chained.
96 /// \param[in] element The event to convert to its string representation
97 /// \param[in] index To which column the event belongs to
98 /// \return false, the event is not a collection
99 template <typename T, std::enable_if_t<!ROOT::Internal::RDF::IsDataContainer<T>::value, int> = 0>
100 bool AddInterpreterString(std::stringstream &stream, T &element, const int &index)
101 {
102 stream << "*((std::string*)" << ROOT::Internal::RDF::PrettyPrintAddr(&(fRepresentations[index]))
103 << ") = cling::printValue((" << fTypes[index] << "*)" << ROOT::Internal::RDF::PrettyPrintAddr(&element) << ");";
104 return false;
105 }
106
107 ////////////////////////////////////////////////////////////////////////////
108 /// Appends collection.size() cling::printValue calls to the stringstream.
109 /// \tparam T the type of the event to convert
110 /// \param[in] stream Where the conversion function call will be chained.
111 /// \param[in] collection The event to convert to its string representation
112 /// \param[in] index To which column the event belongs to
113 /// \return true, the event is a collection
114 /// This function chains a sequence of call to cling::printValue, one for each element of the collection.
115 template <typename T, std::enable_if_t<ROOT::Internal::RDF::IsDataContainer<T>::value, int> = 0>
116 bool AddInterpreterString(std::stringstream &stream, T &collection, const int &index)
117 {
118 size_t collectionSize = std::distance(std::begin(collection), std::end(collection));
119 // Prepare the row to contain as many elements as the number of elements in the collection
120 fCollectionsRepresentations[index] = VecStr_t(collectionSize);
121
122 // Use GetSplit to get the encapsulated type of the collection. For example, GetSplit on
123 // std::vector<std::vector<int>> will return std::vector<int>
125 int nestedLoc = 0;
126 TClassEdit::GetSplit(fTypes[index].c_str(), output, nestedLoc);
127
128 // For each element, append a call and feed the proper type returned by GetSplit
129 for (size_t i = 0; i < collectionSize; ++i) {
130 stream << "*((std::string*)" << ROOT::Internal::RDF::PrettyPrintAddr(&(fCollectionsRepresentations[index][i]))
131 << ") = cling::printValue((" << output[1] << "*)"
132 << ROOT::Internal::RDF::PrettyPrintAddr(&(collection[i])) << ");";
133 }
134 return true;
135 }
136
137 ////////////////////////////////////////////////////////////////////////////
138 /// AddInterpreterString overload for arrays of chars.
139 ///
140 /// \param[in] charArr The character array to convert to string representation
141 /// \param[in] index To which column the event belongs
142 /// \return false, the event is not a collection
143 ///
144 /// This specialization for arrays of characters skips the cling::printValue
145 /// (i.e. appends nothing to the stream) and directly writes to fRepresentations the
146 /// string representation of the array of chars.
147 bool AddInterpreterString(std::stringstream &, ROOT::RVec<char> &charArr, const int &index)
148 {
149 // if null-terminated char array, do not copy the null terminator into std::string, it makes columns misaligned.
150 const auto length = charArr[charArr.size()-1] == '\0' ? charArr.size() - 1 : charArr.size();
151 const std::string arrAsStr(charArr.data(), length); // also works for non-null-terminated strings
152 fRepresentations[index] = arrAsStr;
153 return false; // do not treat this as a collection
154 }
155
156 ////////////////////////////////////////////////////////////////////////////
157 /// AddInterpreterString overload for arrays of booleans.
158 ///
159 /// \param[in] boolArr The bool array to convert to string representation
160 /// \param[in] index To which column the event belongs
161 /// \return true, the event is a collection
162 ///
163 /// This specialization for arrays of booleans skips the cling::printValue
164 /// (i.e. appends nothing to the stream) and directly writes to fCollectionsRepresentations the
165 /// string representation of the array of chars.
166 bool AddInterpreterString(std::stringstream &, ROOT::RVec<bool> &boolArr, const int &index)
167 {
168 auto &collRepr = fCollectionsRepresentations[index];
169 collRepr.clear();
170 collRepr.reserve(boolArr.size());
171 for (bool b : boolArr)
172 collRepr.push_back(b ? "true" : "false");
173
174 return true; // treat this as a collection
175 }
176
177
178 ////////////////////////////////////////////////////////////////////////////
179 /// Adds a single element to the next slot in the table
180 void AddToRow(const std::string &stringEle);
181
182 ////////////////////////////////////////////////////////////////////////////
183 /// Adds a collection to the table
184 ///
185 /// Starting from the slot, the elements are added one under the other, each
186 /// one using a single cell of an entire row
187 void AddCollectionToRow(const VecStr_t &collection);
188
189 ////////////////////////////////////////////////////////////////////////////
190 /// Moves to the next cell
191 ///
192 /// Moves to the next cell, and if the row is full moves to the next row.
193 void MovePosition();
194
195 ////////////////////////////////////////////////////////////////////////////
196 /// Get the number of columns that do NOT fit in the characters limit
197 size_t GetNColumnsToShorten() const;
198
199 ////////////////////////////////////////////////////////////////////////////
200 /// Generate dashes between entries in Print() and AsString() Methods
201 std::string DashesBetweenLines(size_t lastColToPrint, bool allColumnsFit) const;
202
203 ////////////////////////////////////////////////////////////////////////////
204 /// Adds a row of events to the table
205 template <typename... Columns>
206 void AddRow(Columns &... columns)
207 {
208 std::stringstream calc; // JITted code
209 int columnIndex = 0;
210 // Unwrapping the parameters to create the JITted code.
211 fIsCollection = {AddInterpreterString(calc, columns, columnIndex++)...};
212
213 // Let cling::printValue handle the conversion. This can be done only through cling-compiled code.
214 const std::string toJit = calc.str();
215 if (!toJit.empty())
216 ROOT::Internal::RDF::InterpreterCalc(calc.str(), "Display");
217
218 // Populate the fTable using the results of the JITted code.
219 for (size_t i = 0; i < fNColumns; ++i) {
220 if (fIsCollection[i]) {
222 } else {
224 }
225 }
226 }
227
228 void EnsureCurrentColumnWidth(size_t w);
229
230public:
231 ////////////////////////////////////////////////////////////////////////////
232 /// Creates an RDisplay to print the event values
233 /// \param[in] columnNames Columns to print
234 /// \param[in] types The type of each column
235 /// \param[in] nMaxCollectionElements Number of maximum elements in collection.
236 RDisplay(const VecStr_t &columnNames, const VecStr_t &types, size_t nMaxCollectionElements);
237
238 ////////////////////////////////////////////////////////////////////////////
239 /// Prints the representation to the standard output
240 ///
241 /// Collections are shortened to the first and last element. The overall width
242 /// is shortened to a fixed number of columns that should fit the screen width.
243 void Print() const;
244
245 ////////////////////////////////////////////////////////////////////////////
246 /// Returns the representation as a string
247 std::string AsString() const;
248};
249
250} // namespace RDF
251} // namespace ROOT
252
253#endif
#define b(i)
Definition RSha256.hxx:100
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Helper class to let Display print compact tabular representations of the events.
Definition RDisplay.hxx:31
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:280
This class is the textual representation of the content of a columnar dataset.
Definition RDisplay.hxx:64
bool AddInterpreterString(std::stringstream &, ROOT::RVec< bool > &boolArr, const int &index)
AddInterpreterString overload for arrays of booleans.
Definition RDisplay.hxx:166
void AddRow(Columns &... columns)
Adds a row of events to the table.
Definition RDisplay.hxx:206
void AddCollectionToRow(const VecStr_t &collection)
Adds a collection to the table.
size_t fCurrentColumn
Column that is being filled.
Definition RDisplay.hxx:88
size_t fNMaxCollectionElements
Definition RDisplay.hxx:90
std::vector< std::vector< DElement_t > > fTable
String representation of the data to be printed.
Definition RDisplay.hxx:76
std::vector< bool > fIsCollection
True if the column contains a collection.
Definition RDisplay.hxx:74
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:86
VecStr_t fRepresentations
Used by the JITted code to store the string representation of the data.
Definition RDisplay.hxx:79
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:77
bool AddInterpreterString(std::stringstream &stream, T &collection, const int &index)
Appends collection.size() cling::printValue calls to the stringstream.
Definition RDisplay.hxx:116
static constexpr unsigned fgMaxWidth
Maximum width of the table that Print() displays.
Definition RDisplay.hxx:71
void EnsureCurrentColumnWidth(size_t w)
size_t fNextRow
Next row to be filled.
Definition RDisplay.hxx:87
bool AddInterpreterString(std::stringstream &, ROOT::RVec< char > &charArr, const int &index)
AddInterpreterString overload for arrays of chars.
Definition RDisplay.hxx:147
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:68
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:80
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:70
bool AddInterpreterString(std::stringstream &stream, T &element, const int &index)
Appends a cling::printValue call to the stringstream.
Definition RDisplay.hxx:100
VecStr_t fTypes
This attribute stores the type of each column. It is needed by the interpreter to print it.
Definition RDisplay.hxx:73
size_t fNColumns
Number of columns to be printed.
Definition RDisplay.hxx:84
A "std::vector"-like collection of values implementing handy operation to analyse them.
Definition RVec.hxx:1492
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:327
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
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()