Using inlib/exlib within CERN-ROOT

exlib/2root contains code to convert inlib::histo::[h1d,h2d,p1d,p2d] to exlib_[TH1D,TH2D,TProfile,TProfile2D] inheriting respectively TH1D, TH2D, TProfile, TProfile2D. An exlib_[TH1D,TH2D,TProfile,TProfile2D] could then be used within the CERN-ROOT environment, for example to be plotted with a TCanvas. exilb/2root contains also the material to build (from exlib/example/cpp) the exlib_2root plugin that permits to do some inlib/exlib work from a CERN-ROOT-CINT prompt.

Running a compiled program

The exlib example 2root.cpp finds in an aida XML file an inlib h1d and a h2d. After it converts them to an exlib_TH1D and a exlib_TH2D instances and then plots these within a TCanvas. The build and run sequence is :

    cd <path to inlib>
    cd examples/cpp
    c++ -I../.. waxml.cpp
    ./a.out
 You should have now a inlib_waxml.aida file. And then :
    <source setup CERN-ROOT> # in order to have root-config in your PATH.
    cd <path to exlib>
    cd examples/cpp
    ./build 2root.cpp
    ./exlib_example_2root ../../../inlib/examples/cpp/inlib_waxml.aida

You should see :

exlib_exa_2root.png

The code of 2root.cpp looks like :

// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file exlib.license for terms.

#include <inlib/args>
#include <exlib/raxml>

// the CERN-ROOT intrinsic pain :
#include <TCanvas.h>
#include <TApplication.h>

#include <exlib/2root/h2root> //bridge inlib/histo --> CERN-ROOT

ClassImp(exlib_TH1D)
ClassImp(exlib_TH2D)

#include <iostream>

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

  ////////////////////////////////////////////////////////
  /// begin is similar to raxml.cpp //////////////////////
  ////////////////////////////////////////////////////////
 {inlib::args args(argc,argv);

  std::string file;
  if(!args.file(file)) {
    std::cout << " give an AIDA xml file." << std::endl;
    return EXIT_FAILURE;
  }

  bool verbose = false;

  exlib::xml::default_factory fac;
  exlib::raxml ml(fac,std::cout,verbose);

  std::vector<exlib::raxml_out>& objs = ml.objects();
  objs.clear();

  ml.load_file(file,false);

 {std::vector<exlib::raxml_out>::const_iterator it;
  for(it=objs.begin();it!=objs.end();++it) {
    std::cout << " obj = " << (*it).object() << std::endl;
    std::cout << " class = " << (*it).cls() << std::endl;
    std::cout << " path = " << (*it).path() << std::endl;
    std::cout << " name = " << (*it).name() << std::endl;
  }}

  ////////////////////////////////////////////////////////
  /// activate the CERN-ROOT intrinsic pain (CRIP) ///////
  ////////////////////////////////////////////////////////
  TApplication app("2root",&argc,argv);

  TCanvas* canvas = new TCanvas("canvas","",10,10,800,600);
  canvas->Divide(2,1);  

  // look for an h1d and an h2d. If found we convert
  // then to TH1D, TH2D and ask CERN-ROOT to plot them.

  bool found_h1d = false;
  bool found_h2d = false;

 {std::vector<exlib::raxml_out>::const_iterator it;
  for(it=objs.begin();it!=objs.end();++it) {
    const exlib::raxml_out& raxml_out = *it;    
    if(raxml_out.cls()==inlib::histo::h1d::s_class()) {
      //m_sd.m_out << "aobj_cbk::action : plot..." << std::endl;

      if(!found_h1d) {
        found_h1d = true;

        inlib::histo::h1d* h = (inlib::histo::h1d*)raxml_out.object();
        exlib_TH1D* th = new exlib_TH1D(*h);
        th->SetName("h1D");

        canvas->cd(1);
        th->Draw();

      }

    } else if(raxml_out.cls()==inlib::histo::h2d::s_class()) {
      //m_sd.m_out << "aobj_cbk::action : plot..." << std::endl;

      if(!found_h2d) {
        found_h2d = true;

        inlib::histo::h2d* h = (inlib::histo::h2d*)raxml_out.object();
        exlib_TH2D* th = new exlib_TH2D(*h);
        th->SetName("h2D");

        canvas->cd(2);
        th->Draw();
      }
    }
  }}

  canvas->Update();

  app.Run();}
  /////////////////////////////////////////////////
  /////////////////////////////////////////////////
  /////////////////////////////////////////////////

  std::cout << "main : exit..." << std::endl;
  
  return 0;
}

Working from CINT

From exlib/example/cpp, you can build the exlib_2root plugin and then execute the histos.C CINT file from the CERN-ROOT prompt. The build and run sequence is :

    <source setup CERN-ROOT> # in order to have rootcint in your PATH.
    cd <path to exlib>
    cd examples/cpp
    ./build histos.C  # it should build the exlib_2root.so plugin.
    root
    root[] gSystem->Load("exlib_2root");
    root[] .x histos.C

You should see :

exlib_exa_2root.png

The code of histos.C looks like :

// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file exlib.license for terms.

int histos() {

  ////////////////////////////////////////////////////////
  /// inlib : ////////////////////////////////////////////
  ////////////////////////////////////////////////////////
  inlib::random::gauss rg(1,2);
  inlib::random::bw rbw(0,1);

  int entries = 1000000;

  inlib::histo::h1d* h1d = new inlib::histo::h1d("Gauss",100,-5,5);
 {for(int count=0;count<entries;count++) {
    h1d->fill(rg.shoot(),1.4);
  }}
  h1d->hprint(std::cout);

  inlib::histo::h2d* h2d = new inlib::histo::h2d("Gauss_BW",100,-5,5,100,-2,2);
 {for(int count=0;count<entries;count++) {
    h2d->fill(rg.shoot(),rbw.shoot(),0.8);
  }}
  h2d->hprint(std::cout);

  ////////////////////////////////////////////////////////
  /// CERN-ROOT : ////////////////////////////////////////
  ////////////////////////////////////////////////////////

  TCanvas* canvas = new TCanvas("canvas","",10,10,800,600);
  canvas->Divide(2,1);  

  exlib_TH1D* th1 = new exlib_TH1D(*h1d);
  th1->SetName("h1d");
  canvas->cd(1);
  th1->Draw();

  exlib_TH2D* th2 = new exlib_TH2D(*h2d);
  th2->SetName("h2d");
  canvas->cd(2);
  th2->Draw();

  canvas->Update();

}

Notes

We have NOT declared all inlib/exlib to CINT. Some work has to be done to pass all files and we are definitely NOT motivated in wasting our time to "#ifdef __CINT__" our things in order to be "CINT compliant". (Not so clear if the "C" of CINT is for Cranky or Crashy). Anyway, for interested people, exlib/2root gives the basement to bridge inlib/exlib to the fancy and definitely not object oriented CERN-ROOT. (When are people going to open eyes ?)