BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
Code Documentation Rules

The reference documentation of BmnRoot is generated by Doxygen from the comments in the source code and from the README.md files of the directories. It is rebuilt for every commit to the dev branch, so the comments written according to these rules appear there after the merge request is merged. The documentation is written in English.

Main rules

  1. Document new classes, their public functions and data members in the header files.
  2. Use the Doxygen comments: /** ... */ or /// before a declaration, ///< after a member on the same line.
  3. Start each description with a short sentence ending with a period: it is shown in the class and member lists.
  4. Mark the transient data members with ///<!, not with //! (see Data members).
  5. Describe each directory with code in its README.md; add a new top-level directory or a new subdirectory of detectors or database to a topic (see Directories).
  6. Check the Doxygen warnings of the changed files (see Checking the documentation).

When you change an old class, bring the comments of the changed part to these rules.

What to document

  • Classes and structures: what the class represents or does, its place in the data processing (e.g. a task of the reconstruction chain or a data container of the DST), how it is used (the input and output branches of a task, the main functions).
  • Public functions: what the function does, the meaning and units of the parameters and of the return value, the ownership of the returned objects, the behavior on errors.
  • Data members: the meaning and units.
  • Enumerations and their values, global functions and constants.
  • ROOT macros: purpose and parameters (see ROOT macros).
  • Directories: the README.md file (see Directories).

Getters and setters with self-explaining names (GetNHits(), SetMinCharge()) may stay without a description. The documentation tells what the code does and how to use it; the implementation details are explained by the ordinary comments in the code.

Where to put the comments

Classes and functions are documented in the header (.h) files before their declarations. Doxygen joins the descriptions of a function from the header and from the source (.cxx) file, so a description repeated in the .cxx file is shown twice: the comments in the .cxx files are ordinary comments (//), which explain the implementation. Functions declared only in a .cxx or .C file (e.g. the functions of a macro) are documented at their definition.

Comment style

Comment Use
/** ... */ description of several lines before a class, function, enumeration, ...
/// description of one or more lines before a declaration
///< description after a data member or an enumeration value on the same line
//, /* ... */ ordinary comment, not included in the documentation
  • The commands are written with @ (@param, @return); the form with a backslash (\param) is the same, but use one form in a file.
  • The first sentence of a description, up to the first period followed by a space, is the brief description shown in the class and member lists and at the top of the page; the rest is the detailed description. An explicit @brief is not needed. An abbreviation in the first sentence ends it at its period: rephrase the sentence or write a backslash after the period (e.g.\ this).
  • Markdown can be used in the comments: code, lists, emphasis. Code examples are put between @code and @endcode.
  • Do not comment out code with /// or /** */: the code becomes the description of the next declaration. Separator lines like ////////// are ignored.
  • The comments are formatted by clang-format together with the code (120 columns, aligned trailing comments).

Files

A class header is described by its class, so a file comment is optional. If a file has one, write @file without the file name: Doxygen warns about a wrong name, and the name becomes wrong when the file is renamed. @author and @date are optional.

/**
* @file
* Functions for the conversion of the TOF-700 raw data.
* @author Name Surname
*/

The description of a class is put before the class, not into the file comment: the class page shows only the comment of the class.

Functions

/**
* Fits the track with the Kalman filter.
* @param track track to fit, its parameters are updated
* @param pdg PDG code of the particle hypothesis
* @return chi2 of the fit, or a negative value if the fit failed
*/
Double_t FitTrack(BmnTrack* track, Int_t pdg = 211);
int Int_t
double Double_t
  • The names after @param are the names of the arguments in the declaration. If some parameters are documented, document all of them: Doxygen warns about the missing ones. Output arguments are marked as @param[out], input and output ones as @param[in,out].
  • @return is written only for functions returning a value.
  • Give the units of physical quantities (e.g. momentum in GeV/c) and the owner of a returned object (who deletes it).
  • For overridden virtual functions, describe what is specific to the class, e.g. the branches read and registered by Init() of a task. A function without a description shows the description of the overridden BmnRoot function.

Data members

A data member is described after its declaration with ///<. ROOT reads this comment too: it is the title of the member (shown e.g. in the TBrowser), and the marker at its beginning makes the member transient or sets the size of a dynamic array. The markers are written right after ///<:

Data member Declaration
stored in the file Int_t fNHits; ///< number of hits
transient (not stored) TClonesArray* fHits; ///<! input hits
dynamic array of the size fNHits Double_t* fX; ///<[fNHits] coordinates of the hits, cm
pointer, which is never null BmnVertex* fVertex; ///<-> primary vertex

Use only ///<! for the transient members (checked with ROOT 6.36 and Doxygen 1.17):

  • //! text makes the member transient, but Doxygen attaches the text to the next member;
  • //!< text is attached correctly by Doxygen, but ROOT does not see the marker and stores the member;
  • ///<! is understood by both; in the documentation, the description of a transient member starts with !.

Replacing //! with ///<! in old code does not change the I/O of the class: ROOT reads the same title. Plain trailing comments (// text) are not included in the documentation; replace them with ///< text. Enumeration values are described in the same way with ///<.

ROOT macros

The macros (.C files) are included in the documentation as file pages with their functions. Document the main function of a macro with a Doxygen comment, not with ordinary comments at the top of the file, which are not shown:

/**
* Simulation of BM@N events: transport of the generated particles through the setup and conversion of the MC
* points to digits.
* @param genFile input file of the event generator
* @param simFile output file with the MC tracks, points and digits
* @param nEvents number of events to simulate
*/
void run_sim_bmn(TString genFile = "", TString simFile = "bmnsim.root", Int_t nEvents = 10)

How to run the macros of a directory is described in its README.md.

Directories

  • Each directory with code has a README.md in plain GitLab Markdown, which is shown on GitLab and as the page of the directory in this documentation: a # Title, the description of the directory, and the tables of its classes, files and subdirectories. The title is also the brief description of the directory in the file list, in the lists of subdirectories and on the Topics pages.
  • Link the subdirectories as [name](subdir/README.md), so that the links work both on GitLab and here, and write the class names plainly: Doxygen links them to the class pages. Relative links to the source files lead to their file pages, e.g. run_reco_bmn.C.
  • The Python scripts are not included in the Doxygen documentation: describe them in the README.md of their directory.
  • Text needed on GitLab only is put between the lines <!-- gitlab-only --> and <!-- /gitlab-only -->: the markers are not shown on GitLab, and Doxygen skips the text between them.
  • The Topics page groups the directories by subject. A new top-level directory or a new subdirectory of detectors or database is added to a topic in services/doxygen/topics.dox (@dir with its path and @ingroup of the topic), otherwise the documentation build reports it.
  • Do not use @defgroup and @ingroup in the code: the topics are defined in topics.dox only.

Links and special commands

  • Class names are linked automatically. Functions and data members are linked as BmnClass::Function(), or as Function() and #fMember inside the class. A word that is the name of a class, but is used in its common meaning, is written with % right before it, so that it is not linked.
  • @see refers to related classes or functions; @note and @warning are shown as highlighted paragraphs.
  • @deprecated marks a class or function to be removed; @todo marks unfinished work. They are collected on the Deprecated List and Todo List pages.
  • BM@N is written as is.

Checking the documentation

The documentation is built locally with the DoxygenDoc target (Doxygen 1.10 or newer and Graphviz are needed, see services/doxygen); then the warnings of the changed files are looked up in the log:

cmake -S ~/bmnroot -B ~/bmnroot/build -DBUILD_DOXYGEN=ON
make -C ~/bmnroot/build DoxygenDoc
grep -E "BmnExampleTask|run_example" ~/bmnroot/build/services/doxygen/doxygen_warnings.log

Typical warnings are a parameter that is not documented, an @param name that is not an argument of the function, @return of a function returning nothing, and an unknown command (e.g. @ in the text). The warnings of the dev branch are also kept as the doxygen_warnings.log artifact of the pages job of the GitLab CI.

Example

#ifndef BMNEXAMPLETASK_H
#define BMNEXAMPLETASK_H
#include "FairTask.h"
#include <TClonesArray.h>
#include <TString.h>
/** Selection of the hits by BmnExampleTask. */
enum class BmnHitSelection
{
kAll, ///< all hits
kMatched, ///< hits matched to the MC tracks
};
/**
* Example task, which selects the hits of a detector for the track finding.
*
* The task reads the hits from the input branch, selects them by the charge and writes the selected hits to the
* output branch. The selection is set by the setters before Init().
*/
class BmnExampleTask : public FairTask
{
public:
/**
* Creates the task.
* @param inputBranch name of the input branch with the hits
* @param outputBranch name of the output branch for the selected hits
*/
BmnExampleTask(TString inputBranch, TString outputBranch);
virtual ~BmnExampleTask();
/**
* Gets the input branch and registers the output branch.
* @return kSUCCESS, or kFATAL if the input branch is missing
*/
InitStatus Init() override;
/// Selects the hits of the current event.
void Exec(Option_t* option) override;
/**
* Checks whether a hit is selected.
* @param charge charge of the hit, ADC counts
* @return true if the hit passes the selection
*/
Bool_t IsSelected(Double_t charge) const;
void SetMinCharge(Double_t charge) { fMinCharge = charge; }
void SetSelection(BmnHitSelection selection) { fSelection = selection; }
private:
TString fInputBranch; ///< name of the input branch
TString fOutputBranch; ///< name of the output branch
Double_t fMinCharge; ///< minimal charge of the selected hits, ADC counts
BmnHitSelection fSelection; ///< selection of the hits
TClonesArray* fInputHits; ///<! input hits, not stored
TClonesArray* fOutputHits; ///<! selected hits, not stored
ClassDefOverride(BmnExampleTask, 1);
};
#endif
bool Bool_t
const char Option_t
#define ClassDefOverride(name, id)

The reference documentation of BmnRoot is generated by Doxygen from the comments in the source code and from the README.md files of the directories. It is rebuilt for every commit to the dev branch, so the comments written according to these rules appear there after the merge request is merged. The documentation is written in English.

Main rules

  1. Document new classes, their public functions and data members in the header files.
  2. Use the Doxygen comments: /** ... */ or /// before a declaration, ///< after a member on the same line.
  3. Start each description with a short sentence ending with a period: it is shown in the class and member lists.
  4. Mark the transient data members with ///<!, not with //! (see Data members).
  5. Describe each directory with code in its README.md; add a new top-level directory or a new subdirectory of detectors or database to a topic (see Directories).
  6. Check the Doxygen warnings of the changed files (see Checking the documentation).

When you change an old class, bring the comments of the changed part to these rules.

What to document

  • Classes and structures: what the class represents or does, its place in the data processing (e.g. a task of the reconstruction chain or a data container of the DST), how it is used (the input and output branches of a task, the main functions).
  • Public functions: what the function does, the meaning and units of the parameters and of the return value, the ownership of the returned objects, the behavior on errors.
  • Data members: the meaning and units.
  • Enumerations and their values, global functions and constants.
  • ROOT macros: purpose and parameters (see ROOT macros).
  • Directories: the README.md file (see Directories).

Getters and setters with self-explaining names (GetNHits(), SetMinCharge()) may stay without a description. The documentation tells what the code does and how to use it; the implementation details are explained by the ordinary comments in the code.

Where to put the comments

Classes and functions are documented in the header (.h) files before their declarations. Doxygen joins the descriptions of a function from the header and from the source (.cxx) file, so a description repeated in the .cxx file is shown twice: the comments in the .cxx files are ordinary comments (//), which explain the implementation. Functions declared only in a .cxx or .C file (e.g. the functions of a macro) are documented at their definition.

Comment style

Comment Use
/** ... */ description of several lines before a class, function, enumeration, ...
/// description of one or more lines before a declaration
///< description after a data member or an enumeration value on the same line
//, /* ... */ ordinary comment, not included in the documentation
  • The commands are written with @ (@param, @return); the form with a backslash (\param) is the same, but use one form in a file.
  • The first sentence of a description, up to the first period followed by a space, is the brief description shown in the class and member lists and at the top of the page; the rest is the detailed description. An explicit @brief is not needed. An abbreviation in the first sentence ends it at its period: rephrase the sentence or write a backslash after the period (e.g.\ this).
  • Markdown can be used in the comments: code, lists, emphasis. Code examples are put between @code and @endcode.
  • Do not comment out code with /// or /** */: the code becomes the description of the next declaration. Separator lines like ////////// are ignored.
  • The comments are formatted by clang-format together with the code (120 columns, aligned trailing comments).

Files

A class header is described by its class, so a file comment is optional. If a file has one, write @file without the file name: Doxygen warns about a wrong name, and the name becomes wrong when the file is renamed. @author and @date are optional.

/**
* @file
* Functions for the conversion of the TOF-700 raw data.
* @author Name Surname
*/

The description of a class is put before the class, not into the file comment: the class page shows only the comment of the class.

Functions

/**
* Fits the track with the Kalman filter.
* @param track track to fit, its parameters are updated
* @param pdg PDG code of the particle hypothesis
* @return chi2 of the fit, or a negative value if the fit failed
*/
Double_t FitTrack(BmnTrack* track, Int_t pdg = 211);
  • The names after @param are the names of the arguments in the declaration. If some parameters are documented, document all of them: Doxygen warns about the missing ones. Output arguments are marked as @param[out], input and output ones as @param[in,out].
  • @return is written only for functions returning a value.
  • Give the units of physical quantities (e.g. momentum in GeV/c) and the owner of a returned object (who deletes it).
  • For overridden virtual functions, describe what is specific to the class, e.g. the branches read and registered by Init() of a task. A function without a description shows the description of the overridden BmnRoot function.

Data members

A data member is described after its declaration with ///<. ROOT reads this comment too: it is the title of the member (shown e.g. in the TBrowser), and the marker at its beginning makes the member transient or sets the size of a dynamic array. The markers are written right after ///<:

Data member Declaration
stored in the file Int_t fNHits; ///< number of hits
transient (not stored) TClonesArray* fHits; ///<! input hits
dynamic array of the size fNHits Double_t* fX; ///<[fNHits] coordinates of the hits, cm
pointer, which is never null BmnVertex* fVertex; ///<-> primary vertex

Use only ///<! for the transient members (checked with ROOT 6.36 and Doxygen 1.17):

  • //! text makes the member transient, but Doxygen attaches the text to the next member;
  • //!< text is attached correctly by Doxygen, but ROOT does not see the marker and stores the member;
  • ///<! is understood by both; in the documentation, the description of a transient member starts with !.

Replacing //! with ///<! in old code does not change the I/O of the class: ROOT reads the same title. Plain trailing comments (// text) are not included in the documentation; replace them with ///< text. Enumeration values are described in the same way with ///<.

ROOT macros

The macros (.C files) are included in the documentation as file pages with their functions. Document the main function of a macro with a Doxygen comment, not with ordinary comments at the top of the file, which are not shown:

/**
* Simulation of BM@N events: transport of the generated particles through the setup and conversion of the MC
* points to digits.
* @param genFile input file of the event generator
* @param simFile output file with the MC tracks, points and digits
* @param nEvents number of events to simulate
*/
void run_sim_bmn(TString genFile = "", TString simFile = "bmnsim.root", Int_t nEvents = 10)

How to run the macros of a directory is described in its README.md.

Directories

  • Each directory with code has a README.md in plain GitLab Markdown, which is shown on GitLab and as the page of the directory in this documentation: a # Title, the description of the directory, and the tables of its classes, files and subdirectories. The title is also the brief description of the directory in the file list, in the lists of subdirectories and on the Topics pages.
  • Link the subdirectories as [name](subdir/README.md), so that the links work both on GitLab and here, and write the class names plainly: Doxygen links them to the class pages. Relative links to the source files lead to their file pages, e.g. run_reco_bmn.C.
  • The Python scripts are not included in the Doxygen documentation: describe them in the README.md of their directory.
  • Text needed on GitLab only is put between the lines <!-- gitlab-only --> and <!-- /gitlab-only -->: the markers are not shown on GitLab, and Doxygen skips the text between them.
  • The Topics page groups the directories by subject. A new top-level directory or a new subdirectory of detectors or database is added to a topic in services/doxygen/topics.dox (@dir with its path and @ingroup of the topic), otherwise the documentation build reports it.
  • Do not use @defgroup and @ingroup in the code: the topics are defined in topics.dox only.

Links and special commands

  • Class names are linked automatically. Functions and data members are linked as BmnClass::Function(), or as Function() and #fMember inside the class. A word that is the name of a class, but is used in its common meaning, is written with % right before it, so that it is not linked.
  • @see refers to related classes or functions; @note and @warning are shown as highlighted paragraphs.
  • @deprecated marks a class or function to be removed; @todo marks unfinished work. They are collected on the Deprecated List and Todo List pages.
  • BM@N is written as is.

Checking the documentation

The documentation is built locally with the DoxygenDoc target (Doxygen 1.10 or newer and Graphviz are needed, see services/doxygen); then the warnings of the changed files are looked up in the log:

cmake -S ~/bmnroot -B ~/bmnroot/build -DBUILD_DOXYGEN=ON
make -C ~/bmnroot/build DoxygenDoc
grep -E "BmnExampleTask|run_example" ~/bmnroot/build/services/doxygen/doxygen_warnings.log

Typical warnings are a parameter that is not documented, an @param name that is not an argument of the function, @return of a function returning nothing, and an unknown command (e.g. @ in the text). The warnings of the dev branch are also kept as the doxygen_warnings.log artifact of the pages job of the GitLab CI.

Example

#ifndef BMNEXAMPLETASK_H
#define BMNEXAMPLETASK_H
#include "FairTask.h"
#include <TClonesArray.h>
#include <TString.h>
/** Selection of the hits by BmnExampleTask. */
enum class BmnHitSelection
{
kAll, ///< all hits
kMatched, ///< hits matched to the MC tracks
};
/**
* Example task, which selects the hits of a detector for the track finding.
*
* The task reads the hits from the input branch, selects them by the charge and writes the selected hits to the
* output branch. The selection is set by the setters before Init().
*/
class BmnExampleTask : public FairTask
{
public:
/**
* Creates the task.
* @param inputBranch name of the input branch with the hits
* @param outputBranch name of the output branch for the selected hits
*/
BmnExampleTask(TString inputBranch, TString outputBranch);
virtual ~BmnExampleTask();
/**
* Gets the input branch and registers the output branch.
* @return kSUCCESS, or kFATAL if the input branch is missing
*/
InitStatus Init() override;
/// Selects the hits of the current event.
void Exec(Option_t* option) override;
/**
* Checks whether a hit is selected.
* @param charge charge of the hit, ADC counts
* @return true if the hit passes the selection
*/
Bool_t IsSelected(Double_t charge) const;
void SetMinCharge(Double_t charge) { fMinCharge = charge; }
void SetSelection(BmnHitSelection selection) { fSelection = selection; }
private:
TString fInputBranch; ///< name of the input branch
TString fOutputBranch; ///< name of the output branch
Double_t fMinCharge; ///< minimal charge of the selected hits, ADC counts
BmnHitSelection fSelection; ///< selection of the hits
TClonesArray* fInputHits; ///<! input hits, not stored
TClonesArray* fOutputHits; ///<! selected hits, not stored
ClassDefOverride(BmnExampleTask, 1);
};
#endif