ChimeraTK-ApplicationCore 04.06.00
Loading...
Searching...
No Matches
Multiplier.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3#pragma once
4
5#include "ApplicationModule.h"
6#include "ArrayAccessor.h"
7#include "ScalarAccessor.h"
8
9#include <cmath>
10#include <limits>
11
12namespace ChimeraTK {
13
14 template<typename InputType, typename OutputType = InputType, size_t NELEMS = 1>
16 ConstMultiplier(ModuleGroup* owner, const std::string& name, const std::string& description, double theFactor)
17 : ApplicationModule(owner, name, ""), input(this, "input", "", NELEMS, description),
18 output(this, "output", "", NELEMS, description), factor(theFactor) {}
19
22
23 double factor;
24
25 void mainLoop() override {
26 while(true) {
27 // scale value (with rounding, if integral type)
28 if(!std::numeric_limits<OutputType>::is_integer) {
29 for(size_t i = 0; i < NELEMS; ++i) {
30 output[i] = input[i] * factor;
31 }
32 }
33 else {
34 for(size_t i = 0; i < NELEMS; ++i) {
35 output[i] = std::round(input[i] * factor);
36 }
37 }
38
39 // write scaled value
40 output.write();
41
42 // wait for new input value (at the end, since we want to process the
43 // initial values first)
44 input.read();
45 }
46 }
47 };
48
49 template<typename InputType, typename OutputType = InputType, size_t NELEMS = 1>
50 struct Multiplier : public ApplicationModule {
52
53 Multiplier(ModuleGroup* owner, const std::string& name, const std::string& factorName, const std::string& unitInput,
54 const std::string& unitOutput, const std::string& description,
55 const std::unordered_set<std::string>& tagsInput = {}, const std::unordered_set<std::string>& tagsOutput = {},
56 const std::unordered_set<std::string>& tagsFactor = {})
57 : ApplicationModule(owner, ".", "") {
58 input.replace(ArrayPushInput<InputType>(input, name, unitInput, NELEMS, description, tagsInput));
59 factor.replace(ScalarPushInput<double>(
60 input, factorName, "(" + unitOutput + ")/(" + unitInput + ")", description, tagsFactor));
61 output.replace(ArrayOutput<OutputType>(input, name, unitOutput, NELEMS, description, tagsOutput));
62 }
63
64 Multiplier(ModuleGroup* owner, const std::string& inputPath, const std::string& inputUnit,
65 const std::string& factorPath, const std::string& outputPath, const std::string& outputUnit,
66 const std::string& description, const std::unordered_set<std::string>& inputTags = {},
67 const std::unordered_set<std::string>& factorTags = {}, const std::unordered_set<std::string>& outputTags = {})
68 : ApplicationModule(owner, ".", "") {
69 std::string factorUnit = "(" + outputUnit + ")/(" + inputUnit + ")";
70 input.replace(ArrayPushInput<InputType>(this, inputPath, inputUnit, NELEMS, description, inputTags));
71 factor.replace(ScalarPushInput<InputType>(this, factorPath, factorUnit, description, factorTags));
72 output.replace(ArrayOutput<InputType>(this, outputPath, outputUnit, NELEMS, description, outputTags));
73 }
74
78
79 void mainLoop() override {
80 ReadAnyGroup group{input, factor};
81 while(true) {
82 // scale value (with rounding, if integral type)
83 if constexpr(!std::numeric_limits<OutputType>::is_integer) {
84 for(size_t i = 0; i < NELEMS; ++i) {
85 output[i] = input[i] * factor;
86 }
87 }
88 else {
89 for(size_t i = 0; i < NELEMS; ++i) {
90 output[i] = std::round(input[i] * factor);
91 }
92 }
93
94 // write scaled value
95 output.write();
96
97 // wait for new input value (at the end, since we want to process the
98 // initial values first)
99 group.readAny();
100 }
101 }
102 };
103
104 template<typename InputType, typename OutputType = InputType, size_t NELEMS = 1>
105 struct Divider : public ApplicationModule {
107 Divider(ModuleGroup* owner, const std::string& name, const std::string& description)
108 : ApplicationModule(owner, name, ""), input(this, "input", "", NELEMS, description),
109 divider(this, "divider", "", "Divider to scale the input value with"),
110 output(this, "output", "", NELEMS, description) {}
111
115
116 void mainLoop() override {
117 ReadAnyGroup group{input, divider};
118 while(true) {
119 // scale value (with rounding, if integral type)
120 if(!std::numeric_limits<OutputType>::is_integer) {
121 for(size_t i = 0; i < NELEMS; ++i) {
122 output[i] = input[i] / divider;
123 }
124 }
125 else {
126 for(size_t i = 0; i < NELEMS; ++i) {
127 output[i] = std::round(input[i] / divider);
128 }
129 }
130
131 // write scaled value
132 output.write();
133
134 // wait for new input value (at the end, since we want to process the
135 // initial values first)
136 group.readAny();
137 }
138 }
139 };
140
141} // namespace ChimeraTK
ApplicationModule()=default
Default constructor: Allows late initialisation of modules (e.g.
void replace(const ChimeraTK::NDRegisterAccessorAbstractor< UserType > &newAccessor)=delete
Convenience class for input array accessors with UpdateMode::push.
void replace(const ChimeraTK::NDRegisterAccessorAbstractor< UserType > &newAccessor)=delete
Convenience class for input scalar accessors with UpdateMode::push.
InvalidityTracer application module.
Convenience class for output array accessors (always UpdateMode::push)
ArrayPushInput< InputType > input
Definition Multiplier.h:20
ArrayOutput< OutputType > output
Definition Multiplier.h:21
ConstMultiplier(ModuleGroup *owner, const std::string &name, const std::string &description, double theFactor)
Definition Multiplier.h:16
void mainLoop() override
To be implemented by the user: function called in a separate thread executing the main loop of the mo...
Definition Multiplier.h:25
void mainLoop() override
To be implemented by the user: function called in a separate thread executing the main loop of the mo...
Definition Multiplier.h:116
Divider(ModuleGroup *owner, const std::string &name, const std::string &description)
Definition Multiplier.h:107
ArrayOutput< OutputType > output
Definition Multiplier.h:114
ArrayPushInput< InputType > input
Definition Multiplier.h:112
ScalarPushInput< double > divider
Definition Multiplier.h:113
Multiplier(ModuleGroup *owner, const std::string &name, const std::string &factorName, const std::string &unitInput, const std::string &unitOutput, const std::string &description, const std::unordered_set< std::string > &tagsInput={}, const std::unordered_set< std::string > &tagsOutput={}, const std::unordered_set< std::string > &tagsFactor={})
Definition Multiplier.h:53
ArrayOutput< OutputType > output
Definition Multiplier.h:77
ArrayPushInput< InputType > input
Definition Multiplier.h:75
ApplicationModule()=default
Default constructor: Allows late initialisation of modules (e.g.
Multiplier(ModuleGroup *owner, const std::string &inputPath, const std::string &inputUnit, const std::string &factorPath, const std::string &outputPath, const std::string &outputUnit, const std::string &description, const std::unordered_set< std::string > &inputTags={}, const std::unordered_set< std::string > &factorTags={}, const std::unordered_set< std::string > &outputTags={})
Definition Multiplier.h:64
ScalarPushInput< double > factor
Definition Multiplier.h:76
void mainLoop() override
To be implemented by the user: function called in a separate thread executing the main loop of the mo...
Definition Multiplier.h:79