// Copyright 2019-2020 CERN and copyright holders of ALICE O2. // See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. // All rights not expressly granted are reserved. // // This software is distributed under the terms of the GNU General Public // License v3 (GPL Version 3), copied verbatim in the file "COPYING". // // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. #include "Framework/AnalysisDataModel.h" #include "AnalysisDataModel/HFSecondaryVertex.h" #include "AnalysisDataModel/PID/PIDResponse.h" #include "AnalysisDataModel/Multiplicity.h" #include "AnalysisDataModel/Centrality.h" #include "AnalysisDataModel/TrackSelectionTables.h" #include "AnalysisDataModel/Jet.h" #include "AnalysisDataModel/StrangenessTables.h" #include #include using namespace o2::framework; using namespace o2::aod; using namespace o2::soa; static int count = 0; static int width = 10; static int height = 10; void inline graphSize() { fmt::printf( R"( size="%d,%d"; )", width, height); } struct Style { const char* color; const char* background; const char* fontcolor; const char* headerfontcolor; const char* headerbgcolor; const char* methodcolor; const char* methodbgcolor; const char* indexcolor; const char* indexbgcolor; }; static Style styles[] = { {"black", "gray80", "black", "black", "gray70", "black", "gray60", "black", "gray50"}, {"/reds9/2", "/reds9/4", "white", "white", "/reds9/7", "black", "/reds9/6", "/reds9/1", "/reds9/5"}, {"/greens9/2", "/greens9/4", "white", "white", "/greens9/7", "black", "/greens9/6", "/greens9/1", "/greens9/5"}, {"/blues9/2", "/blues9/4", "white", "white", "/blues9/7", "black", "/blues9/6", "/blues9/1", "/blues9/5"}, }; Style const& getDefaultStyle() { return styles[0]; } enum StyleType : int { DEFAULT = 0, RED = 1, GREEN = 2, BLUE = 3, }; static std::vector> tableStyles = { {"HfTrackIndexProng", StyleType::BLUE}, {"HfCandProng", StyleType::BLUE}, {"pidResp", StyleType::GREEN}, {"Mults", StyleType::GREEN}, {"Cents", StyleType::GREEN}, {"Timestamps", StyleType::GREEN}, {"Jet", StyleType::BLUE}, {"Mc", StyleType::RED}, {"V0Datas", StyleType::GREEN}, {"CascData", StyleType::GREEN}, {"TrackSelection", StyleType::GREEN}, {"TracksExtended", StyleType::GREEN}, {"Transient", StyleType::GREEN}, {"Extension", StyleType::GREEN}, }; template Style getStyleFor() { auto label = MetadataTrait::metadata::tableLabel(); auto entry = std::find_if(tableStyles.begin(), tableStyles.end(), [&](auto&& x) { if (std::string(label).find(x.first) != std::string::npos) { return true; }return false; }); if (entry != tableStyles.end()) { auto value = *entry; return styles[value.second]; } return styles[StyleType::DEFAULT]; } void inline nodeEmpty() { fmt::printf( R"(node[shape=none,height=0,width=0,label=""])"); } void inline nodeNormal() { fmt::printf( R"(node[shape=plain,style=filled,fillcolor=gray95])"); } void inline graphHeader(char const* type, char const* name) { fmt::printf(R"(%s %s { edge[dir=back, arrowtail=empty] )", type, name); nodeNormal(); } void inline graphFooter() { fmt::printf("}\n"); } template void displayEntity(); template void displayOriginals(pack) { graphHeader("subgraph", fmt::format("cluster_{}", count++).c_str()); fmt::printf("label = %s;\n", MetadataTrait>>::metadata::tableLabel()); (..., displayEntity()); graphFooter(); } template void printColumn(char const* fg, char const* bg) { if constexpr (!is_index_column_v) { fmt::printf("%s", fg, bg, C::columnLabel()); } } template void printIndexColumn(char const* fg, char const* bg) { if constexpr (is_index_column_v) { fmt::printf("%s", fg, bg, C::columnLabel()); } } template void displayColumns(pack, const char* fg, const char* bg) { (printColumn(fg, bg), ...); fmt::printf("%s", "\n"); } template void displayIndexColumns(pack, char const* fg, char const* bg) { (printIndexColumn(fg, bg), ...); fmt::printf("%s", "\n"); } template void printIndex() { if constexpr (!is_type_with_originals_v) { auto a = MetadataTrait::metadata::tableLabel(); auto b = MetadataTrait::metadata::tableLabel(); fmt::printf("%s -> %s []\n", a, b); } else { using main_original = pack_element_t<1, typename C::binding_t::originals>; auto a = MetadataTrait::metadata::tableLabel(); auto b = MetadataTrait::metadata::tableLabel(); fmt::printf("%s -> %s []\n", a, b); } } template void dumpIndex(pack) { (printIndex(), ...); fmt::printf("%s", "\n"); } template void displayTable() { auto style = getStyleFor(); auto label = MetadataTrait::metadata::tableLabel(); fmt::printf(R"(%s[color="%s" cellpadding="0" fillcolor="%s" fontcolor="%s" label = < )", label, style.color, style.background, style.fontcolor, style.headerbgcolor, style.headerfontcolor, label); if (pack_size(typename T::iterator::persistent_columns_t{}) - pack_size(typename T::iterator::external_index_columns_t{}) > 0) { displayColumns(typename T::iterator::persistent_columns_t{}, style.color, style.background); fmt::printf("%s", "HR"); } if (pack_size(typename T::iterator::dynamic_columns_t{})) { displayColumns(typename T::iterator::dynamic_columns_t{}, style.methodcolor, style.methodbgcolor); fmt::printf("%s", "HR"); } displayIndexColumns(typename T::iterator::external_index_columns_t{}, style.indexcolor, style.indexbgcolor); fmt::printf("%s", "
%s
\n>]\n"); dumpIndex(typename T::iterator::external_index_columns_t{}); } template void displayEntity() { if constexpr (is_soa_join_t::value) { displayOriginals(typename T::originals{}); } else { displayTable(); } } template void displayEntities() { graphHeader("subgraph", fmt::format("cluster_{}", count++).c_str()); (..., displayEntity()); graphFooter(); } int main(int, char**) { graphHeader("digraph", "hierarchy"); graphSize(); fmt::printf(R"(compound = true; )"); displayEntity(); /// rank trick to avoid BCs moving nodeEmpty(); fmt::printf(R"({rank = same; BCs -> root[style=invis];};)"); nodeNormal(); displayEntity(); displayEntity(); displayEntity(); displayEntity(); displayEntity(); displayEntities(); displayEntity(); displayEntity(); displayEntity(); displayEntity(); displayEntity(); displayEntity(); displayEntity(); displayEntities(); displayEntity(); displayEntity(); displayEntity(); displayEntity(); displayEntity(); displayEntity(); displayEntities(); displayEntities(); displayEntities(); displayEntities(); displayEntities(); graphFooter(); return 0; }