Rev 207 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 195 | f9daq | 1 | /********************************************************************\ | 
        
| 2 | |||
| 3 |   Name:         drsread.cpp | 
        ||
| 4 |   Created by:   Rok Pestotnik | 
        ||
| 5 | |||
| 6 |   Contents:     Simple example application to read out a DRS4 | 
        ||
| 7 |                 evaluation board and save into the data file | 
        ||
| 8 |                                 Interface dll for LabWindows CVI | 
        ||
| 9 | |||
| 10 | \********************************************************************/ | 
        ||
| 11 | #ifdef DLLMAIN | 
        ||
| 12 | #define DLLEXPORT  __declspec(dllexport) | 
        ||
| 13 | #else  | 
        ||
| 14 | #define DLLEXPORT   | 
        ||
| 15 | #endif | 
        ||
| 16 | |||
| 17 | |||
| 18 | #include <stdio.h> | 
        ||
| 19 | #include <string.h> | 
        ||
| 20 | #include <stdlib.h> | 
        ||
| 21 | |||
| 22 | #include <math.h> | 
        ||
| 23 | #include <time.h> | 
        ||
| 24 | #include <signal.h> | 
        ||
| 25 | |||
| 26 | #include <TFile.h> | 
        ||
| 27 | #include <TH2F.h> | 
        ||
| 28 | #include <TCanvas.h> | 
        ||
| 29 | //#include <TApplication.h> | 
        ||
| 30 | |||
| 31 | #ifdef _MSC_VER | 
        ||
| 32 | |||
| 33 | #include "gettimeofday.h" | 
        ||
| 34 | #include "timer.h" | 
        ||
| 35 | |||
| 36 | #define DIR_SEPARATOR '\\' | 
        ||
| 37 | |||
| 38 | #elif defined(OS_LINUX) || defined(OS_DARWIN) | 
        ||
| 39 | |||
| 40 | #define O_BINARY 0 | 
        ||
| 41 | #include <unistd.h> | 
        ||
| 42 | #include <ctype.h> | 
        ||
| 43 | #include <sys/ioctl.h> | 
        ||
| 44 | #include <errno.h> | 
        ||
| 45 | #define DIR_SEPARATOR '/' | 
        ||
| 46 | #endif | 
        ||
| 47 | |||
| 48 | #include "DRS.h" | 
        ||
| 49 | #include "drsread.h" | 
        ||
| 50 | |||
| 51 | |||
| 52 | /*------------------------------------------------------------------*/ | 
        ||
| 53 | class drssettings {  | 
        ||
| 54 | static drssettings *s_instance;  | 
        ||
| 55 | public:  | 
        ||
| 56 | drssettings(){  | 
        ||
| 57 | mask = 0xF;  | 
        ||
| 58 | range = 0;  | 
        ||
| 59 | trigger_type = 1;  | 
        ||
| 60 | sampling_frequency = 5;  | 
        ||
| 61 | trigger_delay = 0;  | 
        ||
| 62 | trigger_channel=0;  | 
        ||
| 63 | trigger_polarity=false;  | 
        ||
| 64 | trigger_level=0.05;  | 
        ||
| 65 | |||
| 66 | };  | 
        ||
| 67 | ~drssettings(){};  | 
        ||
| 68 | static drssettings *instance()  | 
        ||
| 69 |     { | 
        ||
| 70 | if (!s_instance)  | 
        ||
| 71 | s_instance = new drssettings;  | 
        ||
| 72 | return s_instance;  | 
        ||
| 73 | };  | 
        ||
| 74 | |||
| 75 | |||
| 76 | unsigned char mask;  | 
        ||
| 77 | double range;  | 
        ||
| 78 | int trigger_type; // 0 software, 1 fast hardware, 2 slow hardware  | 
        ||
| 79 | int trigger_channel;  | 
        ||
| 80 | int sampling_frequency;  | 
        ||
| 81 | double trigger_delay;  | 
        ||
| 82 | double trigger_level;  | 
        ||
| 83 | bool trigger_polarity;  | 
        ||
| 84 | };  | 
        ||
| 85 | drssettings *drssettings::s_instance = 0;  | 
        ||
| 86 | drssettings *DRSParameters;  | 
        ||
| 87 | DLLEXPORT void DRSSetMask(int mask){ drssettings::instance()->mask;};  | 
        ||
| 88 | DLLEXPORT void DRSSetTriggerType(int type){ drssettings::instance()->trigger_type = type;};  | 
        ||
| 89 | DLLEXPORT void DRSSetFrequency(int freq){ drssettings::instance()->sampling_frequency = freq;};  | 
        ||
| 90 | DLLEXPORT void DRSSetRange(double range){ drssettings::instance()->range = range;};  | 
        ||
| 91 | DLLEXPORT void DRSSetTriggerChannel(int channel){ drssettings::instance()->trigger_channel = channel;};  | 
        ||
| 92 | DLLEXPORT void DRSSetTriggerDelay(double delay){ drssettings::instance()->trigger_delay = delay;};  | 
        ||
| 93 | DLLEXPORT void DRSSetTriggerLevel(double level){ drssettings::instance()->trigger_level = level;};  | 
        ||
| 94 | DLLEXPORT void DRSSetTriggerPolarity(int polarity){ drssettings::instance()->trigger_polarity = (polarity==1);};  | 
        ||
| 95 | |||
| 96 | |||
| 97 | static int DRSTimeout;  | 
        ||
| 98 | |||
| 99 | DLLEXPORT int DRSIsTimeout()  | 
        ||
| 100 | { | 
        ||
| 101 | return DRSTimeout;  | 
        ||
| 102 | } | 
        ||
| 103 | |||
| 104 | DLLEXPORT void DRSSetTimeout ( void )  | 
        ||
| 105 | { | 
        ||
| 106 | DRSTimeout=1;  | 
        ||
| 107 | printf("->>> Timer Out !!!\n");  | 
        ||
| 108 | } | 
        ||
| 109 | |||
| 110 | static DRS *drs=NULL;  | 
        ||
| 111 | |||
| 265 | f9daq | 112 | |
| 113 | DLLEXPORT int DRSCalibrateTiming( )  | 
        ||
| 114 | { | 
        ||
| 115 | DRSBoard *b;  | 
        ||
| 116 | if (drs == NULL) drs = new DRS();  | 
        ||
| 117 | if (!drs) return -1;  | 
        ||
| 118 | DRSParameters = drssettings::instance();  | 
        ||
| 119 | |||
| 120 |    //fCalMode = 2; | 
        ||
| 121 | if (drs->GetNumberOfBoards() ) {  | 
        ||
| 122 |         /* continue working with first board only */ | 
        ||
| 123 | b = drs->GetBoard(0);  | 
        ||
| 124 | |||
| 125 | if (b->GetFirmwareVersion() < 13279)  | 
        ||
| 126 | printf("Firmware revision 13279 or later\nrequired for timing calibration\n");  | 
        ||
| 127 | else if (b->GetInputRange() != 0)  | 
        ||
| 128 | printf("Timing calibration can only be done\nat the -0.5V to +0.5V input range\n");  | 
        ||
| 129 | |||
| 130 | else {  | 
        ||
| 131 | |||
| 132 | |||
| 133 |          /* remember current settings */ | 
        ||
| 134 | double acalVolt = b->GetAcalVolt();  | 
        ||
| 135 | int acalMode = b->GetAcalMode();  | 
        ||
| 136 | int tcalFreq = b->GetTcalFreq();  | 
        ||
| 137 | int tcalLevel = b->GetTcalLevel();  | 
        ||
| 138 | int tcalSource = b->GetTcalSource();  | 
        ||
| 139 | int flag1 = b->GetTriggerEnable(0);  | 
        ||
| 140 | int flag2 = b->GetTriggerEnable(1);  | 
        ||
| 141 | int trgSource = b->GetTriggerSource();  | 
        ||
| 142 | int trgDelay = b->GetTriggerDelay();  | 
        ||
| 143 | double range = b->GetInputRange();  | 
        ||
| 144 | int config = b->GetReadoutChannelConfig();  | 
        ||
| 145 | |||
| 146 | |||
| 147 | int status = b->CalibrateTiming(NULL);  | 
        ||
| 148 | |||
| 149 | if (!status)  | 
        ||
| 150 | printf("Error performing timing calibration, please check waveforms and redo voltage calibration.\n");  | 
        ||
| 151 |          else | 
        ||
| 152 | printf("Timing calibration successfully finished.\n");  | 
        ||
| 153 | |||
| 154 | |||
| 155 |          /* restore old values */ | 
        ||
| 156 | b->EnableAcal(acalMode, acalVolt);  | 
        ||
| 157 | b->EnableTcal(tcalFreq, tcalLevel);  | 
        ||
| 158 | b->SelectClockSource(tcalSource);  | 
        ||
| 159 | b->EnableTrigger(flag1, flag2);  | 
        ||
| 160 | b->SetTriggerSource(trgSource);  | 
        ||
| 161 | b->SetTriggerDelayPercent(trgDelay);  | 
        ||
| 162 | b->SetInputRange(range);  | 
        ||
| 163 | b->SetChannelConfig(config, 8, 8);  | 
        ||
| 164 | |||
| 165 | if (b->GetBoardType() == 5)  | 
        ||
| 166 | b->SetTranspMode(1); // Evaluation board with build-in trigger  | 
        ||
| 167 |          else | 
        ||
| 168 | b->SetTranspMode(1); // VPC Mezzanine board  | 
        ||
| 169 | |||
| 170 | return status;  | 
        ||
| 171 |       } | 
        ||
| 172 | |||
| 173 |    } | 
        ||
| 174 | return -1;  | 
        ||
| 175 | } | 
        ||
| 176 | |||
| 177 | |||
| 195 | f9daq | 178 | DLLEXPORT int DRSInit()  | 
        
| 179 | { | 
        ||
| 180 | |||
| 181 | DRSBoard *b;  | 
        ||
| 182 |    /* do drsinitial scan */ | 
        ||
| 265 | f9daq | 183 | if (drs == NULL) drs = new DRS();  | 
        
| 195 | f9daq | 184 | if (!drs) return -1;  | 
        
| 185 | DRSParameters = drssettings::instance();  | 
        ||
| 186 | |||
| 187 |    /* show any found board(s) */ | 
        ||
| 188 | for (int i=0 ; i<drs->GetNumberOfBoards() ; i++) {  | 
        ||
| 189 | b = drs->GetBoard(i);  | 
        ||
| 190 | printf("Found DRS4 evaluation board, serial #%d, firmware revision %d\n",  | 
        ||
| 191 | b->GetBoardSerialNumber(), b->GetFirmwareVersion());  | 
        ||
| 192 |    } | 
        ||
| 193 | |||
| 194 |    /* exit if no board found */ | 
        ||
| 195 | int nBoards = drs->GetNumberOfBoards();  | 
        ||
| 196 | if (nBoards == 0) {  | 
        ||
| 197 | printf("No DRS4 evaluation board found\n");  | 
        ||
| 198 | return -2;  | 
        ||
| 199 |    } | 
        ||
| 200 | |||
| 201 |    /* continue working with first board only */ | 
        ||
| 202 | b = drs->GetBoard(0);  | 
        ||
| 203 | |||
| 204 |    /* drsinitialize board */ | 
        ||
| 205 | b->Init();  | 
        ||
| 206 | |||
| 207 |    /* set sampling frequency default 5 */ | 
        ||
| 208 | b->SetFrequency(DRSParameters->sampling_frequency, true);  | 
        ||
| 209 | |||
| 210 |    /* enable transparent mode needed for analog trigger */ | 
        ||
| 211 | b->SetTranspMode(1);  | 
        ||
| 212 | |||
| 213 |    /* set input range to -0.5V ... +0.5V -> range=0 */ | 
        ||
| 214 | b->SetInputRange(DRSParameters->range);  | 
        ||
| 215 | |||
| 216 |    /* use following line to set range to 0..1V */ | 
        ||
| 217 |    //b->SetInputRange(0.5); | 
        ||
| 218 | |||
| 219 |    /* use following line to turn on the internal 100 MHz clock connected to all channels  */ | 
        ||
| 220 |    //b->EnableTcal(1); | 
        ||
| 221 | |||
| 222 |    /* kaj je to .... | 
        ||
| 223 |     // Set domino mode | 
        ||
| 224 |    // mode == 0: single sweep | 
        ||
| 225 |    // mode == 1: run continously -- default | 
        ||
| 226 |    b->SetDominoMode(1); | 
        ||
| 227 |     // Set domino activity | 
        ||
| 228 |    // mode == 0: stop during readout   | 
        ||
| 229 |    // mode == 1: keep domino wave running -- default | 
        ||
| 230 |    //   | 
        ||
| 231 |    b->SetDominoActive(1); | 
        ||
| 232 | |||
| 233 |    // Set readout mode | 
        ||
| 234 |    // mode == 0: start from first bin  -- default | 
        ||
| 235 |    // mode == 1: start from domino stop | 
        ||
| 236 |    // | 
        ||
| 237 |    b->SetReadoutMode(1); | 
        ||
| 238 |    */ | 
        ||
| 239 | |||
| 240 |    /* use following lines to enable hardware trigger on CH1 at 50 mV positive edge */ | 
        ||
| 241 | printf("Board Type:%d\n",b->GetBoardType() );  | 
        ||
| 242 | if (b->GetBoardType() >= 8) { // Evaluaiton Board V4&5  | 
        ||
| 243 | |||
| 244 | b->EnableTrigger(DRSParameters->trigger_type, 0); // enable hardware trigger - 1 fast trigger, 2 slow trigger, 0 disable hw trigger  | 
        ||
| 245 | b->SetTriggerSource(1<<DRSParameters->trigger_channel); // set CH1 as source // simple or of single channel  | 
        ||
| 246 | } else if (b->GetBoardType() == 7) { // Evaluation Board V3  | 
        ||
| 247 | b->EnableTrigger(0, 1); // lemo off, analog trigger on  | 
        ||
| 248 | b->SetTriggerSource(0); // use CH1 as source  | 
        ||
| 249 |    } | 
        ||
| 250 | b->SetTriggerLevel(DRSParameters->trigger_level); // 0.05 V  | 
        ||
| 251 | b->SetTriggerPolarity(DRSParameters->trigger_polarity); // positive edge  | 
        ||
| 252 | |||
| 253 |    /* use following lines to set individual trigger elvels */ | 
        ||
| 254 |    //b->SetIndividualTriggerLevel(1, 0.1); | 
        ||
| 255 |    //b->SetIndividualTriggerLevel(2, 0.2); | 
        ||
| 256 |    //b->SetIndividualTriggerLevel(3, 0.3); | 
        ||
| 257 |    //b->SetIndividualTriggerLevel(4, 0.4); | 
        ||
| 258 |    //b->SetTriggerSource(15); | 
        ||
| 259 | |||
| 260 | b->SetTriggerDelayNs( DRSParameters->trigger_delay); // zero ns trigger delay  | 
        ||
| 261 | |||
| 262 |    /* use following lines to enable the external trigger */ | 
        ||
| 263 |    //if (b->GetBoardType() == 8) {     // Evaluaiton Board V4 | 
        ||
| 264 |    //   b->EnableTrigger(1, 0);           // enable hardware trigger | 
        ||
| 265 |    //   b->SetTriggerSource(1<<4);        // set external trigger as source | 
        ||
| 266 |    //} else {                          // Evaluation Board V3 | 
        ||
| 267 |    //   b->EnableTrigger(1, 0);           // lemo on, analog trigger off | 
        ||
| 268 |    // } | 
        ||
| 269 | |||
| 270 | return 0;  | 
        ||
| 271 | |||
| 272 | |||
| 273 | } | 
        ||
| 274 | |||
| 275 | static float DRSTimeArray[8][1024];  | 
        ||
| 276 | static float DRSWaveArray[8][1024];  | 
        ||
| 277 | |||
| 278 | DLLEXPORT float * DRSGetTime(int ch){ return DRSTimeArray[ch];}  | 
        ||
| 279 | DLLEXPORT float * DRSGetWave(int ch){ return DRSWaveArray[ch];}  | 
        ||
| 280 | |||
| 281 | DLLEXPORT int DRSRead( int DRStimer)  | 
        ||
| 282 | { | 
        ||
| 283 | |||
| 284 | DRSBoard *b = drs->GetBoard(0);  | 
        ||
| 285 | |||
| 286 | |||
| 287 | |||
| 288 |       /* wait for trigger */ | 
        ||
| 289 | |||
| 290 | |||
| 291 | int tout=1000; /* timeout in mili seconds */  | 
        ||
| 292 | DRSTimeout=0;  | 
        ||
| 293 | |||
| 294 | if (DRStimer) start_timer(tout, &DRSSetTimeout);  | 
        ||
| 295 | |||
| 296 |           /* start board (activate domino wave) */ | 
        ||
| 297 | b->StartDomino();  | 
        ||
| 298 | |||
| 299 | if (!DRSParameters->trigger_type) b->SoftTrigger();  | 
        ||
| 300 | |||
| 301 | while (b->IsBusy()){  | 
        ||
| 302 | |||
| 303 | if (DRSTimeout) {  | 
        ||
| 304 | printf("Waiting for Trigger.. at line %d\n", __LINE__);  | 
        ||
| 305 | |||
| 306 | if (DRStimer) stop_timer();  | 
        ||
| 307 | |||
| 308 | return -1;  | 
        ||
| 309 |         } | 
        ||
| 310 | };  | 
        ||
| 311 | |||
| 312 | |||
| 313 | if (DRStimer) stop_timer();  | 
        ||
| 314 | |||
| 315 | |||
| 316 | |||
| 317 |       /* read all waveforms */ | 
        ||
| 318 | b->TransferWaves(0, 8);  | 
        ||
| 319 | |||
| 320 | |||
| 321 | for (int k=0;k<4;k++){  | 
        ||
| 322 | if (! (DRSParameters->mask & ( 0x1<<k )) ) continue;  | 
        ||
| 323 |       /* Note: On the evaluation board input #1 is connected to channel 0 and 1 of | 
        ||
| 324 |        the DRS chip, input #2 is connected to channel 2 and 3 and so on. So to | 
        ||
| 325 |        get the input #2 we have to read DRS channel #2, not #1. */ | 
        ||
| 326 | |||
| 327 |       /* read time (X) array of k-th channel in ns and waveform (Y) array of k-th channel in mV */ | 
        ||
| 328 | b->GetTime(0, 2*k, b->GetTriggerCell(DRSParameters->trigger_channel), DRSTimeArray[k]);  | 
        ||
| 329 | b->GetWave(0, 2*k, DRSWaveArray[k]);  | 
        ||
| 330 | |||
| 331 | |||
| 332 |       } | 
        ||
| 333 | |||
| 334 | return 0;  | 
        ||
| 335 | } | 
        ||
| 336 | |||
| 337 | DLLEXPORT int DRSEnd(){  | 
        ||
| 338 | |||
| 339 |    /* delete DRS object -> close USB connection */ | 
        ||
| 340 | if (drs) delete drs;  | 
        ||
| 341 | drs = NULL;  | 
        ||
| 342 | return 0;  | 
        ||
| 343 | } | 
        ||
| 344 | |||
| 345 | |||
| 346 | |||
| 347 | DLLEXPORT int DRSToBuffer( unsigned char *p, int m_evSerial )  | 
        ||
| 348 | { | 
        ||
| 349 | |||
| 350 | unsigned short d;  | 
        ||
| 351 | float t;  | 
        ||
| 352 | unsigned char *p0 = p;  | 
        ||
| 353 | |||
| 354 | int m_nBoards = drs->GetNumberOfBoards();  | 
        ||
| 355 | int m_waveDepth = 1024 ;// 2048  | 
        ||
| 356 | int m_inputRange = drs->GetBoard(0)->GetInputRange();  | 
        ||
| 357 | time_t rawtime;  | 
        ||
| 358 | time ( &rawtime );  | 
        ||
| 359 | struct tm m_evTimestamp;  | 
        ||
| 360 | m_evTimestamp = *(localtime ( &rawtime ));  | 
        ||
| 361 | struct timeval mtime;  | 
        ||
| 362 | gettimeofday(&mtime, NULL);  | 
        ||
| 363 | |||
| 364 | if (m_evSerial == 0) {  | 
        ||
| 207 | f9daq | 365 | memcpy(p, "DRS2", 4); // File identifier and version  | 
        
| 366 | p += 4;  | 
        ||
| 195 | f9daq | 367 |          // time calibration header | 
        
| 207 | f9daq | 368 | memcpy(p, "TIME", 4);  | 
        
| 195 | f9daq | 369 | p += 4;  | 
        
| 370 | for (int b=0 ; b<m_nBoards ; b++) {  | 
        ||
| 371 |             // store board serial number | 
        ||
| 372 | sprintf((char *)p, "B#");  | 
        ||
| 373 | p += 2;  | 
        ||
| 374 | *(unsigned short *)p = drs->GetBoard(b)->GetBoardSerialNumber();  | 
        ||
| 375 | p += sizeof(unsigned short);  | 
        ||
| 376 | |||
| 377 | for (int i=0 ; i<4 ; i++) {  | 
        ||
| 378 | if (DRSParameters->mask & (0x1<<i)) {  | 
        ||
| 379 | sprintf((char *)p, "C%03d", i+1);  | 
        ||
| 380 | p += 4;  | 
        ||
| 381 | float tcal[2048];  | 
        ||
| 382 | drs->GetBoard(b)->GetTimeCalibration(0, i*2, 0, tcal, 0);  | 
        ||
| 383 | for (int j=0 ; j<m_waveDepth ; j++) {  | 
        ||
| 384 |                      // save binary time as 32-bit float value | 
        ||
| 385 | if (m_waveDepth == 2048) {  | 
        ||
| 386 | t = (tcal[j]+tcal[j+1])/2;  | 
        ||
| 387 | j++;  | 
        ||
| 388 | } else  | 
        ||
| 389 | t = tcal[j];  | 
        ||
| 390 | *(float *)p = t;  | 
        ||
| 391 | p += sizeof(float);  | 
        ||
| 392 |                   } | 
        ||
| 393 |                } | 
        ||
| 394 |             } | 
        ||
| 395 |          } | 
        ||
| 396 |       } | 
        ||
| 397 | |||
| 398 | |||
| 399 | |||
| 400 | memcpy(p, "EHDR", 4);  | 
        ||
| 401 | p += 4;  | 
        ||
| 402 | *(int *)p = m_evSerial;  | 
        ||
| 403 | p += sizeof(int);  | 
        ||
| 404 | *(unsigned short *)p = m_evTimestamp.tm_year;  | 
        ||
| 405 | p += sizeof(unsigned short);  | 
        ||
| 406 | *(unsigned short *)p = m_evTimestamp.tm_mon;  | 
        ||
| 407 | p += sizeof(unsigned short);  | 
        ||
| 408 | *(unsigned short *)p = m_evTimestamp.tm_mday;  | 
        ||
| 409 | p += sizeof(unsigned short);  | 
        ||
| 410 | *(unsigned short *)p = m_evTimestamp.tm_hour;  | 
        ||
| 411 | p += sizeof(unsigned short);  | 
        ||
| 412 | *(unsigned short *)p = m_evTimestamp.tm_min;  | 
        ||
| 413 | p += sizeof(unsigned short);  | 
        ||
| 414 | *(unsigned short *)p = m_evTimestamp.tm_sec;  | 
        ||
| 415 | p += sizeof(unsigned short);  | 
        ||
| 416 | *(unsigned short *)p = mtime.tv_usec/1000;  | 
        ||
| 417 | p += sizeof(unsigned short);  | 
        ||
| 418 | *(unsigned short *)p = (unsigned short)(m_inputRange * 1000); // range  | 
        ||
| 419 | p += sizeof(unsigned short);  | 
        ||
| 420 | |||
| 421 | int b=0; // only for board 0  | 
        ||
| 422 | |||
| 423 |          // store board serial number | 
        ||
| 424 | sprintf((char *)p, "B#");  | 
        ||
| 425 | p += 2;  | 
        ||
| 426 | *(unsigned short *)p = drs->GetBoard(b)->GetBoardSerialNumber();  | 
        ||
| 427 | p += sizeof(unsigned short);  | 
        ||
| 428 | |||
| 429 |          // store trigger cell | 
        ||
| 430 | sprintf((char *)p, "T#");  | 
        ||
| 431 | p += 2;  | 
        ||
| 432 | *(unsigned short *)p = drs->GetBoard(b)->GetTriggerCell(DRSParameters->trigger_channel);  | 
        ||
| 433 | p += sizeof(unsigned short);  | 
        ||
| 434 | |||
| 435 | for (int i=0 ; i<4 ; i++) {  | 
        ||
| 436 | if (DRSParameters->mask & (0x1<<i)) {  | 
        ||
| 437 | sprintf((char *)p, "C%03d", i+1);  | 
        ||
| 438 | p += 4;  | 
        ||
| 207 | f9daq | 439 | unsigned int s = drs->GetBoard(b)->GetScaler(i);  | 
        
| 440 | memcpy(p, &s, sizeof(int));  | 
        ||
| 441 | p += sizeof(int);  | 
        ||
| 195 | f9daq | 442 | for (int j=0 ; j<m_waveDepth ; j++) {  | 
        
| 443 |                   // save binary date as 16-bit value: | 
        ||
| 444 |                   // 0 = -0.5V,  65535 = +0.5V    for range 0 | 
        ||
| 445 |                   // 0 = -0.05V, 65535 = +0.95V   for range 0.45 | 
        ||
| 446 | if (m_waveDepth == 2048) {  | 
        ||
| 447 |                      // in cascaded mode, save 1024 values as averages of the 2048 values | 
        ||
| 448 | d = (unsigned short)(((DRSWaveArray[i][j]+DRSWaveArray[i][j+1])/2000.0 - m_inputRange + 0.5) * 65535);  | 
        ||
| 449 | *(unsigned short *)p = d;  | 
        ||
| 450 | p += sizeof(unsigned short);  | 
        ||
| 451 | j++;  | 
        ||
| 452 | } else {  | 
        ||
| 453 | d = (unsigned short)((DRSWaveArray[i][j]/1000.0 - m_inputRange + 0.5) * 65535);  | 
        ||
| 454 | *(unsigned short *)p = d;  | 
        ||
| 455 | p += sizeof(unsigned short);  | 
        ||
| 456 |                   } | 
        ||
| 457 |                } | 
        ||
| 458 |             } | 
        ||
| 459 |          } | 
        ||
| 460 | |||
| 461 | return (p-p0); // return number of bytes  | 
        ||
| 462 | } | 
        ||
| 463 | |||
| 464 | |||
| 465 | |||
| 466 | #ifdef MAIN | 
        ||
| 467 | |||
| 468 | |||
| 469 | |||
| 470 | #include "XGetopt.h" | 
        ||
| 471 | #include "getopt.h" | 
        ||
| 472 | |||
| 473 | TH2F *h[4];  | 
        ||
| 474 | |||
| 475 | typedef struct {  | 
        ||
| 476 | char recid[4];  | 
        ||
| 477 | unsigned int posx, posy, posz;  | 
        ||
| 478 | unsigned int iposx, iposy, iposz;  | 
        ||
| 479 | } POSREC;  | 
        ||
| 480 | |||
| 481 | |||
| 482 | int help() {  | 
        ||
| 483 | printf ("*********************************************************************************:\n");  | 
        ||
| 484 | printf ("Usage: Read of the DRS4 PSI board and dump of the waveforms in the file:\n\n");  | 
        ||
| 485 | printf ("Arguments: \n");  | 
        ||
| 486 | printf ("-v verbosity \n");  | 
        ||
| 487 | printf ("-a output rootfile \n");  | 
        ||
| 488 | printf ("-o output filename \n");  | 
        ||
| 203 | f9daq | 489 | printf ("-r range \n");  | 
        
| 195 | f9daq | 490 | printf ("-n number of events\n");  | 
        
| 491 | printf ("-m channel bit mask\n");  | 
        ||
| 492 | printf ("-h trigger type (0 software, 1 fast hardware, 2 slow hardware)\n");  | 
        ||
| 493 | printf ("-d trigger delay in ns\n");  | 
        ||
| 494 | printf ("-f sampling frequency\n");  | 
        ||
| 495 | printf ("-t trigger channel\n");  | 
        ||
| 496 | printf ("-l trigger level\n");  | 
        ||
| 497 | printf ("-p trigger polarity (0 positive\n");  | 
        ||
| 498 | printf ("*********************************************************************************:\n");  | 
        ||
| 499 | printf ("Examples:\n\n");  | 
        ||
| 500 | |||
| 501 | return 0;  | 
        ||
| 502 | } | 
        ||
| 503 | |||
| 504 | |||
| 505 | |||
| 506 | char filename[0xFF]="";  | 
        ||
| 507 | char rootfile[0xFF]="";  | 
        ||
| 508 | int neve = 0;  | 
        ||
| 509 | int verbose = 0;  | 
        ||
| 510 | |||
| 511 | void Init(int argc, char **argv){  | 
        ||
| 512 | DRSParameters = drssettings::instance();  | 
        ||
| 513 | char c;  | 
        ||
| 514 | |||
| 515 | extern char *optarg;  | 
        ||
| 516 | extern int optind;  | 
        ||
| 517 | extern int optopt;  | 
        ||
| 518 | while ((c = getopt (argc, argv, "a:o:v:m:n:f:d:r:h:t:p:l:")) != -1){  | 
        ||
| 519 | |||
| 520 | switch (c)  | 
        ||
| 521 |         { | 
        ||
| 522 | |||
| 523 | case 'a':  | 
        ||
| 524 | sprintf(rootfile,"%s", optarg );  | 
        ||
| 525 | break; // root output  | 
        ||
| 526 | |||
| 527 | case 'o':  | 
        ||
| 528 | sprintf(filename,"%s", optarg );  | 
        ||
| 529 | break; // output  | 
        ||
| 530 | |||
| 531 | case 'v':  | 
        ||
| 532 | verbose = atoi(optarg);  | 
        ||
| 533 | break; // verbosity  | 
        ||
| 534 | case 'm':{  | 
        ||
| 535 | unsigned long ul = strtoul (optarg,NULL,0);  | 
        ||
| 536 | DRSSetMask( (unsigned char)( ul & 0xF ) ) ;  | 
        ||
| 537 | break;  | 
        ||
| 538 | } // channel mask  | 
        ||
| 539 | case 'n':  | 
        ||
| 540 | neve = atoi (optarg);  | 
        ||
| 541 | break; // number of events or number of scan points  | 
        ||
| 542 | |||
| 543 | case 'f':  | 
        ||
| 544 | DRSSetFrequency( atoi (optarg) );  | 
        ||
| 545 | break; // sampling frequency  | 
        ||
| 546 | |||
| 547 | case 'd':  | 
        ||
| 548 | DRSSetTriggerDelay( atof (optarg) );  | 
        ||
| 549 | break; // trigger delay  | 
        ||
| 550 | case 'p':  | 
        ||
| 551 | DRSSetTriggerPolarity( atoi (optarg));  | 
        ||
| 552 | break; // trigger polarity  | 
        ||
| 553 | case 'l':  | 
        ||
| 554 | DRSSetTriggerLevel(atoi (optarg));  | 
        ||
| 555 | break; // trigger level  | 
        ||
| 556 | |||
| 557 | |||
| 558 | case 'r':  | 
        ||
| 559 | DRSSetRange ( atof (optarg) );  | 
        ||
| 560 | break; // range  | 
        ||
| 561 | case 'h':  | 
        ||
| 562 | DRSSetTriggerType( atoi (optarg) );  | 
        ||
| 563 | break; // send sotware trigger before reading out the dat  | 
        ||
| 564 | case 't':  | 
        ||
| 565 | DRSSetTriggerChannel( atoi(optarg) );  | 
        ||
| 566 | break; // trigger channel  | 
        ||
| 567 | |||
| 568 | |||
| 569 | case '?':  | 
        ||
| 570 | if (optopt == 'c')  | 
        ||
| 571 | fprintf (stderr, "Option -%c requires an argument.\n", optopt);  | 
        ||
| 572 | else if (isprint (optopt))  | 
        ||
| 573 | fprintf (stderr, "Unknown option `-%c'.\n", optopt);  | 
        ||
| 574 |             else | 
        ||
| 575 | fprintf (stderr,  | 
        ||
| 576 |                          "Unknown option character `\\x%x'.\n", | 
        ||
| 577 | optopt);  | 
        ||
| 578 | abort ();  | 
        ||
| 579 | default:  | 
        ||
| 580 | abort ();  | 
        ||
| 581 |         } | 
        ||
| 582 |     } | 
        ||
| 583 |     //for (int i=optind; i<argc; i++) data = strtoul (argv[i],NULL,0); | 
        ||
| 584 | |||
| 585 | } | 
        ||
| 586 | |||
| 587 | int ctrl_c=0;  | 
        ||
| 588 | DLLEXPORT void DRSSigInt ( int )  | 
        ||
| 589 | { | 
        ||
| 590 | ctrl_c = 1;  | 
        ||
| 591 | printf("->>> CTRL+c !!!\n");  | 
        ||
| 592 | } | 
        ||
| 593 | |||
| 594 | //#ifdef __CINT__ | 
        ||
| 595 | int main(int argc, char **argv){  | 
        ||
| 596 | //#else | 
        ||
| 597 | //int drsread(int argc, char **argv){    | 
        ||
| 598 | //#endif | 
        ||
| 599 | |||
| 600 | if (signal (SIGINT, DRSSigInt) == SIG_ERR) {  | 
        ||
| 601 | perror ("sigignore");  | 
        ||
| 602 |  } | 
        ||
| 603 | |||
| 604 | |||
| 605 | Init(argc, argv);  | 
        ||
| 606 | if (argc==1) { help(); return 0; }  | 
        ||
| 607 | |||
| 608 | FILE *fp=NULL;  | 
        ||
| 609 | if (strlen(filename)>0) {  | 
        ||
| 610 | if (verbose) printf("Data in the file:%s\n", filename);  | 
        ||
| 611 | fp=fopen(filename,"wb");  | 
        ||
| 612 | } | 
        ||
| 613 | |||
| 614 | TFile *rfile= NULL;  | 
        ||
| 615 | if (strlen(rootfile)>0) {  | 
        ||
| 616 | if (verbose) printf("Data in the file:%s\n", rootfile);  | 
        ||
| 617 | rfile = new TFile(rootfile,"RECREATE");  | 
        ||
| 618 | } | 
        ||
| 619 | |||
| 620 | |||
| 621 | TCanvas *c = new TCanvas(); c->Divide(2,2);  | 
        ||
| 622 | c->Draw();  | 
        ||
| 623 | for (int i=0;i<4;i++){  | 
        ||
| 624 | if (! (DRSParameters->mask & ( 0x1<<i )) ) continue;  | 
        ||
| 625 | char name[0xff];  | 
        ||
| 626 | sprintf(name,"h%d",i);  | 
        ||
| 627 | h[i]=new TH2F(name,name,1024,0,204,1024,-0.6+DRSParameters->range,0.6+DRSParameters->range);  | 
        ||
| 628 | c->cd(i+1); h[i]->Draw("colz");  | 
        ||
| 629 | |||
| 630 | } | 
        ||
| 631 | |||
| 632 | |||
| 633 | |||
| 634 | //--------------------------------------- | 
        ||
| 635 | static unsigned char *buffer;  | 
        ||
| 636 | static int buffer_size = 0;  | 
        ||
| 637 | const int nBoards=1;  | 
        ||
| 638 | const int waveDepth=1024;  | 
        ||
| 639 | if (buffer_size == 0) {  | 
        ||
| 640 | buffer_size = 4 + nBoards * (4 + 4*(4+waveDepth*4));  | 
        ||
| 641 | buffer_size += 24 + nBoards * (8 + 4*(4+waveDepth*2));  | 
        ||
| 642 | buffer = (unsigned char *)malloc(buffer_size);  | 
        ||
| 643 | } | 
        ||
| 644 | |||
| 645 | time_t t,told, tstart;  | 
        ||
| 646 | if (!DRSInit()){  | 
        ||
| 647 | time(&tstart);  | 
        ||
| 648 | told=tstart;  | 
        ||
| 649 | int i=0;  | 
        ||
| 650 | for (i=0; i<neve; i++) {  | 
        ||
| 651 | int nb = (DRSRead(1) == 0 && fp ) ? DRSToBuffer( buffer , i ) : 0;  | 
        ||
| 652 | |||
| 653 | if (DRSTimeout) i--;  | 
        ||
| 654 | if (ctrl_c) break;  | 
        ||
| 655 | time(&t);  | 
        ||
| 656 | if (t!=told ) {  | 
        ||
| 657 | printf("%d events in %2.2f min (%d s) %s",i+1, (double)(t-tstart)/60.,int(t-tstart), ctime(&t));  | 
        ||
| 658 | c->Modified(); c->Update();  | 
        ||
| 659 |         }       | 
        ||
| 660 | told=t;  | 
        ||
| 661 | // Save data     | 
        ||
| 662 | if (nb>0 && fp) fwrite(buffer, 1,nb ,fp);  | 
        ||
| 663 | // Plot Data | 
        ||
| 664 | for (int k=0;k<4;k++){  | 
        ||
| 665 | if (! (DRSParameters->mask & ( 0x1<<k )) ) continue;  | 
        ||
| 666 | float *t=DRSGetTime(k);  | 
        ||
| 667 | float *x=DRSGetWave(k);  | 
        ||
| 668 | for (int i=0 ; i<1024 ; i++) {  | 
        ||
| 669 | if (verbose) printf("[%d] %d. x= %3.2f y=%3.2f\n", k, i, t[i], x[i] );  | 
        ||
| 670 | h[k]->Fill( t[i], x[i]*1e-3);  | 
        ||
| 671 |         } | 
        ||
| 672 |         } | 
        ||
| 673 |   } | 
        ||
| 674 | time(&t);  | 
        ||
| 675 | printf("%d events in %2.2f min (%d s) %s",i+1, (double)(t-tstart)/60.,int(t-tstart), ctime(&t));  | 
        ||
| 676 | |||
| 677 | DRSEnd();  | 
        ||
| 678 | } | 
        ||
| 679 | //--------------------------------------- | 
        ||
| 680 | if (rfile !=NULL) rfile->Write();  | 
        ||
| 681 | if (fp) fclose(fp);  | 
        ||
| 682 | if (c) c->SaveAs("drsread.pdf");  | 
        ||
| 683 | // TApplication* theApp = new TApplication("App", NULL, NULL); | 
        ||
| 684 | // theApp->Run(); | 
        ||
| 685 | |||
| 686 | |||
| 687 | |||
| 688 | } | 
        ||
| 689 | |||
| 207 | f9daq | 690 | #endif |