source: trunk/FACT++/gui/RawEventsViewer/RawEventsViewer.cc @ 19368

Last change on this file since 19368 was 19368, checked in by tbretz, 5 months ago
Allow to switch to fake calibration...
File size: 77.4 KB
Line 
1/*
2 * QtGl.cpp
3 *
4 *  Created on: Jul 19, 2011
5 *      Author: lyard
6 *
7 ******
8 */
9#include <math.h>
10#include <fstream>
11
12#include <boost/date_time/local_time/local_time.hpp>
13
14#include "RawEventsViewer.h"
15
16#include <QFileDialog>
17#include <QMouseEvent>
18
19#include <qwt_symbol.h>
20#include <qwt_plot_grid.h>
21#pragma GCC diagnostic push
22#pragma GCC diagnostic ignored "-Woverloaded-virtual"
23#include <qwt_plot_zoomer.h>
24#pragma GCC diagnostic pop
25
26#include "src/Configuration.h"
27#include "externals/factfits.h"
28
29
30using namespace std;
31
32#undef ACTUAL_NUM_PIXELS
33#define ACTUAL_NUM_PIXELS 1440
34
35//bounding box for diplaying the impulse curve
36float bboxMin[2] = {-0.8,-0.9};
37float bboxMax[2] = {0.8,-0.3};
38/************************************************************
39 * CALC BLUR COLOR if in blur display mode, calculate the interpolated
40 * colour for a given vertex
41 ************************************************************/
42void RawDataViewer::calcBlurColor(int pixel,  int vertex)
43{
44    GLfloat color[3];
45    int first, second;
46    first = vertex-1;
47    second = vertex;
48    if (first < 0)
49        first = 5;
50
51    first = neighbors[pixel][first];
52    second = neighbors[pixel][second];
53//    cout << pixel << " " << vertex << " " << "first: " << first << " second: " << second << endl;
54    for (int i=0;i<3;i++)
55        color[i] = pixelsColor[pixel][i];
56    float divide = 1;
57    if (first != -1)
58    {
59        divide++;
60        for (int i=0;i<3;i++)
61            color[i] += pixelsColor[first][i];
62    }
63    if (second != -1)
64    {
65        divide++;
66        for (int i=0;i<3;i++)
67            color[i] += pixelsColor[second][i];
68    }
69    for (int i=0;i<3;i++)
70        color[i] /= divide;
71
72//    cout << color[0] << " " << color[1] << " " << color[2] << endl;
73
74    glColor3fv(color);
75}
76void RawDataViewer::calcMidBlurColor(int pixel, int vertex)
77{
78    GLfloat color[3];
79    int first;
80    first = vertex-1;
81    if (first < 0)
82        first = 5;
83    first = neighbors[pixel][first];
84    for (int i=0;i<3;i++)
85        color[i] = pixelsColor[pixel][i];
86    float divide = 1;
87    if (first != -1)
88    {
89        divide++;
90        for (int i=0;i<3;i++)
91            color[i] += pixelsColor[first][i];
92    }
93    for (int i=0;i<3;i++)
94        color[i] /= divide;
95    glColor3fv(color);
96}
97/************************************************************
98 * DRAW BLURRY HEXAGON. draws a solid hexagon, with interpolated colours
99 ************************************************************/
100void RawDataViewer::drawBlurryHexagon(int index)
101{
102
103//per-pixel mesh
104    GLfloat color[3];
105    for (int i=0;i<3;i++)
106        color[i] = pixelsColor[index][i];
107    glBegin(GL_TRIANGLES);
108    calcBlurColor(index, 0);
109    glVertex2fv(verticesList[verticesIndices[index][0]]);
110    glColor3fv(color);
111    glVertex2fv(pixelsCoords[index]);
112
113    calcBlurColor(index, 1);
114    glVertex2fv(verticesList[verticesIndices[index][1]]);
115
116    glVertex2fv(verticesList[verticesIndices[index][1]]);
117    glColor3fv(color);
118    glVertex2fv(pixelsCoords[index]);
119
120    calcBlurColor(index, 2);
121    glVertex2fv(verticesList[verticesIndices[index][2]]);
122
123    glVertex2fv(verticesList[verticesIndices[index][2]]);
124    glColor3fv(color);
125    glVertex2fv(pixelsCoords[index]);
126
127    calcBlurColor(index, 3);
128    glVertex2fv(verticesList[verticesIndices[index][3]]);
129
130    glVertex2fv(verticesList[verticesIndices[index][3]]);
131    glColor3fv(color);
132    glVertex2fv(pixelsCoords[index]);
133
134    calcBlurColor(index, 4);
135    glVertex2fv(verticesList[verticesIndices[index][4]]);
136
137    glVertex2fv(verticesList[verticesIndices[index][4]]);
138    glColor3fv(color);
139    glVertex2fv(pixelsCoords[index]);
140
141    calcBlurColor(index, 5);
142    glVertex2fv(verticesList[verticesIndices[index][5]]);
143
144    glVertex2fv(verticesList[verticesIndices[index][5]]);
145    glColor3fv(color);
146    glVertex2fv(pixelsCoords[index]);
147
148    calcBlurColor(index, 0);
149    glVertex2fv(verticesList[verticesIndices[index][0]]);
150    glEnd();
151
152    return;
153}
154
155/************************************************************
156 * DRAW CAMERA draws all the camera pixels
157 ************************************************************/
158void RawDataViewer::drawCamera(bool alsoWire)
159{
160    glLoadIdentity();
161    if (!drawImpulse)
162    {
163        glTranslatef(0,-0.44,0);
164        glRotatef(cameraRotation, 0,0,-1);
165        if (cameraRotation == 90)
166        {
167            glTranslatef(-0.45,-0.45,0);
168        }
169        if (cameraRotation == -90)
170        {
171            glTranslatef(0.45,-0.45,0);
172        }
173        glScalef(1.5,1.5,1);
174    }
175    else
176    {
177        glRotatef(cameraRotation, 0,0,-1);
178          if (cameraRotation == 90)
179        {
180            glTranslatef(-0.45/1.5,-0.45/1.5,0);
181        }
182        if (cameraRotation == -90)
183        {
184            glTranslatef(0.45/1.5,-0.45/1.5,0);
185        }
186  }
187    glColor3f(0.5,0.5,0.5);
188    glLineWidth(1.0);
189    float color;
190
191    for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
192    {
193        if (!nRoi)
194          color = (float)(i)/(float)(ACTUAL_NUM_PIXELS);
195        else
196
197//        if (_softwareOrdering)
198//            color = float(eventData[nRoi*i + whichSlice] + (VALUES_SPAN/2))/(float)(VALUES_SPAN-1);
199//        else
200            color = float(eventData[nRoi*hardwareMapping[i] + whichSlice]+(VALUES_SPAN/2))/(float)(VALUES_SPAN-1);
201        if (logScale)
202        {
203            color *= 9;
204            color += 1;
205            color = log10(color);
206        }
207
208        if (color < ss[0])
209        {
210            pixelsColor[i][0] = tooLowValueCoulour[0];
211            pixelsColor[i][1] = tooLowValueCoulour[1];
212            pixelsColor[i][2] = tooLowValueCoulour[2];
213            continue;
214        }
215        if (color > ss[4])
216        {
217            pixelsColor[i][0] = tooHighValueCoulour[0];
218            pixelsColor[i][1] = tooHighValueCoulour[1];
219            pixelsColor[i][2] = tooHighValueCoulour[2];
220            continue;
221        }
222        int index = 0;
223        while (ss[index] < color && index < 4)
224            index++;
225        index--;
226        if (index < 0) index = 0;
227        float weight0 = (color-ss[index]) / (ss[index+1]-ss[index]);
228        if (weight0 > 1.0f) weight0 = 1.0f;
229        if (weight0 < 0.0f) weight0 = 0.0f;
230        float weight1 = 1.0f-weight0;
231        pixelsColor[i][0] = weight1*rr[index] + weight0*rr[index+1];
232        pixelsColor[i][1] = weight1*gg[index] + weight0*gg[index+1];
233        pixelsColor[i][2] = weight1*bb[index] + weight0*bb[index+1];
234    }
235
236    for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
237    {
238
239        glColor3fv(pixelsColor[i]);
240        glLoadName(i);
241if (drawBlur)
242    drawBlurryHexagon(i);
243else
244    drawHexagon(i,true);
245
246    }
247    if (!alsoWire)
248        return;
249    glTranslatef(0,0,0.1f);
250    glColor3f(0.0f,0.0f,0.0f);
251    for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
252    {
253
254        drawHexagon(i, false);
255    }
256
257}
258
259/************************************************************
260 * DRAW PIXEL CURVE. draws the raw impulse curve of the currently selected pixel
261 ************************************************************/
262void RawDataViewer::drawPixelCurve()
263{
264    float xRange = bboxMax[0] - bboxMin[0];
265    float yRange = bboxMax[1] - bboxMin[1];
266
267    glBegin(GL_LINES);
268    glLineWidth(1.0f);
269    glColor3f(0.0,0.0,0.0);
270    glVertex2f(bboxMin[0], bboxMin[1]);
271    glVertex2f(bboxMax[0], bboxMin[1]);
272    glVertex2f(bboxMin[0], bboxMin[1]);
273    glVertex2f(bboxMin[0], bboxMax[1]);
274    glVertex2f(bboxMin[0], (bboxMin[1]+bboxMax[1])/2.0f);
275    glVertex2f(bboxMax[0], (bboxMin[1]+bboxMax[1])/2.0f);
276    glVertex2f(bboxMin[0] + xRange*nRoi/(float)(nRoi+nRoiTM),
277               bboxMin[1]);
278    glVertex2f(bboxMin[0] + xRange*nRoi/(float)(nRoi+nRoiTM),
279               bboxMax[1]);
280   glEnd();
281    glTranslatef(0,0,0.1f);
282    if (!nRoi)
283          return;
284     glBegin(GL_LINES);
285    glColor3f(1.0f,1.0f,0.0f);
286    float divideMe = (float)(VALUES_SPAN-1);
287    float plusMe = (float)(VALUES_SPAN)/2;
288    if (divideMe <= 0)
289        divideMe = 1;
290
291    /*
292    if (drawCalibrationLoaded)
293        plusMe += 0;//VALUES_SPAN/2;
294    if (drawCalibrationLoaded && calibrationLoaded)
295    {
296        divideMe /=2;
297        plusMe = 0 ;///=2;
298        }*/
299
300//    int mapping = _softwareOrdering ? selectedPixel : hardwareMapping[selectedPixel];
301    int mapping = hardwareMapping[selectedPixel];
302    const int hw = mapping;
303    const PixelMapEntry& mapEntry = fPixelMap.index(selectedPixel);
304    const int pixelIdInPatch = mapEntry.pixel();
305    const int patchId = mapEntry.patch();
306    const int boardId = mapEntry.board();
307    const int crateId = mapEntry.crate();
308
309    if (selectedPixel != -1)
310    {
311    for (int i=0;i<nRoi-1;i++)
312    {
313        float d1 = eventData[nRoi*hw + i]+plusMe;
314        float d2 = eventData[nRoi*hw + i+1]+plusMe;
315        if (!finite(d1)) d1 = 20000;
316        if (!finite(d2)) d2 = 20000;
317        glVertex2f(bboxMin[0] + xRange*i/(float)(nRoi+nRoiTM),
318                   bboxMin[1] + yRange*(d1) /divideMe);
319        glVertex2f(bboxMin[0] + xRange*(i+1)/(float)(nRoi+nRoiTM),
320                   bboxMin[1] + yRange*(d2) /divideMe);
321    }
322    glEnd();
323
324    glColor3f(0.0f, 1.0f, 1.0f);
325    glBegin(GL_LINES);
326    if (pixelIdInPatch == 8)//this channel has a time marker
327    {
328
329        for (int i=0;i<nRoiTM-1;i++)
330        {
331            float d1 = eventData[nRoi*1440 + nRoiTM*(40*crateId + 4*boardId + patchId) + i] + plusMe;
332            float d2 = eventData[nRoi*1440 + nRoiTM*(40*crateId + 4*boardId + patchId) + i+1] + plusMe;
333            if (!finite(d1)) d1 = 20000;
334            if (!finite(d2)) d2 = 20000;
335            glVertex2f(bboxMin[0] + xRange*(i+nRoi)/(float)(nRoi+nRoiTM),
336                       bboxMin[1] + yRange*(d1)/divideMe);
337            glVertex2f(bboxMin[0] + xRange*(i+1+nRoi)/(float)(nRoi+nRoiTM),
338                       bboxMin[1] + yRange*(d2) / divideMe);
339        }
340    }
341
342    }
343    glEnd();
344    glTranslatef(0,0,0.1f);
345    glBegin(GL_LINES);
346    glColor3f(1.0,0.0,0.0);
347    glVertex2f(bboxMin[0] + xRange*whichSlice/(float)(nRoi+nRoiTM),
348               bboxMin[1]);
349    glVertex2f(bboxMin[0] + xRange*whichSlice/(float)(nRoi+nRoiTM),
350               bboxMax[1]);
351
352    glEnd();
353
354}
355/************************************************************
356 * CONSTRUCTOR.
357 ************************************************************/
358RawDataViewer::RawDataViewer(QWidget *cParent) : BasicGlCamera(cParent), RMSvalues(1440), Meanvalues(1440), Maxvalues(1440), PosOfMaxvalues(1440), VALUES_SPAN(4096)
359
360{
361
362    whichSlice = 0;
363
364    nRoi = 0;
365    nRoiTM = 0;
366    offSetRoi = 0;
367    eventNum = 0;
368    rowNum = -1;
369    eventStep = 1;
370    selectedPixel = 393;
371    inputFile = NULL;
372    eventData = NULL;
373    drawPatch = false;
374    drawImpulse = true;
375    drawBlur = false;
376    loopCurrentEvent = false;
377    fIsDrsCalibration = false;
378    SetAutoRefresh(true);
379    runType = "unkown";
380
381
382}
383
384void RawDataViewer::assignPixelMapFile(const string& map)
385{
386    PixelMap mypMap;
387    if (map.empty())
388    {
389        if (!mypMap.Read("FACTmap111030.txt"))
390        {
391            if (!mypMap.Read("/swdev_nfs/FACT++/FACTmap111030.txt"))
392            {
393                if (!mypMap.Read("./FACTmap111030.txt"))
394                {
395                    cerr << "ERROR - Problems reading FACTmap111030.txt" << endl;
396                    exit(-1);
397                }
398            }
399        }
400    }
401    else
402    {
403        if (!mypMap.Read(map))
404        {
405            cerr << "ERROR - Problems reading mapping file '" << map << "'" << endl;
406            exit(-1);
407        }
408    }
409
410    assignPixelMap(mypMap);
411
412    for (int i=0;i<160;i++)
413    {
414        const float color[3] = { 0.5, 0.5, 0.3 };
415
416        for (int j=0;j<3;j++)
417            patchesColor[i][j] = color[j];
418    }
419    fZeroArray = NULL;
420
421    _softwareOrdering = false;
422}
423/************************************************************
424 *  DESTRUCTOR
425 ************************************************************/
426RawDataViewer::~RawDataViewer()
427{
428    if (inputFile != NULL)
429    {
430        inputFile->close();
431        delete inputFile;
432    }
433    if (eventData != NULL) {
434        delete[] eventData;
435        delete[] rawEventData;
436        delete[] waveLetArray;
437    }
438    if (fZeroArray != NULL)
439        delete[] fZeroArray;
440}
441void RawDataViewer::allocateZeroArray()
442{
443    if (fZeroArray == NULL)
444    {
445        fZeroArray = new char[8192];
446    }
447}
448/************************************************************
449 * PAINT GL. main drawing function.
450 ************************************************************/
451void RawDataViewer::paintGL()
452{
453    //Should not be required, but apparently it helps when piping it through X forwarding
454    glFinish();
455    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
456    glLoadIdentity();
457
458    glTranslatef(0,0,-0.5);
459
460    if (drawBlur)
461    {
462        glShadeModel(GL_SMOOTH);
463        drawCamera(false);
464    }
465    else
466    {
467        glShadeModel(GL_FLAT);
468        drawCamera(true);
469    }
470    glTranslatef(0,0,0.1f);
471    if (drawPatch)
472        drawPatches();
473    glTranslatef(0,0,0.1f);
474   if (!drawBlur && (selectedPixel != -1))
475   {
476        glLineWidth(1.0f);
477        glColor3f(1.0,1.0,1.0);
478        drawHexagon(selectedPixel, false);
479   }
480   glTranslatef(0,0,0.1f);
481   if (drawImpulse)
482   {
483    //   glRotatef(cameraRotation, 0,0,1);
484       glLoadIdentity();
485       glLineWidth(2.0);
486       drawPixelCurve();
487   }
488   glTranslatef(0,0,0.1f);
489   DrawScale();
490}
491
492/************************************************************
493 * MOUSE PRESS EVENT. mouse click handler.
494 ************************************************************/
495void RawDataViewer::mousePressEvent(QMouseEvent *cEvent)
496{
497    if (cEvent->pos().x() > width()-(width()/50.f))
498    {
499        toggleInterfaceDisplay();
500        return;
501    }
502    lastPos = cEvent->pos();
503    if (setCorrectSlice(cEvent))
504        return;
505    int face = PixelAtPosition(cEvent->pos());
506
507        selectedPixel = face;
508        emit signalCurrentPixel(face);
509
510    updateGL();
511}
512
513/************************************************************
514 * SET CORRECT SLICE. if displayed, figures out if the graph was
515 * clicked, and if so, which slice should be displayed
516 ************************************************************/
517bool RawDataViewer::setCorrectSlice(QMouseEvent* cEvent)
518{
519    if (!drawImpulse)
520        return false;
521    float cx = (float)cEvent->x() * pixelSize - shownSizex/2;
522    float cy = ((float)height()-(float)cEvent->y())*pixelSize - shownSizey/2;
523    if (cx < bboxMin[0] ||
524        cx > bboxMax[0] ||
525        cy < bboxMin[1] ||
526        cy > bboxMax[1])
527        return false;
528    whichSlice = (cx - bboxMin[0])*(nRoi+nRoiTM)/(bboxMax[0] - bboxMin[0]);
529    if (whichSlice >= nRoi)
530        whichSlice = nRoi-1;
531    emit signalCurrentSlice(whichSlice);
532    return true;
533}
534
535/************************************************************
536 * MOUSE MOVE EVENT. used to track the dragging of slices display
537 ************************************************************/
538void RawDataViewer::mouseMoveEvent(QMouseEvent *cEvent)
539{
540    if (cEvent->buttons() & Qt::LeftButton) {
541        setCorrectSlice(cEvent);
542        updateGL();
543    } else if (cEvent->buttons() & Qt::RightButton) {
544        updateGL();
545    }
546    lastPos = cEvent->pos();
547}
548
549/************************************************************
550 * MOUSE DOUBLE CLICK EVENT. used to select pixels
551 ************************************************************/
552void RawDataViewer::mouseDoubleClickEvent(QMouseEvent *cEvent)
553{
554    int face = PixelAtPosition(cEvent->pos());
555    if (face != -1) {
556        selectedPixel = face;
557        emit signalCurrentPixel(face);
558        updateGL();
559        }
560}
561
562/************************************************************
563 * OPEN FILE. opens a new fits file
564 ************************************************************/
565void RawDataViewer::openFile(string file, bool reopen)
566{
567    if (inputFile)
568    {
569        inputFile->close();
570        delete inputFile;
571    }
572    try {
573        inputFile = reopen && fIsDrsCalibration ? new zfits(file, "Events") :  new factfits(file, "Events");
574    }
575    catch (std::runtime_error e)
576    {
577        cout << "Something went wrong while loading fits. Aborting: " << e.what() << endl;
578        return;
579    }
580    if (!*inputFile)
581    {
582        delete inputFile;
583        inputFile = NULL;
584        return;
585    }
586    vector<string> entriesToCheck;
587    if (inputFile->IsCompressedFITS())
588        entriesToCheck.push_back("ZNAXIS2");
589    else
590        entriesToCheck.push_back("NAXIS2");
591    entriesToCheck.push_back("NROI");
592    entriesToCheck.push_back("REVISION");
593    entriesToCheck.push_back("RUNID");
594    entriesToCheck.push_back("NBOARD");
595    entriesToCheck.push_back("NPIX");
596    entriesToCheck.push_back("NROITM");
597    entriesToCheck.push_back("TIMESYS");
598    entriesToCheck.push_back("DATE");
599    entriesToCheck.push_back("NIGHT");
600    entriesToCheck.push_back("CAMERA");
601    entriesToCheck.push_back("DAQ");
602    entriesToCheck.push_back("TSTART");
603    entriesToCheck.push_back("TSTOP");
604
605
606    for (vector<string>::const_iterator it=entriesToCheck.begin(); it != entriesToCheck.end(); it++)
607    {
608        try {
609        if (!inputFile->HasKey(*it)){
610            cout << "Warning: header keyword " << *it << " missing." << endl;
611            }
612        }
613        catch (std::runtime_error e)
614        {
615            cout << e.what() << endl;
616            return;
617        }
618    }
619
620    nRows = 0;
621    if (inputFile->IsCompressedFITS())
622        nRows = inputFile->HasKey("ZNAXIS2") ? inputFile->GetInt("ZNAXIS2") : 0;
623    else
624        nRows = inputFile->HasKey("NAXIS2") ? inputFile->GetInt("NAXIS2") : 0;
625    nRoi =           inputFile->HasKey("NROI") ?  inputFile->GetInt("NROI") : 0;
626    runNumber =      inputFile->HasKey("RUNID") ?  inputFile->GetInt("RUNID") : -1;
627    nTM =            inputFile->HasKey("NTMARK") ? inputFile->GetInt("NTMARK") : 0;
628
629    runType = "unkown";
630    if (inputFile->HasKey("RUNTYPE"))
631    {
632        runType = inputFile->GetStr("RUNTYPE");
633        if (runType == "")
634            runType = "unkown";
635    }
636    firstDataTime =  inputFile->HasKey("TSTART") ? inputFile->GetInt("TSTART") : -1;
637    lastDataTime =   inputFile->HasKey("TSTOP") ? inputFile->GetInt("TSTOP"): -1;
638    nRoiTM =         inputFile->HasKey("NROITM") ? inputFile->GetInt("NROITM") : 0;
639    revision =       inputFile->HasKey("REVISION") ? inputFile->GetInt("REVISION") : -1;
640    builderVersion = inputFile->HasKey("BLDVER") ? inputFile->GetInt("BLDVER") : -1;
641    nBoards =        inputFile->HasKey("NBOARD") ? inputFile->GetInt("NBOARD") : 0;
642    nPixels =        inputFile->HasKey("NPIX") ?  inputFile->GetInt("NPIX") : 0;
643    timeSystem =     inputFile->HasKey("TIMESYS") ? inputFile->GetStr("TIMESYS") : "";
644    creationDate =   inputFile->HasKey("DATE") ? inputFile->GetStr("DATE") : "";
645    nightInt =       inputFile->HasKey("NIGHT") ? inputFile->GetInt("NIGHT") : 0;
646    camera =         inputFile->HasKey("CAMERA") ? inputFile->GetStr("CAMERA") : "";
647    daq =            inputFile->HasKey("DAQ") ? inputFile->GetStr("DAQ") : "";
648    adcCount =       inputFile->HasKey("ADCRANGE") ? inputFile->GetFloat("ADCRANGE") : 2000;
649    if (nPixels == 0)
650    {
651        cout << "could not read num pixels from fits header. Assuming 1440 (FACT)." << endl;
652        nPixels = 1440;
653    }
654    if (nRoi == 0 && !inputFile->HasKey("NROI"))
655    {//let's try to figure out the roi from the column's format
656        const fits::Table::Columns& cols = inputFile->GetColumns();
657        if (cols.find("Data") == cols.end())
658        {
659            cout << "ERROR: Column \"Data\" could not be found. abortin load." << endl;
660            return;
661        }
662        const fits::Table::Columns::const_iterator col = cols.find("Data");
663        if (col->second.type != 'I')
664        {
665            cout << "ERROR: Data Column has type " << col->second.type << " while viewer expects I" << endl;
666            return;
667        }
668        if (col->second.num % nPixels != 0)
669        {
670            cout << "ERROR: Num pixels (" << nPixels << ") does not match Data length (" << col->second.num << "). Aborting" << endl;
671            return;
672        }
673        nRoi = col->second.num/nPixels;
674        cout << "Estimate num samples per pixels to be " << nRoi;
675        _softwareOrdering = true;
676    }
677    else
678        _softwareOrdering = inputFile->Get<string>("ISMC", "F")=="T";
679
680    if (inputFile->HasKey("OFFSET"))
681        offSetRoi = inputFile->GetInt("OFFSET");
682
683    nbOk = 0;//inputFile->GetInt("NBEVTOK");
684    nbRej = 0;//inputFile->GetInt("NBEVTREJ");
685    nbBad = 0;//inputFile->GetInt("NBEVTBAD");
686
687    eventNum = 1;
688
689    if (eventData != NULL) {
690        delete[] eventData;
691        delete[] rawEventData;
692        delete[] waveLetArray;
693    }
694    eventData = new float[1440*nRoi + 160*nRoiTM];//(1440+160)*nRoi];
695
696    rawEventData = new int16_t[1440*nRoi + 160*nRoiTM];//(1440+160)*nRoi];
697    waveLetArray = new int16_t[1024*1440];
698    try
699    {
700        inputFile->SetPtrAddress("Data", rawEventData);
701        if (inputFile->HasColumn("EventNum"))
702            inputFile->SetPtrAddress("EventNum", &eventNum);
703        else
704            cout << "Warning: could not find column \"EventNum\"" << endl;
705        if (inputFile->HasColumn("TriggerType"))
706            inputFile->SetPtrAddress("TriggerType", &triggerType);
707        else
708            cout << "Warning: could not find column \"TriggerType\"" << endl;
709        if (inputFile->HasColumn("SoftTrig"))
710            inputFile->SetPtrAddress("SoftTrig", &softTrig);
711        else
712            cout << "Warning: could not find column \"SoftTrig\"" << endl;
713        if (inputFile->HasColumn("BoardTime"))
714            inputFile->SetPtrAddress("BoardTime", boardTime);
715        else
716            cout << "Warning: could not find column \"BoardTime\"" << endl;
717        if (inputFile->HasColumn("StartCellData"))
718            inputFile->SetPtrAddress("StartCellData", startPix);
719        else
720            cout << "Warning: could not find column \"StartCellData\"" << endl;
721        if (inputFile->HasColumn("StartCellTimeMarker"))
722            inputFile->SetPtrAddress("StartCellTimeMarker", startTM);
723        else
724            cout << "Warning: could not find column \"StartCellTimeMarker\"" << endl;
725        if (inputFile->HasColumn("TimeMarker"))
726            inputFile->SetPtrAddress("TimeMarker", &rawEventData[1440*nRoi]);
727        else
728            cout << "Warning: could not find column \"TimeMarker\"" << endl;
729    }
730    catch (const runtime_error &e)
731    {
732        cout << e.what() << endl;
733        cout << "Loading aborted." << endl;
734
735        nRoi = nRows = 0;
736
737        return;
738    }
739
740    try
741    {
742        pcTime[0] = pcTime[1] = 0;
743        if (inputFile->HasColumn("UnixTimeUTC"))
744            inputFile->SetPtrAddress("UnixTimeUTC", pcTime);
745    }
746    catch (const runtime_error&)
747    {
748            try
749        {
750            if (inputFile->HasColumn("PCTime"))
751                inputFile->SetPtrAddress("PCTime", pcTime);
752            else
753                cout << "Warning: could not find column \"UnixTimeUTC\" nor \"PCTime\"" << endl;
754
755        }
756        catch (const runtime_error&)
757        {
758
759        }
760    }
761
762
763    if (!reopen)
764    {
765        int backupStep = eventStep;
766        rowNum = -1;
767        eventStep = 1;
768        plusEvent();
769        eventStep = backupStep;
770    }
771    else
772        readEvent();
773
774    emit newFileLoaded();
775    emit signalCurrentPixel(selectedPixel);
776}
777
778void RawDataViewer::openCalibFile(string& file)
779{
780    //calibrationLoaded = false;
781    string msg;
782    try
783    {
784        msg = fDrsCalib.ReadFitsImp(file);
785        if (msg.empty())
786        {
787            emit newFileLoaded();
788            updateGL();
789            return;
790        }
791    }
792    catch (const runtime_error &e)
793    {
794        msg = string("Something went wrong while loading Drs Calib: ") + e.what() + string(".. Aborting file loading");
795    }
796    cerr << msg << endl;
797    fDrsCalib.Clear();
798}
799
800template <typename T>
801void RawDataViewer::getCalibrationDataForDisplay(const CalibDataTypes/* calibTypes*/,
802                                                 const vector<T>& inputData,
803                                                 const int roi,
804                                                 const int roiTM)
805{
806
807    eventData = new float[1440*roi + 160*roiTM];//(1440+160)*nRoi];
808    nRoi=roi;
809    nRoiTM=roiTM;
810
811    long long min, max, mean;
812    min = max = inputData[0];
813    mean=0;
814    for (int i=0;i<1440*roi + 160*roiTM;i++) {
815        eventData[i] = (float)inputData[i];
816        mean += inputData[i];
817        if (inputData[i] > max)
818            max = inputData[i];
819        if (inputData[i] < min)
820            min = inputData[i];
821    }
822    mean /= 1440*roi + 160*roiTM;
823    for (int i=0;i<1440*roi + 160*roiTM;i++)
824        eventData[i] -= (float)mean;
825    VALUES_SPAN = max - min;
826//    cout << VALUES_SPAN << " " << min << " " << max << " " << mean << endl;
827//    cout << 1440*roi + 160*roiTM << " " << roi << " " << roiTM << " " << inputData.size() << endl;
828}
829/************************************************************
830 * PLUS EVENT
831 ************************************************************/
832void RawDataViewer::plusEvent()
833{
834    eventStepping(true);
835}
836/************************************************************
837 * MINUS EVENT
838 ************************************************************/
839void RawDataViewer::minusEvent()
840{
841    eventStepping(false);
842}
843/************************************************************
844 * SET EVENT STEP
845 ************************************************************/
846void RawDataViewer::setEventStep(int step)
847{
848    eventStep = step;
849}
850/************************************************************
851 * EVENT STEPPING
852 ************************************************************/
853
854void RawDataViewer::ApplyCalibration()
855{
856    for (int i=0;i<1440*nRoi + 160*nRoiTM;i++)//(1440+160)*nRoi;i++)
857        eventData[i] = (float)rawEventData[i];
858
859    if (fIsDrsCalibration)
860    {
861        fDrsCalib.Apply(eventData, rawEventData, startPix, nRoi);
862        DrsCalibrate::RemoveSpikes(eventData, nRoi);
863        //TODO apply calibration to the Time markers
864    }
865
866    //hide the time markers
867    int nSlicesToRemove = 60;
868    float* backupData = 0;
869    if (nRoiTM == 0) //they are written into the regular channel
870    {
871        backupData = new float[nSlicesToRemove*160];
872        for (int i=0;i<1440;i++)
873        {
874            const PixelMapEntry& mapEntry = fPixelMap.index(i);
875            const int pixelIdInPatch = mapEntry.pixel();
876            const int patchId = mapEntry.patch();
877            const int boardId = mapEntry.board();
878            const int crateId = mapEntry.crate();
879
880            const int hw = mapEntry.hw();
881            if (pixelIdInPatch == 8)
882            {
883                for (int j=0;j<nSlicesToRemove;j++)
884                {
885                    backupData[(40*crateId + 4*boardId + patchId)*nSlicesToRemove+j] = eventData[(hw*nRoi) + (nRoi-nSlicesToRemove) + j];
886                    eventData[(hw*nRoi) + (nRoi-nSlicesToRemove) + j] = eventData[hw*nRoi + (nRoi-nSlicesToRemove) - 1];
887                }
888            }
889        }
890    }
891
892    vector<float> pixelStatsData(1440*4);
893    DrsCalibrate::GetPixelStats(pixelStatsData.data(), eventData, nRoi);
894
895    for (vector<PixelMapEntry>::const_iterator it=fPixelMap.begin(); it!=fPixelMap.end(); it++)
896    {
897        Meanvalues[it->index]     = pixelStatsData[0*1440+it->hw()];
898        RMSvalues[it->index]      = pixelStatsData[1*1440+it->hw()];
899        Maxvalues[it->index]      = pixelStatsData[2*1440+it->hw()];
900        PosOfMaxvalues[it->index] = pixelStatsData[3*1440+it->hw()];
901    }
902    if (nRoiTM == 0)//move back the data back in place
903    {
904        for (int i=0;i<1440;i++)
905        {
906            const PixelMapEntry& mapEntry = fPixelMap.index(i);
907            const int pixelIdInPatch = mapEntry.pixel();
908            const int patchId = mapEntry.patch();
909            const int boardId = mapEntry.board();
910            const int crateId = mapEntry.crate();
911            if (patchId > 160)
912                cout << "Voila mon probleme: " << patchId << endl;
913            const int hw = mapEntry.hw();
914            if (pixelIdInPatch == 8)
915            {
916 //               cout << "|" << crateId << " " << boardId << " " << patchId << " " << hw << "| ";
917                for (int j=0;j<nSlicesToRemove;j++)
918                {
919                    eventData[(hw*nRoi) + (nRoi - nSlicesToRemove) + j] = backupData[(40*crateId + 4*boardId + patchId)*nSlicesToRemove+j];
920                }
921            }
922        }
923        delete[] backupData;
924    }
925    if (isVisible())
926        updateGL();
927}
928
929void RawDataViewer::eventStepping(bool plus)
930{
931    if (plus)
932        rowNum += eventStep;
933    else
934        rowNum -= eventStep;
935    if (rowNum >= nRows)
936        rowNum -= nRows;
937    if (rowNum < 0)
938        rowNum += nRows;
939
940    readEvent();
941}
942
943void RawDataViewer::readEvent()
944{
945    if (inputFile == NULL)
946        return;
947    inputFile->GetRow(rowNum);
948    if (_softwareOrdering)
949    {//remap pixels data according to hardware id
950        if (nRoiTM != 0)
951            cout << "Warning: did not expect Time Markers data from Monte-Carlo simulations. These will not be mapped properly." << endl;
952        //first copy the data
953        int16_t* tempData = new int16_t[1440*nRoi];
954        for (int i=0;i<1440*nRoi;i++)
955            tempData[i] = rawEventData[i];
956        //copy back the data and re-map it on the fly
957        for (int i=0;i<1440;i++)
958            for (int j=0;j<nRoi;j++)
959                rawEventData[i*nRoi + j] = tempData[softwareMapping[i]*nRoi + j];
960
961        delete[] tempData;
962    }
963//    cout << "Getting row " << rowNum << endl;
964
965
966    ApplyCalibration();
967
968    emit signalCurrentEvent(eventNum);
969    emit signalCurrentPixel(selectedPixel);
970}
971
972/************************************************************
973 * NEXT SLICE. deprec ?
974 ************************************************************/
975void RawDataViewer::nextSlice()
976{
977    whichSlice++;
978    if (whichSlice >= nRoi)
979    {
980        whichSlice = 0;
981        if (!loopCurrentEvent)
982        {
983            int backupStep = eventStep;
984            eventStep = 1;
985            eventStepping(true);
986            eventStep = backupStep;
987        }
988    }
989    emit signalCurrentSlice(whichSlice);
990    updateGL();
991}
992void RawDataViewer::previousSlice()
993{
994    whichSlice--;
995    if (whichSlice < 0)
996    {
997        whichSlice = nRoi-1;
998        if (!loopCurrentEvent)
999        {
1000            int backupStep = eventStep;
1001            eventStep = 1;
1002            eventStepping(false);
1003            eventStep = backupStep;
1004        }
1005    }
1006    emit signalCurrentSlice(whichSlice);
1007    updateGL();
1008}
1009void RawDataViewer::setCurrentPixel(int pix)
1010{
1011 //   if (pix == -1)
1012 //       return;
1013    selectedPixel = pix;
1014    if (isVisible())
1015    updateGL();
1016     emit signalCurrentPixel(pix);
1017}
1018void RawDataViewer::computePulsesStatistics()
1019{
1020    if (!inputFile)
1021    {
1022        cout << "A FITS file must be open in order to complete this operation" << endl;
1023        return;
1024    }
1025
1026
1027//    for (int i=0;i<nRows;i++)//for all events
1028//    {
1029//        inputFile->GetRow(rowNum);
1030//        for (int i=0;i<(1440+160)*nRoi;i++)
1031//            eventData[i] = (float)rawEventData[i];
1032
1033//        for (int j=0;j<ACTUAL_NUM_PIXELS;j++)
1034///        {
1035    int j = selectedPixel;
1036    if (j == -1)
1037        return;
1038            for (int i=0;i<nRoi;i++)
1039            {
1040                aMeas[i] = eventData[j*nRoi+i];// * adcCount;
1041
1042            }
1043            for (int i=0;i<nRoi;i++)
1044            {
1045                if (i==0)
1046                    n1mean[i] = aMeas[i+1];
1047                else
1048                {
1049                    if (i==1023)
1050                        n1mean[i] = aMeas[i-1];
1051                    else
1052                        n1mean[i] = (aMeas[i-1]+aMeas[i+1])/2.f;
1053                }
1054            }
1055            //find spike
1056            for (int i=0;i<nRoi-3;i++)
1057            {
1058                const float fract = 0.8f;
1059                float xx, xp, xpp;
1060                vCorr[i] = 0;//aMeas[i];
1061                xx = aMeas[i] - n1mean[i];
1062                if (xx < -8.f)
1063                {
1064                    xp = aMeas[i+1] - n1mean[i+1];
1065                    xpp = aMeas[i+2] - n1mean[i+2];
1066                    if ((aMeas[i+2] - (aMeas[i] + aMeas[i+3])/2.f) > 10.f)
1067                    {
1068                        vCorr[i+1] = (aMeas[i] + aMeas[i+3])/2.f;
1069                        vCorr[i+2] = (aMeas[i] + aMeas[i+3])/2.f;
1070                        i = i+2;
1071                    }
1072                    else
1073                    {
1074                        if ((xp > -2.*xx*fract) && (xpp < -10.f))
1075                        {
1076                            vCorr[i+1] = n1mean[i+1];
1077                            n1mean[i+2] = aMeas[i+1] - aMeas[i+3]/2.f;
1078                            i++;
1079                        }
1080                    }
1081                }
1082            }
1083            for (int i=0;i<nRoi;i++)
1084                n1mean[i] = aMeas[i]-n1mean[i];
1085 //       }
1086 //   }
1087}
1088/************************************************************
1089 * UICONNECTOR CONSTRUCTOR
1090 ************************************************************/
1091UIConnector::UIConnector(QWidget *p)
1092{
1093    setupUi(this);
1094    initHistograms();
1095
1096    updateSpinnerDisplay = true;
1097    updating = false;
1098
1099    timer.setInterval(10.0);
1100    QObject::connect(&timer, SIGNAL(timeout()),
1101                     this, SLOT(nextSlicePlease()));
1102
1103    QButtonGroup &scaleGroup = *new QButtonGroup(p);// = new QButtonGroup(canvas);
1104    QButtonGroup &animateGroup = *new QButtonGroup(p);// = new QButtonGroup(canvas);
1105
1106    scaleGroup.addButton(currentPixelScale);
1107    scaleGroup.addButton(entireCameraScale);
1108
1109    animateGroup.addButton(playEventsRadio);
1110    animateGroup.addButton(playSlicesRadio);
1111    animateGroup.addButton(playPixelsRadio);
1112
1113    entireCameraScale->setChecked(true);
1114
1115    RMS_window->enableText(false);
1116    Mean_window->enableText(false);
1117    PosOfMax_window->enableText(false);
1118    Max_window->enableText(false);
1119
1120 //   RMS_window->ShowPatchCursor(true);
1121
1122    QObject::connect(GLWindow, SIGNAL(colorPaletteHasChanged()),
1123                     this, SLOT(on_autoScaleColor_clicked()));
1124    QObject::connect(GLWindow, SIGNAL(signalCurrentSlice(int)),
1125                     this, SLOT(currentSliceHasChanged(int)));
1126    QObject::connect(GLWindow, SIGNAL(signalCurrentEvent(int)),
1127                     this, SLOT(currentEventHasChanged(int)));
1128    QObject::connect(GLWindow, SIGNAL(signalCurrentPixel(int)),
1129                     this, SLOT(pixelChanged(int)));
1130    QObject::connect(GLWindow, SIGNAL(newFileLoaded()),
1131                     this, SLOT(newFileLoaded()));
1132
1133    QObject::connect(RMS_window, SIGNAL(signalCurrentPixel(int)),
1134                     GLWindow, SLOT(setCurrentPixel(int)));
1135    QObject::connect(Max_window, SIGNAL(signalCurrentPixel(int)),
1136                     GLWindow, SLOT(setCurrentPixel(int)));
1137    QObject::connect(PosOfMax_window, SIGNAL(signalCurrentPixel(int)),
1138                     GLWindow, SLOT(setCurrentPixel(int)));
1139    QObject::connect(Mean_window, SIGNAL(signalCurrentPixel(int)),
1140                     GLWindow, SLOT(setCurrentPixel(int)));
1141
1142
1143
1144    show();
1145}
1146UIConnector::~UIConnector()
1147{
1148    grid1->detach();
1149    grid2->detach();
1150    grid3->detach();
1151    grid4->detach();
1152    grid5->detach();
1153    grid6->detach();
1154    boardsTimeHistoItem.detach();
1155    startCellHistoItem.detach();
1156    startTimeMarkHistoItem.detach();
1157    pixelValueCurveItem.detach();
1158    pixelAverageCurveItem.detach();
1159    aMeanCurveItem.detach();
1160    vCorrCurveItem.detach();
1161    meanCurveItem.detach();
1162}
1163void UIConnector::slicesPlusPlus()
1164{
1165    GLWindow->nextSlice();
1166}
1167void UIConnector::slicesMinusMinus()
1168{
1169    GLWindow->previousSlice();
1170}
1171void UIConnector::on_calibratedCheckBox_stateChanged(int state)
1172{
1173    GLWindow->fIsDrsCalibration = state;
1174
1175    if (currentCalibFile.empty())
1176        GLWindow->openFile(currentFile, true);
1177
1178    GLWindow->ApplyCalibration();
1179
1180    threeD_Window->setData(GLWindow->eventData);
1181
1182    on_autoScaleColor_clicked();
1183    pixelChanged(GLWindow->selectedPixel);
1184
1185}
1186/************************************************************
1187 * DRAW PATCHES CHECK CHANGE. checkbox handler
1188 ************************************************************/
1189void UIConnector::on_drawPatchCheckBox_stateChanged(int state)
1190{
1191    GLWindow->drawPatch = state;
1192    GLWindow->updateGL();
1193    RMS_window->fDrawPatch = state;
1194    RMS_window->updateGL();
1195    Mean_window->fDrawPatch = state;
1196    Mean_window->updateGL();
1197    Max_window->fDrawPatch = state;
1198    Max_window->updateGL();
1199    PosOfMax_window->fDrawPatch = state;
1200    PosOfMax_window->updateGL();
1201}
1202/************************************************************
1203 * DRAW IMPULSE CHECK CHANGE. checkbox handler
1204 ************************************************************/
1205void UIConnector::on_drawImpulseCheckBox_stateChanged(int state)
1206{
1207    GLWindow->drawImpulse = state;
1208    TriggerOffset_window->drawImpulse = state;
1209    Gain_window->drawImpulse = state;
1210    Baseline_window->drawImpulse = state;
1211    GLWindow->updateGL();
1212    TriggerOffset_window->updateGL();
1213    Gain_window->updateGL();
1214    Baseline_window->updateGL();
1215}
1216/************************************************************
1217 * DRAW BLUR CHECK CHANGE. checkbox handler
1218 ************************************************************/
1219void UIConnector::on_drawBlurCheckBox_stateChanged(int state)
1220{
1221    GLWindow->drawBlur = state;
1222    GLWindow->updateGL();
1223}
1224void UIConnector::on_loopOverCurrentEventBox_stateChanged(int state)
1225{
1226    GLWindow->loopCurrentEvent = state;
1227}
1228
1229/************************************************************
1230 * NEXT SLICE PLEASE
1231 ************************************************************/
1232void UIConnector::nextSlicePlease()
1233{
1234    if (playEventsRadio->isChecked ())
1235        GLWindow->eventStepping(true);
1236    else
1237        if (playPixelsRadio->isChecked())
1238            GLWindow->setCurrentPixel((GLWindow->getCurrentPixel()+1)%1440);
1239        else
1240            GLWindow->nextSlice();
1241}
1242
1243/************************************************************
1244 * SET VIEWER.
1245 ************************************************************/
1246//void UIConnector::setViewer(RawDataViewer* v)
1247//{
1248//    viewer = v;
1249//}
1250/************************************************************
1251 * SLICES PER SECOND CHANGED. timing ui handler
1252 ************************************************************/
1253void UIConnector::slicesPerSecondChanged(double value)
1254{
1255    timer.setInterval(1000.0/value);
1256}
1257
1258void UIConnector::on_colorRange0_valueChanged(double value) { GLWindow->ss[0] = (float)value; GLWindow->updateGL(); }
1259void UIConnector::on_colorRange1_valueChanged(double value) { GLWindow->ss[1] = (float)value; GLWindow->updateGL(); }
1260void UIConnector::on_colorRange2_valueChanged(double value) { GLWindow->ss[2] = (float)value; GLWindow->updateGL(); }
1261void UIConnector::on_colorRange3_valueChanged(double value) { GLWindow->ss[3] = (float)value; GLWindow->updateGL(); }
1262void UIConnector::on_colorRange4_valueChanged(double value) { GLWindow->ss[4] = (float)value; GLWindow->updateGL(); }
1263
1264void UIConnector::on_redValue0_valueChanged(double value) { GLWindow->rr[0] = (float)value; GLWindow->updateGL(); }
1265void UIConnector::on_redValue1_valueChanged(double value) { GLWindow->rr[1] = (float)value; GLWindow->updateGL(); }
1266void UIConnector::on_redValue2_valueChanged(double value) { GLWindow->rr[2] = (float)value; GLWindow->updateGL(); }
1267void UIConnector::on_redValue3_valueChanged(double value) { GLWindow->rr[3] = (float)value; GLWindow->updateGL(); }
1268void UIConnector::on_redValue4_valueChanged(double value) { GLWindow->rr[4] = (float)value; GLWindow->updateGL(); }
1269
1270void UIConnector::on_greenValue0_valueChanged(double value) { GLWindow->gg[0] = (float)value; GLWindow->updateGL(); }
1271void UIConnector::on_greenValue1_valueChanged(double value) { GLWindow->gg[1] = (float)value; GLWindow->updateGL(); }
1272void UIConnector::on_greenValue2_valueChanged(double value) { GLWindow->gg[2] = (float)value; GLWindow->updateGL(); }
1273void UIConnector::on_greenValue3_valueChanged(double value) { GLWindow->gg[3] = (float)value; GLWindow->updateGL(); }
1274void UIConnector::on_greenValue4_valueChanged(double value) { GLWindow->gg[4] = (float)value; GLWindow->updateGL(); }
1275
1276void UIConnector::on_blueValue0_valueChanged(double value) { GLWindow->bb[0] = (float)value; GLWindow->updateGL(); }
1277void UIConnector::on_blueValue1_valueChanged(double value) { GLWindow->bb[1] = (float)value; GLWindow->updateGL(); }
1278void UIConnector::on_blueValue2_valueChanged(double value) { GLWindow->bb[2] = (float)value; GLWindow->updateGL(); }
1279void UIConnector::on_blueValue3_valueChanged(double value) { GLWindow->bb[3] = (float)value; GLWindow->updateGL(); }
1280void UIConnector::on_blueValue4_valueChanged(double value) { GLWindow->bb[4] = (float)value; GLWindow->updateGL(); }
1281
1282/************************************************************
1283 * LOAD NEW FILE CLICKED. button handler
1284 ************************************************************/
1285void UIConnector::on_loadNewFileButton_clicked()
1286{
1287    QFileDialog dialog;
1288    dialog.setFileMode(QFileDialog::ExistingFile);
1289    dialog.open(this, SLOT(fileSelected(QString)));
1290    dialog.setVisible(true);
1291    dialog.exec();
1292}
1293void UIConnector::on_loadDRSCalibButton_clicked()
1294{
1295    QFileDialog dialog;
1296    dialog.setFileMode(QFileDialog::ExistingFile);
1297    dialog.open(this, SLOT(calibFileSelected(QString)));
1298    dialog.setVisible(true);
1299    dialog.exec();
1300}
1301/************************************************************
1302 * FILE SELECTED. return of the file open dialog handler
1303 ************************************************************/
1304void UIConnector::fileSelected(QString file)
1305{
1306    const bool reopen = !currentFile.empty();
1307
1308    currentFile = file.toStdString();
1309    if (!currentFile.empty())
1310        GLWindow->openFile(currentFile, reopen && currentCalibFile.empty());
1311}
1312void UIConnector::calibFileSelected(QString file)
1313{
1314    const bool reopen = currentCalibFile.empty();
1315
1316    currentCalibFile = file.toStdString();
1317    if (reopen && !currentFile.empty())
1318        GLWindow->openFile(currentFile, true);
1319    if (currentCalibFile != "")
1320        GLWindow->openCalibFile(currentCalibFile);
1321
1322
1323    if (GLWindow->fDrsCalib.fRoi != 0)
1324    {//spread the calibration data to the displayers
1325        Baseline_window->getCalibrationDataForDisplay(RawDataViewer::CALIB_BASELINE,
1326                                                      GLWindow->fDrsCalib.fOffset,
1327                                                      GLWindow->fDrsCalib.fRoi,
1328                                                      GLWindow->fDrsCalib.fNumTm);
1329
1330        Gain_window->getCalibrationDataForDisplay(RawDataViewer::CALIB_GAIN,
1331                                                  GLWindow->fDrsCalib.fGain,
1332                                                  GLWindow->fDrsCalib.fRoi,
1333                                                  GLWindow->fDrsCalib.fNumTm);
1334
1335        TriggerOffset_window->getCalibrationDataForDisplay(RawDataViewer::CALIB_TRIG_OFFSET,
1336                                                           GLWindow->fDrsCalib.fTrgOff,
1337                                                           GLWindow->fDrsCalib.fRoi,
1338                                                           GLWindow->fDrsCalib.fNumTm);
1339
1340    }
1341}
1342/************************************************************
1343 * NEW FILE LOADED. update of the UI after a new file has been loaded
1344 ************************************************************/
1345void UIConnector::newFileLoaded()
1346{
1347    ostringstream str;
1348
1349    //extract the file name only (no path) from the full name
1350    str << "File: ";
1351    if (currentFile.size() > 2)
1352        str << currentFile.substr(currentFile.find_last_of("//")+1, currentFile.size()) << "\n";
1353    else
1354        str << "--\n";
1355    str << "Calibration: ";
1356    if (currentCalibFile.size() > 2)
1357        str << currentCalibFile.substr(currentCalibFile.find_last_of("//")+1, currentCalibFile.size()) << "\n";
1358    else
1359        str << "--\n";
1360//    fileLoadedLabel->setText(QString(str.str().c_str()));
1361//    str.str("");
1362    str << "Run number: " << GLWindow->runNumber << "\n";
1363//    runNumberLabel->setText(QString(str.str().c_str()));
1364//    str.str("");
1365    str << "Number of Events: " << GLWindow->nRows << "\n";
1366
1367    displayingEventBox->setMaximum(GLWindow->nRows-1);
1368
1369    str << "Number of Slices: " << GLWindow->nRoi << "\n";// << "/1024";
1370//    numberOfSlicesLabel->setText(QString(str.str().c_str()));
1371//    str.str("");
1372    str << "Number of Time Marks: " << GLWindow->nTM << "\n";
1373//    numberOfTimeMarksLabel->setText(QString(str.str().c_str()));
1374
1375//    str.str("");
1376    str << "Run Type: " << GLWindow->runType << "\n";
1377//    runTypeLabel->setText(QString(str.str().c_str()));
1378//    str.str("");
1379    str << "Time of 1st data: " << GLWindow->firstDataTime << "\n";
1380//    firstTimeLabel->setText(QString(str.str().c_str()));
1381//    str.str("");
1382    str << "Time of last data: " << GLWindow->lastDataTime << "\n";
1383//    lastTimeLabel->setText(QString(str.str().c_str()));
1384//    str.str("");
1385    str << "SVN revision: " << GLWindow->revision << '\n';
1386    str << "Number of boards: " << GLWindow->nBoards << '\n';
1387    str << "Number of pixels: " << GLWindow->nPixels << '\n';
1388    str << "Number of Slices TM: " << GLWindow->nRoiTM << '\n';
1389    str << "Time system: " << GLWindow->timeSystem << '\n';
1390    str << "Date: " << GLWindow->creationDate << '\n';
1391    str << "Night: " << GLWindow->nightInt << '\n';
1392    str << "Camera: " << GLWindow->camera << '\n';
1393    str << "DAQ: " << GLWindow->daq << '\n';
1394    str << "ADC Count: " << GLWindow->adcCount << '\n';
1395    str << "NB Evts OK:" << GLWindow->nbOk << '\n';
1396    str << "NB Evts Rejected: " << GLWindow->nbRej << '\n';
1397    str << "NB Evts Bad: " << GLWindow->nbBad << '\n';
1398    extraInfoLabel->setText(QString(str.str().c_str()));
1399
1400    /*
1401    if (GLWindow->calibrationLoaded)
1402    {
1403        drawCalibrationCheckBox->setEnabled(true);
1404    }*/
1405
1406
1407}
1408/************************************************************
1409 * PLAY PAUSE CLICKED. ui handler
1410 ************************************************************/
1411void UIConnector::on_playPauseButton_clicked()
1412{
1413    if (timer.isActive())
1414        timer.stop();
1415    else
1416        timer.start();
1417}
1418
1419void UIConnector::displaySliceValue()
1420{
1421    if (!GLWindow->nRoi)
1422        return;
1423    if (GLWindow->selectedPixel == -1)
1424    {
1425        ostringstream str;
1426        str << " Current Pixel val.: --";
1427        currentPixelValue->setText(QString(str.str().c_str()));
1428        return;
1429    }
1430//    int mapping = GLWindow->_softwareOrdering ? GLWindow->selectedPixel : GLWindow->hardwareMapping[GLWindow->selectedPixel];
1431    int mapping = GLWindow->hardwareMapping[GLWindow->selectedPixel];
1432    const int idx = GLWindow->nRoi*mapping + GLWindow->whichSlice;
1433
1434    ostringstream str;
1435    str << "Current Pixel val.: " << GLWindow->eventData[idx];
1436    currentPixelValue->setText(QString(str.str().c_str()));
1437}
1438
1439/************************************************************
1440 * CURRENT SLICE HAS CHANGE. ui handler
1441 ************************************************************/
1442void UIConnector::currentSliceHasChanged(int slice)
1443{
1444    if (!GLWindow->nRoi)
1445        return;
1446
1447    if (updateSpinnerDisplay)
1448        displayingSliceBox->setValue(slice);
1449
1450    displaySliceValue();
1451}
1452
1453/*****
1454 *******************************************************
1455 * CURRENT EVENT HAS CHANGED. ui handler
1456 ************************************************************/
1457
1458double xval[50000];
1459double yval[50000];
1460void UIConnector::on_displayingEventBox_valueChanged(int cEvent)
1461{
1462//    cout << "Here " << updateSpinnerDisplay << endl;
1463    if (!updateSpinnerDisplay)
1464        return;
1465    updateSpinnerDisplay = false;
1466//    currentEventHasChanged(cEvent);
1467    GLWindow->rowNum = cEvent - GLWindow->eventStep;
1468    GLWindow->eventStepping(true);
1469    updateSpinnerDisplay = true;
1470
1471//    GLWindow->updateGL();
1472}
1473void UIConnector::on_slicesPerSecValue_valueChanged(double value)
1474{
1475    timer.setInterval(1000.0/value);
1476}
1477void UIConnector::on_displayingSliceBox_valueChanged(int cSlice)
1478{
1479    updateSpinnerDisplay = false;
1480    currentSliceHasChanged(cSlice);
1481    updateSpinnerDisplay = true;
1482    GLWindow->whichSlice = cSlice;
1483    GLWindow->updateGL();
1484}
1485void UIConnector::currentEventHasChanged(int )
1486{
1487
1488    RMS_window->SetData(GLWindow->RMSvalues);
1489    Mean_window->SetData(GLWindow->Meanvalues);
1490    PosOfMax_window->SetData(GLWindow->PosOfMaxvalues);
1491    Max_window->SetData(GLWindow->Maxvalues);
1492    threeD_Window->setData(GLWindow->eventData);//rawEventData);
1493
1494    if (RMS_window->isVisible())
1495        RMS_window->updateGL();
1496    if (Mean_window->isVisible())
1497        Mean_window->updateGL();
1498    if (PosOfMax_window->isVisible())
1499        PosOfMax_window->updateGL();
1500    if (Max_window->isVisible())
1501        Max_window->updateGL();
1502    ostringstream str;
1503//    str << "Displaying Event " << cEvent;
1504//    QString qstr(str.str().c_str());
1505//    emit updateCurrentEventDisplay(qstr);
1506    if (updateSpinnerDisplay)
1507    {
1508        updateSpinnerDisplay = false;
1509        displayingEventBox->setValue(GLWindow->rowNum);
1510        updateSpinnerDisplay = true;
1511    }
1512
1513 //   GLWindow->doWaveLetOnCurrentEventPlease();
1514
1515        //retrieve the data that we want to display
1516    boost::posix_time::ptime hrTime( boost::gregorian::date(1970, boost::gregorian::Jan, 1),
1517            boost::posix_time::seconds(GLWindow->pcTime[0]) +  boost::posix_time::microsec(GLWindow->pcTime[1]));
1518
1519    str.str("");
1520    str << "PC Time: " << boost::posix_time::to_iso_extended_string(hrTime);
1521    PCTimeLabel->setText(QString(str.str().c_str()));
1522
1523    str.str("");
1524    str << "Software Trigger: " << GLWindow->softTrig;
1525    softwareTriggerLabel->setText(QString(str.str().c_str()));
1526
1527    str.str("");
1528    str << "Trigger Type: " << GLWindow->triggerType;
1529    triggerTypeLabel->setText(QString(str.str().c_str()));
1530
1531    displaySliceValue();
1532
1533    if (autoScaleColor->isChecked())
1534        emit GLWindow->colorPaletteHasChanged();//autoScalePressed();
1535
1536    boardsTimeList->clear();
1537    startPixelsList->clear();
1538    startTimeMarksList->clear();
1539    triggerDelayList->clear();
1540    std::map<int, int> boardsHistoMap;
1541    for (int i=0;i <NBOARDS; i++)
1542    {
1543        str.str("");
1544        str << i;
1545        if (i<10) str << " ";
1546        if (i<100) str << " ";
1547        if (i<1000) str << " ";
1548        str << ": " << GLWindow->boardTime[i];
1549        boardsTimeList->addItem(QString(str.str().c_str()));
1550        if (boardsHistoMap.find(GLWindow->boardTime[i]) != boardsHistoMap.end())
1551            boardsHistoMap[GLWindow->boardTime[i]]++;
1552        else
1553            boardsHistoMap[GLWindow->boardTime[i]] = 1;
1554    }
1555    std::map<int, int> pixelHistoMap;
1556    for (int i=0;i <NPIX; i++)
1557    {
1558        str.str("");
1559        str << i;
1560        if (i<10) str << " ";
1561        if (i<100) str << " ";
1562        if (i<1000) str << " ";
1563        str << ": " << GLWindow->startPix[i];
1564        startPixelsList->addItem(QString(str.str().c_str()));
1565        if (pixelHistoMap.find(GLWindow->startPix[i]) != pixelHistoMap.end())
1566            pixelHistoMap[GLWindow->startPix[i]]++;
1567        else
1568            pixelHistoMap[GLWindow->startPix[i]] = 1;
1569    }
1570
1571    std::map<int, int> timeMarksMap;
1572    for (int i=0;i <NTMARK; i++)
1573    {
1574        str.str("");
1575        str << i;
1576        if (i<10) str << " ";
1577        if (i<100) str << " ";
1578        if (i<1000) str << " ";
1579        str << ": " << GLWindow->startTM[i];
1580        startTimeMarksList->addItem(QString(str.str().c_str()));
1581        if (timeMarksMap.find(GLWindow->startTM[i]) != timeMarksMap.end())
1582            timeMarksMap[GLWindow->startTM[i]]++;
1583        else
1584            timeMarksMap[GLWindow->startTM[i]] = 1;
1585    }
1586    std::map<int,int> delayMap;
1587    triggerDelayList->addItem(QString("Patch | Slice:Delay Slice:Delay..."));
1588    for (int i=0;i<NTMARK; i++)
1589    {
1590        str.str("");
1591        str << i << " | ";
1592        for (int j=0;j<GLWindow->nRoi;j++)
1593        {
1594            int value = GLWindow->eventData[1440*GLWindow->nRoi + i*GLWindow->nRoi + j];
1595            if (delayMap.find(value) != delayMap.end())
1596                 delayMap[value]++;
1597             else
1598                 delayMap[value] = 1;
1599            str << j << ":" << value << " ";
1600         }
1601        triggerDelayList->addItem(QString(str.str().c_str()));
1602    }
1603
1604    std::map<int,int>::iterator it = boardsHistoMap.begin();
1605    int nsamples = 0;
1606    int previousValue = it->first-10;
1607    for (unsigned int i=0;i<boardsHistoMap.size();i++)
1608    {
1609        if (previousValue != it->first-1)
1610        {
1611            xval[nsamples] = previousValue+1;
1612            yval[nsamples] = 0;
1613            nsamples++;
1614            xval[nsamples] = it->first-1;
1615            yval[nsamples] = 0;
1616            nsamples++;
1617        }
1618        xval[nsamples] = it->first;
1619        yval[nsamples] = it->second;
1620        previousValue = it->first;
1621        it++;
1622        nsamples++;
1623        xval[nsamples] = previousValue;
1624        yval[nsamples] = 0;
1625        nsamples++;
1626        if (nsamples > 4090)
1627        {
1628            cout << "Error: Maximum number of samples reached for histograms. skipping what's remaining" << endl;
1629            break;
1630        }
1631    }
1632    xval[nsamples] = it==boardsHistoMap.begin() ? 0 : (--it)->first+1;
1633    yval[nsamples] = 0;
1634    nsamples++;
1635 //   if (nsamples > 5)
1636#if QWT_VERSION < 0x060000
1637       boardsTimeHistoItem.setData(xval, yval, nsamples);
1638#else
1639       boardsTimeHistoItem.setSamples(xval, yval, nsamples);
1640#endif
1641
1642    it = pixelHistoMap.begin();
1643    nsamples = 0;
1644    previousValue = it->first-10;
1645    for (unsigned int i=0;i<pixelHistoMap.size();i++)
1646    {
1647        if (previousValue != it->first-1)
1648        {
1649            xval[nsamples] = previousValue+1;
1650            yval[nsamples] = 0;
1651            nsamples++;
1652            xval[nsamples] = it->first-1;
1653            yval[nsamples] = 0;
1654            nsamples++;
1655        }
1656        xval[nsamples] = it->first;
1657        yval[nsamples] = it->second;
1658        previousValue = it->first;
1659        it++;
1660        nsamples++;
1661        xval[nsamples] = previousValue;
1662        yval[nsamples] = 0;
1663        nsamples++;
1664        if (nsamples > 4090)
1665        {
1666            cout << "Error: Maximum number of samples reached for histograms. skipping what's remaining" << endl;
1667            break;
1668        }
1669   }
1670    xval[nsamples] = it==pixelHistoMap.begin() ? 0 : (--it)->first+1;
1671    yval[nsamples] = 0;
1672    nsamples++;
1673//    if (nsamples > 5)
1674#if QWT_VERSION < 0x060000
1675       startCellHistoItem.setData(xval, yval, nsamples);
1676#else
1677       startCellHistoItem.setSamples(xval, yval, nsamples);
1678#endif
1679
1680    it = timeMarksMap.begin();
1681    nsamples = 0;
1682    previousValue = it->first-10;
1683    for (unsigned int i=0;i<timeMarksMap.size();i++)
1684    {
1685        if (previousValue != it->first-1)
1686        {
1687            xval[nsamples] = previousValue+1;
1688            yval[nsamples] = 0;
1689            nsamples++;
1690            xval[nsamples] = it->first-1;
1691            yval[nsamples] = 0;
1692            nsamples++;
1693        }
1694        xval[nsamples] = it->first;
1695        yval[nsamples] = it->second;
1696        previousValue = it->first;
1697        it++;
1698        nsamples++;
1699        xval[nsamples] = previousValue;
1700        yval[nsamples] = 0;
1701        nsamples++;
1702        if (nsamples > 4090)
1703        {
1704            cout << "Error: Maximum number of samples reached for histograms. skipping what's remaining" << endl;
1705            break;
1706        }
1707    }
1708    xval[nsamples] = it==timeMarksMap.begin() ? 0 : (--it)->first+1;
1709    yval[nsamples] = 0;
1710    nsamples++;
1711 //   if (nsamples > 5)
1712#if QWT_VERSION < 0x060000
1713       startTimeMarkHistoItem.setData(xval, yval, nsamples);
1714#else
1715       startTimeMarkHistoItem.setSamples(xval, yval, nsamples);
1716#endif
1717
1718    it = delayMap.begin();
1719    nsamples = 0;
1720    previousValue = it->first-10;
1721    for (unsigned int i=0;i<delayMap.size();i++)
1722    {
1723        if (previousValue != it->first-1)
1724        {
1725            xval[nsamples] = previousValue+1;
1726            yval[nsamples] = 0;
1727            nsamples++;
1728            xval[nsamples] = it->first-1;
1729            yval[nsamples] = 0;
1730            nsamples++;
1731        }
1732        xval[nsamples] = it->first;
1733        yval[nsamples] = it->second;
1734        previousValue = it->first;
1735        it++;
1736        nsamples++;
1737        xval[nsamples] = previousValue;
1738        yval[nsamples] = 0;
1739        nsamples++;
1740        if (nsamples > 4090)
1741        {
1742            cout << "Error: Maximum number of samples reached for histograms. skipping what's remaining" << endl;
1743            break;
1744        }
1745    }
1746    xval[nsamples] = it==delayMap.begin() ? 0 : (--it)->first+1;
1747    yval[nsamples] = 0;
1748    nsamples++;
1749  //  if (nsamples > 5)
1750#if QWT_VERSION < 0x060000
1751       triggerDelayHistoItem.setData(xval, yval, nsamples);
1752#else
1753       triggerDelayHistoItem.setSamples(xval, yval, nsamples);
1754#endif
1755       //WAVELETS HACK
1756/*       std::map<int, int> valuesHistoMap;
1757       std::map<int, int> waveletHistoMap;
1758       for (int i=0;i<1024*1440;i++)
1759       {
1760           if (valuesHistoMap.find(GLWindow->rawEventData[i]) != valuesHistoMap.end())
1761               valuesHistoMap[GLWindow->rawEventData[i]]++;
1762           else
1763               valuesHistoMap[GLWindow->rawEventData[i]] = 1;
1764           if (waveletHistoMap.find(GLWindow->waveLetArray[i]) != waveletHistoMap.end())
1765               waveletHistoMap[GLWindow->waveLetArray[i]]++;
1766           else
1767               waveletHistoMap[GLWindow->waveLetArray[i]] = 1;
1768       }
1769
1770       it = valuesHistoMap.begin();
1771       nsamples = 0;
1772       previousValue = it->first-10;
1773       cout << "Num values Original: " << valuesHistoMap.size() << endl;
1774       for (unsigned int i=0;i<valuesHistoMap.size();i++)
1775       {
1776           if (previousValue != it->first-1)
1777           {
1778               xval[nsamples] = previousValue+1;
1779               yval[nsamples] = 0;
1780               nsamples++;
1781               xval[nsamples] = it->first-1;
1782               yval[nsamples] = 0;
1783               nsamples++;
1784           }
1785           xval[nsamples] = it->first;
1786           yval[nsamples] = it->second;
1787           previousValue = it->first;
1788           it++;
1789           nsamples++;
1790           xval[nsamples] = previousValue;
1791           yval[nsamples] = 0;
1792           nsamples++;
1793           if (nsamples > 50000)
1794           {
1795               cout << "Error: Maximum number of samples reached for histograms. skipping what's remaining" << endl;
1796               break;
1797           }
1798       }
1799       xval[nsamples] = it==valuesHistoMap.begin() ? 0 : (--it)->first+1;
1800       yval[nsamples] = 0;
1801       nsamples++;
1802     //  if (nsamples > 5)
1803   #if QWT_VERSION < 0x060000
1804          triggerDelayHistoItem.setData(xval, yval, nsamples);
1805   #else
1806          triggerDelayHistoItem.setSamples(xval, yval, nsamples);
1807   #endif
1808
1809          it = waveletHistoMap.begin();
1810          nsamples = 0;
1811          previousValue = it->first-10;
1812          cout << "Num values WaveLets: " << waveletHistoMap.size() << endl;
1813          for (unsigned int i=0;i<waveletHistoMap.size();i++)
1814          {
1815              if (previousValue != it->first-1)
1816              {
1817                  xval[nsamples] = previousValue+1;
1818                  yval[nsamples] = 0;
1819                  nsamples++;
1820                  xval[nsamples] = it->first-1;
1821                  yval[nsamples] = 0;
1822                  nsamples++;
1823              }
1824              xval[nsamples] = it->first;
1825              yval[nsamples] = it->second;
1826              previousValue = it->first;
1827              it++;
1828              nsamples++;
1829              xval[nsamples] = previousValue;
1830              yval[nsamples] = 0;
1831              nsamples++;
1832              if (nsamples > 50000)
1833              {
1834                  cout << "Error: Maximum number of samples reached for histograms. skipping what's remaining" << endl;
1835                  break;
1836              }
1837          }
1838          xval[nsamples] = it==waveletHistoMap.begin() ? 0 : (--it)->first+1;
1839          yval[nsamples] = 0;
1840          nsamples++;
1841        //  if (nsamples > 5)
1842      #if QWT_VERSION < 0x060000
1843          startTimeMarkHistoItem.setData(xval, yval, nsamples);
1844      #else
1845          startTimeMarkHistoItem.setSamples(xval, yval, nsamples);
1846      #endif
1847*/
1848//END OF WAVELETS HACK
1849       //    startCellHistoZoom->setZoomBase(startCellHistoItem.boundingRect());
1850    QStack< QRectF > stack;
1851//    QRectF cRectangle = boardsTimeHistoItem.boundingRect();
1852    stack.push(scaleBoundingRectangle(boardsTimeHistoItem.boundingRect(), 1.05f));//cRectangle);//boardsTimeHistoItem.boundingRect());
1853    boardsTimeHistoZoom->setZoomStack(stack);
1854    stack.pop();
1855    stack.push(scaleBoundingRectangle(startCellHistoItem.boundingRect(), 1.05f));
1856    startCellHistoZoom->setZoomStack(stack);
1857    stack.pop();
1858    stack.push(scaleBoundingRectangle(startTimeMarkHistoItem.boundingRect(), 1.05f));
1859    startTimeMarkHistoZoom->setZoomStack(stack);
1860    stack.pop();
1861    stack.push(scaleBoundingRectangle(triggerDelayHistoItem.boundingRect(), 1.05f));
1862    triggerDelayHistoZoom->setZoomStack(stack);
1863    stack.pop();
1864
1865    pixelChanged(GLWindow->selectedPixel);
1866}
1867//can't use a ref to rectangle, as the type must be converted first
1868QRectF UIConnector::scaleBoundingRectangle(QRectF rectangle, float scale)
1869{
1870    QPointF bottomRight = rectangle.bottomRight();
1871    QPointF topLeft = rectangle.topLeft();
1872    QPointF center = rectangle.center();
1873    return QRectF(topLeft + (topLeft-center)*(scale-1.0f), //top left
1874                  bottomRight + (bottomRight-center)*(scale-1.0f)); //bottom right
1875}
1876void UIConnector::initHistograms()
1877{
1878//    QwtPlot*     boardsTimeHisto;
1879//    QwtPlotHistogram boardsTimeHistoItem;
1880    grid1 = new QwtPlotGrid;
1881    grid1->enableX(false);
1882    grid1->enableY(true);
1883    grid1->enableXMin(false);
1884    grid1->enableYMin(false);
1885    grid1->setMajPen(QPen(Qt::black, 0, Qt::DotLine));
1886    grid1->attach(boardsTimeHisto);
1887
1888    grid2 = new QwtPlotGrid;
1889    grid2->enableX(false);
1890    grid2->enableY(true);
1891    grid2->enableXMin(false);
1892    grid2->enableYMin(false);
1893    grid2->setMajPen(QPen(Qt::black, 0, Qt::DotLine));
1894    grid2->attach(startCellsHisto);
1895
1896    grid3 = new QwtPlotGrid;
1897    grid3->enableX(false);
1898    grid3->enableY(true);
1899    grid3->enableXMin(false);
1900    grid3->enableYMin(false);
1901    grid3->setMajPen(QPen(Qt::black, 0, Qt::DotLine));
1902    grid3->attach(startTimeMarkHisto);
1903
1904    grid4 = new QwtPlotGrid;
1905    grid4->enableX(false);
1906    grid4->enableY(true);
1907    grid4->enableXMin(false);
1908    grid4->enableYMin(false);
1909    grid4->setMajPen(QPen(Qt::black, 0, Qt::DotLine));
1910    grid4->attach(pixelValueCurve);
1911
1912    grid6 = new QwtPlotGrid;
1913    grid6->enableX(false);
1914    grid6->enableY(true);
1915    grid6->enableXMin(false);
1916    grid6->enableYMin(false);
1917    grid6->setMajPen(QPen(Qt::black, 0, Qt::DotLine));
1918    grid6->attach(pixelAverageCurve);
1919
1920    grid5 = new QwtPlotGrid;
1921    grid5->enableX(false);
1922    grid5->enableY(true);
1923    grid5->enableXMin(false);
1924    grid5->enableYMin(false);
1925    grid5->setMajPen(QPen(Qt::black, 0, Qt::DotLine));
1926    grid5->attach(triggerDelayHisto);
1927
1928    boardsTimeHisto->setAutoReplot(true);
1929    startCellsHisto->setAutoReplot(true);
1930    startTimeMarkHisto->setAutoReplot(true);
1931    pixelValueCurve->setAutoReplot(true);
1932    pixelAverageCurve->setAutoReplot(true);
1933    triggerDelayHisto->setAutoReplot(true);
1934    boardsTimeHisto->setTitle("Boards time values");
1935    startCellsHisto->setTitle("Start Cell values");
1936    startTimeMarkHisto->setTitle("Start Time Marks values");
1937    pixelValueCurve->setTitle("Current pixel values");
1938    pixelAverageCurve->setTitle("Average pixels values");
1939    triggerDelayHisto->setTitle("Trigger Delays");
1940
1941 //   boardsTimeHistoItem.setBrush(QBrush(Qt::red));
1942//    startCellHistoItem.setBrush(QBrush(Qt::red));
1943//    startTimeMarkHistoItem.setBrush(QBrush(Qt::red));
1944//    triggerDelayHistoItem.setBrush(QBrush(Qt::red));
1945//    pixelValueCurveItem.setBrush(QBrush(Qt::red));
1946
1947    boardsTimeHistoItem.setPen(QColor(Qt::darkGreen));
1948    boardsTimeHistoItem.setStyle(QwtPlotCurve::Steps);
1949    startCellHistoItem.setPen(QColor(Qt::darkGreen));
1950    startCellHistoItem.setStyle(QwtPlotCurve::Steps);
1951    startTimeMarkHistoItem.setPen(QColor(Qt::darkGreen));
1952    startTimeMarkHistoItem.setStyle(QwtPlotCurve::Steps);
1953    triggerDelayHistoItem.setPen(QColor(Qt::darkGreen));
1954    triggerDelayHistoItem.setStyle(QwtPlotCurve::Steps);
1955
1956    boardsTimeHistoItem.attach(boardsTimeHisto);
1957    startCellHistoItem.attach(startCellsHisto);
1958    startTimeMarkHistoItem.attach(startTimeMarkHisto);
1959    triggerDelayHistoItem.attach(triggerDelayHisto);
1960
1961    //curve
1962//    pixelValueCurveItem.setSymbol(new QwtSymbol(QwtSymbol::Cross, Qt::NoBrush, QPen(Qt::black), QSize(5,5)));
1963    pixelValueCurveItem.setPen(QColor(Qt::black));
1964    pixelAverageCurveItem.setPen(QColor(Qt::black));
1965    aMeanCurveItem.setPen(QColor(Qt::darkGreen));
1966    vCorrCurveItem.setPen(QColor(Qt::red));
1967    meanCurveItem.setPen(QColor(Qt::blue));
1968    pixelValueCurveItem.setStyle(QwtPlotCurve::Lines);
1969    pixelAverageCurveItem.setStyle(QwtPlotCurve::Lines);
1970    aMeanCurveItem.setStyle(QwtPlotCurve::Lines);
1971    vCorrCurveItem.setStyle(QwtPlotCurve::Lines);
1972    meanCurveItem.setStyle(QwtPlotCurve::Lines);
1973
1974//    pixelValueCurveItem.setCurveAttribute(QwtPlotCurve::Fitted);
1975    pixelValueCurveItem.attach(pixelValueCurve);
1976    pixelAverageCurveItem.attach(pixelAverageCurve);
1977//    aMeanCurveItem.attach(pixelValueCurve);
1978 //   vCorrCurveItem.attach(pixelValueCurve);
1979//    meanCurveItem.attach(pixelValueCurve);
1980
1981    //FIXME delete these pointers with the destructor
1982    curveZoom = new QwtPlotZoomer(pixelValueCurve->canvas());
1983    curveZoom->setRubberBandPen(QPen(Qt::gray, 2, Qt::DotLine));
1984    curveZoom->setTrackerPen(QPen(Qt::gray));
1985    averageCurveZoom = new QwtPlotZoomer(pixelAverageCurve->canvas());
1986    averageCurveZoom->setRubberBandPen(QPen(Qt::gray, 2, Qt::DotLine));
1987    averageCurveZoom->setTrackerPen(QPen(Qt::gray));
1988
1989    boardsTimeHistoZoom = new QwtPlotZoomer(boardsTimeHisto->canvas());
1990    boardsTimeHistoZoom->setRubberBandPen(QPen(Qt::gray, 2, Qt::DotLine));
1991    boardsTimeHistoZoom->setTrackerPen(QPen(Qt::gray));
1992
1993    startCellHistoZoom = new QwtPlotZoomer(startCellsHisto->canvas());
1994    startCellHistoZoom->setRubberBandPen(QPen(Qt::gray, 2, Qt::DotLine));
1995    startCellHistoZoom->setTrackerPen(QPen(Qt::gray));
1996
1997    startTimeMarkHistoZoom = new QwtPlotZoomer(startTimeMarkHisto->canvas());
1998    startTimeMarkHistoZoom->setRubberBandPen(QPen(Qt::gray, 2, Qt::DotLine));
1999    startTimeMarkHistoZoom->setTrackerPen(QPen(Qt::gray));
2000
2001    triggerDelayHistoZoom = new QwtPlotZoomer(triggerDelayHisto->canvas());
2002    triggerDelayHistoZoom->setRubberBandPen(QPen(Qt::gray, 2, Qt::DotLine));
2003    triggerDelayHistoZoom->setTrackerPen(QPen(Qt::gray));
2004
2005
2006}
2007
2008void UIConnector::pixelChanged(int pixel)
2009{
2010    RMS_window->fWhite = pixel;
2011    Mean_window->fWhite = pixel;
2012    Max_window->fWhite = pixel;
2013    PosOfMax_window->fWhite = pixel;
2014    if (pixel != -1)
2015    {
2016        RMS_window->fWhitePatch = RMS_window->pixelsPatch[pixel];
2017        Mean_window->fWhitePatch = Mean_window->pixelsPatch[pixel];
2018        Max_window->fWhitePatch = Max_window->pixelsPatch[pixel];
2019        PosOfMax_window->fWhitePatch = PosOfMax_window->pixelsPatch[pixel];
2020    }
2021    else
2022    {
2023        RMS_window->fWhitePatch = -1;
2024        Mean_window->fWhitePatch = -1;
2025        Max_window->fWhitePatch = -1;
2026        PosOfMax_window->fWhitePatch = -1;
2027    }
2028    if (pixel == -1)
2029        return;
2030    int softwarePix = pixel;
2031//    if (!GLWindow->_softwareOrdering)
2032        pixel = GLWindow->hardwareMapping[pixel];
2033
2034    HwIDBox->setValue(pixel);
2035
2036    if (!GLWindow->nRoi)
2037        return;
2038
2039int currentPixel = pixel;
2040
2041    for (int i=0;i<GLWindow->nRoi;i++)
2042    {
2043        xval[i] = i;
2044        yval[i] = GLWindow->eventData[GLWindow->nRoi*currentPixel + i];
2045    }
2046
2047
2048int realNumSamples = GLWindow->nRoi;
2049    if (GLWindow->nRoiTM != 0)
2050    {
2051        const PixelMapEntry& mapEntry = GLWindow->fPixelMap.index(softwarePix);
2052        const int pixelIdInPatch = mapEntry.pixel();
2053        const int patchId = mapEntry.patch();
2054        const int boardId = mapEntry.board();
2055        const int crateId = mapEntry.crate();
2056        if (pixelIdInPatch == 8)
2057        {
2058            int TMIndex = 0;
2059            int xIndex = GLWindow->nRoi;
2060            int arrayIndex = GLWindow->nRoi;
2061            if (GLWindow->offSetRoi < 0)
2062                TMIndex -= GLWindow->offSetRoi;
2063            if (GLWindow->offSetRoi > 0)
2064                xIndex += GLWindow->offSetRoi;
2065            for (int i=TMIndex;i<GLWindow->nRoiTM;i++, xIndex++, arrayIndex++)
2066            {
2067                xval[arrayIndex] = xIndex;
2068                yval[arrayIndex] = GLWindow->eventData[GLWindow->nRoi*1440 + GLWindow->nRoiTM*(40*crateId + 4*boardId + patchId) + i];
2069            }
2070            realNumSamples += GLWindow->nRoiTM - TMIndex;
2071        }
2072      //  cout << pixelIdInPatch << " " ;
2073    }
2074
2075#if QWT_VERSION < 0x060000
2076    pixelValueCurveItem.setData(xval, yval, realNumSamples);
2077#else
2078       pixelValueCurveItem.setSamples(xval, yval, realNumSamples);
2079#endif
2080
2081//now compute the average value of all pixels
2082       currentPixel = 0;
2083       for (int i=0;i<GLWindow->nRoi;i++)
2084           yval[i] = 0;
2085       for (int j=0;j<1440;j++) {
2086           currentPixel = j;
2087           for (int i=0;i<GLWindow->nRoi;i++)
2088           {
2089               xval[i] = i;
2090               yval[i] += GLWindow->eventData[GLWindow->nRoi*currentPixel + i];
2091           }
2092       }
2093       for (int i=0;i<GLWindow->nRoi;i++)
2094           yval[i] /= 1440;
2095#if QWT_VERSION < 0x060000
2096       pixelAverageCurveItem.setData(xval, yval, GLWindow->nRoi);
2097#else
2098    pixelAverageCurveItem.setSamples(xval, yval, realNumSamples);
2099#endif
2100
2101    QStack< QRectF > stack;
2102    stack.push(scaleBoundingRectangle(pixelValueCurveItem.boundingRect(), 1.5f));
2103    curveZoom->setZoomBase(scaleBoundingRectangle(pixelValueCurveItem.boundingRect(), 1.5f));
2104    curveZoom->setZoomStack(stack);
2105    stack.pop();
2106    stack.push(scaleBoundingRectangle(pixelAverageCurveItem.boundingRect(), 1.5f));
2107    averageCurveZoom->setZoomBase(scaleBoundingRectangle(pixelAverageCurveItem.boundingRect(), 1.5f));
2108    averageCurveZoom->setZoomStack(stack);
2109    stack.pop();
2110
2111    displaySliceValue();
2112    on_autoScaleColor_clicked();
2113}
2114
2115void UIConnector::on_HwIDBox_valueChanged(int)
2116{
2117    updating = true;
2118
2119    const int hwID = HwIDBox->value();
2120
2121    const int crateID =  hwID/360;
2122    const int boardID = (hwID%360)/36;
2123    const int patchID = (hwID%36 )/9;
2124    const int pixelID =  hwID%9;
2125
2126    SwIDBox->setValue(GLWindow->softwareMapping[hwID]);
2127
2128    crateIDBox->setValue(crateID);
2129    boardIDBox->setValue(boardID);
2130    patchIDBox->setValue(patchID);
2131    pixelIDBox->setValue(pixelID);
2132
2133    updating = false;
2134
2135    GLWindow->selectedPixel = GLWindow->softwareMapping[hwID];
2136    GLWindow->updateGL();
2137
2138    pixelChanged(GLWindow->selectedPixel);
2139}
2140
2141void UIConnector::cbpxChanged()
2142{
2143    if (updating)
2144        return;
2145
2146    const int hwid = crateIDBox->value()*360 + boardIDBox->value()*36 + patchIDBox->value()*9 + pixelIDBox->value();
2147    HwIDBox->setValue(hwid);
2148}
2149
2150void UIConnector::on_SwIDBox_valueChanged(int swid)
2151{
2152    if (updating)
2153        return;
2154
2155//    if (GLWindow->_softwareOrdering)
2156//        HwIDBox->setValue(swid);
2157//    else
2158        HwIDBox->setValue(GLWindow->hardwareMapping[swid]);
2159}
2160
2161void UIConnector::on_autoScaleColor_clicked()
2162{
2163    if (!autoScaleColor->isChecked())
2164    {
2165        GLWindow->ss[0] = 0.496;
2166        GLWindow->ss[1] = 0.507;
2167        GLWindow->ss[2] = 0.518;
2168        GLWindow->ss[3] = 0.529;
2169        GLWindow->ss[4] = 0.540;;
2170        colorRange0->setValue(GLWindow->ss[0]);
2171        colorRange1->setValue(GLWindow->ss[1]);
2172        colorRange2->setValue(GLWindow->ss[2]);
2173        colorRange3->setValue(GLWindow->ss[3]);
2174        colorRange4->setValue(GLWindow->ss[4]);
2175        return;
2176    }
2177    if (!GLWindow->nRoi)
2178        return;
2179
2180    int start = 0;
2181    int end   = 1440;
2182
2183    if (!entireCameraScale->isChecked())
2184    {
2185        start = GLWindow->selectedPixel;
2186        end   = GLWindow->selectedPixel+1;
2187        if (end == 0)
2188        {
2189            start = 0;
2190            end = 1440;
2191        }
2192    }
2193
2194    int min =  100000; //real min = -2048, int_16 = -32768 to 32767
2195    int max = -100000; //real max = 2047
2196
2197    long average = 0;
2198    long numSamples = 0;
2199    int errorDetected = -1;
2200
2201    for (int i=start;i<end;i++)
2202    {
2203        if (i==863)//keep crazy pixel out of the autoscale
2204            continue;
2205        for (int j=10;j<GLWindow->nRoi-50;j++)
2206        {
2207            int cValue = GLWindow->eventData[i*GLWindow->nRoi+j];
2208            if (cValue > max && cValue < 32767)
2209                max = cValue;
2210            if (cValue < min && cValue > -32768)
2211               min = cValue;
2212            if (cValue < 32767 && cValue > -32768)
2213            {
2214                average+=cValue;
2215                numSamples++;
2216            }
2217            else
2218            {
2219                errorDetected = i;
2220            }
2221//            numSamples++;
2222        }
2223    }
2224    average /= numSamples;
2225    if (errorDetected != -1)
2226    {
2227        cout << "Overflow detected at pixel " << errorDetected << " (at least)" << endl;
2228    }
2229//    cout << "min: " << min << " max: " << max << " average: " << average << endl;
2230    float minRange = (float)(min+(GLWindow->VALUES_SPAN/2))/(float)(GLWindow->VALUES_SPAN-1);
2231    float maxRange = (float)(max+(GLWindow->VALUES_SPAN/2))/(float)(GLWindow->VALUES_SPAN-1);
2232    float midRange = (float)(average+(GLWindow->VALUES_SPAN/2))/(float)(GLWindow->VALUES_SPAN-1);
2233    if (GLWindow->logScale)
2234    {
2235        minRange *= 9;
2236        maxRange *= 9;
2237//        midRange *= 9;
2238        minRange += 1;
2239        maxRange += 1;
2240//        midRange += 1;
2241        minRange = log10(minRange);
2242        maxRange = log10(maxRange);
2243//        midRange = (minRange + maxRange)/2.f;
2244        midRange = log10(midRange);
2245    }
2246
2247    GLWindow->ss[0] = minRange;
2248    colorRange0->setValue(GLWindow->ss[0]);
2249    GLWindow->ss[4] = maxRange;
2250    colorRange4->setValue(GLWindow->ss[4]);
2251//    GLWindow->ss[2] = midRange;
2252//    range2->setValue(GLWindow->ss[2]);
2253//    GLWindow->ss[1] = (minRange+midRange)/2;
2254//    range1->setValue(GLWindow->ss[1]);
2255//    GLWindow->ss[3] = (maxRange+midRange)/2;
2256//    range3->setValue(GLWindow->ss[3]);
2257
2258    GLWindow->ss[2] = (maxRange+minRange)/2;
2259    colorRange2->setValue(GLWindow->ss[2]);
2260
2261    GLWindow->ss[1] = minRange+(maxRange-minRange)/4;
2262    colorRange1->setValue(GLWindow->ss[1]);
2263
2264    GLWindow->ss[3] = minRange+3*(maxRange-minRange)/4;
2265    colorRange3->setValue(GLWindow->ss[3]);
2266}
2267
2268void PrintUsage()
2269{
2270    cout << "\n"
2271        "The FACT++ raw data viewer.\n"
2272        "\n"
2273        "Usage: viewer [OPTIONS] [datafile.fits[.gz|.fz] [calibration.drs.fits[.gz]]]\n"
2274        "  or:  viewer [OPTIONS]\n";
2275    cout << endl;
2276
2277}
2278
2279void PrintHelp()
2280{
2281    cout <<
2282            "\n"
2283         << endl;
2284}
2285
2286int UIConnector::SetupConfiguration(Configuration &conf)
2287{
2288    RawDataViewer *canvas = GLWindow;
2289
2290    if (conf.Has("mappingFile"))
2291    {
2292        canvas->assignPixelMapFile(conf.Get<string>("mappingFile"));
2293    }
2294    else
2295        canvas->assignPixelMapFile("");
2296
2297    if (!canvas->isFACT())
2298    {
2299        HwIDBox->setMaximum(71);
2300        SwIDBox->setMaximum(71);
2301        SwIDBox->setValue(0);
2302        HwIDBox->setValue(19);
2303        crateIDBox->setMaximum(0);
2304        crateIDBox->setEnabled(false);
2305        boardIDBox->setMaximum(1);
2306    }
2307
2308    if (conf.Has("color.range"))
2309    {
2310        vector<double> value = conf.Vec<double>("color.range");
2311        if (value.size() != 5)
2312        {
2313            cout << "Error, colorRange option should have exactly 5 double values" << endl;
2314            return -1;
2315        }
2316        for (int i=0;i<5;i++)
2317            canvas->ss[i] = value[i];
2318    }
2319
2320    if (conf.Has("color.red"))
2321    {
2322        vector<double> value = conf.Vec<double>("color.red");
2323        if (value.size() != 5)
2324        {
2325            cout << "Error, colorRed option should have exactly 5 double values" << endl;
2326            return -1;
2327        }
2328        for (int i=0;i<5;i++)
2329            canvas->rr[i] = value[i];
2330    }
2331
2332    if (conf.Has("color.green"))
2333    {
2334        vector<double> value = conf.Vec<double>("color.green");
2335        if (value.size() != 5)
2336        {
2337            cout << "Error, colorGreen option should have exactly 5 double values" << endl;
2338            return -1;
2339        }
2340        for (int i=0;i<5;i++)
2341            canvas->gg[i] = value[i];
2342    }
2343
2344    if (conf.Has("color.blue"))
2345    {
2346        vector<double> value = conf.Vec<double>("color.blue");
2347        if (value.size() != 5)
2348        {
2349            cout << "Error, colorBlue option should have exactly 5 double values" << endl;
2350            return -1;
2351        }
2352        for (int i=0;i<5;i++)
2353            canvas->bb[i] = value[i];
2354    }
2355
2356    colorRange0->setValue(canvas->ss[0]);
2357    colorRange1->setValue(canvas->ss[1]);
2358    colorRange2->setValue(canvas->ss[2]);
2359    colorRange3->setValue(canvas->ss[3]);
2360    colorRange4->setValue(canvas->ss[4]);
2361    redValue0->setValue(canvas->rr[0]);
2362    redValue1->setValue(canvas->rr[1]);
2363    redValue2->setValue(canvas->rr[2]);
2364    redValue3->setValue(canvas->rr[3]);
2365    redValue4->setValue(canvas->rr[4]);
2366    greenValue0->setValue(canvas->gg[0]);
2367    greenValue1->setValue(canvas->gg[1]);
2368    greenValue2->setValue(canvas->gg[2]);
2369    greenValue3->setValue(canvas->gg[3]);
2370    greenValue4->setValue(canvas->gg[4]);
2371    blueValue0->setValue(canvas->bb[0]);
2372    blueValue1->setValue(canvas->bb[1]);
2373    blueValue2->setValue(canvas->bb[2]);
2374    blueValue3->setValue(canvas->bb[3]);
2375    blueValue4->setValue(canvas->bb[4]);
2376
2377    if (conf.Has("drs"))
2378    {
2379        const QString qstr(conf.Get<string>("drs").c_str());
2380        calibFileSelected(qstr);
2381    }
2382
2383    if (conf.Has("file"))
2384    {
2385        const QString qstr(conf.Get<string>("file").c_str());
2386        fileSelected(qstr);
2387    }
2388
2389
2390    return 0;
2391}
2392
2393void SetupConfiguration(Configuration& conf)
2394{
2395    po::options_description configs("Raw Events Viewer Options");
2396    configs.add_options()
2397        ("color.range", vars<double>(), "Range of the display colours")
2398        ("color.red",   vars<double>(), "Range of red values")
2399        ("color.green", vars<double>(), "Range of green values")
2400        ("color.blue",  vars<double>(), "Range of blue values")
2401        ("file,f",      var<string>(),  "File to be loaded")
2402        ("drs,d",       var<string>(),  "DRS calibration file to be loaded")
2403        ("mappingFile", var<string>(),  "Which pixels mapping file to use")
2404        ;
2405    conf.AddOptions(configs);
2406
2407    po::positional_options_description p;
2408    p.add("file", 1); // The first positional options
2409    p.add("drs",  2); // The first positional options
2410    conf.SetArgumentPositions(p);
2411
2412}
2413
2414/************************************************************
2415 * MAIN PROGRAM FUNCTION.
2416 ************************************************************/
2417int main(int argc, const char *argv[])
2418{
2419    QApplication app(argc, const_cast<char**>(argv));
2420
2421    if (!QGLFormat::hasOpenGL()) {
2422        std::cerr << "This system has no OpenGL support" << std::endl;
2423        return 1;
2424    }
2425
2426    Configuration conf(argv[0]);
2427    conf.SetPrintUsage(PrintUsage);
2428    SetupConfiguration(conf);
2429    if (!conf.DoParse(argc, argv, PrintHelp))
2430        return 2;
2431
2432    UIConnector myUi;
2433    if (myUi.SetupConfiguration(conf)<0)
2434        return 3;
2435
2436    return app.exec();
2437}
2438
Note: See TracBrowser for help on using the repository browser.