Enumerator Classes available in ROOT using LinkDef


ROOT Version: Not Provided
Platform: Not Provided
Compiler: Not Provided


Dear all,
I have a question concerning the usage of the LinkDef and the support for the enumerator Class object.
What are the correct instructions to put in the LinkDef ?

I have a file (Enumerators.hpp) like this

#ifndef ENUMERATORSVC_HPP
#define ENUMERATORSVC_HPP

#include "MessageSvc.hpp"

#include "TString.h"

/**
 * \enum Prj
 * \brief Project types flags
 */

enum class Prj  {
    None  = 0, // ONLY FOR PYTHON SUBMITTER
    RKst  = 1,
    RK    = 2,
    RPhi  = 3,
    Error = 99
};


/**
 * \enum Analysis
 * \brief Analysis types flags
 */

enum class Analysis  {
    None  = 0, // ONLY FOR PYTHON SUBMITTER
    MM    = 1,
    EE    = 2,
    Error = 99
};

Then i do in the LinkDef

#ifdef __ROOTCLING__

#pragma link off all class;
//#pragma link off all enum;
//#pragma link off all function;
//#pragma link off all global;
#pragma link off all namespace;
//#pragma link off all struct;
//#pragma link off all typedef;
//#pragma link off all union;

#pragma link C++ nestedclasses;
#pragma link C++ nestedtypedef;

//#pragma link C++ enum Prj;
//#pragma link C++ enum Analysis;
//#pragma link C++ defined_in "Enumerators.hpp";
#pragma link C++ defined_in "HelperSvc.hpp";

Where HelperSvc.hpp does the #include "Enumerators.hpp"

and uses Analysis::None.

I produce the dictionary with

set(PROJECT services)

file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
file(GLOB HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/inc/*.hpp)
list(REMOVE_ITEM HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/inc/LinkDef.h)
message(STATUS "SRCS = ${SOURCES}")
message(STATUS "INCS = ${HEADERS}")

GENERATE_DICTIONARY(${PROJECT}Dict ${HEADERS} LINKDEF ${CMAKE_CURRENT_SOURCE_DIR}/inc/LinkDef.h)

add_library(${PROJECT}-objlib OBJECT ${SOURCES} ${PROJECT}Dict.cxx)

having

function(GENERATE_DICTIONARY dictionary)
    if(${ROOT_VERSION} LESS 6.0)
	ROOT_GENERATE_DICTIONARY(${dictionary} ${ARGN})
    else()
        ROOT_GENERATE_DICTIONARY(${dictionary} MODULE ${dictionary} ${ARGN})
    endif()
endfunction()

What i would like to do is that, once the library is produced , be able in Root and pyRoot to define something like

Analysis myana = Analysis::None ;

Is there a way to have the enumerator classes usable and create a dictionary for them?
If yes, what is the suggested way to do that?
Thanks in advance

Renato

Hi Renato,

did you try to select the enumerator with the pragma #pragma link C++ enum Analysis in your linkdef?
Autoloading/autoparsing will allow you then to use the Analysis myana = Analysis::None at the prompt and in macros.

Cheers,
D

Hi Danilo,

Do i also need after the link C++ enum Analysis
the
#pragma link C++ defined_in "Enumerators.hpp"; ? ( file in which Analysis is done ) even if i do
#pragma link C++ defined_in "SettingSvc.hpp" which does #include Enumerators.hpp ?

Hi @Danilo
I managed to get it working.

What is not working now is the usage in PyROOT.

While in interactive root i can do

Analysis myAna = Analysis::EE; 

IN PyROOT i have to do

r.EE ;

But since i have several enumerators, and some of them have the same value assigned ( 0,1,2,3) … the python interface does a mess.
I think this is a pending issue :
https://sft.its.cern.ch/jira/browse/ROOT-7240

Is there a work around that for the pyROOT?

I can try to do a

namespace Name{ 
   enum class Name2{ 
  } 
} 

but then i don’t know which directives i should give to the LinkDef.h
Any help is more than welcome.

Renato

I managed to get this working with some hackish solution :

I did

namespace pyColor{ 
   enum class Color{  
            RED,
            BLUE, 
           GREEN  
   } 
}
namespace pyColor2{ 
   enum class Color2{ 
         RED, 
         BLUE, 
        GREEN
};
};
using namespace pyCOlor; //prevent all my C++ code including this file to never have to call pyName
using namespace pyColor2;

In LinkDef i do .

   #pragma link c++ enum pyColor::Color;
#pragma link c++ namespace pyColor2; 
   #pragma link c++ enum pyColor2::Colo2r;

In pyROOT i can now do
r.pyColor.RED and r.pyColor2.RED
If i was not placing the namespace for pyXX only r.RED was working was misleading and loading always the first found ( from Color.

Here i posted a stupid example.
Thanks for the help and if you have further suggestions let me know.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.