13#include <rapidjson/reader.h>
14#include <rapidjson/prettywriter.h>
15#include <rapidjson/istreamwrapper.h>
16#include <rapidjson/ostreamwrapper.h>
17#include <rapidjson/error/en.h>
27using nodes = expressions::Node::self_t;
28enum struct Nodes :
int {
46 expressions::Node*
ptr =
nullptr;
50std::array<std::string_view, 11> validKeys{
63struct ExpressionReader :
public rapidjson::BaseReaderHandler<rapidjson::UTF8<>, ExpressionReader> {
64 using Ch = rapidjson::UTF8<>::Ch;
65 using SizeType = rapidjson::SizeType;
85 std::vector<expressions::Projector>
result;
87 std::unique_ptr<expressions::Node>
rootNode =
nullptr;
88 std::unique_ptr<expressions::Node>
node =
nullptr;
102 debug <<
">>> Start" << std::endl;
103 states.push(State::IN_START);
108 debug <<
"StartArray()" << std::endl;
109 if (
states.top() == State::IN_START) {
110 states.push(State::IN_LIST);
113 states.push(State::IN_ERROR);
117 bool EndArray(SizeType)
119 debug <<
"EndArray()" << std::endl;
120 if (
states.top() == State::IN_LIST) {
124 states.push(State::IN_ERROR);
128 bool Key(
const Ch*
str, SizeType,
bool)
130 debug <<
"Key(" <<
str <<
")" << std::endl;
133 if (std::find(validKeys.begin(), validKeys.end(), currentKey) == validKeys.end()) {
134 states.push(State::IN_ERROR);
138 if (
states.top() == State::IN_START) {
144 if (
states.top() == State::IN_ROOT) {
148 states.push(State::IN_ERROR);
153 if (
states.top() == State::IN_LEFT ||
states.top() == State::IN_RIGHT ||
states.top() == State::IN_COND) {
159 if (
states.top() == State::IN_NODE_LITERAL ||
states.top() == State::IN_NODE_OP ||
states.top() == State::IN_NODE_BINDING ||
states.top() == State::IN_NODE_CONDITIONAL) {
168 case State::IN_NODE_LITERAL:
169 node = std::make_unique<expressions::Node>(expressions::LiteralNode{
value,
type});
171 case State::IN_NODE_BINDING:
174 case State::IN_NODE_OP:
175 node = std::make_unique<expressions::Node>(expressions::OpNode{
operation}, expressions::LiteralNode{-1});
177 case State::IN_NODE_CONDITIONAL:
178 node = std::make_unique<expressions::Node>(expressions::ConditionalNode{}, expressions::LiteralNode{-1}, expressions::LiteralNode{-1}, expressions::LiteralNode{
true});
181 states.push(State::IN_ERROR);
189 auto*
n =
path.top().ptr;
190 switch (
path.top().toWrite) {
192 n->left = std::move(node);
193 path.top().toWrite = ToWrite::RIGHT;
194 path.emplace(
n->left.get(), ToWrite::LEFT);
197 n->right = std::move(node);
198 path.top().toWrite = ToWrite::COND;
199 path.emplace(
n->right.get(), ToWrite::LEFT);
202 n->condition = std::move(node);
204 path.emplace(
n->condition.get(), ToWrite::LEFT);
207 states.push(State::IN_ERROR);
212 states.push(State::IN_LEFT);
216 if (
states.top() == State::IN_LEFT) {
220 path.top().toWrite = ToWrite::RIGHT;
221 states.push(State::IN_RIGHT);
225 if (
states.top() == State::IN_RIGHT) {
229 path.top().toWrite = ToWrite::COND;
230 states.push(State::IN_COND);
235 if (
states.top() == State::IN_NODE_LITERAL) {
241 if (
states.top() == State::IN_NODE_BINDING) {
247 if (
states.top() == State::IN_NODE_OP) {
253 debug <<
">>> Unrecognized" << std::endl;
254 states.push(State::IN_ERROR);
261 debug <<
"StartObject()" << std::endl;
263 if (
states.top() == State::IN_START) {
267 if (
states.top() == State::IN_LIST) {
268 states.push(State::IN_ROOT);
272 if (
states.top() == State::IN_LEFT ||
states.top() == State::IN_RIGHT ||
states.top() == State::IN_COND) {
276 states.push(State::IN_ERROR);
280 bool EndObject(SizeType)
283 debug <<
"EndObject()" << std::endl;
285 if (
states.top() == State::IN_NODE_LITERAL ||
states.top() == State::IN_NODE_OP ||
states.top() == State::IN_NODE_BINDING ||
states.top() == State::IN_NODE_CONDITIONAL) {
289 if (
states.top() == State::IN_LEFT ||
states.top() == State::IN_RIGHT ||
states.top() == State::IN_COND) {
295 if (
states.top() == State::IN_ROOT) {
296 result.emplace_back(std::move(rootNode));
303 if (
states.top() == State::IN_START) {
307 states.push(State::IN_ERROR);
314 debug <<
"Null()" << std::endl;
316 if (
states.top() == State::IN_LEFT ||
states.top() == State::IN_RIGHT ||
states.top() == State::IN_COND) {
319 if (
path.top().toWrite == ToWrite::LEFT) {
320 path.top().toWrite = ToWrite::RIGHT;
321 }
else if (
path.top().toWrite == ToWrite::RIGHT) {
322 path.top().toWrite = ToWrite::COND;
323 }
else if (
path.top().toWrite == ToWrite::COND) {
330 states.push(State::IN_ERROR);
336 debug <<
"Bool(" <<
b <<
")" << std::endl;
338 if (
states.top() == State::IN_NODE_LITERAL &&
currentKey.compare(
"value") == 0) {
342 states.push(State::IN_ERROR);
348 debug <<
"Int(" <<
i <<
")" << std::endl;
350 if (
states.top() == State::IN_NODE_LITERAL &&
currentKey.compare(
"value") == 0) {
371 states.push(State::IN_ERROR);
377 if (
states.top() == State::IN_ROOT ||
states.top() == State::IN_LEFT ||
states.top() == State::IN_RIGHT ||
states.top() == State::IN_COND) {
381 case Nodes::NLITERAL:
384 states.push(State::IN_NODE_LITERAL);
385 debug <<
">>> Literal node" << std::endl;
388 case Nodes::NBINDING: {
389 states.push(State::IN_NODE_BINDING);
390 debug <<
">>> Binding node" << std::endl;
394 states.push(State::IN_NODE_OP);
395 debug <<
">>> Operation node" << std::endl;
399 states.push(State::IN_NODE_CONDITIONAL);
400 debug <<
">>> Conditional node" << std::endl;
407 if (
states.top() == State::IN_NODE_BINDING ||
states.top() == State::IN_NODE_CONDITIONAL ||
states.top() == State::IN_NODE_LITERAL ||
states.top() == State::IN_NODE_OP) {
414 if (
states.top() == State::IN_NODE_LITERAL ||
states.top() == State::IN_NODE_BINDING) {
416 type = (atype::type)
i;
421 if (
states.top() == State::IN_NODE_OP &&
currentKey.compare(
"operation") == 0) {
425 states.push(State::IN_ERROR);
429 bool Uint(
unsigned i)
431 debug <<
"Uint(" <<
i <<
")" << std::endl;
433 if (
states.top() == State::IN_NODE_BINDING &&
currentKey.compare(
"hash") == 0) {
438 debug <<
">> falling back to Int" << std::endl;
444 debug <<
"Int64(" <<
i <<
")" << std::endl;
446 if (
states.top() == State::IN_NODE_LITERAL &&
currentKey.compare(
"value") == 0) {
455 states.push(State::IN_ERROR);
460 states.push(State::IN_ERROR);
466 debug <<
"Uint64(" <<
i <<
")" << std::endl;
468 debug <<
">> falling back to Int64" << std::endl;
474 debug <<
"Double(" <<
d <<
")" << std::endl;
476 if (
states.top() == State::IN_NODE_LITERAL) {
485 states.push(State::IN_ERROR);
490 states.push(State::IN_ERROR);
494 bool String(
const Ch*
str, SizeType,
bool)
496 debug <<
"String(" <<
str <<
")" << std::endl;
498 if (
states.top() == State::IN_NODE_BINDING &&
currentKey.compare(
"binding") == 0) {
502 states.push(State::IN_ERROR);
510 rapidjson::Reader reader;
511 rapidjson::IStreamWrapper isw(
s);
512 ExpressionReader ereader;
513 bool ok = reader.Parse(isw, ereader);
516 throw framework::runtime_error_f(
"Cannot parse serialized Expression, error: %s at offset: %d", rapidjson::GetParseError_En(reader.GetParseErrorCode()), reader.GetErrorOffset());
518 return std::move(ereader.result);
526 w.Int((
int)
node->self.index());
528 w.Uint64(
node->index);
535 [&
w](
bool v) {
w.Bool(
v); },
536 [&
w](
float v) {
w.Double(
v); },
537 [&
w](
double v) {
w.Double(
v); },
543 [&
w](int16_t
v) {
w.Int(
v); },
544 [&
w](
int v) {
w.Int(
v); },
548 [&
w](expressions::BindingNode
const&
node) {
556 [&
w](expressions::OpNode
const&
node) {
560 [](expressions::ConditionalNode
const&) {
565void writeExpression(rapidjson::Writer<rapidjson::OStreamWrapper>&
w, expressions::Node*
n)
567 std::stack<Entry>
path;
568 path.emplace(
n, ToWrite::FULL);
569 while (!
path.empty()) {
572 if (
top.toWrite == ToWrite::FULL) {
574 writeNodeHeader(
w,
top.ptr);
575 top.toWrite = ToWrite::LEFT;
579 if (
top.toWrite == ToWrite::LEFT) {
581 top.toWrite = ToWrite::RIGHT;
582 auto*
left =
top.ptr->left.get();
583 if (
left !=
nullptr) {
591 if (
top.toWrite == ToWrite::RIGHT) {
593 top.toWrite = ToWrite::COND;
595 if (
right !=
nullptr) {
603 if (
top.toWrite == ToWrite::COND) {
605 top.toWrite = ToWrite::POP;
606 auto* cond =
top.ptr->condition.get();
607 if (cond !=
nullptr) {
608 path.emplace(cond, ToWrite::FULL);
615 if (
top.toWrite == ToWrite::POP) {
626 rapidjson::OStreamWrapper osw(o);
627 rapidjson::Writer<rapidjson::OStreamWrapper>
w(osw);
632 writeExpression(
w, p.node.get());
640std::shared_ptr<arrow::DataType> arrowDataTypeFromId(atype::type
type,
int list_size = 1, atype::type
element = atype::NA)
652struct SchemaReader :
public rapidjson::BaseReaderHandler<rapidjson::UTF8<>, SchemaReader> {
653 using Ch = rapidjson::UTF8<>::Ch;
654 using SizeType = rapidjson::SizeType;
664 std::ostringstream
debug;
666 std::shared_ptr<arrow::Schema>
schema =
nullptr;
667 std::vector<std::shared_ptr<arrow::Field>>
fields;
678 debug <<
">>> Start" << std::endl;
679 states.push(State::IN_START);
684 debug <<
"StartArray()" << std::endl;
686 states.push(State::IN_LIST);
689 states.push(State::IN_ERROR);
693 bool EndArray(SizeType)
695 debug <<
"EndArray()" << std::endl;
696 if (
states.top() == State::IN_LIST) {
698 schema = std::make_shared<arrow::Schema>(fields);
702 states.push(State::IN_ERROR);
706 bool Key(
const Ch*
str, SizeType,
bool)
708 debug <<
"Key(" <<
str <<
")" << std::endl;
710 if (
states.top() == State::IN_START) {
716 if (
states.top() == State::IN_FIELD) {
731 states.push(State::IN_ERROR);
737 debug <<
"StartObject()" << std::endl;
738 if (
states.top() == State::IN_START) {
742 if (
states.top() == State::IN_LIST) {
743 states.push(State::IN_FIELD);
750 states.push(State::IN_ERROR);
754 bool EndObject(SizeType)
756 debug <<
"EndObject()" << std::endl;
757 if (
states.top() == State::IN_FIELD) {
760 fields.emplace_back(std::make_shared<arrow::Field>(
name, arrowDataTypeFromId(
type, list_size, element)));
764 if (
states.top() == State::IN_START) {
768 states.push(State::IN_ERROR);
772 bool Uint(
unsigned i)
774 debug <<
"Uint(" <<
i <<
")" << std::endl;
775 if (
states.top() == State::IN_FIELD) {
777 type = (atype::type)
i;
790 states.push(State::IN_ERROR);
794 bool String(
const Ch*
str, SizeType,
bool)
796 debug <<
"String(" <<
str <<
")" << std::endl;
797 if (
states.top() == State::IN_FIELD) {
804 states.push(State::IN_ERROR);
810 debug <<
"Int(" <<
i <<
")" << std::endl;
822 rapidjson::Reader reader;
823 rapidjson::IStreamWrapper isw(
s);
824 SchemaReader sreader;
826 bool ok = reader.Parse(isw, sreader);
829 throw framework::runtime_error_f(
"Cannot parse serialized Schema, error: %s at offset: %d", rapidjson::GetParseError_En(reader.GetParseErrorCode()), reader.GetErrorOffset());
831 return sreader.schema;
836void writeSchema(rapidjson::Writer<rapidjson::OStreamWrapper>&
w, arrow::Schema*
schema)
841 w.String(
f->name().c_str());
842 auto fixedList =
dynamic_cast<arrow::FixedSizeListType*
>(
f->type().get());
843 if (fixedList !=
nullptr) {
845 w.Int(fixedList->list_size());
847 w.Int(fixedList->field(0)->type()->id());
849 auto varList =
dynamic_cast<arrow::ListType*
>(
f->type().get());
850 if (varList !=
nullptr) {
854 w.Int(varList->field(0)->type()->id());
857 w.Int(
f->type()->id());
865 rapidjson::OStreamWrapper osw(o);
866 rapidjson::Writer<rapidjson::OStreamWrapper>
w(osw);
std::vector< expressions::Projector > projectors
o2::monitoring::tags::Key Key
std::shared_ptr< arrow::Schema > schema
std::unique_ptr< expressions::Node > rootNode
std::vector< std::shared_ptr< arrow::Field > > fields
std::unique_ptr< expressions::Node > node
unsigned short int uint16_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events d
configStandalone Reconstruction rec_tpc float
GLdouble GLdouble GLdouble GLdouble top
GLuint const GLchar * name
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
GLsizei const GLchar *const * path
GLubyte GLubyte GLubyte GLubyte w
std::shared_ptr< arrow::DataType > concreteArrowType(atype::type type)
Defining ITS Vertex explicitly as messageable.
RuntimeErrorRef runtime_error_f(const char *,...)
static void write(std::ostream &o, std::shared_ptr< arrow::Schema > &schema)
static std::shared_ptr< arrow::Schema > read(std::istream &s)
static std::vector< expressions::Projector > read(std::istream &s)
static void write(std::ostream &o, std::vector< expressions::Projector > &projectors)
An expression tree node corresponding to a literal value.
std::variant< T... > stored_type
From https://en.cppreference.com/w/cpp/utility/variant/visit.