REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestRawMemoryBufferToSignalProcess.cxx
1 /*************************************************************************
2  * This file is part of the REST software framework. *
3  * *
4  * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5  * For more information see http://gifna.unizar.es/trex *
6  * *
7  * REST is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * REST is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have a copy of the GNU General Public License along with *
18  * REST in $REST_PATH/LICENSE. *
19  * If not, see http://www.gnu.org/licenses/. *
20  * For the list of contributors see $REST_PATH/CREDITS. *
21  *************************************************************************/
22 
108 #include "TRestRawMemoryBufferToSignalProcess.h"
109 
110 using namespace std;
111 
112 #include <sys/sem.h>
113 #include <sys/shm.h>
114 
115 #ifdef __APPLE__
116 #include <unistd.h>
117 #endif
118 
119 #if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)) || __APPLE__
120 // The union is already defined in sys/sem.h
121 #else
122 union semun {
123  int val;
124  struct semid_ds* buf;
125  unsigned short int* array;
126  struct seminfo* __buf;
127 };
128 #endif
129 
130 struct sembuf Operacion;
131 
133 
138 
152  Initialize();
153 
154  LoadConfig(configFilename);
155 }
156 
161 
167  Operacion.sem_num = 0; // sem_id
168  Operacion.sem_op = -1;
169  Operacion.sem_flg = 0;
170 
171  semop(id, &Operacion, 1);
172 }
173 
179  Operacion.sem_num = 0; // sem_id
180  Operacion.sem_op = 1;
181  Operacion.sem_flg = 0;
182 
183  semop(id, &Operacion, 1);
184 }
185 
190  SetName("sharedMemoryBufferToSignal-Default");
191  SetTitle("Default config");
192 
193  cout << "SharedMemoryBufferToSignal metadata not found. Loading default "
194  "values"
195  << endl;
196 }
197 
210 void TRestRawMemoryBufferToSignalProcess::LoadConfig(const string& configFilename, const string& name) {
211  if (LoadConfigFromFile(configFilename, name)) {
212  LoadDefaultConfig();
213  }
214 }
215 
221  SetSectionName(this->ClassName());
222  SetLibraryVersion(LIBRARY_VERSION);
223 
224  fOutputRawSignalEvent = new TRestRawSignalEvent();
225 
226  fReset = true;
227 }
228 
230  cout << "TRestRawMemoryBufferToSignalProcess::InitProcess. Creating "
231  "access to shared memory"
232  << endl;
233 
234  key_t MemKey = ftok("/bin/ls", fKeyDaqInfo);
235  int memId = shmget(MemKey, sizeof(daqInfo), 0777);
236  if (memId == -1) {
237  printf("Failed to access daqInfo resource\n");
238  exit(1);
239  }
240 
241  fShMem_daqInfo = (daqInfo*)shmat(memId, (char*)0, 0);
242 
243  key_t SemaphoreKey = ftok("/bin/ls", fKeySemaphore);
244  fSemaphoreId = semget(SemaphoreKey, 1, 0777);
245 
246  if (fSemaphoreId == -1) {
247  printf("Failed to access semaphore resource\n");
248  exit(1);
249  }
250 
251  if (GetVerboseLevel() >= TRestStringOutput::REST_Verbose_Level::REST_Debug) {
252  printf("Sem id : %d\n", fSemaphoreId);
253 
254  printf("Data ready : %d\n", fShMem_daqInfo->dataReady);
255 
256  printf("Number of signals : %d\n", fShMem_daqInfo->nSignals);
257 
258  printf("Timestamp : %lf\n", fShMem_daqInfo->timeStamp);
259 
260  printf("Event id : %d\n", fShMem_daqInfo->eventId);
261 
262  printf("Max signals : %d\n", fShMem_daqInfo->maxSignals);
263  printf("Max samples : %d\n", fShMem_daqInfo->maxSamples);
264  printf("Buffer size : %d\n", fShMem_daqInfo->bufferSize);
265 
267  }
268 
269  int N_DATA = fShMem_daqInfo->bufferSize;
270 
271  MemKey = ftok("/bin/ls", fKeyBuffer);
272  memId = shmget(MemKey, N_DATA * sizeof(unsigned short int), 0777 | IPC_CREAT);
273  if (memId == -1) {
274  printf("Failed to access buffer resource\n");
275  exit(1);
276  }
277 
278  fShMem_Buffer = (unsigned short int*)shmat(memId, (char*)0, 0);
279 }
280 
286  fOutputRawSignalEvent->Initialize();
287 }
288 
293  while (true) {
294  SemaphoreRed(fSemaphoreId);
295  int dataReady = fShMem_daqInfo->dataReady;
296  int maxSamples = fShMem_daqInfo->maxSamples;
297  SemaphoreGreen(fSemaphoreId);
298 
299  // We sleep a while to do not saturate/block the daq with the semaphore.
300  usleep(fTimeDelay);
301 
302  if (dataReady == 2) {
304  SemaphoreRed(fSemaphoreId);
305 
306  for (unsigned int s = 0; s < fShMem_daqInfo->nSignals; s++) {
307  TRestRawSignal signal;
308  signal.SetSignalID(fShMem_Buffer[s * (maxSamples + 1)]);
309 
310  if (GetVerboseLevel() >= TRestStringOutput::REST_Verbose_Level::REST_Debug)
311  cout << "s : " << s << " id : " << signal.GetSignalID() << endl;
312 
313  for (int n = 0; n < maxSamples; n++) {
314  signal.AddPoint((Short_t)fShMem_Buffer[s * (maxSamples + 1) + 1 + n]);
315  }
316  fOutputRawSignalEvent->AddSignal(signal);
317 
318  if (GetVerboseLevel() >= TRestStringOutput::REST_Verbose_Level::REST_Extreme) {
319  signal.Print();
320  GetChar();
321  }
322  }
323 
324  if (fReset) {
325  for (unsigned int n = 0; n < fShMem_daqInfo->bufferSize; n++) fShMem_Buffer[n] = 0;
326  }
327 
328  fShMem_daqInfo->dataReady = 0;
329 
330  fOutputRawSignalEvent->SetID(fShMem_daqInfo->eventId);
331  fOutputRawSignalEvent->SetTime(fShMem_daqInfo->timeStamp);
332 
333  SemaphoreGreen(fSemaphoreId);
335 
336  if (GetVerboseLevel() >= TRestStringOutput::REST_Verbose_Level::REST_Info) {
337  cout << "------------------------------------------" << endl;
338  cout << "Event ID : " << fOutputRawSignalEvent->GetID() << endl;
339  cout << "Time stamp : " << fOutputRawSignalEvent->GetTimeStamp() << endl;
340  cout << "Number of Signals : " << fOutputRawSignalEvent->GetNumberOfSignals() << endl;
341  cout << "------------------------------------------" << endl;
342 
343  if (GetVerboseLevel() >= TRestStringOutput::REST_Verbose_Level::REST_Debug) {
344  for (Int_t n = 0; n < fOutputRawSignalEvent->GetNumberOfSignals(); n++)
345  cout << "Signal N : " << n
346  << " daq id : " << fOutputRawSignalEvent->GetSignal(n)->GetID() << endl;
347  GetChar();
348  }
349  }
350 
351  if (fOutputRawSignalEvent->GetNumberOfSignals() == 0) return nullptr;
352 
353  return fOutputRawSignalEvent;
354  }
355  }
356 
357  return fOutputRawSignalEvent;
358 }
359 
365  fKeyDaqInfo = StringToInteger(GetParameter("daqInfoKey", "3"));
366  fKeyBuffer = StringToInteger(GetParameter("bufferKey", "13"));
367  fKeySemaphore = StringToInteger(GetParameter("semaphoreKey", "14"));
368  fTimeDelay = StringToInteger(GetParameter("timeDelay", "10000"));
369 }
A base class for any REST event.
Definition: TRestEvent.h:38
void SemaphoreRed(int id)
This method will increase the semaphore red level to protect shared memory regions.
void Initialize() override
Function to initialize input/output event members and define the section name.
void LoadDefaultConfig()
Function to load the default config in absence of RML input.
void BeginOfEventProcess(TRestEvent *inputEvent=nullptr) override
Function including required initialization before each event starts to process.
void InitFromConfigFile() override
Function reading input parameters from the RML TRestRawMemoryBufferToSignalProcess metadata section.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
The main processing event function.
void LoadConfig(const std::string &configFilename, const std::string &name="")
Function to load the configuration from an external configuration file.
void SemaphoreGreen(int id)
This method will increase the semaphore green level to release shared memory regions.
void InitProcess() override
To be executed at the beginning of the run (outside event loop)
An event container for time rawdata signals with fixed length.
It defines a Short_t array with a physical parameter that evolves in time using a fixed time bin.
void Print() const
It prints the signal data on screen.
void SetSignalID(Int_t sID)
It sets the id number of the signal.
void AddPoint(Short_t)
Adds a new point to the end of the signal data array.
Int_t GetSignalID() const
Returns the value of signal ID.
@ REST_Info
+show most of the information for each steps
@ REST_Debug
+show the defined debug messages
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.
Int_t StringToInteger(std::string in)
Gets an integer from a string.