DABC (Data Acquisition Backbone Core)  2.9.9
Input.cxx
Go to the documentation of this file.
1 /********************************************************************
2  * The Data Acquisition Backbone Core (DABC)
3  ********************************************************************
4  * Copyright (C) 2009-
5  * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
6  * Planckstr. 1
7  * 64291 Darmstadt
8  * Germany
9  * Contact: http://dabc.gsi.de
10  ********************************************************************
11  * This software can be used under the GPL license agreements as stated
12  * in LICENSE.txt file which is part of the distribution.
13  ********************************************************************/
14 
15 #include "dabc/Pointer.h"
16 #include "user/Input.h"
17 #include <unistd.h>
18 #include <cmath>
19 
20 #include "dabc/Port.h"
21 #include "dabc/logging.h"
22 
23 #include "mbs/Iterator.h"
24 
26  dabc::DataInput (), fURL (url), fNumEvents(0)
27 // provide input and output buffers
28 {
29  DOUT2 ("Created new user::Input\n");
30  fReadLength = url.GetOptionInt("bufsize", 65536);
31 
32  // for mbs header format configuration:
33  fSubeventSubcrate= url.GetOptionInt("cratid", 0);
34  fSubeventProcid = url.GetOptionInt("procid", 1);
35  fSubeventControl = url.GetOptionInt("ctrlid", 7);
36  fSubeventSize = url.GetOptionInt("size", 32);
37  fEarlyTriggerClear = url.HasOption("earlytrigclr");
38  fDebug = url.HasOption("debug");
39 
40  if(fDebug) DOUT0 ("Created new user::Input with read length %d, crate:%d, procid:%d, control:%d\n",
42 
43 }
44 
46 {
47  User_Cleanup();
48 }
49 
50 
51 
53 {
54  DOUT1 ("Read_Init is executed...");
55  if(User_Init()!=0) return false;
56  return dabc::DataInput::Read_Init(wrk,cmd);
57 }
58 
59 
60 
62  {
63  return 0.1; // timeout in seconds in case of dabc::di_RepeatTimeOut
64  }
65 
66 
68 {
69  return ( GetReadLength ()); // will specify buffer size for next event
70 }
71 
73 {
74  DOUT2 ("Read_Start() with bufsize %d\n", buf.GetTotalSize ());
75  return dabc::di_Ok; // synchronous mode, all handled in Read_Complete
76 }
77 
79 {
80  DOUT3 ("Read_Complete() with buffer size :%d\n", buf.GetTotalSize());
81  int trigtype=User_WaitForTrigger ();
82  if (!trigtype)
83  {
84  // case of timeout, need dabc retry?
85  EOUT(("**** Timout of trigger, retry dabc request.. \n"));
87  }
88  if(fEarlyTriggerClear) User_ResetTrigger (); // prepare for next trigger before readout of data (for external DAQ buffering)
90  mbs::WriteIterator iter(buf);
91  iter.NewEvent(fNumEvents);
92  mbs::EventHeader* evhdr = (mbs::EventHeader*) iter.rawdata();
93  // put here DAQ trigger type:
94  evhdr->iTrigger = trigtype;
95 
96  iter.NewSubevent(fSubeventSize, fSubeventSubcrate, fSubeventControl, fSubeventProcid);
97  uint32_t* pldat = (uint32_t*) iter.rawdata();
98  unsigned long subsize=0;
99  int res = User_Readout(pldat, subsize);
100 
101  if(!fEarlyTriggerClear) User_ResetTrigger (); // prepare for next trigger only after readout has finished
102  if ((unsigned) res == dabc::di_SkipBuffer)
103  {
104  return dabc::di_SkipBuffer;
105  }
106  if ((unsigned) res == dabc::di_RepeatTimeOut)
107  {
108  if(fDebug) DOUT1 ("user::Input() returns with timeout\n");
109  return dabc::di_RepeatTimeOut;
110  }
111  if ((unsigned) res == dabc::di_Error)
112  {
113  EOUT("user::Input() returns with Error\n");
114  return dabc::di_Error;
115  }
116 
117  if(!iter.FinishSubEvent(subsize))
118  {
119  EOUT("user::Input() could not finish subevent with size:%d\n",subsize);
120  return dabc::di_Error;
121  }
122  if(!iter.FinishEvent())
123  {
124  EOUT("user::Input() could not finish event \n");
125  return dabc::di_Error;
126  }
127  buf = iter.Close();
128  if(fDebug)
129  {
130  if(fNumEvents % 10000 ==0)
131  {
132  DOUT0 ("UserReadout has send %d events to input, last size:%d, return value:%d, total buffers size:%d\n",
133  fNumEvents, subsize,res, buf.GetTotalSize());
134  }
135  }
136  fNumEvents++;
137  return (unsigned) res;
138 }
139 
140 
142 // below are the user defined functions for proprietary DAQ
143 // they can be changed already here
144 // it is also possible to develop a subclass of user::Input and re-implement it there
146 
148 {
149  DOUT0("Executing User_Init() function for crate:%d, procid:%d, control:%d",
150  fSubeventSubcrate, fSubeventProcid, fSubeventControl);
151  // do antything reasonable here to setup your readout device
152  // parameters can be passed to this function by extracting URL in the constructor and defining member variables
153  return 0; // nonzero return value will mark error in the framework
154 }
155 
157 {
158  DOUT0("Executing User_Cleanup() function");
159  return 0;
160 }
161 
163 {
164  // this is just a dummy implementation, causing a frequent polling readout.
165  // todo: implement check of external readout trigger source
166  int trigtype = mbs::tt_Event;
167  usleep(500);
168  return trigtype;
169 }
170 
172  {
173  // todo: reset trigger state in readout device
174  return 0;
175 }
176 
177 int user::Input::User_Readout (uint32_t* pdat, unsigned long& size)
178  {
179  unsigned numval = 100;
180  for (unsigned nval=0;nval<numval;nval++)
181  {
182  if(size>=fSubeventSize)
183  {
184  DOUT0("User_Readout: data would exceed subevent size %d ,please adjust setup",fSubeventSize);
185  return dabc::di_Error;
186  }
187  *pdat++ = (uint32_t) Gauss_Rnd(nval*500 + 1000, 500./(nval+1));
188  size+=sizeof(uint32_t);
189  }
190  return dabc::di_Ok;
191 }
192 
193 
194 
195 double user::Input::Gauss_Rnd(double mean, double sigma)
196 {
197  // this function is taken from mbs random source to provide some data for standard go4 examples
198  double x, y, z;
199  z = 1.* rand() / RAND_MAX;
200  y = 1.* rand() / RAND_MAX;
201  x = z * 6.28318530717958623;
202  return mean + sigma*sin(x)*sqrt(-2*log(y));
203 }
double Gauss_Rnd(double mean, double sigma)
Reference on memory from memory pool.
Definition: Buffer.h:135
BufferSize_t GetTotalSize() const
Return total size of all buffer segments.
Definition: Buffer.cxx:91
void SetTypeId(unsigned tid)
Definition: Buffer.h:151
Represents command with its arguments.
Definition: Command.h:99
virtual bool Read_Init(const WorkerRef &wrk, const Command &cmd)
Initialize data input, using port and command.
Definition: DataIO.h:82
Uniform Resource Locator interpreter.
Definition: Url.h:33
bool HasOption(const std::string &optname) const
Definition: Url.h:70
int GetOptionInt(const std::string &optname, int dflt=0) const
Definition: Url.cxx:290
Reference on dabc::Worker
Definition: Worker.h:466
Write iterator for MBS events/subevents.
Definition: Iterator.h:97
bool FinishSubEvent(uint32_t rawdatasz=0)
Definition: Iterator.cxx:378
bool NewSubevent(uint32_t minrawsize=0, uint8_t crate=0, uint16_t procid=0, uint8_t control=0)
Definition: Iterator.cxx:329
void * rawdata() const
Definition: Iterator.h:158
bool NewEvent(EventNumType event_number=0, uint32_t subeventsize=0)
Definition: Iterator.cxx:304
dabc::Buffer Close()
Definition: Iterator.cxx:237
Input(dabc::Url &url)
Definition: Input.cxx:25
unsigned int fSubeventSize
subevent size for this example
Definition: Input.h:86
virtual unsigned Read_Complete(dabc::Buffer &buf)
Complete reading of the buffer from source,.
Definition: Input.cxx:78
bool fDebug
flag for optional debug output
Definition: Input.h:102
virtual int User_Readout(uint32_t *pdat, unsigned long &size)
Fill the data at the buffer pointer.
Definition: Input.cxx:177
double Gauss_Rnd(double mean, double sigma)
produce random spectra for the go4 example
Definition: Input.cxx:195
unsigned int fReadLength
actual payload length of read buffer
Definition: Input.h:79
unsigned int fSubeventProcid
For mbsformat: defines subevent procid.
Definition: Input.h:92
virtual int User_ResetTrigger()
Used to clear any kind of external trigger information.
Definition: Input.cxx:171
virtual int User_Cleanup()
shut down the readout hardware properly at the end
Definition: Input.cxx:156
bool fEarlyTriggerClear
rest the trigger before device buffer has been read out.
Definition: Input.h:99
unsigned int fSubeventControl
For mbsformat: defines subevent control.
Definition: Input.h:95
virtual ~Input()
Definition: Input.cxx:45
virtual unsigned Read_Start(dabc::Buffer &buf)
Prepare buffer for reading (if required)
Definition: Input.cxx:72
virtual int User_WaitForTrigger()
Here any kind of external trigger can be waited for.
Definition: Input.cxx:162
virtual double Read_Timeout()
Provide timeout value.
Definition: Input.cxx:61
unsigned int fSubeventSubcrate
For mbsformat: defines subevent subcrate id for case fSingleSubevent=true.
Definition: Input.h:89
virtual unsigned Read_Size()
Defines required buffer size for next operation.
Definition: Input.cxx:67
virtual bool Read_Init(const dabc::WorkerRef &wrk, const dabc::Command &cmd)
Initialize data input, using port and command.
Definition: Input.cxx:52
virtual int User_Init()
Initialize the readout hardware on startup.
Definition: Input.cxx:147
#define DOUT2(args ...)
Definition: logging.h:170
#define DOUT0(args ...)
Definition: logging.h:156
#define DOUT3(args ...)
Definition: logging.h:176
#define EOUT(args ...)
Definition: logging.h:150
#define DOUT1(args ...)
Definition: logging.h:162
Event manipulation API.
Definition: api.h:23
@ di_Ok
Definition: DataIO.h:38
@ di_RepeatTimeOut
Definition: DataIO.h:36
@ di_SkipBuffer
Definition: DataIO.h:41
@ di_Error
Definition: DataIO.h:40
@ tt_Event
Definition: MbsTypeDefs.h:28
@ mbt_MbsEvents
Definition: MbsTypeDefs.h:348