EigerCamera.cpp 37.6 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
40
typedef Requests::CommandReq CommandReq;
typedef Requests::ParamReq ParamReq;
typedef Requests::TransferReq TransferReq;
Arafat Noureddine's avatar
Arafat Noureddine committed
41

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

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

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

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

92
93
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
131

/*----------------------------------------------------------------------------
			    Callback MultiParamRequest
 ----------------------------------------------------------------------------*/
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);
    }
  }

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

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

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

    if (!m_parallel)
      wait(req);
  }

148
  void wait(ParamReq req)
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
  {
    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;
165
  RequestMap m_map;
166
167
168
169
170
171
};

} // namespace Eiger
} // namespace lima


172
173
174
/*----------------------------------------------------------------------------
			    Callback class
 ----------------------------------------------------------------------------*/
175
class Camera::TriggerCallback : public CurlLoop::FutureRequest::Callback
176
177
{
public:
178
  TriggerCallback(Camera& cam) : m_cam(cam) {}
179
180
181

  void status_changed(CurlLoop::FutureRequest::Status status)
  {
182
    m_cam._trigger_finished(status == CurlLoop::FutureRequest::OK);
183
184
185
186
187
188
189
  }
private:
  Camera& m_cam;
};

class Camera::InitCallback : public CurlLoop::FutureRequest::Callback
{	
190
  DEB_CLASS_NAMESPC(DebModCamera, "Camera::InitCallback", "Eiger");
191
192
193
194
195
196
197
198
public:
  InitCallback(Camera& cam) : m_cam(cam) {}

  void status_changed(CurlLoop::FutureRequest::Status status)
  {
    DEB_MEMBER_FUNCT();
    DEB_PARAM() << DEB_VAR1(status);

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
    bool ok = (status == CurlLoop::FutureRequest::OK);
    DEB_TRACE() << DEB_VAR1(ok); 

    // run post-initialization code on detached thread
    AutoPtr<Pars> pars = new Pars{m_cam, ok};
    pthread_t thread;
    pthread_attr_t attr;
    if (pthread_attr_init(&attr)) {
      DEB_ERROR() << "could not init thread attr";
    } else if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) {
      DEB_ERROR() << "could not set thread attr detached state";
    } else if (pthread_create(&thread, &attr, &thread_func, pars)) {
      DEB_ERROR() << "could not create thread";
    } else {
      DEB_TRACE() << "thread created OK";
      pars.forget();
    }
216
  }
217

218
private:
219
220
221
222
223
224
225
226
227
228
229
230
231
232
  struct Pars {
    Camera& cam;
    bool ok;
  };

  static void *thread_func(void *data)
  {
    DEB_STATIC_FUNCT();
    AutoPtr<Pars> pars = (Pars *) data;
    DEB_PARAM() << DEB_VAR1(pars->ok);
    pars->cam._initialization_finished(pars->ok);
    return NULL;
  }

233
234
235
  Camera& m_cam;
};

236
237
238
//-----------------------------------------------------------------------------
///  Ctor
//-----------------------------------------------------------------------------
239
Camera::Camera(const std::string& detector_ip, 	///< [in] Ip address of the detector server
240
	       ApiGeneration api)
241
242
  : 		m_api(api),
		m_image_number(0),
243
                m_latency_time(0.),
244
                m_detectorImageType(Bpp16),
245
		m_initialize_state(IDLE),
246
247
248
		m_trigger_state(IDLE),
		m_serie_id(0),
                m_requests(new Requests(detector_ip)),
249
                m_exp_time(1.),
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
250
		m_detector_ip(detector_ip)
251
252
{
    DEB_CONSTRUCTOR();
253
    DEB_PARAM() << DEB_VAR1(detector_ip);
254
    // Init EigerAPI
255
256
    try
      {
257
	_synchronize();
258
259
260
261
      }
    catch(Exception& e)
      {
	DEB_ALWAYS() << "Could not get configuration parameters, try to initialize";
262
263
264
265
	initialize();
	AutoMutex lock(m_cond.mutex());
	while (m_initialize_state == RUNNING)
	  m_cond.wait();
266
      }
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

    // 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();
286
    delete m_requests;
287
288
289
}


290
291
292
293
294
//----------------------------------------------------------------------------
// initialize detector
//----------------------------------------------------------------------------
void Camera::initialize()
{
295
  DEB_MEMBER_FUNCT();
296
297
  // Finally initialize the detector
  AutoMutex lock(m_cond.mutex());
298
299
  DEB_ALWAYS() << "Initializing detector ... ";
  m_initialize_state = RUNNING;
300
  CommandReq async_initialize = m_requests->get_command(Requests::INITIALIZE);
301
  lock.unlock();
302
303

  std::shared_ptr<CurlLoop::FutureRequest::Callback> cbk(new InitCallback(*this));
304
  async_initialize->register_callback(cbk);
305
}
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329

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();
}

330
331
332
333
334
//-----------------------------------------------------------------------------
/// Set detector for single image acquisition
//-----------------------------------------------------------------------------
void Camera::prepareAcq()
{
335
336
337
338
  DEB_MEMBER_FUNCT();
  AutoMutex aLock(m_cond.mutex());
  if(m_trigger_state != IDLE)
    EIGER_SYNC_CMD(Requests::DISARM);
339
  
340
  unsigned nb_images, nb_triggers;
341
342
343
344
  switch(m_trig_mode)
    {
    case IntTrig:
    case ExtTrigSingle:
345
      nb_images = m_nb_frames, nb_triggers = 1; break;
346
347
348
    case IntTrigMult:
    case ExtTrigMult:
    case ExtGate:
349
      nb_images = 1, nb_triggers = m_nb_frames; break;
350
351
352
    default:
      THROW_HW_ERROR(Error) << "Very weird can't be in this case";
    }
353
  double frame_time = m_exp_time + m_latency_time;
354
355
356
357
358
359
360
361
  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 << ")";
    }
362

363
364
  DEB_PARAM() << DEB_VAR3(frame_time, nb_images, nb_triggers);

365
  bool parallel_sync_cmds = (m_api == Eiger1);
366
367
368
369
370
371
372
373
  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();
374

375
  DEB_TRACE() << "Arm start";
376
  double timeout = 5 * 60.; // 5 min timeout
377
  CommandReq arm_cmd = m_requests->get_command(Requests::ARM);
378
379
380
  try
    {
      arm_cmd->wait(timeout);
381
      DEB_TRACE() << "Arm end";
382
383
384
385
386
      m_serie_id = arm_cmd->get_serie_id();
    }
  catch(const eigerapi::EigerException &e)
    {
      m_requests->cancel(arm_cmd);
387
      HANDLE_EIGERERROR(arm_cmd, e);
388
389
    }
  m_image_number = 0;
390
391
392
393
394
395
396
397
}


//-----------------------------------------------------------------------------
///  start the acquisition
//-----------------------------------------------------------------------------
void Camera::startAcq()
{
398
399
400
401
402
403
404
  DEB_MEMBER_FUNCT();
  AutoMutex lock(m_cond.mutex());


  if(m_trig_mode == IntTrig ||
     m_trig_mode == IntTrigMult)
    {
405
      DEB_TRACE() << "Trigger start";
406
      CommandReq trigger = m_requests->get_command(Requests::TRIGGER);
407
408
409
      m_trigger_state = RUNNING;
      lock.unlock();

410
      std::shared_ptr<CurlLoop::FutureRequest::Callback> cbk(new TriggerCallback(*this));
411
412
413
      trigger->register_callback(cbk);
    }
  
414
415
416
417
418
419
420
421
}


//-----------------------------------------------------------------------------
/// stop the acquisition
//-----------------------------------------------------------------------------
void Camera::stopAcq()
{
422
  DEB_MEMBER_FUNCT();
423
  EIGER_SYNC_CMD(Requests::ABORT);
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
}


//-----------------------------------------------------------------------------
/// 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
{
442
443
  DEB_MEMBER_FUNCT();

444
  ParamReq width_request = 
445
    m_requests->get_param(Requests::DETECTOR_WITDH);
446
  ParamReq height_request = 
447
448
449
450
451
    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);
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
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
}


//-----------------------------------------------------------------------------
/// 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
{
506
507
508
509
510
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(trig_mode);
  switch(trig_mode)
    {
    case IntTrig:
511
    case IntTrigMult:
512
513
514
515
516
517
518
    case ExtTrigSingle:
    case ExtTrigMult:
    case ExtGate:
      return true;
    default:
      return false;
    }
519
520
521
522
523
524
525
526
}


//-----------------------------------------------------------------------------
/// Set the new trigger mode
//-----------------------------------------------------------------------------
void Camera::setTrigMode(TrigMode trig_mode) ///< [in] lima trigger mode to set
{
527
528
529
530
531
532
533
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(trig_mode);

  const char *trig_name;
  switch(trig_mode)
    {
    case IntTrig:
534
    case IntTrigMult:
535
536
537
      trig_name = "ints";break;
    case ExtTrigSingle:
    case ExtTrigMult:
538
      trig_name = "exts";break;
539
540
541
542
543
    case ExtGate:
      trig_name = "exte";break;
    default:
      THROW_HW_ERROR(NotSupported) << DEB_VAR1(trig_mode);
    }
544
545
546

  if (m_trig_mode.changed(trig_mode))
    EIGER_SYNC_SET_PARAM(Requests::TRIGGER_MODE,trig_name);
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
}


//-----------------------------------------------------------------------------
/// 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
//-----------------------------------------------------------------------------
565
566
void Camera::setExpTime(double exp_time, ///< [in] exposure time to set
			bool force)
567
{
568
569
570
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(exp_time);

571
572
  if (m_exp_time.changed(exp_time) || force)
    EIGER_SYNC_SET_PARAM(Requests::EXPOSURE, exp_time);
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
}


//-----------------------------------------------------------------------------
/// 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
{
594
595
596
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(lat_time);

597
  bool force_exp = (lat_time != m_latency_time);
598
  m_latency_time = lat_time;
599
  setExpTime(m_exp_time, force_exp);
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
}


//-----------------------------------------------------------------------------
/// 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();
624
  ParamReq exp_time = 
625
626
627
628
629
630
631
632
    m_requests->get_param(Requests::EXPOSURE);
  try
    {
      exp_time->wait();
    }
  catch(const eigerapi::EigerException &e)
    {
      m_requests->cancel(exp_time);
633
      HANDLE_EIGERERROR(exp_time, e);
634
635
636
    }

  Requests::Param::Value min_val = exp_time->get_min();
637
638
639
640
641
642
  Requests::Param::Value max_val;
  if (m_api == Eiger1)
    max_val = exp_time->get_max();
  else
    max_val.data.double_val = 1800;

643
644
  min_expo = min_val.data.double_val;
  max_expo = max_val.data.double_val;
645
646
647
648
649
650
651
652
653
654
655
656
657
658
  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
659
660
661
662
  min_lat = m_readout_time;
  double min_exp,max_exp;
  getExposureTimeRange(min_exp,max_exp);
  max_lat = max_exp;
663
664
665
666
667
668
669
670
671
672
673
674
675
676

  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)
677
      THROW_HW_ERROR(NotSupported) << "video mode is not supported";
678

679
    m_nb_frames = nb_frames;
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
}


//-----------------------------------------------------------------------------
/// 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
{
709
710
711
712
  DEB_MEMBER_FUNCT();

  Camera::Status status;
  AutoMutex lock(m_cond.mutex());
713
  if(m_initialize_state == ERROR ||
714
715
716
717
     m_trigger_state == ERROR)
    status = Fault;
  else if(m_trigger_state == RUNNING)
    status = Exposure;
718
719
  else if(m_initialize_state == RUNNING)
    status = Initializing;
720
721
722
723
724
  else
    status = Ready;

  DEB_RETURN() << DEB_VAR1(status);
  return status;
725
}
726
727
728
729
730
731
732
733
734
735
//----------------------------------------------------------------------------
// Get camera hardware status
//----------------------------------------------------------------------------
std::string Camera::getCamStatus()
{
  DEB_MEMBER_FUNCT();
  std::string status;
  EIGER_SYNC_GET_PARAM(Requests::DETECTOR_STATUS,status);
  return status;
}
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
//-----------------------------------------------------------------------------
/// 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;
}
*/

//-----------------------------------------------------------------------------
775
///    synchronize with controller
776
//-----------------------------------------------------------------------------
777
void Camera::_synchronize()
778
{
779
  DEB_MEMBER_FUNCT();
780
781
782
783
784
785
  DEB_TRACE() << "_synchronize()";

  AutoMutex lock(m_cond.mutex());

  bool parallel_sync_cmds = (m_api == Eiger1);
  MultiParamRequest synchro(*this, parallel_sync_cmds);
786
787

  std::string trig_name;
788
  synchro.addGet(Requests::TRIGGER_MODE, trig_name);
789
  
790
791
  synchro.addGet(Requests::X_PIXEL_SIZE, m_x_pixelsize);
  synchro.addGet(Requests::Y_PIXEL_SIZE, m_y_pixelsize);
792

793
794
  synchro.addGet(Requests::DETECTOR_WITDH, m_maxImageWidth);
  synchro.addGet(Requests::DETECTOR_HEIGHT, m_maxImageHeight);
795

796
  synchro.addGet(Requests::DETECTOR_READOUT_TIME, m_readout_time);
797

798
799
800
801
  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);
802
  
803
804
  synchro.addGet(Requests::NTRIGGER, m_nb_triggers);
  synchro.addGet(Requests::FRAME_TIME, m_frame_time);
805
806

  bool auto_summation;
807
  synchro.addGet(Requests::AUTO_SUMMATION, auto_summation);
808
809
810

  std::string compression_type;
  synchro.addGet(Requests::COMPRESSION_TYPE, compression_type);
811
  
812
  //Synchro
813
  synchro.wait();
814

815
  m_detectorImageType = auto_summation ? Bpp32 : Bpp16;
816
  _updateImageSize();
817
818
819

  //Trigger mode
  if(trig_name == "ints")
820
    m_trig_mode = m_nb_triggers > 1 ? IntTrigMult : IntTrig;
821
  else if(trig_name == "exts")
822
    m_trig_mode = m_nb_triggers > 1 ? ExtTrigMult : ExtTrigSingle;
823
824
825
  else if(trig_name == "exte")
    m_trig_mode = ExtGate;
  else
826
827
    THROW_HW_ERROR(InvalidValue) << "Unexpected trigger mode: "
				 << DEB_VAR1(trig_name);
828
  
829
  Requests::Param::Value min_frame_time = synchro[Requests::FRAME_TIME]->get_min();
830
  m_min_frame_time = min_frame_time.data.double_val;
831
832
833
834
835
836
837
838
839
840

  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);
841
842
843
844
845
846
847
848
849
850
851
852
853
854
}

//----------------------------------------------------------------------------
//	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);
}

855
/*----------------------------------------------------------------------------
856
	This method is called when the trigger is finished
857
  ----------------------------------------------------------------------------*/
858
void Camera::_trigger_finished(bool ok)
859
860
861
862
{
  DEB_MEMBER_FUNCT();
  DEB_PARAM() << DEB_VAR1(ok);
  
863
864
865
  DEB_TRACE() << "Trigger end";
  if (!ok)
    DEB_ERROR() << "Error in trigger command";
866
867
868

  AutoMutex lock(m_cond.mutex());
  m_trigger_state = ok ? IDLE : ERROR;
869
870
871
872
873
  lock.unlock();

  // Disarm at acq end
  if(isAcquisitionFinished())
    CommandReq disarm = m_requests->get_command(Requests::DISARM);
874
}
875

876
877
878
879
880
881
882
883
884
885
886
bool Camera::isAcquisitionFinished()
{
  DEB_MEMBER_FUNCT();
  AutoMutex lock(m_cond.mutex());
  DEB_PARAM() << DEB_VAR3(m_trigger_state, m_trigger_state, m_image_number);
  bool finished = ((m_trigger_state == IDLE) &&
		   ((m_trig_mode != IntTrigMult) ||
		    (m_image_number == m_nb_frames)));
  DEB_RETURN() << DEB_VAR1(finished);
  return finished;
}
887
888
889
890
891
892
893
894
895
896
897
898
899
900

//-----------------------------------------------------------------------------
/// 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);
}

901
902
903
904
905
906
//-----------------------------------------------------------------------------
/// Returns the temperature of the detector
/*!
@return temperature value
*/
//-----------------------------------------------------------------------------
907
void Camera::getTemperature(double &temp)
908
{
909
910
  DEB_MEMBER_FUNCT();
  EIGER_SYNC_GET_PARAM(Requests::TEMP,temp);
911
912
913
914
915
916
917
918
919
}


//-----------------------------------------------------------------------------
/// Returns the humidity of the detector
/*!
@return humidity value
*/
//-----------------------------------------------------------------------------
920
void Camera::getHumidity(double &humidity)
921
{
922
923
  DEB_MEMBER_FUNCT();
  EIGER_SYNC_GET_PARAM(Requests::HUMIDITY,humidity);
924
925
926
927
928
929
}


//-----------------------------------------------------------------------------
///  Count rate correction setter
//-----------------------------------------------------------------------------
930
void Camera::setCountrateCorrection(bool value) ///< [in] true:enabled, false:disabled
931
{
932
933
    DEB_MEMBER_FUNCT();
    EIGER_SYNC_SET_PARAM(Requests::COUNTRATE_CORRECTION,value);
934
935
936
937
938
939
940
941
}


//-----------------------------------------------------------------------------
///  Count rate correction getter
//-----------------------------------------------------------------------------
void Camera::getCountrateCorrection(bool& value)  ///< [out] true:enabled, false:disabled
{
942
943
  DEB_MEMBER_FUNCT();
  EIGER_SYNC_GET_PARAM(Requests::COUNTRATE_CORRECTION,value);
944
945
946
947
948
949
}


//-----------------------------------------------------------------------------
///  FlatfieldCorrection setter
//-----------------------------------------------------------------------------
950
void Camera::setFlatfieldCorrection(bool value) ///< [in] true:enabled, false:disabled
951
{
952
  DEB_MEMBER_FUNCT();
953
  EIGER_SYNC_SET_PARAM(Requests::FLATFIELD_CORRECTION,value);
954
955
956
957
958
959
960
961
962
963
964
}


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

//----------------------------------------------------------------------------
967
// Auto Summation setter
968
969
970
971
972
973
974
//----------------------------------------------------------------------------
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;
975
  _updateImageSize();
976
}
977
978
979
980

//----------------------------------------------------------------------------
// Auto Summation getter
//----------------------------------------------------------------------------
981
982
983
984
985
986
void Camera::getAutoSummation(bool& value)
{
  DEB_MEMBER_FUNCT();
  EIGER_SYNC_GET_PARAM(Requests::AUTO_SUMMATION,value);
  DEB_RETURN() << DEB_VAR1(value);
}
987
988
989
//-----------------------------------------------------------------------------
///  PixelMask setter
//-----------------------------------------------------------------------------
990
void Camera::setPixelMask(bool value) ///< [in] true:enabled, false:disabled
991
{
992
993
    DEB_MEMBER_FUNCT();
    EIGER_SYNC_SET_PARAM(Requests::PIXEL_MASK,value);
994
995
996
997
998
999
1000
}


//-----------------------------------------------------------------------------
///  PixelMask getter
//-----------------------------------------------------------------------------
void Camera::getPixelMask(bool& value) ///< [out] true:enabled, false:disabled
For faster browsing, not all history is shown. View entire blame