Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:27:27

0001 #include <vector>
0002 #include <string>
0003 #include <iostream>
0004 #include <iomanip>
0005 #include <utility>
0006 
0007 #include "TPRegexp.h"
0008 #include "TEveManager.h"
0009 #include "TEveScene.h"
0010 #include "TEveElement.h"
0011 #include "TEveGeoNode.h"
0012 #include "TGeoNode.h"
0013 #include "TCollection.h"
0014 #include "TObjString.h"
0015 
0016 #include "split.h"
0017 #include "eve_filter.h"
0018 #include "eve_macros.h"
0019 
0020 // global variables... FIXME all this stuff should be incapsulated ina a class !
0021 TPRegexp parents;
0022 std::vector<TPRegexp> filters;
0023 std::vector<Color_t>  colors;
0024 unsigned int matching_nodes;
0025 
0026 void split_path(const std::string & path, std::string & name, std::vector<std::string> & parents) {
0027   split( path, parents, '/', false );
0028   if (parents.empty()) {
0029     name = "";
0030   } else {
0031     name = parents.back();
0032     parents.pop_back();
0033   }
0034 }
0035 
0036 static TPRegexp ns_name_index( "([[:alnum:]]+:[[:alnum:]-\\[\\]]+)(_[0-9]+)+" );
0037 
0038 // generalizes a node name of the form namespace:Name_NUM into a (regexp) filter that allows any number
0039 TPRegexp make_filter(const std::string & token) {
0040   std::string filter;
0041   filter += "(";
0042   if (ns_name_index.MatchB( token ))
0043     filter += ((TObjString*)(ns_name_index.MatchS( token )->At(1)))->GetString();
0044   else
0045     filter += token;
0046   filter += ")_[0-9]+";
0047   return TPRegexp( filter.c_str() );
0048 }
0049 
0050 // generalizes a list of node names of the form namespace:Name_NUM into a (regexp) filter that allows any of the "namespace:Name" followd by any number
0051 TPRegexp make_filter(const std::vector<std::string> & tokens) {
0052   if (tokens.empty())
0053     return TPRegexp();
0054 
0055   std::string filter;
0056   filter += "(";
0057   if (ns_name_index.MatchB( tokens[0] ))
0058     filter += ((TObjString*)(ns_name_index.MatchS( tokens[0] )->At(1)))->GetString();
0059   else
0060     filter += tokens[0];
0061   for (unsigned int i = 1; i < tokens.size(); ++i) {
0062     filter += "|";
0063     if (ns_name_index.MatchB( tokens[i] ))
0064       filter += ((TObjString*)(ns_name_index.MatchS( tokens[i] )->At(1)))->GetString();
0065     else
0066       filter += tokens[i];
0067   }
0068   filter += ")_[0-9]+";
0069   return TPRegexp( filter.c_str() );
0070 }
0071 
0072 // apply the filters to a node, specifying if the removed elements should be hidden (default), deleted (does not work) or ignored
0073 void node_filter(TEveElement * node, int simplify /* = do_hide */, bool verbose /* = false */) {
0074   static int indent = 0;
0075   ++indent;
0076 
0077   expand_node(node);
0078 
0079   for (TEveElement::List_i i = node->BeginChildren(); i != node->EndChildren(); ++i)
0080   {
0081     bool found = false;
0082     TEveGeoNode * child = (TEveGeoNode*)(*i);
0083     for (unsigned int det = 0; det < filters.size(); ++det) {
0084       if (filters[det].MatchB( child->GetName() )) {
0085         // found a selcted leaf
0086         if (verbose) {
0087           for (int _t = 0; _t < indent; ++_t) std::cout << "  ";
0088           std::cout << child->GetName() << " (found)" << std::endl;
0089         }
0090         child->SetRnrSelf( true );
0091         child->SetMainColor( colors[det] );
0092         // simplify - hide or delete its children
0093         switch (simplify) {
0094           case do_hide:
0095             child->SetRnrSelf( true );
0096             child->SetRnrChildren( false );
0097             break;
0098           case do_remove:
0099             child->Destroy();
0100             break;
0101           case do_nothing:
0102             break;
0103         }
0104 
0105         found = true;
0106         ++matching_nodes;
0107         break;  // breaks out of the loop on "det"
0108       }
0109     }
0110     if (found)
0111       continue;
0112     else if (parents.MatchB( child->GetName() )) {
0113       // found a possible parent
0114       if (verbose) {
0115         for (int _t = 0; _t < indent; ++_t) std::cout << "  ";
0116         std::cout << child->GetName() << " (look inside...)" << std::endl;
0117       }
0118       child->SetRnrSelf( false );
0119       child->SetRnrChildren( true );
0120       node_filter( child );
0121     } else {
0122       // enything else
0123       if (verbose) {
0124         for (int _t = 0; _t < indent; ++_t) std::cout << "  ";
0125         std::cout << child->GetName() << " (unused)" << std::endl;
0126       }
0127       // simplify - hide or delete this
0128       switch (simplify) {
0129         case do_hide:
0130           child->SetRnrSelf( false );
0131           child->SetRnrChildren( false );
0132           break;
0133         case do_remove:
0134           child->Destroy();
0135           break;
0136         case do_nothing:
0137           break;
0138       }
0139     }
0140   }
0141 
0142   --indent;
0143 }
0144 
0145 // initializes the filter static variables from a list of elements to display and colors to use
0146 void init_filter(const std::vector< std::pair< std::string, Color_t> > & elements) {
0147   std::vector< std::string > all_parents;
0148   std::vector< std::string > all_names;
0149 
0150   for (unsigned int i = 0; i < elements.size(); ++i) {
0151     std::vector< std::string > s_parents;
0152     std::string s_name;
0153     split_path( elements[i].first, s_name, s_parents );
0154     all_names.push_back( s_name );
0155     all_parents.insert( all_parents.end(), s_parents.begin(), s_parents.end() );
0156 
0157     colors.push_back( elements[i].second );
0158   }
0159 
0160   parents = make_filter( all_parents );
0161   for (unsigned int i = 0; i < all_names.size(); ++i)
0162     filters.push_back( make_filter( all_names[i] ) );
0163 
0164   matching_nodes = 0;
0165 }
0166 
0167 // dump the filters
0168 void dump(void) {
0169   std::cout << parents.fPattern << std::endl;
0170   for (unsigned int i = 0; i < filters.size(); ++i)
0171     std::cout << '\t' << std::setw(32) << std::left << filters[i].fPattern << '\t' << colors[i] << std::endl;
0172 }
0173 
0174 // apply the filters to a node, then notify it to update itself and its children for redrawing
0175 void apply_filter(TEveElement * node, int simplify /* = do_hide */, bool verbose /* = false */) {
0176   if (node == 0)
0177     return;
0178 
0179   if (verbose)
0180     std::cout << get_name(node) << " (look inside...)" << std::endl;
0181 
0182   node_filter( node, simplify );
0183   node->ElementChanged( true, true );
0184 
0185   std::cout << "found " << matching_nodes << " matching nodes" << std::endl;
0186 }
0187 
0188 // find a TEve root object (could be a TEveGeoRootNode or a TEveGeoShape) by its name
0189 TEveElement * get_root_object(const char* name)
0190 {
0191   for (TEveElement::List_i i = gEve->GetScenes()->BeginChildren(); i != gEve->GetScenes()->EndChildren(); ++i) {
0192     TEveScene * scene = dynamic_cast<TEveScene *> (*i);
0193     if (not scene)
0194       continue;
0195     for (TEveElement::List_i n = scene->BeginChildren(); n != scene->EndChildren(); ++n) {
0196       const char* obj_name = get_name( *n );
0197       if (obj_name == 0 or strcmp(name, obj_name))
0198         continue;
0199 
0200       return *n;
0201     }
0202   }
0203 
0204   return 0;
0205 }