RdChannelResponseIncorporator.cc
Go to the documentation of this file.
2 
3 #include <fwk/CentralConfig.h>
4 #include <fwk/RandomEngineRegistry.h>
5 
6 #include <utl/ErrorLogger.h>
7 #include <utl/Reader.h>
8 #include <utl/config.h>
9 #include <utl/AugerUnits.h>
10 #include <utl/TabulatedFunctionComplexLgAmpPhase.h>
11 #include <utl/RandomEngine.h>
12 
13 #include <evt/Event.h>
14 #include <revt/REvent.h>
15 #include <revt/Station.h>
16 #include <revt/Channel.h>
17 
18 #include <rdet/RDetector.h>
19 #include <rdet/Station.h>
20 #include <rdet/Channel.h>
21 
22 #include <CLHEP/Random/RandGauss.h>
23 
24 
25 using namespace utl;
26 using namespace fwk;
27 using namespace std;
28 using namespace revt;
29 using namespace boost;
30 
31 using CLHEP::RandGauss;
32 
33 
35 
36 
39  {
40  Branch topBranch = CentralConfig::GetInstance()->GetTopBranch("RdChannelResponseIncorporator");
41  topBranch.GetChild("InfoLevel").GetData(fInfoLevel);
42 
43  topBranch.GetChild("NumResponsesToCache").GetData(fNumResponsesToCache);
44  topBranch.GetChild("ForwardResponseOnFirstCall").GetData(fForwardResponseOnFirstCall);
45  topBranch.GetChild("OverrideInverseBandLimits").GetData(fInverseBandLimitsOverride);
46  topBranch.GetChild("InverseLowerFrequencyLimit").GetData(fInverseLowerFrequency);
47  topBranch.GetChild("InverseUpperFrequencyLimit").GetData(fInverseUpperFrequency);
48  topBranch.GetChild("OverrideForwardBandLimits").GetData(fForwardBandLimitsOverride);
49  topBranch.GetChild("ForwardLowerFrequencyLimit").GetData(fForwardLowerFrequency);
50  topBranch.GetChild("ForwardUpperFrequencyLimit").GetData(fForwardUpperFrequency);
51 
52  topBranch.GetChild("SmearChannelTraceToMimicInaccurateHardwareDescription").GetData(
53  fSmearChannelTraceToMimicInaccurateHardwareDescription);
54 
55  topBranch.GetChild("RelativeGaussianUcertainty").GetData(fRelativeGaussianUcertainty);
56  if (fSmearChannelTraceToMimicInaccurateHardwareDescription)
57  fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector);
58 
59  ostringstream info;
60  info << "Read config:"
61  << "\n\t ForwardResponseOnFirstCall : "
62  << fForwardResponseOnFirstCall
63  << "\n\t SmearChannelTraceToMimicInaccurateHardwareDescription : "
64  << fSmearChannelTraceToMimicInaccurateHardwareDescription
65  << "\n\t RelativeGaussianUcertainty : "
66  << fRelativeGaussianUcertainty << "\n";
67  INFO(info);
68 
69  return eSuccess;
70  }
71 
72 
74  RdChannelResponseIncorporator::Run(evt::Event& event)
75  {
76  // Check if there are events at all
77  if(!event.HasREvent()) {
78  WARNING("No radio event found!");
79  return eContinueLoop;
80  }
81 
82  det::Detector& thedet = det::Detector::GetInstance();
83  REvent& rEvent = event.GetREvent();
84 
85  ostringstream message;
86  message << "Run first time: " << (rEvent.GetChannelResponseApplied() ? "no" : "yes");
87  INFO(message);
88 
89  // loop through stations and for every station through every channel
90  for (auto& station : rEvent.StationsRange()) {
91  for (auto& channel : station.ChannelsRange()) {
92 
93  if (!channel.IsActive()) {
94  continue;
95  }
96 
97  const rdet::Channel& channeldet =
98  thedet.GetRDetector().GetStation(station.GetId()).GetChannel(channel.GetId());
99  ResponseMap channelresponsemap = channeldet.GetResponseMap();
100 
101  const TabulatedFunctionComplexLgAmpPhase& channelresponse = GetCachedOverallResponse(channelresponsemap);
102 
103  // for later check if in frequency range
104  const double designLowerfrequency = channeldet.GetDesignLowerFreq();
105  const double designUpperfrequency = channeldet.GetDesignUpperFreq();
106 
107 
108  if (!fForwardResponseOnFirstCall) {
109  // module is just called once in module sequence, i.e. this is a data pipeline
110  // -> apply inverse response
111  message.str("");
112  message << "Applying inverse detector response to channel "
113  << channel.GetId() << " of station " << station.GetId();
114  INFOIntermediate(message);
115 
116  if (fInverseBandLimitsOverride)
117  ApplyResponse(channel, channelresponse, true, fInverseLowerFrequency, fInverseUpperFrequency);
118  else
119  ApplyResponse(channel, channelresponse, true, designLowerfrequency, designUpperfrequency);
120  } else {
121  // module is called more than once in module sequence; now check whether this is first or later call
122  if (rEvent.GetChannelResponseApplied()) {
123  // this is (at least) the second call of the module for this event
124  message.str("");
125  message << "Later call: applying inverse response to channel "
126  << channel.GetId() << " of station " << station.GetId();
127  INFODebug(message);
128 
129  if (fInverseBandLimitsOverride)
130  ApplyResponse(channel, channelresponse, true, fInverseLowerFrequency, fInverseUpperFrequency);
131  else
132  ApplyResponse(channel, channelresponse, true, designLowerfrequency, designUpperfrequency);
133  } else {
134  // this is the first call of the module for this event
135  message.str("");
136  message << "First call: applying forward response to channel "
137  << channel.GetId() << " of station " << station.GetId();
138  INFODebug(message);
139 
140  if (fForwardBandLimitsOverride)
141  ApplyResponse(channel, channelresponse, false, fForwardLowerFrequency, fForwardUpperFrequency);
142  else
143  ApplyResponse(channel, channelresponse, false, designLowerfrequency, designUpperfrequency);
144 
145  if (fSmearChannelTraceToMimicInaccurateHardwareDescription) {
146  revt::ChannelTimeSeries& trace = channel.GetChannelTimeSeries();
147  const double smearFactor = RandGauss::shoot(&fRandomEngine->GetEngine(), 1,
148  fRelativeGaussianUcertainty);
149 
150  message.str("");
151  message << "Station " << station.GetId() << " channel " << channel.GetId()
152  << " smeared with " << smearFactor;
153  INFOIntermediate(message);
154 
155  for (auto& val : trace)
156  val *= smearFactor;
157  }
158  }
159  }
160  }
161  }
162 
163  // note down application of channel response in event
164  rEvent.SetChannelResponseApplied(true);
165 
166  return eSuccess;
167  }
168 
169 
171  RdChannelResponseIncorporator::Finish()
172  {
173  ostringstream msg;
174  msg << "RdChannelResponseIncorporator cache hit fraction was "
175  << static_cast<double>(fCacheHits) / static_cast<double>(fCacheAsks)
176  << " for a cache with " << fNumResponsesToCache << " entries.";
177  INFO(msg);
178 
179  return eSuccess;
180  }
181 
182 
183  const
185  RdChannelResponseIncorporator::GetCachedOverallResponse(const ResponseMap& responsemap) const
186  {
187  ++fCacheAsks;
188  vector<CacheRecord>::iterator leastusedentry = fCacheRegistry.begin();
189  for (vector<CacheRecord>::iterator i = fCacheRegistry.begin(); i != fCacheRegistry.end(); ++i) {
190  if (i->get<0>() == responsemap) { // is the response map in the CacheRegistry equal to the specified one?
191  ++fCacheHits; // then register cache hit
192  ++i->get<2>(); // count hit to cache entry
193  return i->get<1>(); // return the found cache entry
194  }
195  // keep track of the least-used cache entry
196  if (i->get<2>() < leastusedentry->get<2>())
197  leastusedentry = i;
198  }
199 
200  // if we arrive here, then the cache did not contain the appropriate entry
201  if (fCacheRegistry.size() == fNumResponsesToCache) // if cache registry is full
202  fCacheRegistry.erase(leastusedentry); // make room for the new entry
203  fCacheRegistry.emplace_back(responsemap, CalculateOverallResponse(responsemap), 0);
204  return fCacheRegistry.back().get<1>(); // return the freshly generated entry
205  }
206 
207 
209  RdChannelResponseIncorporator::CalculateOverallResponse(const ResponseMap& responsemap) const
210  {
212  const rdet::RDetector& rdetector = det::Detector::GetInstance().GetRDetector();
213 
214  // treat first entry of response map manually
215  ResponseMap::const_iterator beginentry = responsemap.Begin();
216  // retrieve the response profile of the first entry
217  totalresponse = rdetector.GetHardwareResponseProfile(beginentry->first);
218  totalresponse.Pow(beginentry->second); // scale it with the correct weight
219  ++beginentry;
220 
221  // now accumulate the rest of the response map
222  for (auto it = beginentry; it != responsemap.End(); ++it) {
224  rdetector.GetHardwareResponseProfile(it->first);
225  tempresponse.Pow(it->second);
226  totalresponse *= tempresponse;
227  }
228 
229  return totalresponse;
230  }
231 
232 
233  void
234  RdChannelResponseIncorporator::ApplyResponse(Channel& channel, const TabulatedFunctionComplexLgAmpPhase& response,
235  bool inverse, double lowerfreq, double upperfreq) const
236  {
237  ChannelFrequencySpectrum& channelspectrum = channel.GetChannelFrequencySpectrum();
238  for (ChannelFrequencySpectrum::SizeType i = 0; i < channelspectrum.GetSize(); ++i) {
239  const double freq = channel.GetFrequencyOfBin(i);
240  if ((freq < lowerfreq) || (freq > upperfreq)) {
241  channelspectrum[i] = complex<double>(0.0, 0.0); // bin is outside design specifications, set it to zero
242  } else {
243  if (inverse)
244  channelspectrum[i] /= response.Y(freq).GetComplex();
245  else
246  channelspectrum[i] *= response.Y(freq).GetComplex();
247  }
248  }
249  }
250 
251 }
Branch GetTopBranch() const
Definition: Branch.cc:63
const_iterator End() const
Get an iterator to the end of the ResponseMap.
Definition: ResponseMap.h:48
double GetDesignUpperFreq() const
Get design value of the freq-band.
int freq
Definition: dump1090.h:244
Interface class to access to the Radio part of an event.
Definition: REvent.h:42
void SetChannelResponseApplied(const bool parFlag)
Definition: REvent.h:274
double GetDesignLowerFreq() const
Get design value of the freq-band.
void Pow(const double power)
calculate the power of a TabulatedFunctionComplexLgAmpPhase (correctly treating amplitude and phase) ...
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
std::complex< double > GetComplex() const
Get the complex number in standard notation; this clips the phase to 2*pi!
void Init()
Initialise the registry.
Detector description interface for Channel-related data.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
bool HasREvent() const
Detector description interface for RDetector-related data.
Definition: RDetector.h:46
std::map< std::string, double >::const_iterator const_iterator
Definition: ResponseMap.h:34
#define INFOIntermediate(y)
Definition: VModule.h:162
Class representing a document branch.
Definition: Branch.h:107
const utl::TabulatedFunctionComplexLgAmpPhase & GetHardwareResponseProfile(const std::string &identifier) const
Get the response (TabulatedFunctionComplexLgAmpPhase) which corresponds to a hardware profile identif...
Definition: RDetector.cc:164
Class to hold collection (x,y) points and provide interpolation between them, where y are complex num...
std::vector< std::complex< double > >::size_type SizeType
Definition: Trace.h:58
const utl::ResponseMap & GetResponseMap() const
Get the ResponseMap of the Channel.
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
bool GetChannelResponseApplied() const
access to fChannelResponseApplied flag
Definition: REvent.h:273
A helper class which manages a list of system response identifiers (std::strings) and their correspon...
Definition: ResponseMap.h:28
SizeType GetSize() const
Definition: Trace.h:156
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
#define INFODebug(y)
Definition: VModule.h:163
utl::ComplexLgAmpPhase Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
const_iterator Begin() const
Get an iterator to the first element of the ResponseMap.
Definition: ResponseMap.h:45
ChannelFrequencySpectrum & GetChannelFrequencySpectrum()
retrieve Channel Frequency Spectrum (write access, only use this if you intend to change the data) ...
double GetFrequencyOfBin(const ChannelFrequencySpectrum::SizeType bin) const
Get the frequency corresponding to a bin of the frequency spectrum.
Class that holds the data associated to an individual radio channel.
const rdet::RDetector & GetRDetector() const
Definition: Detector.cc:143
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: RDetector.cc:141

, generated on Tue Sep 26 2023.