PilatusCamera.cpp 34.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
 This file is part of LImA, a Library for Image Acquisition

 Copyright (C) : 2009-2011
 European Synchrotron Radiation Facility
 BP 220, Grenoble 38043
 FRANCE

 This is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version.

 This software is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <pthread.h>

#include <stdlib.h>
#include <string>
#include <sstream>
#include <vector>
#include <map>
#include <iostream>
30
#include <iomanip>
31
32
33
34
35
36
37
38
39

#include <sys/socket.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#include <poll.h>

40
#include "lima/Exceptions.h"
41

42
#include "PilatusCamera.h"
Arafat Noureddine's avatar
Arafat Noureddine committed
43

44
using namespace lima;
45
using namespace lima::Pilatus;
46

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
static const char  SOCKET_SEPARATOR = '\030';
static const char* SPLIT_SEPARATOR  = "\x18"; // '\x18' == '\030'

//---------------------------
//- utility function
//---------------------------
static inline const char* _get_ip_addresse(const char *name_ip)
{
  
  if(inet_addr(name_ip) != INADDR_NONE)
    return name_ip;
  else
    {
      struct hostent *host = gethostbyname(name_ip);
      if(!host)
	{
	  char buffer[256];
	  snprintf(buffer,sizeof(buffer),"Can not found ip for host %s ",name_ip);
	  throw LIMA_HW_EXC(Error,buffer);
	}
      return inet_ntoa(*((struct in_addr*)host->h_addr));
    }
}
70
71


72
73
74
75
#define RECONNECT_WAIT_UNTIL(testState,errmsg)			    \
  if(m_socket == -1)						    \
    _connect(m_server_ip.c_str(),m_server_port);			    \
								    \
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
76
  while(m_state != testState &&					    \
77
78
	m_state != Camera::ERROR &&				    \
	m_state != Camera::DISCONNECTED)			    \
Arafat Noureddine's avatar
Arafat Noureddine committed
79
80
81
{                                                                   \
  if(!m_cond.wait(TIME_OUT))                                        \
    THROW_HW_ERROR(lima::Error) << errmsg;                          \
Arafat Noureddine's avatar
Arafat Noureddine committed
82
}
83

Arafat Noureddine's avatar
Arafat Noureddine committed
84
85
86
//-----------------------------------------------------
//
//-----------------------------------------------------
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
87
88
89
inline void _split(const std::string inString,
		   const std::string &separator,
		   std::vector<std::string> &returnVector)
90
{
Arafat Noureddine's avatar
Arafat Noureddine committed
91
92
    std::string::size_type start = 0;
    std::string::size_type end = 0;
93

Arafat Noureddine's avatar
Arafat Noureddine committed
94
95
96
97
98
    while ((end=inString.find (separator, start)) != std::string::npos)
    {
        returnVector.push_back (inString.substr (start, end-start));
        start = end+separator.size();
    }
99

Arafat Noureddine's avatar
Arafat Noureddine committed
100
    returnVector.push_back (inString.substr (start));
101
102
}

Arafat Noureddine's avatar
Arafat Noureddine committed
103
104
105
//-----------------------------------------------------
//
//-----------------------------------------------------
106
Camera::Camera(const char *host,int port)
Arafat Noureddine's avatar
Arafat Noureddine committed
107
108
109
                :   m_socket(-1),
                    m_stop(false),
                    m_thread_id(0),
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
110
                    m_state(DISCONNECTED),
111
112
                    m_nb_acquired_images(0),
		    m_has_cmd_setenergy(true),
113
114
115
116
		    m_pilatus3_threshold_mode(false),
		    m_major_version(-1),
		    m_minor_version(-1),
		    m_patch_version(-1)
117
{
Arafat Noureddine's avatar
Arafat Noureddine committed
118
119
120
121
122
123
124
    DEB_CONSTRUCTOR();
    m_server_ip         = host;
    m_server_port       = port;
    _initVariable();

    if(pipe(m_pipes))
        THROW_HW_ERROR(Error) << "Can't open pipe";
125

Arafat Noureddine's avatar
Arafat Noureddine committed
126
    pthread_create(&m_thread_id,NULL,_runFunc,this);
127

128
129
130
131
132
133
134
    try
      {
	connect(host,port);
      }
    catch(Exception &e)		// Not an error in that case
      {
      }
135
136
}

Arafat Noureddine's avatar
Arafat Noureddine committed
137
138
139
//-----------------------------------------------------
//
//-----------------------------------------------------
140
Camera::~Camera()
141
{
142
    DEB_MEMBER_FUNCT();
Arafat Noureddine's avatar
Arafat Noureddine committed
143
    AutoMutex aLock(m_cond.mutex());
144
    m_nb_acquired_images = 0;
Arafat Noureddine's avatar
Arafat Noureddine committed
145
    m_stop = true;
146
    if(m_socket >=0)
Arafat Noureddine's avatar
minor    
Arafat Noureddine committed
147
    {
148
149
150
151
      if(write(m_pipes[1],"|",1) == -1)
	DEB_ERROR() << "Something wrong happen!!!";

      close(m_socket);
152
      m_socket = -1;
153
    }
Arafat Noureddine's avatar
Arafat Noureddine committed
154
    else
155
    {
156
157
      if(write(m_pipes[1],"|",1) == -1)
	DEB_ERROR() << "Something wrong happen!!!";
158
    }
Arafat Noureddine's avatar
Arafat Noureddine committed
159
    aLock.unlock();
Arafat Noureddine's avatar
Arafat Noureddine committed
160

Arafat Noureddine's avatar
Arafat Noureddine committed
161
162
    void *returnPt;
    if(m_thread_id > 0)
163
    {
164
        DEB_TRACE()<<"[pthread_join - BEGIN]";
165
166
        if(pthread_join(m_thread_id,&returnPt)!=0)
        {
167
168
169
            DEB_TRACE()<<"UNknown Error";
        }
        DEB_TRACE()<<"[pthread_join - END]";
170
    }
171
172
}

Arafat Noureddine's avatar
Arafat Noureddine committed
173
174
175
//-----------------------------------------------------
//
//-----------------------------------------------------
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
176
const char* Camera::serverIP() const
Arafat Noureddine's avatar
Arafat Noureddine committed
177
{
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
178
  return m_server_ip.c_str();
Arafat Noureddine's avatar
Arafat Noureddine committed
179
180
181
182
183
}

//-----------------------------------------------------
//
//-----------------------------------------------------
184
int Camera::serverPort() const
Arafat Noureddine's avatar
Arafat Noureddine committed
185
{
Arafat Noureddine's avatar
Arafat Noureddine committed
186
    return m_server_port;
Arafat Noureddine's avatar
Arafat Noureddine committed
187
188
189
190
191
}

//-----------------------------------------------------
//
//-----------------------------------------------------
192
void Camera::_initVariable()
193
{
Arafat Noureddine's avatar
Arafat Noureddine committed
194
195
196
197
    m_imgpath                           = "/ramdisk/images/";
    m_file_name                         = "image_%.5d.cbf";
    m_file_pattern                      = m_file_name;
    m_threshold                         = -1;
198
    m_energy                            = -1;
Arafat Noureddine's avatar
Arafat Noureddine committed
199
200
201
202
203
204
    m_gain                              = DEFAULT_GAIN;
    m_exposure                          = -1.;
    m_nimages                           = 1;
    m_exposure_period                   = -1.;
    m_hardware_trigger_delay            = -1.;
    m_exposure_per_frame                = 1;
Arafat Noureddine's avatar
Arafat Noureddine committed
205
    m_nb_acquired_images 		= 0;
206
    m_trigger_mode 			= INTERNAL_SINGLE;
207

Arafat Noureddine's avatar
Arafat Noureddine committed
208
209
210
211
    GAIN_SERVER_RESPONSE["low"]         = LOW;
    GAIN_SERVER_RESPONSE["mid"]         = MID;
    GAIN_SERVER_RESPONSE["high"]        = HIGH;
    GAIN_SERVER_RESPONSE["ultra high"]  = UHIGH;
212

Arafat Noureddine's avatar
Arafat Noureddine committed
213
214
215
216
    GAIN_VALUE2SERVER[LOW]              = "lowG";
    GAIN_VALUE2SERVER[MID]              = "midG";
    GAIN_VALUE2SERVER[HIGH]             = "highG";
    GAIN_VALUE2SERVER[UHIGH]            = "uhighG";
217
}
Arafat Noureddine's avatar
Arafat Noureddine committed
218
219
220
221

//-----------------------------------------------------
//
//-----------------------------------------------------
222
void Camera::connect(const char *host,int port)
223
{
224
225
226
227
228
  DEB_MEMBER_FUNCT();
  AutoMutex aLock(m_cond.mutex());
  _initVariable();
  _connect(host,port);
}
Arafat Noureddine's avatar
Arafat Noureddine committed
229

230
231
232
void Camera::_connect(const char *host,int port)
{
    DEB_MEMBER_FUNCT();
Arafat Noureddine's avatar
Arafat Noureddine committed
233
234
235
236

    if(host && port)
    {
        if(m_socket >= 0)
237
        {
Arafat Noureddine's avatar
Arafat Noureddine committed
238
            close(m_socket);
239
240
            m_socket = -1;
        }
Arafat Noureddine's avatar
Arafat Noureddine committed
241
242
        else
        {
243
            m_socket = socket(PF_INET, SOCK_STREAM,IPPROTO_TCP);
Arafat Noureddine's avatar
Arafat Noureddine committed
244
245
246
247
248
249
250
            if(m_socket >= 0)
            {
                int flag = 1;
                setsockopt(m_socket,IPPROTO_TCP,TCP_NODELAY, (void*)&flag,sizeof(flag));
                struct sockaddr_in add;
                add.sin_family = AF_INET;
                add.sin_port = htons((unsigned short)port);
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
251
                add.sin_addr.s_addr = inet_addr(_get_ip_addresse(host));
Arafat Noureddine's avatar
Arafat Noureddine committed
252
253
254
255
256
257
                if(::connect(m_socket,reinterpret_cast<sockaddr*>(&add),sizeof(add)))
                {
                    close(m_socket);
                    m_socket = -1;
                    THROW_HW_ERROR(Error) << "Can't open connection";
                }
258
259
260
                if(write(m_pipes[1],"|",1) == -1)
		  DEB_ERROR() << "Something wrong happen to pipe ???";

261
                m_state = Camera::STANDBY;
Arafat Noureddine's avatar
Arafat Noureddine committed
262
263
264
265
266
267
                _resync();
            }
            else
                THROW_HW_ERROR(Error) << "Can't create socket";
        }
    }
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
268
269
    //Workaround to avoid bug in camserver
    send("exposure warmup.edf");
270
271
}

Arafat Noureddine's avatar
Arafat Noureddine committed
272
273
274
//-----------------------------------------------------
//
//-----------------------------------------------------
275
void Camera::_resync()
276
{
277
278
279
280
    if(m_has_cmd_setenergy)
      send("setenergy");
    else
      send("setthreshold");
Arafat Noureddine's avatar
Arafat Noureddine committed
281
282
    send("exptime");
    send("expperiod");
283
    send("nimages 1");
Arafat Noureddine's avatar
Arafat Noureddine committed
284
285
286
287
288
289
290
    std::stringstream cmd;
    cmd<<"imgpath "<<m_imgpath;
    send(cmd.str());
    send("delay");
    send("nexpframe");
    send("setackint 0");
    send("dbglvl 1");
291
    send("version");
292
293
}

Arafat Noureddine's avatar
Arafat Noureddine committed
294
295
296
//-----------------------------------------------------
//
//-----------------------------------------------------
297
void Camera::_reinit()
298
{
Arafat Noureddine's avatar
Arafat Noureddine committed
299
300
    _resync();
    send("nimages");
301
}
302
303
304
305
306
307
308
//-----------------------------------------------------
//
//-----------------------------------------------------
void Camera::_pilatus3model()
{
  m_pilatus3_threshold_mode = true;
}
Arafat Noureddine's avatar
Arafat Noureddine committed
309
//-----------------------------------------------------
310
311
312
313
314
315
316
317
318
319
320
321
// This method will reset threshold if it's a pilatus3 
// and bugged version
//-----------------------------------------------------
void Camera::_work_around_threshold_bug()
{
  if(m_pilatus3_threshold_mode &&
     m_major_version <= 7 &&
     m_minor_version <= 4 &&
     m_patch_version <= 3)
    send("setthreshold 0");
}
//-----------------------------------------------------
Arafat Noureddine's avatar
Arafat Noureddine committed
322
323
//
//-----------------------------------------------------
324
void Camera::send(const std::string& message)
325
{
Arafat Noureddine's avatar
Arafat Noureddine committed
326
    DEB_MEMBER_FUNCT();
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
327
    DEB_TRACE() << DEB_VAR1(message);
Arafat Noureddine's avatar
Arafat Noureddine committed
328
    std::string msg = message;
329
    msg+= SOCKET_SEPARATOR;
330
331
332
    if(write(m_socket,msg.c_str(),msg.size()) == -1)
      THROW_HW_ERROR(Error) << "Could not send message to camserver";

333
334
}

Arafat Noureddine's avatar
Arafat Noureddine committed
335
336
337
//-----------------------------------------------------
//
//-----------------------------------------------------
338
void* Camera::_runFunc(void *commPt)
339
{
340
    ((Camera*)commPt)->_run();
Arafat Noureddine's avatar
Arafat Noureddine committed
341
    return NULL;
342
343
}

344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380

/******************************************************
--> SUCCESS CASE (set number of images)
ni 10
15 OK N images set to: 10

--> SUCCESS CASE (get path where images are saved)
imgpath
10 OK /home/det/p2_det/images/

--> SUCCESS CASE (get path where images must be saved)
imgpath /ramdisk/tmp/Arafat
10 OK /ramdisk/tmp/Arafat/

--> SUCCESS CASE (set exposure period)
expp 0.2
15 OK Exposure period set to: 0.2000000 sec

--> SUCCESS CASE (set exposure time)
expt 0.997
15 OK Exposure time set to: 0.9970000 sec

--> SUCCESS CASE (start acquisition)
exposure toto_0001.cbf
15 OK  Starting 0.1970000 second background: 2011-Aug-04T15:27:22.593
7 OK /ramdisk/tmp/Arafat/toto_0300.cbf

--> SUCCESS CASE (abort acquisition)
exposure toto_0001.cbf
15 OK  Starting 0.1970000 second background: 2011-Aug-04T15:33:03.178
k
13 ERR kill
7 OK /ramdisk/tmp/Arafat/toto_0019.cbf

--> SUCCESS CASE (get threshold)
setthr
15 OK  Settings: mid gain; threshold: 6300 eV; vcmp: 0.654 V
Arafat Noureddine's avatar
Arafat Noureddine committed
381
 Trim file:
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
  /home/det/p2_det/config/calibration/p6m0106_E12600_T6300_vrf_m0p20.bin
 
--> SUCCESS CASE (set threshold to 6000)
setthr 6000
15 OK /tmp/setthreshold.cmd

--> ERROR CASE (send a bad command)
threshold
1 ERR *** Unrecognized command: threshold

--> ERROR CASE (bad parameters)
setthr low 5000
15 ERR ERROR: unknown gain setting: low 5000

TO DO :
397
398
399
1 - manage state for threshold : DONE -> OK
2 - resync() after threshold -> need manage state : DONE -> OK
3 - manage the stop() command like an abort :DONE -> OK
400
******************************************************/
401
void Camera::_run()
402
{
Arafat Noureddine's avatar
Arafat Noureddine committed
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
    DEB_MEMBER_FUNCT();
    struct pollfd fds[2];
    fds[0].fd = m_pipes[0];
    fds[0].events = POLLIN;

    fds[1].events = POLLIN;
    AutoMutex aLock(m_cond.mutex());
    while(!m_stop)
    {
        int nb_poll_fd = 1;
        if(m_socket >= 0)
        {
            fds[1].fd = m_socket;
            ++nb_poll_fd;
        }
        aLock.unlock();
        poll(fds,nb_poll_fd,-1);
        aLock.lock();
        if(fds[0].revents)
        {
            char buffer[1024];
424
425
            if(read(m_pipes[0],buffer,sizeof(buffer)) == -1)
	      DEB_WARNING() << "Something strange happen!";
Arafat Noureddine's avatar
Arafat Noureddine committed
426
427
428
429
        }
        if(nb_poll_fd > 1 && fds[1].revents)
        {
            char messages[16384];
430
431
            int aMessageSize = recv(m_socket,messages,sizeof(messages),0);                    
            if(aMessageSize<=0)
Arafat Noureddine's avatar
Arafat Noureddine committed
432
            {
433
                DEB_TRACE() <<"-- no message received";
Arafat Noureddine's avatar
Arafat Noureddine committed
434
435
                close(m_socket);
                m_socket = -1;
436
                m_state = Camera::DISCONNECTED;                
Arafat Noureddine's avatar
Arafat Noureddine committed
437
438
            }
            else
439
            {                
440
441
                if(m_state == Camera::ERROR)//nothing to do, keep last error until a new explicit user command (start, stop, setenergy, ...)
                  continue;
442
                std::string strMessages(messages,aMessageSize );                    
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
443
                DEB_TRACE() << DEB_VAR1(strMessages);
Arafat Noureddine's avatar
Arafat Noureddine committed
444
                std::vector<std::string> msg_vector;
445
                _split(strMessages,SPLIT_SEPARATOR,msg_vector);
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
446
447
                for(std::vector<std::string>::iterator msg_iterator = msg_vector.begin();
		    msg_iterator != msg_vector.end();++msg_iterator)
Arafat Noureddine's avatar
Arafat Noureddine committed
448
449
450
451
452
453
                {
                    std::string &msg = *msg_iterator;

                    if(msg.substr(0,2) == "15") // generic response
                    {
                        if(msg.substr(3,2) == "OK") // will check what the message is about
454
                        {                            
Arafat Noureddine's avatar
Arafat Noureddine committed
455
                            std::string real_message = msg.substr(6);
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
			    size_t position;
                            if(real_message.find("Energy") != std::string::npos)
			    {
			      size_t columnPos = real_message.find(":");
			      if(columnPos == std::string::npos)
				{
				  m_threshold = m_energy = -1;
				  m_gain = DEFAULT_GAIN;
				}
			      else
				m_energy = atoi(real_message.substr(columnPos + 1).c_str());
			    }
                            if((position = real_message.find("Settings:")) !=
			       std::string::npos) // Threshold and gain is already set,read them
                            {
			        std::string submsg = real_message.substr(position);
Arafat Noureddine's avatar
Arafat Noureddine committed
472
                                std::vector<std::string> threshold_vector;
473
                                _split(submsg.substr(10),";",threshold_vector);
Arafat Noureddine's avatar
Arafat Noureddine committed
474
475
476
477
478
479
480
481
482
483
484
485
                                std::string &gain_string = threshold_vector[0];
                                std::string &threshold_string = threshold_vector[1];
                                std::vector<std::string> thr_val;
                                _split(threshold_string," ",thr_val);
                                std::string &threshold_value = thr_val[2];
                                m_threshold = atoi(threshold_value.c_str());

                                std::vector<std::string> gain_split;
                                _split(gain_string," ",gain_split);
                                std::string &gain_value = gain_split[0];
                                std::map<std::string,Gain>::iterator gFind = GAIN_SERVER_RESPONSE.find(gain_value);
                                m_gain = gFind->second;
486
                                m_state = Camera::STANDBY;                               
Arafat Noureddine's avatar
Arafat Noureddine committed
487
488
489
                            }
                            else if(real_message.find("/tmp/setthreshold")!=std::string::npos)
                            {
490
491
492
493
494
495
496
497
                                if(m_state == Camera::SETTING_THRESHOLD)
                                {
                                  DEB_TRACE() << "-- Threshold process succeeded";
                                }
                                if(m_state == Camera::SETTING_ENERGY)
                                {
                                  DEB_TRACE() << "-- SetEnergy process succeeded";
                                }
498
                                _reinit(); // resync with server
Arafat Noureddine's avatar
Arafat Noureddine committed
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
                            }
                            else if(real_message.find("Exposure")!=std::string::npos)
                            {
                                int columnPos = real_message.find(":");
                                int lastSpace = real_message.rfind(" ");
                                if(real_message.substr(9,4) == "time")
                                {
                                    m_exposure = atof(real_message.substr(columnPos + 1,lastSpace).c_str());
                                }
                                else if(real_message.substr(9,6) == "period")
                                {
                                    m_exposure_period = atof(real_message.substr(columnPos + 1,lastSpace).c_str());
                                }
                                else // Exposures per frame
                                {
                                    m_exposure_per_frame = atoi(real_message.substr(columnPos + 1).c_str());\
                                }
                            }
                            else if(real_message.find("Delay")!=std::string::npos)
                            {
                                int columnPos = real_message.find(":");
                                int lastSpace = real_message.rfind(" ");
                                m_hardware_trigger_delay = atof(real_message.substr(columnPos + 1,lastSpace).c_str());
                            }
                            else if(real_message.find("N images")!=std::string::npos)
                            {
                                int columnPos = real_message.find(":");
                                m_nimages = atoi(real_message.substr(columnPos+1).c_str());
                            }
528
529
			    if(m_state != Camera::RUNNING)
			      m_state = Camera::STANDBY;
Arafat Noureddine's avatar
Arafat Noureddine committed
530
531
532
                        }
                        else  // ERROR MESSAGE
                        {
533
			  m_error_message = msg.substr(7);
534
                            if(m_state == Camera::SETTING_THRESHOLD)
535
			      DEB_TRACE() << "-- Threshold process failed";
536
                            if(m_state == Camera::SETTING_ENERGY)
537
			      DEB_TRACE() << "-- SetEnergy process failed";
538
                            else if(m_state == Camera::RUNNING)
539
			      DEB_TRACE() << "-- Exposure process failed";
Arafat Noureddine's avatar
Arafat Noureddine committed
540
                            else
541
542
			      DEB_TRACE() << "-- ERROR " << m_error_message;

543
544
			    m_state = Camera::ERROR;
			}
Arafat Noureddine's avatar
Arafat Noureddine committed
545
546
547
548
                        m_cond.broadcast();
                    }
                    else if(msg.substr(0,2) == "13") //Acquisition Killed
                    {
549
                        DEB_TRACE() << "-- Acquisition Killed"; 
550
                        m_state = Camera::STANDBY;
Arafat Noureddine's avatar
Arafat Noureddine committed
551
                    }
552
                    else if(msg.substr(0,2) == "7 ")
Arafat Noureddine's avatar
Arafat Noureddine committed
553
                    {
554
                        if(msg.substr(2,2) == "OK")
Arafat Noureddine's avatar
Arafat Noureddine committed
555
                        {
556
557
                            DEB_TRACE() << "-- Exposure succeeded";
                            m_state = Camera::STANDBY;
558
                            m_nb_acquired_images = m_nimages;
Arafat Noureddine's avatar
Arafat Noureddine committed
559
                        }
560
                        else
Arafat Noureddine's avatar
Arafat Noureddine committed
561
                        {
562
                            DEB_TRACE() << "-- ERROR";                      
563
                            m_state = Camera::ERROR;
564
565
566
567
568
569
570
571
                            msg = msg.substr(2);
                            m_error_message = msg.substr(msg.find(" "));
                        }
                    }
                    else if(msg.substr(0,2) == "1 ")
                    {
                        if(msg.substr(2,3) == "ERR")
                        {
572
573
574
575
576
577
578
			  // Not an error just old version of camserver
			  if(msg.find("Unrecognized command: setenergy") != 
			     std::string::npos)
			    {
			      m_has_cmd_setenergy = false;
			      _resync();
			    }
579
580
581
582
583
			  else if(msg.find("Unrecognized command: version") != 
				  std::string::npos)
			    {
			      DEB_TRACE() << "Can't retrieved camserver version";
			    }
584
585
			  else
			    {
586
587
588
                            DEB_TRACE() << "-- ERROR";
                            m_error_message = msg.substr(6);
                            DEB_TRACE() << m_error_message;
589
                            m_state = Camera::ERROR;
590
			    }
Arafat Noureddine's avatar
Arafat Noureddine committed
591
592
                        }
                    }
593
594
595
596
597
                    else if(msg.substr(0,2) == "10")
                    {
                        if(msg.substr(3,2) == "OK")
                        {
                            DEB_TRACE() << "-- imgpath setting succeeded";
598
                            ////m_imgpath = msg.substr(6);////@@@@
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
599
                            m_state = Camera::STANDBY;
600
601
602
603
                        }
                        else
                        {
                            DEB_TRACE() << "-- ERROR";
604
                            m_state = Camera::ERROR;
605
606
607
608
609
                            msg = msg.substr(2);
                            m_error_message = msg.substr(msg.find(" "));
                            DEB_TRACE() << m_error_message;
                        }                        
                    }
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
		    else if(msg.substr(0,2) == "24")
		      {
			if(msg.substr(3,2) == "OK" &&
			   msg.substr(6,12) == "Code release")
			  {
			    DEB_TRACE() << msg.substr(6);
			    std::vector<std::string> version_vector;
			    _split(msg.substr(20),".",version_vector);
			    if(version_vector.size() == 3)
			      {
				m_major_version = atoi(version_vector[0].c_str());
				m_minor_version = atoi(version_vector[1].c_str());
				m_patch_version = atoi(version_vector[2].c_str());
			      }
			  }
		      }
Arafat Noureddine's avatar
Arafat Noureddine committed
626
627
628
629
630
631
632
633
                }
            }
        }
    }
}
//-----------------------------------------------------
//
//-----------------------------------------------------
634
void Camera::setImgpath(const std::string& path)
Arafat Noureddine's avatar
Arafat Noureddine committed
635
636
637
{
    DEB_MEMBER_FUNCT();
    AutoMutex aLock(m_cond.mutex());
638
639
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set imgpath, server not idle");
Arafat Noureddine's avatar
Arafat Noureddine committed
640
641
642
643
644
    m_imgpath = path;    
    std::stringstream cmd;
    cmd<<"imgpath "<<m_imgpath;
    send(cmd.str());
}
645

Arafat Noureddine's avatar
Arafat Noureddine committed
646
647
648
//-----------------------------------------------------
//
//-----------------------------------------------------
649
const std::string& Camera::imgpath() const
Arafat Noureddine's avatar
Arafat Noureddine committed
650
651
652
653
654
655
656
657
{
    AutoMutex aLock(m_cond.mutex());
    return m_imgpath;
}

//-----------------------------------------------------
//
//-----------------------------------------------------   
658
void Camera::setFileName(const std::string& name)
Arafat Noureddine's avatar
Arafat Noureddine committed
659
660
661
662
663
{
    DEB_MEMBER_FUNCT();
    AutoMutex aLock(m_cond.mutex());
    m_file_name = name;
    m_file_pattern = m_file_name;
664
665
}

Arafat Noureddine's avatar
Arafat Noureddine committed
666
667
668
//-----------------------------------------------------
//
//-----------------------------------------------------
669
const std::string& Camera::fileName() const
Arafat Noureddine's avatar
Arafat Noureddine committed
670
671
672
673
674
675
{
    AutoMutex aLock(m_cond.mutex());
    return m_file_name;
}
    
    
Arafat Noureddine's avatar
Arafat Noureddine committed
676
677
678
//-----------------------------------------------------
//
//-----------------------------------------------------
679
Camera::Status Camera::status() const
680
{
Arafat Noureddine's avatar
Arafat Noureddine committed
681
682
    AutoMutex aLock(m_cond.mutex());
    return m_state;
683
684
}

Arafat Noureddine's avatar
Arafat Noureddine committed
685
686
687
//-----------------------------------------------------
//
//-----------------------------------------------------
688
const std::string& Camera::errorMessage() const
689
{
Arafat Noureddine's avatar
Arafat Noureddine committed
690
691
    AutoMutex aLock(m_cond.mutex());
    return m_error_message;
692
693
}

Arafat Noureddine's avatar
Arafat Noureddine committed
694
695
696
//-----------------------------------------------------
//
//-----------------------------------------------------
697
void Camera::softReset()
698
{
Arafat Noureddine's avatar
Arafat Noureddine committed
699
700
    AutoMutex aLock(m_cond.mutex());
    m_error_message.clear();
701
    m_state = Camera::STANDBY;
702
}
Arafat Noureddine's avatar
Arafat Noureddine committed
703
704
705
706

//-----------------------------------------------------
//
//-----------------------------------------------------
707
void Camera::hardReset()
708
{
Arafat Noureddine's avatar
Arafat Noureddine committed
709
710
    AutoMutex aLock(m_cond.mutex());
    send("resetcam");
711
}
Arafat Noureddine's avatar
Arafat Noureddine committed
712

713
//-----------------------------------------------------
714
// Return energy in keV
715
716
717
718
//-----------------------------------------------------
double Camera::energy() const
{
    AutoMutex aLock(m_cond.mutex());
719
720
721
722
    if(m_has_cmd_setenergy)
       return (double)m_energy/1000;
    else
       return (double)m_threshold/600;
723
724
725
}

//-----------------------------------------------------
726
// Set energy in keV
727
728
729
730
731
732
//-----------------------------------------------------
void Camera::setEnergy(double val)
{
    DEB_MEMBER_FUNCT();

    AutoMutex aLock(m_cond.mutex());
733
734
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set energy, server is not idle");
735
736
    if(m_has_cmd_setenergy)
      {
737
738
	_work_around_threshold_bug();

739
740
	m_state = Camera::SETTING_ENERGY;
	std::stringstream msg;
741
	msg << "setenergy " << val*1000;
742
743
744
	send(msg.str());
      }
    else
745
746
747
748
749
750
751
752
753
754
755
756
757
      {
        Camera::Gain gain;
        int threshold;
        // In old version of camserver,  setenergy is not implemented, emulate it instead
        // with threshold and gain, according to rules of ranges given by Dectris support
        threshold = (int)(val * 600); //60% of the energy in eV
        if (val > 12) gain = LOW;
        else if (val > 8 && val <= 12) gain = MID;
        else if (val >= 6 && val <= 8) gain = HIGH;
        else gain = UHIGH;
        aLock.unlock();
        setThresholdGain(threshold, gain);
      }
758
759
760

}

Arafat Noureddine's avatar
Arafat Noureddine committed
761
//-----------------------------------------------------
762
// Return the threshold in eV
Arafat Noureddine's avatar
Arafat Noureddine committed
763
//-----------------------------------------------------
764
int Camera::threshold() const
765
{
Arafat Noureddine's avatar
Arafat Noureddine committed
766
767
    AutoMutex aLock(m_cond.mutex());
    return m_threshold;
768
769
}

Arafat Noureddine's avatar
Arafat Noureddine committed
770
//-----------------------------------------------------
771
// Return the gain
Arafat Noureddine's avatar
Arafat Noureddine committed
772
//-----------------------------------------------------
773
Camera::Gain Camera::gain() const
774
{
Arafat Noureddine's avatar
Arafat Noureddine committed
775
776
    AutoMutex aLock(m_cond.mutex());
    return m_gain;
777
778
}

Arafat Noureddine's avatar
Arafat Noureddine committed
779
//-----------------------------------------------------
780
// Set Threshold (ev) and gain pair
Arafat Noureddine's avatar
Arafat Noureddine committed
781
//-----------------------------------------------------
782
void Camera::setThresholdGain(int value,Camera::Gain gain)
783
{
Arafat Noureddine's avatar
Arafat Noureddine committed
784
    DEB_MEMBER_FUNCT();
785

Arafat Noureddine's avatar
Arafat Noureddine committed
786
    AutoMutex aLock(m_cond.mutex());
787
788
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set threshold, server is not idle");
789
    m_state = Camera::SETTING_THRESHOLD;    
Arafat Noureddine's avatar
Arafat Noureddine committed
790
791
792
793
794
795
796
797
798
799
    if(gain == DEFAULT_GAIN)
    {
        char buffer[128];
        snprintf(buffer,sizeof(buffer),"setthreshold %d",value);
        send(buffer);
    }
    else
    {
        std::map<Gain,std::string>::iterator i = GAIN_VALUE2SERVER.find(gain);
        std::string &gainStr = i->second;
800

Arafat Noureddine's avatar
Arafat Noureddine committed
801
802
        char buffer[128];
        snprintf(buffer,sizeof(buffer),"setthreshold %s %d",gainStr.c_str(),value);
803

Arafat Noureddine's avatar
Arafat Noureddine committed
804
805
        send(buffer);
    }
806

807

Arafat Noureddine's avatar
Arafat Noureddine committed
808
809
    if (m_gap_fill)
        send("gapfill -1");
810
}
811
812
813
814
815
816
817
818
819
//-----------------------------------------------------
//
//-----------------------------------------------------
void Camera::setThreshold(int threshold,int energy)
{
  DEB_MEMBER_FUNCT();

  if(!m_pilatus3_threshold_mode)
    THROW_HW_ERROR(NotSupported) << "Could not use pilatus threshold flavor";
Arafat Noureddine's avatar
Arafat Noureddine committed
820

821
822
823
824
  AutoMutex aLock(m_cond.mutex());
  RECONNECT_WAIT_UNTIL(Camera::STANDBY,
		       "Could not set threshold,server is not idle");

825
826
  _work_around_threshold_bug();

827
828
829
830
831
832
833
834
835
836
837
838
839
840
  m_state = Camera::SETTING_THRESHOLD;
  if(energy < 0)
    {
      char buffer[128];
      snprintf(buffer,sizeof(buffer),"setthreshold %d",threshold);
      send(buffer);
    }
  else
    {
      char buffer[128];
      snprintf(buffer,sizeof(buffer),"setthreshold energy %d %d",energy,threshold);
      send(buffer);
    }
}
Arafat Noureddine's avatar
Arafat Noureddine committed
841
842
843
//-----------------------------------------------------
//
//-----------------------------------------------------
844
double Camera::exposure() const
845
{
Arafat Noureddine's avatar
Arafat Noureddine committed
846
847
    AutoMutex aLock(m_cond.mutex());
    return m_exposure;
848
849
}

Arafat Noureddine's avatar
Arafat Noureddine committed
850
851
852
//-----------------------------------------------------
//
//-----------------------------------------------------
853
void Camera::setExposure(double val)
854
{
Arafat Noureddine's avatar
Arafat Noureddine committed
855
856
857
858
    DEB_MEMBER_FUNCT();
    AutoMutex aLock(m_cond.mutex());
    // yet an other border-effect with the SPEC CCD interface
    // to reach the GATE mode SPEC programs extgate + expotime = 0
859
    if(m_trigger_mode == Camera::EXTERNAL_GATE and val <= 0)
Arafat Noureddine's avatar
Arafat Noureddine committed
860
        return;
861

862
863
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set exposure, server is not idle");
864
    m_state = Camera::SETTING_EXPOSURE;
Arafat Noureddine's avatar
Arafat Noureddine committed
865
866
867
    std::stringstream msg;
    msg << "exptime " << val;
    send(msg.str());
868
869
}

Arafat Noureddine's avatar
Arafat Noureddine committed
870
871
872
//-----------------------------------------------------
//
//-----------------------------------------------------
873
double Camera::exposurePeriod() const
874
{
Arafat Noureddine's avatar
Arafat Noureddine committed
875
876
    AutoMutex aLock(m_cond.mutex());
    return m_exposure_period;
877
878
}

Arafat Noureddine's avatar
Arafat Noureddine committed
879
880
881
//-----------------------------------------------------
//
//-----------------------------------------------------
882
void Camera::setExposurePeriod(double val)
883
{
Arafat Noureddine's avatar
Arafat Noureddine committed
884
885
    DEB_MEMBER_FUNCT();
    AutoMutex aLock(m_cond.mutex());
886
887
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set exposure period, server not idle");
888
    m_state = Camera::SETTING_EXPOSURE_PERIOD;
Arafat Noureddine's avatar
Arafat Noureddine committed
889
    std::stringstream msg;
890
    msg << std::setprecision(9) << "expperiod " << val;
Arafat Noureddine's avatar
Arafat Noureddine committed
891
    send(msg.str());
892
893
894
895
896
897
898
899
900
    // Exposure period can failed if it's two fast
    while(m_state == Camera::SETTING_EXPOSURE_PERIOD)
      m_cond.wait(TIME_OUT);
    if(m_state == Camera::ERROR)
      {
	m_state = Camera::STANDBY;
	THROW_HW_ERROR(Error) << "Could not set exposure period to:"
			      << DEB_VAR2(val,m_error_message);
      }
901
902
}

Arafat Noureddine's avatar
Arafat Noureddine committed
903
904
905
//-----------------------------------------------------
//
//-----------------------------------------------------
906
int Camera::nbImagesInSequence() const
907
{
Arafat Noureddine's avatar
Arafat Noureddine committed
908
909
    AutoMutex aLock(m_cond.mutex());
    return m_nimages;
910
911
}

Arafat Noureddine's avatar
Arafat Noureddine committed
912
913
914
//-----------------------------------------------------
//
//-----------------------------------------------------
915
void Camera::setNbImagesInSequence(int nb)
916
{
Arafat Noureddine's avatar
Arafat Noureddine committed
917
918
    DEB_MEMBER_FUNCT();
    AutoMutex aLock(m_cond.mutex());
919
920
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set number image in sequence, server not idle");
921
    m_state = Camera::SETTING_NB_IMAGE_IN_SEQUENCE;
Arafat Noureddine's avatar
Arafat Noureddine committed
922
923
924
    std::stringstream msg;
    msg << "nimages " << nb;
    send(msg.str());
925
926
}

Arafat Noureddine's avatar
Arafat Noureddine committed
927
928
929
//-----------------------------------------------------
//
//-----------------------------------------------------
930
double Camera::hardwareTriggerDelay() const
931
{
Arafat Noureddine's avatar
Arafat Noureddine committed
932
933
    AutoMutex aLock(m_cond.mutex());
    return m_hardware_trigger_delay;
934
935
}

Arafat Noureddine's avatar
Arafat Noureddine committed
936
937
938
//-----------------------------------------------------
//
//-----------------------------------------------------
939
void Camera::setHardwareTriggerDelay(double value)
940
{
Arafat Noureddine's avatar
Arafat Noureddine committed
941
942
    DEB_MEMBER_FUNCT();
    AutoMutex aLock(m_cond.mutex());
943
944
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set hardware trigger delay, server not idle");
945
    m_state = Camera::SETTING_HARDWARE_TRIGGER_DELAY;
Arafat Noureddine's avatar
Arafat Noureddine committed
946
947
948
    std::stringstream msg;
    msg << "delay " << value;
    send(msg.str());
949
}
Arafat Noureddine's avatar
Arafat Noureddine committed
950
951
952
953

//-----------------------------------------------------
//
//-----------------------------------------------------
954
int Camera::nbExposurePerFrame() const
955
{
Arafat Noureddine's avatar
Arafat Noureddine committed
956
957
    AutoMutex aLock(m_cond.mutex());
    return m_exposure_per_frame;
958
959
}

Arafat Noureddine's avatar
Arafat Noureddine committed
960
961
962
//-----------------------------------------------------
//
//-----------------------------------------------------
963
void Camera::setNbExposurePerFrame(int val)
964
{
Arafat Noureddine's avatar
Arafat Noureddine committed
965
966
    DEB_MEMBER_FUNCT();
    AutoMutex aLock(m_cond.mutex());
967
968
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set exposure per frame, server not idle");
969
    m_state = Camera::SETTING_EXPOSURE_PER_FRAME;
Arafat Noureddine's avatar
Arafat Noureddine committed
970
971
972
    std::stringstream msg;
    msg << "nexpframe " << val;
    send(msg.str());
973
974
}

Arafat Noureddine's avatar
Arafat Noureddine committed
975
976
977
//-----------------------------------------------------
//
//-----------------------------------------------------
978
Camera::TriggerMode Camera::triggerMode() const
979
{
Arafat Noureddine's avatar
Arafat Noureddine committed
980
981
    AutoMutex aLock(m_cond.mutex());
    return m_trigger_mode;
982
983
}

Arafat Noureddine's avatar
Arafat Noureddine committed
984
//-----------------------------------------------------
985
986
987
//@brief set the trigger mode
//
//Trigger can be:
Arafat Noureddine's avatar
Arafat Noureddine committed
988
989
990
// - Internal (Software) == INTERNAL_SINGLE
// - External start == EXTERNAL_SINGLE
// - External multi start == EXTERNAL_MULTI
991
// - External gate == EXTERNAL_GATE
Arafat Noureddine's avatar
Arafat Noureddine committed
992
//-----------------------------------------------------
993
void Camera::setTriggerMode(Camera::TriggerMode triggerMode)
994
{
Arafat Noureddine's avatar
Arafat Noureddine committed
995
996
    AutoMutex aLock(m_cond.mutex());
    m_trigger_mode = triggerMode;
997
998
}

Arafat Noureddine's avatar
Arafat Noureddine committed
999
1000

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