Reading old zebra files in ROOT

I use a fortran program to read a zebra file with the raw data and create an hbook file with an ntuple of refined data. I’d like to have a root file instead of an hbook file.
I know that the program “h2root” create the root file from the hbook file, but i’d like to jump this passage. In fact I’m not so practical with fortran and every time I need to change the hbbok-maker fortran program I have a lot of difficulties.
I read that cernlib fortran routines can be used in C/C++ program including the “cfortran.h” header. So I want to write a ROOT macro if possible, or at least a C/C++ compiled program, that read the zebra file and create directly the ROOT Tree.
I know nothing about zebra banks structure and logic, but I understand that a sort of opening/initialization of zebra file is in the code at the end of this message. As the “cfortran docs” states, I have to change the subroutine calls to C style, i.e. to remove “Call” before routine names. But is it enough? I guess for example how all the variables, that in fortran are declared in common blocks, such as:

  Integer NwmSto,ImainSto
  Integer ImainDiv,ImainCon,Ixmn,MainFen
  Integer Lmain,MainSto
  Common /MAINZEB/NwmSto,ImainSto,ImainDiv,ImainCon,Ixmn(2),
 &                MainFen(14),Lmain,MainSto(MainSiz)

  Integer IuHead,NuHead
  Common /NZHEAD/NuHead,IuHead(MxHead)

  Integer Iquest
  Common /QUEST/Iquest(100)

  Integer Lq,Iq,ImainInt
  Real Q

  Dimension Lq(MainSiz-10),Iq(MainSiz-20),Q(MainSiz-20)
  Equivalence ( Lq(1),Lmain )
  Equivalence ( Iq(1),Q(1),Lq(9) )
  Equivalence (ImainInt,Ixmn(1))

  Integer Izeb_Space, Ipaw_Space
  Parameter ( Izeb_Space = 1000000 )
  Parameter ( Ipaw_Space = 10000000 )

Real Blah2
Common /PAWC/ Blah2(Ipaw_Space)

can be mapped in a C/C++ file.

thanks for any reply (I beg you… don’t say “It’s too difficult, continue using fortran…”)

Follow the fortran code where I think the zebra file is read, with my comments of what I think I have to do to convert it in C++

  • Init zebra  //MY COMMENT: I have to remove "Call", but variables will 
  •                // be correctly mapped?!?!
  • Call MZEBRA(-1)
    Call MZSTOR(ImainSto,'/MAINZEB/',' ',MainFen,Lq,MainSto,
    & MainSto,Lq(MnWork+100),Lq(Izeb_Space-30))
    Call MZLOGL(ImainSto,-2)
  • Book ntuples
  • Call HLIMIT(-Ipaw_Space)
    Call NTUBOOK   //MY COMMENT: I change this to "book" a ROOT
  • Proceed opening and reading the file.
  • Call CFOPEN(LunPtr,Medium,RecSize,Mode,0,'inputrun.fz',Istat)
    If (Istat.NE.0) Then
       Print *, 'Cannot open file inputrun.fz, exiting.'
    Iquest(1) = LunPtr
    Call FZFILE(LunPtr,RecSize,'DLI')
    Call FZLOGL(LunPtr,0)

Iquest(1) = 0
Count = 0
Nerror = 0
n_processa = 100000
Do While ((Iquest(1).NE.4).or.(Iquest(1).NE.5))
C > .or.(Count.LT.n_processa))
C Do While (Count.LT.n_processa)
Call FZIN(LunPtr,ImainDiv,Lmain,2,’ ',Nuh,IuHead)
If ( Iquest(1).EQ.4 .or. Iquest(1).EQ.5 ) Then
Print *, 'Terminating at EOF: ‘, Count, ’ events read in’
GoTo 999
ElseIf (Iquest(1).Ne.0) Then
Nerror = Nerror + 1
Print *, ‘Found an abnormal condition’, Iquest(1)
Print *, Count, ’ events read in so far’
Print *, Nerror,’ errors found so far’
Print *, 'try next event … '
GoTo 990
Endif //MY COMMENT: “print” becomes “cout”

  • Now fill the ntuple
  •    Call NTUFILL(Lmain)  //MY COMMENT: This become "TreeFill", BUT
                                      // in this fortran routine i have the raw data in
                                      // the "Iq(index)" variable: will this variable
                                      // correctly mapped to raw data after 
                                      // conversion?
       Call MZWIPE(21)
       Call MZWIPE(ImainSto+21)

Count = Count + 1

990 Continue
999 Continue

My suggestion is to call teh Zebra routines via extern “C” statements
and then use teh Zebra store like we do in eg cladd THbookFile. See:


I read the sources. If I understand correctly (I’m not a big expert…), I have to declare the Zebra function as 'extern “C” ', that means that compiler will search these routine elsewhere. I have to declare the file/lib where these routines are (in ROOT environment it can be done with gSystem->Load , isn’t it?), but where can I find this “Zebra” lib? And, is it important that it is a fortran or C lib? (Maybe not because a lib is compiled… but to be sure… as I told before i’m not an expert…)
Moreover I have to reproduce with C variables the “COMMON blocks” of fortran, and to declare them 'extern ’ too. This means that the correct assignment will be made by the linker, isn’t it? So I have to know the exact names of the variables and the routines as defined in the compiled lib, isn’t it?
What does “_stdcall” mean?

Thank you very much for your replies