Skip to content
Snippets Groups Projects
MicroDAQ.h 4.13 KiB
Newer Older
 */

#ifndef CHIMERATK_APPLICATION_CORE_MICRO_DAQ_H
#define CHIMERATK_APPLICATION_CORE_MICRO_DAQ_H

#include "ApplicationCore.h"
#include <ChimeraTK/SupportedUserTypes.h>
namespace detail {
struct AccessorAttacher;
struct H5storage;
struct DataSpaceCreator;
struct DataWriter;
} // namespace detail

/**
 *  MicroDAQ module for logging data to HDF5 files. This can be usefull in
 * enviromenents where no sufficient logging of data is possible through the
 * control system. Any ChimeraTK::Module can act as a data source. Which
 * variables should be logged can be selected through EntityOwner::findTag().
 */
struct MicroDAQ : public ApplicationModule {
   *  Constructor. decimationFactor and decimationThreshold are configuration
   * constants which determine how the data reduction is working. Arrays with a
   * size bigger than decimationThreshold will be decimated by decimationFactor
   * before writing to the HDF5 file.
  MicroDAQ(EntityOwner *owner, const std::string &name,
           const std::string &description, uint32_t decimationFactor = 10,
           uint32_t decimationThreshold = 1000, bool eliminateHierarchy = false,
           const std::unordered_set<std::string> &tags = {})
      : ApplicationModule(owner, name, description, eliminateHierarchy, tags),
        decimationFactor_(decimationFactor),
        decimationThreshold_(decimationThreshold) {}

  /** Default constructor, creates a non-working module. Can be used for late
   * initialisation. */
  MicroDAQ() : decimationFactor_(0), decimationThreshold_(0) {}

  ScalarPushInput<int> trigger{
      this,
      "trigger",
      "",
      "When written, the MicroDAQ write snapshot of all variables "
      "to the file",
      {"MicroDAQ.CONFIG"}};
  ScalarPollInput<int> enable{
      this,
      "enable",
      "",
      "DAQ is active when set to 0 and disabled when set to 0.",
      {"MicroDAQ.CONFIG"}};

  ScalarPollInput<uint32_t> nMaxFiles{
      this,
      "nMaxFiles",
      "",
      "Maximum number of files in the ring buffer "
      "(oldest file will be overwritten).",
      {"MicroDAQ.CONFIG"}};
  ScalarPollInput<uint32_t> nTriggersPerFile{
      this,
      "nTriggersPerFile",
      "",
      "Number of triggers stored in each file.",
      {"MicroDAQ.CONFIG"}};

  ScalarOutput<uint32_t> currentFile{this,
                                     "currentFile",
                                     "",
                                     "File number currently written to.",
                                     {"MicroDAQ.CONFIG"}};

  /** Add a Module as a source to this DAQ. */
  void addSource(const Module &source, const RegisterPath &namePrefix = "");

protected:
  void mainLoop() override;

  template <typename UserType>
  VariableNetworkNode getAccessor(const std::string &variableName);

  /** Map of VariableGroups required to build the hierarchies. The key it the
   * full path name. */
  std::map<std::string, VariableGroup> groupMap;

  /** boost::fusion::map of UserTypes to std::lists containing the
   * ArrayPollInput accessors. These accessors are dynamically created by the
   * AccessorAttacher. */
  template <typename UserType>
  using AccessorList = std::list<ArrayPollInput<UserType>>;
  TemplateUserTypeMap<AccessorList> accessorListMap;

  /** boost::fusion::map of UserTypes to std::lists containing the names of the
   * accessors. Technically there would be no need to use TemplateUserTypeMap
   * for this (as type does not depend on the UserType), but since these lists
   * must be filled consistently with the accessorListMap, the same construction
   * is used here. */
  template <typename UserType> using NameList = std::list<std::string>;
  TemplateUserTypeMap<NameList> nameListMap;

  /** Overall variable name list, used to detect name collisions */
  std::list<std::string> overallVariableList;

  /** Parameters for the data decimation */
  uint32_t decimationFactor_, decimationThreshold_;

  friend struct detail::AccessorAttacher;
  friend struct detail::H5storage;
  friend struct detail::DataSpaceCreator;
  friend struct detail::DataWriter;
};

} // namespace ChimeraTK

#endif /* CHIMERATK_APPLICATION_CORE_MICRO_DAQ_H */