Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:40

0001 // Author: David Lawrence  August 8, 2007
0002 //
0003 //
0004 
0005 #include <JANA/JEventProcessor.h>
0006 
0007 #include <map>
0008 using std::map;
0009 
0010 class JEventProcessorJANADOT:public JEventProcessor
0011 {
0012 
0013     /// The janadot plugin is used to generate a call graph with information on
0014     /// factory dependencies on one another as well as some profiling to indicate
0015     /// where the processing time is being spent. The output is a text file containing
0016     /// commands in GraphVix's "DOT" language. This can be converted into a .ps file using
0017     /// the "dot" program (usually installed with the "graphviz" package on Linux.) The
0018     /// .ps file can then be converted to PDF using ps2pdf.if
0019     /// There are a couple of options in janadot that can be controlled via configuration
0020     /// parameters. It should be noted that janadot itself turns on the RECORD_CALL_STACK
0021     /// configuration parameter so that the framework will record the information needed
0022     /// to produce the call graph in the end. Configuration parameters specific to [janadot
0023     /// are:
0024     /// 
0025     /// JANADOT:GROUP:GroupName  - This is used to tell janadot to issue commands that will
0026     /// cause dot to draw the graph using colors and/or a bounding box to identify members
0027     /// of a group. 
0028     /// This is useful for larger projects with lots of factories. The value of
0029     /// "GroupName" is used for the title when drawing a bounding box.
0030     /// The value of the configuration parameter
0031     /// should be a comma separated list of factories to include in the group. If a
0032     /// factory with a name matching "color_XXX" is found in the factory list, then the
0033     /// XXX part is used as the color for the background of the classes in the group.
0034     /// For example:
0035     /// 
0036     /// -PPLUGINS=janadot -PJANADOT:GROUP:Tracking=DTrackHit,DTrackCandidate,DTrackWireBased,color_red
0037     /// 
0038     /// This will cause dot to draw the boxes for DTrackHit,DTrackCandidate, and
0039     /// DTrackWireBased near each other, with a red background then a larger box drawn
0040     /// around it. A label that says "Tracking" will also be draw at the top of the
0041     /// bounding box.
0042     ///
0043     /// If one does not wish to have the bounding and label box drawn then a value
0044     /// of "no_box" should be added to the list of values (similar to how "color_red"
0045     /// was in the above example). Note that these special keyward can be contained
0046     /// anywhere in the list and need not be at the end.
0047     /// 
0048     /// JANADOT:SUPPRESS_UNUSED_FACTORIES  - By default this is set to true, but one can
0049     /// turn it off by setting it to "0". This only has an effect if a JANADOT:GROUP:
0050     /// config. parameter (described above) is given. If this is turned off AND a
0051     /// factory is specified in the list of factories for the group that does not
0052     /// get called during processing, then an ellipse for that factory will be drawn
0053     /// inside the bounding box for the group. These types of factories will have
0054     /// no connections to them and will be filled with white so they will look a
0055     /// little ghostly. In most instances, you will not want this behavior so it
0056     /// is supressed by default.
0057     ///
0058     /// JANADOT:FOCUS  - If this is set then the value is taken to be the factory
0059     /// on which the graph should focus. Specifically, any factories that are not
0060     /// direct decendents or ancestors of the focus factory are ommitted from the
0061     /// graph. The times and percentages drawn are the same as for the full graph
0062     /// no not all time accounting will be visible on such graphs. The specified
0063     /// focus factory is drawn with a triple octagon shape to indicate it was used
0064     /// as the focus.
0065     ///
0066     /// Because the configurations can become large for large projects, a script
0067     /// called "janadot_groups.py" is provided as part of JANA. Just give it the
0068     /// path of the top level directory structure where code you wish to document
0069     /// it is.
0070 
0071 
0072     public:
0073         JEventProcessorJANADOT();
0074 
0075         void Init() override;
0076         void BeginRun(const std::shared_ptr<const JEvent>& event) override;
0077         void Process(const std::shared_ptr<const JEvent>& event) override;
0078 //        void EndRun() override;
0079         void Finish() override;
0080 
0081         enum node_type{
0082             kDefault,
0083             kProcessor,
0084             kFactory,
0085             kCache,
0086             kSource
0087         };
0088 
0089         class CallLink{
0090             public:
0091                 string caller_name;
0092                 string caller_tag;
0093                 string callee_name;
0094                 string callee_tag;
0095                 
0096                 bool operator<(const CallLink &link) const {
0097                     if(this->caller_name!=link.caller_name)return this->caller_name < link.caller_name;
0098                     if(this->callee_name!=link.callee_name)return this->callee_name < link.callee_name;
0099                     if(this->caller_tag!=link.caller_tag)return this->caller_tag < link.caller_tag;
0100                     return this->callee_tag < link.callee_tag;
0101                 }
0102         };
0103         
0104         class CallStats{
0105             public:
0106                 CallStats(void){
0107                     from_cache_ms = 0;
0108                     from_source_ms = 0;
0109                     from_factory_ms = 0;
0110                     data_not_available_ms = 0;
0111                     Nfrom_cache = 0;
0112                     Nfrom_source = 0;
0113                     Nfrom_factory = 0;
0114                     Ndata_not_available = 0;
0115                 }
0116                 double from_cache_ms;
0117                 double from_source_ms;
0118                 double from_factory_ms;
0119                 double data_not_available_ms;
0120                 unsigned int Nfrom_cache;
0121                 unsigned int Nfrom_source;
0122                 unsigned int Nfrom_factory;
0123                 unsigned int Ndata_not_available;
0124         };
0125         
0126         class FactoryCallStats{
0127             public:
0128                 FactoryCallStats(void){
0129                     type = kDefault;
0130                     time_waited_on = 0.0;
0131                     time_waiting = 0.0;
0132                     Nfrom_factory = 0;
0133                     Nfrom_source = 0;
0134                     Nfrom_cache = 0;
0135                 }
0136                 node_type type;
0137                 double time_waited_on;  // time other factories spent waiting on this factory
0138                 double time_waiting;        // time this factory spent waiting on other factories
0139                 unsigned int Nfrom_factory;
0140                 unsigned int Nfrom_source;
0141                 unsigned int Nfrom_cache;
0142         };
0143 
0144         map<CallLink, CallStats> call_links;
0145         map<string, FactoryCallStats> factory_stats;
0146         std::mutex mutex;
0147         bool force_all_factories_active;
0148         bool suppress_unused_factories;
0149         map<string,vector<string> > groups;
0150         map<string,string > group_colors;
0151         map<string,string > node_colors;
0152         set<string> no_subgraph_groups;
0153         bool has_focus;
0154         string focus_factory;
0155         std::string m_output_filename = "jana.dot"; 
0156         bool m_weight_edges = true;
0157         
0158         void FindDecendents(string caller, set<string> &decendents);
0159         void FindAncestors(string callee, set<string> &ancestors);
0160         string MakeTimeString(double time_in_ms);
0161         string MakeNametag(const string &name, const string &tag);
0162 };