Logo ROOT  
Reference Guide
RDFDisplay.cxx
Go to the documentation of this file.
2#include "TInterpreter.h"
3
4#include <iomanip>
5#include <limits>
6
7namespace ROOT {
8namespace Internal {
9namespace RDF {
10
11
12/**
13 * \class ROOT::Internal::RDF::RDisplayElement
14 * \ingroup dataframe
15 * Helper class to let Display print compact tabular representations of the events
16 *
17 * This class is internal and not meant to be explicitly instantiated by the user.
18 * It is needed during printing to understand if a value can be
19 * skipped or must be printed. Each RDisplayElement represents a cell.
20 */
21
22////////////////////////////////////////////////////////////////////////////
23/// Constructor
24/// \param[in] representation The representation string
25RDisplayElement::RDisplayElement(const std::string &representation) : fRepresentation(representation)
26{
27 SetPrint();
28}
29
30////////////////////////////////////////////////////////////////////////////
31/// Constructor assuming an empty representation to be printed
33{
34 SetPrint();
35}
36
37////////////////////////////////////////////////////////////////////////////
38/// Flag this cell as to be printed
40{
42}
43
44////////////////////////////////////////////////////////////////////////////
45/// Flag this cell as to be skipped
47{
49}
50
51////////////////////////////////////////////////////////////////////////////
52/// Flag this cell to be replaced by "..."
54{
56}
57
58////////////////////////////////////////////////////////////////////////////
59/// Return if the cell has to be printed
61{
63}
64
65////////////////////////////////////////////////////////////////////////////
66/// Return if the cell has to be skipped
68{
70}
71
72////////////////////////////////////////////////////////////////////////////
73/// Return if the cell has to be replaced by "..."
75{
77}
78
79const std::string &RDisplayElement::GetRepresentation() const
80{
81 return fRepresentation;
82}
83
85{
86 return fRepresentation.empty();
87}
88
89} // namespace RDF
90} // namespace Internal
91
92namespace RDF {
93
95{
96 // If the current element is wider than the widest element found, update the width
97 if (fWidths[fCurrentColumn] < w) {
98 if (w > std::numeric_limits<unsigned short>::max()) {
99 w = std::numeric_limits<unsigned short>::max();
100 }
101 fWidths[fCurrentColumn] = (unsigned short) w;
102 }
103}
104
105void RDisplay::AddToRow(const std::string &stringEle)
106{
107 // If the current element is wider than the widest element found, update the width
108 EnsureCurrentColumnWidth(stringEle.length());
109
110 // Save the element...
112
113 // ...and move to the next
114 MovePosition();
115}
116
117void RDisplay::AddCollectionToRow(const std::vector<std::string> &collection)
118{
119 auto row = fCurrentRow;
120 // For each element of the collection, save it. The first element will be in the current row, next ones will have
121 // their own row.
122 size_t collectionSize = collection.size();
123 for (size_t index = 0; index < collectionSize; ++index) {
124 auto stringEle = collection[index];
125 auto element = DElement_t(stringEle);
126
127 // Update the width if this element is the biggest found
128 EnsureCurrentColumnWidth(stringEle.length());
129
130 if (index == 0 || index == collectionSize - 1) {
131 // Do nothing, by default DisplayElement is printed
132 } else if (index == 1) {
133 element.SetDots();
134 // Be sure the "..." fit
136 } else {
137 // In the Print(), after the dots, all element will just be ignored except the last one.
138 element.SetIgnore();
139 }
140
141 // Save the element
142 fTable[row][fCurrentColumn] = element;
143 ++row;
144
145 if (index != collectionSize - 1 && fTable.size() <= row) {
146 // This is not the last element, prepare the next row for the next element, if not already done by another
147 // collection
148 fTable.push_back(std::vector<DElement_t>(fNColumns));
149 }
150 }
151 fNextRow = (fNextRow > row) ? fNextRow : row;
152 MovePosition();
153}
154
156{
157 // Go to the next element. If it is outside the row, just go the first element of the next row.
159 if (fCurrentColumn == fNColumns) {
161 fCurrentColumn = 0;
162 fNextRow = fCurrentRow + 1;
163 fTable.push_back(std::vector<DElement_t>(fNColumns));
164 }
165}
166
167RDisplay::RDisplay(const VecStr_t &columnNames, const VecStr_t &types, int entries)
168 : fTypes(types), fWidths(columnNames.size(), 0), fRepresentations(columnNames.size()),
169 fCollectionsRepresentations(columnNames.size()), fNColumns(columnNames.size()), fEntries(entries)
170{
171
172 // Add the first row with the names of the columns
173 fTable.push_back(std::vector<DElement_t>(columnNames.size()));
174 for (auto name : columnNames) {
175 AddToRow(name);
176 }
177}
178
180{
181 size_t totalWidth = 0;
182
183 auto size = fWidths.size();
184 for (size_t i = 0; i < size; ++i) {
185 totalWidth += fWidths[i];
186 if (totalWidth > fgMaxWidth) {
187 return size - i;
188 }
189 }
190
191 return 0;
192}
193
194void RDisplay::Print() const
195{
196 auto columnsToPrint =
197 fNColumns - GetNColumnsToShorten(); // Get the number of columns that fit in the characters limit
198 std::vector<bool> hasPrintedNext(fNColumns,
199 false); // Keeps track if the collection as already been shortened, allowing to skip
200 // all elements until the next printable element.
201 auto nrRows = fTable.size();
202 for (size_t rowIndex = 0; rowIndex < nrRows; ++rowIndex) {
203 auto &row = fTable[rowIndex];
204
205 std::stringstream stringRow;
206 bool isRowEmpty = true; // It may happen during compacting that some rows are empty, this happens for example if
207 // collections have different size. Thanks to this flag, these rows are just ignored.
208 for (size_t columnIndex = 0; columnIndex < columnsToPrint; ++columnIndex) {
209 const auto &element = row[columnIndex];
210 std::string printedElement = "";
211
212 if (element.IsDot()) {
213 printedElement = "...";
214 } else if (element.IsPrint()) {
215 // Maybe the element is part of a collection that is being shortened, and so it was already printed.
216 if (!hasPrintedNext[columnIndex]) {
217 printedElement = element.GetRepresentation();
218 }
219 hasPrintedNext[columnIndex] =
220 false; // Encountered "next printable element", shortening can start again when needed.
221 } else { // IsIgnore
222 // Shortening is starting here. Print directly the last element, to have something like 1 ... 3, and don't
223 // print anything else.
224 if (!hasPrintedNext[columnIndex]) {
225 size_t i = rowIndex + 1; // Starting from the next row...
226 for (; !fTable[i][columnIndex].IsPrint(); ++i) {
227 // .. look for the first element that can be printed, it will be the last of the collection.
228 }
229 printedElement = fTable[i][columnIndex].GetRepresentation(); // Print the element
230 hasPrintedNext[columnIndex] = true; // And start ignoring anything else until the next collection.
231 }
232 }
233 if (!printedElement.empty()) {
234 // Found at least one element, so the row is not empty.
235 isRowEmpty = false;
236 }
237
238 stringRow << std::left << std::setw(fWidths[columnIndex]) << std::setfill(fgSeparator) << printedElement
239 << " | ";
240 }
241 if (!isRowEmpty) {
242 std::cout << stringRow.str() << std::endl;
243 }
244 }
245}
246
247std::string RDisplay::AsString() const
248{
249 // This method works as Print() but without any check on collection. It just returns a string with the whole
250 // representation
251 std::stringstream stringRepresentation;
252 for (auto row : fTable) {
253 for (size_t i = 0; i < row.size(); ++i) {
254 stringRepresentation << std::left << std::setw(fWidths[i]) << std::setfill(fgSeparator)
255 << row[i].GetRepresentation() << " | ";
256 }
257 stringRepresentation << "\n";
258 }
259 return stringRepresentation.str();
260}
261
262} // namespace RDF
263} // namespace ROOT
l unsigned short
Definition: Converters.cxx:862
char name[80]
Definition: TGX11.cxx:109
bool IsIgnore() const
Return if the cell has to be skipped.
Definition: RDFDisplay.cxx:67
bool IsDot() const
Return if the cell has to be replaced by "...".
Definition: RDFDisplay.cxx:74
const std::string & GetRepresentation() const
Definition: RDFDisplay.cxx:79
bool IsPrint() const
Return if the cell has to be printed.
Definition: RDFDisplay.cxx:60
void SetDots()
Flag this cell to be replaced by "...".
Definition: RDFDisplay.cxx:53
void SetPrint()
Flag this cell as to be printed.
Definition: RDFDisplay.cxx:39
void SetIgnore()
Flag this cell as to be skipped.
Definition: RDFDisplay.cxx:46
RDisplayElement()
Constructor assuming an empty representation to be printed.
Definition: RDFDisplay.cxx:32
void AddCollectionToRow(const VecStr_t &collection)
Adds a collection to the table.
Definition: RDFDisplay.cxx:117
size_t fCurrentColumn
Column that is being filled.
Definition: RDisplay.hxx:88
ROOT::Internal::RDF::RDisplayElement DElement_t
Definition: RDisplay.hxx:69
std::vector< std::vector< DElement_t > > fTable
String representation of the data to be printed.
Definition: RDisplay.hxx:76
std::string AsString() const
Returns the representation as a string.
Definition: RDFDisplay.cxx:247
void AddToRow(const std::string &stringEle)
Adds a single element to the next slot in the table.
Definition: RDFDisplay.cxx:105
size_t fCurrentRow
Row that is being filled.
Definition: RDisplay.hxx:86
void MovePosition()
Moves to the next cell.
Definition: RDFDisplay.cxx:155
std::vector< unsigned short > fWidths
Tracks the maximum width of each column, based on the largest element.
Definition: RDisplay.hxx:77
static constexpr unsigned fgMaxWidth
Definition: RDisplay.hxx:71
RDisplay(const VecStr_t &columnNames, const VecStr_t &types, int entries)
Creates an RDisplay to print the event values.
Definition: RDFDisplay.cxx:167
void EnsureCurrentColumnWidth(size_t w)
Definition: RDFDisplay.cxx:94
size_t fNextRow
Next row to be filled.
Definition: RDisplay.hxx:87
std::vector< std::string > VecStr_t
Definition: RDisplay.hxx:68
void Print() const
Prints the representation to the standard output.
Definition: RDFDisplay.cxx:194
size_t GetNColumnsToShorten() const
Get the number of columns that do NOT fit in the characters limit.
Definition: RDFDisplay.cxx:179
static constexpr char fgSeparator
Spacing used to align the table entries.
Definition: RDisplay.hxx:70
size_t fNColumns
Number of columns to be printed.
Definition: RDisplay.hxx:84
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition: StringConv.hxx:21