STAR coding and naming standards


STAR coding standards

  1. C++programming Guidelines
  2. C++ coding style guidelines
  3. File extensions
  4. Miscellaneous

STAR StRoot/ makers naming standards

  1. The directory structure under StRoot tree
  2. Trees and implicit/hidden rules
  3. Current patterned exceptions

STAR coding standards

Fortran and C coding style manual


C++ Programming Guidelines

The programming guidelines refer to how programming language features are used. They have to do with things like adhesion to object oriented programming (data-hiding, encapsulation, etc ...), performance and portability.
  • Every class should have at least one constructor and a destructor
    even if it does nothing or is defined to do nothing. If a class does not have a constructor there is no guarantee of how objects of that class will be initialized, whilst data members should be explicitly initialized therein. When the constructor dynamically allocates memory, a destructor must be added to return the memory to the free pool when an object gets cleaned up.
  • Each class should have an assignment operator:
    ClassName& operator=(const ClassName&)

    and a copy constructor:

    ClassName(const ClassName&)
    when they allocate subsidiary data structures on the heap or consume any other kind of shared resources.
    The assignment operator is called when one instance of a class is assigned to another.
    The copy constructor defines the behavior of the class when it is passed by value as an argument, returned by value from a function, or used to initialize one instance with the value of another class instance. Defining this constructor, all the class objects are copied properly. When it doesn't make sense to copy or assign instances of a given class, the copy constructor or the = operator should be made private.
    Exception : if the class contains only non-pointer data member the default copy constructor and assignment operator might be used. In this case a comment line should state that they were omitted by purpose.
  • Data members should be made private/protected and accessed by inline functions in order to best implement information-hiding. Inline expansion avoids the overhead of a function call and can result in savings of CPU time. It is recommended to use access functions only when needed and not by default.
  • The use of global variables or functions should be avoided where possible, in order to respect encapsulation. The use of C++ namespace is encouraged wherever else necessary. For example,
    int count;

    should NOT be used but instead

    namespace MyNameSpace {
        int count;

    We recommend to for MyNameSpace to be of the explicit form TLATypes, TLAGlobals where TLA stands for your sub-system 3 letters acronym. This will avoid further clashes and a clear separation of namespace.
    If you intend to export namespace i.e. if you need to encapsulate your entire class into a namespace, use the STAR specific $NMSPC tag as follows

    namespace Test   //$NMSPC
        Class AClass : public TNamed
        Class BClass : public TNamed
    This will cause cons to generate a dictionary with the namespace (and ROOT to be happy). Note that when you only intend to hide global variables and constants, you do not need to use this syntax. Also note that the tag $NMSPC triggers the namespace inclusion (multiple namespaces can be used but you cannot combine sections with namespace and sections without).
  • The use of friend classes should be avoided where possible. To guarantee the encapsulation of a base class is always preferable to use protected data over friends or public data and then use inheritance.
  • The use of type casting should be avoided. Especially from const* or const, type casting may be dangerous for data-hiding. In addition pointers should not be cast to int for portability reasons.
  • Comparison from pointers to int should never be used. The return of a pointer allocation is either true or false and there is no need to compare to any integer, the value 0 included. Do not use statements such as if (p==0){ ...} but instead, if (!p){ ...} .
  • Hard-coded numbers within the code must be avoided for portability and maintainability reasons. The use of constants (const) is a valid solution. For values which are likely to change with time, a database approach should be considered. Refer to the database Web page area for more information.
  • Instead of the raw C types, the StType types should be used (for the offline code only). This allows to port applications more easily to different platforms and helps to encapsulate dependencies on external class libraries.
  • Member functions should be declared const if they do not alter the state of any data member.
    Member functions declared as const may not modify member data and are the only functions which may be invoked on a const object. (Such an object is clearly unusable without const methods). A const declaration is an excellent insurance that objects will not be modified (mutated) when they should not be. A great advantage that is provided by C++ is the ability to overload functions with respect to their const-ness. (Two member functions may have the same name where one is const and the other is not).
  • If the state of objects passed by reference or pointer to a function is not altered they should be declared const in the argument list of the function.
  • For printing messages in the STAR framework use the StMessage message manager package documented here. For all messages from a given portion of code, use a unique string, like:
    { LOG_XXX << &quotStZdcVertexMaker::Init(): in ZdcVertexMaker did not find ZdcCalPars." << endm; }

    where XXX is either

    • DEBUG
    • INFO
    • WARN
    • ERROR
    • FATAL
    • QA

    Then, you can filter in/out the wanted / unwanted messages using the logger filter mechanism. The Logger documentation is available here and its use is encouraged.

  • To exit your code on an error condition in the STAR framework, return one of the STAR return codes (an enum) from your Maker:
    enum EReturnCodes{
      kStOK=0,  // OK
      kStOk=0,  // OK
      kStWarn,  // Warning, something wrong but work can be continued
      kStEOF,  // End Of File
      kStErr,  // Error, drop this and go to the next event
      kStFatal      // Fatal error, processing impossible

    Outside Makers in your application code AND for testing conditions that should never happen and indicate disaster if they do, we recommend the use of assert() (it aborts the program if the assertion is false). Don't use exit(). For info on assert() see the man page ('man assert').
    Generally speaking though, it is BAD to just abort the program and should be avoided. Better to message an error and propagate up a fatal error flag. Unless your Maker is a fundamental and base maker (DAQ detecting a corruption, db finding an unlikely condition which should really never happen, IO maker not able to stream, ...) the use of assert() is prohibited as a single detector sub-system error shall not lead to an entire chain abort. The use of clear messages with level FATAL is emphasized.

C++ coding style guidelines

The coding-style guidelines are the ones which refer to the editing styles of the source code. They have to do with things like the code maintainability and readability (see motivations).
  • The public, protected and private keywords must be used explicitly in the class declaration in order to make code more readable. It is recommended to list the public data member and methods first since they define the global interface and are most important for the user/reader.
  • Self-explanatory English names for constants, variables and functions should be used for code readability. Use first-letter capitalization to delineate words; avoid the use of underscore "_" characters (ex. theTotalEnergy, setEnergyTable(), getTrackPosition(), ...). See Class and method naming good advice
  • The code must be properly indented ex. >= 2 characters indentation when inside a control structure) for readability reasons. Try to avoid spanning of lines beyond reasonable (ideally, the reader should see it fit within a screen width without having to scroll or follow the wrapped lines).

  • Member functions should start with a small letter (e.g. StTrack::whatever() )
  • Begin each class data member with a lowercase m. This makes it easy to differentiate between the use of a data member and local (or global) variable within a program (e.g. StDouble mDipAngle).
  • Each class name should begin with St and the appropriate TLA to indicate its origin and prevent name clashes i.e. StTptClusterMerger(). The St will identify a STAR class as opposed to CLHEP or RogueWave etc. and the TLA will reduce the possibility of name clashes for common packages ... for example StGeometry may be a class defined in a number of packages. StTptGeometry, StTrsGeometry, StSptGeometry is much more clear. Classes unrelated to specific packages (e.g. 3-Vectors and Units) will retain only the St prefix.
  • Each header file should contain only one or related class declarations for maintainability and for easier retrieval of class definitions.

  • Each class implementation source code should go into a single source file. for maintainability and for easier retrieval of class implementations.

  • Each header file must be protected from multiple inclusions in order to avoid multiple declarations and circular dependences in the code. e.g.:

        #ifndef NAME_HH
        #define NAME_HH

    It is understood that shall you copy codes from a template, the value of 'NAME' will be meaningful and different from the original.

  • Each file should contain a short header about the author, updates (CVS) and date.
    All files should begin with

        // $Id$
        // $Log$

    and a half line comment with the name of the original author, update notes and dates.
    The $Id$ expands to filename and last updater in CVS, and $Log$ includes the CVS notes logged when the file was committed. The CVS code example StRoot/St_TLA_Maker/ can serve as a template to any new code.

File Extensions

  • C++ header files containing ROOT related code must have the extension .h, the referring source files must have the extension .cxx. This rule is imposed on us by ROOT.

  • Plain C++ header files, i.e. those without ROOT related code have the extension .hh, the source files the extension .cc. Only header files which contains definitions usable in C and C++ may have the extension .h. This is a convention commonly used in HEP (e.g. CLHEP, Geant4).


  • Inline comments should be avoided unless necessary. Often they can be replaced by self-explaining names. For example:


    instead of

            hit->slc();         // set local coordinates

    Use tactical comments to describe the next logical block.

  • Avoid C like memory allocation (malloc/free) and surely, DO NOT mix memory allocation method between C and C++: they are often not interchangeable i.e. free does not work on memory allocated with new. Preferably use operators new and delete. They are part of the language (malloc/free are library routines) and therefore easily portable across platforms.
Class and method naming good advice
These guidelines originated with the members of the STAR online group and the TpcRespSim project. Many of them were taken from the guidelines of the Geant4 project. Direct comments to the STARSOFI list.

STAR StRoot makers naming standards

This document attempts to explain

  • the code directory structure and layout in STAR

  • the rules and assumptions triggered in the make system (cons) solely on the basis of the name choice

  • the existing exceptions to the rules

Naming convention in green are user discouraged (proliferation prevention) and such request should be accompanied with a strong reasoning. Items in magenta are obsolete forms (and code) which will disappear and rendered obsolete in a near future. Anything appearing in red should be forgotten immediately as they are forbidden (and were introduced due to unfortunate momentary laps of reason, power surge or extreme special transitional needs).

Why a naming convention ??
Naming convention keeps consistency between code and packages written by many users. Not only it enables users to have a feel for what-does-what but also, it allows managers to define basic default set of compilation rules depending sometimes naming convention. Naming conventions in general are fundamental to all large projects and although N users will surely have N best-solution, the rules should be enforced as much as possible.

The directory structure under StRoot tree

The StRoot/ tree Is of the following form



ONLY base class should be freely named. Example: StarClassLibrary, StarRoot, Star2Root



A directory tree which will contain a base class many makers will use and derive from.
In this category, XXX can be anything. For example, StChain, StEvent, StEventUtilities



XXX not being a detector sub-system but a set of character with underscores:

the code is FORtran derived. XXX is a sub-system in a general sens (not necessarily a detector-sub-system)



A tree for a Maker, that is, code compiled in this tree will be assembled as one self-sufficient package. A maker is a particular class deriving from StMaker. Its purpose is to run from within a chain (StChain) of makers and perform a specific task.

In this category, sub-name convention are as follow
* StXXXDbMaker a maker containing the database calls for the sub-system XXX (+)
* StXXXSimulationMaker or StXXXSimulatorMaker a simulation maker for the subsystem XXX
* StXXXCalibMaker or StXXXCalibrationMaker a calibration maker for the sub-system XXX
* StXXXMixerMaker a data/simulation mixer code for he sub-system XX
* StXXXDisplayMaker a self-explained named Graphical tool (+)
* StXXTagMaker a maker collecting tags for the sub-system or analysis XX

while XXX is in principle a detector sub-system identification (3 to 4 letters uniquely designating the sub-system), it may also be anything but a detector sub-system (StAssociationMaker, StMiniMcMaker, StDbMaker) or of the form XX=analysis or physics study.



Any directory with named with the word Raw will make our make system include the necessary path for the Run-Time-System DAQ reader files automatically. This convention is additive to any other description and convention herein.

Example: StEmcRawMaker is a "maker" 9as described above) and a code base using the DAQ reader and so would be the expectation for Stl3RawReaderMaker or StFgtRawMaker.



Code compiled in a Util or Utilities tree should be code which do not perform any action (nor a maker) but constitute by itself a set of utility classes and functions. Other classes may depend on a Utility library.
* XXXUtil : XXX IS a sub-system detector.
* XXXUtilities : XXX IS NOT a detector sub-system (this is reserved)



This tree will contain a set of sub-directories chosen by the user, each sub-directory maybe a self-contained project with no relation with anything else. Each sub-directory will therefore lead to the creation of a separate library. The naming convention for the library creation is as follow :
* If the subdirectory is named like StYYY, the library will inherit the same name. Beware of potential name clash in this case
* If the subdirectory has an arbitrary name YYY, the final library name will be have the name StXXXPoolYYY .
The Pool category has some special compilation internal rules: if it does not compile, it may be removed from compilation entirely. As such, codes appearing in Pool directory trees cannot be part of a production maker dependency. A typical usage for this structure is to provide a Pool (or collection) of lose codes not used in production (utility tools for sub-systems, analysis codes or utilities).
can be easer a Physics Work Group acronym or a detector sub-system acronym.



This tree will behave like the Pool trees in terms of library naming creation (separate libraries will be created, one per compilable sub-directory).
XXX can be anything relevant for a sub-system. Client directories MUST compile (unlike the pools) and may be part of a dependency of a data processing chain. Its general goal is to provide a different tree structure for a set of code providing a "service" widely used across makers. For example, the Run Time System (RTS) have a Client tree containing DAQ related reading codes.


Trees and implicit/hidden rules




A basic documentation in plain text (not mandatory). If exists, the software guide will display the information contained in this file.




A directory containing more elaborate documentation, either in html or in LaTeX. Note that if a file named index.html exists, the software guide will link to it




A subdirectory containing stand-alone Makefiles for the package and/or standalone configuration files




A directory having a collection of code using the Maker or utility package of interest (case incensitive)




A directory containing root macros example making use of the maker




This is an obsolete directory name (from staf time) but still considered by the make system. It may also appears in the pams/ tree structure.




This directory may contain test programs (executables should in principle not appear in our standard but be assembled)




A directory possibly containing cross-linked information for Web purposes. However, note that the documentation is, since 2002, auto-generated via the doxygen documentation system (see the sofi page for more information).




A directory containing images such as bitmap, pixmaps or other images used by your program but NOT assembled by any part of the build process. XPM files necessary for Qt for example should not be placed in this directory as explicit rules exists in 'cons' to handle those (but cons will ignore the xpm placed in images/).





A directory containing a set of common include files



Any other name

Will be searched for code one level down only.
All compiled code will be assembled in one library named after to StXXX...
Each sub-directory will be compiled separately that is, each must contain code using explicit include path as the only default search paths for includes will be the one described by CPPPATH and its own directory. 1
Include statement can ALWAYS refer to the relative path after the StRoot/portion as the StRoot/ path is a default in CPPPATH.




As noted above (i.e. the content of those directories will be skipped by the make system)



Any other name

The presence of every sub-directory will create a different dynamic library. Note that this is NOT the case with the other name format (all compiled code would go in a unique library name)
The convention is as follow:
* If the name starts with 'St', for example 'StZZZ', a library will be created containing every compiled code available in StZZZ directory 2
* if the name does NOT start with 'St', for example 'WWW', a library will be created containing all compile code available in WWW directory


Current patterned exceptions.



Directories within this pattern will be compiled using the extra include path pointed by the environment variable QTDIR. The moc program will run on any include containing the Q_OBJECT directive, -DR__QT define is added to CXXFLAGS.



Those are special. Compilation will consider MySQL includes and the created dynamic library will be linked against MySQL



Any directory following this pattern will use the MySQL include as an extra include path for the CPPPATH directive



Are two exceptions of kind (b) [see footnote 1] and uses its own include/ directory as a general extraneous include path.



For this maker, a pre-defined list of sub-directories is being added to the (CPPPATH)



This form will include in the CPPPATH every sub-directories found one level below. Only macros/, examples/ and doc/ are excluded withing this form noted in (a). For the Pool directory, the extraneous rule mentioned here is additive to the one of Pool directories.

Direct comments to the STARSOFI list.

1However, if there is a need for StRoot/StXXX sub-directories compilation to include every available sub-paths (other than the exceptions noted above) (a) as a list of default path in a compiler option or if you want a default include/ directory (b) to be always added in a default include path compiler option statement, you may request this feature to be enabled. To do that, send an Email to STARSOFI .

2In this form, the sub-directory MUST be self-sufficient i.e. all code and include (apart from the default paths) must be in the sub-directory StZZZ