RdADCTraceFixer.cc
Go to the documentation of this file.
1 #include "RdADCTraceFixer.h"
2 
3 #include <fwk/CentralConfig.h>
4 
5 #include <utl/config.h>
6 #include <utl/ErrorLogger.h>
7 #include <utl/Reader.h>
8 
9 #include <evt/Event.h>
10 #include <revt/REvent.h>
11 #include <revt/Station.h>
12 #include <revt/Channel.h>
13 
14 
15 using namespace revt;
16 using namespace fwk;
17 using namespace utl;
18 using std::ostringstream;
19 
20 
21 namespace RdADCTraceFixer {
22 
23 
26  {
27  Branch topBranch = CentralConfig::GetInstance()->GetTopBranch("RdADCTraceFixer");
28  topBranch.GetChild("InfoLevel").GetData(fInfoLevel);
29  topBranch.GetChild("CorrectChannelMixing").GetData(fCorrectChannelMixing);
30 
31  return eSuccess;
32  }
33 
34 
36  RdADCTraceFixer::Run(evt::Event& event)
37  {
38  // Check if there are events at all
39  if (!event.HasREvent()) {
40  WARNING("No radio event found!");
41  return eContinueLoop;
42  }
43 
44  REvent& rEvent = event.GetREvent();
45 
46  // loop through stations and for every station through every channel
47  for (auto& station : rEvent.StationsRange()) {
48 
49  //correct channel mixing (flaws in EA data from 11/22-03/23)
50  if (fCorrectChannelMixing) {
51  std::vector<std::pair<ChannelADCTimeSeries, ChannelADCTimeSeries>> traceOpts;
52  std::pair<ChannelADCTimeSeries, ChannelADCTimeSeries> currTraces;
53 
54  for (const auto& channel : station.ChannelsRange()) {
55 
56  if (!channel.IsActive())
57  break;
58 
59  if (channel.GetId() == 0) {
60  currTraces.first = channel.GetChannelADCTimeSeries();
61  } else {
62  currTraces.second = channel.GetChannelADCTimeSeries();
63  }
64  }
65 
66  const double binning = station.GetChannel(0).GetChannelADCTimeSeries().GetBinning();
67  const int traceLength = currTraces.first.GetSize();
68 
69  // we test 3 options for the NS channel (one channel is conclusive):
70  // no channel mixing
71  traceOpts.push_back(currTraces);
72 
73  // trace starts on odd bin
74  for (int i = 0; i < traceLength; i += 2) {
75  currTraces.first[i] = traceOpts[0].first[i];
76  currTraces.first[i+1] = traceOpts[0].second[i];
77  currTraces.second[i] = traceOpts[0].second[i+1];
78  currTraces.second[i+1] = traceOpts[0].first[i+1];
79  }
80  traceOpts.push_back(currTraces);
81 
82  // trace starts on even bin
83  for (int i = 0; i < traceLength; i += 2) {
84  currTraces.first[i] = traceOpts[0].first[i+1];
85  currTraces.first[i+1] = traceOpts[0].second[i+1];
86  currTraces.second[i] = traceOpts[0].second[i];
87  currTraces.second[i+1] = traceOpts[0].first[i];
88  }
89  traceOpts.push_back(currTraces);
90 
91  // now test all options by making a FFT
92  // look at frequency spectrum to decide which option is correct
93  std::vector<double> freqRatios;
94  for (auto const& opt : traceOpts) {
95  Channel& channelNS = station.GetChannel(0);
96  // we change timeTrace, which changes GetChannelTimeSeries(), which will update
97  // the FFT when calling GetFrequencySpectrum()
98  auto& timeTrace = channelNS.GetChannelTimeSeries();
99 
100  timeTrace.Clear();
101  timeTrace.SetBinning(binning);
102  timeTrace = opt.first * 1.0;
103 
104  auto& myFFTDataContainer = channelNS.GetFFTDataContainer();
105  const auto& freqSpectrum = myFFTDataContainer.GetFrequencySpectrum();
106 
107  const double ratio = CalculateRatio(freqSpectrum, traceLength);
108  freqRatios.push_back(ratio);
109  }
110 
111  const int maxIndex = std::max_element(freqRatios.begin(), freqRatios.end()) - freqRatios.begin();
112 
113  ostringstream info;
114  info <<"\n" << (maxIndex ? "Original trace correct " : "Channel mixing ")
115  << "identified. Saved correct trace.";
116  INFO(info);
117 
118  for (auto& channel : station.ChannelsRange()) {
119 
120  if (!channel.IsActive())
121  break;
122 
123  auto& adcTrace = channel.GetChannelADCTimeSeries();
124 
125  if (channel.GetId() == 0) {
126  adcTrace = traceOpts[maxIndex].first;
127  } else {
128  adcTrace = traceOpts[maxIndex].second;
129  }
130  }
131  }
132  }
133 
134  return eSuccess;
135  }
136 
137 
139  RdADCTraceFixer::Finish()
140  {
141  return eSuccess;
142  }
143 
144 
145  double
146  RdADCTraceFixer::CalculateRatio(const ChannelFrequencySpectrum& freqSpectrum, int traceLength)
147  {
148  double freq = 0;
149  double inRange = 0;
150  double outRange = 0;
151  int counter = 1;
152  for (const auto& amp : freqSpectrum) {
153  freq = double(counter) / double(traceLength) * 250;
154 
155  if (freq >= 30 && freq <= 80) {
156  inRange += abs(amp);
157  } else {
158  outRange += abs(amp);
159  }
160  counter++;
161  }
162  return inRange / outRange;
163  }
164 
165 }
ChannelFFTDataContainer & GetFFTDataContainer()
retrieve Channel FFTDataContainer (write access)
Branch GetTopBranch() const
Definition: Branch.cc:63
int freq
Definition: dump1090.h:244
Interface class to access to the Radio part of an event.
Definition: REvent.h:42
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
bool HasREvent() const
ChannelTimeSeries & GetChannelTimeSeries()
retrieve Channel Time Series (write access, only use this if you intend to change the data) ...
Class representing a document branch.
Definition: Branch.h:107
C< F > & GetFrequencySpectrum()
read out the frequency spectrum (write access)
double abs(const SVector< n, T > &v)
void Clear()
Definition: Trace.h:158
#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
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
Class that holds the data associated to an individual radio channel.

, generated on Tue Sep 26 2023.