PilatusInterface.cpp 25.3 KB
Newer Older
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//###########################################################################
// 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/>.
//###########################################################################
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
22
23
24
25
#include <algorithm>
#include <fcntl.h>
#include <pwd.h>
#include <sys/stat.h>
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
26
27
#include <sys/statvfs.h>
#include <sys/types.h>
28
#include <sys/mman.h>
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
29
#include <unistd.h>
30
#include <errno.h>
31
#include "lima/Debug.h"
32
33
#include "PilatusInterface.h"

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
34
35
using namespace lima;
using namespace lima::Pilatus;
36

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
37
38
39
40
41
42
static const char* CAMERA_INFO_FILE = "p2_det/config/cam_data/camera.def";
static const char* CAMERA_DEFAULT_USER= "det";

static const char CAMERA_NAME_TOKEN[] = "camera_name";
static const char CAMERA_WIDE_TOKEN[] = "camera_wide";
static const char CAMERA_HIGH_TOKEN[] = "camera_high";
43
static const char CAMERA_PILATUS3_TOKEN[] = "PILATUS3";
44

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
45
static const char WATCH_PATH[] = "/lima_data";
46
static const char FILE_PATTERN[] = "tmp_img_%.7d.edf";
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
47
48
static const int  DECTRIS_EDF_OFFSET = 1024;

49
50
/*******************************************************************
 * \brief DetInfoCtrlObj constructor
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
51
 * \param info if info is NULL look for ~det/p2_det/config/cam_data/camera.def file
52
 *******************************************************************/
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
53
DetInfoCtrlObj::DetInfoCtrlObj(const DetInfoCtrlObj::Info* info)
54
{
Arafat Noureddine's avatar
Arafat Noureddine committed
55
    DEB_CONSTRUCTOR();
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    if(info)
      m_info = *info;
    else			// look for local file
      {
	char aBuffer[2048];
	struct passwd aPwd;
	struct passwd *aResultPwd;
	if(getpwnam_r(CAMERA_DEFAULT_USER,&aPwd,
		       aBuffer,sizeof(aBuffer),
		      &aResultPwd))
	  THROW_HW_ERROR(Error) << "Can't get information of user : " 
				<< CAMERA_DEFAULT_USER;
	
	char aConfigFullPath[1024];
	snprintf(aConfigFullPath,sizeof(aConfigFullPath),
		 "%s/%s",aPwd.pw_dir,CAMERA_INFO_FILE);
	FILE* aConfFile = fopen(aConfigFullPath,"r");
	if(!aConfFile)
	  THROW_HW_ERROR(Error) << "Can't open config file :"
				<< aConfigFullPath;
	char aReadBuffer[1024];
77
	int aWidth = -1,aHeight = -1;
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
78
79
80
	while(fgets(aReadBuffer,sizeof(aReadBuffer),aConfFile))
	  {
	    if(!strncmp(aReadBuffer,
81
			CAMERA_NAME_TOKEN,sizeof(CAMERA_NAME_TOKEN) - 1))
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
82
83
	      {
		char *aBeginPt = strchr(aReadBuffer,(unsigned int)'"');
84
		++aBeginPt;
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
85
86
87
		char *aEndPt = strrchr(aBeginPt,(unsigned int)'"');
		*aEndPt = '\0';	// remove last "
		m_info.m_det_model = aBeginPt;
88
89
		//Check if pilatus2 or 3
		m_is_pilatus3 = !strncmp(aBeginPt,CAMERA_PILATUS3_TOKEN,sizeof(CAMERA_PILATUS3_TOKEN) - 1);
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
90
91
	      }
	    else if(!strncmp(aReadBuffer,
92
			     CAMERA_HIGH_TOKEN,sizeof(CAMERA_HIGH_TOKEN) - 1))
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
93
94
	      {
		char *aPt = aReadBuffer;
95
		while(*aPt && (*aPt < '1' || *aPt > '9')) ++aPt;
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
96
97
98
		aHeight = atoi(aPt);
	      }
	    else if(!strncmp(aReadBuffer,
99
			     CAMERA_WIDE_TOKEN,sizeof(CAMERA_WIDE_TOKEN) - 1))
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
100
101
	      {
		char *aPt = aReadBuffer;
102
		while(*aPt && (*aPt < '1' || *aPt > '9')) ++aPt;
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
103
104
105
		aWidth = atoi(aPt);
	      }
	  }
106
107
108
109
110
111
	if(aWidth <= 0 || aHeight <= 0)
	  {
	    fclose(aConfFile);
	    THROW_HW_ERROR(Error) << "Can't get detector info";
	  }
	m_info.m_det_size = Size(aWidth,aHeight);
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
112
113
	fclose(aConfFile);
      }
114
115
116
117
118
119
120
}

//-----------------------------------------------------
//
//-----------------------------------------------------
DetInfoCtrlObj::~DetInfoCtrlObj()
{
Arafat Noureddine's avatar
Arafat Noureddine committed
121
    DEB_DESTRUCTOR();
122
123
124
125
126
127
128
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void DetInfoCtrlObj::getMaxImageSize(Size& size)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
129
130
131
    DEB_MEMBER_FUNCT();
    // get the max image size
    getDetectorImageSize(size);
132
133
134
135
136
137
138
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void DetInfoCtrlObj::getDetectorImageSize(Size& size)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
139
140
    DEB_MEMBER_FUNCT();
    // get the max image size of the detector
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
141
    size = m_info.m_det_size;
142
143
}

144

145
146
147
148
149
//-----------------------------------------------------
//
//-----------------------------------------------------
void DetInfoCtrlObj::getDefImageType(ImageType& image_type)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
150
151
    DEB_MEMBER_FUNCT();
    getCurrImageType(image_type);
152
153
154
155
156
157
158
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void DetInfoCtrlObj::getCurrImageType(ImageType& image_type)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
159
    DEB_MEMBER_FUNCT();
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
160
    image_type= Bpp32S;
161
162
163
164
165
166
167
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void DetInfoCtrlObj::setCurrImageType(ImageType image_type)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
168
169
170
171
172
    DEB_MEMBER_FUNCT();
    ImageType valid_image_type;
    getDefImageType(valid_image_type);
    if (image_type != valid_image_type)
        throw LIMA_HW_EXC(InvalidValue, "Invalid Pixel depth value");
173
174
175
176
177
}

//-----------------------------------------------------
//
//-----------------------------------------------------
178
void DetInfoCtrlObj::getPixelSize(double& x_size,double& y_size)
179
{
Arafat Noureddine's avatar
Arafat Noureddine committed
180
    DEB_MEMBER_FUNCT();
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
181
    x_size = y_size = 172.0e-6;
182
183
184
185
186
187
188
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void DetInfoCtrlObj::getDetectorType(std::string& type)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
189
190
    DEB_MEMBER_FUNCT();
    type  = "Pilatus";
191

192
193
194
195
196
197
198
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void DetInfoCtrlObj::getDetectorModel(std::string& model)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
199
    DEB_MEMBER_FUNCT();
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
200
    model = m_info.m_det_model;
201
}
202
203
204
205
206
//-----------------------------------------------------
//
//-----------------------------------------------------
double DetInfoCtrlObj::getMinLatTime() const
{
207
  return m_is_pilatus3 ? 950e-6 : 3e-3;
208
}
209
210
211
212
213

/*******************************************************************
 * \brief SyncCtrlObj constructor
 *******************************************************************/

214
215
216
217
218
219
220
SyncCtrlObj::SyncCtrlObj(Camera& cam,
			 DetInfoCtrlObj &det_info,
			 RoiCtrlObj &roi) :
  m_cam(cam),
  m_det_info(det_info),
  m_roi(roi),
  m_latency(det_info.getMinLatTime())
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
{
}

//-----------------------------------------------------
//
//-----------------------------------------------------
SyncCtrlObj::~SyncCtrlObj()
{
}

//-----------------------------------------------------
//
//-----------------------------------------------------
bool SyncCtrlObj::checkTrigMode(TrigMode trig_mode)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
236
237
238
239
    bool valid_mode = false;
    switch (trig_mode)
    {
    case IntTrig:
240
    case IntTrigMult:
Arafat Noureddine's avatar
Arafat Noureddine committed
241
242
243
244
245
    case ExtTrigSingle:
    case ExtTrigMult:
    case ExtGate:
        valid_mode = true;
        break;
246

Arafat Noureddine's avatar
Arafat Noureddine committed
247
248
    default:
        valid_mode = false;
249
        break;
Arafat Noureddine's avatar
Arafat Noureddine committed
250
251
    }
    return valid_mode;
252
253
254
255
256
257
258
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void SyncCtrlObj::setTrigMode(TrigMode trig_mode)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
259
260
261
    DEB_MEMBER_FUNCT();
    if (!checkTrigMode(trig_mode))
        throw LIMA_HW_EXC(InvalidValue, "Invalid trigger mode");
262
    Camera::TriggerMode trig;
Arafat Noureddine's avatar
Arafat Noureddine committed
263
264
    switch(trig_mode)
    {
265
        case IntTrig        : trig = Camera::INTERNAL_SINGLE;
Arafat Noureddine's avatar
Arafat Noureddine committed
266
        break;
267
        case IntTrigMult    : trig = Camera::INTERNAL_MULTI;
Arafat Noureddine's avatar
Arafat Noureddine committed
268
        break;
269
        case ExtTrigSingle  : trig = Camera::EXTERNAL_SINGLE;
Arafat Noureddine's avatar
Arafat Noureddine committed
270
        break;
271
        case ExtTrigMult    : trig = Camera::EXTERNAL_MULTI;
Arafat Noureddine's avatar
Arafat Noureddine committed
272
        break;
273
        case ExtGate        : trig = Camera::EXTERNAL_GATE;
Arafat Noureddine's avatar
Arafat Noureddine committed
274
        break;
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
275
	default: break;
Arafat Noureddine's avatar
Arafat Noureddine committed
276
277
    }

278
    m_cam.setTriggerMode(trig);
279
280
281
282
283
284
285
286

}

//-----------------------------------------------------
//
//-----------------------------------------------------
void SyncCtrlObj::getTrigMode(TrigMode& trig_mode)
{
287
    Camera::TriggerMode trig = m_cam.triggerMode();
Arafat Noureddine's avatar
Arafat Noureddine committed
288
289
    switch(trig)
    {
290
        case Camera::INTERNAL_SINGLE    :   trig_mode = IntTrig;
Arafat Noureddine's avatar
Arafat Noureddine committed
291
        break;
292
        case Camera::INTERNAL_MULTI     :   trig_mode = IntTrigMult;
Arafat Noureddine's avatar
Arafat Noureddine committed
293
        break;
294
        case Camera::EXTERNAL_SINGLE    :   trig_mode = ExtTrigSingle;
Arafat Noureddine's avatar
Arafat Noureddine committed
295
        break;
296
        case Camera::EXTERNAL_MULTI     :   trig_mode = ExtTrigMult;
Arafat Noureddine's avatar
Arafat Noureddine committed
297
        break;
298
        case Camera::EXTERNAL_GATE      :   trig_mode = ExtGate;
Arafat Noureddine's avatar
Arafat Noureddine committed
299
300
        break;
    }
301
302
}

303
304
305
//-----------------------------------------------------
//
//-----------------------------------------------------
306
307
void SyncCtrlObj::setExpTime(double exp_time)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
308
    m_exposure_requested = exp_time;
309
    m_cam.setExposure(exp_time);
310
311
312
313
314
315
316
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void SyncCtrlObj::getExpTime(double& exp_time)
{
317
    exp_time = m_cam.exposure();
318
319
320
321
322
323
324
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void SyncCtrlObj::setLatTime(double lat_time)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
325
   m_latency = lat_time;
326
327
}

Arafat Noureddine's avatar
Arafat Noureddine committed
328
329
330
//-----------------------------------------------------
//
//-----------------------------------------------------
331
332
void SyncCtrlObj::getLatTime(double& lat_time)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
333
    lat_time = m_latency;
334
335
336
337
338
339
340
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void SyncCtrlObj::setNbHwFrames(int nb_frames)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
341
    m_nb_frames = nb_frames;
342
343
344
345
346
347
348
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void SyncCtrlObj::getNbHwFrames(int& nb_frames)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
349
    nb_frames =  m_nb_frames;
350
351
352
353
354
355
356
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void SyncCtrlObj::getValidRanges(ValidRangesType& valid_ranges)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
357
358
359
360
    double min_time = 1e-9;
    double max_time = 1e6;
    valid_ranges.min_exp_time = min_time;
    valid_ranges.max_exp_time = max_time;
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
361
    valid_ranges.min_lat_time = m_latency;
Arafat Noureddine's avatar
Arafat Noureddine committed
362
    valid_ranges.max_lat_time = max_time;
363
364
}

365
366
367
//-----------------------------------------------------
//
//-----------------------------------------------------
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
368
void SyncCtrlObj::prepareAcq()
369
{
370
371
    TrigMode trig_mode;
    getTrigMode(trig_mode);
Arafat Noureddine's avatar
Arafat Noureddine committed
372

Arafat Noureddine's avatar
Arafat Noureddine committed
373
    double exposure =  m_exposure_requested;
374
    double exposure_period = exposure + m_latency;
375

376
377
378
379
380
381
382
383
384
385
386
    if(m_det_info.isPilatus3() && 
       (trig_mode == ExtGate || trig_mode == ExtTrigMult))
      {
	int max_frequency = m_roi.getMaxFrequency();
	if(max_frequency > 0)
	  {
	    double min_exposure_period = 1./max_frequency;
	    if(exposure_period < min_exposure_period)
	      exposure_period = min_exposure_period;
	  }
      }
387
    m_cam.setExposurePeriod(exposure_period);
388
	
Arafat Noureddine's avatar
Arafat Noureddine committed
389
    int nb_frames = (trig_mode == IntTrigMult)?1:m_nb_frames;
390
    m_cam.setNbImagesInSequence(nb_frames);
Arafat Noureddine's avatar
Arafat Noureddine committed
391

392
}
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
/*****************************************************************************
				 ROI
*****************************************************************************/
static const int MODULE_WIDTH = 487;
static const int MODULE_HEIGHT = 195;

static const int MODULE_WIDTH_SPACE = 7;
static const int MODULE_HEIGHT_SPACE = 17;

RoiCtrlObj::RoiCtrlObj(Camera& cam,DetInfoCtrlObj& det) :
  m_cam(cam),
  m_det(det),
  m_has_hardware_roi(det.isPilatus3())
{
  DEB_CONSTRUCTOR();
  Size detImageSize;
  det.getDetectorImageSize(detImageSize);

411
412
  int fullframe_max_frequency = -1;

413
414
415
416
  if(m_has_hardware_roi)
    {
      if(detImageSize == Size(2463,2527)) // Pilatus 6M
	{
417
418
	  fullframe_max_frequency = 100;

419
420
421
422
	  Roi c2(2 * MODULE_WIDTH + 2 * MODULE_WIDTH_SPACE,
		 5 * MODULE_HEIGHT + 5 * MODULE_HEIGHT_SPACE,
		 MODULE_WIDTH,
		 2 * MODULE_HEIGHT + MODULE_HEIGHT_SPACE);
423
	  m_possible_rois.push_back(PATTERN2ROI(Pattern("C2",500),c2));
424
425
426
427
428

	  Roi c18(MODULE_WIDTH + MODULE_WIDTH_SPACE,
		  3 * (MODULE_HEIGHT + MODULE_HEIGHT_SPACE),
		  3 * MODULE_WIDTH + 2 * MODULE_WIDTH_SPACE,
		  6 * MODULE_HEIGHT + 5 * MODULE_HEIGHT_SPACE);
429
	  m_possible_rois.push_back(PATTERN2ROI(Pattern("C18",200),c18));
430
431
432
	}
      else if(detImageSize == Size(1475,1679)) // Pilatus 2M
	{
433
434
	  fullframe_max_frequency = 250;

435
436
437
438
	  Roi c2(MODULE_WIDTH + MODULE_WIDTH_SPACE,
		 3 * MODULE_HEIGHT + 3 * MODULE_HEIGHT_SPACE,
		 MODULE_WIDTH,
		 2 * MODULE_HEIGHT + MODULE_HEIGHT_SPACE);
439
	  m_possible_rois.push_back(PATTERN2ROI(Pattern("C2",500),c2));
440
441
442
443
444

	  Roi r8(MODULE_WIDTH + MODULE_WIDTH_SPACE,
		 2 * MODULE_HEIGHT + 2 * MODULE_HEIGHT_SPACE,
		 2 * MODULE_WIDTH + MODULE_WIDTH_SPACE,
		 4 * MODULE_HEIGHT + 3 * MODULE_HEIGHT_SPACE);
445
	  m_possible_rois.push_back(PATTERN2ROI(Pattern("R8",500),r8));
446
447
448
449
450

	  Roi l8(0,
		 2 * MODULE_HEIGHT + 2 * MODULE_HEIGHT_SPACE,
		 2 * MODULE_WIDTH + MODULE_WIDTH_SPACE,
		 4 * MODULE_HEIGHT + 3 * MODULE_HEIGHT_SPACE);
451
	  m_possible_rois.push_back(PATTERN2ROI(Pattern("L8",500),l8));
452
453
454
455
456

	  Roi c12(0,
		  2 * MODULE_HEIGHT + 2 * MODULE_HEIGHT_SPACE,
		  3 * MODULE_WIDTH + 2 * MODULE_WIDTH_SPACE,
		  4 * MODULE_HEIGHT + 3 * MODULE_HEIGHT_SPACE);
457
	  m_possible_rois.push_back(PATTERN2ROI(Pattern("C12",250),c12));
458
459
460
	}
      else if(detImageSize == Size(981,1043)) // Pilatus 1M
	{
461
462
	  fullframe_max_frequency = 500;
	  
463
464
465
466
	  Roi r1(MODULE_WIDTH + MODULE_WIDTH_SPACE,
		 2 * MODULE_HEIGHT + 2 * MODULE_HEIGHT_SPACE,
		 MODULE_WIDTH,
		 MODULE_HEIGHT);
467
	  m_possible_rois.push_back(PATTERN2ROI(Pattern("R1",500),r1));
468
469
470
471
472

	  Roi l1(0,
		 2 * MODULE_HEIGHT + 2 * MODULE_HEIGHT_SPACE,
		 MODULE_WIDTH,
		 MODULE_HEIGHT);
473
	  m_possible_rois.push_back(PATTERN2ROI(Pattern("L1",500),l1));
474
475
476
477
478

	  Roi r3(MODULE_WIDTH + MODULE_WIDTH_SPACE,
		 MODULE_HEIGHT + MODULE_HEIGHT_SPACE,
		 MODULE_WIDTH,
		 3 * MODULE_HEIGHT + 2 * MODULE_HEIGHT_SPACE);
479
	  m_possible_rois.push_back(PATTERN2ROI(Pattern("R3",500),r3));
480
481
482
483
484

	  Roi l3(0,
		 MODULE_HEIGHT + MODULE_HEIGHT_SPACE,
		 MODULE_WIDTH,
		 3 * MODULE_HEIGHT + 2 * MODULE_HEIGHT_SPACE);
485
	  m_possible_rois.push_back(PATTERN2ROI(Pattern("L3",500),l3));
486
487
488
489
490
491
492
493
494
	}
      else
	m_has_hardware_roi = false;
    }

  if(!m_has_hardware_roi)
    DEB_WARNING() << "Hardware Roi not managed for this detector";
  
  Roi full(Point(0,0),detImageSize);
495
  m_possible_rois.push_back(PATTERN2ROI(Pattern("0",fullframe_max_frequency),full));
496
  m_current_roi = full;
497
  m_current_max_frequency = fullframe_max_frequency;
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
}

void RoiCtrlObj::checkRoi(const Roi& set_roi, Roi& hw_roi)
{
  DEB_MEMBER_FUNCT();

  ROIS::const_iterator i = _getRoi(set_roi);
  if(i == m_possible_rois.end())
    THROW_HW_ERROR(Error) << "Something weird happen";

  hw_roi = i->second;
}

void RoiCtrlObj::setRoi(const Roi& set_roi)
{
  DEB_MEMBER_FUNCT();
  
  ROIS::const_iterator i;
  if(set_roi.isActive())
    {
      i = _getRoi(set_roi);
      if(i == m_possible_rois.end())
	THROW_HW_ERROR(Error) << "Something weird happen";
    }
  else
    i = --m_possible_rois.end(); // full_frame

 
  if(m_has_hardware_roi)
527
    m_cam.setRoi(i->first.pattern);
528
529
  
  m_current_roi = i->second;
530
  m_current_max_frequency = i->first.max_frequency;
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
}

void RoiCtrlObj::getRoi(Roi& hw_roi)
{
  hw_roi = m_current_roi;
}

inline RoiCtrlObj::ROIS::const_iterator
RoiCtrlObj::_getRoi(const Roi& roi) const
{
  for(ROIS::const_iterator i = m_possible_rois.begin();
      i != m_possible_rois.end();++i)
    {
      if(i->second.containsRoi(roi))
	return i;
    }
  return m_possible_rois.end();
}
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
/*****************************************************************************
			  Memory map manager
*****************************************************************************/
class _MmapManager : public HwBufferCtrlObj::Callback
{
  DEB_CLASS(DebModCamera, "Pilatus::_MmapManager");
  typedef std::pair<void*,long> AddressNSize;
  typedef std::map<void*,AddressNSize> Data2BaseNSize;
  typedef std::multiset<void *> BufferList;
public:
  _MmapManager() : HwBufferCtrlObj::Callback() {}
  virtual void map(void* address)
  {
    DEB_MEMBER_FUNCT();

    AutoMutex lock(m_mutex);
    m_buffer_in_use.insert(address);
  }
  virtual void release(void* address)
  {
    DEB_MEMBER_FUNCT();

    AutoMutex lock(m_mutex);
    BufferList::iterator it = m_buffer_in_use.find(address);
    if(it == m_buffer_in_use.end())
      THROW_HW_ERROR(Error) << "Internal error: releasing buffer not in used list";

    m_buffer_in_use.erase(it++);
    if(it == m_buffer_in_use.end() || *it != address)
      {
	Data2BaseNSize::iterator mmap_info = m_data_2_base_n_size.find(address);
	munmap(mmap_info->second.first,mmap_info->second.second);
	m_data_2_base_n_size.erase(mmap_info);
      }
  }
  virtual void releaseAll()
  {
    DEB_MEMBER_FUNCT();

    AutoMutex lock(m_mutex);
    for(Data2BaseNSize::iterator mmap_info = m_data_2_base_n_size.begin();
	mmap_info != m_data_2_base_n_size.end();++mmap_info)
      munmap(mmap_info->second.first,mmap_info->second.second);
    m_data_2_base_n_size.clear();
    m_buffer_in_use.clear();
  }

  void register_new_mmap(void *mmap_mem_base,
			 void *aDataBuffer,long length)
  {
    AutoMutex lock(m_mutex);
    m_data_2_base_n_size[aDataBuffer] = AddressNSize(mmap_mem_base,length);
  }
  
private:
  Mutex			m_mutex;
  Data2BaseNSize	m_data_2_base_n_size;
  BufferList		m_buffer_in_use;
};
608

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
609
610
611
612
613
614
615
616
/*******************************************************************
 * \brief Interface::_BufferCallback
 *******************************************************************/
class Interface::_BufferCallback : public HwTmpfsBufferMgr::Callback
{
  DEB_CLASS_NAMESPC(DebModCamera, "_BufferCallback", "Pilatus");
public:
  _BufferCallback(Interface& hwInterface) : m_interface(hwInterface) {}
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
617
  virtual ~_BufferCallback() {}
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
618
619
620
621
622
623
  virtual void prepare(const DirectoryEvent::Parameters &params)
  {
    DEB_MEMBER_FUNCT();

    m_interface.m_cam.setImgpath(params.watch_path);
    m_interface.m_cam.setFileName(params.file_pattern);
624
    m_image_events.clear();
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
625
626
627
628
629
630
631
632
  }

  virtual bool getFrameInfo(int image_number,const char* full_path,
			    HwFileEventCallbackHelper::CallFrom from,
			    HwFrameInfoType &frame_info)
  {
    DEB_MEMBER_FUNCT();

633
634
    m_image_events.insert(image_number);

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
635
636
    FrameDim anImageDim;
    getFrameDim(anImageDim);
637
    long memSize = anImageDim.getMemSize();
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
638
639
640
641
642
643
644
645
646

    int fd = open(full_path,O_RDONLY);
    if(fd < 0)
      {
	if(from == HwFileEventCallbackHelper::OnDemand)
	  THROW_HW_ERROR(Error) << "Image is no more available";
	else
	  {
	    m_interface.m_cam.errorStopAcquisition();
647
	    THROW_HW_ERROR(Error) << strerror(errno) << DEB_VAR1(full_path);
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
648
649
	  }
      }
650
651
652
653
654
655
    void* mmap_mem_base = mmap(NULL,DECTRIS_EDF_OFFSET + memSize,
			  PROT_READ,MAP_SHARED,fd,0);

    close(fd);

    if(mmap_mem_base == MAP_FAILED)
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
656
657
658
659
660
      {
	m_interface.m_cam.errorStopAcquisition();
	THROW_HW_ERROR(Error) << "Problem to read image:" << DEB_VAR1(full_path);
      }
    
661
    void* aDataBuffer = (char*)mmap_mem_base + DECTRIS_EDF_OFFSET;
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
662
663
    frame_info = HwFrameInfoType(image_number,aDataBuffer,&anImageDim,
				 Timestamp(),0,
664
665
666
				 HwFrameInfoType::Managed);
    m_mmap_manager.register_new_mmap(mmap_mem_base,
				     aDataBuffer,DECTRIS_EDF_OFFSET + memSize);
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
667
668
669
670
671
672
673
    bool aReturnFlag = true;
    if(m_interface.m_buffer.getNbOfFramePending() > 32)
      {
	m_interface.m_cam.errorStopAcquisition();
	aReturnFlag = false;
      }
    else
674
675
      aReturnFlag = int(m_image_events.size()) != m_interface.m_cam.nbImagesInSequence();
    
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
676
677
678
679
680
681
    return aReturnFlag;
  }
  virtual void getFrameDim(FrameDim& frame_dim)
  {
    DEB_MEMBER_FUNCT();

682
683
684
    Roi hw_roi;
    m_interface.m_roi.getRoi(hw_roi);
    const Size &current_size = hw_roi.getSize();
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
685
686
687
688
689
690
    ImageType current_image_type;
    m_interface.m_det_info.getCurrImageType(current_image_type);
    
    frame_dim.setSize(current_size);
    frame_dim.setImageType(current_image_type);
  }
691
692
693
694
  virtual HwBufferCtrlObj::Callback* getBufferCallback()
  {
    return &m_mmap_manager;
  }
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
695
696
private:
  Interface&	m_interface;
697
  _MmapManager	m_mmap_manager;
698
  std::set<long>		m_image_events;
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
699
};
700
701
702
703
704

/*******************************************************************
 * \brief Hw Interface constructor
 *******************************************************************/

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
705
Interface::Interface(Camera& cam,const DetInfoCtrlObj::Info* info)
706
            :   m_cam(cam),
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
707
708
709
710
                m_det_info(info),
		m_buffer_cbk(new Interface::_BufferCallback(*this)),
                m_buffer(WATCH_PATH,FILE_PATTERN,
			 *m_buffer_cbk),
711
712
713
		m_roi(cam,m_det_info),
                m_sync(cam,m_det_info,m_roi),
		m_saving(cam)
714
{
Arafat Noureddine's avatar
Arafat Noureddine committed
715
    DEB_CONSTRUCTOR();
716

Arafat Noureddine's avatar
Arafat Noureddine committed
717
718
    HwDetInfoCtrlObj *det_info = &m_det_info;
    m_cap_list.push_back(HwCap(det_info));
719

Arafat Noureddine's avatar
Arafat Noureddine committed
720
721
    HwBufferCtrlObj *buffer = &m_buffer;
    m_cap_list.push_back(HwCap(buffer));
722

Arafat Noureddine's avatar
Arafat Noureddine committed
723
724
    HwSyncCtrlObj *sync = &m_sync;
    m_cap_list.push_back(HwCap(sync));
725

726
727
    HwSavingCtrlObj *saving = &m_saving;
    m_cap_list.push_back(HwCap(saving));
728

729
730
731
    HwRoiCtrlObj *roi = &m_roi;
    m_cap_list.push_back(HwCap(roi));

732
    m_buffer.getDirectoryEvent().watch_moved_to();
733
734
735

    //Activate new pilatus3 threshold method
    if(m_det_info.isPilatus3()) cam._pilatus3model();
736
737
738
739
740
741
742
}

//-----------------------------------------------------
//
//-----------------------------------------------------
Interface::~Interface()
{
Arafat Noureddine's avatar
Arafat Noureddine committed
743
    DEB_DESTRUCTOR();
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
744
    delete m_buffer_cbk;
745
746
747
748
749
750
751
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void Interface::getCapList(HwInterface::CapList &cap_list) const
{
Arafat Noureddine's avatar
Arafat Noureddine committed
752
753
    DEB_MEMBER_FUNCT();
    cap_list = m_cap_list;
754
755
756
757
758
759
760
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void Interface::reset(ResetLevel reset_level)
{
Arafat Noureddine's avatar
Arafat Noureddine committed
761
762
    DEB_MEMBER_FUNCT();
    DEB_PARAM() << DEB_VAR1(reset_level);
763

Arafat Noureddine's avatar
Arafat Noureddine committed
764
    stopAcq();
765

Arafat Noureddine's avatar
Arafat Noureddine committed
766
767
768
769
770
771
    Size image_size;
    m_det_info.getMaxImageSize(image_size);
    ImageType image_type;
    m_det_info.getDefImageType(image_type);
    FrameDim frame_dim(image_size, image_type);
    m_buffer.setFrameDim(frame_dim);
772

Arafat Noureddine's avatar
Arafat Noureddine committed
773
774
    m_buffer.setNbConcatFrames(1);
    m_buffer.setNbBuffers(1);
775
776
777
778
    if(reset_level == HardReset)
        m_cam.hardReset();
    else
	m_cam.softReset();
779
780
781
782
783
784
785
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void Interface::prepareAcq()
{
Arafat Noureddine's avatar
Arafat Noureddine committed
786
    DEB_MEMBER_FUNCT();
Arafat Noureddine's avatar
Arafat Noureddine committed
787

788
789
790
791
    if(m_saving.isActive())
      m_saving.prepare();
    else
      m_buffer.prepare();
Arafat Noureddine's avatar
Arafat Noureddine committed
792
    m_sync.prepareAcq();
Arafat Noureddine's avatar
Arafat Noureddine committed
793

794
795
796
797
798
799
800
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void Interface::startAcq()
{
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
801
    DEB_MEMBER_FUNCT();
802
803
804
805
806
807

    if(m_saving.isActive())
      m_saving.start();
    else
      m_buffer.start();

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
808
    m_cam.startAcquisition();
809
810
811
812
813
814
815
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void Interface::stopAcq()
{
Arafat Noureddine's avatar
Arafat Noureddine committed
816
    DEB_MEMBER_FUNCT();
817

818
819
820
821
822
823
    if(m_saving.isActive())
      m_saving.stop();
    else
      m_buffer.stop();

    m_cam.stopAcquisition();
824
825
826
827
828
829
830
}

//-----------------------------------------------------
//
//-----------------------------------------------------
void Interface::getStatus(StatusType& status)
{
831

832
    DEB_MEMBER_FUNCT();
833
    Camera::Status cam_status = m_cam.status();
834

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
835
    if(cam_status == Camera::STANDBY)
836
    {
837
	status.det = DetIdle;
838
839
840
841
842
843
844
845
846
	if(!m_saving.isActive())
	  {
	    int nbFrames;
	    m_sync.getNbHwFrames(nbFrames);
	    if(m_buffer.isStopped())
	      status.acq = AcqReady;
	    else
	      status.acq = getNbHwAcquiredFrames() >= nbFrames ? AcqReady : AcqRunning;
	  }
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
847
	else
848
	  status.acq = AcqReady;
849
    }
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
850
851
    else if(cam_status == Camera::DISCONNECTED ||
	    cam_status == Camera::ERROR)
Arafat Noureddine's avatar
Arafat Noureddine committed
852
853
854
855
856
857
    {
        status.det = DetFault;
        status.acq = AcqFault;
    }
    else
    {
858
859
860
        status.det = DetExposure;
        status.acq = AcqRunning;       
    }    
861
    status.det_mask = DetExposure;
862
    DEB_TRACE() << DEB_VAR2(cam_status,status);
863
864
865
866
867
868
869
}

//-----------------------------------------------------
//
//-----------------------------------------------------
int Interface::getNbHwAcquiredFrames()
{
Arafat Noureddine's avatar
Arafat Noureddine committed
870
    DEB_MEMBER_FUNCT();
871
    int acq_frames = m_buffer.getLastAcquiredFrame()+1;
Arafat Noureddine's avatar
Arafat Noureddine committed
872
873
    return acq_frames;
}
Arafat Noureddine's avatar
Arafat Noureddine committed
874
875
876
877

//-----------------------------------------------------
//
//-----------------------------------------------------
878
void Interface::setThresholdGain(int threshold, Camera::Gain gain)
Arafat Noureddine's avatar
Arafat Noureddine committed
879
{
880
    m_cam.setThresholdGain(threshold, gain);
Arafat Noureddine's avatar
Arafat Noureddine committed
881
}
882
883
884
885
886
887
888
//-----------------------------------------------------
//
//-----------------------------------------------------
void Interface::setThreshold(int threshold,int energy)
{
  m_cam.setThreshold(threshold,energy);
}
Arafat Noureddine's avatar
Arafat Noureddine committed
889
890
//-----------------------------------------------------
//
Arafat Noureddine's avatar
Arafat Noureddine committed
891
//-----------------------------------------------------
Arafat Noureddine's avatar
Arafat Noureddine committed
892
893
int Interface::getThreshold(void)
{
894
    return m_cam.threshold();
Arafat Noureddine's avatar
Arafat Noureddine committed
895
896
897
898
899
}


//-----------------------------------------------------
//
Arafat Noureddine's avatar
Arafat Noureddine committed
900
//-----------------------------------------------------
901
Camera::Gain Interface::getGain(void)
Arafat Noureddine's avatar
Arafat Noureddine committed
902
{
903
    return m_cam.gain();
Arafat Noureddine's avatar
Arafat Noureddine committed
904
}
905

906
907
//-----------------------------------------------------
//
Arafat Noureddine's avatar
Arafat Noureddine committed
908
909
910
//-----------------------------------------------------
void Interface::sendAnyCommand(const std::string& str)
{
911
    m_cam.sendAnyCommand(str);
Arafat Noureddine's avatar
Arafat Noureddine committed
912
}
913
914
915

//-----------------------------------------------------
//
Arafat Noureddine's avatar
Arafat Noureddine committed
916
//-----------------------------------------------------
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
void Interface::setEnergy(double energy)
{
	m_cam.setEnergy(energy);
}
//-----------------------------------------------------
//
//-----------------------------------------------------
double Interface::getEnergy(void)
{
    return m_cam.energy();
}

//-----------------------------------------------------
//
//-----------------------------------------------------