EigerCamera.cpp 37.3 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
23
24
25
26
27
///###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2014
// 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/>.
//############################################################################

#include <sstream>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
28
#include <pthread.h>
29
#include "EigerCamera.h"
30
#include <eigerapi/Requests.h>
31
#include "lima/Timestamp.h"
32
33
34
35

using namespace lima;
using namespace lima::Eiger;
using namespace std;
36
using namespace eigerapi;
37

38
39
typedef Requests::CommandReq CommandReq;
typedef Requests::ParamReq ParamReq;
Arafat Noureddine's avatar
Arafat Noureddine committed
40

41
42
#define HANDLE_EIGERERROR(req, e) {					\
    THROW_HW_ERROR(Error) << (req)->get_url() << ":" << (e).what();	\
43
44
45
46
}

#define EIGER_SYNC_CMD_TIMEOUT(CommandType,timeout)			\
  {									\
47
    CommandReq cmd = m_requests->get_command(CommandType);		\
48
49
50
51
52
53
54
    try									\
      {									\
	cmd->wait(timeout);						\
      }									\
    catch(const eigerapi::EigerException &e)				\
      {									\
	m_requests->cancel(cmd);					\
55
	HANDLE_EIGERERROR(cmd, e);					\
56
57
58
59
60
61
62
63
      }									\
  }

#define EIGER_SYNC_CMD(CommandType)		\
  EIGER_SYNC_CMD_TIMEOUT(CommandType,CurlLoop::FutureRequest::TIMEOUT)
  
#define EIGER_SYNC_SET_PARAM(ParamType,value)				\
  {									\
64
    ParamReq req =				\
65
66
67
68
69
70
71
      m_requests->set_param(ParamType,value);				\
    try									\
      {									\
	req->wait();							\
      }									\
    catch(const eigerapi::EigerException &e)				\
      {									\
72
	HANDLE_EIGERERROR(req, e);					\
73
74
75
76
77
      }									\
  }

#define EIGER_SYNC_GET_PARAM(ParamType,value)				\
  {									\
78
    ParamReq req =				\
79
80
81
82
83
84
85
86
      m_requests->get_param(ParamType,value);				\
    try									\
      {									\
	req->wait();							\
      }									\
    catch(const eigerapi::EigerException &e)				\
      {									\
	m_requests->cancel(req);					\
87
	HANDLE_EIGERERROR(req, e);					\
88
89
90
      }									\
  }

91
92

/*----------------------------------------------------------------------------
93
			    class MultiParamRequest
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
 ----------------------------------------------------------------------------*/
namespace lima
{
namespace Eiger
{

class MultiParamRequest
{
  DEB_CLASS_NAMESPC(DebModCamera, "MultiParamRequest", "Eiger");

public:
  typedef Requests::PARAM_NAME Name;

  MultiParamRequest(Camera& cam, bool parallel)
    : m_cam(cam), m_parallel(parallel)
  {}

  void addGet(Name name)
  { add(name, m_cam.m_requests->get_param(name)); }

  template <typename T>
  void addGet(Name name, T& var)
  { add(name, m_cam.m_requests->get_param(name, var)); }
	
  template <typename T>
  void addSet(Name name, const T& var)
  { add(name, m_cam.m_requests->set_param(name, var)); }
	
  void wait()
  {
    if (m_parallel) {
      RequestList::const_iterator it, end = m_list.end();
      for (it = m_list.begin(); it != end; ++it)
	wait(*it);
    }
  }

131
  ParamReq operator [](Name name)
132
133
134
  { return m_map[name]; }

private:
135
136
  typedef std::list<ParamReq> RequestList;
  typedef std::map<Name, ParamReq> RequestMap;
137

138
  void add(Name name, ParamReq req)
139
140
141
142
143
144
145
146
  {
    m_list.push_back(req);
    m_map[name] = req;

    if (!m_parallel)
      wait(req);
  }

147
  void wait(ParamReq req)
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
  {
    DEB_MEMBER_FUNCT();

    try {
      req->wait();
    } catch (const eigerapi::EigerException &e) {
      RequestList::const_iterator it, end = m_list.end();
      for (it = m_list.begin(); it != end; ++it)
	m_cam.m_requests->cancel(*it);
      HANDLE_EIGERERROR(req, e);
    }
  }
  
  Camera& m_cam;
  bool m_parallel;
  RequestList m_list;
164
  RequestMap m_map;
165
166
167
168
169
170
};

} // namespace Eiger
} // namespace lima


171
172
173
/*----------------------------------------------------------------------------
			    Callback class
 ----------------------------------------------------------------------------*/
174
class Camera::TriggerCallback : public CurlLoop::FutureRequest::Callback
175
{
176
  DEB_CLASS_NAMESPC(DebModCamera, "Camera::TriggerCallback", "Eiger");
177
public:
178
  TriggerCallback(Camera& cam) : m_cam(cam) {}
179

180
181
  void status_changed(CurlLoop::FutureRequest::Status status,
		      std::string error)
182
  {
183
184
185
186
187
188
    DEB_MEMBER_FUNCT();
    DEB_PARAM() << DEB_VAR2(status, error);
    bool ok = (status == CurlLoop::FutureRequest::OK);
    if (!ok)
      DEB_ERROR() << DEB_VAR1(error); 
    m_cam._trigger_finished(ok);
189
190
191
192
193
194
195
  }
private:
  Camera& m_cam;
};

class Camera::InitCallback : public CurlLoop::FutureRequest::Callback
{	
196
  DEB_CLASS_NAMESPC(DebModCamera, "Camera::InitCallback", "Eiger");
197
198
199
public:
  InitCallback(Camera& cam) : m_cam(cam) {}

200
201
  void status_changed(CurlLoop::FutureRequest::Status status,
		      std::string error)
202
203
  {
    DEB_MEMBER_FUNCT();
204
    DEB_PARAM() << DEB_VAR2(status, error);
205
    bool ok = (status == CurlLoop::FutureRequest::OK);
206
207
208
    if (!ok)
      DEB_ERROR() << DEB_VAR1(error); 
    m_cam._initialization_finished(ok);
209
  }
210

211
212
213
214
private:
  Camera& m_cam;
};

215
216
217
//-----------------------------------------------------------------------------
///  Ctor
//-----------------------------------------------------------------------------
218
Camera::Camera(const std::string& detector_ip, 	///< [in] Ip address of the detector server
219
	       ApiGeneration api)
220
221
  : 		m_api(api),
		m_image_number(0),
222
                m_latency_time(0.),
223
                m_detectorImageType(Bpp16),
224
		m_initialize_state(IDLE),
225
		m_trigger_state(IDLE),
226
		m_armed(false),
227
228
		m_serie_id(0),
                m_requests(new Requests(detector_ip)),
229
                m_exp_time(1.),
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
230
		m_detector_ip(detector_ip)
231
232
{
    DEB_CONSTRUCTOR();
233
    DEB_PARAM() << DEB_VAR1(detector_ip);
234
    // Init EigerAPI
235
236
    try
      {
237
	_synchronize();
238
239
240
241
      }
    catch(Exception& e)
      {
	DEB_ALWAYS() << "Could not get configuration parameters, try to initialize";
242
243
244
245
	initialize();
	AutoMutex lock(m_cond.mutex());
	while (m_initialize_state == RUNNING)
	  m_cond.wait();
246
      }
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265

    // Display max image size
    DEB_TRACE() << "Detector max width: " << m_maxImageWidth;
    DEB_TRACE() << "Detector max height:" << m_maxImageHeight;

    // --- Set detector for software single image mode    
    setTrigMode(IntTrig);

    m_nb_frames = 1;

}


//-----------------------------------------------------------------------------
///  Dtor
//-----------------------------------------------------------------------------
Camera::~Camera()
{
    DEB_DESTRUCTOR();
266
    delete m_requests;
267
268
269
}


270
271
272
273
274
//----------------------------------------------------------------------------
// initialize detector
//----------------------------------------------------------------------------
void Camera::initialize()
{
275
  DEB_MEMBER_FUNCT();
276
277
  // Finally initialize the detector
  AutoMutex lock(m_cond.mutex());
278
279
  DEB_ALWAYS() << "Initializing detector ... ";
  m_initialize_state = RUNNING;
280
  CommandReq async_initialize = m_requests->get_command(Requests::INITIALIZE);
281
  lock.unlock();
282

283
284
  CurlLoop::FutureRequest::CallbackPtr cbk(new InitCallback(*this));
  async_initialize->register_callback(cbk, true);
285
}
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309

void Camera::_initialization_finished(bool ok)
{
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(ok);

  const char *status_desc = ok ? "OK" : "Error";
  DEB_ALWAYS() << "Initialize finished: " << status_desc;

  if (ok) {
    try {
      DEB_ALWAYS() << "Synchronizing with detector ...";
      _synchronize();
      DEB_ALWAYS() << "Done!";
    } catch (const lima::Exception& e) {
      ok = false;
    }
  }
    
  AutoMutex lock(m_cond.mutex());
  m_initialize_state = ok ? Camera::IDLE : Camera::ERROR;
  m_cond.signal();
}

310
311
312
313
314
//-----------------------------------------------------------------------------
/// Set detector for single image acquisition
//-----------------------------------------------------------------------------
void Camera::prepareAcq()
{
315
316
  DEB_MEMBER_FUNCT();
  AutoMutex aLock(m_cond.mutex());
317
318
  if(m_armed)
    THROW_HW_ERROR(Error) << "Camera already armed";
319
  
320
  unsigned nb_images, nb_triggers;
321
322
323
324
  switch(m_trig_mode)
    {
    case IntTrig:
    case ExtTrigSingle:
325
      nb_images = m_nb_frames, nb_triggers = 1; break;
326
327
328
    case IntTrigMult:
    case ExtTrigMult:
    case ExtGate:
329
      nb_images = 1, nb_triggers = m_nb_frames; break;
330
331
332
    default:
      THROW_HW_ERROR(Error) << "Very weird can't be in this case";
    }
333
  double frame_time = m_exp_time + m_latency_time;
334
335
336
337
338
339
340
341
  if(frame_time < m_min_frame_time)
    {    
      if(m_latency_time <= m_readout_time)
	frame_time = m_min_frame_time;
      else
	THROW_HW_ERROR(Error) << "This detector can't go at this frame rate (" << 1 / frame_time
			      << ") is limited to (" << 1 / m_min_frame_time << ")";
    }
342

343
344
  DEB_PARAM() << DEB_VAR3(frame_time, nb_images, nb_triggers);

345
  bool parallel_sync_cmds = (m_api == Eiger1);
346
347
348
349
350
351
352
353
  MultiParamRequest synchro(*this, parallel_sync_cmds);
  if (m_frame_time.changed(frame_time))
    synchro.addSet(Requests::FRAME_TIME, frame_time);
  if (m_nb_images.changed(nb_images))
    synchro.addSet(Requests::NIMAGES, nb_images);
  if (m_nb_triggers.changed(nb_triggers))
    synchro.addSet(Requests::NTRIGGER, nb_triggers);
  synchro.wait();
354

355
  DEB_TRACE() << "Arm start";
356
  double timeout = 5 * 60.; // 5 min timeout
357
  CommandReq arm_cmd = m_requests->get_command(Requests::ARM);
358
359
360
  try
    {
      arm_cmd->wait(timeout);
361
      DEB_TRACE() << "Arm end";
362
      m_serie_id = arm_cmd->get_serie_id();
363
      m_armed = true;
364
365
366
367
    }
  catch(const eigerapi::EigerException &e)
    {
      m_requests->cancel(arm_cmd);
368
      HANDLE_EIGERERROR(arm_cmd, e);
369
370
    }
  m_image_number = 0;
371
372
373
374
375
376
377
378
}


//-----------------------------------------------------------------------------
///  start the acquisition
//-----------------------------------------------------------------------------
void Camera::startAcq()
{
379
380
381
382
383
384
  DEB_MEMBER_FUNCT();
  AutoMutex lock(m_cond.mutex());

  if(m_trig_mode == IntTrig ||
     m_trig_mode == IntTrigMult)
    {
385
386
387
      bool disarm_at_end = ((m_trig_mode == IntTrig) ||
			    (m_image_number == m_nb_frames - 1));
      DEB_TRACE() << "Trigger start: " << DEB_VAR1(disarm_at_end);
388
      CommandReq trigger = m_requests->get_command(Requests::TRIGGER);
389
390
391
      m_trigger_state = RUNNING;
      lock.unlock();

392
393
      CurlLoop::FutureRequest::CallbackPtr cbk(new TriggerCallback(*this));
      trigger->register_callback(cbk, disarm_at_end);
394
395
    }
  
396
397
398
399
400
401
402
403
}


//-----------------------------------------------------------------------------
/// stop the acquisition
//-----------------------------------------------------------------------------
void Camera::stopAcq()
{
404
  DEB_MEMBER_FUNCT();
405
  AutoMutex lock(m_cond.mutex());
406
  EIGER_SYNC_CMD(Requests::ABORT);
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
}


//-----------------------------------------------------------------------------
/// return the detector Max image size 
//-----------------------------------------------------------------------------
void Camera::getDetectorMaxImageSize(Size& size) ///< [out] image dimensions
{
	DEB_MEMBER_FUNCT();
	size = Size(m_maxImageWidth, m_maxImageHeight);
}


//-----------------------------------------------------------------------------
/// return the detector image size 
//-----------------------------------------------------------------------------
void Camera::getDetectorImageSize(Size& size) ///< [out] image dimensions
{
425
426
  DEB_MEMBER_FUNCT();

427
  ParamReq width_request = 
428
    m_requests->get_param(Requests::DETECTOR_WITDH);
429
  ParamReq height_request = 
430
431
432
433
434
    m_requests->get_param(Requests::DETECTOR_HEIGHT);

  Requests::Param::Value width = width_request->get();
  Requests::Param::Value height = height_request->get();
  size = Size(width.data.int_val, height.data.int_val);
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
}


//-----------------------------------------------------------------------------
/// Get the image type
//-----------------------------------------------------------------------------
void Camera::getImageType(ImageType& type) ///< [out] image type
{
    DEB_MEMBER_FUNCT();

    type = m_detectorImageType;    
}


//-----------------------------------------------------------------------------
//! Camera::setImageType()
//-----------------------------------------------------------------------------
void Camera::setImageType(ImageType type) ///< [in] image type
{
	DEB_MEMBER_FUNCT();
	DEB_TRACE() << "Camera::setImageType - " << DEB_VAR1(type);
}


//-----------------------------------------------------------------------------
/// return the detector type
//-----------------------------------------------------------------------------
void Camera::getDetectorType(string& type) ///< [out] detector type
{
  DEB_MEMBER_FUNCT();

  type = m_detector_type;
}


//-----------------------------------------------------------------------------
/// return the detector model
//-----------------------------------------------------------------------------
void Camera::getDetectorModel(string& model) ///< [out] detector model
{
  DEB_MEMBER_FUNCT();

  model = m_detector_model;
}


//-----------------------------------------------------------------------------
/// Checks trigger mode
/*!
@return true if the given trigger mode is supported
*/
//-----------------------------------------------------------------------------
bool Camera::checkTrigMode(TrigMode trig_mode) ///< [in] trigger mode to check
{
489
490
491
492
493
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(trig_mode);
  switch(trig_mode)
    {
    case IntTrig:
494
    case IntTrigMult:
495
496
497
498
499
500
501
    case ExtTrigSingle:
    case ExtTrigMult:
    case ExtGate:
      return true;
    default:
      return false;
    }
502
503
504
505
506
507
508
509
}


//-----------------------------------------------------------------------------
/// Set the new trigger mode
//-----------------------------------------------------------------------------
void Camera::setTrigMode(TrigMode trig_mode) ///< [in] lima trigger mode to set
{
510
511
512
513
514
515
516
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(trig_mode);

  const char *trig_name;
  switch(trig_mode)
    {
    case IntTrig:
517
    case IntTrigMult:
518
519
520
      trig_name = "ints";break;
    case ExtTrigSingle:
    case ExtTrigMult:
521
      trig_name = "exts";break;
522
523
524
525
526
    case ExtGate:
      trig_name = "exte";break;
    default:
      THROW_HW_ERROR(NotSupported) << DEB_VAR1(trig_mode);
    }
527
528
529

  if (m_trig_mode.changed(trig_mode))
    EIGER_SYNC_SET_PARAM(Requests::TRIGGER_MODE,trig_name);
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
}


//-----------------------------------------------------------------------------
/// Get the current trigger mode
//-----------------------------------------------------------------------------
void Camera::getTrigMode(TrigMode& mode) ///< [out] current trigger mode
{
  DEB_MEMBER_FUNCT();
  mode = m_trig_mode;

  DEB_RETURN() << DEB_VAR1(mode);
}


//-----------------------------------------------------------------------------
/// Set the new exposure time
//-----------------------------------------------------------------------------
548
549
void Camera::setExpTime(double exp_time, ///< [in] exposure time to set
			bool force)
550
{
551
552
553
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(exp_time);

554
555
  if (m_exp_time.changed(exp_time) || force)
    EIGER_SYNC_SET_PARAM(Requests::EXPOSURE, exp_time);
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
}


//-----------------------------------------------------------------------------
/// Get the current exposure time
//-----------------------------------------------------------------------------
void Camera::getExpTime(double& exp_time) ///< [out] current exposure time
{
 DEB_MEMBER_FUNCT();

 exp_time = m_exp_time;

 DEB_RETURN() << DEB_VAR1(exp_time);
}


//-----------------------------------------------------------------------------
/// Set the new latency time between images
//-----------------------------------------------------------------------------
void Camera::setLatTime(double lat_time) ///< [in] latency time
{
577
578
579
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(lat_time);

580
  bool force_exp = (lat_time != m_latency_time);
581
  m_latency_time = lat_time;
582
  setExpTime(m_exp_time, force_exp);
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
}


//-----------------------------------------------------------------------------
/// Get the current latency time
//-----------------------------------------------------------------------------
void Camera::getLatTime(double& lat_time) ///< [out] current latency time
{
  DEB_MEMBER_FUNCT();
  
  lat_time = m_latency_time;

  DEB_RETURN() << DEB_VAR1(lat_time);
}


//-----------------------------------------------------------------------------
/// Get the exposure time range
//-----------------------------------------------------------------------------
void Camera::getExposureTimeRange(double& min_expo,	///< [out] minimum exposure time
                                  double& max_expo)   ///< [out] maximum exposure time
const
{
  DEB_MEMBER_FUNCT();
607
  ParamReq exp_time = 
608
609
610
611
612
613
614
615
    m_requests->get_param(Requests::EXPOSURE);
  try
    {
      exp_time->wait();
    }
  catch(const eigerapi::EigerException &e)
    {
      m_requests->cancel(exp_time);
616
      HANDLE_EIGERERROR(exp_time, e);
617
618
619
    }

  Requests::Param::Value min_val = exp_time->get_min();
620
621
622
623
624
625
  Requests::Param::Value max_val;
  if (m_api == Eiger1)
    max_val = exp_time->get_max();
  else
    max_val.data.double_val = 1800;

626
627
  min_expo = min_val.data.double_val;
  max_expo = max_val.data.double_val;
628
629
630
631
632
633
634
635
636
637
638
639
640
641
  DEB_RETURN() << DEB_VAR2(min_expo, max_expo);
}


//-----------------------------------------------------------------------------
///  Get the latency time range
//-----------------------------------------------------------------------------
void Camera::getLatTimeRange(double& min_lat, ///< [out] minimum latency
                             double& max_lat) ///< [out] maximum latency
const
{
  DEB_MEMBER_FUNCT();

    // --- no info on min latency
642
643
644
645
  min_lat = m_readout_time;
  double min_exp,max_exp;
  getExposureTimeRange(min_exp,max_exp);
  max_lat = max_exp;
646
647
648
649
650
651
652
653
654
655
656
657
658
659

  DEB_RETURN() << DEB_VAR2(min_lat, max_lat);
}


//-----------------------------------------------------------------------------
/// Set the number of frames to be taken
//-----------------------------------------------------------------------------
void Camera::setNbFrames(int nb_frames) ///< [in] number of frames to take
{
    DEB_MEMBER_FUNCT();
    DEB_PARAM() << DEB_VAR1(nb_frames);

    if (0==nb_frames)
660
      THROW_HW_ERROR(NotSupported) << "video mode is not supported";
661

662
    m_nb_frames = nb_frames;
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
}


//-----------------------------------------------------------------------------
/// Get the number of frames to be taken
//-----------------------------------------------------------------------------
void Camera::getNbFrames(int& nb_frames) ///< [out] current number of frames to take
{
  DEB_MEMBER_FUNCT();
  nb_frames = m_nb_frames;
  DEB_RETURN() << DEB_VAR1(nb_frames);
}


//-----------------------------------------------------------------------------
/// Get the current acquired frames
//-----------------------------------------------------------------------------
void Camera::getNbHwAcquiredFrames(int &nb_acq_frames) ///< [out] number of acquired files
{ 
  DEB_MEMBER_FUNCT();    
  nb_acq_frames = m_image_number;
}


//-----------------------------------------------------------------------------
/// Get the camera status
//-----------------------------------------------------------------------------
Camera::Status Camera::getStatus() ///< [out] current camera status
{
692
693
694
695
  DEB_MEMBER_FUNCT();

  Camera::Status status;
  AutoMutex lock(m_cond.mutex());
696
  if(m_initialize_state == ERROR ||
697
698
699
700
     m_trigger_state == ERROR)
    status = Fault;
  else if(m_trigger_state == RUNNING)
    status = Exposure;
701
702
  else if(m_armed)
    status = Armed;
703
704
  else if(m_initialize_state == RUNNING)
    status = Initializing;
705
706
707
708
709
  else
    status = Ready;

  DEB_RETURN() << DEB_VAR1(status);
  return status;
710
}
711
712
713
714
715
716
717
718
719
720
//----------------------------------------------------------------------------
// Get camera hardware status
//----------------------------------------------------------------------------
std::string Camera::getCamStatus()
{
  DEB_MEMBER_FUNCT();
  std::string status;
  EIGER_SYNC_GET_PARAM(Requests::DETECTOR_STATUS,status);
  return status;
}
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
//-----------------------------------------------------------------------------
/// Tells if binning is available
/*!
@return always false, hw binning mode is not supported
*/
//-----------------------------------------------------------------------------
bool Camera::isBinningAvailable()
{
  DEB_MEMBER_FUNCT();
  return false;
}


//-----------------------------------------------------------------------------
/// return the detector pixel size in meter
//-----------------------------------------------------------------------------
void Camera::getPixelSize(double& sizex,	///< [out] horizontal pixel size
                          double& sizey)	///< [out] vertical   pixel size
{
  DEB_MEMBER_FUNCT();

  sizex = m_x_pixelsize;
  sizey = m_y_pixelsize;
  DEB_RETURN() << DEB_VAR2(sizex, sizey); 
}


//-----------------------------------------------------------------------------
/// reset the camera, no hw reset available on Eiger camera
//-----------------------------------------------------------------------------
/*
void Camera::reset()
{
    DEB_MEMBER_FUNCT();
    return;
}
*/

//-----------------------------------------------------------------------------
760
///    synchronize with controller
761
//-----------------------------------------------------------------------------
762
void Camera::_synchronize()
763
{
764
  DEB_MEMBER_FUNCT();
765
766
767
768
769
770
  DEB_TRACE() << "_synchronize()";

  AutoMutex lock(m_cond.mutex());

  bool parallel_sync_cmds = (m_api == Eiger1);
  MultiParamRequest synchro(*this, parallel_sync_cmds);
771
772

  std::string trig_name;
773
  synchro.addGet(Requests::TRIGGER_MODE, trig_name);
774
  
775
776
  synchro.addGet(Requests::X_PIXEL_SIZE, m_x_pixelsize);
  synchro.addGet(Requests::Y_PIXEL_SIZE, m_y_pixelsize);
777

778
779
  synchro.addGet(Requests::DETECTOR_WITDH, m_maxImageWidth);
  synchro.addGet(Requests::DETECTOR_HEIGHT, m_maxImageHeight);
780

781
  synchro.addGet(Requests::DETECTOR_READOUT_TIME, m_readout_time);
782

783
784
785
786
  synchro.addGet(Requests::DESCRIPTION, m_detector_model);
  synchro.addGet(Requests::DETECTOR_NUMBER, m_detector_type);
  synchro.addGet(Requests::EXPOSURE, m_exp_time);
  synchro.addGet(Requests::NIMAGES, m_nb_images);
787
  
788
789
  synchro.addGet(Requests::NTRIGGER, m_nb_triggers);
  synchro.addGet(Requests::FRAME_TIME, m_frame_time);
790
791

  bool auto_summation;
792
  synchro.addGet(Requests::AUTO_SUMMATION, auto_summation);
793
794
795

  std::string compression_type;
  synchro.addGet(Requests::COMPRESSION_TYPE, compression_type);
796
  
797
  //Synchro
798
  synchro.wait();
799

800
  m_detectorImageType = auto_summation ? Bpp32 : Bpp16;
801
  _updateImageSize();
802
803
804

  //Trigger mode
  if(trig_name == "ints")
805
    m_trig_mode = m_nb_triggers > 1 ? IntTrigMult : IntTrig;
806
  else if(trig_name == "exts")
807
    m_trig_mode = m_nb_triggers > 1 ? ExtTrigMult : ExtTrigSingle;
808
809
810
  else if(trig_name == "exte")
    m_trig_mode = ExtGate;
  else
811
812
    THROW_HW_ERROR(InvalidValue) << "Unexpected trigger mode: "
				 << DEB_VAR1(trig_name);
813
  
814
  Requests::Param::Value min_frame_time = synchro[Requests::FRAME_TIME]->get_min();
815
  m_min_frame_time = min_frame_time.data.double_val;
816
817
818
819
820
821
822
823
824
825

  if (compression_type == "none")
    m_compression_type = NoCompression;
  else if (compression_type == "lz4")
    m_compression_type = LZ4;
  else if (compression_type == "bslz4")
    m_compression_type = BSLZ4;
  else
    THROW_HW_ERROR(InvalidValue) << "Unexpected compression type: "
				 << DEB_VAR1(compression_type);
826
827
828
829
830
831
832
833
834
835
836
837
838
839
}

//----------------------------------------------------------------------------
//	ImageSizeChanged hook
//----------------------------------------------------------------------------
void Camera::_updateImageSize()
{
  DEB_MEMBER_FUNCT();
  Size image_size;
  getDetectorImageSize(image_size);
  DEB_TRACE() << DEB_VAR2(image_size,m_detectorImageType);
  maxImageSizeChanged(image_size,m_detectorImageType);
}

840
/*----------------------------------------------------------------------------
841
	This method is called when the trigger is finished
842
  ----------------------------------------------------------------------------*/
843
void Camera::_trigger_finished(bool ok)
844
845
846
847
{
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(ok);
  
848
  DEB_TRACE() << "Trigger end";
849
  if(!ok)
850
    DEB_ERROR() << "Error in trigger command";
851
  else if(allFramesAcquired())
852
853
    try { disarm(); }
    catch (...) { ok = false; }
854
855
856
857

  AutoMutex lock(m_cond.mutex());
  m_trigger_state = ok ? IDLE : ERROR;
}
858

859
bool Camera::allFramesAcquired()
860
861
862
{
  DEB_MEMBER_FUNCT();
  AutoMutex lock(m_cond.mutex());
863
864
  DEB_PARAM() << DEB_VAR2(m_image_number, m_nb_frames);
  bool finished = (m_image_number == m_nb_frames);
865
866
867
  DEB_RETURN() << DEB_VAR1(finished);
  return finished;
}
868
869
870
871
872
873
874
875
876
877
878
879
880
881

//-----------------------------------------------------------------------------
/// Returns the API generation of the detector
/*!
@return temperature value
*/
//-----------------------------------------------------------------------------
void Camera::getApiGeneration(ApiGeneration& api)
{
  DEB_MEMBER_FUNCT();
  api = m_api;
  DEB_RETURN() << DEB_VAR1(api);
}

882
883
884
885
886
887
//-----------------------------------------------------------------------------
/// Returns the temperature of the detector
/*!
@return temperature value
*/
//-----------------------------------------------------------------------------
888
void Camera::getTemperature(double &temp)
889
{
890
891
  DEB_MEMBER_FUNCT();
  EIGER_SYNC_GET_PARAM(Requests::TEMP,temp);
892
893
894
895
896
897
898
899
900
}


//-----------------------------------------------------------------------------
/// Returns the humidity of the detector
/*!
@return humidity value
*/
//-----------------------------------------------------------------------------
901
void Camera::getHumidity(double &humidity)
902
{
903
904
  DEB_MEMBER_FUNCT();
  EIGER_SYNC_GET_PARAM(Requests::HUMIDITY,humidity);
905
906
907
908
909
910
}


//-----------------------------------------------------------------------------
///  Count rate correction setter
//-----------------------------------------------------------------------------
911
void Camera::setCountrateCorrection(bool value) ///< [in] true:enabled, false:disabled
912
{
913
914
    DEB_MEMBER_FUNCT();
    EIGER_SYNC_SET_PARAM(Requests::COUNTRATE_CORRECTION,value);
915
916
917
918
919
920
921
922
}


//-----------------------------------------------------------------------------
///  Count rate correction getter
//-----------------------------------------------------------------------------
void Camera::getCountrateCorrection(bool& value)  ///< [out] true:enabled, false:disabled
{
923
924
  DEB_MEMBER_FUNCT();
  EIGER_SYNC_GET_PARAM(Requests::COUNTRATE_CORRECTION,value);
925
926
927
928
929
930
}


//-----------------------------------------------------------------------------
///  FlatfieldCorrection setter
//-----------------------------------------------------------------------------
931
void Camera::setFlatfieldCorrection(bool value) ///< [in] true:enabled, false:disabled
932
{
933
  DEB_MEMBER_FUNCT();
934
  EIGER_SYNC_SET_PARAM(Requests::FLATFIELD_CORRECTION,value);
935
936
937
938
939
940
941
942
943
944
945
}


//-----------------------------------------------------------------------------
///  FlatfieldCorrection getter
//-----------------------------------------------------------------------------
void Camera::getFlatfieldCorrection(bool& value) ///< [out] true:enabled, false:disabled
{
  DEB_MEMBER_FUNCT();
  EIGER_SYNC_GET_PARAM(Requests::FLATFIELD_CORRECTION,value);
}
946
947

//----------------------------------------------------------------------------
948
// Auto Summation setter
949
950
951
952
953
954
955
//----------------------------------------------------------------------------
void Camera::setAutoSummation(bool value)
{
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(value);
  EIGER_SYNC_SET_PARAM(Requests::AUTO_SUMMATION,value);
  m_detectorImageType = value ? Bpp32 : Bpp16;
956
  _updateImageSize();
957
}
958
959
960
961

//----------------------------------------------------------------------------
// Auto Summation getter
//----------------------------------------------------------------------------
962
963
964
965
966
967
void Camera::getAutoSummation(bool& value)
{
  DEB_MEMBER_FUNCT();
  EIGER_SYNC_GET_PARAM(Requests::AUTO_SUMMATION,value);
  DEB_RETURN() << DEB_VAR1(value);
}
968
969
970
//-----------------------------------------------------------------------------
///  PixelMask setter
//-----------------------------------------------------------------------------
971
void Camera::setPixelMask(bool value) ///< [in] true:enabled, false:disabled
972
{
973
974
    DEB_MEMBER_FUNCT();
    EIGER_SYNC_SET_PARAM(Requests::PIXEL_MASK,value);
975
976
977
978
979
980
981
982
}


//-----------------------------------------------------------------------------
///  PixelMask getter
//-----------------------------------------------------------------------------
void Camera::getPixelMask(bool& value) ///< [out] true:enabled, false:disabled
{
983
984
  DEB_MEMBER_FUNCT();
  EIGER_SYNC_GET_PARAM(Requests::PIXEL_MASK,value);
985
986
987
988
989
}

//-----------------------------------------------------------------------------
/// EfficiencyCorrection setter
//-----------------------------------------------------------------------------
990
void Camera::setEfficiencyCorrection(bool enabled) ///< [in] true:enabled, false:disabled
991
{
992
    DEB_MEMBER_FUNCT();
993
994
995
996
997
    if (m_api == Eiger1) {
        EIGER_SYNC_SET_PARAM(Requests::EFFICIENCY_CORRECTION,enabled);
    } else {
        DEB_WARNING() << "Efficiency correction is not implemented";
    }
998
999
1000
}


For faster browsing, not all history is shown. View entire blame