You are here

Using the feedback mechanism

In this section we describe how to enable and use the realtime feedback mechanism provided by PROOF.

  1. Introduction: the PROOF feedback mechanism
  2. TProof interface
    1. Enabling basic feedback on per query base (ROOT version >= 5.34)
    2. Modifying and displaying the feedback list
    3. Setting the frequency
    4. Getting the feedback objects: the TProof::Feedback(TList *) signal
  3. TDrawFeedback example

1. Introduction: the PROOF feedback mechanism

The feedback mechanism provided by PROOF consists in giving the user the possibility to get back, at a chosen frequency, the current status of a set of output objects. These objects must be previously registered by the user in the feedback list. When the internal feedback timer expires, the objects in the feedback list are sent by the workers to the master, merged and sent to the user, and made available via the ROOT signal technology.

Needless to say that the all process may be quite heavy and is intended for light monitoring objects. 

2. TProof interface

2.1. Enabling basic feedback on per query base (ROOT version >= 5.34)

Starting with ROOT version 5.34 is it possible to enable basic feedback using the option field of the selector. This change is client-side only, so it is enough to upgrade the client to have it working with cluster running older versions.

The keywords enabling automatic setup of feedback are 'fb=comma-separated-list-of-names ' or 'feedback=comma-separated-list-of-names '; the comma-separated list of names is ended by a space, to allow identification of the next option. When these key-pair values are detected feedback is enable for the specified object names, and a TDrawFeedback object created to display them. For example:

root [] proof->Process("tutorials/proof/ProofSimple.C+", 10000000, "fb=h10")
enables feedback for the histogram 'h10' of the tutorial selector ProofSimple.

The special name 'stats' is reserved for the set of internal statistics histograms {processed events, processed packets, being processed packets}-per-worker (see Creating and Saving the Performance Tree):

root [] proof->Process("tutorials/proof/ProofSimple.C+", 10000000, "fb=stats")
In this case the feedback handling is done with TStatsFeedback instead of TDrawFeedback. The histograms are plot one in one canvas in three vertical pads.

2.2. Modifying and displaying the feedback list

To enable the feedback mechanism it is sufficient to register at least one object. The way to register the objects is straightforward: TProof has a feedback list member and provides the following methods to modify it:

2.3. Setting the frequency

Once enabled the feedback mechanism by adding at least one object to the list, PROOF start sending back the feedback objects at a default frequency of 0.5 Hz, i.e. every 2000 milliseconds. The default feedback period can be modified using the parameter PROOF_FeedbackPeriod which takes the period in milliseconds (a Long_t integer). For example, to set the period to 5 seconds, just set

// Set the feedback period to 5 seconds
proof->SetParameter("PROOF_FeedbackPeriod", (Long_t) 5000);

before starting the query. 

2.4. Getting the feedback objects: the TProof::Feedback(TList *) signal

Once reaching the client, the list of feedback objects is made available via a ROOT signal (see TQObject technology) with signature TProof::Feedback(TList *). To use these objects the client must connect to the signal and provide a method or a function to process the list (i.e. displaying the monitoring histograms). An example of class using this can be found in TDrawFeedback under $ROOTSYS/proof/proofplayer ; this utility class is described to some detail in the next section.

3. The TDrawFeedback example

In the section we dissect the utility class TDrawFeedback . Its purpose is to show how to display in separate canvases a set of 1D histograms registered to the list.

The definition of the class is the following:

class TDrawFeedback : public TObject, public TQObject {
private:
   Bool_t         fAll;    //draw all or selected objects
   THashList     *fNames;  //selected objects

protected:
   Option_t      *fOption; //draw option
   TProof        *fProof;  //handle to PROOF session

public:
   TDrawFeedback(TProof *proof = 0, TSeqCollection *names = 0);
   ~TDrawFeedback();

   void Feedback(TList *objs);
   void SetOption(Option_t *option) { fOption = option; }

   ClassDef(TDrawFeedback,0)  // Present PROOF query feedback
};
The class derives from TObject and TQObject: this is needed to be enable to usage of the ROOT signal mechanism. The class has four members. The first two (fAll, fNames) allow to choose a subset of feedback histograms to draw. The third one is the drawing option. Finally the class save the pointer to the PROOF session: this is needed to connect and disconnect from the feedback signal.

A part from constructor and destructor, the class has one main method, Feedback(TList *), used to process the signal, and one setter to set a specific drawing option.

If now we look at the constructor implementation we see that the main part is the connection to the signal:

//______________________________________________________________________________
TDrawFeedback::TDrawFeedback(TProof *proof, TSeqCollection *names)
  : fAll(kFALSE)
{
   // Constructor

   ...

   Bool_t ok = proof->Connect("Feedback(TList *objs)", "TDrawFeedback",
                  this, "Feedback(TList *objs)");
   ...
}
here we request that the method Feedback(TList *) of this object of type TDrawFeedback is called when the PROOF session of interest (e.g. 'proof') emits the Feedback(TList *). In the destructor we just break this link:
//______________________________________________________________________________
TDrawFeedback::~TDrawFeedback()
{
   // Destructor

   delete fNames;
   fProof->Disconnect("Feedback(TList*)", this, "Feedback(TList*");
}

If we now look at the main method TDrawFeedback(TList *), we see that we just go through the list of objects received from TProof, check whether it is a TH1 and if we are asked to draw it, create a canvas and draw a copy of the histogram:

//______________________________________________________________________________
void TDrawFeedback::Feedback(TList *objs)
{
   // Display feedback

   ...

   TIter next(objs);
   TObject *o;
   while( (o = next()) )
   {
      TString name = o->GetName();
      if (fAll || fNames->FindObject(name.Data())) {

         name += "_canvas";

         TVirtualPad *p = (TVirtualPad*) canvases->FindObject(name.Data());

         if ( p == 0 ) {
            gROOT->MakeDefCanvas();
            gPad->SetName(name);
            PDB(kFeedback,2) Info("Feedback","Created canvas %s", name.Data());
         } else {
            p->cd();
            PDB(kFeedback,2) Info("Feedback","Used canvas %s", name.Data());
         }

         if (TH1 *h = dynamic_cast(o)) {
            h->DrawCopy(fOption);
         }

         gPad->Update();
      }
   }
   ...
}
This is of course the place where to play wit graphics or to do other manipulations if required by the specific task.