PilatusCamera.cpp 37.4 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

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

#include <poll.h>
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
39
#include <unistd.h>
40

41
#include "lima/Exceptions.h"
42

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

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

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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));
    }
}
71
72


73
74
75
76
#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
77
  while(m_state != testState &&					    \
78
79
	m_state != Camera::ERROR &&				    \
	m_state != Camera::DISCONNECTED)			    \
Arafat Noureddine's avatar
Arafat Noureddine committed
80
81
82
{                                                                   \
  if(!m_cond.wait(TIME_OUT))                                        \
    THROW_HW_ERROR(lima::Error) << errmsg;                          \
Arafat Noureddine's avatar
Arafat Noureddine committed
83
}
84

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

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

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

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

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

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

132
133
134
135
136
137
138
    try
      {
	connect(host,port);
      }
    catch(Exception &e)		// Not an error in that case
      {
      }
139
140
}

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

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

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

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

//-----------------------------------------------------
//
//-----------------------------------------------------
188
int Camera::serverPort() const
Arafat Noureddine's avatar
Arafat Noureddine committed
189
{
Arafat Noureddine's avatar
Arafat Noureddine committed
190
    return m_server_port;
Arafat Noureddine's avatar
Arafat Noureddine committed
191
192
193
194
195
}

//-----------------------------------------------------
//
//-----------------------------------------------------
196
void Camera::_initVariable()
197
{
Arafat Noureddine's avatar
Arafat Noureddine committed
198
199
200
201
    m_imgpath                           = "/ramdisk/images/";
    m_file_name                         = "image_%.5d.cbf";
    m_file_pattern                      = m_file_name;
    m_threshold                         = -1;
202
    m_energy                            = -1;
Arafat Noureddine's avatar
Arafat Noureddine committed
203
204
205
206
207
208
    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
209
    m_nb_acquired_images 		= 0;
210
    m_trigger_mode 			= INTERNAL_SINGLE;
211

Arafat Noureddine's avatar
Arafat Noureddine committed
212
213
214
215
    GAIN_SERVER_RESPONSE["low"]         = LOW;
    GAIN_SERVER_RESPONSE["mid"]         = MID;
    GAIN_SERVER_RESPONSE["high"]        = HIGH;
    GAIN_SERVER_RESPONSE["ultra high"]  = UHIGH;
216

Arafat Noureddine's avatar
Arafat Noureddine committed
217
218
219
220
    GAIN_VALUE2SERVER[LOW]              = "lowG";
    GAIN_VALUE2SERVER[MID]              = "midG";
    GAIN_VALUE2SERVER[HIGH]             = "highG";
    GAIN_VALUE2SERVER[UHIGH]            = "uhighG";
221
}
Arafat Noureddine's avatar
Arafat Noureddine committed
222
223
224
225

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

234
235
236
void Camera::_connect(const char *host,int port)
{
    DEB_MEMBER_FUNCT();
Arafat Noureddine's avatar
Arafat Noureddine committed
237
238
239
240

    if(host && port)
    {
        if(m_socket >= 0)
241
        {
Arafat Noureddine's avatar
Arafat Noureddine committed
242
            close(m_socket);
243
244
            m_socket = -1;
        }
Arafat Noureddine's avatar
Arafat Noureddine committed
245
246
        else
        {
247
            m_socket = socket(PF_INET, SOCK_STREAM,IPPROTO_TCP);
Arafat Noureddine's avatar
Arafat Noureddine committed
248
249
250
251
252
253
254
            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
255
                add.sin_addr.s_addr = inet_addr(_get_ip_addresse(host));
Arafat Noureddine's avatar
Arafat Noureddine committed
256
257
258
259
260
261
                if(::connect(m_socket,reinterpret_cast<sockaddr*>(&add),sizeof(add)))
                {
                    close(m_socket);
                    m_socket = -1;
                    THROW_HW_ERROR(Error) << "Can't open connection";
                }
262
263
264
                if(write(m_pipes[1],"|",1) == -1)
		  DEB_ERROR() << "Something wrong happen to pipe ???";

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

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

Arafat Noureddine's avatar
Arafat Noureddine committed
300
301
302
//-----------------------------------------------------
//
//-----------------------------------------------------
303
void Camera::_reinit()
304
{
Arafat Noureddine's avatar
Arafat Noureddine committed
305
306
    _resync();
    send("nimages");
307
}
308
309
310
//-----------------------------------------------------
//
//-----------------------------------------------------
Jordi's avatar
Jordi committed
311
312
313
314
315
316
317
void Camera::_pilatus2model()
{
  m_pilatus2_model = true;
}
//-----------------------------------------------------
//
//-----------------------------------------------------
318
319
320
321
void Camera::_pilatus3model()
{
  m_pilatus3_threshold_mode = true;
}
Arafat Noureddine's avatar
Arafat Noureddine committed
322
//-----------------------------------------------------
323
324
325
326
327
328
329
330
331
332
333
334
// 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
335
336
//
//-----------------------------------------------------
337
void Camera::send(const std::string& message)
338
{
Arafat Noureddine's avatar
Arafat Noureddine committed
339
    DEB_MEMBER_FUNCT();
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
340
    DEB_TRACE() << DEB_VAR1(message);
Arafat Noureddine's avatar
Arafat Noureddine committed
341
    std::string msg = message;
342
    msg+= SOCKET_SEPARATOR;
343
344
345
    if(write(m_socket,msg.c_str(),msg.size()) == -1)
      THROW_HW_ERROR(Error) << "Could not send message to camserver";

346
347
}

Arafat Noureddine's avatar
Arafat Noureddine committed
348
349
350
//-----------------------------------------------------
//
//-----------------------------------------------------
351
void* Camera::_runFunc(void *commPt)
352
{
353
    ((Camera*)commPt)->_run();
Arafat Noureddine's avatar
Arafat Noureddine committed
354
    return NULL;
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
381
382
383
384
385
386
387
388
389
390
391
392
393

/******************************************************
--> 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
394
 Trim file:
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
  /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 :
410
411
412
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
413
******************************************************/
414
void Camera::_run()
415
{
Arafat Noureddine's avatar
Arafat Noureddine committed
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
    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];
437
438
            if(read(m_pipes[0],buffer,sizeof(buffer)) == -1)
	      DEB_WARNING() << "Something strange happen!";
Arafat Noureddine's avatar
Arafat Noureddine committed
439
440
441
442
        }
        if(nb_poll_fd > 1 && fds[1].revents)
        {
            char messages[16384];
443
444
            int aMessageSize = recv(m_socket,messages,sizeof(messages),0);                    
            if(aMessageSize<=0)
Arafat Noureddine's avatar
Arafat Noureddine committed
445
            {
446
                DEB_TRACE() <<"-- no message received";
Arafat Noureddine's avatar
Arafat Noureddine committed
447
448
                close(m_socket);
                m_socket = -1;
449
                m_state = Camera::DISCONNECTED;                
Arafat Noureddine's avatar
Arafat Noureddine committed
450
451
            }
            else
452
            {                
453
454
                if(m_state == Camera::ERROR)//nothing to do, keep last error until a new explicit user command (start, stop, setenergy, ...)
                  continue;
455
                std::string strMessages(messages,aMessageSize );                    
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
456
                DEB_TRACE() << DEB_VAR1(strMessages);
Arafat Noureddine's avatar
Arafat Noureddine committed
457
                std::vector<std::string> msg_vector;
458
                _split(strMessages,SPLIT_SEPARATOR,msg_vector);
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
459
460
                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
461
462
463
464
465
466
                {
                    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
467
                        {                            
Arafat Noureddine's avatar
Arafat Noureddine committed
468
                            std::string real_message = msg.substr(6);
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
			    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
485
                                std::vector<std::string> threshold_vector;
486
                                _split(submsg.substr(10),";",threshold_vector);
Arafat Noureddine's avatar
Arafat Noureddine committed
487
488
489
490
491
492
493
494
495
496
497
498
                                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;
499
                                m_state = Camera::STANDBY;                               
Arafat Noureddine's avatar
Arafat Noureddine committed
500
501
502
                            }
                            else if(real_message.find("/tmp/setthreshold")!=std::string::npos)
                            {
503
504
505
506
507
508
509
510
                                if(m_state == Camera::SETTING_THRESHOLD)
                                {
                                  DEB_TRACE() << "-- Threshold process succeeded";
                                }
                                if(m_state == Camera::SETTING_ENERGY)
                                {
                                  DEB_TRACE() << "-- SetEnergy process succeeded";
                                }
511
                                _reinit(); // resync with server
Arafat Noureddine's avatar
Arafat Noureddine committed
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
                            }
                            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());
                            }
541
542
			    if(m_state != Camera::RUNNING)
			      m_state = Camera::STANDBY;
Jordi's avatar
Jordi committed
543
544
545
546
547
548
                        }// Fixes message from camserver tvx-7.3.13-121212 version
                        else if(msg.substr(0,10) == "15 ERR ROI" && m_pilatus2_model)
			  {
			      DEB_TRACE() << "-- setROI process succeeded";
			      m_state = Camera::STANDBY;
			  }
Arafat Noureddine's avatar
Arafat Noureddine committed
549
550
                        else  // ERROR MESSAGE
                        {
551
			  m_error_message = msg.substr(7);
552
                            if(m_state == Camera::SETTING_THRESHOLD)
553
			      DEB_TRACE() << "-- Threshold process failed";
554
                            if(m_state == Camera::SETTING_ENERGY)
555
			      DEB_TRACE() << "-- SetEnergy process failed";
556
                            else if(m_state == Camera::RUNNING)
557
			      DEB_TRACE() << "-- Exposure process failed";
Arafat Noureddine's avatar
Arafat Noureddine committed
558
                            else
559
560
			      DEB_TRACE() << "-- ERROR " << m_error_message;

561
562
			    m_state = Camera::ERROR;
			}
Arafat Noureddine's avatar
Arafat Noureddine committed
563
564
565
566
                        m_cond.broadcast();
                    }
                    else if(msg.substr(0,2) == "13") //Acquisition Killed
                    {
567
                        DEB_TRACE() << "-- Acquisition Killed"; 
568
                        m_state = Camera::STANDBY;
Arafat Noureddine's avatar
Arafat Noureddine committed
569
                    }
570
                    else if(msg.substr(0,2) == "7 ")
Arafat Noureddine's avatar
Arafat Noureddine committed
571
                    {
572
                        if(msg.substr(2,2) == "OK")
Arafat Noureddine's avatar
Arafat Noureddine committed
573
                        {
574
575
                            DEB_TRACE() << "-- Exposure succeeded";
                            m_state = Camera::STANDBY;
576
                            m_nb_acquired_images = m_nimages;
Arafat Noureddine's avatar
Arafat Noureddine committed
577
                        }
578
                        else
Arafat Noureddine's avatar
Arafat Noureddine committed
579
                        {
580
                            DEB_TRACE() << "-- ERROR";                      
581
                            m_state = Camera::ERROR;
582
583
584
585
586
587
588
589
                            msg = msg.substr(2);
                            m_error_message = msg.substr(msg.find(" "));
                        }
                    }
                    else if(msg.substr(0,2) == "1 ")
                    {
                        if(msg.substr(2,3) == "ERR")
                        {
590
591
592
593
594
595
596
			  // Not an error just old version of camserver
			  if(msg.find("Unrecognized command: setenergy") != 
			     std::string::npos)
			    {
			      m_has_cmd_setenergy = false;
			      _resync();
			    }
597
598
599
600
601
			  else if(msg.find("Unrecognized command: version") != 
				  std::string::npos)
			    {
			      DEB_TRACE() << "Can't retrieved camserver version";
			    }
602
603
604
605
606
607
			  else if(msg.find("Unrecognized command: setroi") !=
				  std::string::npos)
			    {
			      m_has_cmd_roi = false;
			      _resync();
			    }
608
609
610
611
612
613
614
			  else if(msg.find("Unrecognized command: resetmodulepower") != 
				  std::string::npos)
			    {
			      m_cmd_high_voltage_reset = DONT_HAVE_HIGH_VOLTAGE;
			      m_state = Camera::STANDBY;
			      m_cond.broadcast();
			    }
615
616
			  else
			    {
617
618
619
                            DEB_TRACE() << "-- ERROR";
                            m_error_message = msg.substr(6);
                            DEB_TRACE() << m_error_message;
620
                            m_state = Camera::ERROR;
621
			    }
Arafat Noureddine's avatar
Arafat Noureddine committed
622
623
                        }
                    }
624
625
626
627
628
                    else if(msg.substr(0,2) == "10")
                    {
                        if(msg.substr(3,2) == "OK")
                        {
                            DEB_TRACE() << "-- imgpath setting succeeded";
629
                            ////m_imgpath = msg.substr(6);////@@@@
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
630
                            m_state = Camera::STANDBY;
631
632
633
634
                        }
                        else
                        {
                            DEB_TRACE() << "-- ERROR";
635
                            m_state = Camera::ERROR;
636
637
638
639
640
                            msg = msg.substr(2);
                            m_error_message = msg.substr(msg.find(" "));
                            DEB_TRACE() << m_error_message;
                        }                        
                    }
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
		    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
657
658
659
660
661
662
663
664
                }
            }
        }
    }
}
//-----------------------------------------------------
//
//-----------------------------------------------------
665
void Camera::setImgpath(const std::string& path)
Arafat Noureddine's avatar
Arafat Noureddine committed
666
667
668
{
    DEB_MEMBER_FUNCT();
    AutoMutex aLock(m_cond.mutex());
669
670
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set imgpath, server not idle");
Arafat Noureddine's avatar
Arafat Noureddine committed
671
672
673
674
675
    m_imgpath = path;    
    std::stringstream cmd;
    cmd<<"imgpath "<<m_imgpath;
    send(cmd.str());
}
676

Arafat Noureddine's avatar
Arafat Noureddine committed
677
678
679
//-----------------------------------------------------
//
//-----------------------------------------------------
680
const std::string& Camera::imgpath() const
Arafat Noureddine's avatar
Arafat Noureddine committed
681
682
683
684
685
686
687
688
{
    AutoMutex aLock(m_cond.mutex());
    return m_imgpath;
}

//-----------------------------------------------------
//
//-----------------------------------------------------   
689
void Camera::setFileName(const std::string& name)
Arafat Noureddine's avatar
Arafat Noureddine committed
690
691
692
693
694
{
    DEB_MEMBER_FUNCT();
    AutoMutex aLock(m_cond.mutex());
    m_file_name = name;
    m_file_pattern = m_file_name;
695
696
}

Arafat Noureddine's avatar
Arafat Noureddine committed
697
698
699
//-----------------------------------------------------
//
//-----------------------------------------------------
700
const std::string& Camera::fileName() const
Arafat Noureddine's avatar
Arafat Noureddine committed
701
702
703
704
705
706
{
    AutoMutex aLock(m_cond.mutex());
    return m_file_name;
}
    
    
Arafat Noureddine's avatar
Arafat Noureddine committed
707
708
709
//-----------------------------------------------------
//
//-----------------------------------------------------
710
Camera::Status Camera::status() const
711
{
Arafat Noureddine's avatar
Arafat Noureddine committed
712
713
    AutoMutex aLock(m_cond.mutex());
    return m_state;
714
715
}

Arafat Noureddine's avatar
Arafat Noureddine committed
716
717
718
//-----------------------------------------------------
//
//-----------------------------------------------------
719
const std::string& Camera::errorMessage() const
720
{
Arafat Noureddine's avatar
Arafat Noureddine committed
721
722
    AutoMutex aLock(m_cond.mutex());
    return m_error_message;
723
724
}

Arafat Noureddine's avatar
Arafat Noureddine committed
725
726
727
//-----------------------------------------------------
//
//-----------------------------------------------------
728
void Camera::softReset()
729
{
Arafat Noureddine's avatar
Arafat Noureddine committed
730
731
    AutoMutex aLock(m_cond.mutex());
    m_error_message.clear();
732
    m_state = Camera::STANDBY;
733
}
Arafat Noureddine's avatar
Arafat Noureddine committed
734
735
736
737

//-----------------------------------------------------
//
//-----------------------------------------------------
738
void Camera::hardReset()
739
{
Arafat Noureddine's avatar
Arafat Noureddine committed
740
741
    AutoMutex aLock(m_cond.mutex());
    send("resetcam");
742
}
Arafat Noureddine's avatar
Arafat Noureddine committed
743

744
//-----------------------------------------------------
745
// Return energy in keV
746
747
748
749
//-----------------------------------------------------
double Camera::energy() const
{
    AutoMutex aLock(m_cond.mutex());
750
751
752
753
    if(m_has_cmd_setenergy)
       return (double)m_energy/1000;
    else
       return (double)m_threshold/600;
754
755
756
}

//-----------------------------------------------------
757
// Set energy in keV
758
759
760
761
762
763
//-----------------------------------------------------
void Camera::setEnergy(double val)
{
    DEB_MEMBER_FUNCT();

    AutoMutex aLock(m_cond.mutex());
764
765
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set energy, server is not idle");
766
767
    if(m_has_cmd_setenergy)
      {
768
769
	_work_around_threshold_bug();

770
771
	m_state = Camera::SETTING_ENERGY;
	std::stringstream msg;
772
	msg << "setenergy " << val*1000;
773
774
775
	send(msg.str());
      }
    else
776
777
778
779
780
781
782
783
784
785
786
787
788
      {
        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);
      }
789
790
791

}

Arafat Noureddine's avatar
Arafat Noureddine committed
792
//-----------------------------------------------------
793
// Return the threshold in eV
Arafat Noureddine's avatar
Arafat Noureddine committed
794
//-----------------------------------------------------
795
int Camera::threshold() const
796
{
Arafat Noureddine's avatar
Arafat Noureddine committed
797
798
    AutoMutex aLock(m_cond.mutex());
    return m_threshold;
799
800
}

Arafat Noureddine's avatar
Arafat Noureddine committed
801
//-----------------------------------------------------
802
// Return the gain
Arafat Noureddine's avatar
Arafat Noureddine committed
803
//-----------------------------------------------------
804
Camera::Gain Camera::gain() const
805
{
Arafat Noureddine's avatar
Arafat Noureddine committed
806
807
    AutoMutex aLock(m_cond.mutex());
    return m_gain;
808
809
}

Arafat Noureddine's avatar
Arafat Noureddine committed
810
//-----------------------------------------------------
811
// Set Threshold (ev) and gain pair
Arafat Noureddine's avatar
Arafat Noureddine committed
812
//-----------------------------------------------------
813
void Camera::setThresholdGain(int value,Camera::Gain gain)
814
{
Arafat Noureddine's avatar
Arafat Noureddine committed
815
    DEB_MEMBER_FUNCT();
816

Arafat Noureddine's avatar
Arafat Noureddine committed
817
    AutoMutex aLock(m_cond.mutex());
818
819
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set threshold, server is not idle");
820
    m_state = Camera::SETTING_THRESHOLD;    
Arafat Noureddine's avatar
Arafat Noureddine committed
821
822
823
824
825
826
827
828
829
830
    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;
831

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

Arafat Noureddine's avatar
Arafat Noureddine committed
835
836
        send(buffer);
    }
837

838

Arafat Noureddine's avatar
Arafat Noureddine committed
839
840
    if (m_gap_fill)
        send("gapfill -1");
841
}
842
843
844
845
846
847
848
849
850
//-----------------------------------------------------
//
//-----------------------------------------------------
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
851

852
853
854
855
  AutoMutex aLock(m_cond.mutex());
  RECONNECT_WAIT_UNTIL(Camera::STANDBY,
		       "Could not set threshold,server is not idle");

856
857
  _work_around_threshold_bug();

858
859
860
861
862
863
864
865
866
867
868
869
870
871
  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
872
873
874
//-----------------------------------------------------
//
//-----------------------------------------------------
875
double Camera::exposure() const
876
{
Arafat Noureddine's avatar
Arafat Noureddine committed
877
878
    AutoMutex aLock(m_cond.mutex());
    return m_exposure;
879
880
}

Arafat Noureddine's avatar
Arafat Noureddine committed
881
882
883
//-----------------------------------------------------
//
//-----------------------------------------------------
884
void Camera::setExposure(double val)
885
{
Arafat Noureddine's avatar
Arafat Noureddine committed
886
887
888
889
    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
890
    if(m_trigger_mode == Camera::EXTERNAL_GATE and val <= 0)
Arafat Noureddine's avatar
Arafat Noureddine committed
891
        return;
892

893
894
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set exposure, server is not idle");
895
    m_state = Camera::SETTING_EXPOSURE;
Arafat Noureddine's avatar
Arafat Noureddine committed
896
897
898
    std::stringstream msg;
    msg << "exptime " << val;
    send(msg.str());
899
900
}

Arafat Noureddine's avatar
Arafat Noureddine committed
901
902
903
//-----------------------------------------------------
//
//-----------------------------------------------------
904
double Camera::exposurePeriod() const
905
{
Arafat Noureddine's avatar
Arafat Noureddine committed
906
907
    AutoMutex aLock(m_cond.mutex());
    return m_exposure_period;
908
909
}

Arafat Noureddine's avatar
Arafat Noureddine committed
910
911
912
//-----------------------------------------------------
//
//-----------------------------------------------------
913
void Camera::setExposurePeriod(double val)
914
{
Arafat Noureddine's avatar
Arafat Noureddine committed
915
916
    DEB_MEMBER_FUNCT();
    AutoMutex aLock(m_cond.mutex());
917
918
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set exposure period, server not idle");
919
    m_state = Camera::SETTING_EXPOSURE_PERIOD;
Arafat Noureddine's avatar
Arafat Noureddine committed
920
    std::stringstream msg;
921
    msg << std::setprecision(9) << "expperiod " << val;
Arafat Noureddine's avatar
Arafat Noureddine committed
922
    send(msg.str());
923
924
925
926
927
928
929
930
931
    // 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);
      }
932
933
}

Arafat Noureddine's avatar
Arafat Noureddine committed
934
935
936
//-----------------------------------------------------
//
//-----------------------------------------------------
937
int Camera::nbImagesInSequence() const
938
{
Arafat Noureddine's avatar
Arafat Noureddine committed
939
940
    AutoMutex aLock(m_cond.mutex());
    return m_nimages;
941
942
}

Arafat Noureddine's avatar
Arafat Noureddine committed
943
944
945
//-----------------------------------------------------
//
//-----------------------------------------------------
946
void Camera::setNbImagesInSequence(int nb)
947
{
Arafat Noureddine's avatar
Arafat Noureddine committed
948
949
    DEB_MEMBER_FUNCT();
    AutoMutex aLock(m_cond.mutex());
950
951
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set number image in sequence, server not idle");
952
    m_state = Camera::SETTING_NB_IMAGE_IN_SEQUENCE;
Arafat Noureddine's avatar
Arafat Noureddine committed
953
954
955
    std::stringstream msg;
    msg << "nimages " << nb;
    send(msg.str());
956
957
}

Arafat Noureddine's avatar
Arafat Noureddine committed
958
959
960
//-----------------------------------------------------
//
//-----------------------------------------------------
961
double Camera::hardwareTriggerDelay() const
962
{
Arafat Noureddine's avatar
Arafat Noureddine committed
963
964
    AutoMutex aLock(m_cond.mutex());
    return m_hardware_trigger_delay;
965
966
}

Arafat Noureddine's avatar
Arafat Noureddine committed
967
968
969
//-----------------------------------------------------
//
//-----------------------------------------------------
970
void Camera::setHardwareTriggerDelay(double value)
971
{
Arafat Noureddine's avatar
Arafat Noureddine committed
972
973
    DEB_MEMBER_FUNCT();
    AutoMutex aLock(m_cond.mutex());
974
975
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set hardware trigger delay, server not idle");
976
    m_state = Camera::SETTING_HARDWARE_TRIGGER_DELAY;
Arafat Noureddine's avatar
Arafat Noureddine committed
977
978
979
    std::stringstream msg;
    msg << "delay " << value;
    send(msg.str());
980
}
Arafat Noureddine's avatar
Arafat Noureddine committed
981
982
983
984

//-----------------------------------------------------
//
//-----------------------------------------------------
985
int Camera::nbExposurePerFrame() const
986
{
Arafat Noureddine's avatar
Arafat Noureddine committed
987
988
    AutoMutex aLock(m_cond.mutex());
    return m_exposure_per_frame;
989
990
}

Arafat Noureddine's avatar
Arafat Noureddine committed
991
992
993
//-----------------------------------------------------
//
//-----------------------------------------------------
994
void Camera::setNbExposurePerFrame(int val)
995
{
Arafat Noureddine's avatar
Arafat Noureddine committed
996
997
    DEB_MEMBER_FUNCT();
    AutoMutex aLock(m_cond.mutex());
998
999
    RECONNECT_WAIT_UNTIL(Camera::STANDBY,
			 "Could not set exposure per frame, server not idle");
1000
    m_state = Camera::SETTING_EXPOSURE_PER_FRAME;