Subversion Repositories f9daq

Rev

Rev 167 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "../include/sipmscan.h"
#include "../include/workstation.h"

#include <stdio.h>
#include <stdlib.h>

int retTemp;

// Additional functions -------------------------------------

// Display the currently selected histogram in the file list
void TGAppMainFrame::DisplayHistogram(char *histfile, int histtype, int opt)
{
   char histtime[256];
   char ctemp[512];

   if(DBGSIG)
      printf("DisplayHistogram(): Selected file: %s\n", histfile);

   TCanvas *gCanvas = analysisCanvas->GetCanvas();

   inroot = TFile::Open(histfile, "READ");

   TTree *header_data, *meas_data;
   inroot->GetObject("header_data", header_data);
   inroot->GetObject("meas_data", meas_data);

   // Reading the header
   header_data->SetBranchAddress("nrch", &evtheader.nrch);
   header_data->GetEntry(0);
   header_data->SetBranchAddress("timestamp", &evtheader.timestamp);
   header_data->GetEntry(0);
   header_data->SetBranchAddress("biasvolt", &evtheader.biasvolt);
   header_data->GetEntry(0);
   header_data->SetBranchAddress("xpos", &evtheader.xpos);
   header_data->GetEntry(0);
   header_data->SetBranchAddress("ypos", &evtheader.ypos);
   header_data->GetEntry(0);
   header_data->SetBranchAddress("zpos", &evtheader.zpos);
   header_data->GetEntry(0);
   header_data->SetBranchAddress("temperature", &evtheader.temperature);
   header_data->GetEntry(0);
   if( header_data->FindBranch("angle") )
   {
      header_data->SetBranchAddress("angle", &evtheader.angle);
      header_data->GetEntry(0);
   }
   header_data->SetBranchAddress("laserinfo", &evtheader.laserinfo);
   header_data->GetEntry(0);

   // Change timestamp to local time
   GetTime(evtheader.timestamp, histtime);

   // Displaying header information debug
   if(DBGSIG)
   {
      printf("DisplayHistogram(): Opened file header information:\n");
      printf("- Number of channels (ADC and TDC are considered as separate channels): %d\n", evtheader.nrch);
      printf("- Timestamp: %d (%s)\n", evtheader.timestamp, histtime);
      printf("- Bias voltage: %lf\n", evtheader.biasvolt);
      printf("- Table position (X,Y,Z): %d, %d, %d\n", evtheader.xpos, evtheader.ypos, evtheader.zpos);
      if(evtheader.temperature)
         printf("- Temperature: %lf\n", evtheader.temperature);
      if( header_data->FindBranch("angle") )
         printf("- Incidence angle: %lf\n", evtheader.angle);
      else
         printf("- Incidence angle: No angle information!\n");
      printf("- Laser and filter settings: %s\n", evtheader.laserinfo);
   }

   // Displaying header information on the GUI
   dispTime->widgetTE->SetText(histtime);
   dispBias->widgetNE[0]->SetNumber(evtheader.biasvolt);
   sprintf(ctemp, "%d, %d, %d", evtheader.xpos, evtheader.ypos, evtheader.zpos);
   dispPos->widgetTE->SetText(ctemp);
   if(evtheader.temperature)
      dispTemp->widgetNE[0]->SetNumber(evtheader.temperature);
   else
      dispTemp->widgetNE[0]->SetNumber(0.0);
   if( header_data->FindBranch("angle") )
      dispAngle->widgetNE[0]->SetNumber(evtheader.angle);
   else
      dispAngle->widgetNE[0]->SetNumber(0.0);
   dispLaser->widgetTE->SetText(evtheader.laserinfo);

   selectCh->widgetNE[0]->SetLimitValues(0, (evtheader.nrch/2)-1);

   // Redraw the histograms
   int j;
   char rdc[256];
   char rdcsel[256];

   j = selectCh->widgetNE[0]->GetNumber();

   printf("Found %d data points.\n", (int)meas_data->GetEntries());

   gCanvas->cd();
   double range[4];
   range[0] = adcRange->widgetNE[0]->GetNumber();
   range[1] = adcRange->widgetNE[1]->GetNumber();
   range[2] = tdcRange->widgetNE[0]->GetNumber();
   range[3] = tdcRange->widgetNE[1]->GetNumber();

   // ADC histogram
   if(histtype == 0)
   {
      if( range[0] == range[1] )
         sprintf(rdc, "ADC%d>>%s", j, histname);
      else
         sprintf(rdc, "ADC%d>>%s(%d,%lf,%lf)", j, histname, (int)(range[1]-range[0]), range[0]-0.5, range[1]-0.5);

      sprintf(rdcsel, "(TDC%d>%lf)&&(TDC%d<%lf)", j, range[2]*tdctimeconversion, j, range[3]*tdctimeconversion);
      meas_data->Draw(rdc, rdcsel);

      sprintf(rdc, "ADC%d, Vbias=%.3lf, TDC=(%.2lf,%.2lf);ADC;", j, evtheader.biasvolt, range[2], range[3]);
      TH1F *histtemp = (TH1F*)gCanvas->GetPrimitive(histname);
      if(!cleanPlots)
         histtemp->SetTitle(rdc);
      else
         histtemp->SetTitle(";ADC;");
      histtemp->GetXaxis()->SetLabelSize(0.025);
      histtemp->GetXaxis()->CenterTitle(kTRUE);
      histtemp->GetYaxis()->SetLabelSize(0.025);
      if(cleanPlots)
      {
         TGaxis *yax = (TGaxis*)histtemp->GetYaxis();
         yax->SetMaxDigits(4);
      }

      gCanvas->Modified();
      gCanvas->Update();

      if( yRange->widgetNE[0]->GetNumber() != yRange->widgetNE[1]->GetNumber() )
      {
         if( (histOpt->widgetChBox[0]->IsDown()) && (yRange->widgetNE[0]->GetNumber() <= 0) )
         {
            histtemp->GetYaxis()->SetRangeUser(0.5, yRange->widgetNE[1]->GetNumber());
            yRange->widgetNE[0]->SetNumber(0.5);
            logChange = 1;
         }
         else
         {
            gCanvas->SetLogy(kFALSE);
            if(logChange == 1)
            {
               yRange->widgetNE[0]->SetNumber(0.0);
               logChange = 0;
            }
            histtemp->GetYaxis()->SetRangeUser(yRange->widgetNE[0]->GetNumber(), yRange->widgetNE[1]->GetNumber());
         }
      }

      TPaveStats *stats = (TPaveStats*)histtemp->FindObject("stats");
      if(!cleanPlots)
      {
         stats->SetX1NDC(0.84); stats->SetX2NDC(0.97);
         stats->SetY1NDC(0.87); stats->SetY2NDC(0.97);
      }
      else
      {
         stats->SetX1NDC(1.1); stats->SetX2NDC(1.3);
         stats->SetY1NDC(1.1); stats->SetY2NDC(1.3);
      }
   }
   // TDC histogram
   else if(histtype == 1)
   {
      if( range[0] == range[1] )
         sprintf(rdc, "(TDC%d/%lf)>>%s", j, tdctimeconversion, histname);
      else
         sprintf(rdc, "(TDC%d/%lf)>>%s(%d,%lf,%lf)", j, tdctimeconversion, histname, (int)((range[3]-range[2])*tdctimeconversion), range[2], range[3]);

      sprintf(rdcsel, "(TDC%d>%lf)&&(TDC%d<%lf)", j, range[2]*tdctimeconversion, j, range[3]*tdctimeconversion);
      meas_data->Draw(rdc, rdcsel);

      sprintf(rdc, "TDC%d, Vbias=%.3lf, TDC=(%.2lf,%.2lf);Time (TDC channel) [ns];", j, evtheader.biasvolt, range[2], range[3]);
      TH1F *histtemp = (TH1F*)gCanvas->GetPrimitive(histname);
      if(!cleanPlots)
         histtemp->SetTitle(rdc);
      else
         histtemp->SetTitle(";Time (TDC channel) [ns];");
      histtemp->GetXaxis()->SetLabelSize(0.025);
      histtemp->GetXaxis()->CenterTitle(kTRUE);
      histtemp->GetYaxis()->SetLabelSize(0.025);
      if(cleanPlots)
      {
         TGaxis *yax = (TGaxis*)histtemp->GetYaxis();
         yax->SetMaxDigits(4);
      }

      gCanvas->Modified();
      gCanvas->Update();

      if( yRange->widgetNE[0]->GetNumber() != yRange->widgetNE[1]->GetNumber() )
      {
         if( (histOpt->widgetChBox[0]->IsDown()) && (yRange->widgetNE[0]->GetNumber() <= 0) )
         {
            histtemp->GetYaxis()->SetRangeUser(0.5, yRange->widgetNE[1]->GetNumber());
            yRange->widgetNE[0]->SetNumber(0.5);
            logChange = 1;
         }
         else
         {
            gCanvas->SetLogy(kFALSE);
            if(logChange == 1)
            {
               yRange->widgetNE[0]->SetNumber(0.0);
               logChange = 0;
            }
            histtemp->GetYaxis()->SetRangeUser(yRange->widgetNE[0]->GetNumber(), yRange->widgetNE[1]->GetNumber());
         }
      }

      TPaveStats *stats = (TPaveStats*)histtemp->FindObject("stats");
      if(!cleanPlots)
      {
         stats->SetX1NDC(0.84); stats->SetX2NDC(0.97);
         stats->SetY1NDC(0.87); stats->SetY2NDC(0.97);
      }
      else
      {
         stats->SetX1NDC(1.1); stats->SetX2NDC(1.3);
         stats->SetY1NDC(1.1); stats->SetY2NDC(1.3);
      }
   }
   // ADC vs. TDC histogram
   else if(histtype == 2)
   {
      if( ((range[0] == range[1]) && (range[2] == range[3])) || (range[2] == range[3]) || (range[0] == range[1]) )
         sprintf(rdc, "(TDC%d/%lf):ADC%d>>%s", j, tdctimeconversion, j, histname);
      else
         sprintf(rdc, "(TDC%d/%lf):ADC%d>>%s(%d,%lf,%lf,%d,%lf,%lf)", j, tdctimeconversion, j, histname, (int)(range[1]-range[0])/2, range[0]-0.5, range[1]-0.5, (int)((range[3]-range[2])*tdctimeconversion)/2, range[2], range[3]);
      meas_data->Draw(rdc,"","COLZ");

      sprintf(rdc, "ADC/TDC%d, Vbias=%.3lf, TDC=(%.2lf,%.2lf);ADC;TDC", j, evtheader.biasvolt, range[2], range[3]);
      TH2F *histtemp = (TH2F*)gCanvas->GetPrimitive(histname);
      if(!cleanPlots)
         histtemp->SetTitle(rdc);
      else
         histtemp->SetTitle(";ADC;Time (TDC channel) [ns]");
      histtemp->GetXaxis()->SetLabelSize(0.025);
      histtemp->GetXaxis()->CenterTitle(kTRUE);
      histtemp->GetYaxis()->SetLabelSize(0.025);
      histtemp->GetYaxis()->CenterTitle(kTRUE);
      histtemp->GetYaxis()->SetTitleOffset(1.35);
      if(cleanPlots)
      {
         TGaxis *yax = (TGaxis*)histtemp->GetYaxis();
         yax->SetMaxDigits(4);
      }

      gCanvas->Modified();
      gCanvas->Update();

      TPaveStats *stats = (TPaveStats*)histtemp->FindObject("stats");
      stats->SetX1NDC(1.1); stats->SetX2NDC(1.3);
      stats->SetY1NDC(1.1); stats->SetY2NDC(1.3);

      TPaletteAxis *gpalette = (TPaletteAxis*)histtemp->GetListOfFunctions()->FindObject("palette");
      gpalette->SetLabelSize(0.022);
   }

   if(histtype < 2)
   {
      if( histOpt->widgetChBox[0]->IsDown() )
         gCanvas->SetLogy(kTRUE);
      else if( !histOpt->widgetChBox[0]->IsDown() )
         gCanvas->SetLogy(kFALSE);
   }
   else
      gCanvas->SetLogy(kFALSE);

   gCanvas->Modified();
   gCanvas->Update();

   delete header_data;
   delete meas_data;

   // Delete the opened file when we just display it in the analysis canvas (otherwise wait for histogram save)
   if(opt != 1)
      delete inroot;

   // If you close the opened file (delete inroot), the data can not be accessed by other functions (any time we wish to use the data directly from histogram, we need to call the DisplayHistogram function -> using different opt to determine what we need to do)
}

// Start a measurement (acquisition from CAMAC)
void TGAppMainFrame::RunMeas(void *ptr, int runCase, int &scanon)
{
   int vscan = 0, pscan = 0, zscan = 0, ascan = 0;
   if(scansOn->widgetChBox[0]->IsDown()) vscan = 1;
   if(scansOn->widgetChBox[1]->IsDown()) pscan = 1;
   if(scansOn->widgetChBox[2]->IsDown()) zscan = 1;
   if(scansOn->widgetChBox[3]->IsDown()) ascan = 1;

   printf("Start of Run, run case %d\n", runCase);

   float progVal;

   char ctemp[256];
   char ctemp2[256];
   char fname[256];
   int itemp = 0;
   TH1F *liveHist;

   float minVoltage, maxVoltage, stepVoltage, diffVoltage;
   float minXpos, maxXpos, stepXpos, diffXpos;
   float minYpos, maxYpos, stepYpos, diffYpos;
   float minZpos, maxZpos, stepZpos, diffZpos;
   float minAlpha, maxAlpha, stepAlpha, diffAlpha;

   minVoltage = vOutStart->widgetNE[0]->GetNumber();
   maxVoltage = vOutStop->widgetNE[0]->GetNumber();
   diffVoltage = abs(maxVoltage - minVoltage);
   stepVoltage = abs(vOutStep->widgetNE[0]->GetNumber());
   minXpos = xPosMin->widgetNE[0]->GetNumber();
   maxXpos = xPosMax->widgetNE[0]->GetNumber();
   diffXpos = abs(maxXpos - minXpos);
   stepXpos = abs(xPosStep->widgetNE[0]->GetNumber());
   minYpos = yPosMin->widgetNE[0]->GetNumber();
   maxYpos = yPosMax->widgetNE[0]->GetNumber();
   diffYpos = abs(maxYpos - minYpos);
   stepYpos = abs(yPosStep->widgetNE[0]->GetNumber());
   minZpos = zPosMin->widgetNE[0]->GetNumber();
   maxZpos = zPosMax->widgetNE[0]->GetNumber();
   diffZpos = abs(maxZpos - minZpos);
   stepZpos = abs(zPosStep->widgetNE[0]->GetNumber());
   minAlpha = rotPosMin->widgetNE[0]->GetNumber();
   maxAlpha = rotPosMax->widgetNE[0]->GetNumber();
   diffAlpha = abs(maxAlpha - minAlpha);
   stepAlpha = abs(rotPosStep->widgetNE[0]->GetNumber());

   remove_ext((char*)fileName->widgetTE->GetText(), ctemp);

   // TODO - angle scan + voltage scan
   // Voltage or surface scan
   if( vscan || pscan || ascan )
   {
      // No Z scan, No angle scan
      if(!zscan && !ascan)
      {
         // When we have a voltage scan
         if( vscan && (stepVoltage > 0.) )
            SeqNumber(runCase, (int)diffVoltage/stepVoltage, ctemp2);
         // With only a surface scan
         else if(pscan)
         {
            if( stepXpos == 0 )
               itemp = 1;
            else
               itemp = (int)diffXpos/stepXpos;

            if( stepYpos == 0 )
               itemp *= 1;
            else
               itemp *= (int)diffYpos/stepYpos;
            SeqNumber(runCase, itemp, ctemp2);
         }
         sprintf(fname, "%s_%s%s", ctemp, ctemp2, histext);
      }
      // With Z scan, No angle scan
      else if(zscan && !ascan)
      {
         SeqNumber((int)zPos->widgetNE[0]->GetNumber(), maxZpos, ctemp2);

         // Voltage scan is on
         if( vscan && (stepVoltage > 0.) )
         {
            sprintf(fname, "%s_z%s_", ctemp, ctemp2);
            SeqNumber(runCase, (int)diffVoltage/stepVoltage+1, ctemp2);
            strcat(fname, ctemp2);
            strcat(fname, histext);
         }
         // Surface scan is on
         else if(pscan)
         {
            sprintf(fname, "%s_z%s_", ctemp, ctemp2);

            if( stepXpos == 0 )
               itemp = 1;
            else
               itemp = (int)diffXpos/stepXpos+1;

            if( stepYpos == 0 )
               itemp *= 1;
            else
               itemp *= (int)diffYpos/stepYpos+1;
            SeqNumber(runCase, itemp, ctemp2);
            strcat(fname, ctemp2);
            strcat(fname, histext);
         }
         // Just Z scan
         else
            sprintf(fname, "%s_z%s%s", ctemp, ctemp2, histext);
      }
      // No Z scan, With angle scan
      else if(!zscan && ascan)
      {
         SeqNumber(runCase, (int)diffAlpha/stepAlpha, ctemp2);

         // Voltage scan is on
         if( vscan && (stepVoltage > 0.) )
         {
            sprintf(fname, "%s_phi%s_", ctemp, ctemp2);
            SeqNumber(runCase, (int)diffVoltage/stepVoltage+1, ctemp2);
            strcat(fname, ctemp2);
            strcat(fname, histext);
         }
         // Just angle scan
         else
            sprintf(fname, "%s_phi%s%s", ctemp, ctemp2, histext);
      }
   }
   // All the rest
   else if(!vscan && !pscan)
      sprintf(fname, "%s%s", ctemp, histext);

   // Check if set voltage is below the hard limit
   if( vOut->widgetNE[0]->GetNumber() > vHardlimit->widgetNE[0]->GetNumber() )
   {
      printf("Voltage hard limit triggered (%lf > %lf)!\n", vOut->widgetNE[0]->GetNumber(), vHardlimit->widgetNE[0]->GetNumber() );
      vOut->widgetNE[0]->SetNumber( vHardlimit->widgetNE[0]->GetNumber() );
   }

   printf("Output file is (runCase = %d): %s\n", runCase, fname);

   // Writing to output file
   outroot = TFile::Open(fname, "RECREATE");

   TTree *header_data = new TTree("header_data", "Header information for the measurement.");
   TTree *meas_data = new TTree("meas_data", "Saved ADC and TDC measurement data.");
   TTree *scope_data = new TTree("scope_data", "Saved scope measurement data.");

   // Branches for the header
   header_data->Branch("nrch", &evtheader.nrch, "nrch/I");
   header_data->Branch("timestamp", &evtheader.timestamp, "timestamp/I");
   header_data->Branch("biasvolt", &evtheader.biasvolt, "biasvolt/D");
   header_data->Branch("xpos", &evtheader.xpos, "xpos/I");
   header_data->Branch("ypos", &evtheader.ypos, "ypos/I");
   header_data->Branch("zpos", &evtheader.zpos, "zpos/I");
   header_data->Branch("temperature", &evtheader.temperature, "temperature/D");
   header_data->Branch("angle", &evtheader.angle, "angle/D");
   header_data->Branch("laserinfo", &evtheader.laserinfo, "laserinfo/C");

   evtheader.nrch = (int)NCH->widgetNE[0]->GetNumber()*2;
   evtheader.timestamp = (int)time(NULL);
   evtheader.biasvolt = (double)vOut->widgetNE[0]->GetNumber();
   if(posUnits->widgetCB->GetSelected() == 0)
   {
      evtheader.xpos = (int)xPos->widgetNE[0]->GetNumber();
      evtheader.ypos = (int)yPos->widgetNE[0]->GetNumber();
      evtheader.zpos = (int)zPos->widgetNE[0]->GetNumber();
   }
   else if(posUnits->widgetCB->GetSelected() == 1)
   {
      evtheader.xpos = (int)xPos->widgetNE[0]->GetNumber()/lenconversion;
      evtheader.ypos = (int)yPos->widgetNE[0]->GetNumber()/lenconversion;
      evtheader.zpos = (int)zPos->widgetNE[0]->GetNumber()/lenconversion;
   }
   evtheader.temperature = (double)chtemp->widgetNE[0]->GetNumber();
   if(rotUnits->widgetCB->GetSelected() == 0)
      evtheader.angle = (double)rotPos->widgetNE[0]->GetNumber()*rotconversion;
   else if(rotUnits->widgetCB->GetSelected() == 1)
      evtheader.angle = (double)rotPos->widgetNE[0]->GetNumber();
   sprintf(evtheader.laserinfo, "%s", laserInfo->widgetTE->GetText());

   char histtime[256];
   GetTime(evtheader.timestamp, histtime);

   printf("Save file header information:\n");
   printf("- Number of channels: %d\n", evtheader.nrch);
   printf("- Timestamp: %d (%s)\n", evtheader.timestamp, histtime);
   printf("- Bias voltage: %lf\n", evtheader.biasvolt);
   printf("- Table position (X,Y,Z): %d, %d, %d\n", evtheader.xpos, evtheader.ypos, evtheader.zpos);
   printf("- Temperature: %lf\n", evtheader.temperature);
   printf("- Incidence angle: %lf\n", evtheader.angle);
   printf("- Laser and filter settings: %s\n", evtheader.laserinfo);

   header_data->Fill();

   // Branches for ADC and TDC data
   for(int i = 0; i < evtheader.nrch/2; i++)
   {
      sprintf(ctemp, "ADC%d", i);
      sprintf(fname, "ADC%d/I", i);
      meas_data->Branch(ctemp, &evtdata.adcdata[i], fname);

      sprintf(ctemp, "TDC%d", i);
      sprintf(fname, "TDC%d/I", i);
      meas_data->Branch(ctemp, &evtdata.tdcdata[i], fname);
   }

   //TODO
   // Initialize the scope before measurement
/*   if( sCamaclink->IsDown() )
      InitializeScope();*/


   // Branch for scope measurement data
/*   if(gScopeDaq->scopeUseType == 2) // only if we select waveform measurement
   {
      if(gScopeDaq->scopeMeasSel == 0)
         scope_data->Branch("amp", &evtmeas.measdata, "amp/D");
      else if(gScopeDaq->scopeMeasSel == 1)
         scope_data->Branch("area", &evtmeas.measdata, "area/D");
      else if(gScopeDaq->scopeMeasSel == 2)
         scope_data->Branch("delay", &evtmeas.measdata, "delay/D");
      else if(gScopeDaq->scopeMeasSel == 3)
         scope_data->Branch("fall", &evtmeas.measdata, "fall/D");
      else if(gScopeDaq->scopeMeasSel == 4)
         scope_data->Branch("freq", &evtmeas.measdata, "freq/D");
      else if(gScopeDaq->scopeMeasSel == 5)
         scope_data->Branch("max", &evtmeas.measdata, "max/D");
      else if(gScopeDaq->scopeMeasSel == 6)
         scope_data->Branch("mean", &evtmeas.measdata, "mean/D");
      else if(gScopeDaq->scopeMeasSel == 7)
         scope_data->Branch("min", &evtmeas.measdata, "min/D");
      else if(gScopeDaq->scopeMeasSel == 8)
         scope_data->Branch("pk2p", &evtmeas.measdata, "pk2p/D");
      else if(gScopeDaq->scopeMeasSel == 9)
         scope_data->Branch("pwidth", &evtmeas.measdata, "pwidth/D");
      else if(gScopeDaq->scopeMeasSel == 10)
         scope_data->Branch("rise", &evtmeas.measdata, "rise/D");
   }*/


   int neve  = (int) evtNum->widgetNE[0]->GetNumber();
   int allEvt, zProg;
   zProg = 1;

#if WORKSTAT == 'I'
#else
// ONLY FOR TESTING!
   TRandom *randNum = new TRandom();
   randNum->SetSeed(0);
// ONLY FOR TESTING!
#endif

   // Initialize the CAMAC
   if (gDaq)
   {
      if(scanon == 0)
      {
         gDaq->init(evtheader.nrch);
         scanon = 1;
      }
      gDaq->fStop=0;

      // Set the stopwatch
      clock_t clkt1;

      // Prepare histogram for live histogram update
      int liven;
      TCanvas *gCanvas;
      if(liveUpdate && (!vscan && !pscan && !zscan && !ascan))
      {
         gCanvas = measCanvas->GetCanvas();
         gCanvas->SetGrid();
         gCanvas->cd();
         liveHist = new TH1F(histname,"",(int)TMath::Sqrt(neve),0,0);
         liven = 1;
      }

      // Start gathering
      gDaq->start();

      for (int n=0;n<neve && !gDaq->fStop ;/*n++*/)
      {
         int nb = gDaq->event(gBuf,BSIZE);

#if WORKSTAT == 'I'
#else
// ONLY FOR TESTING!
         for(int i=0; i < evtheader.nrch; i++)
         {
            if(i == 1)
               gBuf[i] = randNum->Gaus(1500,300);
            else if(i == 0)
               gBuf[i] = randNum->Poisson(2500);
         }
// ONLY FOR TESTING!
#endif
         if (nb<=0) n--;

         int nc=0;

         while ( (nb>0) && (n<neve) )
         {
            for(int i = 0; i < evtheader.nrch; i++)
            {
               unsigned short adc = gBuf[i+nc]&0xFFFF;
               if(i % 2 == 0)           // TDC
                  evtdata.tdcdata[i/2] = (int)adc;
               else if(i % 2 == 1)      // ADC
                  evtdata.adcdata[i/2] = (int)adc;

               // Start plotting the scope waveform
/*             if( (gScopeDaq->scopeUseType == 1) && (sCamaclink->IsDown()) )
                  StartScopeAcq();*/
// TODO
            }
            meas_data->Fill();
            n++;
sleep(1);

            // Start making a scope measurement
/*          if( (gScopeDaq->scopeUseType == 2) && (sCamaclink->IsDown()) )
            {
               StartScopeAcq();
               evtmeas.measdata = gScopeDaq->measubuf;
            }
            scope_data->Fill();*/
// TODO

            // Start filling the histogram (only in normal single scan)
            if(liveUpdate && (!vscan && !pscan && !zscan && !ascan))
            {
               liveHist->Fill(evtdata.adcdata[0]);
               if( n == (neve*liven)/10 )
               {
                  gCanvas->cd();
                  liveHist->Draw("");
                  gCanvas->Modified();
                  gCanvas->Update();
                  liven++;
               }
            }
           
            nc += evtheader.nrch;
            nb -= evtheader.nrch;
         }

         MyTimer();
         allEvt = n;
         if (gSystem->ProcessEvents()) printf("Run Interrupted\n");

         if( acqStarted && (n == (neve*zProg)/10) && (!vscan && !pscan && !zscan && !ascan) )
         {
            // Progress the progress bar
            progVal = (float)zProg*10;
            measProgress->widgetPB->SetPosition(progVal);

            // Calculate the remaining time
            TimeEstimate(clkt0, timet0, progVal, ctemp, 0);
            printf("End time: %s\n", ctemp);
            measProgress->widgetTE->SetText(ctemp);

            gVirtualX->Update(1);
            zProg++;
         }
      }

      printf("Number of gathered events: %d\n", allEvt);
      measProgress->widgetTB[0]->SetText("Start acquisition");
      acqStarted = false;

      gDaq->stop();
   }

   printf("End of Run neve=%d\n",neve);

   header_data->Write();
   meas_data->Write();
//   scope_data->Write(); // TODO
   delete header_data;
   delete meas_data;
   delete scope_data;

   // Remove the histogram
   if(liveUpdate && (!vscan && !pscan && !zscan && !ascan))
      delete liveHist;


   outroot->Close();
}

int TGAppMainFrame::MyTimer()
{
   char cmd[100];
   GetTime(-1, cmd);
   if (timeStamp) timeStamp->widgetTE->SetText(cmd);
   return 0;
}

// Additional functions -------------------------------------

// Settings pane connections --------------------------------

// Enable or disable scans
void TGAppMainFrame::EnableScan(int type)
{
   // Voltage scan
   if(type == 0)
   {
      if(scansOn->widgetChBox[type]->IsOn())
      {
         vOutStart->widgetNE[0]->SetState(kTRUE);
         vOutStop->widgetNE[0]->SetState(kTRUE);
         vOutStep->widgetNE[0]->SetState(kTRUE);
      }
      else
      {
         vOutStart->widgetNE[0]->SetState(kFALSE);
         vOutStop->widgetNE[0]->SetState(kFALSE);
         vOutStep->widgetNE[0]->SetState(kFALSE);
      }
   }
   // Surface (X, Y axis) scan
   else if(type == 1)
   {
      if(scansOn->widgetChBox[type]->IsOn())
      {
         xPosMin->widgetNE[0]->SetState(kTRUE);
         xPosMax->widgetNE[0]->SetState(kTRUE);
         xPosStep->widgetNE[0]->SetState(kTRUE);
         yPosMin->widgetNE[0]->SetState(kTRUE);
         yPosMax->widgetNE[0]->SetState(kTRUE);
         yPosStep->widgetNE[0]->SetState(kTRUE);
      }
      else
      {
         xPosMin->widgetNE[0]->SetState(kFALSE);
         xPosMax->widgetNE[0]->SetState(kFALSE);
         xPosStep->widgetNE[0]->SetState(kFALSE);
         yPosMin->widgetNE[0]->SetState(kFALSE);
         yPosMax->widgetNE[0]->SetState(kFALSE);
         yPosStep->widgetNE[0]->SetState(kFALSE);
      }
   }
   // Z axis scan
   else if(type == 2)
   {
      if(scansOn->widgetChBox[type]->IsOn())
      {
         zPosMin->widgetNE[0]->SetState(kTRUE);
         zPosMax->widgetNE[0]->SetState(kTRUE);
         zPosStep->widgetNE[0]->SetState(kTRUE);
      }
      else
      {
         zPosMin->widgetNE[0]->SetState(kFALSE);
         zPosMax->widgetNE[0]->SetState(kFALSE);
         zPosStep->widgetNE[0]->SetState(kFALSE);
      }
   }
   // Incidence angle scan
   else if(type == 3)
   {
      if(scansOn->widgetChBox[type]->IsOn())
      {
         rotPosMin->widgetNE[0]->SetState(kTRUE);
         rotPosMax->widgetNE[0]->SetState(kTRUE);
         rotPosStep->widgetNE[0]->SetState(kTRUE);
      }
      else
      {
         rotPosMin->widgetNE[0]->SetState(kFALSE);
         rotPosMax->widgetNE[0]->SetState(kFALSE);
         rotPosStep->widgetNE[0]->SetState(kFALSE);
      }
   }
}

// Apply the upper voltage limit from settings pane to main window
void TGAppMainFrame::VoltageLimit()
{
   vOut->widgetNE[0]->SetLimitValues(0, vHardlimit->widgetNE[0]->GetNumber() );
}

// Select the table position units to be used (1 = 0.3595 micron)
void TGAppMainFrame::ChangeUnits(int type)
{
   int pos[12], poslim[3], chng = 0;
   double micro[12], microlim[3];

   TGNumberEntry *posEntries[12];
   posEntries[0] = (TGNumberEntry*)xPos->widgetNE[0];
   posEntries[1] = (TGNumberEntry*)yPos->widgetNE[0];
   posEntries[2] = (TGNumberEntry*)zPos->widgetNE[0];
   posEntries[3] = (TGNumberEntry*)xPosMin->widgetNE[0];
   posEntries[4] = (TGNumberEntry*)xPosMax->widgetNE[0];
   posEntries[5] = (TGNumberEntry*)xPosStep->widgetNE[0];
   posEntries[6] = (TGNumberEntry*)yPosMin->widgetNE[0];
   posEntries[7] = (TGNumberEntry*)yPosMax->widgetNE[0];
   posEntries[8] = (TGNumberEntry*)yPosStep->widgetNE[0];
   posEntries[9] = (TGNumberEntry*)zPosMin->widgetNE[0];
   posEntries[10] = (TGNumberEntry*)zPosMax->widgetNE[0];
   posEntries[11] = (TGNumberEntry*)zPosStep->widgetNE[0];

   // Table position values
   if(type == 0)
   {
      // Check if we had microns before
      if(posEntries[0]->GetNumStyle() == TGNumberFormat::kNESRealTwo)
         chng = 1;

      // Change to table position values  
      if(chng == 1)
      {
         for(int i = 0; i < 12; i++)
         {
            if(posEntries[i]->GetNumber() == 0.0)
               pos[i] = 0;
            else
               pos[i] = (int)posEntries[i]->GetNumber()/lenconversion;
         }

         poslim[0] = -100;
         poslim[1] = 215000;
         poslim[2] = 375000;

         for(int i = 0; i < 12; i++)
         {
            posEntries[i]->SetNumStyle(TGNumberFormat::kNESInteger);
            if( (i > 8) || (i == 2) ) // limits for Z axis (longer table)
               posEntries[i]->SetLimits(TGNumberFormat::kNELLimitMinMax, poslim[0], poslim[2]);
            else
               posEntries[i]->SetLimits(TGNumberFormat::kNELLimitMinMax, poslim[0], poslim[1]);

            posEntries[i]->SetNumber(pos[i]);
         }
      }
   }
   // Microns
   else if(type == 1)
   {
      // Check if we had table position values before
      if(posEntries[0]->GetNumStyle() == TGNumberFormat::kNESInteger)
         chng = 1;

      // Change to microns  
      if(chng == 1)
      {
         for(int i = 0; i < 12; i++)
         {
            if(posEntries[i]->GetNumber() == 0.0)
               micro[i] = 0.;
            else
               micro[i] = (double)posEntries[i]->GetNumber()*lenconversion;
         }
   
         microlim[0] = (double)-100*lenconversion;
         microlim[1] = (double)215000*lenconversion;
         microlim[2] = (double)375000*lenconversion;
   
         for(int i = 0; i < 12; i++)
         {
            posEntries[i]->SetNumStyle(TGNumberFormat::kNESRealTwo);
            if( (i > 8) || (i == 2) ) // limits for Z axis (longer table)
               posEntries[i]->SetLimits(TGNumberFormat::kNELLimitMinMax, microlim[0], microlim[2]);
            else
               posEntries[i]->SetLimits(TGNumberFormat::kNELLimitMinMax, microlim[0], microlim[1]);
   
            posEntries[i]->SetNumber(micro[i]);
         }
      }
   }
}

// Select the rotation units to be used (1 = 6.3281/3600 degrees)
void TGAppMainFrame::ChangeUnitsRot(int type)
{
   int rot[4], rotlim[2], chng = 0;
   double deg[4], deglim[2];

   TGNumberEntry *rotEntries[4];
   rotEntries[0] = (TGNumberEntry*)rotPos->widgetNE[0];
   rotEntries[1] = (TGNumberEntry*)rotPosMin->widgetNE[0];
   rotEntries[2] = (TGNumberEntry*)rotPosMax->widgetNE[0];
   rotEntries[3] = (TGNumberEntry*)rotPosStep->widgetNE[0];

   // Rotation values
   if(type == 0)
   {
      // Check if we had degrees before
      if(rotEntries[0]->GetNumStyle() == TGNumberFormat::kNESRealTwo)
         chng = 1;

      // Change to rotation values  
      if(chng == 1)
      {
         for(int i = 0; i < 4; i++)
         {
            if(rotEntries[i]->GetNumber() == 0.0)
               rot[i] = 0;
            else
               rot[i] = (int)rotEntries[i]->GetNumber()/rotconversion;
         }

         rotlim[0] = (int)-180/rotconversion;
         rotlim[1] = (int)180/rotconversion;

         for(int i = 0; i < 4; i++)
         {
            rotEntries[i]->SetNumStyle(TGNumberFormat::kNESInteger);
            rotEntries[i]->SetLimits(TGNumberFormat::kNELLimitMinMax, rotlim[0], rotlim[1]);

            rotEntries[i]->SetNumber(rot[i]);
         }
      }
   }
   // Degree
   else if(type == 1)
   {
      // Check if we had table position values before
      if(rotEntries[0]->GetNumStyle() == TGNumberFormat::kNESInteger)
         chng = 1;

      // Change to degrees  
      if(chng == 1)
      {
         for(int i = 0; i < 4; i++)
         {
            if(rotEntries[i]->GetNumber() == 0)
               deg[i] = 0.;
            else
               deg[i] = (double)rotEntries[i]->GetNumber()*rotconversion;
         }
   
         deglim[0] = -180.;
         deglim[1] = 180.;
   
         for(int i = 0; i < 4; i++)
         {
            rotEntries[i]->SetNumStyle(TGNumberFormat::kNESRealTwo);
            rotEntries[i]->SetLimits(TGNumberFormat::kNELLimitMinMax, deglim[0], deglim[1]);
   
            rotEntries[i]->SetNumber(deg[i]);
         }
      }
   }
}

// Enable display canvas to have a live update of histogram
void TGAppMainFrame::EnableLiveUpdate()
{
   liveUpdate = liveDisp->widgetChBox[0]->IsDown();
}

// Settings pane connections --------------------------------

// Main measurement window connections ----------------------

// Get the currently selected channel
int TGAppMainFrame::GetChannel()
{
   int selectedOutput;
   if(vOutCh->widgetCB->GetSelected() < 8) selectedOutput = (vOutCh->widgetCB->GetSelected())+1;
   else if( (vOutCh->widgetCB->GetSelected() >= 8) && (vOutCh->widgetCB->GetSelected() < 16) ) selectedOutput = (vOutCh->widgetCB->GetSelected())+93;
   else selectedOutput = 1;

   return selectedOutput;
}

// Set, get or reset the output voltage
void TGAppMainFrame::VoltOut(int opt)
{
   char cmd[256];

   // Set the selected voltage
   if(opt == 0)
   {
      int outOn;
      float outputVoltage;
     
      outputVoltage = vOut->widgetNE[0]->GetNumber();
   
      if(vOutOpt->widgetChBox[1]->IsOn()) outOn = 1;
      else outOn = 0;
     
      fflush(stdout);
      sprintf(cmd, "%s/src/mpod/mpod_voltage.sh -o %d -v %f -s %d", rootdir, GetChannel(), outputVoltage, outOn);
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif
      fflush(stdout);
   }
   // Get current voltage
   else if(opt == 1)
   {
      fflush(stdout);
      sprintf(cmd, "%s/src/mpod/mpod_voltage.sh -o %d -g > %s/settings/curvolt.txt", rootdir, GetChannel(), rootdir);
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif
      fflush(stdout);

#if WORKSTAT == 'I'
      FILE* fvolt;
      double dtemp;
      char ctemp[24];
      sprintf(cmd, "%s/settings/curvolt.txt", rootdir);
      fvolt = fopen(cmd, "r");
     
      if(fvolt != NULL)
      {
         sprintf(cmd, "WIENER-CRATE-MIB::outputVoltage.u%d = Opaque: Float: %s V\n", GetChannel()-1, "%lf" );
         retTemp = fscanf(fvolt, cmd, &dtemp);
         vOut->widgetNE[0]->SetNumber(dtemp);
         sprintf(cmd, "WIENER-CRATE-MIB::outputSwitch.u%d = INTEGER: %s\n", GetChannel()-1, "%s" );
         retTemp = fscanf(fvolt, cmd, ctemp);
         if( strcmp(ctemp, "On(1)") == 0 )
            vOutOpt->widgetChBox[1]->SetState(kButtonDown);
         else if( strcmp(ctemp, "Off(0)") == 0 )
            vOutOpt->widgetChBox[1]->SetState(kButtonUp);
      }
   
      fclose(fvolt);
#endif
   }
   // Reset output voltage (if stuck in interlock)
   else if(opt == 2)
   {
      vOut->widgetNE[0]->SetNumber(0.000);
      vOutOpt->widgetChBox[1]->SetState(kButtonUp);

      fflush(stdout);
      sprintf(cmd, "%s/src/mpod/mpod_voltage.sh -r %d", rootdir, GetChannel());
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif
      fflush(stdout);
   }
}

// Set output voltage polarity to negative
void TGAppMainFrame::NegativePolarity()
{
   double newHardlimit;
   int polar = 0;  // 0 = positive, 1 = negative

   if(vOutOpt->widgetChBox[0]->IsOn())
      polar = 1;
   else
      polar = 0;

   // Set hard limit to the negative version of what it was before
   if( (vHardlimit->widgetNE[0]->GetNumber() > 0.) && (polar == 1) )
      newHardlimit = -(vHardlimit->widgetNE[0]->GetNumber());
   else if( (vHardlimit->widgetNE[0]->GetNumber() < 0.) && (polar == 0) )
      newHardlimit = -(vHardlimit->widgetNE[0]->GetNumber());
   else if(vHardlimit->widgetNE[0]->GetNumber() == 0.)
      newHardlimit = 0.;
   else
      newHardlimit = vHardlimit->widgetNE[0]->GetNumber();

   // Apropriately set the limit to the output voltage number entry
   vHardlimit->widgetNE[0]->SetNumber(newHardlimit);

   if(polar == 1)
      vOut->widgetNE[0]->SetLimits(TGNumberFormat::kNELLimitMinMax, newHardlimit, 0.);
   else if(polar == 0)
      vOut->widgetNE[0]->SetLimits(TGNumberFormat::kNELLimitMinMax, 0., newHardlimit);
}

// Set, get, home or reset the table position
void TGAppMainFrame::PositionSet(int opt)
{
   char cmd[1024];

   // Set the selected table position
   if(opt == 0)
   {
      int positX, positY, positZ;
 
      if(posUnits->widgetCB->GetSelected() == 0)
      {
         positX = xPos->widgetNE[0]->GetNumber();
         positY = yPos->widgetNE[0]->GetNumber();
         positZ = zPos->widgetNE[0]->GetNumber();
      }
      else if(posUnits->widgetCB->GetSelected() == 1)
      {
         positX = (int)xPos->widgetNE[0]->GetNumber()/lenconversion;
         positY = (int)yPos->widgetNE[0]->GetNumber()/lenconversion;
         positZ = (int)zPos->widgetNE[0]->GetNumber()/lenconversion;
      }
 
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 1 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 1 -c m", rootdir, positX, rootdir);
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif
 
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 2 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 2 -c m", rootdir, positY, rootdir);
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif
 
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 3 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 3 -c m", rootdir, positZ, rootdir);
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif
   }
   // Get current table position
   else if(opt == 1)
   {
      fflush(stdout);
   
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 1 -p > %s/settings/curpos.txt", rootdir, rootdir);  // X-axis
      fflush(stdout);
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif
   
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 2 -p >> %s/settings/curpos.txt", rootdir, rootdir); // Y-axis
      fflush(stdout);
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif
   
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 3 -p >> %s/settings/curpos.txt", rootdir, rootdir); // Z-axis
      fflush(stdout);
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif

#if WORKSTAT == 'I'
      FILE* fpos;
      int itemp;
      sprintf(cmd, "%s/settings/curpos.txt", rootdir);
      fpos = fopen(cmd, "r");
     
      if(fpos != NULL)
      {
         if(posUnits->widgetCB->GetSelected() == 0)
         {
            retTemp = fscanf(fpos, "%d\n", &itemp);
            xPos->widgetNE[0]->SetNumber(itemp);
            retTemp = fscanf(fpos, "%d\n", &itemp);
            yPos->widgetNE[0]->SetNumber(itemp);
            retTemp = fscanf(fpos, "%d\n", &itemp);
            zPos->widgetNE[0]->SetNumber(itemp);
         }
         else if(posUnits->widgetCB->GetSelected() == 1)
         {
            retTemp = fscanf(fpos, "%d\n", &itemp);
            xPos->widgetNE[0]->SetNumber((double)itemp*lenconversion);
            retTemp = fscanf(fpos, "%d\n", &itemp);
            yPos->widgetNE[0]->SetNumber((double)itemp*lenconversion);
            retTemp = fscanf(fpos, "%d\n", &itemp);
            zPos->widgetNE[0]->SetNumber((double)itemp*lenconversion);
         }
      }

      fclose(fpos);
#endif
   }
   // Home the table position
   else if(opt == 2)
   {
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 1 -h", rootdir);    // X-axis
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif

      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 2 -h", rootdir);    // Y-axis
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif

      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 3 -h", rootdir);    // Z-axis
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif
      PositionSet(1);
   }
   // Reset the table position
   else if(opt == 3)
   {
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 1 -r && sudo %s/src/MIKRO/mikro_ctrl -n 1 -i 3 && sudo %s/src/MIKRO/mikro_ctrl -n 1 -h", rootdir, rootdir, rootdir);        // X-axis
#if WORKSTAT == 'I'
      printf("Positioning table reset, initialization and homing in progress. Please wait...\n");
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif

      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 2 -r && sudo %s/src/MIKRO/mikro_ctrl -n 2 -i 3 && sudo %s/src/MIKRO/mikro_ctrl -n 2 -h", rootdir, rootdir, rootdir);        // Y-axis
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif

      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 3 -r && sudo %s/src/MIKRO/mikro_ctrl -n 3 -i 3 && sudo %s/src/MIKRO/mikro_ctrl -n 3 -h", rootdir, rootdir, rootdir);        // Z-axis
#if WORKSTAT == 'I'
      retTemp = system(cmd);
      printf("Positioning table reset, initialization and homing complete.\n");
#else
      printf("Cmd: %s\n",cmd);
#endif
      PositionSet(1);
   }
}

// Set, get, home or reset the rotation platform
void TGAppMainFrame::RotationSet(int opt)
{
   char cmd[1024];

   // Set the selected rotation
   if(opt == 0)
   {
      int positAlpha;
 
      if(rotUnits->widgetCB->GetSelected() == 0)
         positAlpha = rotPos->widgetNE[0]->GetNumber();
      else if(rotUnits->widgetCB->GetSelected() == 1)
         positAlpha = rotPos->widgetNE[0]->GetNumber()/rotconversion;
 
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 4 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 4 -c m", rootdir, positAlpha, rootdir);
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif
   }
   // Get current rotation
   else if(opt == 1)
   {
      fflush(stdout);
   
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 4 -p > %s/settings/currot.txt", rootdir, rootdir);
      fflush(stdout);
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif

#if WORKSTAT == 'I'
      FILE* frot;
      int itemp;
      sprintf(cmd, "%s/settings/currot.txt", rootdir);
      frot = fopen(cmd, "r");

      if(frot != NULL)
      {
         retTemp = fscanf(frot, "%d\n", &itemp);
         if(rotUnits->widgetCB->GetSelected() == 0)
            rotPos->widgetNE[0]->SetNumber(itemp);
         else if(rotUnits->widgetCB->GetSelected() == 1)
            rotPos->widgetNE[0]->SetNumber((double)itemp*rotconversion);
      }

      fclose(frot);
#endif
   }
   // Home the rotation
   else if(opt == 2)
   {
      // TODO: For now only set back to 0, not home!
//      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 4 -h", rootdir);
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 4 -v 0 -s la && %s/src/MIKRO/mikro_ctrl -n 4 -c m", rootdir, rootdir);
#if WORKSTAT == 'I'
      retTemp = system(cmd);
#else
      printf("Cmd: %s\n",cmd);
#endif
      RotationSet(1);
   }
   // Reset the rotation
   else if(opt == 3)
   {
      // TODO: For now only set back to 0, not home!
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 4 -r && sudo %s/src/MIKRO/mikro_ctrl -n 4 -i 2 && sudo %s/src/MIKRO/mikro_ctrl -n 4 -h", rootdir, rootdir, rootdir);
#if WORKSTAT == 'I'
      printf("Rotation platform reset, initalization and homing in progress. Please wait...\n");
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 4 -v 0 -s la && %s/src/MIKRO/mikro_ctrl -n 4 -c m", rootdir, rootdir);
      retTemp = system(cmd);
      sleep(15);        // wait for the motor to change position from wherever to 0
      sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 4 -r && sudo %s/src/MIKRO/mikro_ctrl -n 4 -i 2", rootdir, rootdir);
      retTemp = system(cmd);
      printf("Rotation platform reset, initalization and homing complete.\n");
#else
      printf("Cmd: %s\n",cmd);
#endif
      RotationSet(1);
   }
}

// File browser for selecting the save file
void TGAppMainFrame::SaveFile()
{
   TGFileInfo file_info;
   const char *filetypes[] = {"Histograms",histextall,0,0};
   char *cTemp;
   file_info.fFileTypes = filetypes;
   cTemp = new char[1024];
   sprintf(cTemp, "%s/results", rootdir);
   file_info.fIniDir = StrDup(cTemp);
   new TGFileDialog(gClient->GetDefaultRoot(), fMain, kFDSave, &file_info);
   delete[] cTemp;

   if(file_info.fFilename != NULL)
      fileName->widgetTE->SetText(file_info.fFilename);
}

// Start the acquisition
void TGAppMainFrame::StartAcq()
{
   // Variable that will initialize camac only once (for scans)
   int scanon = 0;

   // Determine the type of measurement to perform
   int vscan = 0, pscan = 0, zscan = 0, ascan = 0;
   if(scansOn->widgetChBox[0]->IsDown()) vscan = 1;
   if(scansOn->widgetChBox[1]->IsDown()) pscan = 1;
   if(scansOn->widgetChBox[2]->IsDown()) zscan = 1;
   if(scansOn->widgetChBox[3]->IsDown()) ascan = 1;

   char cmd[256];
   int i, j, k;
   float progVal;
   FILE *pfin;

   // Variables for voltage scan
   float currentVoltage, minVoltage, maxVoltage, stepVoltage;
   int repetition;

   // Variables for surface scan and Z axis scan
   float minXpos, maxXpos, stepXpos;
   float minYpos, maxYpos, stepYpos;
   float minZpos, maxZpos, stepZpos;
   int repetX, repetY, repetZ;

   // Variables for angle scan
   float currentAlpha, minAlpha, maxAlpha, stepAlpha;
   int repetAlpha;

   // Only voltage scan
   if( (vscan == 1) && (pscan == 0) && (ascan == 0) )
   { // TODO - include possibility to make voltage and angle scan at same time
      // If already started, stop the acquisition
      if(acqStarted)
      {
         printf("Stopping current voltage scan...\n");
         gROOT->SetInterrupt();
         measProgress->widgetTB[0]->SetText("Start acquisition");
         acqStarted = false;

         // Write information to the finish_sig.txt value
         sprintf(cmd, "%s/dbg/finish_sig.txt", rootdir);
         pfin = fopen(cmd,"w");
         fprintf(pfin, "%s: Voltage scan stopped.", timeStamp->widgetTE->GetText());
         fclose(pfin);
      }
      // If stopped, start the acquisition
      else if(!acqStarted)
      {
         printf("Running a voltage scan...\n");

         // Check the steps
         minVoltage = vOutStart->widgetNE[0]->GetNumber();
         maxVoltage = vOutStop->widgetNE[0]->GetNumber();
         stepVoltage = vOutStep->widgetNE[0]->GetNumber();

         if(stepVoltage == 0.)
            repetition = 1;
         else
         {
            // Example: min = 40, max = 70, step = 5 (in increasing steps)
            if( (maxVoltage > minVoltage) && (stepVoltage > 0) )
               repetition = ((maxVoltage - minVoltage)/stepVoltage)+1;
            // Example: min = 70, max = 40, step = -5 (in decreasing steps)
            else if( (maxVoltage < minVoltage) && (stepVoltage < 0) )
               repetition = ((minVoltage - maxVoltage)/stepVoltage)-1;
            // Example: min = 70, max = 70 (no scan)
            else if( maxVoltage == minVoltage )
               repetition = 1;
            // If step is not correctly set, stop the acqusition
            else
            {
               // TODO
               printf("Stopping current voltage scan...\n");
               gROOT->SetInterrupt();
               measProgress->widgetTB[0]->SetText("Start acquisition");
               acqStarted = false;
               repetition = 0;
            }
         }

         if(DBGSIG) printf("StartAcq(): Voltage repetition (%lf,%lf,%lf) = %d\n", minVoltage, maxVoltage, stepVoltage, repetition);

         i = 0;

         // TODO - Setting button text and acqStarted do not work!
         measProgress->widgetTB[0]->SetText("Stop acquisition");
         acqStarted = true;
         progVal = 0.00;
         measProgress->widgetPB->SetPosition(progVal);
         gVirtualX->Update(1);

         clkt0 = clock();
         timet0 = time(NULL);

         while(1)
         {
            if( (repetition > 0) && (i == repetition) ) break;
            else if( (repetition < 0) && (i == -repetition) ) break;
            else if( repetition == 0 ) break;

            progVal = (float)(100.00/abs(repetition))*i;
            measProgress->widgetPB->SetPosition(progVal);

            TimeEstimate(clkt0, timet0, progVal, cmd, singlewait*abs(repetition));
            measProgress->widgetTE->SetText(cmd);

            gVirtualX->Update(1);
       
            fflush(stdout);
            currentVoltage = minVoltage + stepVoltage*i;
            sprintf(cmd, "%s/src/mpod/mpod_voltage.sh -o %d -v %f -s 1", rootdir, GetChannel(), currentVoltage);
#if WORKSTAT == 'I'
            retTemp = system(cmd);
#else
            printf("Cmd: %s\n",cmd);
#endif
            fflush(stdout);
       
            printf("Waiting for voltage change...\n");
            sleep(singlewait);
            vOut->widgetNE[0]->SetNumber(currentVoltage);
            gVirtualX->Update(1);
            printf("Continuing...\n");
       
            // Here comes function to start histogramming <<<<<<<<<<<<<<<<<<<<<<<<
            RunMeas((void*)0, i, scanon); // TODO
            fflush(stdout);

            i++;
         }

         // Set output back to off
         fflush(stdout);
         printf("Measurement finished, returning to starting voltage...\n");
         sprintf(cmd, "%s/src/mpod/mpod_voltage.sh -o %d -v %f -s 1", rootdir, GetChannel(), minVoltage);
         vOut->widgetNE[0]->SetNumber(minVoltage);
#if WORKSTAT == 'I'
         retTemp = system(cmd);
#else
         printf("Cmd: %s\n",cmd);
#endif
         fflush(stdout);
       
         progVal = 100.00;
         measProgress->widgetPB->SetPosition(progVal);
         printf("\n");

         sprintf(cmd, "%s/dbg/finish_sig.txt", rootdir);
         pfin = fopen(cmd,"w");
         fprintf(pfin, "%s: Voltage scan finished.", timeStamp->widgetTE->GetText());
         fclose(pfin);

         measProgress->widgetTB[0]->SetText("Start acquisition");
         acqStarted = false;
      }
   }
   // Surface scan
   else if( (pscan == 1) && (vscan == 0) && (ascan == 0) )
   {
      // If already started, stop the acquisition
      if(acqStarted)
      {
         printf("Stopping current surface scan...\n");
         gROOT->SetInterrupt();
         measProgress->widgetTB[0]->SetText("Start acquisition");
         acqStarted = false;

         // Write information to the finish_sig.txt value
         sprintf(cmd, "%s/dbg/finish_sig.txt", rootdir);
         pfin = fopen(cmd,"w");
         fprintf(pfin, "%s: Surface scan stopped.", timeStamp->widgetTE->GetText());
         fclose(pfin);
      }
      // If stopped, start the acquisition
      else if(!acqStarted)
      {
         printf("Running a surface scan...\n");

         minXpos = xPosMin->widgetNE[0]->GetNumber();
         maxXpos = xPosMax->widgetNE[0]->GetNumber();
         stepXpos = xPosStep->widgetNE[0]->GetNumber();
         minYpos = yPosMin->widgetNE[0]->GetNumber();
         maxYpos = yPosMax->widgetNE[0]->GetNumber();
         stepYpos = yPosStep->widgetNE[0]->GetNumber();
         minZpos = zPosMin->widgetNE[0]->GetNumber();
         maxZpos = zPosMax->widgetNE[0]->GetNumber();
         stepZpos = zPosStep->widgetNE[0]->GetNumber();

         // Setting repetition for Z axis scan
         if(zscan == 1)
         {
            if(stepZpos == 0.)
               repetZ = 1;
            else
            {
               // Example: min = 40, max = 70, step = 5 (in increasing steps)
               if( (maxZpos > minZpos) && (stepZpos > 0) )
                  repetZ = ((maxZpos - minZpos)/stepZpos)+1;
               // Example: min = 70, max = 40, step = -5 (in decreasing steps)
               else if( (maxZpos < minZpos) && (stepZpos < 0) )
                  repetZ = ((minZpos - maxZpos)/stepZpos)-1;
               // Example: min = 70, max = 70 (no scan)
               else if( maxZpos == minZpos )
                  repetZ = 1;
               // If step is not correctly set, stop the acqusition
               else
               {
                  // TODO
                  printf("Stopping current surface scan (Z step error)...\n");
                  gROOT->SetInterrupt();
                  measProgress->widgetTB[0]->SetText("Start acquisition");
                  acqStarted = false;
                  repetZ = 0;
               }
            }
         }
         else
         {
            minZpos = zPos->widgetNE[0]->GetNumber();
            repetZ = 1;
         }

         // Setting repetition for X axis
         if(stepXpos == 0.)
            repetX = 1;
         else
         {
            // Example: min = 40, max = 70, step = 5 (in increasing steps)
            if( (maxXpos > minXpos) && (stepXpos > 0) )
               repetX = ((maxXpos - minXpos)/stepXpos)+1;
            // Example: min = 70, max = 40, step = -5 (in decreasing steps)
            else if( (maxXpos < minXpos) && (stepXpos < 0) )
               repetX = ((minXpos - maxXpos)/stepXpos)-1;
            // Example: min = 70, max = 70 (no scan)
            else if( maxXpos == minXpos )
               repetX = 1;
            // If step is not correctly set, stop the acqusition
            else
            {
               // TODO
               printf("Stopping current surface scan (X step error)...\n");
               gROOT->SetInterrupt();
               measProgress->widgetTB[0]->SetText("Start acquisition");
               acqStarted = false;
               repetX = 0;
            }
         }
         // Setting repetition for Y axis
         if(stepYpos == 0.)
            repetY = 1;
         else
         {
            // Example: min = 40, max = 70, step = 5 (in increasing steps)
            if( (maxYpos > minYpos) && (stepYpos > 0) )
               repetY = ((maxYpos - minYpos)/stepYpos)+1;
            // Example: min = 70, max = 40, step = -5 (in decreasing steps)
            else if( (maxYpos < minYpos) && (stepYpos < 0) )
               repetY = ((minYpos - maxYpos)/stepYpos)-1;
            // Example: min = 70, max = 70 (no scan)
            else if( maxYpos == minYpos )
               repetY = 1;
            // If step is not correctly set, stop the acqusition
            else
            {
               // TODO
               printf("Stopping current surface scan (Y step error)...\n");
               gROOT->SetInterrupt();
               measProgress->widgetTB[0]->SetText("Start acquisition");
               acqStarted = false;
               repetY = 0;
            }
         }

         if(DBGSIG) printf("StartAcq(): X axis repetition (%lf,%lf,%lf) = %d\n", minXpos, maxXpos, stepXpos, repetX);
         if(DBGSIG) printf("StartAcq(): Y axis repetition (%lf,%lf,%lf) = %d\n", minYpos, maxYpos, stepYpos, repetY);
         if(DBGSIG) printf("StartAcq(): Z axis repetition (%lf,%lf,%lf) = %d\n", minZpos, maxZpos, stepZpos, repetZ);

         i = 0; j = 0; k = 0;

         // TODO - Setting button text and acqStarted do not work!
         measProgress->widgetTB[0]->SetText("Stop acquisition");
         acqStarted = true;
         progVal = 0.00;
         measProgress->widgetPB->SetPosition(progVal);
         gVirtualX->Update(1);

         clkt0 = clock();
         timet0 = time(NULL);

         // Scan over Z axis
         while(1)
         {
            if( (repetZ > 0) && (k == repetZ) ) break;
            else if( (repetZ < 0) && (k == -repetZ) ) break;
            else if( repetZ == 0 ) break;

            fflush(stdout);
            // Z-axis change
            if( posUnits->widgetCB->GetSelected() == 0)
               sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 3 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 3 -c m", rootdir, (int)(minZpos + stepZpos*k), rootdir);
            else if( posUnits->widgetCB->GetSelected() == 1)
               sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 3 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 3 -c m", rootdir, (int)((minZpos + stepZpos*k)/lenconversion), rootdir);
#if WORKSTAT == 'I'
            retTemp = system(cmd);
#else
            printf("Cmd: %s\n",cmd);
#endif
            fflush(stdout);
     
            printf("Next Z position...\n");
            sleep(2*doublewait);
            zPos->widgetNE[0]->SetNumber(minZpos + stepZpos*k);
            fflush(stdout);

            // Scan over Y axis
            while(1)
            {
               if( (repetY > 0) && (j == repetY) ) break;
               else if( (repetY < 0) && (j == -repetY) ) break;
               else if( repetY == 0 ) break;

               fflush(stdout);
               // Y-axis change
               if( posUnits->widgetCB->GetSelected() == 0)
                  sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 2 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 2 -c m", rootdir, (int)(minYpos + stepYpos*j), rootdir);
               else if( posUnits->widgetCB->GetSelected() == 1)
                  sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 2 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 2 -c m", rootdir, (int)((minYpos + stepYpos*j)/lenconversion), rootdir);
#if WORKSTAT == 'I'
               retTemp = system(cmd);
#else
               printf("Cmd: %s\n",cmd);
#endif
               fflush(stdout);
     
               printf("Next Y position...\n");
               sleep(2*doublewait);
               yPos->widgetNE[0]->SetNumber(minYpos + stepYpos*j);
               fflush(stdout);

               // Scan over X axis
               while(1)
               {
                  if( (repetX > 0) && (i == repetX) ) break;
                  else if( (repetX < 0) && (i == -repetX) ) break;
                  else if( repetX == 0 ) break;

                  progVal = (float)(100.00/(abs(repetX)*abs(repetY)*abs(repetZ)))*(k*abs(repetX)*abs(repetY) + j*abs(repetX) + i);
                  measProgress->widgetPB->SetPosition(progVal);

                  TimeEstimate(clkt0, timet0, progVal, cmd, doublewait*((abs(repetX)+2)*abs(repetY)+2)*abs(repetZ));
                  measProgress->widgetTE->SetText(cmd);

                  gVirtualX->Update(1);

                  // X-axis change
                  if( posUnits->widgetCB->GetSelected() == 0)
                     sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 1 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 1 -c m", rootdir, (int)(minXpos + stepXpos*i), rootdir);
                  else if( posUnits->widgetCB->GetSelected() == 1)
                     sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 1 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 1 -c m", rootdir, (int)((minXpos + stepXpos*i)/lenconversion), rootdir);
#if WORKSTAT == 'I'
                  retTemp = system(cmd);
#else
                  printf("Cmd: %s\n",cmd);
#endif
                  fflush(stdout);
       
                  printf("Next X position...\n");
                  fflush(stdout);
     
                  printf("Waiting for position change...\n");
                  sleep(doublewait);
                  xPos->widgetNE[0]->SetNumber(minXpos + stepXpos*i);
                  printf("Continuing...\n");
     
               // Here comes function to start histogramming <<<<<<<<<<<<<<<<<<<<<<<<
                  RunMeas((void*)0, (j*repetX + i), scanon);
     
                  fflush(stdout);

                  i++;
               }

               i = 0;
               printf("\n");

               j++;
            }

            j = 0;

            k++;
         }
printf("Time = %d\n", (int)time(NULL));

         fflush(stdout);
         printf("Measurement finished, returning to starting position...\n");
         // X-axis return
         if( posUnits->widgetCB->GetSelected() == 0)
            sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 1 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 1 -c m", rootdir, (int)minXpos, rootdir);
         else if( posUnits->widgetCB->GetSelected() == 1)
            sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 1 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 1 -c m", rootdir, (int)(minXpos/lenconversion), rootdir);
#if WORKSTAT == 'I'
         retTemp = system(cmd);
#else
         printf("Cmd: %s\n",cmd);
#endif
         fflush(stdout);

         // Y-axis return
         if( posUnits->widgetCB->GetSelected() == 0)
            sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 2 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 2 -c m", rootdir, (int)minYpos, rootdir);
         else if( posUnits->widgetCB->GetSelected() == 1)
            sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 2 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 2 -c m", rootdir, (int)(minYpos/lenconversion), rootdir);
#if WORKSTAT == 'I'
         retTemp = system(cmd);
#else
         printf("Cmd: %s\n",cmd);
#endif

         // Z-axis return
         if( posUnits->widgetCB->GetSelected() == 0)
            sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 3 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 3 -c m", rootdir, (int)minZpos, rootdir);
         else if( posUnits->widgetCB->GetSelected() == 1)
            sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 3 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 3 -c m", rootdir, (int)(minZpos/lenconversion), rootdir);
#if WORKSTAT == 'I'
         retTemp = system(cmd);
#else
         printf("Cmd: %s\n",cmd);
#endif
         xPos->widgetNE[0]->SetNumber(minXpos);
         yPos->widgetNE[0]->SetNumber(minYpos);
         zPos->widgetNE[0]->SetNumber(minZpos);

         progVal = 100.00;
         measProgress->widgetPB->SetPosition(progVal);
         printf("\n");

         // Write information to the finish_sig.txt value
         sprintf(cmd, "%s/dbg/finish_sig.txt", rootdir);
         pfin = fopen(cmd,"w");
         fprintf(pfin, "%s: Surface scan finished.", timeStamp->widgetTE->GetText());
         fclose(pfin);

         measProgress->widgetTB[0]->SetText("Start acquisition");
         acqStarted = false;
      }
   }
   // Only angle scan
   if( (ascan == 1) && (pscan == 0) && (vscan == 0) )
   {
      // If already started, stop the acquisition
      if(acqStarted)
      {
         printf("Stopping current angle scan...\n");
         gROOT->SetInterrupt();
         measProgress->widgetTB[0]->SetText("Start acquisition");
         acqStarted = false;

         // Write information to the finish_sig.txt value
         sprintf(cmd, "%s/dbg/finish_sig.txt", rootdir);
         pfin = fopen(cmd,"w");
         fprintf(pfin, "%s: Angle scan stopped.", timeStamp->widgetTE->GetText());
         fclose(pfin);
      }
      // If stopped, start the acquisition
      else if(!acqStarted)
      {
         printf("Running an incidence angle scan...\n");

         // Check the steps
         minAlpha = rotPosMin->widgetNE[0]->GetNumber();
         maxAlpha = rotPosMax->widgetNE[0]->GetNumber();
         stepAlpha = rotPosStep->widgetNE[0]->GetNumber();

         if(stepAlpha == 0.)
            repetAlpha = 1;
         else
         {
            // Example: min = 40, max = 70, step = 5 (in increasing steps)
            if( (maxAlpha > minAlpha) && (stepAlpha > 0) )
               repetAlpha = ((maxAlpha - minAlpha)/stepAlpha)+1;
            // Example: min = 70, max = 40, step = -5 (in decreasing steps)
            else if( (maxAlpha < minAlpha) && (stepAlpha < 0) )
               repetAlpha = ((minAlpha - maxAlpha)/stepAlpha)-1;
            // Example: min = 70, max = 70 (no scan)
            else if( maxAlpha == minAlpha )
               repetAlpha = 1;
            // If step is not correctly set, stop the acqusition
            else
            {
               // TODO
               printf("Stopping current incidence angle scan...\n");
               gROOT->SetInterrupt();
               measProgress->widgetTB[0]->SetText("Start acquisition");
               acqStarted = false;
               repetAlpha = 0;
            }
         }

         if(DBGSIG) printf("StartAcq(): Angle repetition (%lf,%lf,%lf) = %d\n", minAlpha, maxAlpha, stepAlpha, repetAlpha);

         int angleWait = TMath::Ceil(abs(rotPos->widgetNE[0]->GetNumber()-minAlpha)*15/(rotPos->widgetNE[0]->GetNumMax()));
         if(rotUnits->widgetCB->GetSelected() == 1)
         {
            minAlpha = minAlpha/rotconversion;
            maxAlpha = maxAlpha/rotconversion;
            stepAlpha = stepAlpha/rotconversion;
         }

         i = 0;

         // TODO - Setting button text and acqStarted do not work!
         measProgress->widgetTB[0]->SetText("Stop acquisition");
         acqStarted = true;
         progVal = 0.00;
         measProgress->widgetPB->SetPosition(progVal);
         gVirtualX->Update(1);

         clkt0 = clock();
         timet0 = time(NULL);

         // Setting angle to initial position
         sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 4 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 4 -c m", rootdir, (int)minAlpha, rootdir);
         if(rotUnits->widgetCB->GetSelected() == 0)
            rotPos->widgetNE[0]->SetNumber(minAlpha);
         else if(rotUnits->widgetCB->GetSelected() == 1)
            rotPos->widgetNE[0]->SetNumber(minAlpha*rotconversion);
#if WORKSTAT == 'I'
            retTemp = system(cmd);
#else
            printf("Cmd: %s\n",cmd);
#endif
            fflush(stdout);
       
            printf("Waiting for %ds for rotation platform to move into starting position...\n", angleWait);
            sleep(angleWait);

         while(1)
         {
            if( (repetAlpha > 0) && (i == repetAlpha) ) break;
            else if( (repetAlpha < 0) && (i == -repetAlpha) ) break;
            else if( repetAlpha == 0 ) break;

            progVal = (float)(100.00/abs(repetAlpha))*i;
            measProgress->widgetPB->SetPosition(progVal);

            TimeEstimate(clkt0, timet0, progVal, cmd, singlewait*abs(repetAlpha));
            measProgress->widgetTE->SetText(cmd);

            gVirtualX->Update(1);
       
            fflush(stdout);
            currentAlpha = minAlpha + stepAlpha*i;
            sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 4 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 4 -c m", rootdir, (int)currentAlpha, rootdir);
#if WORKSTAT == 'I'
            retTemp = system(cmd);
#else
            printf("Cmd: %s\n",cmd);
#endif
            fflush(stdout);
       
            printf("Waiting for angle change...\n");
            sleep(singlewait);
            if(rotUnits->widgetCB->GetSelected() == 0)
               rotPos->widgetNE[0]->SetNumber(currentAlpha);
            else if(rotUnits->widgetCB->GetSelected() == 1)
               rotPos->widgetNE[0]->SetNumber(currentAlpha*rotconversion);
            gVirtualX->Update(1);
            printf("Continuing...\n");
       
            // Here comes function to start histogramming <<<<<<<<<<<<<<<<<<<<<<<<
            RunMeas((void*)0, i, scanon); // TODO
            fflush(stdout);

            i++;
         }
       
         // Set angle back to original position
         fflush(stdout);
         printf("Measurement finished, returning to starting incidence angle...\n");
         sprintf(cmd, "sudo %s/src/MIKRO/mikro_ctrl -n 4 -v %d -s la && %s/src/MIKRO/mikro_ctrl -n 4 -c m", rootdir, (int)minAlpha, rootdir);
         if(rotUnits->widgetCB->GetSelected() == 0)
            rotPos->widgetNE[0]->SetNumber(minAlpha);
         else if(rotUnits->widgetCB->GetSelected() == 1)
            rotPos->widgetNE[0]->SetNumber(minAlpha*rotconversion);
#if WORKSTAT == 'I'
         retTemp = system(cmd);
#else
         printf("Cmd: %s\n",cmd);
#endif
         fflush(stdout);
       
         progVal = 100.00;
         measProgress->widgetPB->SetPosition(progVal);
         printf("\n");

         sprintf(cmd, "%s/dbg/finish_sig.txt", rootdir);
         pfin = fopen(cmd,"w");
         fprintf(pfin, "%s: Incidence angle scan finished.", timeStamp->widgetTE->GetText());
         fclose(pfin);

         measProgress->widgetTB[0]->SetText("Start acquisition");
         acqStarted = false;
      }
   }
   // Normal single measurement
   else if( (vscan == 0) && (pscan == 0) && (ascan == 0) )
   {
      // Set the start button to stop and enable stopping of measurement
      if(acqStarted)
      {
         printf("Stopping current single scan...\n");
         gROOT->SetInterrupt();
         measProgress->widgetTB[0]->SetText("Start acquisition");
         acqStarted = false;
      }
      else if(!acqStarted)
      {
         measProgress->widgetTB[0]->SetText("Stop acquisition");
         acqStarted = true;

         printf("Running a single scan...\n");
         clkt0 = clock();
         timet0 = time(NULL);
         RunMeas((void*)0, 0, scanon);
         printf("Measurement finished...\n");
         printf("\n");

         measProgress->widgetTB[0]->SetText("Start acquisition");
         acqStarted = false;
      }
   }
}

// Main measurement window connections ----------------------

// Histogram file selection pane connections ----------------

// File browser for opening histograms
void TGAppMainFrame::SelectDirectory()
{
   int i = fileList->GetNumberOfEntries();
   char *cTemp;

   TGFileInfo file_info;
   const char *filetypes[] = {"Histograms",histextall,0,0};
   file_info.fFileTypes = filetypes;
   cTemp = new char[1024];
   sprintf(cTemp, "%s/results", rootdir);
   file_info.fIniDir = StrDup(cTemp);
   file_info.fMultipleSelection = kTRUE;
   new TGFileDialog(gClient->GetDefaultRoot(), fMain, kFDOpen, &file_info);
   delete[] cTemp;

   TList *files = file_info.fFileNamesList;
   if(files)
   {
      TSystemFile *file;
      TString fname;
      TIter next(files);
      while(file=(TSystemFile*)next())
      {
         fname = file->GetName();
         fileList->AddEntry(fname.Data(), i);
         i++;
      }
   }
   fileList->Layout();
}

// Toggle multiple selection in filelist or delete all entries
void TGAppMainFrame::ListMultiSelect(int opt)
{
   // Enable multiselect
   if(opt == 0)
   {
      fileList->SetMultipleSelections((multiSelect->widgetChBox[0]->IsOn()));

      if(multiSelect->widgetChBox[1]->IsDown())
         multiSelect->widgetChBox[1]->SetState(kButtonUp);
   }
   else if(opt == 1)
   {
      if(multiSelect->widgetChBox[1]->IsDown())
      {
         multiSelect->widgetChBox[0]->SetState(kButtonDown);
         fileList->SetMultipleSelections((multiSelect->widgetChBox[0]->IsOn()));
         for(int i = 0; i < fileList->GetNumberOfEntries(); i++)
            fileList->Select(i,kTRUE);
      }
      else if(!multiSelect->widgetChBox[1]->IsDown())
      {
         multiSelect->widgetChBox[0]->SetState(kButtonUp);
         fileList->SetMultipleSelections((multiSelect->widgetChBox[0]->IsOn()));
         for(int i = 0; i < fileList->GetNumberOfEntries(); i++)
            fileList->Select(i,kFALSE);
      }
   }
}

// Navigation buttons for the filelist (<<, >>) and double click
void TGAppMainFrame::FileListNavigation(int opt)
{
   unsigned int nrfiles = fileList->GetNumberOfEntries();
   int curSel;
   TList *files;
   if( nrfiles > 0 )
   {
      if(opt < -1)
      {
         // turn off multiple selection and select first file on list
         if(multiSelect->widgetChBox[0]->IsOn())
         {
            fileList->SetMultipleSelections(kFALSE);
            multiSelect->widgetChBox[0]->SetState(kButtonUp);
            multiSelect->widgetChBox[1]->SetState(kButtonUp);

            fileList->Select(0,kTRUE);
         }
         else
         {
            // if nothing is selected, curSel will be -1
            curSel = fileList->GetSelected();
            // go to next file on list
            if(opt == -3)
            {
               if( (curSel == (int)(nrfiles-1)) || (curSel == -1) )
                  fileList->Select(0);
               else
                  fileList->Select(curSel+1);
            }
            // go to previous file on list
            else if(opt == -2)
            {
               if( (curSel == 0) || (curSel == -1) )
                  fileList->Select(nrfiles-1);
               else
                  fileList->Select(curSel-1);
            }
         }
      }
   }

   UpdateHistogram(0);
}

// Open the header edit window when pressing on editHeader button
void TGAppMainFrame::HeaderEdit()
{
   bool createTab = true;
   int tabid = -1;

   for(int i = 0; i < fTab->GetNumberOfTabs(); i++)
   {
      if(strcmp("File header editor", fTab->GetTabTab(i)->GetString() ) == 0)
      {
         createTab = false;
         tabid = i;
      }
     
      if(DBGSIG > 1) printf("HeaderEdit(): Name of tab = %s\n", fTab->GetTabTab(i)->GetString() );
   }

   unsigned int nrfiles = fileList->GetNumberOfEntries();
   if(nrfiles > 0)
      HeaderEditTab(fTab, createTab, &tabid);
}

// Clear the histogram file selection list and dark run analysis selection
void TGAppMainFrame::ClearHistogramList()
{
   fileList->RemoveAll();
   darkRun->widgetTE->Clear();
}

// Histogram file selection pane connections ----------------

// Histogram controls pane connections ----------------------

// Readjust the histogram range after changing ADC, TDC, Y range or logarithmic scale (opt: 0 = normal redraw, 1 = export, 2 = redraw when changing which channel to display)
void TGAppMainFrame::UpdateHistogram(int opt)
{
   if(DBGSIG > 1)
   {
      printf("UpdateHistogram(): Clearing the TList\n");
      gDirectory->GetList()->Delete();
      gObjectTable->Print();
   }

   // Do not do normal histogram update if we have multiple files selected
   if( (opt == 0) && (multiSelect->widgetChBox[0]->IsDown()) )
   {
      printf("UpdateHistogram(): To preview changes done to a histogram, please deselect the \"Multiple files select\" option.");
      return;
   }

   // Do not update histogram if we are on the same channel
   if( ((opt == 2) && (selChannel != (int)selectCh->widgetNE[0]->GetNumber())) || (opt < 2) )
   {
      unsigned int nrfiles = fileList->GetNumberOfEntries();
      TCanvas *gCanvas;
      char exportname[512];
      char cTemp[512];
   
      if(opt == 1)
         gCanvas = analysisCanvas->GetCanvas();
   
      if(nrfiles > 0)
      {
         TList *files;
         files = new TList();
         fileList->GetSelectedEntries(files);
         
         if(files)
         {
            for(int i = 0; i < (int)nrfiles; i++)
            {
               if(files->At(i))
               {
                  if(DBGSIG)
                     printf("UpdateHistogram(): Filename: %s\n", files->At(i)->GetTitle());
                  if(opt == 1)
                     remove_ext((char*)files->At(i)->GetTitle(), cTemp);
                  if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DADC) )
                  {
                     sprintf(exportname, "%s_adc%d.pdf", cTemp, (int)selectCh->widgetNE[0]->GetNumber());
                     DisplayHistogram( (char*)(files->At(i)->GetTitle()), 0, opt);
                  }
                  else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DTDC) )
                  {
                     sprintf(exportname, "%s_tdc%d.pdf", cTemp, (int)selectCh->widgetNE[0]->GetNumber());
                     DisplayHistogram( (char*)(files->At(i)->GetTitle()), 1, opt);
                  }
                  else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_2D) )
                  {
                     sprintf(exportname, "%s_adctdc%d.pdf", cTemp, (int)selectCh->widgetNE[0]->GetNumber());
                     DisplayHistogram( (char*)(files->At(i)->GetTitle()), 2, opt);
                  }
   
                  if(opt == 1)
                  {
                     gCanvas->SaveAs(exportname);
                     delete inroot;
                  }
               }
            }
         }
      }
      selChannel = selectCh->widgetNE[0]->GetNumber();
   }

   if(DBGSIG > 1)
   {
      printf("UpdateHistogram(): After drawing histograms (connections)\n");
      gObjectTable->Print();
   }
}

// Options for histogram (logarithmic scale, clean plots)
void TGAppMainFrame::HistogramOptions(int opt)
{
   // Logarithmic scale
   if(opt == 0)
      UpdateHistogram(0);
   // Clean plots
   else if(opt == 1)
   {
      cleanPlots = histOpt->widgetChBox[1]->IsDown();
      UpdateHistogram(0);
   }
}

// Changing the histogram type to display
void TGAppMainFrame::ChangeHisttype(int type)
{
   TGTextButton *pressedB = new TGTextButton();
   int menuID = 0;
   unsigned int nrfiles = fileList->GetNumberOfEntries();

   // ADC histogram
   if(type == 0)
   {
      pressedB = plotType->widgetTB[0];
      menuID = M_ANALYSIS_HISTTYPE_1DADC;

      plotType->widgetTB[1]->SetDown(kFALSE);
      plotType->widgetTB[2]->SetDown(kFALSE);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DTDC);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_2D);
   }
   // TDC histogram
   else if(type == 1)
   {
      pressedB = plotType->widgetTB[1];
      menuID = M_ANALYSIS_HISTTYPE_1DTDC;

      plotType->widgetTB[0]->SetDown(kFALSE);
      plotType->widgetTB[2]->SetDown(kFALSE);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DADC);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_2D);
   }
   // ADC vs. TDC histogram
   else if(type == 2)
   {
      pressedB = plotType->widgetTB[2];
      menuID = M_ANALYSIS_HISTTYPE_2D;

      plotType->widgetTB[0]->SetDown(kFALSE);
      plotType->widgetTB[1]->SetDown(kFALSE);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DADC);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DTDC);
   }

   if( fMenuHisttype->IsEntryChecked(menuID) )
   {
      pressedB->SetDown(kFALSE);
      fMenuHisttype->UnCheckEntry(menuID);
   }
   else if( !fMenuHisttype->IsEntryChecked(menuID) )
   {
      pressedB->SetDown(kTRUE);
      fMenuHisttype->CheckEntry(menuID);
   }

   UpdateHistogram(0);
}

// Histogram controls pane connections ----------------------