20 #include "../externals/zofits.h" 22 namespace ba = boost::asio;
23 namespace bs = boost::system;
56 Out() << endl <<
kBold <<
"Header received (N=" << dec << fCounter <<
"):" << endl;
57 Out() << fEventHeader;
59 Out() << Converter::GetHex<uint16_t>(fEventHeader, 16) << endl;
68 Out() <<
"ROI|" << fEventHeader.Crate() <<
":" << fEventHeader.Board() <<
":" << c <<
":";
70 Out() <<
" " << setw(4) << fChannelHeader[c+ch*
FAD::kNumChips].fRegionOfInterest;
74 Out() <<
"CEL|" << fEventHeader.Crate() <<
":" <<fEventHeader.Board() <<
": ";
80 Out() <<
" " << setw(4) << fChannelHeader[c+ch*
FAD::kNumChips].fStartCell;
88 if (cel!=fChannelHeader[c+ch*FAD::kNumChips].
fStartCell)
99 Out() << Converter::GetHex<uint16_t>(fChannelHeader, 16) << endl;
118 PrintChannelHeaders();
125 if (fIsVerbose && fIsDataOutput)
126 Out() << Converter::GetHex<uint16_t>(
data, sz, 16,
true) << endl;
139 if (bytes_received==0 || err)
141 if (err==ba::error::eof)
142 Warn(
"Connection to "+URL()+
" closed by remote host (FAD).");
146 if (err && err!=ba::error::eof &&
147 err!=ba::error::basic_errors::not_connected &&
148 err!=ba::error::basic_errors::operation_aborted)
151 str <<
"Reading from " << URL() <<
": " << err.message() <<
" (" << err <<
")";
159 if (type==kReadHeader)
161 if (bytes_received!=
sizeof(FAD::EventHeader))
164 str <<
"Bytes received (" << bytes_received <<
" don't match header size " <<
sizeof(FAD::EventHeader);
170 fEventHeader = fBuffer;
175 str <<
"Invalid header received: start delimiter wrong, received ";
189 fBuffer.resize(fEventHeader.fPackageLength-
sizeof(FAD::EventHeader)/2);
201 str <<
"Invalid data received: end delimiter wrong, received ";
208 uint8_t *ptr =
reinterpret_cast<uint8_t*
>(fBuffer.data());
209 uint8_t *
end = ptr + fBuffer.size()*2;
212 if (ptr+
sizeof(FAD::ChannelHeader) > end)
214 Error(
"Channel header exceeds buffer size.");
219 fChannelHeader[
i] = vector<uint16_t>((uint16_t*)ptr, (uint16_t*)ptr+
sizeof(FAD::ChannelHeader)/2);
220 ptr +=
sizeof(FAD::ChannelHeader);
226 Error(
"Data block exceeds buffer size.");
231 const uint16_t *
data =
reinterpret_cast<uint16_t*
>(ptr);
233 ptr += fChannelHeader[
i].fRegionOfInterest*2;
237 UpdateChannelHeaders();
241 fBuffer.resize(
sizeof(FAD::EventHeader)/2);
247 if (error==ba::error::basic_errors::operation_aborted)
253 str <<
"Read timeout of " << URL() <<
": " << error.message() <<
" (" << error <<
")";
272 if (fInTimeout.expires_at() > ba::deadline_timer::traits_type::now())
275 Error(
"Timeout reading data from "+URL());
282 fBufEventHeader.clear();
283 fBufEventHeader.fEventCounter = 1;
284 fBufEventHeader.fStatus = 0xf000|
285 FAD::EventHeader::kDenable|
286 FAD::EventHeader::kDwrite|
287 FAD::EventHeader::kDcmLocked|
288 FAD::EventHeader::kDcmReady|
289 FAD::EventHeader::kSpiSclk;
291 fEventHeader.clear();
293 fChannelHeader[
i].
clear();
297 fBuffer.resize(
sizeof(FAD::EventHeader)/2);
310 if (fBlockTransmission || !IsConnected())
315 msg <<
"Sending command:" << hex;
316 msg <<
" 0x" << setw(4) << setfill(
'0') << cmd[0];
317 msg <<
" (+ " << cmd.size()-1 <<
" bytes data)";
320 transform(cmd.begin(), cmd.end(), cmd.begin(), htons);
327 if (fBlockTransmission || !IsConnected())
332 msg <<
"Sending command:" << hex;
333 msg <<
" 0x" << setw(4) << setfill(
'0') << cmd;
337 PostMessage(&cmd,
sizeof(uint16_t));
342 if (fBlockTransmission || !IsConnected())
347 msg <<
"Sending command:" << hex;
348 msg <<
" 0x" << setw(4) << setfill(
'0') << cmd;
349 msg <<
" 0x" << setw(4) << setfill(
'0') <<
data;
352 const uint16_t d[2] = { htons(cmd), htons(data) };
353 PostMessage(d,
sizeof(d));
359 fIsVerbose(false), fIsHexOutput(false), fIsDataOutput(false),
360 fBlockTransmission(false), fCounter(0),
375 case FAD::kCmdDrsEnable: fBufEventHeader.Enable(FAD::EventHeader::kDenable, on);
break;
376 case FAD::kCmdDwrite: fBufEventHeader.Enable(FAD::EventHeader::kDwrite, on);
break;
378 case FAD::kCmdBusyOn: fBufEventHeader.Enable(FAD::EventHeader::kBusyOn, on);
break;
379 case FAD::kCmdBusyOff: fBufEventHeader.Enable(FAD::EventHeader::kBusyOff, on);
break;
381 case FAD::kCmdSocket: fBufEventHeader.Enable(FAD::EventHeader::kSock17, !on);
break;
386 PostCmd(cmd + (on ? 0 : 0x100));
402 if (val<0 || val>0xffff)
405 fBufEventHeader.fTriggerGeneratorPrescaler = val;
414 fBufEventHeader.fRunNumber = num;
435 fBufEventHeader.fDac[
i] = val;
445 fBufEventHeader.fDac[addr] = val;
471 fTargetRoi[addr] = val;
497 fBlockTransmission = b;
502 return fBlockTransmission;
510 PrintChannelHeaders();
513 Out() <<
"No event received yet." << endl;
527 return fEventHeader==fBufEventHeader;
532 return HasCorrectRoi() && HasCorrectHeader();
537 Out() <<
"================================================================================" << endl;
538 fEventHeader.print(Out());
539 Out() <<
"--------------------------------------------------------------------------------" << endl;
540 fBufEventHeader.print(Out());
541 Out() <<
"================================================================================" << endl;
568 msg << name <<
" - Received event has " << has <<
" bytes, but expected " << size <<
".";
575 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
576 i->second->Cmd(command);
578 return T::GetCurrentState();
583 if (!CheckEventSize(evt.
GetSize(),
"SendCmd", 4))
584 return T::kSM_FatalError;
588 T::Warn(
"Command value out of range (0-65535).");
589 return T::GetCurrentState();
592 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
595 return T::GetCurrentState();
600 if (!CheckEventSize(evt.
GetSize(),
"SendCmdData", 8))
601 return T::kSM_FatalError;
603 const uint32_t *ptr = evt.
Ptr<uint32_t>();
607 T::Warn(
"Command value out of range (0-65535).");
608 return T::GetCurrentState();
613 T::Warn(
"Data value out of range (0-65535).");
614 return T::GetCurrentState();
617 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
618 i->second->PostCmd(ptr[0], ptr[1]);
620 return T::GetCurrentState();
625 if (!CheckEventSize(evt.
GetSize(),
"CmdEnable", 1))
626 return T::kSM_FatalError;
628 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
629 i->second->Cmd(command, evt.
GetBool());
631 return T::GetCurrentState();
634 bool Check(
const uint32_t *dat, uint32_t maxaddr, uint32_t maxval)
639 msg << hex <<
"Address " << dat[0] <<
" out of range, max=" << maxaddr <<
".";
647 msg << hex <<
"Value " << dat[1] <<
" out of range, max=" << maxval <<
".";
657 if (!CheckEventSize(evt.
GetSize(),
"SetRegister", 8))
658 return T::kSM_FatalError;
660 const uint32_t *dat = evt.
Ptr<uint32_t>();
663 return T::GetCurrentState();
665 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
666 i->second->CmdSetRegister(dat[0], dat[1]);
668 return T::GetCurrentState();
673 if (!CheckEventSize(evt.
GetSize(),
"SetRoi", 8))
674 return T::kSM_FatalError;
676 const int32_t *dat = evt.
Ptr<int32_t>();
678 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
679 if (!
i->second->CmdSetRoi(dat[0], dat[1]))
682 msg << hex <<
"Channel " << dat[0] <<
" or Value " << dat[1] <<
" out of range.";
684 return T::GetCurrentState();
688 return T::GetCurrentState();
693 if (!CheckEventSize(evt.
GetSize(),
"SetDac", 8))
694 return T::kSM_FatalError;
696 const int32_t *dat = evt.
Ptr<int32_t>();
698 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
699 if (!
i->second->CmdSetDacValue(dat[0], dat[1]))
702 msg << hex <<
"Channel " << dat[0] <<
" or Value " << dat[1] <<
" out of range.";
704 return T::GetCurrentState();
707 return T::GetCurrentState();
712 for (
int nn=0; nn<n; nn++)
713 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
716 return T::GetCurrentState();
721 if (!CheckEventSize(evt.
GetSize(),
"SendTriggers", 4))
722 return T::kSM_FatalError;
726 return T::GetCurrentState();
742 if (!CheckEventSize(evt.
GetSize(),
"PhaseShift", 2))
743 return T::kSM_FatalError;
745 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
746 i->second->CmdPhaseShift(evt.
GetShort());
748 return T::GetCurrentState();
753 if (!CheckEventSize(evt.
GetSize(),
"SetTriggerRate", 4))
754 return T::kSM_FatalError;
759 msg << hex <<
"Value " << evt.
GetUShort() <<
" out of range, max=" << 0xffff <<
"(?)";
761 return T::GetCurrentState();
764 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
765 i->second->CmdSetTriggerRate(evt.
GetUInt());
767 return T::GetCurrentState();
772 if (!CheckEventSize(evt.
GetSize(),
"SetRunNumber", 8))
773 return T::kSM_FatalError;
775 const uint64_t num = evt.
GetUXtra();
780 msg <<
"Run number " << num <<
" out of range [1;" << FAD::kMaxRunNumber <<
"]";
782 return T::GetCurrentState();
785 if (!IncreaseRunNumber(num))
786 return T::GetCurrentState();
788 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
789 i->second->CmdSetRunNumber(GetRunNumber());
791 return T::GetCurrentState();
796 if (!CheckEventSize(evt.
GetSize(),
"SetMaxMemoryBuffer", 2))
797 return T::kSM_FatalError;
804 msg << hex <<
"Value " << mem <<
" out of range.";
806 return T::GetCurrentState();
811 return T::GetCurrentState();
816 if (!CheckEventSize(evt.
GetSize(),
"SetEventTimeoutSec", 2))
817 return T::kSM_FatalError;
824 msg << hex <<
"Value " << sec <<
" out of range.";
826 return T::GetCurrentState();
829 SetEventTimeout(sec);
831 return T::GetCurrentState();
836 if (!CheckEventSize(evt.
GetSize(),
"SetFileFormat", 2))
837 return T::kSM_FatalError;
856 return T::GetCurrentState();
859 return T::GetCurrentState();
865 return T::GetCurrentState();
871 return T::GetCurrentState();
877 return T::GetCurrentState();
894 if (!CheckEventSize(evt.
GetSize(),
"SetVerbosity", 1))
895 return T::kSM_FatalError;
897 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
898 i->second->SetVerbose(evt.
GetBool());
900 return T::GetCurrentState();
905 if (!CheckEventSize(evt.
GetSize(),
"SetHexOutput", 1))
906 return T::kSM_FatalError;
908 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
909 i->second->SetHexOutput(evt.
GetBool());
911 return T::GetCurrentState();
916 if (!CheckEventSize(evt.
GetSize(),
"SetDataOutput", 1))
917 return T::kSM_FatalError;
919 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
920 i->second->SetDataOutput(evt.
GetBool());
922 return T::GetCurrentState();
927 if (!CheckEventSize(evt.
GetSize(),
"SetDebugTx", 1))
928 return T::kSM_FatalError;
930 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
931 i->second->SetDebugTx(evt.
GetBool());
933 return T::GetCurrentState();
936 const BoardList::iterator
GetSlot(uint16_t slot)
938 const BoardList::iterator it=fBoards.find(slot);
939 if (it==fBoards.end())
942 str <<
"Slot " << slot <<
" not found.";
951 if (!CheckEventSize(evt.
GetSize(),
"PrintEvent", 2))
952 return T::kSM_FatalError;
954 const int16_t slot = evt.
Get<int16_t>();
958 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
959 i->second->PrintEvent();
963 const BoardList::iterator it=GetSlot(slot);
964 if (it!=fBoards.end())
965 it->second->PrintEvent();
968 return T::GetCurrentState();
973 if (!CheckEventSize(evt.
GetSize(),
"SetBlockTransmission", 3))
974 return T::kSM_FatalError;
976 const int16_t slot = evt.
Get<int32_t>();
978 const BoardList::iterator it=GetSlot(slot);
979 if (it!=fBoards.end())
980 it->second->SetBlockTransmission(evt.
Get<uint8_t>(2));
982 return T::GetCurrentState();
987 if (!CheckEventSize(evt.
GetSize(),
"SetBlockTransmissionRange", 5))
988 return T::kSM_FatalError;
990 const int16_t *slot = evt.
Ptr<int16_t>();
991 const bool block = evt.
Get<uint8_t>(4);
993 for (
int i=slot[0];
i<=slot[1];
i++)
995 const BoardList::iterator it=GetSlot(
i);
996 if (it!=fBoards.end())
997 it->second->SetBlockTransmission(block);
1000 return T::GetCurrentState();
1005 if (!CheckEventSize(evt.
GetSize(),
"SetIgnoreSlot", 3))
1006 return T::kSM_FatalError;
1008 const uint16_t slot = evt.
Get<uint16_t>();
1012 T::Warn(
"Slot out of range (0-39).");
1013 return T::GetCurrentState();
1016 SetIgnore(slot, evt.
Get<uint8_t>(2));
1018 return T::GetCurrentState();
1023 if (!CheckEventSize(evt.
GetSize(),
"SetIgnoreSlots", 5))
1024 return T::kSM_FatalError;
1026 const int16_t *slot = evt.
Ptr<int16_t>();
1027 const bool block = evt.
Get<uint8_t>(4);
1029 if (slot[0]<0 || slot[1]>39 || slot[0]>slot[1])
1031 T::Warn(
"Slot out of range.");
1032 return T::GetCurrentState();
1035 for (
int i=slot[0];
i<=slot[1];
i++)
1036 SetIgnore(
i, block);
1038 return T::GetCurrentState();
1043 const string name = evt.
Ptr<
char>(16);
1045 fTargetConfig = fConfigs.find(name);
1046 if (fTargetConfig==fConfigs.end())
1048 T::Error(
"StartConfigure - Run-type '"+name+
"' not found.");
1049 return T::GetCurrentState();
1053 const uint32_t runno = StartNewRun(evt.
Get<int64_t>(), evt.
Get<int64_t>(8), *fTargetConfig);
1058 str <<
"Starting configuration for run " << runno <<
" (" << name <<
")";
1059 T::Message(str.str());
1062 T::Warn(
"Run number exceeds logical maximum of 999 - this is no problem for writing but might give raise to problems in the analysis.");
1064 const FAD::Configuration &conf = fTargetConfig->second;
1066 for (BoardList::iterator it=fBoards.begin(); it!=fBoards.end(); it++)
1084 fad.
CmdSetRoi(
i*FAD::kNumChannelsPerChip+j, conf.fRoi[j]);
1097 const int64_t runs[2] = { runno, runno+1 };
1098 fDimStartRun.Update(runs);
1105 const int64_t runs[2] = { -1, GetRunNumber() };
1106 fDimStartRun.Update(runs);
1113 if (runid==GetRunNumber()-1)
1121 const tcp::endpoint endpoint = GetEndpoint(addr);
1122 if (endpoint==tcp::endpoint())
1123 return T::GetCurrentState();
1125 for (BoardList::const_iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
1127 if (
i->second->GetEndpoint()==endpoint)
1129 T::Warn(
"Address "+addr+
" already known.... ignored.");
1130 return T::GetCurrentState();
1134 AddEndpoint(endpoint);
1136 return T::GetCurrentState();
1141 if (!CheckEventSize(evt.
GetSize(),
"RemoveSlot", 2))
1142 return T::kSM_FatalError;
1144 const int16_t slot = evt.
GetShort();
1146 const BoardList::iterator it = GetSlot(slot);
1148 if (it==fBoards.end())
1149 return T::GetCurrentState();
1151 ConnectSlot(slot, tcp::endpoint());
1156 return T::GetCurrentState();
1161 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
1163 const int &idx =
i->first;
1167 str <<
"Slot " << setw(2) << idx <<
": " << fad->
GetEndpoint();
1170 str <<
" (0:connecting, ";
1174 str <<
" (0:disconnected, ";
1176 str <<
" (0:connected, ";
1179 switch (fStatus2[idx])
1181 case 0: str <<
"1:disconnected)";
break;
1182 case 8: str <<
"1:connected)";
break;
1183 default: str <<
"1:connecting)";
break;
1187 str <<
" [cmd_blocked]";
1189 if (fStatus2[idx]==8 && IsIgnored(idx))
1190 str <<
" [data_ignored]";
1193 str <<
" [configured]";
1195 T::Out() << str.str() << endl;
1198 T::Out() <<
"Event builder thread:";
1199 if (!IsThreadRunning())
1201 T::Out() <<
" running" << endl;
1205 return T::GetCurrentState();
1221 T::Warn(
"Connection to "+str.str()+
" already in progress.");
1230 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
1231 EnableConnection(
i->second, enable);
1237 return T::GetCurrentState();
1242 if (!CheckEventSize(evt.
GetSize(),
"EnableSlot", 2))
1243 return T::kSM_FatalError;
1245 const int16_t slot = evt.
GetShort();
1247 const BoardList::iterator it = GetSlot(slot);
1248 if (it==fBoards.end())
1249 return T::GetCurrentState();
1251 EnableConnection(it->second, enable);
1252 ConnectSlot(it->first, enable ? it->second->GetEndpoint() : tcp::endpoint());
1254 return T::GetCurrentState();
1259 if (!CheckEventSize(evt.
GetSize(),
"ToggleSlot", 2))
1260 return T::kSM_FatalError;
1262 const int16_t slot = evt.
GetShort();
1264 const BoardList::iterator it = GetSlot(slot);
1265 if (it==fBoards.end())
1266 return T::GetCurrentState();
1268 const bool enable = it->second->IsDisconnected();
1270 EnableConnection(it->second, enable);
1271 ConnectSlot(it->first, enable ? it->second->GetEndpoint() : tcp::endpoint());
1273 return T::GetCurrentState();
1278 vector<tcp::endpoint> addr(40);
1280 for (BoardList::iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
1281 addr[
i->first] =
i->second->GetEndpoint();
1286 return T::GetCurrentState();
1293 return T::GetCurrentState();
1300 return T::GetCurrentState();
1306 return T::GetCurrentState();
1313 if (!CheckEventSize(evt.
GetSize(),
"SetupZFits", 2))
1314 return T::kSM_FatalError;
1317 return T::GetCurrentState();
1403 uint16_t nclosed1 = 0;
1404 uint16_t nconnecting1 = 0;
1405 uint16_t nconnecting2 = 0;
1406 uint16_t nconnected1 = 0;
1407 uint16_t nconnected2 = 0;
1408 uint16_t nconfigured = 0;
1410 vector<uint8_t> stat1(40);
1411 vector<uint8_t> stat2(40);
1415 const bool runs = IsThreadRunning();
1417 for (
int idx=0; idx<40; idx++)
1420 const BoardList::const_iterator &slot = fBoards.find(idx);
1421 if (slot!=fBoards.end())
1457 if (IsConnecting(idx))
1463 if (IsConnected(idx))
1472 if (fStatus1!=stat1 || fStatus2!=stat2 || fStatusT!=runs)
1477 UpdateConnectionStatus(stat1, stat2, runs);
1520 if (nconnecting1==0 && nconnected1>0 && nconnected2==nconnected1)
1526 for (BoardList::iterator it=fBoards.begin(); it!=fBoards.end(); it++)
1527 if (!it->second->IsTxQueueEmpty())
1535 for (BoardList::iterator it=fBoards.begin(); it!=fBoards.end(); it++)
1547 if (nconfigured!=nconnected1)
1553 for (BoardList::iterator it=fBoards.begin(); it!=fBoards.end(); it++)
1563 if (fTargetConfig->second.fContinousTrigger)
1581 for (BoardList::iterator it=fBoards.begin(); it!=fBoards.end(); it++)
1582 if (!it->second->IsTxQueueEmpty())
1594 if (IsRunWaiting() && nconfigured==nconnected1)
1597 if (!IsRunWaiting())
1598 T::Message(
"Run successfully started... first data received.");
1599 if (nconfigured!=nconnected1)
1600 T::Message(
"Configuration of some boards changed.");
1607 if (nconnecting1>0 || nconnecting2>0 || nconnected1!=nconnected2)
1619 if (fBoards.find(i)==fBoards.end())
1626 T::Warn(
"Not more than 40 slots allowed.");
1647 vector<uint8_t> stat(41);
1649 for (
int i=0;
i<40;
i++)
1650 stat[
i] = stat1[
i]|(stat2[
i]<<3);
1654 fDimConnection.
Update(stat);
1661 fStatus1(40), fStatus2(40), fStatusT(false),
1662 fDimStartRun(
"FAD_CONTROL/START_RUN",
"X:1;X:1",
1664 "|run[idx]:Run no of last conf'd run (-1 if reset or none config'd yet)" 1665 "|next[idx]:Run number which will be assigned to next configuration"),
1666 fDimConnection(
"FAD_CONTROL/CONNECTIONS",
"C:40;C:1",
1667 "Connection status of FAD boards" 1668 "|status[bitpattern]:lower bits stat1, upper bits stat2, for every board. 40=thread" 1669 "|thread[bool]:true or false whether the event builder threads are running")
1675 T::AddStateName(FAD::State::kOffline,
"Disengaged",
1676 "All enabled FAD boards are disconnected and the event-builer thread is not running.");
1679 "All enabled FAD boards are disconnected, but the event-builder thread is running.");
1682 "Only some enabled FAD boards are connected.");
1685 "All enabled FAD boards are connected..");
1688 "Waiting 3 seconds for all FADs to be configured before requesting configuration.");
1691 "Waiting until all boards returned their configuration and they are valid.");
1694 "Waiting until 'enable trigger line' was sent to all boards.");
1697 "The configuration of all boards was successfully cross checked. Waiting for events with a new run number to receive.");
1699 T::AddStateName(FAD::State::kRunInProgress,
"RunInProgress",
1700 "Events currently received by the event builder will be flagged to be written, no end-of-run event occured yet.");
1705 (
"Send a command to the FADs. Values between 0 and 0xffff are allowed." 1706 "|command[uint16]:Command to be transmittted.");
1709 (
"Send a command with data to the FADs. Values between 0 and 0xffff are allowed." 1710 "|command[uint16]:Command to be transmittted." 1711 "|data[uint16]:Data to be sent with the command.");
1718 (
"Set BUSY continously low");
1721 (
"Set BUSY constantly high (has priority over BUSY_OFF)");
1727 (
"Switch Domino wave");
1730 (
"Set Dwrite (possibly high / always low)");
1733 (
"Enable continous (internal) trigger.");
1736 (
"Incoming triggers can be accepted/will not be accepted");
1739 (
"Set debug mode (yes: dump events through command socket, no=dump events through other sockets)");
1743 (
"Enable continous trigger");
1744 T::AddEvent(
"SEND_SINGLE_TRIGGER")
1746 (
"Issue software triggers");
1749 (
"Issue N software triggers (note that these are the triggers sent, not the triggers executed)" 1750 "|N[int]: Number of triggers to be sent to the board.");
1761 (
"Adjust ADC phase (in 'steps')" 1766 (
"Reset the FAD boards' event counter to 0.");
1770 (
"Sent a new run-number to the boards" 1771 "|num[int]:Run number");
1773 T::AddEvent(
"SET_MAX_MEMORY",
"S:1")
1775 (
"Set maximum memory buffer size allowed to be consumed by the EventBuilder to buffer events." 1776 "|memory[short]:Buffer size in Mega-bytes.");
1778 T::AddEvent(
"SET_EVENT_TIMEOUT",
"S:1")
1780 (
"Set the timeout after which an event expires which was not completely received yet." 1781 "|timeout[sec]:Timeout in seconds [1;32767]");
1785 (
"set register to value" 1786 "|addr[short]:Address of register" 1787 "|val[short]:Value to be set");
1792 (
"Set region-of-interest to value" 1793 "|channel[short]:Channel on each chip for which the ROI is set (0-8), -1 for all" 1794 "|val[short]:Value to be set");
1799 (
"Set DAC numbers in range to value" 1800 "|addr[short]:Address of register (-1 for all)" 1801 "|val[short]:Value to be set");
1805 (
"Configure a new run. If the internla trigger is enabled this might even start a new run." 1806 "|time_max[s]:Maximum time before the run is closed in seconds (0: unlimited)" 1807 "|num_max[int]:Maximum number of events before the run is closed in seconds (0: unlimited)" 1808 "|run_type[string]:Run type which describes the runs");
1812 (
"If configuration failed and the fadctrl is waiting for something, use this to reset the state.");
1815 T::AddEvent(
"SET_VERBOSE",
"B:1")
1817 (
"Set verbosity state" 1818 "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data");
1820 T::AddEvent(
"SET_HEX_OUTPUT",
"B:1")
1822 (
"Enable or disable hex output for received data" 1823 "|hexout[bool]:disable or enable hex output for received data (yes/no)");
1825 T::AddEvent(
"SET_DATA_OUTPUT",
"B:1")
1827 (
"Enable or disable printing of the received adc data to the console" 1828 "|dataout[bool]:disable or enable data output for received data (yes/no)");
1830 T::AddEvent(
"SET_DEBUG_TX",
"B:1")
1832 (
"Enable or disable the output of messages in case of successfull data transmission to the boards." 1833 "|debug[bool]:disable or enable debug output for transmitted data (yes/no)");
1835 T::AddEvent(
"PRINT_EVENT",
"S:1")
1837 (
"Print (last) event" 1838 "|board[short]:slot from which the event should be printed (-1 for all)");
1840 T::AddEvent(
"BLOCK_TRANSMISSION",
"S:1;B:1")
1842 (
"Blocks the transmission of commands to the given slot. Use with care! For debugging pupose only!" 1843 "|slot[short]:Slot to which the command transmission should be blocked (0-39)" 1844 "|enable[bool]:Whether the command transmission should be blockes (yes) or allowed (no)");
1846 T::AddEvent(
"BLOCK_TRANSMISSION_RANGE",
"S:2;B:1")
1848 (
"Blocks the transmission of commands to the given range of slots. Use with care! For debugging pupose only!" 1849 "|first[short]:First slot to which the command transmission should be blocked (0-39)" 1850 "|last[short]:Last slot to which the command transmission should be blocked (0-39)" 1851 "|enable[bool]:Whether the command transmission should be blockes (yes) or allowed (no)");
1853 T::AddEvent(
"IGNORE_EVENTS",
"S:1;B:1")
1855 (
"Instructs the event-builder to ignore events from the given slot but still read the data from the socket." 1856 "|slot[short]:Slot from which the data should be ignored when building events" 1857 "|enable[bool]:Whether the event builder should ignore data from this slot (yes) or allowed (no)");
1859 T::AddEvent(
"IGNORE_EVENTS_RANGE",
"S:2;B:1")
1861 (
"Instructs the event-builder to ignore events from the given slot but still read the data from the socket." 1862 "|first[short]:First slot from which the data should be ignored when building events" 1863 "|last[short]:Last slot from which the data should be ignored when building events" 1864 "|enable[bool]:Whether the event builder should ignore data from this slot (yes) or allowed (no)");
1868 (
"Close all run files opened by the EventBuilder.");
1877 T::AddEvent(
"START", FAD::State::kOffline)
1879 (
"Start EventBuilder thread and connect all valid slots.");
1883 (
"Stop EventBuilder thread (still write buffered events) and disconnect all slots.");
1887 (
"Immediately abort EventBuilder thread and disconnect all slots.");
1891 (
"Wait for buffers to drain, close all files and reinitialize event builder thread.");
1895 (
"Free all buffers, close all files and reinitialize event builder thread.");
1899 (
"Connect a disconnected slot.");
1903 (
"Disconnect a connected slot.");
1907 (
"Toggle the status of a slot.");
1909 T::AddEvent(
"SET_FILE_FORMAT",
"S:1")
1911 (
"Set the output file format (see FAD::FileFormat_t)");
1913 T::AddEvent(
"START_DRS_CALIBRATION")
1915 (
"Start a drs calibration (shortcut for SET_FILEFORMAT 4)");
1917 T::AddEvent(
"RESET_SECONDARY_DRS_BASELINE")
1919 (
"Reset the secondary drs baseline (e.g. to change roi)");
1921 T::AddEvent(
"LOAD_DRS_CALIBRATION",
"C")
1923 (
"Load a DRS calibration file" 1928 T::AddEvent(
"SET_ZFITS_DEFAULT_NUM_THREADS",
"S")
1930 (
"Set the number of compression threads to use (+1 for writing)" 1931 "|num[int]:Number of threads");
1932 T::AddEvent(
"SET_ZFITS_DEFAULT_MAX_MEMORY",
"S")
1934 (
"Set the maximum amount of memory zfits will use for compression" 1935 "|mem[int]:Memory in MB");
1936 T::AddEvent(
"SET_ZFITS_DEFAULT_NUM_TILES",
"S")
1938 (
"Set the number of tiles with which the catalog is initialized" 1939 "|num[int]:Number of tiles");
1940 T::AddEvent(
"SET_ZFITS_DEFAULT_ROWS_PER_TILE",
"S")
1942 (
"Set the number of rows which are compressed into one tile" 1943 "|num[int]:Number of rows per tile");
1946 T::AddEvent(
"ADD_ADDRESS",
"C", FAD::State::kOffline)
1948 (
"Add the address of a DRS4 board to the first free slot" 1949 "|IP[string]:address in the format <address:port>");
1950 T::AddEvent(
"REMOVE_SLOT",
"S:1", FAD::State::kOffline)
1952 (
"Remove the Iaddress in slot n. For a list see LIST" 1953 "|slot[short]:Remove the address in slot n from the list");
1954 T::AddEvent(
"LIST_SLOTS")
1956 (
"Print a list of all available board addressesa and whether they are enabled");
1961 for (BoardList::const_iterator
i=fBoards.begin();
i!=fBoards.end();
i++)
1968 const size_t p0 = base.find_first_of(
':');
1969 const size_t p1 = base.find_last_of(
':');
1971 if (p0==string::npos || p0!=p1)
1973 T::Out() <<
kRed <<
"GetEndpoint - Wrong format ('host:port' expected)" << endl;
1974 return tcp::endpoint();
1979 boost::system::error_code ec;
1981 const tcp::resolver::query query(base.substr(0, p0), base.substr(p0+1));
1982 const tcp::resolver::iterator iterator = resolver.resolve(query, ec);
1986 T::Out() <<
kRed <<
"GetEndpoint - Couldn't resolve endpoint '" << base <<
"': " << ec.message();
1987 return tcp::endpoint();
2001 if (!conf.
HasDef(name, sub))
2003 T::Error(
"Neither "+name+
"default nor "+name+sub+
" found.");
2007 const V val = conf.
GetDef<V>(name, sub);
2013 str << name << sub <<
"=" << val <<
" exceeds allowed maximum of " << max <<
"!";
2022 fIsVerbose = !conf.
Get<
bool>(
"quiet");
2023 fIsHexOutput = conf.
Get<
bool>(
"hex-out");
2024 fIsDataOutput = conf.
Get<
bool>(
"data-out");
2025 fDebugTx = conf.
Get<
bool>(
"debug-tx");
2028 if (conf.
Has(
"zfits.num-threads"))
2030 if (conf.
Has(
"zfits.max-mem"))
2032 if (conf.
Has(
"zfits.num-tiles"))
2034 if (conf.
Has(
"zfits.num-rows"))
2038 SetMaxMemory(conf.
Get<
unsigned int>(
"max-mem"));
2039 SetEventTimeout(conf.
Get<uint16_t>(
"event-timeout"));
2041 if (!InitRunNumber(conf.
Get<
string>(
"destination-folder")))
2045 const vector<string> types = conf.
Vec<
string>(
"run-type");
2046 if (types.size()==0)
2047 T::Warn(
"No run-types defined.");
2049 T::Message(
"Defining run-types");
2050 for (vector<string>::const_iterator it=types.begin();
2051 it!=types.end(); it++)
2053 T::Message(
" -> "+ *it);
2055 if (fConfigs.count(*it)>0)
2057 T::Error(
"Run-type "+*it+
" defined twice.");
2061 FAD::Configuration target;
2063 if (!CheckConfigVal<bool>(conf,
true,
"enable-drs.", *it) ||
2064 !CheckConfigVal<bool>(conf,
true,
"enable-dwrite.", *it) ||
2065 !CheckConfigVal<bool>(conf,
true,
"enable-continous-trigger.", *it))
2068 target.fDenable = conf.
GetDef<
bool>(
"enable-drs.", *it);
2069 target.fDwrite = conf.
GetDef<
bool>(
"enable-dwrite.", *it);
2070 target.fContinousTrigger = conf.
GetDef<
bool>(
"enable-continous-trigger.", *it);
2072 target.fTriggerRate = 0;
2075 if (!CheckConfigVal<uint16_t>(conf, 0xffff,
"trigger-rate.", *it))
2078 target.fTriggerRate = conf.
GetDef<uint16_t>(
"trigger-rate.", *it);
2084 str <<
"roi-ch" <<
i <<
'.';
2090 target.fRoi[
i] = conf.HasDef(str.str(), *it) ?
2091 conf.GetDef<uint16_t>(str.str(), *it) :
2092 conf.GetDef<uint16_t>(
"roi.", *it);
2098 str <<
"dac-" <<
i <<
'.';
2104 target.fDac[
i] = conf.HasDef(str.str(), *it) ?
2105 conf.GetDef<uint16_t>(str.str(), *it) :
2106 conf.GetDef<uint16_t>(
"dac.", *it);
2109 fConfigs[*it] = target;
2116 if (conf.
Has(
"debug-addr"))
2118 const string addr = conf.
Get<
string>(
"debug-addr");
2119 const int num = conf.
Get<
unsigned int>(
"debug-num");
2121 const tcp::endpoint endpoint = GetEndpoint(addr);
2122 if (endpoint==tcp::endpoint())
2125 for (
int i=0;
i<num;
i++)
2126 AddEndpoint(tcp::endpoint(endpoint.address(), endpoint.port()+8*
i));
2128 if (conf.
Get<
bool>(
"start"))
2135 if (conf.
Has(
"base-addr"))
2137 string base = conf.
Get<
string>(
"base-addr");
2139 if (base==
"def" || base ==
"default")
2140 base =
"10.0.128.128:31919";
2142 const tcp::endpoint endpoint = GetEndpoint(base);
2143 if (endpoint==tcp::endpoint())
2146 const ba::ip::address_v4::bytes_type ip = endpoint.address().to_v4().to_bytes();
2148 if (ip[2]>250 || ip[3]>244)
2150 T::Out() <<
kRed <<
"EvalConfiguration - IP address given by --base-addr out-of-range." << endl;
2154 for (
int crate=0; crate<4; crate++)
2155 for (
int board=0; board<10; board++)
2157 ba::ip::address_v4::bytes_type target = endpoint.address().to_v4().to_bytes();
2161 AddEndpoint(tcp::endpoint(ba::ip::address_v4(target), endpoint.port()));
2164 if (conf.
Get<
bool>(
"start"))
2172 if (conf.
Has(
"addr"))
2174 const vector<string> addrs = conf.
Vec<
string>(
"addr");
2175 for (vector<string>::const_iterator
i=addrs.begin();
i<addrs.end();
i++)
2177 const tcp::endpoint endpoint = GetEndpoint(*
i);
2178 if (endpoint==tcp::endpoint())
2181 AddEndpoint(endpoint);
2184 if (conf.
Get<
bool>(
"start"))
2197 template<
class T,
class S>
2200 return Main::execute<T, StateMachineFAD<S>>(conf);
2205 po::options_description control(
"FAD control options");
2206 control.add_options()
2207 (
"quiet,q",
po_bool(
true),
"Disable printing contents of all received messages in clear text.")
2208 (
"hex-out",
po_bool(),
"Enable printing contents of all printed messages also as hex data.")
2209 (
"data-out",
po_bool(),
"Enable printing received event data.")
2210 (
"debug-tx",
po_bool(),
"Enable debugging of ethernet transmission.")
2213 po::options_description connect(
"FAD connection options");
2214 connect.add_options()
2215 (
"addr", vars<string>(),
"Network address of FAD")
2216 (
"base-addr", var<string>(),
"Base address of all FAD")
2217 (
"debug-num,n", var<unsigned int>(40),
"Sets the number of fake boards to be connected locally")
2218 (
"debug-addr", var<string>(),
"")
2219 (
"start",
po_bool(
false),
"Start the connction immediately after boot")
2222 po::options_description builder(
"Event builder options");
2223 builder.add_options()
2224 (
"max-mem", var<unsigned int>(100),
"Maximum memory the event builder thread is allowed to consume for its event buffer")
2225 (
"event-timeout", var<uint16_t>(30),
"After how many seconds is an event considered to be timed out? (<=0: disabled)")
2226 (
"destination-folder", var<string>(
""),
"Destination folder (base folder) for the event builder binary data files.")
2229 po::options_description
zfits(
"FITS compression options");
2231 (
"zfits.num-threads", var<int32_t>(),
"Number of threads to spawn writing compressed FITS files")
2232 (
"zfits.max-mem", var<uint32_t>(),
"Maximum amount of memory to be allocated by FITS compression in MB")
2233 (
"zfits.num-tiles", var<uint32_t>(),
"Maximum number of tiles in the catalog")
2234 (
"zfits.num-rows", var<uint32_t>(),
"Maximum number of rows per tile")
2237 po::options_description runtype(
"Run type configuration");
2238 runtype.add_options()
2239 (
"run-type", vars<string>(),
"Run type, e.g. data, pedestal, drs-calibration, light-pulser")
2240 (
"enable-dwrite.*", var<bool>(),
"")
2241 (
"enable-drs.*", var<bool>(),
"")
2242 (
"enable-continous-trigger.*", var<bool>(),
"")
2243 (
"trigger-rate.*", var<uint16_t>(),
"")
2244 (
"dac.*", var<uint16_t>(),
"")
2245 (
"dac-0.*", var<uint16_t>(),
"")
2246 (
"dac-1.*", var<uint16_t>(),
"")
2247 (
"dac-2.*", var<uint16_t>(),
"")
2248 (
"dac-3.*", var<uint16_t>(),
"")
2249 (
"dac-4.*", var<uint16_t>(),
"")
2250 (
"dac-5.*", var<uint16_t>(),
"")
2251 (
"dac-6.*", var<uint16_t>(),
"")
2252 (
"dac-7.*", var<uint16_t>(),
"")
2253 (
"roi.*", var<uint16_t>(),
"")
2254 (
"roi-ch0.*", var<uint16_t>(),
"")
2255 (
"roi-ch1.*", var<uint16_t>(),
"")
2256 (
"roi-ch2.*", var<uint16_t>(),
"")
2257 (
"roi-ch3.*", var<uint16_t>(),
"")
2258 (
"roi-ch4.*", var<uint16_t>(),
"")
2259 (
"roi-ch5.*", var<uint16_t>(),
"")
2260 (
"roi-ch6.*", var<uint16_t>(),
"")
2261 (
"roi-ch7.*", var<uint16_t>(),
"")
2262 (
"roi-ch8.*", var<uint16_t>(),
"")
2265 conf.
AddEnv(
"dns",
"DIM_DNS_NODE");
2266 conf.
AddEnv(
"host",
"DIM_HOST_NODE");
2278 "The fadctrl controls the FAD boards.\n" 2280 "The default is that the program is started without user intercation. " 2281 "All actions are supposed to arrive as DimCommands. Using the -c " 2282 "option, a local shell can be initialized. With h or help a short " 2283 "help message about the usuage can be brought to the screen.\n" 2285 "Usage: fadctrl [-c type] [OPTIONS]\n" 2286 " or: fadctrl [OPTIONS]\n";
2292 Main::PrintHelp<StateMachineFAD<StateMachine>>();
2298 int main(
int argc,
const char* argv[])
2311 if (!conf.
Has(
"console"))
2316 return RunShell<LocalStream, StateMachineDim>(conf);
2329 if (conf.
Get<
int>(
"console")==0)
2330 return RunShell<LocalShell, StateMachineDim>(conf);
2332 return RunShell<LocalConsole, StateMachineDim>(conf);
void SetDebugTx(bool b=true)
int RunShell(Configuration &conf)
FAD::EventHeader fBufEventHeader
int StartDrsCalibration()
int SendTriggers(const EventImp &evt)
int SetDac(const EventImp &evt)
int SendCmd(const EventImp &evt)
vector< uint16_t > fTargetRoi
int SetMaxMemoryBuffer(const EventImp &evt)
void ConnectionEstablished()
virtual void UpdateChannelHeaders()
int main(int argc, const char *argv[])
bool Check(const uint32_t *dat, uint32_t maxaddr, uint32_t maxval)
void PostClose(bool restart=true)
bool HasCorrectHeader() const
A general base-class describing events issues in a state machine.
const char * GetText() const
void CmdSetRegister(uint8_t addr, uint16_t val)
bool IsDisconnected() const
map< string, FAD::Configuration > Configs
bool CmdSetRoi(uint16_t val)
void SetupConfiguration(Configuration &conf)
The base implementation of a distributed messaging system.
int SendCmdData(const EventImp &evt)
void PostCmd(uint16_t cmd, uint16_t data)
vector< uint8_t > fStatus1
virtual void UpdateFirstHeader()
int SetIgnoreSlots(const EventImp &evt)
void SetPrintUsage(const std::function< void(void)> &func)
T Get(const std::string &var)
int SetBlockTransmissionRange(const EventImp &evt)
void AddEndpoint(const tcp::endpoint &addr)
int ResetSecondaryDrsBaseline()
int SetDataOutput(const EventImp &evt)
void SetupConfiguration(Configuration &conf)
bool IsTransmissionBlocked() const
static uint32_t DefaultMaxMemory(const uint32_t &_n=0)
void AddEnv(const std::string &conf, const std::string &env)
std::vector< T > Vec(const std::string &var)
int CmdEnable(const EventImp &evt, FAD::Enable command)
void PostCmd(std::vector< uint16_t > cmd)
void CmdSetRunNumber(uint32_t num)
int ToggleSlot(const EventImp &evt)
bool IsConnecting() const
int SetHexOutput(const EventImp &evt)
static uint32_t DefaultMaxNumTiles(const uint32_t &_n=0)
void SetEndpoint(const std::string &addr, int port)
void debugHead(const FAD::EventHeader &h)
int SetIgnoreSlot(const EventImp &evt)
virtual int ResetSecondaryDrsBaseline()
void SetBlockTransmission(bool b)
uint16_t GetUShort() const
static uint32_t DefaultNumThreads(const uint32_t &_n=-2)
static setter for the default number of threads to use. -1 means all available physical cores ...
int Cmd(FAD::Enable command)
bool CmdSetTriggerRate(int32_t val)
virtual void StartConnect()
bool Has(const std::string &var)
T GetDef(const std::string &var, const S &val)
vector< uint16_t > fBuffer
int AddAddress(const EventImp &evt)
void AddOptions(const po::options_description &opt, bool visible=true)
bool CmdSetRoi(int8_t addr, uint16_t val)
int LoadDrsCalibration(const EventImp &evt)
void EnableAll(bool enable=true)
DimDescribedService fDimStartRun
int SetBlockTransmission(const EventImp &evt)
void PrintChannelHeaders()
int SetupZFits(const EventImp &evt, const std::function< void(int32_t)> &func)
int PrintEvent(const EventImp &evt)
int SetTriggerRate(const EventImp &evt)
int SetRunNumber(const EventImp &evt)
Commandline parsing, resource file parsing and database access.
void EnableConnection(ConnectionFAD *ptr, bool enable=true)
map< uint8_t, ConnectionFAD * > BoardList
ConnectionFAD(ba::io_service &ioservice, MessageImp &imp, uint16_t slot)
int SetRegister(const EventImp &evt)
const BoardList::iterator GetSlot(uint16_t slot)
int SetEventTimeoutSec(const EventImp &evt)
void CloseRun(uint32_t runid)
uint64_t GetUXtra() const
void SetDataOutput(bool b)
int SetVerbosity(const EventImp &evt)
static uint32_t DefaultNumRowsPerTile(const uint32_t &_n=0)
virtual void HandleReadTimeout(const boost::system::error_code &)
void LoadDrsCalibration(const char *fname)
const boost::asio::ip::tcp::endpoint & GetEndpoint() const
int SetFileFormat(const EventImp &evt)
DimDescribedService fDimConnection
bool CheckConfigVal(Configuration &conf, V max, const string &name, const string &sub)
Configs::const_iterator fTargetConfig
virtual void UpdateEventHeader()
int PhaseShift(const EventImp &evt)
vector< uint8_t > fStatus2
int RemoveSlot(const EventImp &evt)
void CmdPhaseShift(int16_t val)
void PostCmd(uint16_t cmd)
Connection(boost::asio::io_service &io_service, std::ostream &out)
static EventBuilderWrapper * This
po::typed_value< bool > * po_bool(bool def=false)
int EnableSlot(const EventImp &evt, bool enable)
void HandleReceivedData(const bs::error_code &err, size_t bytes_received, int type)
void UpdateConnectionStatus(const vector< uint8_t > &stat1, const vector< uint8_t > &stat2, bool thread)
void HandleReadTimeout(const bs::error_code &error)
void SetHexOutput(bool b)
T Get(size_t offset=0) const
const FAD::EventHeader & GetConfiguration() const
Maintains an ansynchronous TCP/IP client connection.
int SetRoi(const EventImp &evt)
bool HasDef(const std::string &var, const T &val)
StateMachineFAD(ostream &out=cout)
bool DoParse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
bool CheckEventSize(size_t has, const char *name, size_t size)
bool IsConfigured() const
tcp::endpoint GetEndpoint(const string &base)
FAD::EventHeader fEventHeader
virtual int CloseOpenFiles()
int SetDebugTx(const EventImp &evt)
const T * Ptr(size_t offset=0) const
virtual void UpdateData(const uint16_t *data, size_t sz)
int EvalOptions(Configuration &conf)
void Cmd(FAD::Enable cmd, bool on=true)
bool CmdSetDacValue(int8_t addr, uint16_t val)
int StartConfigure(const EventImp &evt)
virtual size_t GetSize() const
bool HasCorrectRoi() const