#include <TCLAnalyzer.h> class CTclAnalyzer { public: typedef std::pair<std::string, CEventProcessor*> PipelineElement; typedef std::list<PipelineElement> EventProcessingPipeline; typedef EventProcessingPipeline::iterator EventProcessorIterator; typedef std::vector<CTCLVariable*> VariableArray; public: CTclAnalyzer(CTCLInterpreter& rInterp, UInt_t nP, UInt_t nBunch); CTCLInterpreter* getInterpreter(); virtual void OnStateChange(UInt_t nType, CBufferDecoder& rDecoder); virtual void OnPhysics(CBufferDecoder& rDecoder); virtual void OnOther(UInt_t nType, CBufferDecoder& rDecoder); virtual void OnScaler(CBufferDecoder& rDecoder); virtual void OnEndFile(); virtual void OnBegin(CBufferDecoder* rDecoder); virtual void OnEnd(CBufferDecoder* rDecoder); virtual void OnPause(CBufferDecoder* rDecoder); virtual void OnResume(CBufferDecoder* rDecoder); virtual void OnInitialize(); void AddEventProcessor(CEventProcessor& rProcessor, const char* pName = 0); // Append to pipe. EventProcessorIterator FindEventProcessor(std::string name); EventProcessorIterator FindEventProcessor(CEventProcessor& processor); void InsertEventProcessor(CEventProcessor& processor, EventProcessorIterator here, const char* name = 0); CEventProcessor* RemoveEventProcessor(std::string name); CEventProcessor* RemoveEventProcessor(EventProcessorIterator here); UInt_t size(); EventProcessorIterator begin(); EventProcessorIterator end(); void IncrementCounter(Counter eSelect, UInt_t incr = 1); void ClearCounter(Counter eSelect); void SetEventSize(UInt_t nSize); void IncrementEventSize(UInt_t nIncr=2) ; UInt_t GetEventSize() ; }; enum Counter { RunsAnalyzed = 0, EventsAnalyzed = 1, EventsAnalyzedThisRun = 2, EventsAccepted = 3, EventsAcceptedThisRun = 4, EventsRejected = 5, EventsRejectedThisRun = 6 };
The CTclAnalyzer
class is a SpecTcl analyzer
that extends the base class by:
Maintaining statistical counters that can be retrieved from Tcl
Supporting a list of event processors, rather than a single one. The list is called the Event processing pipeline.
CTclAnalyzer( CTCLInterpreter& rInterp, UInt_t nP, UInt_t nBunch);
The constructor sets up several variables that
are defined in
rInterp
. This interpreter
should be the SpecTcl command interpreter so that these
variables will be visible to commands executed by SpecTcl.
nP
is the initial number of parameters
for each CEvent
object
constructed by the base class. Since these objects are
recycled from event to event, the value of this
has no effect on performance.
nBunch
is the size of the bunch
of events that will be accumulated before invoking the
event sink pipeline.
CTCLInterpreter* getInterpreter();
Returns the interpreter in which this analyzer maintains its statistics variables. Normally, this is the SpecTcl command processing interpreter.
Note that the return value is a pointer to a
CTCLInterpreter
object. The
reference documentation on the Tcl++ library describes
this and related classes. The
CTCLInterpreter manpage
provides details about this specific claass.
virtual void OnStateChange( UInt_t nType, CBufferDecoder& rDecoder);
Overrides the base class's method that processes
state change operations. After calling the base
class's OnStateChange
method,
this method fans out
the state change processing for the following
item types:
Invokes OnBegin
Invokes
OnEnd
.
Invokes OnPause
Invokes OnResume
virtual
void OnPhysics( CBufferDecoder& rDecoder);
After invoking the base class OnPhysics
method, increments statistics variables that
indicate the number of items analyzed and the
sequence number of the last item analyzed. For
NSCLDAQ-8.x and earlier, the decoder gets the
sequence number from the buffer header. For
NSCLDAQ-10.0 and later, this sequence number is
number of triggers from the most recently seen
PHYSICS_EVENT_COUNT item.
Note that no effort is made to actually analyze the
data in this method. The Tcl analyzer establishes
an event processor for the base class that contains
an ordered list of event processors. When the
base class OnPhysics
method
virtual void OnOther( UInt_t nType, CBufferDecoder& rDecoder);
Iterates over the event processors in the
event processing pipeline invoking their
OnOther
methods.
If an event processor returns a false value
(kfFALSE), iteration is aborted
after that stage of the pipeline.
virtual void OnScaler( CBufferDecoder& rDecoder);
Called when a scaler item is received. This
invokes OnOther
.
virtual void OnEndFile();
Called when an end file is encountered on a data source. For file data sources this happens when there's no more data in the file. For pipe data sources this happens when the program feeding the pipeline exits.
The event processors in the pipeline are iterated
calling OnEventSourcEOF
.
If one of the event processors returns
false, event processor pipeline processing is terminated.
Regardless, the RunState
Tcl variable
is set to Halted indicating that
SpecTcl is no longer processing event data.
virtual void OnEnd( CBufferDecoder* rDecoder);
Called when an end run item is encounterd. Sets the
RunState
variable to
Halted indicating analysis is no longer
active and then calls the OnEnd
method of each event processor in the event processing
pipeline.
If an event processor returns false, no more event processors will be called.
virtual void OnPause( CBufferDecoder* rDecoder);
Called when a pause run item is received. The
RunState
variable is set to
Paused and the
OnPause
method is
called for each element of the event processing pipeline.
If an event processing pipeline element returns false, no futher event processors are called.
virtual void OnResume( CBufferDecoder* rDecoder);
Called when a resume item is received. The
RunState
variable is set to
Active indicating data is being
analyzed. The
OnResume
method is invoked
for each element of the event processing pipeline.
If an element of the pipeline returns false,
no more event processors are invoked.
Note that when analyzing a file data source, the
RunState
variable will flip quickly
between Paused and
Active for a run that is paused and
resumed. For a pipe data source connected to live data,
however, this variable will remain in the
Paused state until the user
resumes the run.
virtual void OnInitialize();
Called after SpecTcl's initialization is complete.
The OnInitialize
method
of each element of the event processign pipeline is
called. If any element returns false, no more elements
are called.
This is intended for use when initialization requires knowing that all of SpeTcl's services are available.
void AddEventProcessor( CEventProcessor& rProcessor, const char* pName = 0);
Adds rProcessor
as to the
end of the event processing pipeline. The object
must be live as long as it is in the event processing
pipeline.
If provided, pName
is used to name
the event processor. If this is not provided, a unique
name of the form Anonymous::number
is assigned where number
is a sequentially assigned integer number.
EventProcessorIterator FindEventProcessor( std::string name);
Returns an iterator to the element of the event processing
pipeline that has the name name
.
If no such element exists, the value returned is the
same as that returned from
end
.
Event processor iterators can be treated as if they
were pointers to an
std::pair<std::string, CEventProcessor*>
.
The first element of the pair is the name of an event processor.
The second, a pointer to the event processor itself.
Incrementing an iterator points it to the next pipeline
element. Incrementing the iterator when it points to the
last element of the pipeline returns
the same value as that returned from
end
.
EventProcessorIterator FindEventProcessor( CEventProcessor& processor);
Locates an event processor given a reference to it. The use case for this is to delete an anonymous event processor from the eventprocessing pipeline.
void InsertEventProcessor( CEventProcessor& processor, EventProcessorIterator here, const char* name = 0);
Provides the ability to insert an event processor anywhere
in the event processing pipeline. The event processor
is inserted just prior to the item pointed to by
here
.
CEventProcessor* RemoveEventProcessor( std::string name);
Removes the named event processor
name
. The return value
is a pointer to the event processor removed from
the list. No steps are taken to destroy that processor so
if it has been dynamically created with new
it must be destroyed with delete
If there is no event processor in the event processing pipeline, the return value is a null pointer. It is up to the caller to decide if this represents an error.
CEventProcessor* RemoveEventProcessor( EventProcessorIterator here);
Removes the event processor pointed to by the iterator
here
. The return value is
a pointer to the event processor that was removed.
It is up to the caller to destroy that event processor,
if desired.
Note this method invalidates the iterator here
.
Destruction and assignment become the only operatiosn with
defined meaning.
UInt_t size();
Returns the number of elements in the event procesing pipeline.
EventProcessorIterator begin();
Returns an iterator that points to the first element of
the event processing pipeline. See
find
above for a description of
EventProcessorIterator
objects.
EventProcessorIterator end();
Returns an end of iteration iterator. This is the value of
the iterator that results from incrementing an iterator
that points to the last PipelineElement
Here is sample code that might list the names of all event processors:
CAnalyzer* pA; ... // Assume pA got set to point at the analyzer: for (auto p = pA->begin(), p != pA->end(); p++) { std::cout << p->first << std::endl; }
The code above is intended just to show a typical use of
begin
and
end
to iterate over the entire
event processing pipeline.
void IncrementCounter( Counter eSelect, UInt_t incr = 1);
Increments one of the Tcl statistics counters
maintained by this object. eSelect
selects which counter to increment. It is described
in DATA TYPES below.
Unless incr
is supplied, the
counter is incremented by 1.
void ClearCounter( Counter eSelect);
Clears the counter selected by
eSelect
. This values this
enumerated parameter can have are described
in DATA TYPES below.
void SetEventSize( UInt_t nSize);
At least one event processor must invoke this.
The event size in bytes is set to be nSize
.
This is used to determine where the next event in a run of
events is.
Note that if a supervent has been declared this will be used to point to the next event in the superevent.
void IncrementEventSize( UInt_t nIncr = 2);
Adds nIncr
to the size of the
event.
UInt_t GetEventSize();
Returns the current understanding of the size of this event.
The header TCLAnalyzer.h defines both nested and global level data types. This section will first describe the globally defined data types and then the nested type.
One globally defined data type Counter
is defined. This is an enumerated type whose values select the
Tcl counter operated on by e.g. IncrementCounter
.
These statistics are maintained in the Tcl array
Statistics
.
The type can have any of the following values.
Increments the RunsAnalyzed element
of Statistics
. This counter
is incremented by the analyzer whenever it
executes its
OnBegin
method.
Selects the element
EventsAnalyzed from the
Statistics
array. This counter
is incremented every time
OnEvent
is executed.
Selects EventsAnalyzedThisRun.
Same as EventsAnalyzed but
additionally, this counter is also cleared by
OnBegin
Selects EventsSelected. This counts the number of events that made it through the entire event processing pipeline without any element returning false.
Selects EventsAcceptedThisRun.
Same as EventsAccepted but is also
cleared by OnBegin
Selects EventsRejected. Incremented
for each event for which the event processing pipeline was aborted
because an event processor returned false. Note that
exceptions thrown by an event processor caught by the
CTclAnalyzer
object are
treated as pipeline aborts for the purpose
of this counter.
Selects EventsRejectedThisRun. This
is the same as EventsRejected but
is also cleared by
OnBegin
.
Several data types are defined within the CTclAnalyzer
class. These are mostly related to the event processing pipeline.
These types are defined via typedef. To specify
these types in your code you'll need to use the scope resolution
operator. For example, PipelineElement
must be referred to as a CTclAnalyzer::PipelineElement
.
PipelineElement
This is an element of the list that contains an event processing pipeline element. It associates an event processor with a name and places it in an ordered container of event processors.
The actual type is:
std::pair<std::string, CEventProcessor*>
EventProcessingPipeline
The actual event processing pipeline. This is actually a
std::list<PipelineElement>
EventProcessorIterator
Represents an iterator into the event processing
pipeline container. This is actually a
EventProcessingPipeline::iterator
VariableArray
Defines a vector that contains TCL variables:
std::vector<CTCLVariable*>