DABC (Data Acquisition Backbone Core)  2.9.9
Factory.cxx
Go to the documentation of this file.
1 // $Id: Factory.cxx 4569 2020-07-31 12:38:50Z linev $
2 
3 /************************************************************
4  * The Data Acquisition Backbone Core (DABC) *
5  ************************************************************
6  * Copyright (C) 2009 - *
7  * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
8  * Planckstr. 1, 64291 Darmstadt, Germany *
9  * Contact: http://dabc.gsi.de *
10  ************************************************************
11  * This software can be used under the GPL license *
12  * agreements as stated in LICENSE.txt file *
13  * which is part of the distribution. *
14  ************************************************************/
15 
16 #include "hadaq/Factory.h"
17 
18 #include "dabc/Manager.h"
19 
20 #include "hadaq/HldInput.h"
21 #include "hadaq/HldOutput.h"
22 #include "hadaq/UdpTransport.h"
23 #include "hadaq/SorterModule.h"
24 #include "hadaq/CombinerModule.h"
25 #include "hadaq/TerminalModule.h"
26 #include "hadaq/BnetMasterModule.h"
27 #include "hadaq/MonitorModule.h"
28 #include "hadaq/api.h"
29 
30 
32 
33 
34 dabc::Reference hadaq::Factory::CreateObject(const std::string &classname, const std::string &objname, dabc::Command cmd)
35 {
36  if (classname=="hadaq_iter")
37  return new hadaq::EventsIterator(objname);
38 
39  return dabc::Factory::CreateObject(classname, objname, cmd);
40 }
41 
42 
43 dabc::DataInput* hadaq::Factory::CreateDataInput(const std::string &typ)
44 {
45  dabc::Url url(typ);
46  if (url.GetProtocol()=="hld") {
47  DOUT1("HLD input file name %s", url.GetFullName().c_str());
48 
49  return new hadaq::HldInput(url);
50  }
51 
52  return nullptr;
53 }
54 
56 {
57  dabc::Url url(typ);
58  if (url.GetProtocol()=="hld") {
59  DOUT1("HLD output file name %s", url.GetFullName().c_str());
60  return new hadaq::HldOutput(url);
61  }
62 
63  return nullptr;
64 }
65 
66 dabc::Module* hadaq::Factory::CreateTransport(const dabc::Reference& port, const std::string &typ, dabc::Command cmd)
67 {
68  dabc::Url url(typ);
69 
70  dabc::PortRef portref = port;
71 
72  if (!portref.IsInput() || url.GetFullName().empty() ||
73  ((url.GetProtocol()!="hadaq") && (url.GetProtocol()!="nhadaq") && (url.GetProtocol()!="ohadaq")))
74  return dabc::Factory::CreateTransport(port, typ, cmd);
75 
76  unsigned trignum = portref.GetModule().Cfg(hadaq::xmlHadaqTrignumRange, cmd).AsUInt(0x1000000);
77 
78  std::string portname = portref.GetName();
79 
80  int calibr = url.GetOptionInt("calibr", -1);
81 
82  if (url.HasOption("trb") && (url.HasOption("tdc") || (calibr>=0))) {
83  // first create TDC calibration module, connected to combiner
84 
85  std::string calname = dabc::format("TRB%04x_TdcCal", (unsigned) url.GetOptionInt("trb"));
86 
87 
88  if (calibr>=0)
89  DOUT0("Create calibration module %s AUTOMODE %d", calname.c_str(), calibr);
90  else
91  DOUT0("Create calibration module %s TDCS %s", calname.c_str(), url.GetOptionStr("tdc").c_str());
92 
93  dabc::CmdCreateModule mcmd("stream::TdcCalibrationModule", calname);
94  mcmd.SetStr("TRB", url.GetOptionStr("trb"));
95  if ((calibr>=0) && !url.HasOption("dummy")) {
96  mcmd.SetInt("Mode", calibr);
97  } else {
98  mcmd.SetInt("Mode", -1);
99  mcmd.SetStr("TDC", url.GetOptionStr("tdc"));
100  }
101 
102  if (url.HasOption("hub")) mcmd.SetStr("HUB", url.GetOptionStr("hub"));
103  if (url.HasOption("trig")) mcmd.SetStr("CalibrTrigger", url.GetOptionStr("trig"));
104  if (url.HasOption("dummy")) mcmd.SetBool("Dummy", true);
105  mcmd.SetInt("portid", portref.ItemSubId());
106  mcmd.SetInt(dabc::xmlNumInputs, 1);
107  mcmd.SetInt(dabc::xmlNumOutputs, 1);
108 
109  dabc::mgr.Execute(mcmd);
110 
111  dabc::ModuleRef calm = dabc::mgr.FindModule(calname);
112 
113  dabc::LocalTransport::ConnectPorts(calm.FindPort("Output0"), portref, cmd);
114 
115  portref = calm.FindPort("Input0");
116 
117  // workaround - we say manager that it should connect transport with other port
119 
120  dabc::mgr.app().AddObject("module", calname);
121  }
122 
123  if (url.HasOption("resort")) {
124  // then create resort module, connected to combiner or TDC calibration
125 
126  std::string sortname = dabc::format("%sResort", portname.c_str());
127 
128  DOUT0("Create sort module %s trignum 0x%06x", sortname.c_str(), trignum);
129 
130  dabc::CmdCreateModule mcmd("hadaq::SorterModule", sortname);
131  mcmd.SetUInt(hadaq::xmlHadaqTrignumRange, trignum);
132  dabc::mgr.Execute(mcmd);
133 
134  dabc::ModuleRef sortm = dabc::mgr.FindModule(sortname);
135 
136  dabc::LocalTransport::ConnectPorts(sortm.FindPort("Output0"), portref, cmd);
137 
138  portref = sortm.FindPort("Input0");
139 
140  // workaround - we say manager that it should connect transport with other port
142 
143  dabc::mgr.app().AddObject("module", sortname);
144  }
145 
146  int nport = url.GetPort();
147  if (nport<=0) { EOUT("Port not specified"); return 0; }
148 
149  int rcvbuflen = url.GetOptionInt("udpbuf", 200000);
150  int fd = NewAddon::OpenUdp(url.GetHostName(), nport, rcvbuflen);
151  if (fd<=0) { EOUT("Cannot open UDP socket for %s", url.GetHostNameWithPort().c_str()); return 0; }
152 
153  int mtu = url.GetOptionInt("mtu", 64512);
154  int maxloop = url.GetOptionInt("maxloop", 100);
155  double flush = url.GetOptionDouble(dabc::xml_flush, 1.);
156  double reduce = url.GetOptionDouble("reduce", 1.);
157  double lost_rate = url.GetOptionDouble("lost", 0);
158  bool debug = url.HasOption("debug");
159  int udp_queue = url.GetOptionInt("upd_queue", 0);
160  double heartbeat = url.GetOptionDouble("heartbeat", -1.);
161 
162  if (udp_queue>0) cmd.SetInt("TransportQueue", udp_queue);
163 
164  DOUT0("Start HADAQ UDP transport on %s", url.GetHostNameWithPort().c_str());
165 
166  NewAddon* addon = new NewAddon(fd, nport, mtu, debug, maxloop, reduce, lost_rate);
167  return new hadaq::NewTransport(cmd, portref, addon, flush, heartbeat);
168 }
169 
170 
171 dabc::Module* hadaq::Factory::CreateModule(const std::string &classname, const std::string &modulename, dabc::Command cmd)
172 {
173  if (classname == "hadaq::CombinerModule")
174  return new hadaq::CombinerModule(modulename, cmd);
175 
176  if (classname == "hadaq::SorterModule")
177  return new hadaq::SorterModule(modulename, cmd);
178 
179  if (classname == "hadaq::MbsTransmitterModule") {
180  EOUT("MbsTransmitterModule class no longer supported");
181  return nullptr;
182  }
183 
184  if (classname == "hadaq::ReadoutModule")
185  return new hadaq::ReadoutModule(modulename, cmd);
186 
187  if (classname == "hadaq::TerminalModule")
188  return new hadaq::TerminalModule(modulename, cmd);
189 
190  if (classname == "hadaq::BnetMasterModule")
191  return new hadaq::BnetMasterModule(modulename, cmd);
192 
193  if (classname == "hadaq::MonitorModule")
194  return new hadaq::MonitorModule(modulename, cmd);
195 
196  return dabc::Factory::CreateModule(classname, modulename, cmd);
197 }
bool AddObject(const std::string &kind, const std::string &name)
Adds object into application list List used when objects must be destroyed or application start/stop ...
static const char * PortArg()
Definition: Manager.h:182
Represents command with its arguments.
Definition: Command.h:99
bool SetStr(const std::string &name, const char *value)
Definition: Command.h:134
bool SetInt(const std::string &name, int v)
Definition: Command.h:138
Interface for implementing any kind of data input.
Definition: DataIO.h:61
Interface for implementing any kind of data output.
Definition: DataIO.h:158
Small helper class to correctly instantiate user-specific factories.
Definition: Factory.h:106
virtual Module * CreateTransport(const Reference &port, const std::string &typ, Command cmd)
Factory method to create transport.
Definition: Factory.cxx:61
virtual Module * CreateModule(const std::string &classname, const std::string &modulename, Command cmd)
Factory method to create module.
Definition: Factory.h:67
virtual Reference CreateObject(const std::string &classname, const std::string &objname, Command cmd)
Factory method to create object.
Definition: Factory.h:58
static int ConnectPorts(Reference port1ref, Reference port2ref, Command cmd=nullptr)
ApplicationRef app()
Definition: Manager.cxx:2074
ModuleRef FindModule(const std::string &name)
Definition: Manager.cxx:2018
WorkerRef GetModule() const
Definition: ModuleItem.cxx:66
unsigned ItemSubId() const
Definition: ModuleItem.h:123
Reference on dabc::Module class
Definition: Module.h:275
PortRef FindPort(const std::string &name)
Return reference on the port.
Definition: Module.cxx:1031
Base for dabc::ModuleSync and dabc::ModuleAsync classes.
Definition: Module.h:42
Reference on the dabc::Port class
Definition: Port.h:195
bool IsInput() const
Returns true if it is input port.
Definition: Port.h:199
uint64_t AsUInt(uint64_t dflt=0) const
Definition: Record.cxx:525
Reference on the arbitrary object
Definition: Reference.h:73
const char * GetName() const
Return name of referenced object, if object not assigned, returns "---".
Definition: Reference.cxx:167
std::string ItemName(bool compact=true) const
Produce string, which can be used as name argument in dabc::mgr.FindItem(name) call.
Definition: Reference.cxx:241
Uniform Resource Locator interpreter.
Definition: Url.h:33
RecordField Cfg(const std::string &name, Command cmd=nullptr) const
Returns configuration record of specified name.
Definition: Worker.h:482
bool Execute(Command cmd, double tmout=-1.)
Definition: Worker.cxx:1147
Master monitor for BNet components.
Factory for HADAQ classes
Definition: Factory.h:29
dabc::DataInput * CreateDataInput(const std::string &typ) override
Factory method to create data input.
Definition: Factory.cxx:43
dabc::DataOutput * CreateDataOutput(const std::string &typ) override
Factory method to create data output.
Definition: Factory.cxx:55
dabc::Module * CreateModule(const std::string &classname, const std::string &modulename, dabc::Command cmd) override
Factory method to create module.
Definition: Factory.cxx:171
dabc::Module * CreateTransport(const dabc::Reference &port, const std::string &typ, dabc::Command cmd) override
Factory method to create transport.
Definition: Factory.cxx:66
dabc::Reference CreateObject(const std::string &classname, const std::string &objname, dabc::Command cmd) override
Factory method to create object.
Definition: Factory.cxx:34
Implementation of file input for HLD files.
Definition: HldInput.h:31
Implementation of file output for HLD files.
Definition: HldOutput.h:31
Monitor of TRB slow control data.
Definition: MonitorModule.h:32
static int OpenUdp(const std::string &host, int nport, int rcvbuflen)
Sorts HADAQ subevents according to trigger number.
Definition: SorterModule.h:38
Terminal for HADAQ event builder.
#define DOUT0(args ...)
Definition: logging.h:156
#define EOUT(args ...)
Definition: logging.h:150
#define DOUT1(args ...)
Definition: logging.h:162
const char * xmlNumOutputs
Definition: Object.cxx:55
ManagerRef mgr
Definition: Manager.cxx:42
std::string format(const char *fmt,...)
Definition: string.cxx:49
const char * xml_flush
Definition: Object.cxx:75
const char * xmlNumInputs
Definition: Object.cxx:54
const char * xmlHadaqTrignumRange
dabc::FactoryPlugin hadaqfactory(new hadaq::Factory("hadaq"))