Diana Software
MVariableOperation.cc
Go to the documentation of this file.
1 #include "MVariableOperation.hh"
2 #include "QBaseType.hh"
3 #include "QEvent.hh"
4 #include <algorithm>
5 #include "QEventList.hh"
6 #include "QRawEvent.hh"
7 
9 
10 using namespace Diana;
11 using std::cout;
12 using std::endl;
13 using std::vector;
14 
16 {
17  //Getting Arguments from cfg
18  fInputVar= GetString("Variable","",true);
19  fOutputVar = GetString("OutputVar","",true);
20  fFunction = GetString("Function","",true);
21 
22  fParamNames=FindVars(fFunction);
23 
24  fOtherVars = FindQuantities(fFunction);
25 
26  fChannels = GetVectorInt("Channels",vector<int>(),true);
27  std::sort(fChannels.begin(),fChannels.end());
28  channelparams.resize(fChannels.size());
29  for(size_t i =0; i<fChannels.size();i++){
30  channelparams[i].channel_number=fChannels[i];
31  }
32  cout<<endl;
33 
34  StringParams = GetString("Parameters","",true);
35  FindParameters(StringParams);
36  cout<<"InputVar\t"<<fInputVar.GetStringLabel()<<endl;
37  cout<<"OutputVar\t"<<fOutputVar<<endl;
38  cout<<"Function\t"<<fFunction<<endl;
39  cout<<"Parameter Names: ";
40  for(size_t k=0;k<fParamNames.size();k++){
41  cout<<"["<<fParamNames[k]<<"] ";
42  }
43  cout<<endl;
44  cout<<"Parameters:"<<endl;
45  for(size_t k=0;k<channelparams.size(); k++){
46  if(channelparams[k].fParameters.size()!=fParamNames.size()){
47  Panic("Number of parameters in formula don't match parameter values provided for channel %d",channelparams[k].channel_number);
48  }
49  cout<<"\tChannel "<< channelparams[k].channel_number<<" Parameters: ";
50  for(size_t i =0;i<channelparams[k].fParameters.size();i++){
51  cout<<channelparams[k].fParameters[i]<<" ";
52  }
53  cout<<endl;
54  }
55 
56  fFunc = TF1("EvalFunc",fFunction,-1e7,1e7);
57  cout<<"Found Quantities"<<endl;
58  for(size_t i =0;i<fOtherVars.size();i++){
59  cout<<"\t["<<fParamNames.size()+i<<"] "<<fOtherVars[i].GetStringLabel()<<endl;
60  SetReq(fOtherVars[i],ev);
61  }
62  SetReq(fInputVar,ev);
63  ev.Require<QPulseInfo>("DAQ","PulseInfo");
64  ev.Add<QDouble>(fOutputVar.Data());
65 }
66 
68  TString lab = TString(EvLab.GetStringLabel());
69  if(lab.Contains("BaselineData")){
70  ev.Require<QBaselineData>(EvLab.GetOwner().c_str(),"BaselineData");
71  }else{
72  ev.RequireByLabel<QDouble>(EvLab);
73  }
74 }
75 
77  TString lab = TString(EvLab.GetStringLabel());
78  double variable=0;
79  if(lab.Contains("BaselineData")){
80  const QBaselineData& bData=ev.Get<QBaselineData>(EvLab.GetOwner().c_str(),"BaselineData");
81  TString varlab = lab(lab.First(".")+1,lab.Length());
82  if(varlab.CompareTo("fBaseline")==0){
83  variable = bData.GetBaseline();
84 
85  }else if(varlab.CompareTo("fBaselineFlatRMS")==0){
86  variable = bData.GetBaselineFlatRMS();
87 
88  }else if(varlab.CompareTo("fBaselineIntercept")==0){
89  variable = bData.GetBaselineIntercept();
90 
91  }else if(varlab.CompareTo("fBaselineSlope")==0){
92  variable = bData.GetBaselineSlope();
93 
94  }else if(varlab.CompareTo("fBaselineSlopeRMSWindow")==0){
95  variable = bData.GetBaselineSlopeRMSWindow();
96 
97  }else if(varlab.CompareTo("fBaselineRMS")==0){
98  variable = bData.GetBaselineRMS();
99 
100  }else if(varlab.CompareTo("fRightBaseline")==0){
101  variable = bData.GetRightBaseline();
102 
103  }else if(varlab.CompareTo("fRightBaselineRMS")==0){
104  variable = bData.GetRightBaselineInRMS();
105  }else if(varlab.CompareTo("fRightLeftBaseline")==0){
106  variable = bData.GetRightLeftBaseline();
107  }else if(varlab.CompareTo("fRightLeftBaselineInRMS")==0){
108  variable = bData.GetRightLeftBaselineInRMS();
109  }else{
110  Panic(TString("'")+varlab+TString("' if not a valid choice for the 'Variable' field."));
111  }
112  }else{
113  variable = ev.GetByLabel<QDouble>(EvLab);
114  }
115  return variable;
116 
117 }
119 {
120  const QPulseInfo& pulseInfo = ev.Get<QPulseInfo>("DAQ","PulseInfo");
121  const int chan = pulseInfo.GetChannelId();
122  size_t chan_counter=channelparams.size();
123  for(size_t i =0;i<channelparams.size();i++){
124  if(channelparams[i].channel_number==chan){
125  chan_counter=i;
126  break;
127  }
128  }
129 
130  if(chan_counter==channelparams.size()){
131  Panic("Channel %d not found in provided channels from cfg!",chan);
132  }
133  for(size_t i =0;i<fParamNames.size();i++){
134  fFunc.SetParameter(fParamNames[i],channelparams[chan_counter].fParameters[i]);
135  }
136 
137  const double variable=GetValue(fInputVar,ev);
138  for(size_t i =0;i<fOtherVars.size();i++){
139  const double tmp = GetValue(fOtherVars[i],ev);
140  fFunc.SetParameter(fParamNames.size()+i,tmp);
141  }
142  ev.Get<QDouble>(fOutputVar.Data()) = fFunc.Eval(variable);
143 }
144 
145 vector<Int_t> MVariableOperation::FindVars(TString instring){
146  vector<TString> out;
147  size_t idxopen=0;
148  size_t idxclose=0;
149  bool condition = true;
150  while(condition){
151  idxclose=TString(instring(int(idxopen),instring.Length()-int(idxopen))).First(']') + idxopen;
152  idxopen=TString(instring(int(idxopen),instring.Length()-int(idxopen))).First('[') + idxopen;
153  if(idxclose<=idxopen){
154  condition=false;
155  continue;
156  }
157 
158  TString substr = TString(instring(int(idxopen),int(idxclose+1-idxopen)));
159  if(!substr.BeginsWith("[")){
160  condition=false;
161  continue;
162  }
163 
164  bool found=false;
165  for(size_t j=0;j<out.size();j++){
166  if(out[j].CompareTo(TString(substr(1,substr.Length()-2)))==0){
167  found=true;
168  }
169  }
170  if(!found){
171  out.push_back(TString(substr(1,substr.Length()-2)));
172  }
173  idxopen=idxclose+1;
174  }
175  vector<Int_t> out2;
176  for(size_t j=0;j<out.size();j++){
177  out2.push_back(out[j].Atoi());
178  }
179  std::sort (out2.begin(), out2.end());
180  return out2;
181 
182 
183 }
184 
185 vector<Diana::QEventLabel> MVariableOperation::FindQuantities(TString instring){
186  vector<TString> out;
187  size_t idxopen=0;
188  size_t idxclose=0;
189  bool condition=true;
190  while(condition){
191  idxclose=TString(instring(int(idxopen),instring.Length()-int(idxopen))).First('&') + idxopen;
192  idxopen=TString(instring(int(idxopen),instring.Length()-int(idxopen))).First('^') + idxopen;
193  if(idxclose<=idxopen){
194  condition=false;
195  continue;
196  }
197 
198  TString substr = TString(instring(int(idxopen),int(idxclose+1-idxopen)));
199  if(!substr.BeginsWith("^")){
200  condition=false;
201  continue;
202  }
203 
204  bool found=false;
205  for(size_t j=0;j<out.size();j++){
206  if(out[j].CompareTo(TString(substr(1,substr.Length()-2)))==0){
207  found=true;
208  }
209  }
210  if(!found){
211  out.push_back(TString(substr(1,substr.Length()-2)));
212  }
213  idxopen=idxclose+1;
214  }
215  TString modin = instring;
216  bool stop=false;
217  while(!stop){
218  idxopen = modin.First("^");
219  idxclose = modin.First("&");
220  TString v = TString(modin(idxopen+1,idxclose-idxopen-1));
221  if(idxclose<=idxopen){
222  stop=true;
223  continue;
224  }
225  size_t idx=0;
226  condition=true;
227  while(condition){
228  if(idx>=out.size()){
229  condition=false;
230  continue;
231  }
232  if (out[idx].CompareTo(v)!=0){
233  idx++;
234  }else{
235  condition=false;
236  continue;
237  }
238 
239  }
240  TString idxsub;
241  idxsub.Form("%lu",fParamNames.size()+idx);
242  modin = modin(0,int(idxopen))+"["+idxsub+"]"+modin(int(idxclose)+1,int(modin.Length()));
243  }
244  fFunction =modin;
245  vector<Diana::QEventLabel> out2;
246  for(size_t j=0;j<out.size();j++){
247  out2.push_back(Diana::QEventLabel(out[j]));
248  }
249  return out2;
250 
251 
252 }
253 
254 void MVariableOperation::FindParameters(TString instring){
255  //Remove Spaces
256  TString manip="";
257  for(int i =0; i< instring.Length();i++){
258  if(TString(instring(i,1)).CompareTo(" ")!=0){
259  manip+=TString(instring(i,1));
260  }
261  }
262 
263  //Find all "}," indicating channel separation
264  vector<int> separations={-1};
265  bool found=true;
266  while(found){
267  TString tmpstr=TString(manip(separations[separations.size()-1]+1,manip.Length()));
268  int tmp = -1;
269  for(int kk=0;kk<tmpstr.Length()-1;kk++){
270  if(TString(tmpstr(kk,2)).CompareTo("},")==0){
271  tmp=kk;
272  break;
273  }
274  }
275  if(tmp==-1 or TString(manip(separations[separations.size()-1]+1,manip.Length())).Length()/2+TString(manip(separations[separations.size()-1]+1,manip.Length())).Length()%2==tmp){
276  found=false;
277  }else{
278  separations.push_back(tmp+separations[separations.size()-1]+2);
279  }
280  }
281  //separating channels
282  size_t found_channels=0;
283  for(size_t i =0;i<separations.size();i++){
284  TString params;
285  if(i < separations.size()-1){
286  params = TString(manip(separations[i]+1,separations[i+1]-separations[i]-1));
287  }else{
288  params = TString(manip(separations[i]+1,manip.Length()));
289  }
290 
291  //Channel identification
292  int tmp = params.First(":");
293  if(tmp==-1 or tmp ==params.Length()){
294  Panic("Please provide channel ! String %s not valid! Format channel:{param1,param2,..}",params.Data());
295  }
296  tmp++;
297  int ch = TString(params(0,tmp)).Atoi();
298  params = TString(params(tmp,params.Length()));
299 
300  //Parameter identification
301  int start=params.First("{");
302  if(start==-1 or start ==params.Length()){
303  Panic("Wrong format ! String %s not valid! Format channel:{param1,param2,..}",params.Data());
304  }
305  int stop=params.First("}");
306  if(stop==-1 or stop ==params.Length()){
307  Panic("Wrong format ! String %s not valid! Format channel:{param1,param2,..}",params.Data());
308  }
309  start++;
310  params = TString(params(start,stop-start));
311  found = true;
312  vector<int> paramssep={-1};
313  while(found){
314  TString tmpstr2=TString(params(paramssep[paramssep.size()-1]+1,params.Length()));
315  tmp = -1;
316  for(int kk=0;kk<tmpstr2.Length();kk++){
317  if(TString(tmpstr2(kk,1)).CompareTo(",")==0){
318  tmp=kk;
319  break;
320  }
321  }
322  if(tmp==-1 or TString(params(paramssep[paramssep.size()-1],params.Length())).Length()==tmp){
323  found=false;
324  }else{
325  paramssep.push_back(tmp+paramssep[paramssep.size()-1]+1);
326  }
327  }
328 
329  size_t chcounter=channelparams.size();
330 
331  for(size_t k=0;k<channelparams.size(); k++){
332  if(channelparams[k].channel_number == ch){
333  chcounter=k;
334 
335  }
336  }
337  if(chcounter == channelparams.size()){
338  Panic("Selected Channel not found! Please include it in the cfg parameter!");
339  }else{
340  found_channels++;
341  }
342 
343  for(size_t i =0;i<paramssep.size();i++){
344  TString params2;
345  if(i == 0){
346  params2 = TString(params(0,paramssep[1]));
347  }else if(i < paramssep.size()-1){
348  params2 = TString(params(paramssep[i]+1,paramssep[i+1]-paramssep[i]));
349 
350  }else{
351  params2 = TString(params(paramssep[i]+1,params.Length()));
352  }
353  channelparams[chcounter].fParameters.push_back(params2.Atof());
354 
355  }
356  }
357  if(found_channels <channelparams.size()){
358  Panic("Please indicate parameters for all channels!");
359  }else if(found_channels >channelparams.size()){
360  Panic("Something weird happening... more channels found than present");
361  }
362 }
363 
365 {
366  /* This method is called at the end of the event loop.
367  * Here you can:
368  *
369  * 1) Operate on the sequence execution parameters(see QBaseModule.hh).
370  *
371  * 2) Read/Write global data.
372  */
373 }
374 
#define REGISTER_MODULE(clazz)
Definition: QDriver.hh:133
Perform function on variable.
double GetValue(Diana::QEventLabel EvLab, Diana::QEvent &ev)
std::vector< Int_t > FindVars(TString instring)
void SetReq(Diana::QEventLabel EvLab, Diana::QEvent &ev)
void FindParameters(TString instring)
void Do(Diana::QEvent &ev)
Do method. Declare and implement only one of the two versions.
void Done()
Done method.
std::vector< Diana::QEventLabel > FindQuantities(TString instring)
void Init(Diana::QEvent &ev)
Init method.
base types wrapped into a QObject. Currently implemented types are QInt QDouble and QFloat....
Definition: QBaseType.hh:17
baseline data
double GetBaseline() const
double GetBaselineRMS() const
double GetBaselineSlope() const
double GetBaselineFlatRMS() const
double GetRightLeftBaselineInRMS() const
double GetRightLeftBaseline() const
double GetRightBaselineInRMS() const
double GetBaselineIntercept() const
double GetBaselineSlopeRMSWindow() const
double GetRightBaseline() const
label for QObject in the QEvent
Definition: QEventLabel.hh:23
std::string GetStringLabel() const
get string in the format "owner@name"
Definition: QEventLabel.cc:48
const std::string & GetOwner() const
get owner
Definition: QEventLabel.hh:55
diana event
Definition: QEvent.hh:46
const Q & GetByLabel(const QEventLabel &label) const
Get a QObject in read mode by label.
Definition: QEvent.hh:135
void RequireByLabel(const QEventLabel &label) const
notify the QEvent that we need a QObject, if not found an exception is thrown
Definition: QEvent.hh:242
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
void Add(WriteHandle< Q > &handle)
Add a QObject to the event.
Definition: QEvent.hh:193
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...