API
picamCtrl.hpp
Go to the documentation of this file.
1 /** \file picamCtrl.hpp
2  * \brief The MagAO-X Princeton Instruments EMCCD camera controller.
3  *
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  * \ingroup picamCtrl_files
7  */
8 
9 #ifndef picamCtrl_hpp
10 #define picamCtrl_hpp
11 
12 
13 //#include <ImageStruct.h>
14 #include <ImageStreamIO/ImageStreamIO.h>
15 
16 #include <picam_advanced.h>
17 
18 #include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
19 #include "../../magaox_git_version.h"
20 
21 #define DEBUG
22 
23 #ifdef DEBUG
24 #define BREADCRUMB std::cerr << __FILE__ << " " << __LINE__ << "\n";
25 #else
26 #define BREADCRUMB
27 #endif
28 
29 inline
30 std::string PicamEnum2String( PicamEnumeratedType type, piint value )
31 {
32  const pichar* string;
33  Picam_GetEnumerationString( type, value, &string );
34  std::string str(string);
35  Picam_DestroyString( string );
36 
37  return str;
38 }
39 
40 namespace MagAOX
41 {
42 namespace app
43 {
44 
45 int readoutParams( piint & adcQual,
46  piflt & adcSpeed,
47  const std::string & rosn
48  )
49 {
50  if(rosn == "ccd_00_1MHz")
51  {
52  adcQual = PicamAdcQuality_LowNoise;
53  adcSpeed = 0.1;
54  }
55  else if(rosn == "ccd_01MHz")
56  {
57  adcQual = PicamAdcQuality_LowNoise;
58  adcSpeed = 1;
59  }
60  else if(rosn == "emccd_05MHz")
61  {
62  adcQual = PicamAdcQuality_ElectronMultiplied;
63  adcSpeed = 5;
64  }
65  else if(rosn == "emccd_10MHz")
66  {
67  adcQual = PicamAdcQuality_ElectronMultiplied;
68  adcSpeed = 10;
69  }
70  else if(rosn == "emccd_20MHz")
71  {
72  adcQual = PicamAdcQuality_ElectronMultiplied;
73  adcSpeed = 20;
74  }
75  else if(rosn == "emccd_30MHz")
76  {
77  adcQual = PicamAdcQuality_ElectronMultiplied;
78  adcSpeed = 30;
79  }
80  else
81  {
82  return -1;
83  }
84 
85  return 0;
86 }
87 
88 int vshiftParams( piflt & vss,
89  const std::string & vsn
90  )
91 {
92  if(vsn == "0_7us")
93  {
94  vss = 0.7;
95  }
96  else if(vsn == "1_2us")
97  {
98  vss = 1.2;
99  }
100  else if(vsn == "2_0us")
101  {
102  vss = 2.0;
103  }
104  else if(vsn == "5_0us")
105  {
106  vss = 5.0;
107  }
108  else
109  {
110  return -1;
111  }
112 
113  return 0;
114 }
115 
116 
117 /** \defgroup picamCtrl Princeton Instruments EMCCD Camera
118  * \brief Control of a Princeton Instruments EMCCD Camera.
119  *
120  * <a href="../handbook/operating/software/apps/picamCtrl.html">Application Documentation</a>
121  *
122  * \ingroup apps
123  *
124  */
125 
126 /** \defgroup picamCtrl_files Princeton Instruments EMCCD Camera Files
127  * \ingroup picamCtrl
128  */
129 
130 /** MagAO-X application to control a Princeton Instruments EMCCD
131  *
132  * \ingroup picamCtrl
133  *
134  * \todo Config item for ImageStreamIO name filename
135  * \todo implement ImageStreamIO circular buffer, with config setting
136  */
137 class picamCtrl : public MagAOXApp<>, public dev::stdCamera<picamCtrl>, public dev::frameGrabber<picamCtrl>, public dev::dssShutter<picamCtrl>, public dev::telemeter<picamCtrl>
138 {
139 
140  friend class dev::stdCamera<picamCtrl>;
141  friend class dev::frameGrabber<picamCtrl>;
142  friend class dev::dssShutter<picamCtrl>;
143  friend class dev::telemeter<picamCtrl>;
144 
146 
147 public:
148  /** \name app::dev Configurations
149  *@{
150  */
151  static constexpr bool c_stdCamera_tempControl = true; ///< app::dev config to tell stdCamera to expose temperature controls
152 
153  static constexpr bool c_stdCamera_temp = true; ///< app::dev config to tell stdCamera to expose temperature
154 
155  static constexpr bool c_stdCamera_readoutSpeed = true; ///< app::dev config to tell stdCamera to expose readout speed controls
156 
157  static constexpr bool c_stdCamera_vShiftSpeed = true; ///< app:dev config to tell stdCamera to expose vertical shift speed control
158 
159  static constexpr bool c_stdCamera_emGain = true; ///< app::dev config to tell stdCamera to expose EM gain controls
160 
161  static constexpr bool c_stdCamera_exptimeCtrl = true; ///< app::dev config to tell stdCamera to expose exposure time controls
162 
163  static constexpr bool c_stdCamera_fpsCtrl = false; ///< app::dev config to tell stdCamera not to expose FPS controls
164 
165  static constexpr bool c_stdCamera_fps = true; ///< app::dev config to tell stdCamera not to expose FPS status
166 
167  static constexpr bool c_stdCamera_synchro = false; ///< app::dev config to tell stdCamera to not expose synchro mode controls
168 
169  static constexpr bool c_stdCamera_usesModes = false; ///< app:dev config to tell stdCamera not to expose mode controls
170 
171  static constexpr bool c_stdCamera_usesROI = true; ///< app:dev config to tell stdCamera to expose ROI controls
172 
173  static constexpr bool c_stdCamera_cropMode = false; ///< app:dev config to tell stdCamera to expose Crop Mode controls
174 
175  static constexpr bool c_stdCamera_hasShutter = true; ///< app:dev config to tell stdCamera to expose shutter controls
176 
177  static constexpr bool c_stdCamera_usesStateString = false; ///< app::dev confg to tell stdCamera to expose the state string property
178 
179  static constexpr bool c_frameGrabber_flippable = true; ///< app:dev config to tell framegrabber this camera can be flipped
180 
181  ///@}
182 
183 protected:
184 
185  /** \name configurable parameters
186  *@{
187  */
188  std::string m_serialNumber; ///< The camera's identifying serial number
189 
190 
191  ///@}
192 
193  int m_depth {0};
194 
195  piint m_timeStampMask {PicamTimeStampsMask_ExposureStarted}; // time stamp at end of exposure
196  pi64s m_tsRes; // time stamp resolution
197  piint m_frameSize;
198  double m_camera_timestamp {0.0};
201 
202 
203 
204 
205 
206 
207 
208  PicamHandle m_cameraHandle {0};
209  PicamHandle m_modelHandle {0};
210 
211  PicamAcquisitionBuffer m_acqBuff;
212  PicamAvailableData m_available;
213 
214  std::string m_cameraName;
215  std::string m_cameraModel;
216 
217 public:
218 
219  ///Default c'tor
220  picamCtrl();
221 
222  ///Destructor
223  ~picamCtrl() noexcept;
224 
225  /// Setup the configuration system (called by MagAOXApp::setup())
226  virtual void setupConfig();
227 
228  /// load the configuration system results (called by MagAOXApp::setup())
229  virtual void loadConfig();
230 
231  /// Startup functions
232  /** Sets up the INDI vars.
233  *
234  */
235  virtual int appStartup();
236 
237  /// Implementation of the FSM for the Siglent SDG
238  virtual int appLogic();
239 
240  /// Implementation of the on-power-off FSM logic
241  virtual int onPowerOff();
242 
243  /// Implementation of the while-powered-off FSM
244  virtual int whilePowerOff();
245 
246  /// Do any needed shutdown tasks. Currently nothing in this app.
247  virtual int appShutdown();
248 
249 protected:
250  int getPicamParameter( piint & value,
251  PicamParameter parameter
252  );
253 
254  int getPicamParameter( piflt & value,
255  PicamParameter parameter
256  );
257 
258  int setPicamParameter( PicamParameter parameter,
259  pi64s value,
260  bool commit = true
261  );
262 
263  int setPicamParameter( PicamParameter parameter,
264  piint value,
265  bool commit = true
266  );
267 
268  int setPicamParameter( PicamHandle handle,
269  PicamParameter parameter,
270  piflt value,
271  bool commit = true
272  );
273 
274  int setPicamParameter( PicamHandle handle,
275  PicamParameter parameter,
276  piint value,
277  bool commit = true
278  );
279 
280 
281  int setPicamParameter( PicamParameter parameter,
282  piflt value,
283  bool commit = true
284  );
285 
286  int setPicamParameterOnline( PicamHandle handle,
287  PicamParameter parameter,
288  piflt value
289  );
290 
291  int setPicamParameterOnline( PicamParameter parameter,
292  piflt value
293  );
294 
295  int setPicamParameterOnline( PicamHandle handle,
296  PicamParameter parameter,
297  piint value
298  );
299 
300  int setPicamParameterOnline( PicamParameter parameter,
301  piint value
302  );
303 
304  int connect();
305 
306  int getAcquisitionState();
307 
308  int getTemps();
309 
310  // stdCamera interface:
311 
312  //This must set the power-on default values of
313  /* -- m_ccdTempSetpt
314  * -- m_currentROI
315  */
316  int powerOnDefaults();
317 
318  int setTempControl();
319  int setTempSetPt();
320  int setReadoutSpeed();
321  int setVShiftSpeed();
322  int setEMGain();
323  int setExpTime();
324  int capExpTime(piflt& exptime);
325  int setFPS();
326 
327  /// Check the next ROI
328  /** Checks if the target values are valid and adjusts them to the closest valid values if needed.
329  *
330  * \returns 0 if successful
331  * \returns -1 otherwise
332  */
333  int checkNextROI();
334 
335  int setNextROI();
336 
337  /// Sets the shutter state, via call to dssShutter::setShutterState(int) [stdCamera interface]
338  /**
339  * \returns 0 always
340  */
341  int setShutter(int sh);
342 
343  //Framegrabber interface:
344  int configureAcquisition();
345  float fps();
346  int startAcquisition();
347  int acquireAndCheckValid();
348  int loadImageIntoStream(void * dest);
349  int reconfig();
350 
351 
352  //INDI:
353 protected:
354 
355  pcf::IndiProperty m_indiP_readouttime;
356 
357 public:
358  INDI_NEWCALLBACK_DECL(picamCtrl, m_indiP_adcquality);
359 
360  /** \name Telemeter Interface
361  *
362  * @{
363  */
364  int checkRecordTimes();
365 
366  int recordTelem( const telem_stdcam * );
367 
368 
369  ///@}
370 };
371 
372 inline
373 picamCtrl::picamCtrl() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
374 {
375  m_powerMgtEnabled = true;
376 
377  m_acqBuff.memory_size = 0;
378  m_acqBuff.memory = 0;
379 
380  m_defaultReadoutSpeed = "emccd_05MHz";
381  m_readoutSpeedNames = {"ccd_00_1MHz", "ccd_01MHz", "emccd_05MHz", "emccd_10MHz", "emccd_20MHz", "emccd_30MHz"};
382  m_readoutSpeedNameLabels = {"CCD 0.1 MHz", "CCD 1 MHz", "EMCCD 5 MHz", "EMCCD 10 MHz", "EMCCD 20 MHz", "EMCCD 30 MHz"};
383 
384  m_defaultVShiftSpeed = "1_2us";
385  m_vShiftSpeedNames = {"0_7us", "1_2us", "2_0us", "5_0us"};
386  m_vShiftSpeedNameLabels = {"0.7 us", "1.2 us", "2.0 us", "5.0 us"};
387 
388 
389  m_default_x = 511.5;
390  m_default_y = 511.5;
391  m_default_w = 1024;
392  m_default_h = 1024;
393 
394  m_full_x = 511.5;
395  m_full_y = 511.5;
396  m_full_w = 1024;
397  m_full_h = 1024;
398 
399  m_maxEMGain = 1000;
400 
401  return;
402 }
403 
404 inline
406 {
407  if(m_acqBuff.memory)
408  {
409  free(m_acqBuff.memory);
410  }
411 
412  return;
413 }
414 
415 inline
417 {
418  config.add("camera.serialNumber", "", "camera.serialNumber", argType::Required, "camera", "serialNumber", false, "int", "The identifying serial number of the camera.");
419 
424 }
425 
426 inline
428 {
429 
430  config(m_serialNumber, "camera.serialNumber");
431 
436 
437 
438 }
439 
440 inline
442 {
443 
444  // DELETE ME
445  //m_outfile = fopen("/home/xsup/test2.txt", "w");
446 
447  createROIndiNumber( m_indiP_readouttime, "readout_time", "Readout Time (s)");
448  indi::addNumberElement<float>( m_indiP_readouttime, "value", 0.0, std::numeric_limits<float>::max(), 0.0, "%0.1f", "readout time");
450 
451 
452  m_minTemp = -55;
453  m_maxTemp = 25;
454  m_stepTemp = 0;
455 
456  m_minROIx = 0;
457  m_maxROIx = 1023;
458  m_stepROIx = 0;
459 
460  m_minROIy = 0;
461  m_maxROIy = 1023;
462  m_stepROIy = 0;
463 
464  m_minROIWidth = 1;
465  m_maxROIWidth = 1024;
466  m_stepROIWidth = 4;
467 
468  m_minROIHeight = 1;
469  m_maxROIHeight = 1024;
470  m_stepROIHeight = 1;
471 
472  m_minROIBinning_x = 1;
473  m_maxROIBinning_x = 32;
474  m_stepROIBinning_x = 1;
475 
476  m_minROIBinning_y = 1;
477  m_maxROIBinning_y = 1024;
478  m_stepROIBinning_y = 1;
479 
481  {
482  return log<software_critical,-1>({__FILE__,__LINE__});
483  }
484 
486  {
487  return log<software_critical,-1>({__FILE__,__LINE__});
488  }
489 
491  {
492  return log<software_critical,-1>({__FILE__,__LINE__});
493  }
494 
496  {
497  return log<software_error,-1>({__FILE__,__LINE__});
498  }
499 
500  return 0;
501 
502 }
503 
504 inline
506 {
507  //and run stdCamera's appLogic
509  {
510  return log<software_error, -1>({__FILE__, __LINE__});
511  }
512 
513  //first run frameGrabber's appLogic to see if the f.g. thread has exited.
515  {
516  return log<software_error, -1>({__FILE__, __LINE__});
517  }
518 
519  //and run dssShutter's appLogic
521  {
522  return log<software_error, -1>({__FILE__, __LINE__});
523  }
524 
525 
527  {
528  m_reconfig = true; //Trigger a f.g. thread reconfig.
529 
530  //Might have gotten here because of a power off.
531  if(powerState() != 1 || powerStateTarget() != 1) return 0;
532 
533  std::unique_lock<std::mutex> lock(m_indiMutex);
534  if(connect() < 0)
535  {
536  if(powerState() != 1 || powerStateTarget() != 1) return 0;
537  log<software_error>({__FILE__, __LINE__});
538  }
539 
540  if(state() != stateCodes::CONNECTED) return 0;
541  }
542 
543  if( state() == stateCodes::CONNECTED )
544  {
545  //Get a lock
546  std::unique_lock<std::mutex> lock(m_indiMutex);
547 
548  if( getAcquisitionState() < 0 )
549  {
550  if(powerState() != 1 || powerStateTarget() != 1) return 0;
551  return log<software_error,0>({__FILE__,__LINE__});
552  }
553 
554  if( setTempSetPt() < 0 ) //m_ccdTempSetpt already set on power on
555  {
556  if(powerState() != 1 || powerStateTarget() != 1) return 0;
557  return log<software_error,0>({__FILE__,__LINE__});
558  }
559 
560 
562  {
563  return log<software_error,0>({__FILE__,__LINE__});
564  }
565 
566  setPicamParameter(m_modelHandle, PicamParameter_DisableCoolingFan, PicamCoolingFanStatus_On);
567 
568 
569  }
570 
572  {
573  //Get a lock if we can
574  std::unique_lock<std::mutex> lock(m_indiMutex, std::try_to_lock);
575 
576  //but don't wait for it, just go back around.
577  if(!lock.owns_lock()) return 0;
578 
579  if(getAcquisitionState() < 0)
580  {
581  if(powerState() != 1 || powerStateTarget() != 1) return 0;
582 
584  return 0;
585  }
586 
587 
588 
589  if(getTemps() < 0)
590  {
591  if(powerState() != 1 || powerStateTarget() != 1) return 0;
592 
594  return 0;
595  }
596 
598  {
599  return log<software_error,0>({__FILE__,__LINE__});
600  }
601 
603  {
604  return log<software_error,0>({__FILE__,__LINE__});
605  }
606 
608  {
609  log<software_error>({__FILE__, __LINE__});
610  return 0;
611  }
612 
613  }
614 
615  //Fall through check?
616  return 0;
617 
618 }
619 
620 inline
622 {
623  std::lock_guard<std::mutex> lock(m_indiMutex);
624 
625  if(m_cameraHandle)
626  {
627  Picam_CloseCamera(m_cameraHandle);
628  m_cameraHandle = 0;
629  }
630 
631  Picam_UninitializeLibrary();
632 
634  {
635  log<software_error>({__FILE__, __LINE__});
636  }
637 
639  {
640  log<software_error>({__FILE__, __LINE__});
641  }
642 
643  return 0;
644 }
645 
646 inline
648 {
650  {
651  log<software_error>({__FILE__, __LINE__});
652  }
653 
655  {
656  log<software_error>({__FILE__, __LINE__});
657  }
658 
659  return 0;
660 }
661 
662 inline
664 {
666 
667  if(m_cameraHandle)
668  {
669  Picam_CloseCamera(m_cameraHandle);
670  m_cameraHandle = 0;
671  }
672 
673  Picam_UninitializeLibrary();
674 
675  ///\todo error check these base class fxns.
678 
679  return 0;
680 }
681 
682 inline
684  PicamParameter parameter
685  )
686 {
687  PicamError error = Picam_GetParameterIntegerValue( m_cameraHandle, parameter, &value );
688 
689  if(MagAOXAppT::m_powerState == 0) return -1; //Flag error but don't log
690 
691  if(error != PicamError_None)
692  {
693  if(powerState() != 1 || powerStateTarget() != 1) return -1;
694  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
695  return -1;
696  }
697 
698  return 0;
699 }
700 
701 inline
703  PicamParameter parameter
704  )
705 {
706  PicamError error = Picam_GetParameterFloatingPointValue( m_cameraHandle, parameter, &value );
707 
708  if(MagAOXAppT::m_powerState == 0) return -1; //Flag error but don't log
709 
710  if(error != PicamError_None)
711  {
712  if(powerState() != 1 || powerStateTarget() != 1) return -1;
713  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
714  return -1;
715  }
716 
717  return 0;
718 }
719 
720 inline
721 int picamCtrl::setPicamParameter( PicamParameter parameter,
722  pi64s value,
723  bool commit
724  )
725 {
726  PicamError error = Picam_SetParameterLargeIntegerValue( m_cameraHandle, parameter, value );
727  if(error != PicamError_None)
728  {
729  if(powerState() != 1 || powerStateTarget() != 1) return -1;
730  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
731  return -1;
732  }
733 
734  if(!commit) return 0;
735 
736  const PicamParameter* failed_parameters;
737  piint failed_parameters_count;
738 
739  error = Picam_CommitParameters( m_cameraHandle, &failed_parameters, &failed_parameters_count );
740  if(error != PicamError_None)
741  {
742  if(powerState() != 1 || powerStateTarget() != 1) return -1;
743  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
744  return -1;
745  }
746 
747  for( int i=0; i< failed_parameters_count; ++i)
748  {
749  if( failed_parameters[i] == parameter)
750  {
751  Picam_DestroyParameters( failed_parameters );
752  return log<text_log,-1>( "Parameter not committed");
753  }
754  }
755 
756  Picam_DestroyParameters( failed_parameters );
757 
758  return 0;
759 }
760 
761 inline
762 int picamCtrl::setPicamParameter( PicamHandle handle,
763  PicamParameter parameter,
764  piflt value,
765  bool commit
766  )
767 {
768  PicamError error = Picam_SetParameterFloatingPointValue( handle, parameter, value );
769  if(error != PicamError_None)
770  {
771  if(powerState() != 1 || powerStateTarget() != 1) return -1;
772  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
773  return -1;
774  }
775 
776  if(!commit) return 0;
777 
778  const PicamParameter* failed_parameters;
779  piint failed_parameters_count;
780 
781  error = Picam_CommitParameters( handle, &failed_parameters, &failed_parameters_count );
782  if(error != PicamError_None)
783  {
784  if(powerState() != 1 || powerStateTarget() != 1) return -1;
785  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
786  return -1;
787  }
788 
789  for( int i=0; i< failed_parameters_count; ++i)
790  {
791  if( failed_parameters[i] == parameter)
792  {
793  Picam_DestroyParameters( failed_parameters );
794  return log<text_log,-1>( "Parameter not committed");
795  }
796  }
797 
798  Picam_DestroyParameters( failed_parameters );
799 
800  return 0;
801 }
802 
803 inline
804 int picamCtrl::setPicamParameter( PicamHandle handle,
805  PicamParameter parameter,
806  piint value,
807  bool commit
808  )
809 {
810  PicamError error = Picam_SetParameterIntegerValue( handle, parameter, value );
811  if(error != PicamError_None)
812  {
813  if(powerState() != 1 || powerStateTarget() != 1) return -1;
814  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
815  return -1;
816  }
817 
818  if(!commit) return 0;
819 
820  const PicamParameter* failed_parameters;
821  piint failed_parameters_count;
822 
823  error = Picam_CommitParameters( handle, &failed_parameters, &failed_parameters_count );
824  if(error != PicamError_None)
825  {
826  if(powerState() != 1 || powerStateTarget() != 1) return -1;
827  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
828  return -1;
829  }
830 
831  for( int i=0; i< failed_parameters_count; ++i)
832  {
833  if( failed_parameters[i] == parameter)
834  {
835  Picam_DestroyParameters( failed_parameters );
836  return log<text_log,-1>( "Parameter not committed");
837  }
838  }
839 
840  Picam_DestroyParameters( failed_parameters );
841 
842  return 0;
843 }
844 
845 inline
846 int picamCtrl::setPicamParameter( PicamParameter parameter,
847  piflt value,
848  bool commit
849  )
850 {
851  return setPicamParameter( m_cameraHandle, parameter, value, commit);
852 }
853 
854 inline
855 int picamCtrl::setPicamParameter( PicamParameter parameter,
856  piint value,
857  bool commit
858  )
859 {
860  return setPicamParameter( m_cameraHandle, parameter, value, commit);
861 }
862 
863 inline
864 int picamCtrl::setPicamParameterOnline( PicamHandle handle,
865  PicamParameter parameter,
866  piflt value
867  )
868 {
869  PicamError error = Picam_SetParameterFloatingPointValueOnline( handle, parameter, value );
870  if(error != PicamError_None)
871  {
872  if(powerState() != 1 || powerStateTarget() != 1) return -1;
873  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
874  return -1;
875  }
876 
877  return 0;
878 }
879 
880 inline
881 int picamCtrl::setPicamParameterOnline( PicamParameter parameter,
882  piflt value
883  )
884 {
885  return setPicamParameterOnline(m_cameraHandle, parameter, value);
886 }
887 
888 inline
889 int picamCtrl::setPicamParameterOnline( PicamHandle handle,
890  PicamParameter parameter,
891  piint value
892  )
893 {
894  PicamError error = Picam_SetParameterIntegerValueOnline( handle, parameter, value );
895  if(error != PicamError_None)
896  {
897  if(powerState() != 1 || powerStateTarget() != 1) return -1;
898  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
899  return -1;
900  }
901 
902  return 0;
903 }
904 
905 inline
906 int picamCtrl::setPicamParameterOnline( PicamParameter parameter,
907  piint value
908  )
909 {
910  return setPicamParameterOnline(m_cameraHandle, parameter, value);
911 }
912 
913 inline
915 {
916 
917  PicamError error;
918  PicamCameraID * id_array;
919  piint id_count;
920 
921  if(m_acqBuff.memory)
922  {
923  free(m_acqBuff.memory);
924  m_acqBuff.memory = NULL;
925  m_acqBuff.memory_size = 0;
926  }
927 
928  Picam_UninitializeLibrary();
929 
930  //Have to initialize the library every time. Otherwise we won't catch a newly booted camera.
931  Picam_InitializeLibrary();
932 
933  if(m_cameraHandle)
934  {
935  Picam_CloseCamera(m_cameraHandle);
936  m_cameraHandle = 0;
937  }
938 
939  Picam_GetAvailableCameraIDs(const_cast<const PicamCameraID **>(&id_array), &id_count);
940 
941  if(powerState() != 1 || powerStateTarget() != 1) return 0;
942 
943  if(id_count == 0)
944  {
945  Picam_DestroyCameraIDs(id_array);
946 
947  Picam_UninitializeLibrary();
948 
950  if(!stateLogged())
951  {
952  log<text_log>("no P.I. Cameras available.");
953  }
954  return 0;
955  }
956 
957  for(int i=0; i< id_count; ++i)
958  {
959  if( std::string(id_array[i].serial_number) == m_serialNumber )
960  {
961  log<text_log>("Camera was found. Now connecting.");
962 
963  error = PicamAdvanced_OpenCameraDevice(&id_array[i], &m_cameraHandle);
964  if(error == PicamError_None)
965  {
966  m_cameraName = id_array[i].sensor_name;
967  m_cameraModel = PicamEnum2String(PicamEnumeratedType_Model, id_array[i].model);
968 
969  error = PicamAdvanced_GetCameraModel( m_cameraHandle, &m_modelHandle );
970  if( error != PicamError_None )
971  {
972  log<software_error>({__FILE__, __LINE__, "failed to get camera model"});
973  }
974 
976  log<text_log>("Connected to " + m_cameraName + " [S/N " + m_serialNumber + "]");
977 
978  Picam_DestroyCameraIDs(id_array);
979 
982 
983  return 0;
984  }
985  else
986  {
987  if(powerState() != 1 || powerStateTarget() != 1) return 0;
988 
990  if(!stateLogged())
991  {
992  log<software_error>({__FILE__,__LINE__, 0, error, "Error connecting to camera."});
993  }
994 
995  Picam_DestroyCameraIDs(id_array);
996 
997  Picam_UninitializeLibrary();
998  return -1;
999  }
1000  }
1001  }
1002 
1004  if(!stateLogged())
1005  {
1006  log<text_log>("Camera not found in available ids.");
1007  }
1008 
1009  Picam_DestroyCameraIDs(id_array);
1010 
1011 
1012  Picam_UninitializeLibrary();
1013 
1014 
1015  return 0;
1016 }
1017 
1018 
1019 inline
1021 {
1022  pibln running = false;
1023 
1024  PicamError error = Picam_IsAcquisitionRunning(m_cameraHandle, &running);
1025 
1026  if(MagAOXAppT::m_powerState == 0) return 0;
1027 
1028  if(error != PicamError_None)
1029  {
1030  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1031  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
1033  return -1;
1034  }
1035 
1036  if(running) state(stateCodes::OPERATING);
1037  else state(stateCodes::READY);
1038 
1039  if(!running)
1040  {
1041  log<text_log>("acqusition stopped. restarting", logPrio::LOG_ERROR);
1042  m_reconfig = true;
1043  }
1044 
1045  return 0;
1046 
1047 }
1048 
1049 inline
1051 {
1052  piflt currTemperature;
1053 
1054  if(getPicamParameter(currTemperature, PicamParameter_SensorTemperatureReading) < 0)
1055  {
1056  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1057 
1058  log<software_error>({__FILE__, __LINE__});
1060  return -1;
1061  }
1062 
1063  m_ccdTemp = currTemperature;
1064 
1065  //PicamSensorTemperatureStatus
1066  piint status;
1067 
1068  if(getPicamParameter( status, PicamParameter_SensorTemperatureStatus ) < 0)
1069  {
1070  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1071 
1072  log<software_error>({__FILE__, __LINE__});
1074  return -1;
1075  }
1076 
1077  if(status == 1)
1078  {
1079  m_tempControlStatus = true;
1080  m_tempControlOnTarget = false;
1081  m_tempControlStatusStr = "UNLOCKED";
1082  }
1083  else if(status == 2)
1084  {
1085  m_tempControlStatus = true;
1086  m_tempControlOnTarget = true;
1087  m_tempControlStatusStr = "LOCKED";
1088  }
1089  else if(status == 3)
1090  {
1091  m_tempControlStatus = false;
1092  m_tempControlOnTarget = false;
1093  m_tempControlStatusStr = "FAULTED";
1094  log<text_log>("temperature control faulted", logPrio::LOG_ALERT);
1095  }
1096  else
1097  {
1098  m_tempControlStatus = false;
1099  m_tempControlOnTarget = false;
1100  m_tempControlStatusStr = "UNKNOWN";
1101  }
1102 
1103  recordCamera();
1104 
1105  return 0;
1106 
1107 }
1108 
1109 inline
1111 {
1112  return 0;
1113 }
1114 
1115 inline
1117 {
1118  m_ccdTempSetpt = -55; //This is the power on setpoint
1119 
1120  m_currentROI.x = 511.5;
1121  m_currentROI.y = 511.5;
1122  m_currentROI.w = 1024;
1123  m_currentROI.h = 1024;
1124  m_currentROI.bin_x = 1;
1125  m_currentROI.bin_y = 1;
1126 
1127  m_readoutSpeedName = "emccd_05MHz";
1128  m_vShiftSpeedName = "1_2us";
1129  return 0;
1130 }
1131 
1132 inline
1134 {
1135  //Always on
1136  m_tempControlStatus = true;
1137  m_tempControlStatusSet = true;
1138  updateSwitchIfChanged(m_indiP_tempcont, "toggle", pcf::IndiElement::On, INDI_IDLE);
1139  recordCamera(true);
1140  return 0;
1141 }
1142 
1143 inline
1145 {
1146  ///\todo bounds check here.
1147  m_reconfig = true;
1148 
1149  recordCamera(true);
1150  return 0;
1151 }
1152 
1153 inline
1155 {
1156  m_reconfig = true;
1157  recordCamera(true);
1158  return 0;
1159 }
1160 
1161 inline
1163 {
1164  m_reconfig = true;
1165  recordCamera(true);
1166  return 0;
1167 }
1168 
1169 inline
1171 {
1172  piint adcQual;
1173  piflt adcSpeed;
1174 
1175  if(readoutParams(adcQual, adcSpeed, m_readoutSpeedName) < 0)
1176  {
1177  log<software_error>({__FILE__, __LINE__, "Invalid readout speed: " + m_readoutSpeedNameSet});
1179  return -1;
1180  }
1181 
1182  if(adcQual != PicamAdcQuality_ElectronMultiplied)
1183  {
1184  m_emGain = 1;
1185  m_adcSpeed = adcSpeed;
1186  recordCamera(true);
1187  log<text_log>("Attempt to set EM gain while in conventional amplifier.", logPrio::LOG_NOTICE);
1188  return 0;
1189  }
1190 
1191  piint emg = m_emGainSet;
1192  if(emg < 0)
1193  {
1194  emg = 0;
1195  log<text_log>("EM gain limited to 0", logPrio::LOG_WARNING);
1196  }
1197 
1198  if(emg > m_maxEMGain)
1199  {
1200  emg = m_maxEMGain;
1201  log<text_log>("EM gain limited to maxEMGain = " + std::to_string(emg), logPrio::LOG_WARNING);
1202  }
1203 
1204  recordCamera(true);
1205  if(setPicamParameterOnline(m_modelHandle, PicamParameter_AdcEMGain, emg) < 0)
1206  {
1207  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1208  log<software_error>({__FILE__, __LINE__, "Error setting EM gain"});
1209  return -1;
1210  }
1211 
1212  piint AdcEMGain;
1213  if(getPicamParameter(AdcEMGain, PicamParameter_AdcEMGain) < 0)
1214  {
1215  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1216  return log<software_error,-1>({__FILE__, __LINE__, "could not get AdcEMGain"});
1217  }
1218  m_emGain = AdcEMGain;
1219  m_adcSpeed = adcSpeed;
1220  recordCamera(true);
1221  return 0;
1222 }
1223 
1224 inline
1226 {
1227  long intexptime = m_expTimeSet * 1000 * 10000 + 0.5;
1228  piflt exptime = ((double)intexptime)/10000;
1229  capExpTime(exptime);
1230 
1231  int rv;
1232 
1233  recordCamera(true);
1234 
1235  if(state() == stateCodes::OPERATING)
1236  {
1237  rv = setPicamParameterOnline(m_modelHandle, PicamParameter_ExposureTime, exptime);
1238  }
1239  else
1240  {
1241  rv = setPicamParameter(m_modelHandle, PicamParameter_ExposureTime, exptime);
1242  }
1243 
1244  if(rv < 0)
1245  {
1246  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1247  log<software_error>({__FILE__, __LINE__, "Error setting exposure time"});
1248  return -1;
1249  }
1250 
1251  m_expTime = exptime/1000.0;
1252 
1253  recordCamera(true);
1254 
1256 
1257  if(getPicamParameter(m_FrameRateCalculation, PicamParameter_FrameRateCalculation) < 0)
1258  {
1259  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1260  log<software_error>({__FILE__, __LINE__, "could not get FrameRateCalculation"});
1261  }
1263 
1264  recordCamera(true);
1265 
1266  return 0;
1267 }
1268 
1269 inline
1270 int picamCtrl::capExpTime(piflt& exptime)
1271 {
1272  // cap at minimum possible value
1273  if(exptime < m_ReadOutTimeCalculation)
1274  {
1275  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1276  log<text_log>("Got exposure time " + std::to_string(exptime) + " ms but min value is " + std::to_string(m_ReadOutTimeCalculation) + " ms");
1277  long intexptime = m_ReadOutTimeCalculation * 10000 + 0.5;
1278  exptime = ((double)intexptime)/10000;
1279  }
1280 
1281  return 0;
1282 }
1283 
1284 inline
1286 {
1287  return 0;
1288 }
1289 
1290 //Set ROI property to busy if accepted, set toggle to Off and Idlw either way.
1291 //Set ROI actual
1292 //Update current values (including struct and indiP) and set to OK when done
1293 inline
1295 {
1296  m_reconfig = true;
1297 
1298  updateSwitchIfChanged(m_indiP_roi_set, "request", pcf::IndiElement::Off, INDI_IDLE);
1299 
1300  return 0;
1301 
1302 }
1303 
1304 inline
1306 {
1308 }
1309 
1310 inline
1312 {
1313 
1314  piint readoutStride;
1315  piint framesPerReadout;
1316  piint frameStride;
1317  //piint frameSize;
1318  piint pixelBitDepth;
1319 
1320  m_camera_timestamp = 0; // reset tracked timestamp
1321 
1322  std::unique_lock<std::mutex> lock(m_indiMutex);
1323 
1324 
1325  // Time stamp handling
1326  if(Picam_SetParameterIntegerValue(m_modelHandle, PicamParameter_TimeStamps, m_timeStampMask) < 0)
1327  {
1328  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1329  log<software_error>({__FILE__,__LINE__, "Could not set time stamp mask"});
1330  }
1331  if(Picam_GetParameterLargeIntegerValue(m_modelHandle, PicamParameter_TimeStampResolution, &m_tsRes) < 0)
1332  {
1333  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1334  log<software_error>({__FILE__,__LINE__, "Could not get timestamp resolution"}) ;
1335  }
1336 
1337  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1338  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1339  // Check Frame Transfer
1340  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1341  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1342 
1343  piint cmode;
1344  if(getPicamParameter(cmode, PicamParameter_ReadoutControlMode) < 0)
1345  {
1346  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1347  log<software_error>({__FILE__,__LINE__, "could not get Readout Control Mode"});
1348  return -1;
1349  }
1350 
1351  if( cmode != PicamReadoutControlMode_FrameTransfer)
1352  {
1353  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1354  log<software_error>({__FILE__,__LINE__, "Readout Control Mode not configured for frame transfer"}) ;
1355  return -1;
1356  }
1357 
1358  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1359  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1360  // Temperature
1361  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1362  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1363 
1364  if(setPicamParameter( PicamParameter_SensorTemperatureSetPoint, m_ccdTempSetpt) < 0)
1365  {
1366  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1367  log<software_error>({__FILE__, __LINE__, "Error setting temperature setpoint"});
1369  return -1;
1370  }
1371 
1372  //log<text_log>( "Set temperature set point: " + std::to_string(m_ccdTempSetpt) + " C");
1373 
1374  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1375  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1376  // ADC Speed and Quality
1377  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1378  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1379 
1380  piint adcQual;
1381  piflt adcSpeed;
1382 
1383  if(readoutParams(adcQual, adcSpeed, m_readoutSpeedNameSet) < 0)
1384  {
1385  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1386  log<software_error>({__FILE__, __LINE__, "Invalid readout speed: " + m_readoutSpeedNameSet});
1388  return -1;
1389  }
1390 
1391  if( setPicamParameter(m_modelHandle, PicamParameter_AdcSpeed, adcSpeed, false) < 0) //don't commit b/c it will error if quality mismatched
1392  {
1393  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1394  log<software_error>({__FILE__, __LINE__, "Error setting ADC Speed"});
1395  //state(stateCodes::ERROR);
1396  //return -1;
1397  }
1398 
1399  if( setPicamParameter(m_modelHandle, PicamParameter_AdcQuality, adcQual) < 0)
1400  {
1401  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1402  log<software_error>({__FILE__, __LINE__, "Error setting ADC Quality"});
1404  return -1;
1405  }
1406  m_adcSpeed = adcSpeed;
1408  log<text_log>( "Readout speed set to: " + m_readoutSpeedNameSet);
1409 
1410  if(adcQual == PicamAdcQuality_LowNoise)
1411  {
1412  m_emGain = 1.0;
1413  m_emGainSet = 1.0;
1414  }
1415 
1416  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1417  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1418  // Vertical Shift Rate
1419  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1420  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1421 
1422  piflt vss;
1423  if(vshiftParams(vss, m_vShiftSpeedNameSet) < 0)
1424  {
1425  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1426  log<software_error>({__FILE__, __LINE__, "Invalid vertical shift speed: " + m_vShiftSpeedNameSet});
1428  return -1;
1429  }
1430 
1431  if( setPicamParameter(m_modelHandle, PicamParameter_VerticalShiftRate, vss) < 0)
1432  {
1433  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1434  log<software_error>({__FILE__, __LINE__, "Error setting Vertical Shift Rate"});
1436  return -1;
1437  }
1438 
1440  m_vshiftSpeed = vss;
1441  log<text_log>( "Vertical Shift Rate set to: " + m_vShiftSpeedName);
1442 
1443  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1444  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1445  // Dimensions
1446  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1447  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1448 
1449  PicamRois nextrois;
1450  PicamRoi nextroi;
1451 
1452  nextrois.roi_array = &nextroi;
1453  nextrois.roi_count = 1;
1454 
1455  int roi_err = false;
1457  {
1458  nextroi.x = ((1023-m_nextROI.x) - 0.5*( (float) m_nextROI.w - 1.0));
1459  }
1460  else
1461  {
1462  nextroi.x = (m_nextROI.x - 0.5*( (float) m_nextROI.w - 1.0));
1463  }
1464 
1465  if(nextroi.x < 0)
1466  {
1467  log<software_error>({__FILE__, __LINE__, "can't set ROI to x center < 0"});
1468  roi_err = true;
1469  }
1470 
1471  if(nextroi.x > 1023)
1472  {
1473  log<software_error>({__FILE__, __LINE__, "can't set ROI to x center > 1023"});
1474  roi_err = true;
1475  }
1476 
1477 
1479  {
1480  nextroi.y = ((1023 - m_nextROI.y) - 0.5*( (float) m_nextROI.h - 1.0));
1481  }
1482  else
1483  {
1484  nextroi.y = (m_nextROI.y - 0.5*( (float) m_nextROI.h - 1.0));
1485  }
1486 
1487  if(nextroi.y < 0)
1488  {
1489  log<software_error>({__FILE__, __LINE__, "can't set ROI to y center < 0"});
1490  roi_err = true;
1491  }
1492 
1493  if(nextroi.y > 1023)
1494  {
1495  log<software_error>({__FILE__, __LINE__, "can't set ROI to y center > 1023"});
1496  roi_err = true;
1497  }
1498 
1499  nextroi.width = m_nextROI.w;
1500 
1501  if(nextroi.width < 0)
1502  {
1503  log<software_error>({__FILE__, __LINE__, "can't set ROI to width to be < 0"});
1504  roi_err = true;
1505  }
1506 
1507  if(nextroi.x + nextroi.width > 1024)
1508  {
1509  log<software_error>({__FILE__, __LINE__, "can't set ROI to width such that edge is > 1023"});
1510  roi_err = true;
1511  }
1512 
1513  nextroi.height = m_nextROI.h;
1514 
1515  if(nextroi.y + nextroi.height > 1024)
1516  {
1517  log<software_error>({__FILE__, __LINE__, "can't set ROI to height such that edge is > 1023"});
1518  roi_err = true;
1519  }
1520 
1521  if(nextroi.height < 0)
1522  {
1523  log<software_error>({__FILE__, __LINE__, "can't set ROI to height to be < 0"});
1524  roi_err = true;
1525  }
1526 
1527  nextroi.x_binning = m_nextROI.bin_x;
1528 
1529  if(nextroi.x_binning < 0)
1530  {
1531  log<software_error>({__FILE__, __LINE__, "can't set ROI x binning < 0"});
1532  roi_err = true;
1533  }
1534 
1535  nextroi.y_binning = m_nextROI.bin_y;
1536 
1537  if(nextroi.y_binning < 0)
1538  {
1539  log<software_error>({__FILE__, __LINE__, "can't set ROI y binning < 0"});
1540  roi_err = true;
1541  }
1542 
1543  PicamError error;
1544 
1545  if(!roi_err)
1546  {
1547  error = Picam_SetParameterRoisValue( m_cameraHandle, PicamParameter_Rois, &nextrois);
1548  if( error != PicamError_None )
1549  {
1550  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1551  std::cerr << PicamEnum2String(PicamEnumeratedType_Error, error) << "\n";
1552  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
1554  return -1;
1555  }
1556  }
1557 
1558  if(getPicamParameter(readoutStride, PicamParameter_ReadoutStride) < 0)
1559  {
1560  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1561  log<software_error>({__FILE__, __LINE__, "Error getting readout stride"});
1563  return -1;
1564  }
1565 
1566  if(getPicamParameter(frameStride, PicamParameter_FrameStride) < 0)
1567  {
1568  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1569  log<software_error>({__FILE__, __LINE__, "Error getting frame stride"});
1571 
1572  return -1;
1573  }
1574 
1575  if(getPicamParameter(framesPerReadout, PicamParameter_FramesPerReadout) < 0)
1576  {
1577  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1578  log<software_error>({__FILE__, __LINE__, "Error getting frames per readout"});
1580  return -1;
1581  }
1582 
1583  if(getPicamParameter( m_frameSize, PicamParameter_FrameSize) < 0)
1584  {
1585  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1586  log<software_error>({__FILE__, __LINE__, "Error getting frame size"});
1588  return -1;
1589  }
1590 
1591  if(getPicamParameter( pixelBitDepth, PicamParameter_PixelBitDepth) < 0)
1592  {
1593  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1594  log<software_error>({__FILE__, __LINE__,"Error getting pixel bit depth"});
1596  return -1;
1597  }
1598  m_depth = pixelBitDepth;
1599 
1600  const PicamRois* rois;
1601  error = Picam_GetParameterRoisValue( m_cameraHandle, PicamParameter_Rois, &rois );
1602  if( error != PicamError_None )
1603  {
1604  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1605  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
1607  return -1;
1608  }
1609  m_xbinning = rois->roi_array[0].x_binning;
1610  m_currentROI.bin_x = m_xbinning;
1611  m_ybinning = rois->roi_array[0].y_binning;
1612  m_currentROI.bin_y = m_ybinning;
1613 
1614  std::cerr << rois->roi_array[0].x << "\n";
1615  std::cerr << (rois->roi_array[0].x-1) << "\n";
1616  std::cerr << rois->roi_array[0].width << "\n";
1617  std::cerr << 0.5*( (float) (rois->roi_array[0].width - 1.0)) << "\n";
1618 
1619 
1621  {
1622  m_currentROI.x = (1023.0-rois->roi_array[0].x) - 0.5*( (float) (rois->roi_array[0].width - 1.0)) ;
1623  //nextroi.x = ((1023-m_nextROI.x) - 0.5*( (float) m_nextROI.w - 1.0));
1624  }
1625  else
1626  {
1627  m_currentROI.x = (rois->roi_array[0].x) + 0.5*( (float) (rois->roi_array[0].width - 1.0)) ;
1628  }
1629 
1630 
1632  {
1633  m_currentROI.y = (1023.0-rois->roi_array[0].y) - 0.5*( (float) (rois->roi_array[0].height - 1.0)) ;
1634  //nextroi.y = ((1023 - m_nextROI.y) - 0.5*( (float) m_nextROI.h - 1.0));
1635  }
1636  else
1637  {
1638  m_currentROI.y = (rois->roi_array[0].y) + 0.5*( (float) (rois->roi_array[0].height - 1.0)) ;
1639  }
1640 
1641 
1642 
1643 
1644 
1645  m_currentROI.w = rois->roi_array[0].width;
1646  m_currentROI.h = rois->roi_array[0].height;
1647 
1648  m_width = rois->roi_array[0].width / rois->roi_array[0].x_binning;
1649  m_height = rois->roi_array[0].height / rois->roi_array[0].y_binning;
1650  Picam_DestroyRois( rois );
1651 
1652 
1659 
1660 
1661  //We also update target to the settable values
1662  m_nextROI.x = m_currentROI.x;
1663  m_nextROI.y = m_currentROI.y;
1664  m_nextROI.w = m_currentROI.w;
1665  m_nextROI.h = m_currentROI.h;
1666  m_nextROI.bin_x = m_currentROI.bin_x;
1667  m_nextROI.bin_y = m_currentROI.bin_y;
1668 
1675 
1676 
1677  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1678  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1679  // Exposure Time and Frame Rate
1680  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1681  //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
1682 
1683  if(getPicamParameter(m_ReadOutTimeCalculation, PicamParameter_ReadoutTimeCalculation) < 0)
1684  {
1685  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1686  return log<software_error, -1>({__FILE__, __LINE__, "could not get ReadOutTimeCalculation"});
1687  }
1688  std::cerr << "Readout time is: " << m_ReadOutTimeCalculation << "\n";
1689  updateIfChanged( m_indiP_readouttime, "value", m_ReadOutTimeCalculation/1000.0, INDI_OK); // convert from msec to sec
1690 
1691  const PicamRangeConstraint * constraint_array;
1692  piint constraint_count;
1693  PicamAdvanced_GetParameterRangeConstraints( m_modelHandle, PicamParameter_ExposureTime, &constraint_array, &constraint_count);
1694 
1695  if(constraint_count != 1)
1696  {
1697  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1698  log<text_log>("Constraint count is not 1: " + std::to_string(constraint_count) + " constraints",logPrio::LOG_ERROR);
1699  }
1700  else
1701  {
1702  m_minExpTime = constraint_array[0].minimum;
1703  m_maxExpTime = constraint_array[0].maximum;
1704  m_stepExpTime = constraint_array[0].increment;
1705 
1706  m_indiP_exptime["current"].setMin(m_minExpTime);
1707  m_indiP_exptime["current"].setMax(m_maxExpTime);
1708  m_indiP_exptime["current"].setStep(m_stepExpTime);
1709 
1710  m_indiP_exptime["target"].setMin(m_minExpTime);
1711  m_indiP_exptime["target"].setMax(m_maxExpTime);
1712  m_indiP_exptime["target"].setStep(m_stepExpTime);
1713  }
1714 
1715  if(m_expTimeSet > 0)
1716  {
1717  long intexptime = m_expTimeSet * 1000 * 10000 + 0.5;
1718  piflt exptime = ((double)intexptime)/10000;
1719  capExpTime(exptime);
1720  std::cerr << "Setting exposure time to " << m_expTimeSet << "\n";
1721  int rv = setPicamParameter(m_modelHandle, PicamParameter_ExposureTime, exptime);
1722 
1723  if(rv < 0)
1724  {
1725  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1726  return log<software_error, -1>({__FILE__, __LINE__, "Error setting exposure time"});
1727  }
1728  }
1729 
1730  piflt exptime;
1731  if(getPicamParameter(exptime, PicamParameter_ExposureTime) < 0)
1732  {
1733  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1734  return log<software_error,-1>({__FILE__, __LINE__, "Error getting exposure time"});
1735  }
1736  else
1737  {
1738  capExpTime(exptime);
1739  m_expTime = exptime/1000.0;
1740  m_expTimeSet = m_expTime; //At this point it must be true.
1743  }
1744 
1745  if(getPicamParameter(m_FrameRateCalculation, PicamParameter_FrameRateCalculation) < 0)
1746  {
1747  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1748  return log<software_error,-1>({__FILE__, __LINE__, "Error getting frame rate"});
1749  }
1750  else
1751  {
1754  }
1755  std::cerr << "FrameRate is: " << m_FrameRateCalculation << "\n";
1756 
1757  piint AdcQuality;
1758  if(getPicamParameter(AdcQuality, PicamParameter_AdcQuality) < 0)
1759  {
1760  std::cerr << "could not get AdcQuality\n";
1761  }
1762  std::string adcqStr = PicamEnum2String( PicamEnumeratedType_AdcQuality, AdcQuality );
1763  std::cerr << "AdcQuality is: " << adcqStr << "\n";
1764 
1765  piflt verticalShiftRate;
1766  if(getPicamParameter(verticalShiftRate, PicamParameter_VerticalShiftRate) < 0)
1767  {
1768  std::cerr << "could not get VerticalShiftRate\n";
1769  }
1770  std::cerr << "VerticalShiftRate is: " << verticalShiftRate << "\n";
1771 
1772  piflt AdcSpeed;
1773  if(getPicamParameter(AdcSpeed, PicamParameter_AdcSpeed) < 0)
1774  {
1775  std::cerr << "could not get AdcSpeed\n";
1776  }
1777  std::cerr << "AdcSpeed is: " << AdcSpeed << "\n";
1778 
1779 
1780  std::cerr << "************************************************************\n";
1781 
1782 
1783  piint AdcAnalogGain;
1784  if(getPicamParameter(AdcAnalogGain, PicamParameter_AdcAnalogGain) < 0)
1785  {
1786  std::cerr << "could not get AdcAnalogGain\n";
1787  }
1788  std::string adcgStr = PicamEnum2String( PicamEnumeratedType_AdcAnalogGain, AdcAnalogGain );
1789  std::cerr << "AdcAnalogGain is: " << adcgStr << "\n";
1790 
1791  if(m_readoutSpeedName == "ccd_00_1MHz" || m_readoutSpeedName == "ccd_01MHz")
1792  {
1793  m_emGain = 1;
1794  }
1795  else
1796  {
1797  piint AdcEMGain;
1798  if(getPicamParameter(AdcEMGain, PicamParameter_AdcEMGain) < 0)
1799  {
1800  std::cerr << "could not get AdcEMGain\n";
1801  }
1802  m_emGain = AdcEMGain;
1803  }
1804 
1805 /*
1806  std::cerr << "Onlineable:\n";
1807  pibln onlineable;
1808  Picam_CanSetParameterOnline(m_modelHandle, PicamParameter_ReadoutControlMode,&onlineable);
1809  std::cerr << "ReadoutControlMode: " << onlineable << "\n"; //0
1810 
1811  Picam_CanSetParameterOnline(m_modelHandle, PicamParameter_AdcQuality,&onlineable);
1812  std::cerr << "AdcQuality: " << onlineable << "\n"; //0
1813 
1814  Picam_CanSetParameterOnline(m_modelHandle, PicamParameter_AdcAnalogGain,&onlineable);
1815  std::cerr << "AdcAnalogGain: " << onlineable << "\n"; //1
1816 
1817  Picam_CanSetParameterOnline(m_modelHandle, PicamParameter_DisableCoolingFan,&onlineable);
1818  std::cerr << "DisableCoolingFan: " << onlineable << "\n";//0
1819 
1820  Picam_CanSetParameterOnline(m_modelHandle, PicamParameter_SensorTemperatureSetPoint,&onlineable);
1821  std::cerr << "SensorTemperatureSetPoint: " << onlineable << "\n"; //0
1822 
1823  Picam_CanSetParameterOnline(m_modelHandle, PicamParameter_AdcEMGain,&onlineable);
1824  std::cerr << "AdcEMGain: " << onlineable << "\n"; //1
1825 
1826  Picam_CanSetParameterOnline(m_modelHandle, PicamParameter_FrameRateCalculation,&onlineable);
1827  std::cerr << "FrameRateCalculation: " << onlineable << "\n"; //0
1828 
1829  std::cerr << "************************************************************\n";
1830 */
1831 
1832  //If not previously allocated, allocate a nice big buffer to play with
1833  pi64s newbuffsz = framesPerReadout*readoutStride*10; //Save room for 10 frames
1834  if( newbuffsz > m_acqBuff.memory_size)
1835  {
1836  if(m_acqBuff.memory)
1837  {
1838  std::cerr << "Clearing\n";
1839  free(m_acqBuff.memory);
1840  m_acqBuff.memory = NULL;
1841  PicamAdvanced_SetAcquisitionBuffer(m_cameraHandle, NULL);
1842  }
1843 
1844  m_acqBuff.memory_size = newbuffsz;
1845  std::cerr << "m_acqBuff.memory_size: " << m_acqBuff.memory_size << "\n";
1846  m_acqBuff.memory = malloc(m_acqBuff.memory_size);
1847 
1848  error = PicamAdvanced_SetAcquisitionBuffer(m_cameraHandle, &m_acqBuff);
1849  if(error != PicamError_None)
1850  {
1851  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
1853 
1854  std::cerr << "-->" << PicamEnum2String(PicamEnumeratedType_Error, error) << "\n";
1855  }
1856  }
1857 
1858  //Start continuous acquisition
1859  if(setPicamParameter(PicamParameter_ReadoutCount,(pi64s) 0) < 0)
1860  {
1861  log<software_error>({__FILE__, __LINE__, "Error setting readouts=0"});
1863  return -1;
1864  }
1865 
1866  recordCamera();
1867 
1868  error = Picam_StartAcquisition(m_cameraHandle);
1869  if(error != PicamError_None)
1870  {
1871  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
1873 
1874  return -1;
1875  }
1876 
1877  m_dataType = _DATATYPE_UINT16; //Where does this go?
1878 
1879  return 0;
1880 
1881 }
1882 
1883 inline
1885 {
1886  return m_fps;
1887 }
1888 
1889 inline
1891 {
1892  return 0;
1893 }
1894 
1895 inline
1897 {
1898  piint camTimeOut = 1000; //1 second keeps us responsive without busy-waiting too much
1899 
1900  PicamAcquisitionStatus status;
1901 
1902  PicamAvailableData available;
1903 
1904  PicamError error;
1905  error = Picam_WaitForAcquisitionUpdate(m_cameraHandle, camTimeOut, &available, &status);
1906 
1907  if(error == PicamError_TimeOutOccurred)
1908  {
1909  return 1; //This sends it back to framegrabber to check for reconfig, etc.
1910  }
1911 
1912  clock_gettime(CLOCK_REALTIME, &m_currImageTimestamp);
1913 
1914  if(error != PicamError_None)
1915  {
1916  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
1918 
1919  return -1;
1920  }
1921 
1922  m_available.initial_readout = available.initial_readout;
1923  m_available.readout_count = available.readout_count;
1924 
1925  if(m_available.initial_readout == 0)
1926  {
1927  return 1;
1928  }
1929 
1930  //std::cerr << "readout: " << m_available.initial_readout << " " << m_available.readout_count << "\n";
1931 
1932  // camera time stamp
1933  pibyte *frame = NULL;
1934  pi64s metadataOffset;
1935 
1936  frame = static_cast<pibyte*>(m_available.initial_readout);
1937  metadataOffset = (pi64s)frame + m_frameSize;
1938 
1939  pi64s *tmpPtr = reinterpret_cast<pi64s*>(metadataOffset);
1940 
1941  double cam_ts = (double)*tmpPtr/(double)m_tsRes;
1942  double delta_ts = cam_ts - m_camera_timestamp;
1943 
1944  // check for a frame skip
1945  if(delta_ts > 1.5 / m_FrameRateCalculation){
1946  std::cerr << "Skipped frame(s)! (Expected a " << 1000./m_FrameRateCalculation << " ms gap but got " << 1000*delta_ts << " ms)\n";
1947  }
1948  // print
1949 
1950  m_camera_timestamp = cam_ts; // update to latest
1951 
1952  //fprintf(m_outfile, "%d %-15.8f\n", m_imageStream->md->cnt0+1, (double)*tmpPtr/(double)m_tsRes);
1953 
1954  return 0;
1955 
1956 }
1957 
1958 inline
1960 {
1961  if( frameGrabber<picamCtrl>::loadImageIntoStreamCopy(dest, m_available.initial_readout, m_width, m_height, m_typeSize) == nullptr) return -1;
1962 
1963  return 0;
1964 }
1965 
1966 inline
1968 {
1969  ///\todo clean this up. Just need to wait on acquisition update the first time probably.
1970 
1971  PicamError error = Picam_StopAcquisition(m_cameraHandle);
1972  if(error != PicamError_None)
1973  {
1974  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
1976 
1977  return -1;
1978  }
1979 
1980  pibln running = true;
1981 
1982  error = Picam_IsAcquisitionRunning(m_cameraHandle, &running);
1983 
1984  while(running)
1985  {
1986  if(MagAOXAppT::m_powerState == 0) return 0;
1987  sleep(1);
1988 
1989  error = Picam_StopAcquisition(m_cameraHandle);
1990 
1991  if(error != PicamError_None)
1992  {
1993  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
1995  return -1;
1996  }
1997 
1998  piint camTimeOut = 1000;
1999 
2000  PicamAcquisitionStatus status;
2001 
2002  PicamAvailableData available;
2003 
2004  error = Picam_WaitForAcquisitionUpdate(m_cameraHandle, camTimeOut, &available, &status);
2005  if(error != PicamError_None)
2006  {
2007  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
2009  return -1;
2010  }
2011 
2012 // if(! status.running )
2013 // {
2014 // std::cerr << "Not running \n";
2015 //
2016 // std::cerr << "status.running: " << status.running << "\n";
2017 // std::cerr << "status.errors: " << status.errors << "\n";
2018 // std::cerr << "CameraFaulted: " << (int)(status.errors & PicamAcquisitionErrorsMask_CameraFaulted) << "\n";
2019 // std::cerr << "CannectionLost: " << (int)(status.errors & PicamAcquisitionErrorsMask_ConnectionLost) << "\n";
2020 // std::cerr << "DataLost: " << (int)(status.errors & PicamAcquisitionErrorsMask_DataLost) << "\n";
2021 // std::cerr << "DataNotArriving: " << (int)(status.errors & PicamAcquisitionErrorsMask_DataNotArriving) << "\n";
2022 // std::cerr << "None: " << (int)(status.errors & PicamAcquisitionErrorsMask_None) << "\n";
2023 // std::cerr << "ShutterOverheated: " << (int)(status.errors & PicamAcquisitionErrorsMask_ShutterOverheated) << "\n";
2024 // std::cerr << "status.readout_rate: " << status.readout_rate << "\n";
2025 // }
2026 
2027  error = Picam_IsAcquisitionRunning(m_cameraHandle, &running);
2028  if(error != PicamError_None)
2029  {
2030  log<software_error>({__FILE__, __LINE__, 0, error, PicamEnum2String(PicamEnumeratedType_Error, error)});
2032  return -1;
2033  }
2034  }
2035 
2036  return 0;
2037 }
2038 
2039 
2040 
2042 {
2044 }
2045 
2047 {
2048  return recordCamera(true);
2049 }
2050 
2051 
2052 
2053 }//namespace app
2054 } //namespace MagAOX
2055 #endif
The base-class for MagAO-X applications.
Definition: MagAOXApp.hpp:75
void updateIfChanged(pcf::IndiProperty &p, const std::string &el, const T &newVal, pcf::IndiProperty::PropertyStateType ipState=pcf::IndiProperty::Ok)
Update an INDI property element value if it has changed.
Definition: MagAOXApp.hpp:2877
stateCodes::stateCodeT state()
Get the current state code.
Definition: MagAOXApp.hpp:2082
int powerState()
Returns the current power state.
Definition: MagAOXApp.hpp:3179
int m_powerState
Current power state, 1=On, 0=Off, -1=Unk.
Definition: MagAOXApp.hpp:995
int powerStateTarget()
Returns the target power state.
Definition: MagAOXApp.hpp:3187
void updateSwitchIfChanged(pcf::IndiProperty &p, const std::string &el, const pcf::IndiElement::SwitchStateType &newVal, pcf::IndiProperty::PropertyStateType ipState=pcf::IndiProperty::Ok)
Update an INDI switch element value if it has changed.
Definition: MagAOXApp.hpp:2901
int stateLogged()
Updates and returns the value of m_stateLogged. Will be 0 on first call after a state change,...
Definition: MagAOXApp.hpp:2140
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
Definition: MagAOXApp.hpp:1590
int createROIndiNumber(pcf::IndiProperty &prop, const std::string &propName, const std::string &propLabel="", const std::string &propGroup="")
Create a ReadOnly INDI Number property.
Definition: MagAOXApp.hpp:2294
int registerIndiPropertyReadOnly(pcf::IndiProperty &prop)
Register an INDI property which is read only.
Definition: MagAOXApp.hpp:2437
std::mutex m_indiMutex
Mutex for locking INDI communications.
Definition: MagAOXApp.hpp:540
bool m_powerMgtEnabled
Flag controls whether power mgt is used. Set this in the constructor of a derived app....
Definition: MagAOXApp.hpp:981
MagAO-X Uniblitz DSS Shutter interface.
Definition: dssShutter.hpp:37
int whilePowerOff()
Actions while powered off.
Definition: dssShutter.hpp:480
void loadConfig(mx::app::appConfigurator &config)
load the configuration system results
Definition: dssShutter.hpp:322
int onPowerOff()
Actions on power off.
Definition: dssShutter.hpp:474
int appShutdown()
applogic shutdown
Definition: dssShutter.hpp:437
void setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
Definition: dssShutter.hpp:304
int setShutterState(int sh)
Change shutter state.
Definition: dssShutter.hpp:486
int m_xbinning
The x-binning according to the framegrabber.
timespec m_currImageTimestamp
The timestamp of the current image.
uint32_t m_width
The width of the image, once deinterlaced etc.
int appShutdown()
Shuts down the framegrabber thread.
void * loadImageIntoStreamCopy(void *dest, void *src, size_t width, size_t height, size_t szof)
int m_ybinning
The y-binning according to the framegrabber.
void loadConfig(mx::app::appConfigurator &config)
load the configuration system results
void setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
size_t m_typeSize
The size of the type, in bytes. Result of sizeof.
int updateINDI()
Update the INDI properties for this device controller.
uint8_t m_dataType
The ImageStreamIO type code.
bool m_reconfig
Flag to set if a camera reconfiguration requires a framegrabber reset.
uint32_t m_height
The height of the image, once deinterlaced etc.
MagAO-X standard camera interface.
Definition: stdCamera.hpp:232
float m_maxEMGain
The configurable maximum EM gain. To be enforced in derivedT.
Definition: stdCamera.hpp:296
std::vector< std::string > m_readoutSpeedNames
Definition: stdCamera.hpp:279
float m_minExpTime
The minimum exposure time, used for INDI attributes.
Definition: stdCamera.hpp:308
pcf::IndiProperty m_indiP_roi_y
Property used to set the ROI x center coordinate.
Definition: stdCamera.hpp:415
float m_default_x
Power-on ROI center x coordinate.
Definition: stdCamera.hpp:395
std::string m_tempControlStatusStr
Camera specific description of temperature control status.
Definition: stdCamera.hpp:267
float m_emGain
The camera's current EM gain (if available).
Definition: stdCamera.hpp:294
std::vector< std::string > m_readoutSpeedNameLabels
Definition: stdCamera.hpp:280
float m_emGainSet
The camera's EM gain, as set by the user.
Definition: stdCamera.hpp:295
std::string m_vShiftSpeedNameSet
The user requested vshift speed name, to be set by derived()
Definition: stdCamera.hpp:289
std::string m_defaultReadoutSpeed
The default readout speed of the camera.
Definition: stdCamera.hpp:245
float m_expTime
The current exposure time, in seconds.
Definition: stdCamera.hpp:312
float m_maxExpTime
The maximum exposure time, used for INDI attributes.
Definition: stdCamera.hpp:309
int m_default_h
Power-on ROI height.
Definition: stdCamera.hpp:398
float m_expTimeSet
The exposure time, in seconds, as set by user.
Definition: stdCamera.hpp:313
pcf::IndiProperty m_indiP_roi_h
Property used to set the ROI height.
Definition: stdCamera.hpp:417
void setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
Definition: stdCamera.hpp:980
float m_full_y
The full ROI center y coordinate.
Definition: stdCamera.hpp:403
std::string m_readoutSpeedName
The current readout speed name.
Definition: stdCamera.hpp:282
float m_ccdTempSetpt
The desired temperature, in C.
Definition: stdCamera.hpp:260
bool m_tempControlStatus
Whether or not temperature control is active.
Definition: stdCamera.hpp:262
pcf::IndiProperty m_indiP_roi_w
Property used to set the ROI width.
Definition: stdCamera.hpp:416
pcf::IndiProperty m_indiP_roi_bin_x
Property used to set the ROI x binning.
Definition: stdCamera.hpp:418
float m_full_x
The full ROI center x coordinate.
Definition: stdCamera.hpp:402
std::string m_vShiftSpeedName
The current vshift speed name.
Definition: stdCamera.hpp:288
float m_ccdTemp
The current temperature, in C.
Definition: stdCamera.hpp:258
int updateINDI()
Update the INDI properties for this device controller.
Definition: stdCamera.hpp:2739
std::vector< std::string > m_vShiftSpeedNames
Definition: stdCamera.hpp:285
std::string m_defaultVShiftSpeed
The default readout speed of the camera.
Definition: stdCamera.hpp:246
bool m_tempControlOnTarget
Whether or not the temperature control system is on its target temperature.
Definition: stdCamera.hpp:265
float m_stepExpTime
The maximum exposure time stepsize, used for INDI attributes.
Definition: stdCamera.hpp:310
void loadConfig(mx::app::appConfigurator &config)
load the configuration system results
Definition: stdCamera.hpp:1019
std::vector< std::string > m_vShiftSpeedNameLabels
Definition: stdCamera.hpp:286
pcf::IndiProperty m_indiP_roi_set
Property used to trigger setting the ROI.
Definition: stdCamera.hpp:425
float m_default_y
Power-on ROI center y coordinate.
Definition: stdCamera.hpp:396
pcf::IndiProperty m_indiP_roi_bin_y
Property used to set the ROI y binning.
Definition: stdCamera.hpp:419
pcf::IndiProperty m_indiP_roi_x
Property used to set the ROI x center coordinate.
Definition: stdCamera.hpp:414
bool m_tempControlStatusSet
Desired state of temperature control.
Definition: stdCamera.hpp:263
int onPowerOff()
Actions on power off.
Definition: stdCamera.hpp:1592
std::string m_readoutSpeedNameSet
The user requested readout speed name, to be set by derived()
Definition: stdCamera.hpp:283
int recordTelem(const telem_stdcam *)
Definition: picamCtrl.hpp:2046
int loadImageIntoStream(void *dest)
Definition: picamCtrl.hpp:1959
static constexpr bool c_stdCamera_usesROI
app:dev config to tell stdCamera to expose ROI controls
Definition: picamCtrl.hpp:171
virtual void loadConfig()
load the configuration system results (called by MagAOXApp::setup())
Definition: picamCtrl.hpp:427
std::string m_cameraModel
Definition: picamCtrl.hpp:215
std::string m_serialNumber
The camera's identifying serial number.
Definition: picamCtrl.hpp:188
static constexpr bool c_stdCamera_exptimeCtrl
app::dev config to tell stdCamera to expose exposure time controls
Definition: picamCtrl.hpp:161
static constexpr bool c_stdCamera_synchro
app::dev config to tell stdCamera to not expose synchro mode controls
Definition: picamCtrl.hpp:167
std::string m_cameraName
Definition: picamCtrl.hpp:214
int setShutter(int sh)
Sets the shutter state, via call to dssShutter::setShutterState(int) [stdCamera interface].
Definition: picamCtrl.hpp:1305
virtual int appShutdown()
Do any needed shutdown tasks. Currently nothing in this app.
Definition: picamCtrl.hpp:663
static constexpr bool c_stdCamera_vShiftSpeed
app:dev config to tell stdCamera to expose vertical shift speed control
Definition: picamCtrl.hpp:157
virtual void setupConfig()
Setup the configuration system (called by MagAOXApp::setup())
Definition: picamCtrl.hpp:416
int checkNextROI()
Check the next ROI.
Definition: picamCtrl.hpp:1285
INDI_NEWCALLBACK_DECL(picamCtrl, m_indiP_adcquality)
PicamHandle m_cameraHandle
Definition: picamCtrl.hpp:208
static constexpr bool c_stdCamera_fpsCtrl
app::dev config to tell stdCamera not to expose FPS controls
Definition: picamCtrl.hpp:163
static constexpr bool c_stdCamera_cropMode
app:dev config to tell stdCamera to expose Crop Mode controls
Definition: picamCtrl.hpp:173
PicamHandle m_modelHandle
Definition: picamCtrl.hpp:209
static constexpr bool c_stdCamera_hasShutter
app:dev config to tell stdCamera to expose shutter controls
Definition: picamCtrl.hpp:175
static constexpr bool c_stdCamera_tempControl
app::dev config to tell stdCamera to expose temperature controls
Definition: picamCtrl.hpp:151
static constexpr bool c_stdCamera_temp
app::dev config to tell stdCamera to expose temperature
Definition: picamCtrl.hpp:153
~picamCtrl() noexcept
Destructor.
Definition: picamCtrl.hpp:405
static constexpr bool c_stdCamera_emGain
app::dev config to tell stdCamera to expose EM gain controls
Definition: picamCtrl.hpp:159
pcf::IndiProperty m_indiP_readouttime
Definition: picamCtrl.hpp:355
virtual int whilePowerOff()
Implementation of the while-powered-off FSM.
Definition: picamCtrl.hpp:647
int getPicamParameter(piint &value, PicamParameter parameter)
Definition: picamCtrl.hpp:683
picamCtrl()
Default c'tor.
Definition: picamCtrl.hpp:373
int setPicamParameter(PicamParameter parameter, pi64s value, bool commit=true)
Definition: picamCtrl.hpp:721
static constexpr bool c_stdCamera_readoutSpeed
app::dev config to tell stdCamera to expose readout speed controls
Definition: picamCtrl.hpp:155
virtual int onPowerOff()
Implementation of the on-power-off FSM logic.
Definition: picamCtrl.hpp:621
static constexpr bool c_stdCamera_usesModes
app:dev config to tell stdCamera not to expose mode controls
Definition: picamCtrl.hpp:169
static constexpr bool c_stdCamera_usesStateString
app::dev confg to tell stdCamera to expose the state string property
Definition: picamCtrl.hpp:177
int setPicamParameterOnline(PicamHandle handle, PicamParameter parameter, piflt value)
Definition: picamCtrl.hpp:864
static constexpr bool c_frameGrabber_flippable
app:dev config to tell framegrabber this camera can be flipped
Definition: picamCtrl.hpp:179
PicamAvailableData m_available
Definition: picamCtrl.hpp:212
static constexpr bool c_stdCamera_fps
app::dev config to tell stdCamera not to expose FPS status
Definition: picamCtrl.hpp:165
virtual int appStartup()
Startup functions.
Definition: picamCtrl.hpp:441
virtual int appLogic()
Implementation of the FSM for the Siglent SDG.
Definition: picamCtrl.hpp:505
PicamAcquisitionBuffer m_acqBuff
Definition: picamCtrl.hpp:211
int capExpTime(piflt &exptime)
Definition: picamCtrl.hpp:1270
@ OPERATING
The device is operating, other than homing.
Definition: stateCodes.hpp:50
@ NODEVICE
No device exists for the application to control.
Definition: stateCodes.hpp:41
@ ERROR
The application has encountered an error, from which it is recovering (with or without intervention)
Definition: stateCodes.hpp:38
@ READY
The device is ready for operation, but is not operating.
Definition: stateCodes.hpp:51
@ CONNECTED
The application has connected to the device or service.
Definition: stateCodes.hpp:45
@ NOTCONNECTED
The application is not connected to the device or service.
Definition: stateCodes.hpp:44
#define INDI_IDLE
Definition: indiUtils.hpp:28
#define INDI_OK
Definition: indiUtils.hpp:29
GeneratorWrapper< T > value(T &&value)
Definition: catch.hpp:4001
std::ostream & cerr()
int readoutParams(int &newa, int &newhss, const std::string &ron)
Definition: andorCtrl.hpp:277
int vshiftParams(int &newvs, const std::string &vssn, float &vs)
Definition: andorCtrl.hpp:325
Definition: dm.hpp:24
constexpr static logPrioT LOG_ERROR
An error has occured which the software will attempt to correct.
Definition: logPriority.hpp:40
constexpr static logPrioT LOG_ALERT
This should only be used if some action is required by operators to keep the system safe.
Definition: logPriority.hpp:34
constexpr static logPrioT LOG_WARNING
A condition has occurred which may become an error, but the process continues.
Definition: logPriority.hpp:43
constexpr static logPrioT LOG_NOTICE
A normal but significant condition.
Definition: logPriority.hpp:46
std::string PicamEnum2String(PicamEnumeratedType type, piint value)
Definition: picamCtrl.hpp:30
A device which saves telemetry.
Definition: telemeter.hpp:52
int loadConfig(appConfigurator &config)
Load the device section from an application configurator.
Definition: telemeter.hpp:208
int appLogic()
Perform telemeter application logic.
Definition: telemeter.hpp:253
int setupConfig(appConfigurator &config)
Setup an application configurator for the device section.
Definition: telemeter.hpp:195
int checkRecordTimes(const telT &tel, telTs... tels)
Check the time of the last record for each telemetry type and make an entry if needed.
Definition: telemeter.hpp:266
Software CRITICAL log entry.
Software ERR log entry.
Log entry recording stdcam stage specific status.
A simple text log, a string-type log.
Definition: text_log.hpp:24