CMsgRootConsumer.cc

From GlueXWiki
Revision as of 10:16, 26 June 2009 by Wolin (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
//  Example shows how to receive serialized root object via cMsg 
//    and deserialize into real root object
//
//  Elliott Wolin, JLab, 26-jan-2009


// include files
#include <iostream>
#include <iomanip>
#include <string>
#include <stdlib.h>


// for cMsg
#include "cMsg.hxx"


// root include files
#include "TCanvas.h"
#include "TH1.h"
#include "TMessage.h"


using namespace std;
using namespace cmsg;


//  misc variables */
static string url           = "cMsg://localhost/cMsg";
static TCanvas *canvas      = NULL;
static int hcount           = 0;
static int debug            = 0;
static int done             = 0;



// prototypes */
void decode_command_line(int argc, char **argv);



//----------------------------------------------------------------
//----------------------------------------------------------------


// needed to expose protected TMessage constructor
class MyTMessage : public TMessage {
public:
   MyTMessage(void *buf, Int_t len) : TMessage(buf, len) { }
};


//----------------------------------------------------------------
//----------------------------------------------------------------


// callback class receives cMsg message and deserializes root object
class rootCallback : public cMsgCallback {

public:
  void callback(cMsgMessage *msg, void *userObject) {
    hcount++;

    // create input root message object from cMsg byte array
    MyTMessage *myTM = new MyTMessage(msg->getByteArray(),msg->getByteArrayLength());


    // get object class name
    TNamed *namedObj = (TNamed*)myTM->ReadObject(myTM->GetClass());
    string className = namedObj->ClassName();
    cout << "Received object ClassName is:  " << className << endl;


    // how to get the object directly if you already know what type it is
//     TH1F *hist = (TH1F*)myTM->ReadObject(myTM->GetClass());


    // how to cast TNamed object to subclass
//     if(className=="TH1F") {
//       TH1F *fhist = (TH1F*)namedObj;
//     }


    // cast to histogram base class TH1
    TH1 *hist = dynamic_cast<TH1*>(namedObj);
    if(hist!=NULL) {

      // print hist info
      hist->Print();

      // save hist as gif file
      canvas->Clear();
      hist->Draw();
      canvas->SaveAs("hist.gif");
      cout << endl;
      cout << endl;

    } else {
      cerr << "?not a TH1 object" << endl;
    }


    delete(msg);
  }
};


//----------------------------------------------------------------
//----------------------------------------------------------------


int main (int argc, char **argv) {


  // decode command line
  decode_command_line(argc,argv);


  try {

    // connect to cMsg server, create subscriptions and start receiving
    cMsg c(url,"hconsumer","histogram consumer");
    c.connect();
    c.subscribe("root","hist",new rootCallback(),NULL);
    c.start();


    // create root canvas
    canvas = new TCanvas("canvas");


    // wait for messages
    while(!done) {
      done=hcount>=10;
      sleep(1);
    }


    // done
    c.stop();
    c.disconnect();


  } catch(cMsgException &e) {
    cout << "?cMsg exception:  " << e.what() << endl;
    exit(EXIT_FAILURE);

  } catch(...) {
    cout << "?unknown exception" << endl;
    exit(EXIT_FAILURE);
  }


  exit(EXIT_SUCCESS);
}


//----------------------------------------------------------------


void decode_command_line(int argc, char**argv) {
  
  const char *help = 
    "\nusage:\n\n  analysis [-url url] [-debug]\n";
  int i;
    
    
  // loop over arguments */
  i=1;
  while (i<argc) {
    if (strncasecmp(argv[i],"-h",2)==0) {
      printf("%s\n",help);
      exit(EXIT_SUCCESS);

    } else if (strncasecmp(argv[i],"-url",4)==0) {
      url=string(argv[i+1]);
      i=i+2;

    } else if (strncasecmp(argv[i],"-debug",6)==0) {
      debug=1;
      i=i+1;

    } else if (strncasecmp(argv[i],"-",1)==0) {
      printf("\n  ?unknown command line arg: %s\n\n",argv[i]);
      exit(EXIT_FAILURE);

    } else {
      break;
    }
  }
  

  return;
}


//----------------------------------------------------------------