Diana Software
MJitterByDelay.cc
Go to the documentation of this file.
1 #include "MJitterByDelay.hh"
2 #include "QBaseType.hh"
3 #include "QVector.hh"
4 #include "QError.hh"
5 #include "QEvent.hh"
6 #include "QRawEvent.hh"
7 #include "QEventList.hh"
8 #include "QOFData.hh"
9 #include "QDetChannelCollectionHandle.hh"
10 #include "QJitter.hh"
11 #include "QJitterHandle.hh"
12 #include <vector>
13 #include <math.h>
14 #include <algorithm>
15 #include <TH1D.h>
16 
18 
19  using std::vector;
20  using namespace Diana;
21 
23 {
24  fOutput = GetString("Output", "jitter.txt");
25  fRefCh_IsSet = false;
26  fRefCh = GetInt("ReferenceChannel", Q_INT_DEFAULT, false);
27  fTower = GetInt("Tower", Q_INT_DEFAULT, false);
28 
29  Info("Tower is: %d", fTower);
30 
31  if (fRefCh!=Q_INT_DEFAULT) {
32  Info("Reference Channel set to: %d", fRefCh);
33  fRefCh_IsSet = true;
34  }
35 
36  fOFLabel = GetString("OFLabel","COF"); // to maintain backwards compatibility
37 
38  ev.Require<QPulseInfo>("DAQ","PulseInfo");
39  ev.Require<QHeader>("DAQ","Header");
40  ev.Require<QOFData>(fOFLabel,"OFData");
41 
42  // clear quantities
43  fJitterSum = 0.;
44  fJitterErrorSum = 0.;
45  fDelays.clear();
46 }
47 
48 //void MJitterByDelay::Do(QEvent& ev, const QEventList& neighbours)
50 {
51  const QPulseInfo& pulseInfo = ev.Get<QPulseInfo>("DAQ","PulseInfo");
52  const int& channel = pulseInfo.GetChannelId();
53 
54  fGoodChannels.insert(channel);
55 
56  const QOFData& ofd = ev.Get<QOFData>(fOFLabel.c_str(),"OFData");
57  const double& delay = ofd.GetDelay();
58 
59  const QHeader& hdr = ev.Get<QHeader>("DAQ","Header");
60  fRun = hdr.GetRun();
61 
62  // creates QVector of delays for each channel, if already set, return
63  if(fDelays.find(channel) != fDelays.end())
64  {
65  (fDelays.find(channel)->second).Append(delay);
66  return;
67  }
68 
69  QVector vecDelay;
70  vecDelay.Append(delay);
71  fDelays[channel] = vecDelay;
72  vecDelay.Clear();
73 }
74 
76 {
77  // get dataset
78  GlobalHandle<QInt> dHandle("Dataset");
79  GlobalData().Get("",&dHandle,"");
80  fDataset = dHandle.Get();
81 
82  QDetChannelCollectionHandle dccHandle;
83  dccHandle.SetRun(fRun);
84  GlobalData().Get("",&dccHandle,"");
85  const QDetChannelCollection& DCC = dccHandle.Get();
86 
87  QVector Delays;
88  QVector Delays_red;
89 
90  double Delay = 0.;
91  double DelayRMS = 0.;
92 
93  std::map<int,Diana::QVector > ::const_iterator mapIter;
94  for (mapIter=fDelays.begin(); mapIter!=fDelays.end(); ++mapIter)
95  {
96  int ch = mapIter->first;
97  Delays = mapIter->second;
98 
99  // calculates the mean value of vector fDelays for each channel
100  // mean value is calculated after removing the outliers (cut on median +- 3*MAD)
101 
102  double medianDelays = Delays.GetMedian();
103  double MADDelays = Delays.GetMedianAbsoluteDeviation();
104 
105  for (size_t j=0; j<Delays.Size(); j++)
106  {
107  if(Delays[j]>(medianDelays-3.*MADDelays) && Delays[j]<(medianDelays+3.*MADDelays))
108  {
109  Delays_red.Append(Delays[j]);
110  }
111  }
112  if(Delays_red.Size()>0) {
113 
114  Delay = (Delays_red.Sum(Delays_red.Size(),0))/((double) Delays_red.Size());
115  DelayRMS = (Delays_red.GetRMS(Delays_red.Size()))/(sqrt((double) Delays_red.Size()));
116  fDelay[ch]=Delay;
117  fDelayRMS[ch]=DelayRMS;
118  }
119 
120  Delays_red.Clear();
121  Delays.Clear();
122  std::cout << ch << " " << fDelay[ch] << std::endl;
123  }
124 
125  // loop over detector geometry
126 
127  const std::vector<int>& towers = DCC.GetTowers();
128  fLastFloor = false;
129 
130  // if reference channel is not specified, identify reference channel as the channel in position 1,
131  // first floor, first tower
132  // |
133  // 3 | 2
134  // ----|-----
135  // 4 | 1
136  // |
137 
138  // if reference channel is set find position of reference channel
139 
140 
141 
142  //FIXME temporary workaround, must check if there are cases where it doesn't work. See debugMJitterByDelay.txt
143  int position = 0;
144 
145  if (!fRefCh_IsSet) {
146  for(position = 1; position <= 4; position++)
147  {
148  fRefCh = FindChanWithPosInTowerFloor(position,fTower,1);
149  Info("Reference Channel set to: %d, Position: %d", fRefCh,position);
150  if(fRefCh!=Q_INT_DEFAULT) continue;
151  }
152  }
153 
154  else if (fRefCh_IsSet) {
155  position = DCC.Get(fRefCh).fTd.fTdPos;
156  }
157 
158  for (size_t j=0; j<towers.size(); j++)
159  {
160  int tower = towers[j];
161  const std::vector<int>& floors = DCC.GetFloorsInTower(tower);
162 
163  // check if tower has floors
164  if (floors.size()>0) Info("Processing tower: %d",tower);
165  if (tower!=fTower) {Info("Skip tower %d",tower); continue;} // process by tower
166  else if (floors.size()==0) {Info("Tower %d has no floors",tower); continue;} //problem if size =0
167 
168  int last_floor = floors[floors.size()-1];
169 
170  // starts loop over floors
171  for (size_t i=0; i<floors.size(); i++)
172  {
173  int floor = floors[i];
174  if (floor == last_floor) fLastFloor = true;
175 
176  Info("Processing floor: %d, position: %d",floor,position);
177  position = ProcessFloor(position,tower,floor);
178  }
179  }
180 }
181 
182 double MJitterByDelay::FindJitter(int ch, int o_ch)
183 {
184  double jitter = 0.;
185  std::map<int,double>::const_iterator miter = fDelay.find(ch);
186  std::map<int,double>::const_iterator viter = fDelay.find(o_ch);
187  if (miter!=fDelay.end() && viter!=fDelay.end())
188  {
189  // jitter = fDelay[ch]-fDelay[o_ch];
190  jitter = fDelay[ch];
191  }
192  return jitter;
193 }
194 
195 double MJitterByDelay::FindJitterRMS(int ch, int o_ch)
196 {
197  double jitterRMS = 0.;
198  std::map<int,double>::const_iterator miter = fDelayRMS.find(ch);
199  std::map<int,double>::const_iterator viter = fDelayRMS.find(o_ch);
200  if (miter!=fDelayRMS.end() && viter!=fDelayRMS.end())
201  {
202  // jitterRMS = fDelayRMS[ch]-fDelayRMS[o_ch];
203  jitterRMS = fDelayRMS[ch];
204  }
205  return jitterRMS;
206 }
207 
208 int MJitterByDelay::FindChanWithPosInTowerFloor(int pos, int tower, int floor)
209 {
210  int chan = Q_INT_DEFAULT;
211  std::vector<int> chans;
212 
213  QDetChannelCollectionHandle dccHandle;
214  dccHandle.SetRun(fRun);
215  GlobalData().Get("",&dccHandle,"");
216  const QDetChannelCollection& DCC = dccHandle.Get();
217 
218  const std::vector<int>& chTF = DCC.GetChannelsInTowerFloor(tower,floor);
219 
220  for (size_t i=0; i<chTF.size(); i++)
221  {
222  if (DCC.Get(chTF[i]).fTd.fTdPos == pos) chans.push_back(chTF[i]);
223  }
224 
225  for (size_t j=0; j<chans.size(); j++)
226  {
227  if (fGoodChannels.count(chans[j])>0)
228  {
229  chan = chans[j];
230  std::cout << "good channels : " << chans[j] << std::endl;
231  }
232  }
233 
234  return chan;
235 }
236 
237 void MJitterByDelay::SaveJitter(int ch, double jitter, double jitter_error)
238 {
239  QJitter jitterObj;
240  jitterObj.Clear();
241 
242  // set the object jitterObj
243  jitterObj.fRefChannel = fRefCh;
244  jitterObj.fJitter = jitter;
245  jitterObj.fJitterError = jitter_error;
246 
247  QJitterHandle jitterHandle(ch,fDataset);
248  jitterHandle.SetCalibVersion(GetConfig().fVersionTag);
249  jitterHandle.SetCalibLabel("");
250 
251  jitterHandle.Set(jitterObj);
252  GlobalData().Set(&jitterHandle,fOutput);
253 }
254 
255 int MJitterByDelay::ProcessFloor(int start_pos, int tower, int floor)
256 {
257  int ndet = 4;
258  int pos[ndet];
259  int ch_pos[ndet];
260  int best_pos = 1;
261 
262  double jitter_rel;
263  double jitterRMS_rel;
264 
265  for (int i=0; i<ndet; i++)
266  {
267  pos[i] = start_pos+i;
268  if (pos[i]>4) pos[i]=pos[i]-4;
269 
270  ch_pos[i] = FindChanWithPosInTowerFloor(pos[i],tower,floor);
271  jitter_rel = FindJitter(ch_pos[i],fRefCh);
272  jitterRMS_rel = FindJitterRMS(ch_pos[i],fRefCh);
273  if (jitter_rel!=0.) SaveJitter(ch_pos[i],jitter_rel,jitterRMS_rel);
274  }
275  return best_pos;
276 }
277 
const int channel
#define Q_INT_DEFAULT
Definition: QDiana.hh:26
#define REGISTER_MODULE(clazz)
Definition: QDriver.hh:133
Calculates mean value of OFDelay for all channels using pulser events (later used as a proxy for jitt...
int ProcessFloor(int pos, int tower, int floor)
ProcessFloor function.
void SaveJitter(int ch, double jitter, double jitter_error)
SaveJitter function.
void Init(Diana::QEvent &ev)
Init method.
void Done()
Done method.
int FindChanWithPosInTowerFloor(int pos, int tower, int floor)
FindPos function.
void Do(Diana::QEvent &ev)
Do method
double FindJitterRMS(int ch, int o_ch)
FindJitterRMS function.
double FindJitter(int ch, int o_ch)
FindJitter function.
diana event
Definition: QEvent.hh:46
void Require(const std::string &owner, const std::string &name) const
notify the QEvent that we need a QObject, if not found an exception is thrown
Definition: QEvent.hh:232
void Get(const char *owner, ReadHandle< Q > &handle) const
Get a QObject Handle in read mode.
Definition: QEvent.hh:74
Raw event: basic information like run number and time.
Definition: QHeader.hh:16
int GetRun() const
destructor
Definition: QHeader.hh:22
global handle for jitter by coincidence
void SetCalibLabel(const std::string &calibl)
void SetCalibVersion(const std::string &calibv)
jitter by coincidence
Definition: QJitter.hh:17
void Clear()
Definition: QJitter.hh:21
int fRefChannel
Definition: QJitter.hh:28
double fJitterError
Definition: QJitter.hh:30
double fJitter
Definition: QJitter.hh:29
Raw event: bolometer channel, trigger positions and types.
Definition: QPulseInfo.hh:18
const int & GetChannelId() const
Get ChannelId.
Definition: QPulseInfo.hh:22
the Diana namespace is needed because sometimes we use Qt libraries, that use same class names of our...