diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 1e1684cb5e95b8ddc2d4df1dab25396a2c0a7a49..2af4efb1b63902970564aa7b943a245759dafa77 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -5,6 +5,7 @@ set(CBMBASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/base) add_subdirectory(data) add_subdirectory(field) add_subdirectory(base) +add_subdirectory(qa) add_subdirectory(detectors/trd) add_subdirectory(detectors/rich) diff --git a/core/qa/CMakeLists.txt b/core/qa/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1140f0e592341210ff1e5e5d4c45b0df1ced8b6e --- /dev/null +++ b/core/qa/CMakeLists.txt @@ -0,0 +1,30 @@ +Set(INCLUDE_DIRECTORIES +${CMAKE_CURRENT_SOURCE_DIR} +) + +Include_Directories( ${INCLUDE_DIRECTORIES}) + +Set(SYSTEM_INCLUDE_DIRECTORIES + ${BASE_INCLUDE_DIRECTORIES} +) + +Include_Directories(SYSTEM ${SYSTEM_INCLUDE_DIRECTORIES}) + +set(LINK_DIRECTORIES +${ROOT_LIBRARY_DIR} +${FAIRROOT_LIBRARY_DIR} +${Boost_LIBRARY_DIRS} +) + +link_directories( ${LINK_DIRECTORIES}) + +set(SRCS +CbmQaCanvas.cxx +) + +set(LINKDEF CbmQaBaseLinkDef.h) +Set(LIBRARY_NAME CbmQaBase) +Set(DEPENDENCIES +) + +GENERATE_LIBRARY() diff --git a/core/qa/CbmQaBaseLinkDef.h b/core/qa/CbmQaBaseLinkDef.h new file mode 100644 index 0000000000000000000000000000000000000000..1709eae5e18db5a891cc4b2ca5d1f03f24b064b1 --- /dev/null +++ b/core/qa/CbmQaBaseLinkDef.h @@ -0,0 +1,8 @@ +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class CbmQaCanvas - ; +#endif diff --git a/core/qa/CbmQaCanvas.cxx b/core/qa/CbmQaCanvas.cxx new file mode 100644 index 0000000000000000000000000000000000000000..932ed9b23ac8e4e1ba9641794379b5654b2e180a --- /dev/null +++ b/core/qa/CbmQaCanvas.cxx @@ -0,0 +1,35 @@ +/// \file CbmQaCanvas.cxx +/// \brief Implementation of the CbmQaCanvas class +/// \author Sergey Gorbunov <se.gorbunov@gsi.de> +/// \date 17.09.2020 + +#include "CbmQaCanvas.h" +#include "TBuffer.h" +#include "TVirtualPad.h" + +ClassImp(CbmQaCanvas); + +/// The Streamer is declared by ClassDef() macro +/// Stream an object of class CbmQaCanvas +/// +void CbmQaCanvas::Streamer(TBuffer& R__b) { + + // Save global gPad pointer, + // because it will be modified by TCanvas streamer + auto store = gPad; + if (R__b.IsReading()) { + R__b.ReadClassBuffer(CbmQaCanvas::Class(), this); + } else { + R__b.WriteClassBuffer(CbmQaCanvas::Class(), this); + } + // restore the global pointer + gPad = store; +} + +void CbmQaCanvas::Divide2D(int nPads) { + if (nPads < 1) nPads = 1; + int rows = (int) sqrt(nPads); + int cols = nPads / rows; + if (cols * rows < nPads) cols++; + TCanvas::Divide(cols, rows); +} diff --git a/core/qa/CbmQaCanvas.h b/core/qa/CbmQaCanvas.h new file mode 100644 index 0000000000000000000000000000000000000000..d88209aa46c6daa2588a8700512b98171b4d5d06 --- /dev/null +++ b/core/qa/CbmQaCanvas.h @@ -0,0 +1,64 @@ +/// \file CbmQaCanvas.h +/// \brief Definition of the CbmQaCanvas class +/// \author Sergey Gorbunov <se.gorbunov@gsi.de> +/// \date 17.09.2020 + +#ifndef CbmQaCanvas_H +#define CbmQaCanvas_H + +#include "TCanvas.h" +#include "TROOT.h" + +/// A modification of TCanvas which is helpful for storing canvases in a root +/// file together with other objects. +/// +/// 1. When ROOT reads a file which contains canvases, for no reason it sets +/// global gPad to the last canvas in the file, thus deactivating the browser +/// window. CbmQaCanvas modifies the standard TCanvas::Streamer() to suppress +/// this feature. +/// +/// 2. The CbmQaCanvas is created in the batch mode, i.e. it is not +/// automatically displayed. +/// +/// 3. Please use DrawCopy() methods instead of Draw(), to draw objects in the +/// canvas. Otherwise the same object can be stored several times in the file; +/// later this will cause crashes in the ROOT Browser for whatever reason. +/// +class CbmQaCanvas : public TCanvas { +public: + /// Default constructor needed by the ROOT streamer + CbmQaCanvas() : TCanvas() {} + + /// Reimplementation of any existing TCanvas constructor + /// It sets the batch mode ON and then calls the constructor + template<typename... Types> + CbmQaCanvas(Types... args) : CbmQaCanvas(SetBatchModeOn(), args...) {} + + /// Destructor + virtual ~CbmQaCanvas() {} + + /// Divide canvas into nPads in 2D in a nice way + void Divide2D(int nPads); + +private: + /// Use a specific type name in order to avoid ambiguities when unrolling + /// templates + enum MyBoolean : Bool_t; + + /// Constructor which calls TCanvas constructor and restores the bach mode + template<typename... Types> + CbmQaCanvas(MyBoolean oldBatchMode, Types... args) : TCanvas(args...) { + gROOT->SetBatch((Bool_t) oldBatchMode); + } + + /// Set batch mode ON and return its old value + static MyBoolean SetBatchModeOn() { + MyBoolean oldBatchMode = (MyBoolean) gROOT->IsBatch(); + gROOT->SetBatch(kTRUE); + return oldBatchMode; + } + + ClassDef(CbmQaCanvas, 1); +}; + +#endif