SlsDetectorCamera.h 9.88 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2011
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//###########################################################################

23
24
#ifndef __SLS_DETECTOR_CAMERA_H
#define __SLS_DETECTOR_CAMERA_H
25

26
#include "SlsDetectorArgs.h"
27
#include "SlsDetectorReceiver.h"
28
#include "SlsDetectorCPUAffinity.h"
29

30
#include "sls/Detector.h"
31

32
#include "lima/HwBufferMgr.h"
33
#include "lima/HwMaxImageSizeCallback.h"
34
#include "lima/Event.h"
35

36
#include <queue>
37
38
39
40
41
42
43

namespace lima 
{

namespace SlsDetector
{

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
enum BufferType {
	AcqBuffer, LimaBuffer
};

class BufferCtrlObj : public NumaSoftBufferCtrlObj {

 public:
	BufferCtrlObj() : m_type(AcqBuffer) {}

	void releaseBuffers() { getBuffer().releaseBuffers(); }

	void setType(BufferType type)
	{
		if (type == m_type)
			return;
		releaseBuffers();
		m_type = type;
	}

	virtual void getMaxNbBuffers(int& max_nb_buffers)
	{
		if (m_type == LimaBuffer)
			max_nb_buffers = 1024;
		else
			NumaSoftBufferCtrlObj::getMaxNbBuffers(max_nb_buffers);
	}

	Data getFrameData(FrameType frame)
	{
		Data d;
		StdBufferCbMgr& buffer = getBuffer();
		const FrameDim& frame_dim = buffer.getFrameDim();
		switch (frame_dim.getImageType()) {
		case Bpp8:  d.type = Data::UINT8;  break;
		case Bpp16: d.type = Data::UINT16; break;
		case Bpp32: d.type = Data::UINT32; break;
		default: throw LIMA_HW_EXC(Error, "Invalid image type");
		}
		const Size& size = frame_dim.getSize();
		d.dimensions = {size.getWidth(), size.getHeight()};
		Buffer *b = new Buffer;
		b->owner = Buffer::MAPPED;
		b->data = buffer.getFrameBufferPtr(frame);;
		d.setBuffer(b);
		b->unref();
		return d;
	}

 private:
	BufferType m_type;
};

96
97
class Eiger;

98
class Camera : public HwMaxImageSizeCallbackGen, public EventCallbackGen
99
{
100
101
102
	DEB_CLASS_NAMESPC(DebModCamera, "Camera", "SlsDetector");

public:
103
104
	typedef Defs::TrigMode TrigMode;
	typedef Defs::Settings Settings;
105
106
	typedef Defs::DACIndex DACIndex;
	typedef Defs::ADCIndex ADCIndex;
107
	typedef Defs::DetStatus DetStatus;
108

109
	Camera(std::string config_fname, int det_id = 0);
110
	Camera(const Camera& o) = delete;
111
112
	virtual ~Camera();

113
114
115
116
	Type getType();

	Model *getModel()
	{ return m_model; }
117

118
	NameList getHostnameList()
119
120
121
122
123
	{ return m_input_data->host_name_list; }

	int getNbDetModules()
	{ return m_input_data->host_name_list.size(); }

124
125
	int getNbRecvs()
	{ return m_recv_list.size(); }
126

127
128
	Receiver* getRecv(int i)
	{ return m_recv_list[i]; }
129

130
131
	void setBufferCtrlObj(BufferCtrlObj *buffer_ctrl_obj,
			      BufferType type = LimaBuffer);
132

133
134
135
	void setModuleActive(int mod_idx, bool  active);
	void getModuleActive(int mod_idx, bool& active);

136
	void clearAllBuffers();
137
	void releaseBuffers();
138

139
140
141
	void setPixelDepth(PixelDepth  pixel_depth);
	void getPixelDepth(PixelDepth& pixel_depth);

142
143
	void setRawMode(bool  raw_mode);
	void getRawMode(bool& raw_mode);
144

145
146
147
	AcqState getAcqState();
	void waitAcqState(AcqState state);
	AcqState waitNotAcqState(AcqState state);
148

149
150
151
152
153
	ImageType getImageType() const
	{ return m_image_type; }

	void getFrameDim(FrameDim& frame_dim, bool raw = false)
	{ m_model->getFrameDim(frame_dim, raw); }
154

155
156
	FrameMap *getFrameMap()
	{ return &m_frame_map; }
157
158
159
160

	void putCmd(const std::string& s, int idx = -1);
	std::string getCmd(const std::string& s, int idx = -1);

161
	int getFramesCaught();
162
	DetStatus getDetStatus();
163
	DetStatus getDetTrigStatus();
164

165
166
	void setTrigMode(TrigMode  trig_mode);
	void getTrigMode(TrigMode& trig_mode);
167
168
	void setNbFrames(FrameType  nb_frames);
	void getNbFrames(FrameType& nb_frames);
169
170
	void setExpTime(double  exp_time);
	void getExpTime(double& exp_time);
171
172
	void setLatTime(double  lat_time);
	void getLatTime(double& lat_time);
173
174
175
	void setFramePeriod(double  frame_period);
	void getFramePeriod(double& frame_period);

Alejandro Homs Puron's avatar
Alejandro Homs Puron committed
176
177
178
	void setSkipFrameFreq(FrameType  skip_frame_freq);
	void getSkipFrameFreq(FrameType& skip_frame_freq);

179
180
	// setDAC: mod_idx: 0-N=module, -1=all
	void setDAC(int mod_idx, DACIndex dac_idx, int  val, 
181
		    bool milli_volt = false);
182
	void getDAC(int mod_idx, DACIndex dac_idx, int& val, 
183
184
185
186
		    bool milli_volt = false);
	void getDACList(DACIndex dac_idx, IntList& val_list,
			bool milli_volt = false);

187
	void getADC(int mod_idx, ADCIndex adc_idx, int& val);
188
189
	void getADCList(ADCIndex adc_idx, IntList& val_list);

190
191
	void setSettings(Settings  settings);
	void getSettings(Settings& settings);
192

193
194
195
	void setTolerateLostPackets(bool  tol_lost_packets);
	void getTolerateLostPackets(bool& tol_lost_packets);

196
197
	int getNbBadFrames(int item_idx);
	void getBadFrameList(int item_idx, int first_idx, int last_idx,
198
			     IntList& bad_frame_list);
199
	void getBadFrameList(int item_idx, IntList& bad_frame_list);
200

201
202
203
	void prepareAcq();
	void startAcq();
	void stopAcq();
204

205
206
	void triggerFrame();

207
208
209
	void registerTimeRangesChangedCallback(TimeRangesChangedCallback& cb);
	void unregisterTimeRangesChangedCallback(TimeRangesChangedCallback& cb);

210
	void getStats(Stats& stats, int recv_idx=-1);
211

212
213
214
	void setPixelDepthCPUAffinityMap(PixelDepthCPUAffinityMap aff_map);
	void getPixelDepthCPUAffinityMap(PixelDepthCPUAffinityMap& aff_map);

215
	GlobalCPUAffinityMgr::ProcessingFinishedEvent *
216
217
		getProcessingFinishedEvent();

218
	void reportException(Exception& e, std::string name);
219

220
private:
221
	typedef std::map<int, int> RecvPortMap;
222
	typedef std::queue<int> FrameQueue;
223
	typedef std::vector<AutoPtr<Receiver> > RecvList;
224

225
226
227
228
229
230
	struct AppInputData
	{
		DEB_CLASS_NAMESPC(DebModCamera, "Camera::AppInputData", 
				  "SlsDetector");
	public:
		std::string config_file_name;
231
		NameList host_name_list;
232
233
234
235
236
		RecvPortMap recv_port_map;
		AppInputData(std::string cfg_fname);
		void parseConfigFile();
	};

237
238
239
240
241
242
	class AcqThread : public Thread
	{
		DEB_CLASS_NAMESPC(DebModCamera, "Camera::AcqThread", 
				  "SlsDetector");
	public:
		AcqThread(Camera *cam);
243
244

		void queueFinishedFrame(FrameType frame);
245
246
		virtual void start(AutoMutex& l);
		void stop(AutoMutex& l, bool wait);
247

248
249
	protected:
		virtual void threadFunction();
250

251
	private:
252
253
		typedef std::pair<bool, bool> Status;

254
255
256
257
258
259
		class ExceptionCleanUp : Thread::ExceptionCleanUp
		{
			DEB_CLASS_NAMESPC(DebModCamera, 
					  "Camera::AcqThread::ExceptionCleanUp",
					  "SlsDetector");
		public:
260
			ExceptionCleanUp(AcqThread& thread, AutoMutex& l);
261
			virtual ~ExceptionCleanUp();
262
263
		private:
			AutoMutex& m_lock;
264
265
		};

266
		Status newFrameReady(FrameType frame);
267
268
		void startAcq();
		void stopAcq();
269
		void cleanUp(AutoMutex& l);
270

271
		Camera *m_cam;
272
		Cond& m_cond;
273
		AcqState& m_state;
274
		FrameQueue m_frame_queue;
275
	};
276

277
	friend class Model;
278
	friend class Receiver;
279
	friend class GlobalCPUAffinityMgr;
280

281
282
	friend class Eiger;

283
284
	void setModel(Model *model);

285
286
287
	AutoMutex lock()
	{ return AutoMutex(m_cond.mutex()); }

288
	void updateImageSize();
289
	void updateTimeRanges();
290
	void updateCPUAffinity(bool recv_restarted);
291
	void setRecvCPUAffinity(const RecvCPUAffinityList& recv_affinity_list);
292

293
294
295
296
297
	static sls::ns NSec(double x)
	{
		std::chrono::duration<double> sec(x);
		return std::chrono::duration_cast<sls::ns>(sec);
	}
298

299
	AcqState getEffectiveState();
300

301
302
303
304
305
306
307
308
309
310
311
312
313
	BufferCtrlObj **getBufferCtrlObjPtr(BufferType type)
	{
		return (type == AcqBuffer) ? &m_acq_buffer_ctrl_obj :
					     &m_lima_buffer_ctrl_obj;
	}

	StdBufferCbMgr *getBufferCbMgr(BufferType type)
	{
		BufferCtrlObj *buffer = *getBufferCtrlObjPtr(type);
		return buffer ? &buffer->getBuffer() : NULL;
	}

	void setAcqBufferCPUAffinity(CPUAffinity buffer_affinity);
314

315
	char *getAcqFrameBufferPtr(FrameType frame_nb);
316
	void removeSharedMem();
317
318
	void createReceivers();

319
320
321
	bool checkLostPackets();
	FrameType getLastReceivedFrame();

322
	void waitLastSkippedFrame();
323
	void processLastSkippedFrame(int recv_idx);
324

325
326
327
328
	void getSortedBadFrameList(IntList first_idx, IntList last_idx,
				   IntList& bad_frame_list );
	void getSortedBadFrameList(IntList& bad_frame_list)
	{ getSortedBadFrameList(IntList(), IntList(), bad_frame_list); }
329

330
331
	std::string execCmd(const std::string& s, bool put, int idx = -1);

332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
	template <class T>
	void putNbCmd(const std::string& cmd, T val, int idx = -1)
	{
		std::ostringstream os;
		os << cmd << " " << val;
		putCmd(os.str(), idx);
	}

	template <class T>
	T getNbCmd(const std::string& cmd, int idx = -1)
	{
		std::string ans = getCmd(cmd, idx);
		std::istringstream is(ans);
		T val;
		is >> val;
		return val;
	}
349

350
351
352
	void setReceiverFifoDepth(int fifo_depth);
	void resetFramesCaught();

353
	int m_det_id;
354
	Model *m_model;
355
	Cond m_cond;
356
	AutoPtr<AppInputData> m_input_data;
357
	AutoPtr<sls::Detector> m_det;
358
359
	FrameMap m_frame_map;
	RecvList m_recv_list;
360
	TrigMode m_trig_mode;
Alejandro Homs Puron's avatar
Alejandro Homs Puron committed
361
362
363
	FrameType m_lima_nb_frames;
	FrameType m_det_nb_frames;
	FrameType m_skip_frame_freq;
364
	SortedIntList m_missing_last_skipped_frame;
365
	double m_last_skipped_frame_timeout;
366
	double m_exp_time;
367
	double m_lat_time;
368
	double m_frame_period;
369
	Settings m_settings;
370
371
372
	CPUAffinity m_buffer_affinity;
	BufferCtrlObj *m_acq_buffer_ctrl_obj;
	BufferCtrlObj *m_lima_buffer_ctrl_obj;
373
	PixelDepth m_pixel_depth;
374
	ImageType m_image_type;
375
	bool m_raw_mode;
376
	AcqState m_state;
377
	Timestamp m_next_ready_ts;
378
379
	double m_new_frame_timeout;
	double m_abort_sleep_time;
380
	bool m_tol_lost_packets;
381
	FrameArray m_prev_ifa;
382
	TimeRangesChangedCallback *m_time_ranges_cb;
383
	PixelDepthCPUAffinityMap m_cpu_affinity_map;
384
	GlobalCPUAffinityMgr m_global_cpu_affinity_mgr;
385
	AutoPtr<AcqThread> m_acq_thread;
386
387
388
389
390
391
392
};

} // namespace SlsDetector

} // namespace lima


393
#endif // __SLS_DETECTOR_CAMERA_H