Last version:
FLUKA 2023.3.4, April 10th 2024
(last respin 2023.3.4)
flair-2.3-0d 13-Sep-2023

News:

-- Fluka Release
( 10.04.2024 )

FLUKA 2023.3.4 has been released.


font_small font_med font_big print_ascii

 [ 1 ]  [ 2 ]  [ 3 ]  [ 4 ]  [ 5 ]  [ 6 ]  [ back ] 


We give here a simple example of an external C++ library which allows to obtain the output of the a simple example root.inp input file in the form of a ROOT tree, that can be saved on file and then opened and analyzed. The main steps are the following:

  1. Define a class Results, containing the information we want to extract from FLUKA and to save on the tree.
    The class header shown below contains the same information saved in the original example. It must be pointed out that this first step is not mandatory. A ROOT tree can also be filled with simple variables.
    #ifndef ROOT_Results
    #define ROOT_Results
    
    #include "TObject.h"
    
    class Results : public TObject {
    
     private:
    
      Int_t ij;
      Double_t econtr, xa, ya, za, txx, tyy, tzz;
    
     public:
    
      Results() : ij(0), econtr(0), xa(0), ya(0),
        za(0), txx(0), tyy(0), tzz(0) {}
      Results(Int_t ijj, Double_t econtrr, Double_t xaa,
    	  Double_t yaa, Double_t zaa,
    	  Double_t txxx, Double_t tyyy, Double_t tzzz);
      virtual ~Results();
    
      ClassDef(Results,1);
    
    };
    
    #endif
    
  2. Write a C++ library of functions which acts as the interface between FLUKA and ROOT.

    The library functions will allow to open the ROOT file, to create the ROOT tree and to fill it with objects of class "Results". The library used in this example is shown below.

    All the functions are defined inside extern "C" blocks, to avoid undefined symbols when linking. The first function myusrini opens the ROOT file and creates the ROOT tree to be filled, the second function treefill fills the tree with objects of class "Results", after creating them, and the last function fileclose closes the ROOT file. It must be noted that the include directives concerning the ROOT classes have been added and that the way the values are passed to the function treefill follows the requirements mentioned in 0.2.
    #ifndef __CFORTRAN_LOADED
    #include "cfortran.h"
    #endif
    
    #include 
    
    #include 
    #include "Results.h"
    #include 
    #include 
    
    #ifndef WIN32
    #define myusrini myusrini_
    #else
    #define myusrini MYUSRINI
    #endif
    
    static TFile *RootFile = 0;
    static TTree *RootTree = 0;
    static Results *TheResults = 0;
    
    extern "C" {
      void myusrini (Double_t &pluto)
      {
        printf("Executing MYUSRINI\n");
        RootFile = new TFile("Out.root","recreate");
        RootTree = new TTree("ResultsTree","Protons");
        RootTree->Branch("Results", "Results", &TheResults, 64000, 1);
    
        printf("%f\n", pluto);
    
      }
    }
    
    #ifndef WIN32
    #define treefill treefill_
    #else
    #define treefill TREEFILL
    #endif
    
    extern "C" {
      void treefill(Int_t &ij, Double_t &econtr, Double_t 
    , Double_t &ya, Double_t &za,
    		Double_t &txx, Double_t &tyy, Double_t &tzz)
      {
        if (TheResults) {
          delete TheResults;
          TheResults = 0;
        }
    
        TheResults = new Results(ij, econtr, xa, ya, za,
    			     txx, tyy, tzz);
        RootTree->Fill();
      }
    }
    
    #ifndef WIN32
    #define fileclose fileclose_
    #else
    #define fileclose FILECLOSE
    #endif
    
    extern "C" {
      void fileclose()
      {
        if (TheResults) {
          delete TheResults;
          TheResults = 0;
        }
        RootTree->Write();
        RootFile->Close();
      }
    }
    
    
    
  3. Place the needed function calls inside the FORTRAN user routines.

    Now, the fortran user routines: usrini.f, usrout.f and mgdraw.f can be edited and modified as shown below

    As can be seen, in this case the values to be stored in the ROOT tree are passed as a calling arguments of the function treefill(....).

    usrini

    ...
          LUSRIN = .TRUE.
    * *** Write from here on *** *
          PIPPO = 2.5D0
          CALL myusrini(PIPPO);
    ...
    

    usrout

    
    ...
          CALL FILECLOSE
    ...
    

    mgdraw

    ...
    *
    *======================================================================*
    *                                                                      *
    *     Boundary-(X)crossing DRAWing:                                    *
    *                                                                      *
    *     Icode = 1x: call from Kaskad                                     *
    *             19: boundary crossing                                    *
    *     Icode = 2x: call from Emfsco                                     *
    *             29: boundary crossing                                    *
    *     Icode = 3x: call from Kasneu                                     *
    *             39: boundary crossing                                    *
    *     Icode = 4x: call from Kashea                                     *
    *             49: boundary crossing                                    *
    *     Icode = 5x: call from Kasoph                                     *
    *             59: boundary crossing                                    *
    *                                                                      *
    *======================================================================*
    *                                                                      *
          ENTRY BXDRAW ( ICODE, MREG, NEWREG, XSCO, YSCO, ZSCO )
          IF(MREG.EQ.3.AND.NEWREG.EQ.2) THEN
             IF( JTRACK.EQ.1) THEN
                IF(ETRACK.GT.AM(JTRACK)) THEN
                   XTUP(1) = JTRACK
                   XTUP(2) = ETRACK-AM(JTRACK)
                   XTUP(3) = XSCO
                   XTUP(4) = YSCO
                   XTUP(5) = ZSCO
                   XTUP(6) = CXTRCK
                   XTUP(7) = CYTRCK
                   XTUP(8) = CZTRCK
                   CALL treefill(JTRACK,
         +                       (ETRACK-AM(JTRACK)),XSCO,YSCO,ZSCO,
         +                       CXTRCK,CYTRCK,CZTRCK)
                ENDIF
             ENDIF
          ENDIF
          RETURN
    ...
    
  4. Compile the fortran routines with the usual fff script.
    • $FLUPRO/flutil/fff usrini.f
    • $FLUPRO/flutil/fff usrout.f
    • $FLUPRO/flutil/fff mgdraw.f
  5. Compile the C++ part of the code using a Makefile. Actually the Makefile contains also the compilation of the fluka routines and the linking.

    The result of the compilation will be a file FluLib.o with the external library symbols, and a shared library libResults.so containing the information on the class Results, it's attributes and (if present) it's methods. This shared library can be dynamically linked inside the root interactive environment.
  6. Link everything together in the FLUKA executable using the modified lfluka script.

    In order to link the custom shared object libResults.so> and the ROOT libraries, it is sufficient to add the last line to the final command (provided the ROOT packages is correctly installed).

    Finally, the executable can be produced as usual:

    $FLUPRO/flutil/lfluka -m fluka usrini.o usrout.o histin.o mgdraw.o FluLib.o libResults.so -o rootfluka

    WARNING: Please be sure you have the root library directory defined in the dynamic libraries path. To do so please add the path in the LD_LIBRARY_PATH variable, and the CURRENT directory:

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root-path/lib:`pwd`

    The `pwd` is used to add the current directory which will be needed later for FLUKA to find the libResults.so library.

    As obvious, the libraries FluLib.o and libResults.so must also be linked. All the above steps are included inside the Makefile. Type:
    • make clean
    • make

    to get all modules compiled and the rootfluka executable linked
  7. Run the program using the usual rfluka script. Now, the executable is ready to run. The usual command:

    FLUTIL/rfluka -e rootfluka -N0 -M1 inp-file

    starts the fluka run, which proceeds in the standard way. It is important to remember to set the environmental variable in order to include the path to the directory in which the program is running.
  8. (Finally) Open the root file browse the tree and make some plots of the physical variables saved. The ROOT tree can be analyzed inside the ROOT interactive environment, after loading the shared object libResults.so. The content can be scanned through the ROOT tree browser (as in Figure 1 or using an apposite CINT macro. Start root and give the command new TBrowser(). Select in the files the root001_Out.root file and inspect in "ROOT Files" branch the contents of the ntuple we just created with FLUKA.

    Figure 2 shows the proton energy distribution from the FLUKA simulation.

    TBrowser
    Figure 1: ROOT tree browser showing the variables retrieved from FLUKA run


    Econtr
    Figure 2: Example of a distribution of an output variable

Example Files:



Riccardo Brunetti (INFN, Italy); 9 May 2003
Vasilis Vlachoudis (CERN, Geneve); 6 March 2008


Last updated: 10th of October, 2008

© FLUKA Team 2000–2024

Informativa cookies