Subversion Repositories f9daq

Rev

Blame | Last modification | View Log | RSS feed

#include "workstation.h"
#include "daq.h"
#include "root_include.h"
#include "windowed_test.h"

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

#include "daqscope.h"

//---------------------------------------------------------------
// Subwindow layout class

class TGMdiSubwindow
{
RQ_OBJECT("TGMdiSubwindow")

protected:
   TGMdiFrame       *fMdiFrame;

public:
   TGMdiSubwindow(TGMdiMainFrame *main, int w, int h);

   TGMdiFrame *GetMdiFrame() const { return fMdiFrame; }
   virtual Bool_t CloseWindow();
};

//---------------------------------------------------------------
// Main window class

class TGAppMainFrame
{
RQ_OBJECT("TGAppMainFrame")

protected:
   TGMainFrame     *fMain;
   TGMdiMainFrame  *fMainFrame;
   TGMdiMenuBar    *fMenuBar;
   TGLayoutHints   *fMenuBarItemLayout;
   TGPopupMenu     *fMenuFile, *fMenuAnalysis, *fMenuTools, *fMenuWindow, *fMenuHelp;
   TGPopupMenu     *fMenuHisttype;
   TGMdiSubwindow  *settingsPane, *mainSubwindow, *histogramPane, *histogramPaneFile, *histogramPaneCtr, *fieldpointPane, *headerPane;

   void InitMenu();
   void MeasurementLayout();
   void OpenWindow(int winid);
   void CloseWindow();
   Bool_t About();
public:
   TGAppMainFrame(const TGWindow *p, int w, int h);

   void HandleMenu(Int_t id);

   void EnableVoltScan();
   void EnableSurfScan();
   void EnableZaxisScan();
   void VoltageLimit();
   void ChannelLimit();
   void CleanPlotToggle();
   void ConnectToScope();

   void SetVoltOut();
   void GetVoltOut();
   void ResetVoltOut();
   void SetPosition();
   void GetPosition();
   void HomePosition();

   void InitializeScope();
   void StartScopeAcq();
   void CustomScopeCommand();
   void SelectedMeasType(int mtype);

   void SaveFile();
   void StartAcq();

   void SelectDirectory();
   void ListMultiSelect();
   void ListSelectAll();
   void FileListNavigation(int pn);
   void HeaderEdit();

   void DisplayHistogram(char *histfile, int histtype);
   void SetHistRange();
   void ChangeHisttype(int type);
   void ChangeChannel();
   void HistogramExport();
   void MakeSurfPlot(TList *files);
   void MakeBreakdownPlot(int nrp, double *volt, double *volterr, double *psep1, double *pseperr1, double *psep2, double *pseperr2, double *psep3, double *pseperr3, char *plotfile, int separations);

   void FitSpectrum(TList *files, int q);
   void EdgeDetection(TGraph *pdf, TGraph *cdf, char *outname, TCanvas *g1dCanvas, double pdfmax, int direction);
   void IntegSpectrum(TList *files, int direction);
   void PhotonMu(TList *files);

   void UpdateTempPlot();
   void TempEndToggle();
   void ExportTempPlot();
   void GetTempFile(int set);

   void EditTickToggle(int set);
   void headerchange(char *histfile, bool *changetype);
   void headeredit();

   void RunMeas(void *ptr, int runCase, int zaxisscan, int &scanon);
};

const char *histExt = ".root";
const char *histExtAll = "*.root";
daq *gDaq;
daqscope *gScopeDaq;
//int debugSig = 0;
int retTemp;
int gStop=0;
unsigned int gBuf[BSIZE];
int logchange = 0;
double tdctimeconversion = 45.0909;
double lenconversion = 0.3595;
int oscOn;
const char *allMeasNames[11] = {"Amplitude","Area","Delay","Fall","Frequency","Maximum","Mean","Minimum","Peak-to-peak","Peak width","Rise"};

// ROOT file variable structure -----------
struct EventHeader {
  int nrch;
  int timestamp;
  double biasvolt;
  int xpos;
  int ypos;
  int zpos;
  double temperature;
  double angle;
  char laserinfo[256];
} evtheader;

struct EventData {
  int adcdata[8];
  int tdcdata[8];
} evtdata;

struct EventMeas {
  double measdata;
} evtmeas;

TFile *inroot;
TFile *outroot;

// Test graphs for scope measurements
TCanvas *wCanvas;
TGraph *testgraph;

//---------------------------------------------------------------
// Global variables

TGCheckButton *voltscanOn;
TGCheckButton *surfscanOn;
TGCheckButton *zscanOn;
TGTextEntry   *oscIP;
TGTextButton  *oscConnect;
TGCheckButton *histogramOn;
TGNumberEntry *vHardlimit;
TGNumberEntry *NCH;
TGTextEntry   *laserInfo;
TGNumberEntry *chtemp;
TGNumberEntry *incangle;
TGCheckButton *cleanOn;

TGTab         *setTab;
TGComboBox    *vOutCh;
TGNumberEntry *vOut;
TGCheckButton *vOutOnOff;
TGTextButton  *vOutSet;
TGTextButton  *vOutGet;
TGTextButton  *vOutReset;
TGNumberEntry *vOutStart;
TGNumberEntry *vOutStop;
TGNumberEntry *vOutStep;
TGNumberEntry *xPos;
TGNumberEntry *yPos;
TGNumberEntry *zPos;
TGTextButton  *positionSet;
TGTextButton  *positionGet;
TGTextButton  *positionHome;
TGNumberEntry *xPosMin;
TGNumberEntry *xPosMax;
TGNumberEntry *xPosStep;
TGNumberEntry *yPosMin;
TGNumberEntry *yPosMax;
TGNumberEntry *yPosStep;
TGNumberEntry *zPosMin;
TGNumberEntry *zPosMax;
TGNumberEntry *zPosStep;
TGNumberEntry *evtNum;
TGTextEntry   *timeStamp;
TGTextEntry   *fileName;
TGTextButton  *saveFile;
TGTextButton  *measStart;
TGLabel       *busyLabel;
TGHProgressBar *curProgress;

TRootEmbeddedCanvas *histCanvas;

TGTextButton  *selectDir;
TGListBox     *fileList;
TGCheckButton *multiSelect;
TGCheckButton *multiSelectAll;
TGTextButton  *prevFile;
TGTextButton  *nextFile;
TGTextButton  *editHeader;

TGTextEntry *disptime;
TGNumberEntry *dispbias;
TGTextEntry *disppos;
TGNumberEntry *disptemp;
TGNumberEntry *dispangle;
TGTextEntry *displaser;

TGNumberEntry *adcMinRange;
TGNumberEntry *adcMaxRange;
TGNumberEntry *tdcMinwindow;
TGNumberEntry *tdcMaxwindow;
TGNumberEntry *yMinRange;
TGNumberEntry *yMaxRange;
TGNumberEntry *selectCh;
TGTextButton  *changeADC;
TGTextButton  *changeTDC;
TGTextButton  *changeADCTDC;
TGTextButton  *change2Dsurf;
TGCheckButton *logscale;
TGTextButton  *exportHist;
TGNumberEntry *fitSigma;
TGNumberEntry *fitTresh;
TGNumberEntry *fitInter;
TGNumberEntry *accError;
TGNumberEntry *minPeak;
TGNumberEntry *pedesLow;
TGCheckButton *exfitplots;

TGCheckButton *sCH[8];
TGComboBox    *sMeasType;
TGCheckButton *sCamaclink;
TGTextEntry   *scopeCommand;
TGTextEntry   *scopeReturn;
TGTextButton  *sendScopeCustom;
TGComboBox    *sMeasgroup;
TGTextButton  *scopeInit;

TRootEmbeddedCanvas *displayCanvas;
TGComboBox    *tempCh;
TGComboBox    *tempDay[2];
TGComboBox    *tempMonth[2];
TGComboBox    *tempYear[2];
TGComboBox    *tempHour[2];
TGComboBox    *tempMinute[2];
TGComboBox    *tempSecond[2];
TGTextButton  *tempFile[2];
TGCheckButton *tempEndOn;
TGTextButton  *updateTemp;
TGTextButton  *exportTemp;
//TGTextButton  *closeTemp;

TGCheckButton *biasedittick;
TGNumberEntry *biasedit;
TGCheckButton *posedittick;
TGNumberEntry *posedit[3];
TGCheckButton *tempedittick;
TGNumberEntry *tempedit;
TGCheckButton *angleedittick;
TGNumberEntry *angleedit;
TGCheckButton *laseredittick;
TGTextEntry   *laseredit;
TGTextButton  *editHead;

Bool_t firstrun = kTRUE;
Bool_t started;
Bool_t cleanPlots = kTRUE;

// Layout hints definitions
TGLayoutHints *f0 = new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2);
TGLayoutHints *f0centerx = new TGLayoutHints(kLHintsCenterX,2,2,2,2);
TGLayoutHints *f0centery = new TGLayoutHints(kLHintsLeft | kLHintsCenterY,2,2,2,2);
TGLayoutHints *f0center2d = new TGLayoutHints(kLHintsCenterX | kLHintsCenterY,2,2,2,2);
TGLayoutHints *f0right = new TGLayoutHints(kLHintsRight | kLHintsTop,2,2,2,2);
TGLayoutHints *f1 = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,2,2,2,2);
TGLayoutHints *f2 = new TGLayoutHints(kLHintsExpandX,2,2,2,2);
TGLayoutHints *f3 = new TGLayoutHints(kLHintsCenterY,2,2,20,2);
TGLayoutHints *f3notop = new TGLayoutHints(kLHintsCenterY,4,4,2,30);

// Separate functions -----------------------------------------
void GetTime(int intime, char *outtime)
{
   time_t rawtime;
   struct tm * timeinfo;
   if(intime < 0)
      time(&rawtime);
   else
      rawtime = (time_t)intime;
   timeinfo = localtime(&rawtime);
   sprintf(outtime, "%s", asctime(timeinfo));
   int len = strlen(outtime);
   if(len) outtime[len-1] = 0;
}

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

int GetChannel()
{
   int selectedOutput;
   if(vOutCh->GetSelected() < 8) selectedOutput = (vOutCh->GetSelected())+1;
   else if( (vOutCh->GetSelected() >= 8) && (vOutCh->GetSelected() < 16) ) selectedOutput = (vOutCh->GetSelected())+93;
   else selectedOutput = 1;

   return selectedOutput;
}

void remove_ext(char *inname, char *outname)
{
  char ctemp[256];
  for(int i = 0; i < (int)strlen(inname); i++)
  {
    if( (inname[i] == '.') && (i > (int)(strlen(inname)-6)) )
    {
      ctemp[i] = '\0';
      sprintf(outname, "%s", ctemp);
      break;
    }
    else
      ctemp[i] = inname[i];
  }

  if(debug)
    printf("Outfile (remove_ext): %s\n", outname);
}

void remove_from_last(char *inname, char search, char *outname)
{
   char ctemp[256];
   int searchpos = -1;
   for(int i = (int)strlen(inname); i >= 0; i--)
   {
      if(inname[i] == search)
      {
         searchpos = i;
         break;
      }
   }

   for(int i = 0; i < searchpos; i++)
      ctemp[i] = inname[i];

   ctemp[searchpos] = '\0';
   sprintf(outname, "%s", ctemp);

   if(debug)
      printf("Outfile (remove_from_last): %s\n", outname);
}

void SeqNumber(int innum, int maxnum, char *outstr)
{
   int zeronum = 5;

   // Check how many zeroes we need to add to get sequential numbers
   if( (maxnum > 0) && (maxnum < 1000) )
      zeronum = 2;
   else if( (maxnum >= 1000) && (maxnum < 10000) )
      zeronum = 3;
   else if( (maxnum >= 10000) && (maxnum < 100000) )
      zeronum = 4;
   else if( (maxnum >= 100000) && (maxnum < 1000000) )
      zeronum = 5;

   // Make the sequence number depending on the number of zeroes
   if(zeronum == 2)
   {
      if(innum < 10)
         sprintf(outstr, "00%d", innum);
      else if( (innum >= 10) && (innum < 100) )
         sprintf(outstr, "0%d", innum);
      else if( (innum >= 100) && (innum < 1000) )
         sprintf(outstr, "%d", innum);
   }
   else if(zeronum == 3)
   {
      if(innum < 10)
         sprintf(outstr, "000%d", innum);
      else if( (innum >= 10) && (innum < 100) )
         sprintf(outstr, "00%d", innum);
      else if( (innum >= 100) && (innum < 1000) )
         sprintf(outstr, "0%d", innum);
      else if( (innum >= 1000) && (innum < 10000) )
         sprintf(outstr, "%d", innum);
   }
   else if(zeronum == 4)
   {
      if(innum < 10)
         sprintf(outstr, "0000%d", innum);
      else if( (innum >= 10) && (innum < 100) )
         sprintf(outstr, "000%d", innum);
      else if( (innum >= 100) && (innum < 1000) )
         sprintf(outstr, "00%d", innum);
      else if( (innum >= 1000) && (innum < 10000) )
         sprintf(outstr, "0%d", innum);
      else if( (innum >= 10000) && (innum < 100000) )
         sprintf(outstr, "%d", innum);
   }
   else if(zeronum == 5)
   {
      if(innum < 10)
         sprintf(outstr, "00000%d", innum);
      else if( (innum >= 10) && (innum < 100) )
         sprintf(outstr, "0000%d", innum);
      else if( (innum >= 100) && (innum < 1000) )
         sprintf(outstr, "000%d", innum);
      else if( (innum >= 1000) && (innum < 10000) )
         sprintf(outstr, "00%d", innum);
      else if( (innum >= 10000) && (innum < 100000) )
         sprintf(outstr, "0%d", innum);
      else if( (innum >= 100000) && (innum < 1000000) )
         sprintf(outstr, "%d", innum);
   }
}

// Peak detection function
int npeaks;
double FindPeaks(double *x, double *par)
{
   double result = 0;
   for(int i = 0; i < npeaks; i++)
   {
      double norm = par[3*i];
      double mean = par[3*i+1];
      double sigma = par[3*i+2];
      result += norm*TMath::Gaus(x[0], mean, sigma);
   }
   return result;
}

// Temperature sensor functions -----------------------------
const char* dbname = "mysql://f9lab08.ijs.si/f9phdet";
const char* tblname = "fprtd122";
const char* username = "f9daq";
const char* userpass = "f9lab";

// Get the temperature from MYSQL database
double GetTemperature(int ch, const char *s)
{
   int bin=5+7*4-ch*4;
   char hex[16];
   strncpy(hex, (const char *) &s[bin], 4);
   hex[4]=0;
   int ix;
   sscanf (hex,"%x",&ix);
   //printf("0x%s\t",hex);
   return (ix/65535.)*1050.-200.;
}

// Transform local time to timestamp
int GetTimeStamp(int *intime)
{
   time_t rawtime;
   struct tm * timeinfo;
   time(&rawtime);
   timeinfo = localtime(&rawtime);

   printf("%d.%d.%d, %d:%d:%d\n", intime[0], intime[1], intime[2], intime[3], intime[4], intime[5]);

   timeinfo->tm_mday = intime[0];
   timeinfo->tm_mon = intime[1] - 1;
   timeinfo->tm_year = intime[2] - 1900;
   timeinfo->tm_hour = intime[3];
   timeinfo->tm_min = intime[4];
   timeinfo->tm_sec = intime[5];
   
   return (int)mktime(timeinfo);
}

// Get data from MYSQL database
void fieldpoint(int *timerange, int selch)
{
   char humantime[256];

   // Display selected timestamps
   GetTime(timerange[0], humantime);
   printf("Minimum time set to: %s (%d)\n", humantime, timerange[0]);
   if(timerange[1] != -1)
   {
      GetTime(timerange[1], humantime);
      printf("Maximum time set to: %s (%d)\n", humantime, timerange[1]);
   }
   printf("Selected fieldpoint channel: %d\n", selch);
   printf("\n");

   // Database settings
   TSQLServer *db = TSQLServer::Connect(dbname, username, userpass);
   printf("Server info: %s\n", db->ServerInfo());
   TSQLRow *row;
   TSQLResult *res;

   // list databases available on server
   printf("\nList all databases on server %s\n", db->GetHost());
   res = db->GetDataBases();
   while ((row = res->Next())) {
      printf("%s\n", row->GetField(0));
      delete row;
   }
   delete res;

   // list tables in database "test" (the permission tables)
   printf("\nList all tables in database \"f9phdet\" on server %s\n", db->GetHost());
   res = db->GetTables("f9phdet");
   while ((row = res->Next())) {
      printf("%s\n", row->GetField(0));
      delete row;
   }
   delete res;
   
   // list columns in table "runcatalog" in database "mysql"
   printf("\nList all columns in table \"f9phdet\" in database \"f9rtd122\" on server %s\n", db->GetHost());
   res = db->GetColumns("f9phdet", "fprtd122");
   while ((row = res->Next())) {
      printf("%s\n", row->GetField(0));
      delete row;
   }
   delete res;

   // query database and print results
   char sql[1000] = "SELECT status,data,timestamp FROM fprtd122 WHERE status='A272727272727272748' AND substring(data,1,4)='A00C' ";
   if(timerange[1] == -1)
      sprintf(sql,"%s AND timestamp>='%d'", sql, timerange[0]);
   else
      sprintf(sql,"%s AND timestamp>='%d' AND timestamp<='%d'", sql, timerange[0], timerange[1]);
   printf("%s\n",sql);
   
   res = db->Query(sql);

   int nrows = res->GetRowCount();
   printf("\nGot %d rows in result\n", nrows);
   
   // Printing and plotting
   char timeval[256];
   TGraph *gr;
   gr = new TGraph(nrows);
   gr->SetLineColor(kRed);
   gr->SetLineWidth(1);
   gr->SetMarkerColor(kRed);
   gr->SetMarkerStyle(20);
   gr->SetTitle("Temperature sensor;Time;Temperature (deg.)");

   FILE *fp;
   fp = fopen("./fieldpoint/dataout_fieldpoint.txt", "w");

   if(debug)
      printf("Time\tTemperature\n");
   for (int i = 0; i < nrows; i++) {
      row = res->Next();

      GetTime((int)atof(row->GetField(2)), timeval);
      double x = atof(row->GetField(2));
      double y = GetTemperature(selch,row->GetField(1));
      gr->SetPoint(i,x,y);

      fprintf(fp, "%s\t%f\n",timeval,y);

      if(debug)
         printf("%s\t%f\n",timeval,y);
      
      delete row;
   }

   fclose(fp);

   delete res;
   delete db;

   TCanvas *gCanvas = displayCanvas->GetCanvas();
   gCanvas->SetGrid();
   gr->GetXaxis()->SetTimeDisplay(1);
   gr->GetXaxis()->SetTimeFormat("%d.%m.%H:%M");
   gr->GetXaxis()->SetLabelSize(0.027);
   gr->GetXaxis()->SetTitleSize(0.038);
   gr->GetYaxis()->SetLabelSize(0.027);
   gr->GetYaxis()->SetTitleSize(0.038);
   gr->GetXaxis()->SetNdivisions(515,kTRUE);
   gr->Draw("AL");

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

// Update the temperature plot
void TGAppMainFrame::UpdateTempPlot()
{
   int stime[6];
   int etime[6];

   int timestamp[2];

   time_t rtime;
   int curyear;
   time(&rtime);
   curyear = (int)(localtime(&rtime))->tm_year+1900;

   int leapy = 0;

   // Getting the start time
   stime[0] = (int)(tempDay[0]->GetSelected())+1;
   stime[2] = curyear - (int)(tempYear[0]->GetSelected());
   printf("%d, %d, %d\n", stime[2], curyear, (int)(tempYear[0]->GetSelected()));
   stime[3] = (int)(tempHour[0]->GetSelected());
   stime[4] = (int)(tempMinute[0]->GetSelected());
   stime[5] = (int)(tempSecond[0]->GetSelected());

   switch( tempMonth[0]->GetSelected() )
   {
      case 0:
         stime[1] = (int)(tempMonth[0]->GetSelected())+1;
         break;
      case 1:
         if( stime[2]%4 == 0)
            leapy = 1;

         if( (leapy == 1) && (stime[0] > 29) )
         {
            stime[0] = 29;
            tempDay[0]->Select(28);
         }
         else if( (leapy == 0) && (stime[0] > 28) )
         {
            stime[0] = 28;
            tempDay[0]->Select(27);
         }
         stime[1] = (int)(tempMonth[0]->GetSelected())+1;
         break;
      case 2:
         stime[1] = (int)(tempMonth[0]->GetSelected())+1;
         break;
      case 3:
         if(stime[0] > 30)
         {
            stime[0] = 30;
            tempDay[0]->Select(29);
         }
         stime[1] = (int)(tempMonth[0]->GetSelected())+1;
         break;
      case 4:
         stime[1] = (int)(tempMonth[0]->GetSelected())+1;
         break;
      case 5:
         if(stime[0] > 30)
         {
            stime[0] = 30;
            tempDay[0]->Select(29);
         }
         stime[1] = (int)(tempMonth[0]->GetSelected())+1;
         break;
      case 6:
         stime[1] = (int)(tempMonth[0]->GetSelected())+1;
         break;
      case 7:
         stime[1] = (int)(tempMonth[0]->GetSelected())+1;
         break;
      case 8:
         if(stime[0] > 30)
         {
            stime[0] = 30;
            tempDay[0]->Select(29);
         }
         stime[1] = (int)(tempMonth[0]->GetSelected())+1;
         break;
      case 9:
         stime[1] = (int)(tempMonth[0]->GetSelected())+1;
         break;
      case 10:
         if(stime[0] > 30)
         {
            stime[0] = 30;
            tempDay[0]->Select(29);
         }
         stime[1] = (int)(tempMonth[0]->GetSelected())+1;
         break;
      case 11:
         stime[1] = (int)(tempMonth[0]->GetSelected())+1;
         break;
      default:
         break;
   }

   timestamp[0] = GetTimeStamp(stime);
   printf("Start time: %d\n", timestamp[0]);

   // Getting the end time
   etime[0] = (int)(tempDay[1]->GetSelected())+1;
   etime[2] = curyear - (int)(tempYear[1]->GetSelected());
   etime[3] = (int)(tempHour[1]->GetSelected());
   etime[4] = (int)(tempMinute[1]->GetSelected());
   etime[5] = (int)(tempSecond[1]->GetSelected());

   switch( tempMonth[1]->GetSelected() )
   {
      case 0:
         etime[1] = (int)(tempMonth[1]->GetSelected())+1;
         break;
      case 1:
         if( etime[2]%4 == 0)
            leapy = 1;

         if( (leapy == 1) && (etime[0] > 29) )
         {
            etime[0] = 29;
            tempDay[1]->Select(28);
         }
         else if( (leapy == 0) && (etime[0] > 28) )
         {
            etime[0] = 28;
            tempDay[1]->Select(27);
         }
         etime[1] = (int)(tempMonth[1]->GetSelected())+1;
         break;
      case 2:
         etime[1] = (int)(tempMonth[1]->GetSelected())+1;
         break;
      case 3:
         if(etime[0] > 30)
         {
            etime[0] = 30;
            tempDay[1]->Select(29);
         }
         etime[1] = (int)(tempMonth[1]->GetSelected())+1;
         break;
      case 4:
         etime[1] = (int)(tempMonth[1]->GetSelected())+1;
         break;
      case 5:
         if(etime[0] > 30)
         {
            etime[0] = 30;
            tempDay[1]->Select(29);
         }
         etime[1] = (int)(tempMonth[1]->GetSelected())+1;
         break;
      case 6:
         etime[1] = (int)(tempMonth[1]->GetSelected())+1;
         break;
      case 7:
         etime[1] = (int)(tempMonth[1]->GetSelected())+1;
         break;
      case 8:
         if(etime[0] > 30)
         {
            etime[0] = 30;
            tempDay[1]->Select(29);
         }
         etime[1] = (int)(tempMonth[1]->GetSelected())+1;
         break;
      case 9:
         etime[1] = (int)(tempMonth[1]->GetSelected())+1;
         break;
      case 10:
         if(etime[0] > 30)
         {
            etime[0] = 30;
            tempDay[1]->Select(29);
         }
         etime[1] = (int)(tempMonth[1]->GetSelected())+1;
         break;
      case 11:
         etime[1] = (int)(tempMonth[1]->GetSelected())+1;
         break;
      default:
         break;
   }

   if( tempEndOn->IsDown() )
      timestamp[1] = -1;
   else
      timestamp[1] = GetTimeStamp(etime);
   printf("End time: %d\n", timestamp[1]);

   fieldpoint(timestamp, tempCh->GetSelected());
}

// Export the temperature plot to pdf
void TGAppMainFrame::ExportTempPlot()
{
   TCanvas *gCanvas = displayCanvas->GetCanvas();
   gCanvas->Modified();
   gCanvas->Update();
   gCanvas->SaveAs("./fieldpoint/plotout_fieldpoint.pdf");
}

// Get time information from a saved file
void TGAppMainFrame::GetTempFile(int set)
{
   TGFileInfo file_info;
   const char *filetypes[] = {"Histograms",histExtAll,0,0};
   file_info.fFileTypes = filetypes;
   file_info.fIniDir = StrDup("./results");
   file_info.fMultipleSelection = kFALSE;
   new TGFileDialog(gClient->GetDefaultRoot(), fMain, kFDOpen, &file_info);
   int i = 0;

   TTree *header_data;
   time_t rtime, ctime;
   struct tm * timeinfo;

   int curyear;
   time(&ctime);
   curyear = (int)(localtime(&ctime))->tm_year+1900;

   TList *files = file_info.fFileNamesList;
   TString fname;
   // If multiple files were selected, only use the first one
   if(files)
   {
      printf("Using only the first selected file.\n");

      TSystemFile *file;
      TIter next(files);
      while(i == 0)
      {
         file=(TSystemFile*)next();
         fname = file->GetName();
         i++;
      }
   }
   // If only one file was selected, use it
   else
      fname = file_info.fFilename;

   if((int)fname.Length() > 0)
   {
      inroot = new TFile(fname, "READ");
      
      inroot->GetObject("header_data", header_data);
      
      // Reading the timestamp information
      header_data->SetBranchAddress("timestamp", &evtheader.timestamp);
      header_data->GetEntry(0);
      
      rtime = (time_t)evtheader.timestamp;
      timeinfo = localtime(&rtime);
//   printf("Time: %d.%d.%d, %d:%d:%d\n", timeinfo->tm_mday, timeinfo->tm_mon+1, timeinfo->tm_year+1900, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);

      tempDay[set]->Select(timeinfo->tm_mday - 1);
      tempMonth[set]->Select(timeinfo->tm_mon);
      tempYear[set]->Select(curyear - (timeinfo->tm_year+1900));
      tempHour[set]->Select(timeinfo->tm_hour);
      tempMinute[set]->Select(timeinfo->tm_min);
      tempSecond[set]->Select(timeinfo->tm_sec);

      inroot->Close();
   }
   else
      printf("No file selected.\n");
   
   delete inroot;
}

// Toggle the endtime settings for temperature sensor
void TGAppMainFrame::TempEndToggle()
{
   if( tempEndOn->IsDown() )
   {
      tempDay[1]->SetEnabled(kFALSE);
      tempMonth[1]->SetEnabled(kFALSE);
      tempYear[1]->SetEnabled(kFALSE);
      tempHour[1]->SetEnabled(kFALSE);
      tempMinute[1]->SetEnabled(kFALSE);
      tempSecond[1]->SetEnabled(kFALSE);
      tempFile[1]->SetEnabled(kFALSE);
   }
   else
   {
      tempDay[1]->SetEnabled(kTRUE);
      tempMonth[1]->SetEnabled(kTRUE);
      tempYear[1]->SetEnabled(kTRUE);
      tempHour[1]->SetEnabled(kTRUE);
      tempMinute[1]->SetEnabled(kTRUE);
      tempSecond[1]->SetEnabled(kTRUE);
      tempFile[1]->SetEnabled(kTRUE);
   }
}

// --------------------------------------------------------------

// Header editor functions --------------------------------------

// Toggle the edit possibility for header entries
void TGAppMainFrame::EditTickToggle(int set)
{
   if(set == 1)
   {
      if(biasedittick->IsDown()) biasedit->SetState(kTRUE);
      else biasedit->SetState(kFALSE);
   }
   else if(set == 2)
   {
      if(posedittick->IsDown())
      {
         posedit[0]->SetState(kTRUE);
         posedit[1]->SetState(kTRUE);
         posedit[2]->SetState(kTRUE);
      }
      else
      {
         posedit[0]->SetState(kFALSE);
         posedit[1]->SetState(kFALSE);
         posedit[2]->SetState(kFALSE);
      }
   }
   else if(set == 3)
   {
      if(tempedittick->IsDown()) tempedit->SetState(kTRUE);
      else tempedit->SetState(kFALSE);
   }
   else if(set == 4)
   {
      if(angleedittick->IsDown()) angleedit->SetState(kTRUE);
      else angleedit->SetState(kFALSE);
   }
   else if(set == 5)
   {
      if(laseredittick->IsDown()) laseredit->SetState(kTRUE);
      else laseredit->SetState(kFALSE);
   }
}

// Run the editing of file headers
void TGAppMainFrame::headerchange(char *histfile, bool *changetype)
{
   if(debug)
      printf("Selected file: %s\n", histfile);

   // Preparing input file and the temporary output file
   inroot = new TFile(histfile, "READ");

   char outname[256];
   sprintf(outname, "%s/results/temp.root", rootdir);
   outroot = new TFile(outname, "RECREATE");

   // Tree structure of input file
   TTree *header_data, *meas_data, *scope_data;

   inroot->GetObject("header_data", header_data);
   inroot->GetObject("meas_data", meas_data);
   inroot->GetObject("scope_data", scope_data);

   // Tree structure of output file
   TTree *new_meas_data = meas_data->CloneTree();
   TTree *new_scope_data = scope_data->CloneTree();

   // Save branches from the old header to temporary variables
   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);

   int itemp[5] = {0,0,0,0,0};
   double dtemp[3] = {0.,0.,0.};
   char ctemp[256];

   itemp[0] = evtheader.nrch;
   itemp[1] = evtheader.timestamp;
   itemp[2] = evtheader.xpos;
   itemp[3] = evtheader.ypos;
   itemp[4] = evtheader.zpos;
   dtemp[0] = evtheader.biasvolt;
   dtemp[1] = evtheader.temperature;
   if( header_data->FindBranch("angle") )
      dtemp[2] = evtheader.angle;
   else
      dtemp[2] = 0.;
   sprintf(ctemp, "%s", evtheader.laserinfo);

   delete header_data;
   delete meas_data;
   delete scope_data;
   inroot->Close();
   delete inroot;
  
   // Prepare branches for the new header
   TTree *new_header_data = new TTree("header_data", "Header information for the measurement.");
   new_header_data->Branch("nrch", &evtheader.nrch, "nrch/I");
   new_header_data->Branch("timestamp", &evtheader.timestamp, "timestamp/I");
   new_header_data->Branch("biasvolt", &evtheader.biasvolt, "biasvolt/D");
   new_header_data->Branch("xpos", &evtheader.xpos, "xpos/I");
   new_header_data->Branch("ypos", &evtheader.ypos, "ypos/I");
   new_header_data->Branch("zpos", &evtheader.zpos, "zpos/I");
   new_header_data->Branch("temperature", &evtheader.temperature, "temperature/D");
   new_header_data->Branch("angle", &evtheader.angle, "temperature/D");
   new_header_data->Branch("laserinfo", &evtheader.laserinfo, "laserinfo/C");

   // Save new values (and old ones where we don't want to edit anything)
   evtheader.nrch = itemp[0];
   evtheader.timestamp = itemp[1];
   if(changetype[0])
      evtheader.biasvolt = (double)biasedit->GetNumber();
   else
      evtheader.biasvolt = dtemp[0];
   if(changetype[1])
   {
      evtheader.xpos = (int)posedit[0]->GetNumber();
      evtheader.ypos = (int)posedit[1]->GetNumber();
      evtheader.zpos = (int)posedit[2]->GetNumber();
   }
   else
   {
      evtheader.xpos = itemp[2];
      evtheader.ypos = itemp[3];
      evtheader.zpos = itemp[4];
   }
   if(changetype[2])
      evtheader.temperature = (double)tempedit->GetNumber();
   else
      evtheader.temperature = dtemp[1];
   if(changetype[3])
      evtheader.angle = (double)angleedit->GetNumber();
   else
      evtheader.angle = dtemp[2];
   if(changetype[4])
      sprintf(evtheader.laserinfo, "%s", laseredit->GetText());
   else
      sprintf(evtheader.laserinfo, "%s", ctemp);

   new_header_data->Fill();

   // Write down the temporary output file
   new_header_data->Write();
   new_meas_data->Write();
   new_scope_data->Write();

   delete new_header_data;
   delete new_meas_data;
   delete new_scope_data;
   outroot->Close();
   delete outroot;

   // Replace the original file with temporary output file (and delete temporary file)
   sprintf(outname, "cp -f %s/results/temp.root %s", rootdir, histfile);
   retTemp = system(outname);
   sprintf(outname, "rm -f %s/results/temp.root", rootdir);
   retTemp = system(outname);

   printf("Edited header in file: %s\n", histfile);
}

// Setup the editing of file headers
void TGAppMainFrame::headeredit()
{
   unsigned int nrfiles = fileList->GetNumberOfEntries();
   TList *files;
   // Changelist: Bias, Position, Temperature, Angle, Laser info
   bool changelist[] = { biasedittick->IsDown(), posedittick->IsDown(), tempedittick->IsDown(), angleedittick->IsDown(), laseredittick->IsDown() };

   if( nrfiles > 0 )
   {
      // check the selected file/files and return its name/their names
      files = new TList();
      fileList->GetSelectedEntries(files);
      if(files)
      {
         for(int i = 0; i < (int)nrfiles; i++)
         {
            if(files->At(i))
            {
               if(debug)
                  printf("Filename: %s\n", files->At(i)->GetTitle());

               headerchange( (char*)(files->At(i)->GetTitle()), changelist );
            }
         }
      }
   }
}

// --------------------------------------------------------------

// Class related functions --------------------------------------

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

// Apply the upper channel limit from settings pane to histogram settings
void TGAppMainFrame::ChannelLimit()
{
   selectCh->SetLimitValues(0, (NCH->GetNumber()-1) );
}

// Enable or disable voltage scan controls
void TGAppMainFrame::EnableVoltScan()
{
   if(voltscanOn->IsOn())
   {
      vOutStart->SetState(kTRUE);
      vOutStop->SetState(kTRUE);
      vOutStep->SetState(kTRUE);
   }
   else
   {
      vOutStart->SetState(kFALSE);
      vOutStop->SetState(kFALSE);
      vOutStep->SetState(kFALSE);
   }
}

// Enable or disable surface scan controls
void TGAppMainFrame::EnableSurfScan()
{
   if(surfscanOn->IsOn())
   {
      xPosMin->SetState(kTRUE);
      xPosMax->SetState(kTRUE);
      xPosStep->SetState(kTRUE);
      yPosMin->SetState(kTRUE);
      yPosMax->SetState(kTRUE);
      yPosStep->SetState(kTRUE);
   }
   else
   {
      xPosMin->SetState(kFALSE);
      xPosMax->SetState(kFALSE);
      xPosStep->SetState(kFALSE);
      yPosMin->SetState(kFALSE);
      yPosMax->SetState(kFALSE);
      yPosStep->SetState(kFALSE);
   }
}

// Enable or disable Z axis scan controls
void TGAppMainFrame::EnableZaxisScan()
{
   if(zscanOn->IsOn())
   {
      zPosMin->SetState(kTRUE);
      zPosMax->SetState(kTRUE);
      zPosStep->SetState(kTRUE);
   }
   else
   {
      zPosMin->SetState(kFALSE);
      zPosMax->SetState(kFALSE);
      zPosStep->SetState(kFALSE);
   }
}

// Toggle clean plots on/off
void TGAppMainFrame::CleanPlotToggle()
{
   cleanPlots = cleanOn->IsDown();
}

// Connect to oscilloscope
void TGAppMainFrame::ConnectToScope()
{
   int scopeState = -1;
   char *IPaddr = (char*)oscIP->GetText();
   int IPcorr = 0;

   if(oscOn == 0)
   {
      // Check if the IP address has the required three .
      for(int i = 0; i < (int)strlen(IPaddr); i++)
         if(IPaddr[i] == '.')
            IPcorr++;
    
      if( (IPaddr != NULL) && (IPcorr == 3) )
      {
#if WORKSTAT == 'I' || WORKSTAT == 'S'
         printf("Connecting to oscilloscope.\n");
         retTemp = gScopeDaq->connect(IPaddr);
         scopeState = 1; // For testing instead of making a real connection
#else
         scopeState = 1;
         retTemp = 0;
#endif
      }
      else
      {
         scopeState = -1;
         printf("Please enter a valid scope IP address.\n");
      }
   }
   else if(oscOn > 0)
   {
#if WORKSTAT == 'I' || WORKSTAT == 'S'
         printf("Disconnecting from oscilloscope.\n");
         retTemp = gScopeDaq->disconnect(IPaddr);
         scopeState = -1; // For testing instead of making a real disconnection
#else
         scopeState = -1;
         retTemp = 0;
#endif
   }

   if(retTemp == 0)
   {
      if(scopeState >= 0)
      {
         oscIP->SetEnabled(kFALSE);
         oscConnect->SetText("Disconnect");
         oscConnect->SetTextJustify(36);
         oscConnect->SetWrapLength(-1);
         oscConnect->Resize(60,22);

         for(int i = 0; i < 8; i++)
         {
            sCH[i]->SetState(kButtonUp);
            sCH[i]->SetEnabled(kFALSE);
         }
         sMeasType->SetEnabled(kTRUE);
         sCamaclink->SetState(kButtonUp);
         sCamaclink->SetEnabled(kFALSE);
         scopeCommand->SetEnabled(kTRUE);
         sendScopeCustom->SetEnabled(kTRUE);
         sMeasgroup->SetEnabled(kFALSE);
         scopeInit->SetEnabled(kFALSE);
       
         oscOn = 1;
      }
      else
      {
         oscIP->SetEnabled(kTRUE);
         oscConnect->SetText("Connect");
         oscConnect->SetTextJustify(36);
         oscConnect->SetWrapLength(-1);
         oscConnect->Resize(60,22);
    
         for(int i = 0; i < 8; i++)
         {
            sCH[i]->SetState(kButtonUp);
            sCH[i]->SetEnabled(kFALSE);
         }
         sMeasType->Select(0);
         sMeasType->SetEnabled(kFALSE);
         sCamaclink->SetState(kButtonUp);
         sCamaclink->SetEnabled(kFALSE);
         scopeCommand->SetEnabled(kFALSE);
         sendScopeCustom->SetEnabled(kFALSE);
         sMeasgroup->SetEnabled(kFALSE);
         scopeInit->SetEnabled(kFALSE);
    
         oscOn = 0;
      }
   }
   else
      printf("Error! Connecting/disconnecting failed.\n");
}

// Set the output voltage
void TGAppMainFrame::SetVoltOut()
{
   char cmd[256];
   int outOn;
   float outputVoltage;

   outputVoltage = vOut->GetNumber();

   if(vOutOnOff->IsOn()) outOn = 1;
   else outOn = 0;
  
   fflush(stdout);
   sprintf(cmd, "%s/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 the output voltage
void TGAppMainFrame::GetVoltOut()
{
   char cmd[256];

   fflush(stdout);
   sprintf(cmd, "%s/mpod/mpod_voltage.sh -o %d -g > %s/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/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->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 )
         vOutOnOff->SetState(kButtonDown);
      else if( strcmp(ctemp, "Off(0)") == 0 )
         vOutOnOff->SetState(kButtonUp);
   }

   fclose(fvolt);
#endif
}

// Reset the output voltage
void TGAppMainFrame::ResetVoltOut()
{
   char cmd[256];

   vOut->SetNumber(0.000);
   vOutOnOff->SetState(kButtonUp);

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

// Get the current table position
void TGAppMainFrame::GetPosition()
{
   char cmd[256];
  
   fflush(stdout);
   
   sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 1 -p > %s/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/MIKRO/mikro_ctrl -n 2 -p >> %s/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/MIKRO/mikro_ctrl -n 3 -p >> %s/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/curpos.txt", rootdir);
   fpos = fopen(cmd, "r");
   
   if(fpos != NULL)
   {
      retTemp = fscanf(fpos, "%d\n", &itemp);
      xPos->SetNumber(itemp);
      retTemp = fscanf(fpos, "%d\n", &itemp);
      yPos->SetNumber(itemp);
      retTemp = fscanf(fpos, "%d\n", &itemp);
      zPos->SetNumber(itemp);
   }

   fclose(fpos);
#endif
}

// Set the current table position
void TGAppMainFrame::SetPosition()
{
   char cmd[256];
   int positX, positY, positZ;
  
   positX = xPos->GetNumber();
   positY = yPos->GetNumber();
   positZ = zPos->GetNumber();
  
   sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 1 -v %d -s la && %s/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/MIKRO/mikro_ctrl -n 2 -v %d -s la && %s/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/MIKRO/mikro_ctrl -n 3 -v %d -s la && %s/MIKRO/mikro_ctrl -n 3 -c m", rootdir, positZ, rootdir);
#if WORKSTAT == 'I'
   retTemp = system(cmd);
#else
   printf("Cmd: %s\n",cmd);
#endif
}

// Set the current table position to a predetermined HOME position
void TGAppMainFrame::HomePosition()
{
   char cmd[256];

   sprintf(cmd, "sudo %s/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/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/MIKRO/mikro_ctrl -n 3 -h", rootdir);   // Z-axis
#if WORKSTAT == 'I'
   retTemp = system(cmd);
#else
   printf("Cmd: %s\n",cmd);
#endif
}

// Initialize the currently connected scope for measurements
void TGAppMainFrame::InitializeScope()
{
   int iTemp;
   int chTemp[8];
   for(int i = 0; i < 8; i++) chTemp[i] = -1;
   gScopeDaq->scopeUseType = sMeasType->GetSelected();

   // Check what channels are selected
   iTemp = 0;
   for(int i = 0; i < 8; i++)
   {
      if(sCH[i]->IsDown())
      {
         chTemp[iTemp] = i;
         iTemp++;
      }
   }
   if(iTemp == 0)
   {
      // If no channel is selected, we select the first one
      chTemp[0] = 0;
      iTemp++;
      sCH[0]->SetState(kButtonDown);
   }
   // If measurement is used, only use the first selected channel
   if(gScopeDaq->scopeUseType == 2)
   {
      for(int i = 1; i < iTemp; i++)
         sCH[chTemp[i]]->SetState(kButtonUp);
      iTemp = 1;
   }

   gScopeDaq->scopeChanNr = iTemp;
   for(int i = 0; i < 8; i++) gScopeDaq->scopeChans[i] = chTemp[i];

   // Check which measurement is selected
   gScopeDaq->scopeMeasSel = sMeasgroup->GetSelected();

   gScopeDaq->init();
}

// Run a scope measurement
void TGAppMainFrame::StartScopeAcq()
{
   // Lock the scope front panel
   gScopeDaq->lockunlock(true);

   retTemp = gScopeDaq->event();

   if(gScopeDaq->scopeUseType == 1)
   {
      char len[16];
      int sval;
      short *spoints;

      if(retTemp == 0)
      {
         // Read the number of y bytes at beginning of CURVE binary data
         memcpy(len, &gScopeDaq->eventbuf[1],1);
         len[1] = 0;
         sval = atoi(len);
//         printf("Number of y bytes = %d\n", sval);

         // Read the data
         spoints = (short *)(&gScopeDaq->eventbuf[2+sval]);
       
         // Read the number of data points
         memcpy(len, &gScopeDaq->eventbuf[2],sval);
         len[sval] = 0;
         sval = atoi(len);
//         printf("Number of data points = %d\n", sval/2);

         double *grafx, *grafy;
         grafx = new double[sval/2];
         grafy = new double[sval/2];
         // Parse data and graph it
         for(int i = 0; i < sval/2; i++)
         {
            grafx[i] = i*gScopeDaq->tektime*10./(sval/2.);
            grafy[i] = ((double)spoints[i]*5.*gScopeDaq->tekvolt/32767.) - (gScopeDaq->choffset*gScopeDaq->tekvolt);
         }
       
         wCanvas->cd();
         testgraph = new TGraph(sval/2, grafx, grafy);
         testgraph->GetXaxis()->SetTitle("Time [s]");
         testgraph->GetXaxis()->SetRangeUser(grafx[0], grafx[(sval/2)-1]);
         testgraph->GetYaxis()->SetTitle("Voltage [V]");
         testgraph->Draw("AL");
         wCanvas->Modified();
         wCanvas->Update();
       
         delete[] grafx;
         delete[] grafy;
      }
   }
   else if(gScopeDaq->scopeUseType == 2)
   {
      if(retTemp == 0)
      {
         if(gScopeDaq->measubuf < 1.e-4)
            printf("Measurement: %le\n", gScopeDaq->measubuf);
         else
            printf("Measurement: %lf\n", gScopeDaq->measubuf);
      }
   }

   // Unlock the scope front panel
   gScopeDaq->lockunlock(false);
}

// Send a custom command to the scope
void TGAppMainFrame::CustomScopeCommand()
{
   char *cmd = (char*)scopeCommand->GetText();
   char ret[100000];
   if( strchr(cmd, '?') == NULL)
   {
      printf("Sending command: %s\n", cmd);
#if WORKSTAT == 'I' || WORKSTAT == 'S'
      gScopeDaq->customCommand(cmd, false, ret);
#endif
   }
   else
   {
      printf("Sending query: %s\n", cmd);
#if WORKSTAT == 'I' || WORKSTAT == 'S'
      gScopeDaq->customCommand(cmd, true, ret);
#endif
   }

#if WORKSTAT == 'I' || WORKSTAT == 'S'
   scopeReturn->SetText(ret);
#endif

#if WORKSTAT == 'O'
   sprintf(ret, "Program running in offline mode. Use I or S when configuring...");
   scopeReturn->SetText(ret);
#endif
}

// When we select the measurement type, change other scope settings accordingly
void TGAppMainFrame::SelectedMeasType(int mtype)
{
   // No waveform analysis
   if(mtype == 0)
   {
      for(int i = 0; i < 8; i++)
      {
         sCH[i]->SetState(kButtonUp);
         sCH[i]->SetEnabled(kFALSE);
      }
      sMeasType->SetEnabled(kTRUE);
      sCamaclink->SetState(kButtonUp);
      sCamaclink->SetEnabled(kFALSE);
      scopeCommand->SetEnabled(kTRUE);
      sendScopeCustom->SetEnabled(kTRUE);
      sMeasgroup->SetEnabled(kFALSE);
      scopeInit->SetEnabled(kFALSE);
    
      oscOn = 1;
   }
   // Complete waveform acquisition
   else if(mtype == 1)
   {
      for(int i = 0; i < 8; i++)
         sCH[i]->SetEnabled(kTRUE);
      sMeasType->SetEnabled(kTRUE);
      sCamaclink->SetState(kButtonDown);
      sCamaclink->SetEnabled(kTRUE);
      scopeCommand->SetEnabled(kTRUE);
      sendScopeCustom->SetEnabled(kTRUE);
      sMeasgroup->SetEnabled(kFALSE);
      scopeInit->SetEnabled(kTRUE);
    
      oscOn = 2;
   }
   // Waveform measurements
   else if(mtype == 2)
   {
      for(int i = 0; i < 8; i++)
         sCH[i]->SetEnabled(kTRUE);
      sMeasType->SetEnabled(kTRUE);
      sCamaclink->SetState(kButtonUp);
      sCamaclink->SetEnabled(kTRUE);
      scopeCommand->SetEnabled(kTRUE);
      sendScopeCustom->SetEnabled(kTRUE);
      sMeasgroup->SetEnabled(kTRUE);
      scopeInit->SetEnabled(kTRUE);
    
      oscOn = 3;
   }
}

// Make breakdown voltage plot
void TGAppMainFrame::MakeBreakdownPlot(int nrp, double *volt, double *volterr, double *psep1, double *pseperr1, double *psep2, double *pseperr2, double *psep3, double *pseperr3, char *plotfile, int separations)
{
   double fparam[2], fparamerr[2], meanval;
   TLatex *latex;
   char ctemp[256];
   int sortindex[nrp];

   TCanvas *canvas;

   if(separations == 1)
   {
      canvas = new TCanvas("canv","canv",900,400);
   }
   else if(separations == 2)
   {
      canvas = new TCanvas("canv","canv",900,800);
      canvas->Divide(1,2);
   }
   else
   {
      canvas = new TCanvas("canv","canv",900,1200);
      canvas->Divide(1,3);
   }

   // First graph is plotted always
   TGraphErrors *gr1 = new TGraphErrors(nrp, volt, psep1, volterr, pseperr1);
  
   if(!cleanPlots)
      gr1->SetTitle("1st - 2nd peak separation");
   else
      gr1->SetTitle();
   gr1->SetLineColor(kBlue);
   gr1->SetMarkerColor(kBlue);
   gr1->SetMarkerStyle(20);
   gr1->SetMarkerSize(0.4);
 
   // Plotting the first breakdown voltage plot
   canvas->cd(1);
   gPad->SetGridx(1);
   gPad->SetGridy(1);

   gr1->Draw("AP");
   gr1->GetXaxis()->SetTitle("Bias voltage (V)");
   gr1->GetYaxis()->SetTitle("Peak separation");
   gr1->GetYaxis()->CenterTitle();
   gr1->Fit("pol1","Q");
  
   TF1 *fit1 = gr1->GetFunction("pol1");
   fparam[0] = fit1->GetParameter(0);
   fparamerr[0] = fit1->GetParError(0); 
   fparam[1] = fit1->GetParameter(1);
   fparamerr[1] = fit1->GetParError(1);

   TMath::Sort(nrp, psep1, sortindex, kFALSE);

   meanval = -fparam[0]/fparam[1];
   if(!cleanPlots)
   {
      sprintf(ctemp, "#splitline{#Delta_{p}(U) = (%.2lf #pm %.2lf)#timesU + (%.2lf #pm %.3lf)}{U_{0} = %.2lf #pm %.3lf}", fparam[0], fparamerr[0], fparam[1], fparamerr[1], meanval, meanval*(TMath::Abs(fparamerr[0]/fparam[0]) + TMath::Abs(fparamerr[1]/fparam[1])) );
      latex = new TLatex();
      latex->SetTextSize(0.039);
      latex->DrawLatex(volt[0], 0.97*psep1[sortindex[nrp-1]], ctemp);
   }
   else
      printf("#Delta_p(U) = (%.2lf #pm %.2lf)*U + (%.2lf #pm %.3lf)\nU_0 = %.2lf #pm %.3lf", fparam[0], fparamerr[0], fparam[1], fparamerr[1], meanval, meanval*(TMath::Abs(fparamerr[0]/fparam[0]) + TMath::Abs(fparamerr[1]/fparam[1])) );

   // Second graph
   if(separations > 1)
   {
      TGraphErrors *gr2 = new TGraphErrors(nrp, volt, psep2, volterr, pseperr2);
     
      if(!cleanPlots)
         gr2->SetTitle("2nd - 3rd peak separation");
      else
         gr2->SetTitle();
      gr2->SetLineColor(kMagenta);
      gr2->SetMarkerColor(kMagenta);
      gr2->SetMarkerStyle(21);
      gr2->SetMarkerSize(0.4);
    
      // Plotting the second breakdown voltage plot
      canvas->cd(2);
      gPad->SetGridx(1);
      gPad->SetGridy(1);
    
      gr2->Draw("AP");
      gr2->GetXaxis()->SetTitle("Bias voltage (V)");
      gr2->GetYaxis()->SetTitle("Peak separation");
      gr2->GetYaxis()->CenterTitle();
      gr2->Fit("pol1","Q");
     
      TF1 *fit2 = gr2->GetFunction("pol1");
      fparam[0] = fit2->GetParameter(0);
      fparamerr[0] = fit2->GetParError(0); 
      fparam[1] = fit2->GetParameter(1);
      fparamerr[1] = fit2->GetParError(1);
    
      meanval = -fparam[0]/fparam[1];
      if(!cleanPlots)
      {
         sprintf(ctemp, "#splitline{#Delta_{p}(U) = (%.2lf #pm %.2lf)#timesU + (%.2lf #pm %.3lf)}{U_{0} = %.2lf #pm %.3lf}", fparam[0], fparamerr[0], fparam[1], fparamerr[1], meanval, meanval*(TMath::Abs(fparamerr[0]/fparam[0]) + TMath::Abs(fparamerr[1]/fparam[1])) );
         latex = new TLatex();
         latex->SetTextSize(0.039);
         latex->DrawLatex(volt[0], 0.97*psep2[sortindex[nrp-1]], ctemp);
      }
      else
         printf("#Delta_p(U) = (%.2lf #pm %.2lf)*U + (%.2lf #pm %.3lf)\nU_0 = %.2lf #pm %.3lf", fparam[0], fparamerr[0], fparam[1], fparamerr[1], meanval, meanval*(TMath::Abs(fparamerr[0]/fparam[0]) + TMath::Abs(fparamerr[1]/fparam[1])) );
   }

   // Third graph
   if(separations > 2)
   {
      TGraphErrors *gr3 = new TGraphErrors(nrp, volt, psep3, volterr, pseperr3);
     
      if(!cleanPlots)
         gr3->SetTitle("3rd - 4th peak separation");
      else
         gr3->SetTitle();
      gr3->SetLineColor(kGreen);
      gr3->SetMarkerColor(kGreen);
      gr3->SetMarkerStyle(22);
      gr3->SetMarkerSize(0.4);
    
      // Plotting the third breakdown voltage plot
      canvas->cd(3);
      gPad->SetGridx(1);
      gPad->SetGridy(1);
    
      gr3->Draw("AP");
      gr3->GetXaxis()->SetTitle("Bias voltage (V)");
      gr3->GetYaxis()->SetTitle("Peak separation");
      gr3->GetYaxis()->CenterTitle();
      gr3->Fit("pol1","Q");
     
      TF1 *fit3 = gr3->GetFunction("pol1");
      fparam[0] = fit3->GetParameter(0);
      fparamerr[0] = fit3->GetParError(0); 
      fparam[1] = fit3->GetParameter(1);
      fparamerr[1] = fit3->GetParError(1);
    
      meanval = -fparam[0]/fparam[1];
      if(!cleanPlots)
      {
         sprintf(ctemp, "#splitline{#Delta_{p}(U) = (%.2lf #pm %.2lf)#timesU + (%.2lf #pm %.3lf)}{U_{0} = %.2lf #pm %.3lf}", fparam[0], fparamerr[0], fparam[1], fparamerr[1], meanval, meanval*(TMath::Abs(fparamerr[0]/fparam[0]) + TMath::Abs(fparamerr[1]/fparam[1])) );
         latex = new TLatex();
         latex->SetTextSize(0.039);
         latex->DrawLatex(volt[0], 0.97*psep3[sortindex[nrp-1]], ctemp);
      }
      else
         printf("#Delta_p(U) = (%.2lf #pm %.2lf)*U + (%.2lf #pm %.3lf)\nU_0 = %.2lf #pm %.3lf", fparam[0], fparamerr[0], fparam[1], fparamerr[1], meanval, meanval*(TMath::Abs(fparamerr[0]/fparam[0]) + TMath::Abs(fparamerr[1]/fparam[1])) );
   }

   // Saving the produced plot
   canvas->SaveAs(plotfile);
}

// Fit the ADC spectrum peaks and make a breakdown voltage plot
void TGAppMainFrame::FitSpectrum(TList *files, int q)
{
   TCanvas *gCanvas = histCanvas->GetCanvas();
   gCanvas->cd();
   TH1F *histtemp;
   TSpectrum *spec;
   TH1 *histback;
   TH1F *h2;
   float *xpeaks;
   TF1 *fit;
   TF1 *fittingfunc;
   double *fparam;
   double *fparamerr;
   double meanparam[20], meanparamerr[20];
   int sortindex[20];
   char exportname[256];
   char paramname[256];
   char ctemp[256];

   FILE *fp;
   remove_from_last((char*)files->At(0)->GetTitle(), '_', ctemp);
   sprintf(paramname, "%s_fitresult.txt", ctemp);
   fp = fopen(paramname, "w");
   fclose(fp);

   int peaklimit = minPeak->GetNumber()+1; // +1 to account for the pedestal peak
   printf("The minimum peak limit is set to: %d\n", peaklimit);
   int p = 0;
   double dtemp;
   double volt[files->GetSize()], volterr[files->GetSize()], sep[3][files->GetSize()], seperr[3][files->GetSize()]; 
   int first = 1;

   // Initialize all values
   for(int m = 0; m < files->GetSize(); m++)
   {
      volt[m] = 0; volterr[m] = 0;
      for(int i = 0; i < 3; i++)
      { sep[i][m] = 0; seperr[i][m] = 0; }
      if(m < 20) { meanparam[m] = 0; meanparamerr[m] = 0; }
   }

   for(int m = 0; m < files->GetSize(); m++)
   {
      DisplayHistogram( (char*)(files->At(m)->GetTitle()), 0);
      dtemp = evtheader.biasvolt;
      gCanvas->Modified();
      gCanvas->Update();

      histtemp = (TH1F*)gCanvas->GetPrimitive(histname);
      npeaks = 20;
      double par[3000];
      spec = new TSpectrum(npeaks);
      // Find spectrum background
      histback = spec->Background(histtemp, (int)fitInter->GetNumber(), "same");
      // Clone histogram and subtract background from it
      h2 = (TH1F*)histtemp->Clone("h2");
      h2->Add(histback, -1);
      // Search for the peaks
      int found = spec->Search(h2, fitSigma->GetNumber(), "goff", fitTresh->GetNumber() );
      printf("Found %d candidates to fit.\n",found);
      npeaks = found;
    
      xpeaks = spec->GetPositionX();
      for(int i = 0; i < found; i++)
      {
         float xp = xpeaks[i];
         int bin = h2->GetXaxis()->FindBin(xp);
         float yp = h2->GetBinContent(bin);
         par[3*i] = yp;
         par[3*i+1] = xp;
         par[3*i+2] = (double)fitSigma->GetNumber();
      }
    
      // Fit the histogram
      fit = new TF1("fit", FindPeaks, 0, 400, 3*npeaks);
      TVirtualFitter::Fitter(histtemp, 3*npeaks);
      fit->SetParameters(par);
      fit->SetNpx(300);
      h2->Fit("fit","Q");  // for quiet mode, add Q
      fittingfunc = h2->GetFunction("fit");
      fparam = fittingfunc->GetParameters();
      fparamerr = fittingfunc->GetParErrors();
    
      // Gather the parameters (mean peak value for now)
      int j = 1;
      int nrfit = 0;
      bool errors = false;
      while(1)
      {
         if( (fparam[j] < 1.E-30) || (fparamerr[j] < 1.E-10) )
            break;
         else
         {
            if(fparam[j] > pedesLow->GetNumber())
            {
               meanparam[nrfit] = fparam[j];
               meanparamerr[nrfit] = fparamerr[j];
               nrfit++;
            }
         }
    
         j+=3;
      }
      printf("%d peaks fitted.\n",nrfit);

      if(nrfit >= peaklimit)
      {
         TMath::Sort(nrfit, meanparam, sortindex, kFALSE);

         // Write out parameters to a file
//         fp = fopen(paramname, "a");
     
         // Only save the ones that do not have a too large error on peak separation for the first three peaks
//         if( ((TMath::Abs(meanparamerr[sortindex[2]]) + TMath::Abs(meanparamerr[sortindex[1]]))/(meanparam[sortindex[2]] - meanparam[sortindex[1]]) < accError->GetNumber()) && ((TMath::Abs(meanparamerr[sortindex[3]]) + TMath::Abs(meanparamerr[sortindex[2]]))/(meanparam[sortindex[3]] - meanparam[sortindex[2]]) < accError->GetNumber()) && ((TMath::Abs(meanparamerr[sortindex[4]]) + TMath::Abs(meanparamerr[sortindex[3]]))/(meanparam[sortindex[4]] - meanparam[sortindex[3]]) < accError->GetNumber()) )
//         if( (seperr[0][0]/sep[0][0] < accError->GetNumber()) && (seperr[1][0]/sep[1][0] < accError->GetNumber()) && (seperr[2][0]/sep[2][0] < accError->GetNumber()) )
//         {
//            fprintf(fp, "%le\t%d\t", dtemp, nrfit);

//            for(int i = 0; i < nrfit; i++)
//            {
//               if(debug)
//                  printf("Peak %d (%lfV): %lf\t%lf\n", i+1, dtemp, meanparam[sortindex[i]], meanparamerr[sortindex[i]]);
//               fprintf(fp, "%le\t%le\t", meanparam[sortindex[i]], meanparamerr[sortindex[i]]);
//            }
//            printf("\n");
//            fprintf(fp, "\n");
//         }

//         fclose(fp);
    
         h2->SetStats(0);
         
         gCanvas->Modified();
         gCanvas->Update();
    
         // Save each fitting plot
         if(exfitplots->IsDown())
         {
            remove_ext((char*)files->At(m)->GetTitle(), ctemp);
            sprintf(exportname, "%s_fit.pdf", ctemp);
            gCanvas->SaveAs(exportname);
         }
     
         volt[p] = dtemp;
         volterr[p] = 1.e-4;

         if(nrfit == 3)
         {
            sep[0][p] = meanparam[sortindex[2]] - meanparam[sortindex[1]];
            seperr[0][p] = TMath::Abs(meanparamerr[sortindex[2]]) + TMath::Abs(meanparamerr[sortindex[1]]);

            errors = (seperr[0][p]/sep[0][p] < accError->GetNumber());

            if(debug)
               printf("p=%d:\t%lf\t%lf\t%lf\n", p, volt[p], sep[0][p], seperr[0][p]);
         }
         else if(nrfit == 4)
         {
            sep[0][p] = meanparam[sortindex[2]] - meanparam[sortindex[1]];
            sep[1][p] = meanparam[sortindex[3]] - meanparam[sortindex[2]];
            seperr[0][p] = TMath::Abs(meanparamerr[sortindex[2]]) + TMath::Abs(meanparamerr[sortindex[1]]);
            seperr[1][p] = TMath::Abs(meanparamerr[sortindex[3]]) + TMath::Abs(meanparamerr[sortindex[2]]);

            errors = ((seperr[0][p]/sep[0][p] < accError->GetNumber()) && (seperr[1][p]/sep[1][p] < accError->GetNumber()));

            if(debug)
               printf("p=%d:\t%lf\t%lf\t%lf\t%lf\t%lf\n", p, volt[p], sep[0][p], seperr[0][p], sep[1][p], seperr[1][p]);
         }
         else if(nrfit > 4)
         {
            sep[0][p] = meanparam[sortindex[2]] - meanparam[sortindex[1]];
            sep[1][p] = meanparam[sortindex[3]] - meanparam[sortindex[2]];
            sep[2][p] = meanparam[sortindex[4]] - meanparam[sortindex[3]];
            seperr[0][p] = TMath::Abs(meanparamerr[sortindex[2]]) + TMath::Abs(meanparamerr[sortindex[1]]);
            seperr[1][p] = TMath::Abs(meanparamerr[sortindex[3]]) + TMath::Abs(meanparamerr[sortindex[2]]);
            seperr[2][p] = TMath::Abs(meanparamerr[sortindex[4]]) + TMath::Abs(meanparamerr[sortindex[3]]);

            errors = ((seperr[0][p]/sep[0][p] < accError->GetNumber()) && (seperr[1][p]/sep[1][p] < accError->GetNumber()) && (seperr[2][p]/sep[2][p] < accError->GetNumber()));

            if(debug)
               printf("p=%d:\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n", p, volt[p], sep[0][p], seperr[0][p], sep[1][p], seperr[1][p], sep[2][p], seperr[2][p]);
         }

         // Write out parameters to a file
         fp = fopen(paramname, "a");

         // Accept only the points with a small enough error
         if( errors )
         {
            if(first == 1)
            {
               fprintf(fp, "%le\t%d\t", dtemp, nrfit);

               for(int i = 0; i < nrfit; i++)
               {
                  if(debug)
                     printf("Peak %d (%lfV): %lf\t%lf\n", i+1, dtemp, meanparam[sortindex[i]], meanparamerr[sortindex[i]]);
                  fprintf(fp, "%le\t%le\t", meanparam[sortindex[i]], meanparamerr[sortindex[i]]);
               }
               printf("\n");
               fprintf(fp, "\n");
               first = 0;
            }

            p++;
         }
         else
         {
            if(nrfit == 3)
               printf("Point (at %.2lfV) rejected due to too large errors: %lf\n", volt[p], seperr[0][p]/sep[0][p]);
            else if(nrfit == 4)
               printf("Point (at %.2lfV) rejected due to too large errors: %lf, %lf\n", volt[p], seperr[0][p]/sep[0][p], seperr[1][p]/sep[1][p]);
            else if(nrfit > 4)
               printf("Point (at %.2lfV) rejected due to too large errors: %lf, %lf, %lf\n", volt[p], seperr[0][p]/sep[0][p], seperr[1][p]/sep[1][p], seperr[2][p]/sep[2][p]);
         }

         fclose(fp);
      }

      if(q == 1) break;

      first = 1;
   }

   // Plot & fit breakdown voltage plots
   if(q > 1)
   {
      remove_from_last((char*)files->At(0)->GetTitle(), '_', ctemp);
      sprintf(paramname, "%s_breakdown.pdf", ctemp);
      MakeBreakdownPlot(p, volt, volterr, sep[0], seperr[0], sep[1], seperr[1], sep[2], seperr[2], paramname, peaklimit-2);
   }
}

// Plotting of PDF and CDF functions for the edge (with the added fit)
void TGAppMainFrame::EdgeDetection(TGraph *pdf, TGraph *cdf, char *outname, TCanvas *g1dCanvas, double pdfmax, int direction)
{
//   double x, y;

   pdf->Fit("gaus","Q");
   pdf->GetFunction("gaus")->SetNpx(400);
/*
   for(int i = 0; i < nrpoints; i++)
   {
      pdf->GetPoint(i, x, y);
      pdf->SetPoint(i, x, (y/pdfmax) );
   }
*/
   gStyle->SetOptFit(1);

   cdf->Draw("AL");
   gPad->Update();
   pdf->Draw("LP");

   g1dCanvas->Modified();
   g1dCanvas->Update();

   TPaveStats *stats = (TPaveStats*)pdf->FindObject("stats");
   if(!cleanPlots)
   {
//      stats->SetX1NDC(0.14); stats->SetX2NDC(0.28);
//      stats->SetY1NDC(0.83); stats->SetY2NDC(0.96);
      stats->SetX1NDC(0.86); stats->SetX2NDC(1.0);
      stats->SetY1NDC(0.87); stats->SetY2NDC(1.0);
   }
   else
   {
      stats->SetX1NDC(1.1); stats->SetX2NDC(1.3);
      stats->SetY1NDC(1.1); stats->SetY2NDC(1.3);
   }

   g1dCanvas->SetGridx(1);
   g1dCanvas->SetGridy(1);
   if(direction == 1)
      cdf->GetXaxis()->SetTitle("X [#mum]");
   else if(direction == 2)
      cdf->GetXaxis()->SetTitle("Y [#mum]");
   cdf->GetXaxis()->CenterTitle(kTRUE);
   cdf->GetXaxis()->SetLabelSize(0.022);
   cdf->GetYaxis()->SetTitle("Normalized ADC integral");
//   cdf->GetYaxis()->SetTitle("Normalized ADC integral (CDF)");
//   cdf->GetYaxis()->SetTitleColor(kBlue);
   cdf->GetYaxis()->CenterTitle(kTRUE);
   cdf->GetYaxis()->SetLabelSize(0.022);
   cdf->GetYaxis()->SetRangeUser(0,1);
   cdf->GetYaxis()->SetTitleSize(0.030);
//   cdf->GetYaxis()->SetLabelColor(kBlue);
   if(!cleanPlots)
      cdf->SetTitle("SiPM edge detection");
   else
      cdf->SetTitle();
   cdf->SetLineColor(kBlue);
   pdf->SetLineWidth(2);
   cdf->SetLineWidth(2);

/*   TGaxis *axis = new TGaxis(gPad->GetUxmax(), 0, gPad->GetUxmax(), 1, 0, pdfmax, 510, "+L");
   axis->Draw();
   axis->SetTitle("Normalized ADC integral (PDF)");
   axis->SetTitleSize(0.035);
   axis->CenterTitle();
   axis->SetTitleColor(kBlack);
   axis->SetTitleFont(42);
   axis->SetLabelSize(0.022);
   axis->SetLabelColor(kBlack);*/

   g1dCanvas->Modified();
   g1dCanvas->Update();

   g1dCanvas->SaveAs(outname);
}

// Integrate the spectrum
void TGAppMainFrame::IntegSpectrum(TList *files, int direction)
{
   unsigned int nrfiles = fileList->GetNumberOfEntries();
   char ctemp[256];
   int j, k = 0, m = 0, n = 0;

   TCanvas *gCanvas = new TCanvas("canv","canv",900,900);
   TCanvas *g1dCanvas = new TCanvas("canv1d","canv1d",1200,900);
   TTree *header_data, *meas_data;
   double *integralCount, *integralAcc;
   integralCount = new double[nrfiles];
   integralAcc = new double[nrfiles];
//   double xsurfmin, ysurfmin, zsurfmin;
   double *surfx, *surfy, *surfz;
   surfx = new double[nrfiles];
   surfy = new double[nrfiles];
   surfz = new double[nrfiles];
   for(int i = 0; i < (int)nrfiles; i++) {integralCount[i] = 0; integralAcc[i] = 0; }

   TGraph *gScan[2];    // graphs for PDF and CDF functions
   double pdfmax = -1;
   TGraph2D *gScan2D;
   gScan2D = new TGraph2D();
   int nrentries;
   double minInteg, maxInteg;

   char exportname[256];

   if(files->GetSize() > 0)
   {
      for(int i = 0; i < (int)files->GetSize(); i++)
      {
         n++;
         if(files->At(i))
         {
            sprintf(ctemp, "%s", files->At(i)->GetTitle());
            inroot = new TFile(ctemp, "READ");
          
            inroot->GetObject("header_data", header_data);
            inroot->GetObject("meas_data", meas_data);
          
            // Reading the header
            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);
    
            char rdc[256];
            j = selectCh->GetNumber();
            double rangetdc[2];
            rangetdc[0] = tdcMinwindow->GetNumber();
            rangetdc[1] = tdcMaxwindow->GetNumber();
    
            k = 0;
            m = 0;
          
            // Reading the data
            for(int e = 0; e < meas_data->GetEntries(); e++)
            {
               sprintf(rdc, "ADC%d", j);
               meas_data->SetBranchAddress(rdc, &evtdata.adcdata[j]);
               meas_data->GetEntry(e);
          
               sprintf(rdc, "TDC%d", j);
               meas_data->SetBranchAddress(rdc, &evtdata.tdcdata[j]);
               meas_data->GetEntry(e);
    
               // If our data point is inside the TDC window
               if( ((double)evtdata.tdcdata[j]/tdctimeconversion >= rangetdc[0]) && ((double)evtdata.tdcdata[j]/tdctimeconversion <= rangetdc[1]) )
               {
                  k++;
                  m += evtdata.adcdata[j];
               }
            }

/*          if(n == 1)  // these values can be used to set 0 value at first X, Y and Z positions
            {
               xsurfmin = evtheader.xpos;
               ysurfmin = evtheader.ypos;
               zsurfmin = evtheader.zpos;
            }
            surfx[i] = (double)(evtheader.xpos-xsurfmin)*lenconversion;
            surfy[i] = (double)(evtheader.ypos-ysurfmin)*lenconversion;
            surfz[i] = (double)(evtheader.zpos-zsurfmin)*lenconversion;*/
            surfx[i] = (double)(evtheader.xpos*lenconversion);
            surfy[i] = (double)(evtheader.ypos*lenconversion);
            surfz[i] = (double)(evtheader.zpos*lenconversion);

/*            surfx[i] = evtheader.xpos;
            surfy[i] = evtheader.ypos;
            surfz[i] = evtheader.zpos;
*/
            integralCount[i] += ((double)m)/((double)k);
            
            inroot->Close();
            delete inroot;
         }
      }

      nrentries = n;
      printf("%d files were selected.\n", nrentries);

      double curzval = surfz[0];
      j = 0;
      int acc = 0;
      int zb;
      for(int i = 0; i <= nrentries; i++)
      {  
         if(acc == nrentries)
         {
            minInteg = TMath::MinElement(j, integralAcc);

            for(int za = 0; za < j; za++)
               integralAcc[za] = integralAcc[za] - minInteg;

            maxInteg = TMath::MaxElement(j, integralAcc);

            for(int za = 0; za < j; za++)
            {
               zb = i-j+za;
               integralCount[zb] = integralAcc[za]/maxInteg;
               if(debug)
                  printf("Integral check 2 (i=%d,j=%d,za=%d,z=%.2lf,zb=%d): %lf\t%lf\n", i, j, za, surfz[i-j], zb, integralCount[zb], integralAcc[za]/maxInteg);
            }

            // Plotting of PDF and CDF functions for the edge (with the added fit)
            gScan[1] = new TGraph();
            for(int za = 0; za < j; za++)
            {
               zb = i-j+za;
               if(direction == 1)
                  gScan[1]->SetPoint(za, (double)surfx[zb], (double)integralAcc[za]/maxInteg);
               else if(direction == 2)
                  gScan[1]->SetPoint(za, (double)surfy[zb], (double)integralAcc[za]/maxInteg);

               if( ((integralAcc[za+1]-integralAcc[za])/maxInteg > pdfmax) && (za < j-1) )
                  pdfmax = (integralAcc[za+1]-integralAcc[za])/maxInteg;
            }

            pdfmax = (TMath::Ceil(pdfmax*10))/10.;
     
            gScan[0] = new TGraph();
            for(int za = j-1; za >= 0; za--)
            {
               zb = (i-1)-(j-1)+za;
               if((integralAcc[za]-integralAcc[za-1])/(maxInteg) < 0)
               {
                  if(direction == 1)
                     gScan[0]->SetPoint(za, (double)surfx[zb], 0);
                  else if(direction == 2)
                     gScan[0]->SetPoint(za, (double)surfy[zb], 0);
               }
               else
               {
                  if(direction == 1)
                     gScan[0]->SetPoint(za, (double)surfx[zb], (integralAcc[za]-integralAcc[za-1])/(maxInteg));
                  else if(direction == 2)
                     gScan[0]->SetPoint(za, (double)surfy[zb], (integralAcc[za]-integralAcc[za-1])/(maxInteg));
//               gScan[0]->SetPoint(za, (double)surfx[zb], (integralAcc[za]-integralAcc[za-1])/(pdfmax*maxInteg));
               }
            }
     
            remove_from_last((char*)files->At(i-1)->GetTitle(), '_', ctemp);
            sprintf(exportname, "%s_edge.pdf", ctemp);
            EdgeDetection(gScan[0], gScan[1], exportname, g1dCanvas, pdfmax, direction);
     
//            delete gScan[0];
//            delete gScan[1];

            i--;
            pdfmax = 0;
            break;
         }       
         else
         {
            if(surfz[i] == curzval)
            {
               integralAcc[j] = integralCount[i];
               if(debug)
                  printf("Integral check 1 (i=%d,j=%d,z=%.2lf): %lf\t%lf\n", i, j, surfz[i], integralCount[i], integralAcc[j]);
               j++;
               acc++;
            }
            else
            {
               minInteg = TMath::MinElement(j, integralAcc);
           
               for(int za = 0; za < j; za++)
                  integralAcc[za] = integralAcc[za] - minInteg;
           
               maxInteg = TMath::MaxElement(j, integralAcc);
           
               for(int za = 0; za < j; za++)
               {
                  zb = i-j+za;
                  integralCount[zb] = integralAcc[za]/maxInteg;
                  if(debug)
                     printf("Integral check 2 (i=%d,j=%d,za=%d,z=%.2lf,zb=%d): %lf\t%lf\n", i, j, za, surfz[i-j], zb, integralCount[zb], integralAcc[za]/maxInteg);
               }
               
               curzval = surfz[i];
               i--;

               // Plotting of PDF and CDF functions for the edge (with the added fit)
               gScan[1] = new TGraph();
               for(int za = 0; za < j; za++)
               {
                  zb = i-(j-1)+za;
                  if(direction == 1)
                     gScan[1]->SetPoint(za, (double)surfx[zb], (double)integralAcc[za]/maxInteg);
                  else if(direction == 2)
                     gScan[1]->SetPoint(za, (double)surfy[zb], (double)integralAcc[za]/maxInteg);

                  if( ((integralAcc[za+1]-integralAcc[za])/maxInteg > pdfmax) && (za < j-1) )
                     pdfmax = (integralAcc[za+1]-integralAcc[za])/maxInteg;
               }

               pdfmax = (TMath::Ceil(pdfmax*10))/10.;

               gScan[0] = new TGraph();
               for(int za = j-1; za >= 0; za--)
               {
                  zb = i-(j-1)+za;
                  if((integralAcc[za]-integralAcc[za-1])/(maxInteg) < 0)
                  {
                     if(direction == 1)
                        gScan[0]->SetPoint(za, (double)surfx[zb], 0);
                     else if(direction == 2)
                        gScan[0]->SetPoint(za, (double)surfy[zb], 0);
                  }
                  else
                  {
                     if(direction == 1)
                        gScan[0]->SetPoint(za, (double)surfx[zb], (integralAcc[za]-integralAcc[za-1])/(maxInteg));
                     else if(direction == 2)
                        gScan[0]->SetPoint(za, (double)surfy[zb], (integralAcc[za]-integralAcc[za-1])/(maxInteg));
//                  gScan[0]->SetPoint(za, (double)surfx[zb], (integralAcc[za]-integralAcc[za-1])/(pdfmax*maxInteg));
                  }
               }

               remove_from_last((char*)files->At(i)->GetTitle(), '_', ctemp);
               sprintf(exportname, "%s_edge.pdf", ctemp);
               EdgeDetection(gScan[0], gScan[1], exportname, g1dCanvas, pdfmax, direction);
     
               delete gScan[0];
               delete gScan[1];

               j = 0;
               pdfmax = 0;
            }
         }
      }

//      delete g1dCanvas;
    
      double range[4];
      if(direction == 1)
      {
         range[0] = TMath::MinElement(nrentries, surfx);
         range[1] = TMath::MaxElement(nrentries, surfx);
      }
      else if(direction == 2)
      {
         range[0] = TMath::MinElement(nrentries, surfy);
         range[1] = TMath::MaxElement(nrentries, surfy);
      }
      else
      {
         range[0] = TMath::MinElement(nrentries, surfx);
         range[1] = TMath::MaxElement(nrentries, surfx);
      }
      range[2] = TMath::MinElement(nrentries, surfz);
      range[3] = TMath::MaxElement(nrentries, surfz);
    
      // Plotting of 2D edge plot
      for(int i = 0; i < nrentries; i++)
      {
         if(direction == 1)
         {
            if(debug)
               printf("%.2lf\t%.2lf\t%lf\n", surfx[i], surfz[i], integralCount[i]);
            gScan2D->SetPoint(i, surfx[i], surfz[i], integralCount[i]);
         }
         else if(direction == 2)
         {
            if(debug)
               printf("%.2lf\t%.2lf\t%lf\n", surfy[i], surfz[i], integralCount[i]);
            gScan2D->SetPoint(i, surfy[i], surfz[i], integralCount[i]);
         }
      }

      gCanvas->cd();
      gStyle->SetPalette(1);
      gScan2D->Draw("COLZ");
     
      gCanvas->Modified();
      gCanvas->Update();
     
      if(direction == 1)
         gScan2D->GetXaxis()->SetTitle("X [#mum]");
      else if(direction == 2)
         gScan2D->GetXaxis()->SetTitle("Y [#mum]");
      gScan2D->GetXaxis()->CenterTitle(kTRUE);
      gScan2D->GetXaxis()->SetLabelSize(0.022);
      gScan2D->GetXaxis()->SetRangeUser(range[0], range[1]);
      gScan2D->GetXaxis()->SetNoExponent();
      gScan2D->GetYaxis()->SetTitle("Z [#mum]");
      gScan2D->GetYaxis()->SetTitleOffset(1.3);
      gScan2D->GetYaxis()->CenterTitle(kTRUE);
      gScan2D->GetYaxis()->SetLabelSize(0.022);
      gScan2D->GetYaxis()->SetRangeUser(range[2], range[3]);
      TGaxis *yax = (TGaxis*)gScan2D->GetYaxis();
      yax->SetMaxDigits(4);
      if(!cleanPlots)
         gScan2D->SetTitle("Laser focal point");
      else
         gScan2D->SetTitle();
  
      gCanvas->Modified();
      gCanvas->Update();

      remove_from_last((char*)files->At(0)->GetTitle(), '_', ctemp);
      sprintf(exportname, "%s", ctemp);
      remove_from_last(exportname, '_', ctemp);
      if(direction == 1)
         sprintf(exportname, "%s_xdir_focalpoint.pdf", ctemp);
      else if(direction == 2)
         sprintf(exportname, "%s_ydir_focalpoint.pdf", ctemp);
      gCanvas->SaveAs(exportname);
   }
}

// Integrate the spectrum
void TGAppMainFrame::PhotonMu(TList *files)
{
   unsigned int nrfiles = fileList->GetNumberOfEntries();
   char ctemp[256];
   int j, k = 0, m = 0, n = 0, k2 = 0, m2 = 0;

   TCanvas *gCanvas;
   TTree *header_data, *meas_data;
   double *integralCount, *integralPedestal;
   integralCount = new double[nrfiles];
   integralPedestal = new double[nrfiles];
   double *angle;
   double *pdeval;
   double *muval;
   angle = new double[nrfiles];
   pdeval = new double[nrfiles];
   muval = new double[nrfiles];
   for(int i = 0; i < (int)nrfiles; i++) {integralCount[i] = 0; integralPedestal[i] = 0; }

//   TGraph *gScan[2];  // graph for angle dependence
   int nrentries;

   TSpectrum *spec;
   TH1F *histtemp;
   TH1 *histback;
   TH1F *h2;
   float *xpeaks;
   TF1 *fit;
   TF1 *fittingfunc;
   double *fparam;
   double meanparam;
   int adcpedestal[2];
   double paramsigma = 0;

   if(files->GetSize() > 0)
   {
      for(int i = 0; i < (int)files->GetSize(); i++)
      {
         n++;
         if(files->At(i))
         {
            // Find the pedestal peak and the first minimum after pedestal ----------------
            DisplayHistogram( (char*)(files->At(i)->GetTitle()), 0);
            histCanvas->GetCanvas()->Modified();
            histCanvas->GetCanvas()->Update();
       
            histtemp = (TH1F*)histCanvas->GetCanvas()->GetPrimitive(histname);
            npeaks = 1;
            double par[300];
            spec = new TSpectrum(npeaks);
            // Find spectrum background
            histback = spec->Background(histtemp, (int)fitInter->GetNumber(), "same");
            // Clone histogram and subtract background from it
            h2 = (TH1F*)histtemp->Clone("h2");
            h2->Add(histback, -1);
            // Search for the peaks
            int found = spec->Search(h2, fitSigma->GetNumber(), "goff", fitTresh->GetNumber() );
            printf("Found %d candidates to fit.\n",found);
            npeaks = found;
    
            xpeaks = spec->GetPositionX();
            for(j = 0; j < found; j++)
            {
               float xp = xpeaks[j];
               int bin = h2->GetXaxis()->FindBin(xp);
               float yp = h2->GetBinContent(bin);
               par[3*j] = yp;
               par[3*j+1] = xp;
               par[3*j+2] = (double)fitSigma->GetNumber();
            }
          
            // Fit the histogram
            fit = new TF1("fit", FindPeaks, 0, 400, 3*npeaks);
            TVirtualFitter::Fitter(histtemp, 3*npeaks);
            fit->SetParameters(par);
            fit->SetNpx(300);
            h2->Fit("fit","Q");  // for quiet mode, add Q
            fittingfunc = h2->GetFunction("fit");
            fparam = fittingfunc->GetParameters();
          
            // Gather the parameters (mean peak value for now)
            j = 1;

            meanparam = fparam[j];
            paramsigma = fparam[j+1];

/*            while(1)
            {
               if( (fparam[j] < 1.E-30) || (fparamerr[j] < 1.E-10) )
                  break;
               else
               {
                  if(fparam[j] > 0)
                  {
                     meanparam = fparam[j];
                     meanparamerr = fparamerr[j];
                     paramsigma = fparam[j+1];
                     nrfit++;
                  }
               }
          
               j+=3;
            }
*/       
            histCanvas->GetCanvas()->Modified();
            histCanvas->GetCanvas()->Update();
       
            j = 0;
            adcpedestal[0] = 0;
            adcpedestal[1] = -1;
            while(1)
            {
               int bin = histtemp->GetXaxis()->FindBin((int)(j+meanparam+paramsigma));
       
               int yp = histtemp->GetBinContent(bin);
               if(adcpedestal[1] == -1)
               {
                  adcpedestal[0] = j+meanparam+paramsigma;
                  adcpedestal[1] = yp;
               }
               else
               {
                  if(adcpedestal[1] >= yp)
                  {
                     adcpedestal[0] = j+meanparam+paramsigma;
                     adcpedestal[1] = yp;
                  }
                  else
                     break;
               }
       
               j++;
               if(j > 50) break;
            }
       
            cout << "Pedestal ends with ADC value: " << adcpedestal[0] << endl;

            // ----------------------------------------------------------------------------

            sprintf(ctemp, "%s", files->At(i)->GetTitle());
            inroot = new TFile(ctemp, "READ");
          
            inroot->GetObject("header_data", header_data);
            inroot->GetObject("meas_data", meas_data);
          
            // Reading the header
            if( header_data->FindBranch("angle") )
            {
               header_data->SetBranchAddress("angle", &evtheader.angle);
               header_data->GetEntry(0);
            }
            else
            {
               printf("Error! Selected file has no angle header value. Please edit header to add the angle header value.\n");
               break;
            }
    
            char rdc[256];
            j = selectCh->GetNumber();
            double rangetdc[2];
            rangetdc[0] = tdcMinwindow->GetNumber();
            rangetdc[1] = tdcMaxwindow->GetNumber();
    
            k = 0;
            k2 = 0;
            m = 0;
            m2 = 0;
          
            // Reading the data
            for(int e = 0; e < meas_data->GetEntries(); e++)
            {
               sprintf(rdc, "ADC%d", j);
               meas_data->SetBranchAddress(rdc, &evtdata.adcdata[j]);
               meas_data->GetEntry(e);
          
               sprintf(rdc, "TDC%d", j);
               meas_data->SetBranchAddress(rdc, &evtdata.tdcdata[j]);
               meas_data->GetEntry(e);
    
               // If our data point is inside the TDC window
               if( ((double)evtdata.tdcdata[j]/tdctimeconversion >= rangetdc[0]) && ((double)evtdata.tdcdata[j]/tdctimeconversion <= rangetdc[1]) )
               {
                  // Gather only the integral of the pedestal
                  if((double)evtdata.adcdata[j] < (double)adcpedestal[0]+0.5 )
                  {
                     k2++;
                     m2 += evtdata.adcdata[j];
                  }

                  // Gather the complete integral
                  k++;
                  m += evtdata.adcdata[j];
               }
            }

            angle[i] = (double)(evtheader.angle);  // angle in radians

//            integralCount[i] += ((double)m)/((double)k);
            integralCount[i] += (double)m;
            cout << "Integral (" << k << " evts) = " << integralCount[i] << endl;

            integralPedestal[i] += (double)m2;
            cout << "Integral (" << k2 << " evts) = " << integralPedestal[i] << endl;

            muval[i] = -TMath::Log((double)k2/(double)k);

            pdeval[i] = muval[i]/(muval[0]*TMath::Cos(angle[i]*TMath::ACos(-1.)/180.));
            
            inroot->Close();
            delete inroot;
         }
      }

      nrentries = n;
      printf("%d files were selected.\n", nrentries);

      cout << "angle\tmu\trelative PDE\n" << endl;
      for(int i = 0; i < (int)files->GetSize(); i++)
      {
            // Relative PDE calculation
            cout << angle[i] << "\t" << muval[i] << "\t" << pdeval[i] << endl;
      }

      // Plot mu and PDE angle dependance plots
      gCanvas = new TCanvas("canv","canv",1200,900);
      gCanvas->SetGrid();

      TGraph *pde = new TGraph(nrentries, angle, pdeval);
      pde->SetMarkerStyle(21);
      pde->SetMarkerSize(1.0);
      pde->SetMarkerColor(2);
      pde->SetLineWidth(2);
      pde->SetLineColor(2);
      pde->GetXaxis()->SetLabelSize(0.030);
      pde->GetXaxis()->CenterTitle();
      pde->GetXaxis()->SetRange(-5,90);
      pde->GetXaxis()->SetRangeUser(-5,90);
      pde->GetYaxis()->SetTitleOffset(1.2);
      pde->GetYaxis()->SetLabelSize(0.030);
      pde->GetYaxis()->CenterTitle();
      pde->GetYaxis()->SetRangeUser(0.3, 1.18);
      pde->Draw("ALP");

      pde->SetTitle(";Incidence angle (#circ);Relative PDE(#theta) / #mu(#theta)");

      TGraph *mugr = new TGraph(nrentries, angle, muval);
      mugr->SetMarkerStyle(20);
      mugr->SetMarkerSize(1.0);
      mugr->SetMarkerColor(4);
      mugr->SetLineWidth(2);
      mugr->SetLineColor(4);
      mugr->Draw("SAME;LP");

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

void TGAppMainFrame::RunMeas(void *ptr, int runCase, int zaxisscan, int &scanon)
{
   printf("Start of Run, run case %d\n", runCase);
   float progVal;

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

   remove_ext((char*)fileName->GetText(), ctemp);
//   printf("Save name: %s\nNo extension: %s\n", fileName->GetText(), ctemp);

   // Open file for writing
/*   if(runCase == 0)
   {
      sprintf(fname, "rm %s_%s", ctemp, histExtAll);
      retTemp = system(fname);
   }*/  // deleting might not be necesary due to RECREATE in root file open

   if( voltscanOn->IsOn() || surfscanOn->IsOn() )
   {
      if(zaxisscan == 0)
      {
         if( (voltscanOn->IsOn()) && (vOutStep->GetNumber() > 0.) )
            SeqNumber(runCase, (int)((vOutStop->GetNumber())-(vOutStart->GetNumber()))/(vOutStep->GetNumber()), ctemp2);
         else if( surfscanOn->IsOn() )
         {
            if( xPosStep->GetNumber() == 0 )
               itemp = 1;
            else
               itemp = (int)((xPosMax->GetNumber())-(xPosMin->GetNumber()))/(xPosStep->GetNumber());

            if( yPosStep->GetNumber() == 0 )
               itemp *= 1;
            else
               itemp *= (int)((yPosMax->GetNumber())-(yPosMin->GetNumber()))/(yPosStep->GetNumber());
            SeqNumber(runCase, itemp, ctemp2);
         }
         sprintf(fname, "%s_%s%s", ctemp, ctemp2, histExt);
      }
      else if(zaxisscan == 1)
      {
         SeqNumber((int)zPos->GetNumber(), (int)zPosMax->GetNumber(), ctemp2);

         if( (voltscanOn->IsOn()) && (vOutStep->GetNumber() > 0.) )
         {
            sprintf(fname, "%s_z%s_", ctemp, ctemp2);
            SeqNumber(runCase, (int)((vOutStop->GetNumber())-(vOutStart->GetNumber()))/(vOutStep->GetNumber())+1, ctemp2);
            strcat(fname, ctemp2);
            strcat(fname, histExt);
         }
         else if( surfscanOn->IsOn() )
         {
            sprintf(fname, "%s_z%s_", ctemp, ctemp2);

            if( xPosStep->GetNumber() == 0 )
               itemp = 1;
            else
               itemp = (int)((xPosMax->GetNumber())-(xPosMin->GetNumber()))/(xPosStep->GetNumber())+1;

            if( yPosStep->GetNumber() == 0 )
               itemp *= 1;
            else
               itemp *= (int)((yPosMax->GetNumber())-(yPosMin->GetNumber()))/(yPosStep->GetNumber())+1;
            SeqNumber(runCase, itemp, ctemp2);
            strcat(fname, ctemp2);
            strcat(fname, histExt);
         }
         else
            sprintf(fname, "%s_z%s%s", ctemp, ctemp2, histExt);

/*         if(runCase < 10)
            sprintf(fname, "%s_z%d_0000%d%s", ctemp, (int)zPos->GetNumber(), runCase, histExt);
         else if( (runCase >= 10) && (runCase < 100) )
            sprintf(fname, "%s_z%d_000%d%s", ctemp, (int)zPos->GetNumber(), runCase, histExt);
         else if( (runCase >= 100) && (runCase < 1000) )
            sprintf(fname, "%s_z%d_00%d%s", ctemp, (int)zPos->GetNumber(), runCase, histExt);
         else if( (runCase >= 1000) && (runCase < 10000) )
            sprintf(fname, "%s_z%d_0%d%s", ctemp, (int)zPos->GetNumber(), runCase, histExt);
         else if( (runCase >= 10000) && (runCase < 100000) )
            sprintf(fname, "%s_z%d_0%d%s", ctemp, (int)zPos->GetNumber(), runCase, histExt);
*/      }
   }
   else if( !voltscanOn->IsOn() && !surfscanOn->IsOn() )
      sprintf(fname, "%s%s", ctemp, histExt);
//   printf("Rootfile: %s\n", fname);

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

   outroot = new TFile(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("laserinfo", &evtheader.laserinfo, "laserinfo/C");

   evtheader.nrch = (int)NCH->GetNumber()*2;
   evtheader.timestamp = (int)time(NULL);
   evtheader.biasvolt = (double)vOut->GetNumber();
   evtheader.xpos = (int)xPos->GetNumber();
   evtheader.ypos = (int)yPos->GetNumber();
   evtheader.zpos = (int)zPos->GetNumber();
   evtheader.temperature = (double)chtemp->GetNumber();
   evtheader.angle = (double)incangle->GetNumber();
   sprintf(evtheader.laserinfo, "%s", laserInfo->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("- 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);
   }

   // 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->GetNumber();
   int allEvt, zProg;
   zProg = 1;

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

   if (gDaq)
   {
      if(scanon == 0)
      {
         gDaq->init(evtheader.nrch);
         scanon = 1;
      }
      gDaq->fStop=0;
      // Start gathering
      gDaq->start();

      busyLabel->Enable();

      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();
            }
            meas_data->Fill();

            // Start making a scope measurement
            if( (gScopeDaq->scopeUseType == 2) && (sCamaclink->IsDown()) )
            {
               StartScopeAcq();
               evtmeas.measdata = gScopeDaq->measubuf;
            }
            scope_data->Fill();
            
            n++;
            nc += evtheader.nrch;
            nb -= evtheader.nrch;
         }

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

         if( (started) && (n == (neve*zProg)/10) )
         {
            progVal = (float)zProg*10;
            curProgress->SetPosition(progVal);
            zProg++;
         }
      }

      printf("Number of gathered events: %d\n", allEvt);
      measStart->SetText("Start acquisition");
      started = kFALSE;

      gDaq->stop();
   }

   busyLabel->Disable();
   printf("End of Run neve=%d\n",neve);

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

   outroot->Close();
}

// 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;
   if(voltscanOn->IsOn()) vscan = 1;
   if(surfscanOn->IsOn()) pscan = 1;
   if(zscanOn->IsOn()) zscan = 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
   int minXpos, maxXpos, stepXpos;
   int minYpos, maxYpos, stepYpos;
   int minZpos, maxZpos, stepZpos;
   int repetX, repetY, repetZ;

   // Voltage scan
   if( (vscan == 1) && (pscan == 0) )
   {
      if(started)
      {
         printf("Stopping current voltage scan...\n");
         gROOT->SetInterrupt();
         measStart->SetText("Start acquisition");
         started = kFALSE;

         pfin = fopen("finish_sig.txt","w");
         fprintf(pfin, "%s: Voltage scan stopped.", timeStamp->GetText());
         fclose(pfin);
      }
      else if(!started)
      {
         measStart->SetText("Stop acquisition");
         started = kTRUE;

         printf("Running a voltage scan...\n");
      
         minVoltage = vOutStart->GetNumber();
         maxVoltage = vOutStop->GetNumber();
         stepVoltage = vOutStep->GetNumber();
    
         if(stepVoltage == 0.)
            repetition = 1;
         else
            repetition = ((maxVoltage - minVoltage)/stepVoltage)+1;
    
         for(i=0; i < repetition; i++)
         {
            progVal = (float)(100.00/repetition)*i;
            curProgress->SetPosition(progVal);
        
            fflush(stdout);
            currentVoltage = minVoltage + stepVoltage*i;
            sprintf(cmd, "%s/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(3);
            vOut->SetNumber(currentVoltage);
            printf("Continuing...\n");
        
            // Here comes function to start histogramming <<<<<<<<<<<<<<<<<<<<<<<<
            RunMeas((void*)0, i, 0, scanon);
            fflush(stdout);
         }
        
         // Set output back to off
         fflush(stdout);
         printf("Measurement finished, returning to starting voltage...\n");
         sprintf(cmd, "%s/mpod/mpod_voltage.sh -o %d -v %f -s 1", rootdir, GetChannel(), minVoltage);
         vOut->SetNumber(minVoltage);
#if WORKSTAT == 'I'
         retTemp = system(cmd);
#else
         printf("Cmd: %s\n",cmd);
#endif
         fflush(stdout);
        
         progVal = 100.00;
         curProgress->SetPosition(progVal);
         printf("\n");

         pfin = fopen("finish_sig.txt","w");
         fprintf(pfin, "%s: Voltage scan finished.", timeStamp->GetText());
         fclose(pfin);
      }
   }
   // Surface scan
   else if( (pscan == 1) && (vscan == 0) )
   {
      minXpos = xPosMin->GetNumber();
      maxXpos = xPosMax->GetNumber();
      stepXpos = xPosStep->GetNumber();
      minYpos = yPosMin->GetNumber();
      maxYpos = yPosMax->GetNumber();
      stepYpos = yPosStep->GetNumber();
      minZpos = zPosMin->GetNumber();
      maxZpos = zPosMax->GetNumber();
      stepZpos = zPosStep->GetNumber();

      if(zscan == 1)
      {
         if(stepZpos == 0.) repetZ = 1;
         else repetZ = ((maxZpos - minZpos)/stepZpos)+1;
      }
      else
      {
         minZpos = zPos->GetNumber();
         repetZ = 1;
      }

      if(stepXpos == 0.) repetX = 1;
      else repetX = ((maxXpos - minXpos)/stepXpos)+1;
      if(stepYpos == 0.) repetY = 1;
      else repetY = ((maxYpos - minYpos)/stepYpos)+1;

      for(k=0; k < repetZ; k++)
      {
         fflush(stdout);
         // Y-axis change
         sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 3 -v %d -s la && %s/MIKRO/mikro_ctrl -n 3 -c m", rootdir, minZpos + stepZpos*k, rootdir);
#if WORKSTAT == 'I'
         retTemp = system(cmd);
#else
         printf("Cmd: %s\n",cmd);
#endif
         fflush(stdout);
         
         int iloop =0;
                do {
                        usleep(50);
                        sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 3 -p > %s/curpos.txt", rootdir, rootdir);
                        retTemp = system(cmd);

                        FILE* fpos;
                        int itemp;
                        sprintf(cmd, "%s/curpos.txt", rootdir);
                        fpos = fopen(cmd, "r");

                        if(fpos != NULL)
                        {
                                retTemp = fscanf(fpos, "%d\n", &itemp);
                        }

                        fclose(fpos);
                        printf(">>>>>>> Cur Z Pos = %d\n", itemp);


                        if( abs(itemp - (minZpos + stepZpos*k)) < 3 ) break;

                        iloop++;
                } while(iloop < 10000);
     
         printf("Next Z position...\n");
         zPos->SetNumber(minZpos + stepZpos*k);
         fflush(stdout);
     
         for(j=0; j < repetY; j++)
         {
            fflush(stdout);
            // Y-axis change
            sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 2 -v %d -s la && %s/MIKRO/mikro_ctrl -n 2 -c m", rootdir, minYpos + stepYpos*j, rootdir);
#if WORKSTAT == 'I'
            retTemp = system(cmd);
#else
            printf("Cmd: %s\n",cmd);
#endif
            fflush(stdout);
            
                        printf("Waiting for position change...\n");
            //sleep(4);
            
            int iloop =0;
                        do {
                                usleep(50);
                                sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 2 -p > %s/curpos.txt", rootdir, rootdir);
                                retTemp = system(cmd);

                                FILE* fpos;
                                int itemp;
                                sprintf(cmd, "%s/curpos.txt", rootdir);
                                fpos = fopen(cmd, "r");

                                if(fpos != NULL)
                                {
                                        retTemp = fscanf(fpos, "%d\n", &itemp);
                                }

                                fclose(fpos);
                                printf(">>>>>>> Cur Y Pos = %d\n", itemp);


                                if( abs(itemp - (minYpos + stepYpos*j)) < 3 ) break;

                                iloop++;
                        } while(iloop < 10000);
            
            printf("Next Y position...\n");
            yPos->SetNumber(minYpos + stepYpos*j);
            fflush(stdout);
     
            for(i=0; i < repetX; i++)
            {
               progVal = (float)(100.00/(repetX*repetY))*(j*repetX+i);
               curProgress->SetPosition(progVal);
               
                                int jloop =0;
                                do {
                                        usleep(100);

                                        // X-axis change
                                        sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 1 -v %d -s la && %s/MIKRO/mikro_ctrl -n 1 -c m", rootdir, minXpos + stepXpos*i, 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(2);

                                        int iloop =0;
                                        do {
                                                usleep(100);
                                                sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 1 -p > %s/curpos.txt", rootdir, rootdir);
                                                retTemp = system(cmd);

                                                FILE* fpos;
                                                int itemp;
                                                sprintf(cmd, "%s/curpos.txt", rootdir);
                                                fpos = fopen(cmd, "r");

                                                if(fpos != NULL)
                                                {
                                                        retTemp = fscanf(fpos, "%d\n", &itemp);
                                                }

                                                fclose(fpos);
                                                printf(">>>>>>> Cur X Pos = %d\n", itemp);


                                                if( abs(itemp - ( minXpos + stepXpos*i)) < 3 ) break;

                                                iloop++;
                                        } while(iloop < 100);
                                        
                                        sprintf(cmd, "sudo %s/MIKRO/mikro_ctrl -n 1 -p > %s/curpos.txt", rootdir, rootdir);
                                        retTemp = system(cmd);

                                        FILE* fpos;
                                        int itemp;
                                        sprintf(cmd, "%s/curpos.txt", rootdir);
                                        fpos = fopen(cmd, "r");

                                        if(fpos != NULL)
                                        {
                                                retTemp = fscanf(fpos, "%d\n", &itemp);
                                        }

                                        fclose(fpos);
                                        
                                        if( abs(itemp - ( minXpos + stepXpos*i)) < 3 ) break;

                                        jloop++;
                                } while(jloop < 100);
               
               
               
               xPos->SetNumber(minXpos + stepXpos*i);
               printf("Continuing...\n");
     
//               for (k=0;k<(NTDCCH+NADCCH);k++) gHisto1D[k]->Reset();
//               for (k=0;k<(NTDCCH+NADCCH)/2;k++) gHisto2D[k]->Reset();
     
               // Here comes function to start histogramming <<<<<<<<<<<<<<<<<<<<<<<<
               RunMeas((void*)0, (j*repetX + i), zscan , scanon);
     
               fflush(stdout);
            }
     
            printf("\n");
         }
      }

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

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

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

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

      pfin = fopen("finish_sig.txt","w");
      fprintf(pfin, "%s: Surface scan finished.", timeStamp->GetText());
      fclose(pfin);
   }
   // Normal single measurement
   else if( (vscan == 0) && (pscan == 0) )
   {
      // Set the start button to stop and enable stopping of measurement
      if(started)
      {
         printf("Stopping current single scan...\n");
         gROOT->SetInterrupt();
//         gDaq->fStop=1;
         measStart->SetText("Start acquisition");
         started = kFALSE;
      }
      else if(!started)
      {
         measStart->SetText("Stop acquisition");
         started = kTRUE;

         printf("Running a single scan...\n");
         RunMeas((void*)0, 0, 0, scanon);
         printf("Measurement finished...\n");
         printf("\n");
      }
   }
}

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

   TGFileInfo file_info;
   const char *filetypes[] = {"Histograms",histExtAll,0,0};
   file_info.fFileTypes = filetypes;
   file_info.fIniDir = StrDup("./results");
   file_info.fMultipleSelection = kTRUE;
   new TGFileDialog(gClient->GetDefaultRoot(), fMain, kFDOpen, &file_info);

   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();
}

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

   fileName->SetText(file_info.fFilename);
}

// Toggle multiple selection in filelist
void TGAppMainFrame::ListMultiSelect()
{
   fileList->SetMultipleSelections((multiSelect->IsOn()));

   if(multiSelectAll->IsDown())
      multiSelectAll->SetState(kButtonUp);
}

// Select all entries in filelist
void TGAppMainFrame::ListSelectAll()
{
   if(multiSelectAll->IsDown())
   {
      multiSelect->SetState(kButtonDown);
      fileList->SetMultipleSelections((multiSelect->IsOn()));
      for(int i = 0; i < fileList->GetNumberOfEntries(); i++) 
         fileList->Select(i,kTRUE);
   }
   else if(!multiSelectAll->IsDown())
   {
      multiSelect->SetState(kButtonUp);
      fileList->SetMultipleSelections((multiSelect->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 pn)
{
   unsigned int nrfiles = fileList->GetNumberOfEntries();
   int curSel;
   TList *files;
   if( nrfiles > 0 )
   {
      if(pn < -1)
      {
         if(multiSelect->IsOn())
         {
            // turn off multiple selection and select first file on list
            fileList->SetMultipleSelections(kFALSE);
            multiSelect->SetState(kButtonUp);
            multiSelectAll->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(pn == -3)
            {
               if( (curSel == (int)(nrfiles-1)) || (curSel == -1) )
                  fileList->Select(0);
               else
                  fileList->Select(curSel+1);
            }
            // go to previous file on list
            else if(pn == -2)
            {
               if( (curSel == 0) || (curSel == -1) )
                  fileList->Select(nrfiles-1);
               else
                  fileList->Select(curSel-1);
            }
         }
      }

      // check the newly selected file/files and return its name/their names
      files = new TList();
      fileList->GetSelectedEntries(files);
      if(files)
      {
         for(int i = 0; i < (int)nrfiles; i++)
         {
            if(files->At(i))
            {
               if(debug)
                  printf("Filename: %s\n", files->At(i)->GetTitle());
               if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DADC) )
                  DisplayHistogram( (char*)(files->At(i)->GetTitle()), 0);
               else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DTDC) )
                  DisplayHistogram( (char*)(files->At(i)->GetTitle()), 1);
               else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_2D) )
                  DisplayHistogram( (char*)(files->At(i)->GetTitle()), 2);
            }
         }
      }

      // Still need to include drawing of histograms we move to!!!
   }
}

// Open the header edit window when pressing on editHeader button
void TGAppMainFrame::HeaderEdit()
{
   OpenWindow(2);
}

// Display the currently selected histogram in file list
void TGAppMainFrame::DisplayHistogram(char* histfile, int histtype)
{
   if(debug)
      printf("Selected file: %s\n", histfile);

   TCanvas *gCanvas = histCanvas->GetCanvas();

   inroot = new TFile(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);

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

   // Displaying header information (debug and on the GUI)
   if(debug)
   {
      printf("Opened 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);
      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);
   }

   char ctemp[512];
   disptime->SetText(histtime);
   dispbias->SetNumber(evtheader.biasvolt);
   sprintf(ctemp, "%d, %d, %d", evtheader.xpos, evtheader.ypos, evtheader.zpos);
   disppos->SetText(ctemp);
   if(evtheader.temperature)
      disptemp->SetNumber(evtheader.temperature);
   else
      disptemp->SetNumber(0.0);
   if( header_data->FindBranch("angle") )
      dispangle->SetNumber(evtheader.angle);
   else
      dispangle->SetNumber(0.0);
   displaser->SetText(evtheader.laserinfo);

   int j;
   char rdc[256];
   char rdcsel[256];

   j = selectCh->GetNumber();

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

   gCanvas->cd();
   double range[4];
   range[0] = adcMinRange->GetNumber();
   range[1] = adcMaxRange->GetNumber();
   range[2] = tdcMinwindow->GetNumber();
   range[3] = tdcMaxwindow->GetNumber();

   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( yMinRange->GetNumber() != yMaxRange->GetNumber() )
      {
         if( (logscale->IsDown()) && (yMinRange->GetNumber() <= 0) )
         {
            histtemp->GetYaxis()->SetRangeUser(0.5, yMaxRange->GetNumber());
            yMinRange->SetNumber(0.5);
            logchange = 1;
         }
         else
         {
            gCanvas->SetLogy(kFALSE);
            if(logchange == 1)
            {
               yMinRange->SetNumber(0.0);
               logchange = 0;
            }
            histtemp->GetYaxis()->SetRangeUser(yMinRange->GetNumber(), yMaxRange->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);
      }
   }
   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( yMinRange->GetNumber() != yMaxRange->GetNumber() )
      {
         if( (logscale->IsDown()) && (yMinRange->GetNumber() <= 0) )
         {
            histtemp->GetYaxis()->SetRangeUser(0.5, yMaxRange->GetNumber());
            yMinRange->SetNumber(0.5);
            logchange = 1;
         }
         else
         {
            gCanvas->SetLogy(kFALSE);
            if(logchange == 1)
            {
               yMinRange->SetNumber(0.0);
               logchange = 0;
            }
            histtemp->GetYaxis()->SetRangeUser(yMinRange->GetNumber(), yMaxRange->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);
      }
   }
   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->SetOptStat(0);
      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( logscale->IsDown() )
         gCanvas->SetLogy(kTRUE);
      else if( !logscale->IsDown() )
         gCanvas->SetLogy(kFALSE);
   }
   else
      gCanvas->SetLogy(kFALSE);

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

   // If you close the opened file, the data can't be accessed by other functions
}

// Create a 2D surface plot and plot it
void TGAppMainFrame::MakeSurfPlot(TList *files)
{
   unsigned int nrfiles = fileList->GetNumberOfEntries();
   int j, k = 0, m = 0, n = 0;
   char ctemp[256];
   TCanvas *gCanvas = histCanvas->GetCanvas();
   TTree *header_data, *meas_data;
   double *integralCount;
   double *surfx, *surfy;
   double xsurfmin = 0, ysurfmin = 0;
   integralCount = new double[nrfiles];
   for(int i = 0; i < (int)nrfiles; i++) integralCount[i] = 0;
   surfx = new double[nrfiles];
   surfy = new double[nrfiles];
   int nrentries;
   TGraph2D *gScan2D;
   gScan2D = new TGraph2D();

/*   int zProg = 0;
   float progVal;
   curProgress->SetPosition(zProg);*/

   char exportname[256];
   
   if(multiSelect->IsOn())
   {
      printf("Creating a surface plot. Please wait...\n");
      fileList->GetSelectedEntries(files);
      if(files)
      {
         busyLabel->Enable();

         for(int i = 0; i < (int)nrfiles; i++)
         {
            if(files->At(i))
            {
               n++;
//               printf("Filename: %s\n", files->At(i)->GetTitle());
             
               sprintf(ctemp, "%s", files->At(i)->GetTitle());
               inroot = new TFile(ctemp, "READ");
             
               inroot->GetObject("header_data", header_data);
               inroot->GetObject("meas_data", meas_data);
             
               // Reading the header
               header_data->SetBranchAddress("xpos", &evtheader.xpos);
               header_data->GetEntry(0);
               header_data->SetBranchAddress("ypos", &evtheader.ypos);
               header_data->GetEntry(0);

               char rdc[256];
               j = selectCh->GetNumber();
               double rangetdc[2];
               rangetdc[0] = tdcMinwindow->GetNumber();
               rangetdc[1] = tdcMaxwindow->GetNumber();

               k = 0;
               m = 0;
             
               // Reading the data
               for(int i = 0; i < meas_data->GetEntries(); i++)
               {
                  sprintf(rdc, "ADC%d", j);
                  meas_data->SetBranchAddress(rdc, &evtdata.adcdata[j]);
                  meas_data->GetEntry(i);
             
                  sprintf(rdc, "TDC%d", j);
                  meas_data->SetBranchAddress(rdc, &evtdata.tdcdata[j]);
                  meas_data->GetEntry(i);

                  // If our data point is inside the TDC window
                  if( ((double)evtdata.tdcdata[j]/tdctimeconversion >= rangetdc[0]) && ((double)evtdata.tdcdata[j]/tdctimeconversion <= rangetdc[1]) )
                  {
                     k++;
                     m += evtdata.adcdata[j];
                  }
               }

               integralCount[n-1] += ((double)m)/((double)k);
               if(n == 1)
               {
                  xsurfmin = evtheader.xpos;
                  ysurfmin = evtheader.ypos;
               }
               surfx[n-1] = (double)(evtheader.xpos-xsurfmin)*lenconversion;
               surfy[n-1] = (double)(evtheader.ypos-ysurfmin)*lenconversion;

/*             if( n == (((files->GetSize())*zProg)/20)+1 ) // divide by 20 because files->GetSize() gives a double value of the files selected
               {
                  progVal = (float)n;
                  curProgress->SetPosition(progVal);
                  zProg++;
                  printf("Progress = %lf\n", progVal);
               }*/

               inroot->Close();
               delete inroot;
            }
         }

         busyLabel->Disable();

         nrentries = n;
         printf("%d files were selected.\n", nrentries);

         for(int i = 0; i < nrentries; i++)
         {
//            printf("At position (%d,%d), the ADC integral is: %lf.\n", surfx[i], surfy[i], integralCount[i]);
            gScan2D->SetPoint(i, surfx[i], surfy[i], integralCount[i]);
         }
         gCanvas->cd();
         gScan2D->Draw("COLZ");

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

         gScan2D->GetXaxis()->SetTitle("X [#mum]");
         gScan2D->GetXaxis()->CenterTitle(kTRUE);
         gScan2D->GetXaxis()->SetLabelSize(0.022);
         gScan2D->GetXaxis()->SetRangeUser(surfx[0], surfx[nrentries-1]);
//       j = 500+(int)((surfx[nrentries-1]-surfx[0])/(surfx[1]-surfx[0]));
//       if(j > 510) j = 510;
         gScan2D->GetXaxis()->SetNdivisions(510, kTRUE);
         gScan2D->GetYaxis()->SetTitle("Y [#mum]");
         gScan2D->GetYaxis()->SetTitleOffset(1.3);
         gScan2D->GetYaxis()->CenterTitle(kTRUE);
         gScan2D->GetYaxis()->SetLabelSize(0.022);
         gScan2D->GetYaxis()->SetRangeUser(surfy[0], surfy[nrentries-1]);
//       j = 500+(int)((surfy[nrentries-1]-surfy[0])/(surfy[(int)((surfx[nrentries-1]-surfx[0])/(surfx[1]-surfx[0])+1)]-surfy[0]));
//       if(j > 510) j = 510;
         gScan2D->GetYaxis()->SetNdivisions(510, kTRUE);

         TGaxis *yax = (TGaxis*)gScan2D->GetYaxis();
         yax->SetMaxDigits(4);

         if(!cleanPlots)
            gScan2D->SetTitle("Surface scan");
         else
            gScan2D->SetTitle();

//         TPaletteAxis *gpalette = (TPaletteAxis*)gScan2D->GetListOfFunctions()->FindObject("palette");
//         gpalette->SetLabelSize(0.022);

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

         remove_from_last((char*)files->At(0)->GetTitle(), '_', ctemp);
         sprintf(exportname, "%s_surfscan.pdf", ctemp);
         gCanvas->SaveAs(exportname);
      }
   }
   else
   {
      printf("To make a 2D surface scan plot, select multiple root files.\n");
      change2Dsurf->SetDown(kFALSE);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_SURF);
   }

   delete[] surfx;
   delete[] surfy;
   delete[] integralCount;
}

// Change histogram when changing the channel
void TGAppMainFrame::ChangeChannel()
{
   unsigned int nrfiles = fileList->GetNumberOfEntries();
   TList *files;

   if( nrfiles > 0 )
   {
      // check the newly selected file/files and return its name/their names
      files = new TList();
      fileList->GetSelectedEntries(files);
      if(files)
      {
         for(int i = 0; i < (int)nrfiles; i++)
         {
            if(files->At(i))
            {
               if(debug)
                  printf("Filename: %s\n", files->At(i)->GetTitle());
               if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DADC) )
                  DisplayHistogram( (char*)(files->At(i)->GetTitle()), 0);
               else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DTDC) )
                  DisplayHistogram( (char*)(files->At(i)->GetTitle()), 1);
               else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_2D) )
                  DisplayHistogram( (char*)(files->At(i)->GetTitle()), 2);
            }
         }
      }
   }
}

// Setting a predetermined X range
void TGAppMainFrame::SetHistRange()
{
   unsigned int nrfiles = fileList->GetNumberOfEntries();

   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(debug)
                  printf("Filename: %s\n", files->At(i)->GetTitle());
               if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DADC) )
                  DisplayHistogram( (char*)(files->At(i)->GetTitle()), 0);
               else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DTDC) )
                  DisplayHistogram( (char*)(files->At(i)->GetTitle()), 1);
               else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_2D) )
                  DisplayHistogram( (char*)(files->At(i)->GetTitle()), 2);
            }
         }
      }
   }
}

// 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 = changeADC;
      menuID = M_ANALYSIS_HISTTYPE_1DADC;

      changeTDC->SetDown(kFALSE);
      changeADCTDC->SetDown(kFALSE);
      change2Dsurf->SetDown(kFALSE);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DTDC);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_2D);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_SURF);
   }
   // TDC histogram
   else if(type == 1)
   {
      pressedB = changeTDC;
      menuID = M_ANALYSIS_HISTTYPE_1DTDC;

      changeADC->SetDown(kFALSE);
      changeADCTDC->SetDown(kFALSE);
      change2Dsurf->SetDown(kFALSE);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DADC);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_2D);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_SURF);
   }
   // ADC vs. TDC histogram
   else if(type == 2)
   {
      pressedB = changeADCTDC;
      menuID = M_ANALYSIS_HISTTYPE_2D;

      changeADC->SetDown(kFALSE);
      changeTDC->SetDown(kFALSE);
      change2Dsurf->SetDown(kFALSE);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DADC);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DTDC);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_SURF);
   }
   // Surface scan plot
   else if(type == 3)
   {
      pressedB = change2Dsurf;
      menuID = M_ANALYSIS_HISTTYPE_SURF;

      changeADC->SetDown(kFALSE);
      changeTDC->SetDown(kFALSE);
      changeADCTDC->SetDown(kFALSE);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DADC);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_1DTDC);
      fMenuHisttype->UnCheckEntry(M_ANALYSIS_HISTTYPE_2D);
   }

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

   if(nrfiles > 0)
   {
      // Still need to add the switch!!!
      TList *files;
      files = new TList();
      fileList->GetSelectedEntries(files);

      if(type < 3)
         DisplayHistogram( (char*)(files->At(0)->GetTitle()), type);
      else if(type == 3)
         MakeSurfPlot( files );
   }
}

// Changing the histogram type to display
void TGAppMainFrame::HistogramExport()
{
   unsigned int nrfiles = fileList->GetNumberOfEntries();
   TList *files;
   TCanvas *gCanvas = histCanvas->GetCanvas();
   
   char exportname[256];
   char ctemp[256];

   if(nrfiles > 0)
   {
      files = new TList();
      fileList->GetSelectedEntries(files);
      if(files)
      {
         if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_SURF) ) // for the surface scan, the plot from all selected files is already created
         {
            remove_from_last((char*)files->At(0)->GetTitle(), '_', ctemp);
            sprintf(exportname, "%s_surfscan.pdf", ctemp);
            gCanvas->SaveAs(exportname);
         }
         else
         {
            for(int i = 0; i < (int)nrfiles; i++)
            {
               if(files->At(i))
               {
                  remove_ext((char*)files->At(i)->GetTitle(), ctemp);
     
                  if(debug)
                     printf("Filename: %s\n", files->At(i)->GetTitle());
                  if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DADC) )
                  {
                     sprintf(exportname, "%s_adc%d.pdf", ctemp, (int)selectCh->GetNumber());
                     DisplayHistogram( (char*)(files->At(i)->GetTitle()), 0);
                  }
                  else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DTDC) )
                  {
                     sprintf(exportname, "%s_tdc%d.pdf", ctemp, (int)selectCh->GetNumber());
                     DisplayHistogram( (char*)(files->At(i)->GetTitle()), 1);
                  }
                  else if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_2D) )
                  {
                     sprintf(exportname, "%s_adctdc%d.pdf", ctemp, (int)selectCh->GetNumber());
                     DisplayHistogram( (char*)(files->At(i)->GetTitle()), 2);
                  }
     
                  gCanvas->SaveAs(exportname);
               }
            }
         }
      }
   }
}

//---------------------------------------------------------------
// Main window constructor definition (& layout)

TGAppMainFrame::TGAppMainFrame(const TGWindow *p, int w, int h)
{
   gDaq = new daq();
   gScopeDaq = new daqscope();

   // Define the main window and menubar
   fMain = new TGMainFrame(p, w, h, kVerticalFrame);    // vertical frame split into menubar and main frame
   fMenuBar = new TGMdiMenuBar(fMain, 10, 10);          // just prepare menubar, draw it with InitMenu()
   fMain->AddFrame(fMenuBar, new TGLayoutHints(kLHintsTop | kLHintsExpandX));

   // Define the main frame where opened subwindows will appear
   fMainFrame = new TGMdiMainFrame(fMain, fMenuBar, 300, 300);
   fMain->AddFrame(fMainFrame, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));

   // Initialize the menubar the initial measurement layout subwindows and display the main window
   InitMenu();
   MeasurementLayout();
   fMain->SetWindowName(WINDOW_NAME);
   fMain->MapSubwindows();
   fMain->MapWindow();
   fMain->Layout();
   GetPosition();
   GetVoltOut();
}

//---------------------------------------------------------------
// Event handler for menubar actions

void TGAppMainFrame::HandleMenu(Int_t id)
{
   TList *files;

   switch (id) {
      case M_FILE_NEW:
         // Clear any values and histogram
         break;

      case M_FILE_EXIT:
         CloseWindow();
         break;

      case M_ANALYSIS_HISTTYPE_1DADC:
         // Toggles the ADC button
         ChangeHisttype(0);
         break;

      case M_ANALYSIS_HISTTYPE_1DTDC:
         ChangeHisttype(1);
         break;

      case M_ANALYSIS_HISTTYPE_2D:
         ChangeHisttype(2);
         break;

      case M_ANALYSIS_HISTTYPE_SURF:
         ChangeHisttype(3);
         break;

      case M_ANALYSIS_FIT:
         // Fit spectrum
         files = new TList();
         fileList->GetSelectedEntries(files);

         if( fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DADC) && (files->GetSize() > 0) )
            FitSpectrum(files, 1);
         break;

      case M_ANALYSIS_FITSEL:
         // Fit all spectra
         files = new TList();
         fileList->GetSelectedEntries(files);

         if( (fMenuHisttype->IsEntryChecked(M_ANALYSIS_HISTTYPE_1DADC)) && (files->GetSize() > 1) )
            FitSpectrum(files, files->GetSize());
         break;

      case M_ANALYSIS_INTEGX:
         // Integrate the current spectra
         files = new TList();
         fileList->GetSelectedEntries(files);

         IntegSpectrum(files, 1);
         break;

      case M_ANALYSIS_INTEGY:
         // Integrate the current spectra
         files = new TList();
         fileList->GetSelectedEntries(files);

         IntegSpectrum(files, 2);
         break;

      case M_ANALYSIS_PHOTMU:
         // Integrate the current spectra and calculate mean of detected photons: mu = -log(Nped/Ntot)
         files = new TList();
         fileList->GetSelectedEntries(files);

         PhotonMu(files);
         break;

      case M_TOOLS_FIELDPOINT:
         OpenWindow(1);
         break;

      case M_WINDOW_HOR:
         fMainFrame->TileHorizontal();
         break;

      case M_WINDOW_VERT:
         fMainFrame->TileVertical();
         break;

      case M_HELP_ABOUT:
         About();
         break;

      default:
         fMainFrame->SetCurrent(id);
         break;
   }
}

//---------------------------------------------------------------
// Initialize the main window menu

void TGAppMainFrame::InitMenu()
{
   fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);

   // Popup menu in menubar for File controls
   fMenuFile = new TGPopupMenu(gClient->GetRoot());     // adds a new popup menu to the menubar
   fMenuFile->AddEntry(new TGHotString("&New Measurement"), M_FILE_NEW);
   fMenuFile->AddSeparator();
   fMenuFile->AddEntry(new TGHotString("E&xit"), M_FILE_EXIT);

   // Popup menu in menubar for Analysis controls
   fMenuHisttype = new TGPopupMenu(gClient->GetRoot()); // adds a cascade menu that will be incorporated into analysis controls
   fMenuHisttype->AddEntry(new TGHotString("1D &ADC histogram"), M_ANALYSIS_HISTTYPE_1DADC);
   fMenuHisttype->AddEntry(new TGHotString("1D &TDC histogram"), M_ANALYSIS_HISTTYPE_1DTDC);
   fMenuHisttype->AddEntry(new TGHotString("&2D ADC vs. TDC histogram"), M_ANALYSIS_HISTTYPE_2D);
   fMenuHisttype->AddEntry(new TGHotString("2D &surface scan plot"), M_ANALYSIS_HISTTYPE_SURF);

   fMenuAnalysis = new TGPopupMenu(gClient->GetRoot()); // adds a new popup menu to the menubar
   fMenuAnalysis->AddPopup(new TGHotString("&Histogram type"), fMenuHisttype);

   fMenuAnalysis->AddEntry(new TGHotString("&Fit spectrum"), M_ANALYSIS_FIT);
   fMenuAnalysis->AddEntry(new TGHotString("Fit &all selected"), M_ANALYSIS_FITSEL);
   fMenuAnalysis->AddEntry(new TGHotString("Integrate spectrum (&X direction)"), M_ANALYSIS_INTEGX);
   fMenuAnalysis->AddEntry(new TGHotString("Integrate spectrum (&Y direction)"), M_ANALYSIS_INTEGY);
   fMenuAnalysis->AddEntry(new TGHotString("Relative &PDE"), M_ANALYSIS_PHOTMU);

   // Popup menu in menubar for External tools
   fMenuTools = new TGPopupMenu(gClient->GetRoot());    // adds a new popup menu to the menubar
   fMenuTools->AddEntry(new TGHotString("&Fieldpoint temperature sensor"), M_TOOLS_FIELDPOINT);

   // Popup menu in menubar for Window controls
   fMenuWindow = new TGPopupMenu(gClient->GetRoot());   // adds a new popup menu to the menubar
   fMenuWindow->AddEntry(new TGHotString("Tile &Horizontally"), M_WINDOW_HOR);
   fMenuWindow->AddEntry(new TGHotString("Tile &Vertically"), M_WINDOW_VERT);
   fMenuWindow->AddPopup(new TGHotString("&Windows"), fMainFrame->GetWinListMenu());

   // Popup menu in menubar for Help controls
   fMenuHelp = new TGPopupMenu(gClient->GetRoot());
   fMenuHelp->AddEntry(new TGHotString("&About"), M_HELP_ABOUT);

   // Connect all menu items with actions - handled by HandleMenu()
   fMenuFile->Connect("Activated(Int_t)", "TGAppMainFrame", this, "HandleMenu(Int_t)");
   fMenuAnalysis->Connect("Activated(Int_t)", "TGAppMainFrame", this, "HandleMenu(Int_t)");
   fMenuTools->Connect("Activated(Int_t)", "TGAppMainFrame", this, "HandleMenu(Int_t)");
   fMenuWindow->Connect("Activated(Int_t)", "TGAppMainFrame", this, "HandleMenu(Int_t)");
   fMenuHelp->Connect("Activated(Int_t)", "TGAppMainFrame", this, "HandleMenu(Int_t)");

   // Draw the created popup menus on the menubar
   fMenuBar->AddPopup(new TGHotString("&File"), fMenuFile, fMenuBarItemLayout);
   fMenuBar->AddPopup(new TGHotString("&Analysis"),fMenuAnalysis,fMenuBarItemLayout);
   fMenuBar->AddPopup(new TGHotString("&Tools"),fMenuTools,fMenuBarItemLayout);
   fMenuBar->AddPopup(new TGHotString("&Windows"),fMenuWindow,fMenuBarItemLayout);
   fMenuBar->AddPopup(new TGHotString("&Help"), fMenuHelp, fMenuBarItemLayout);

   // Disable fieldpoint if we are not connected to the IJS network
#if IJSNET == 0
   fMenuTools->DisableEntry(M_TOOLS_FIELDPOINT);
#endif
}

//---------------------------------------------------------------
// Set the measurement subwindow layout

void TGAppMainFrame::MeasurementLayout()
{
   TGMdiFrame *mdiFrame;

   // Generic horizontal and vertical frames
   TGHorizontalFrame *fH1, *fH2, *fH3;
   TGVerticalFrame *fV1;
   TGGroupFrame *fG1;
   TGLabel *lab;
   TGCompositeFrame *fT1;

   // Sizes of internal group and subwindow structures
   int subwin[2];
   int subgroup[2];

// Settings pane ---------------------------------------------------------------------------
   subwin[0] = (winWidth/6)-5; subwin[1] = 3*((winHeight/5)-5)-10;
   settingsPane = new TGMdiSubwindow(fMainFrame, subwin[0], subwin[1]);
   mdiFrame = settingsPane->GetMdiFrame();

   // Check button to toggle voltage scan
   voltscanOn = new TGCheckButton(mdiFrame, "Voltage scan ON/OFF");
   voltscanOn->Resize(50,22);
   voltscanOn->SetState(kButtonUp);
   mdiFrame->AddFrame(voltscanOn, f0centerx);

   // Check button to toggle surface scan
   surfscanOn = new TGCheckButton(mdiFrame, "Surface scan ON/OFF");
   surfscanOn->Resize(50,22);
   surfscanOn->SetState(kButtonUp);
   mdiFrame->AddFrame(surfscanOn, f0centerx);

   // Check button to toggle Z direction scan
   zscanOn = new TGCheckButton(mdiFrame, "Z-axis scan ON/OFF");
   zscanOn->Resize(50,22);
   zscanOn->SetState(kButtonUp);
   mdiFrame->AddFrame(zscanOn, f0centerx);

   // Check button to toggle (open) the histogram window
//   histogramOn = new TGCheckButton(mdiFrame, "Histogram display ON/OFF");
//   histogramOn->Resize(50,22);
//   histogramOn->SetState(kButtonUp);
//   mdiFrame->AddFrame(histogramOn, f0centerx);

   subgroup[0] = subwin[0]-10;
   // Hard limit for maximum voltage we can set
   fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30);
   lab = new TGLabel(fH1, "Voltage limit:");
   fH1->AddFrame(lab, f0center2d);
   vHardlimit = new TGNumberEntry(fH1, 70.00, 4, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEAAnyNumber);
   vHardlimit->Resize(80,22);
   fH1->AddFrame(vHardlimit, f0center2d);
   mdiFrame->AddFrame(fH1, f2);

   // Number of used channels
   fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30);
   lab = new TGLabel(fH1, "Nr. of channels:");
   fH1->AddFrame(lab, f0center2d);
   NCH = new TGNumberEntry(fH1, 1, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 1, 8);
   NCH->Resize(40,22);
   fH1->AddFrame(NCH, f0center2d);
   mdiFrame->AddFrame(fH1, f2);

   // Check button to toggle plots with additional information or clean plots
   cleanOn = new TGCheckButton(mdiFrame, "Clean plots ON/OFF");
   cleanOn->Resize(50,22);
   cleanOn->SetState(kButtonDown);
   cleanPlots = 1;
   mdiFrame->AddFrame(cleanOn, f0centerx);

   // Button and textbox to enter the oscilloscope IP address
   lab = new TGLabel(mdiFrame, "Scope IP:");
   mdiFrame->AddFrame(lab, f0);
   fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30);
   oscIP = new TGTextEntry(fH1, "178.172.43.157");
   oscIP->Resize(110,22);
   fH1->AddFrame(oscIP, f0);
   oscConnect = new TGTextButton(fH1, "Connect");
   oscConnect->SetTextJustify(36);
   oscConnect->SetWrapLength(-1);
   oscConnect->Resize(60,22);
   fH1->AddFrame(oscConnect, f0);
   oscOn = 0;
   mdiFrame->AddFrame(fH1, f2);

   // Laser settings (freq., tune, ND filter)
   lab = new TGLabel(mdiFrame, "Laser settings:");
   mdiFrame->AddFrame(lab, f0);
   fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30);
   laserInfo = new TGTextEntry(fH1, "kHz, tune, ND");
   fH1->AddFrame(laserInfo, f2);
   mdiFrame->AddFrame(fH1, f2);

   // Chamber temperature (will only be manually set until we can get it directly from the chamber)
   fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30);
   lab = new TGLabel(fH1, "Chamber temp.:");
   fH1->AddFrame(lab, f0center2d);
   chtemp = new TGNumberEntry(fH1, 25.0, 6, 999, TGNumberFormat::kNESRealOne, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -70., 150.);
   chtemp->Resize(60,22);
   fH1->AddFrame(chtemp, f0center2d);
   mdiFrame->AddFrame(fH1, f2);
   
   // Incidence angle (will only be manually set until we can make it motorized)
   fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30);
   lab = new TGLabel(fH1, "Incid. angle:");
   fH1->AddFrame(lab, f0center2d);
   incangle = new TGNumberEntry(fH1, 0.0, 6, 999, TGNumberFormat::kNESRealOne, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -180., 180.);
   incangle->Resize(60,22);
   fH1->AddFrame(incangle, f0center2d);
   mdiFrame->AddFrame(fH1, f2);

   mdiFrame->SetMdiHints(kMdiMinimize);
   mdiFrame->SetWindowName("Settings pane");
   mdiFrame->MapSubwindows();
   mdiFrame->Layout();
   mdiFrame->Move(0,0);
// Settings pane ---------------------------------------------------------------------------

// Main window -----------------------------------------------------------------------------
   subwin[0] = 3*((winWidth/6)-5); subwin[1] = 3*((winHeight/5)-5)-10;
   mainSubwindow = new TGMdiSubwindow(fMainFrame, subwin[0], subwin[1]);
   mdiFrame = mainSubwindow->GetMdiFrame();

   // Voltage and position tab
   subgroup[0] = 2*subwin[0]/5-12;
   subgroup[1] = (subwin[1]+15)/2+5;
   setTab = new TGTab(mdiFrame, subgroup[0], subgroup[1]);
   
   fT1 = setTab->AddTab("Voltage + Position");

   fH1 = new TGHorizontalFrame(fT1, subwin[0], subgroup[1], kFixedHeight);
   // Left pane (Bias voltage controls)
   fV1 = new TGVerticalFrame(fH1, subgroup[0], subgroup[1], kFixedWidth | kFixedHeight);
   fG1 = new TGGroupFrame(fV1, "Bias voltage controls");

   // Output voltage supply channel
   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH2, "Output channel:");
   fH2->AddFrame(lab, f0center2d);
   vOutCh = new TGComboBox(fH2, 200);
   vOutCh->AddEntry("1", 0);
   vOutCh->AddEntry("2", 1);
   vOutCh->AddEntry("3", 2);
   vOutCh->AddEntry("4", 3);
   vOutCh->AddEntry("5", 4);
   vOutCh->AddEntry("6", 5);
   vOutCh->AddEntry("7", 6);
   vOutCh->AddEntry("8", 7);
   vOutCh->AddEntry("101", 8);
   vOutCh->AddEntry("102", 9);
   vOutCh->AddEntry("103", 10);
   vOutCh->AddEntry("104", 11);
   vOutCh->AddEntry("105", 12);
   vOutCh->AddEntry("106", 13);
   vOutCh->AddEntry("107", 14);
   vOutCh->AddEntry("108", 15);
   vOutCh->Resize(50,22);
   vOutCh->Select(0);
   fH2->AddFrame(vOutCh, f0center2d);
   fG1->AddFrame(fH2, f2);

   // Output voltage setting
   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH2, "Output voltage:");
   fH2->AddFrame(lab, f0center2d);
   vOut = new TGNumberEntry(fH2, 0.00, 4, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, 0, vHardlimit->GetNumber());
   vOut->Resize(80,22);
   fH2->AddFrame(vOut, f0center2d);
   fG1->AddFrame(fH2, f2);

   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   vOutOnOff = new TGCheckButton(fH2, "Output ON/OFF");
   vOutOnOff->Resize(subgroup[0]-10,22);
   vOutOnOff->SetState(kButtonUp);
   fH2->AddFrame(vOutOnOff, f0centerx);
   fG1->AddFrame(fH2, f2);

   // Set, get and reset voltage buttons
   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   fH3 = new TGHorizontalFrame(fH2, subgroup[0], 30);
   vOutSet = new TGTextButton(fH3, "Set");
   vOutSet->SetTextJustify(36);
   vOutSet->SetWrapLength(-1);
   vOutSet->Resize(60,22);
   fH3->AddFrame(vOutSet, f0);
   vOutGet = new TGTextButton(fH3, "Get");
   vOutGet->SetTextJustify(36);
   vOutGet->SetWrapLength(-1);
   vOutGet->Resize(60,22);
   fH3->AddFrame(vOutGet, f0);
   vOutReset = new TGTextButton(fH3, "Reset");
   vOutReset->SetTextJustify(36);
   vOutReset->SetWrapLength(-1);
   vOutReset->Resize(60,22);
   fH3->AddFrame(vOutReset, f0);
   fH2->AddFrame(fH3, f0centerx);
   fG1->AddFrame(fH2, f2);

   // Voltage scan controls
   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH2, "V (min):");
   fH2->AddFrame(lab, f0center2d);
   vOutStart = new TGNumberEntry(fH2, 0.00, 4, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEAAnyNumber);
   vOutStart->Resize(80,22);
   fH2->AddFrame(vOutStart, f0center2d);
   fG1->AddFrame(fH2, f2);

   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH2, "V (max):");
   fH2->AddFrame(lab, f0center2d);
   vOutStop = new TGNumberEntry(fH2, 0.00, 4, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEAAnyNumber);
   vOutStop->Resize(80,22);
   fH2->AddFrame(vOutStop, f0center2d);
   fG1->AddFrame(fH2, f2);

   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH2, "V (step):");
   fH2->AddFrame(lab, f0center2d);
   vOutStep = new TGNumberEntry(fH2, 0.00, 4, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEAAnyNumber);
   vOutStep->Resize(80,22);
   fH2->AddFrame(vOutStep, f0center2d);
   fG1->AddFrame(fH2, f2);

   fV1->AddFrame(fG1, f1);
   // Left pane (Bias voltage controls)
   fH1->AddFrame(fV1, f0);
   
   // Right pane (Table position controls)
   subgroup[0] = 3*subwin[0]/5-12;
   fV1 = new TGVerticalFrame(fH1, subgroup[0], subgroup[1], kFixedWidth | kFixedHeight);
   fG1 = new TGGroupFrame(fV1, "Table position controls");

   // X, Y and Z positions
   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH2, "X:");
   fH2->AddFrame(lab, f0center2d);
   xPos = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 215000);
   xPos->Resize(80,22);
   fH2->AddFrame(xPos, f0center2d);

   lab = new TGLabel(fH2, "Z (min):");
   fH2->AddFrame(lab, f0center2d);
   zPosMin = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 375000);
   zPosMin->Resize(80,22);
   fH2->AddFrame(zPosMin, f0center2d);
   fG1->AddFrame(fH2, f2);

   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH2, "Y:");
   fH2->AddFrame(lab, f0center2d);
   yPos = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 215000);
   yPos->Resize(80,22);
   fH2->AddFrame(yPos, f0center2d);

   lab = new TGLabel(fH2, "Z (max):");
   fH2->AddFrame(lab, f0center2d);
   zPosMax = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 375000);
   zPosMax->Resize(80,22);
   fH2->AddFrame(zPosMax, f0center2d);
   fG1->AddFrame(fH2, f2);

   fH2 = new TGHorizontalFrame(fG1, subgroup[0] ,30);
   lab = new TGLabel(fH2, "Z:");
   fH2->AddFrame(lab, f0center2d);
   zPos = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 375000);
   zPos->Resize(80,22);
   fH2->AddFrame(zPos, f0center2d);

   lab = new TGLabel(fH2, "Z (step):");
   fH2->AddFrame(lab, f0center2d);
   zPosStep = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative);
   zPosStep->Resize(80,22);
   fH2->AddFrame(zPosStep, f0center2d);
   fG1->AddFrame(fH2, f2);

   // Set, Get and Home the table position
   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   fH3 = new TGHorizontalFrame(fH2, subgroup[0], 30);
   positionSet = new TGTextButton(fH3, "Set");
   positionSet->SetTextJustify(36);
   positionSet->SetWrapLength(-1);
   positionSet->Resize(60,22);
   fH3->AddFrame(positionSet, f0);
   positionGet = new TGTextButton(fH3, "Get");
   positionGet->SetTextJustify(36);
   positionGet->SetWrapLength(-1);
   positionGet->Resize(60,22);
   fH3->AddFrame(positionGet, f0);
   positionHome = new TGTextButton(fH3, "Home");
   positionHome->SetTextJustify(36);
   positionHome->SetWrapLength(-1);
   positionHome->Resize(60,22);
   fH3->AddFrame(positionHome, f0);
   fH2->AddFrame(fH3, f0centerx);
   fG1->AddFrame(fH2, f2);

   // Position scan controls
   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH2, "X (min):");
   fH2->AddFrame(lab, f0center2d);
   xPosMin = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 215000);
   xPosMin->Resize(80,22);
   fH2->AddFrame(xPosMin, f0center2d);

   lab = new TGLabel(fH2, "Y (min):");
   fH2->AddFrame(lab, f0center2d);
   yPosMin = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 215000);
   yPosMin->Resize(80,22);
   fH2->AddFrame(yPosMin, f0center2d);
   fG1->AddFrame(fH2, f2);

   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH2, "X (max):");
   fH2->AddFrame(lab, f0center2d);
   xPosMax = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 215000);
   xPosMax->Resize(80,22);
   fH2->AddFrame(xPosMax, f0center2d);

   lab = new TGLabel(fH2, "Y (max):");
   fH2->AddFrame(lab, f0center2d);
   yPosMax = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax, -100, 215000);
   yPosMax->Resize(80,22);
   fH2->AddFrame(yPosMax, f0center2d);
   fG1->AddFrame(fH2, f2);

   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH2, "X (step):");
   fH2->AddFrame(lab, f0center2d);
   xPosStep = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative);
   xPosStep->Resize(80,22);
   fH2->AddFrame(xPosStep, f0center2d);

   lab = new TGLabel(fH2, "Y (step):");
   fH2->AddFrame(lab, f0center2d);
   yPosStep = new TGNumberEntry(fH2, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative);
   yPosStep->Resize(80,22);
   fH2->AddFrame(yPosStep, f0center2d);
   fG1->AddFrame(fH2, f2);
   
   fV1->AddFrame(fG1, f1);
   // Right pane (Table position controls)
   fH1->AddFrame(fV1, f0);
   fT1->AddFrame(fH1, f1);

   // Waveform tab
   fT1 = setTab->AddTab("Waveform analysis");
   fH1 = new TGHorizontalFrame(fT1, subwin[0], subgroup[1], kFixedHeight);
   subgroup[0] = 1*subwin[0]/2-12;
   fV1 = new TGVerticalFrame(fH1, subgroup[0], subgroup[1]/3, kFixedWidth);

   fG1 = new TGGroupFrame(fV1, "Acquisition channel");

   // Selection of channels
   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 100);
   sCH[0] = new TGCheckButton(fH2, "CH1");
   sCH[0]->Resize(50,22);
   sCH[0]->SetState(kButtonUp);
   fH2->AddFrame(sCH[0], f0centerx);
   sCH[1] = new TGCheckButton(fH2, "CH2");
   sCH[1]->Resize(50,22);
   sCH[1]->SetState(kButtonUp);
   fH2->AddFrame(sCH[1], f0centerx);
   sCH[2] = new TGCheckButton(fH2, "CH3");
   sCH[2]->Resize(50,22);
   sCH[2]->SetState(kButtonUp);
   fH2->AddFrame(sCH[2], f0centerx);
   sCH[3] = new TGCheckButton(fH2, "CH4");
   sCH[3]->Resize(50,22);
   sCH[3]->SetState(kButtonUp);
   fH2->AddFrame(sCH[3], f0centerx);
   fG1->AddFrame(fH2, f0centerx);

   // Selection of MATH channels
   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 100);
   sCH[4] = new TGCheckButton(fH2, "MATH1");
   sCH[4]->Resize(50,22);
   sCH[4]->SetState(kButtonUp);
   fH2->AddFrame(sCH[4], f0centerx);
   sCH[5] = new TGCheckButton(fH2, "MATH2");
   sCH[5]->Resize(50,22);
   sCH[5]->SetState(kButtonUp);
   fH2->AddFrame(sCH[5], f0centerx);
   sCH[6] = new TGCheckButton(fH2, "MATH3");
   sCH[6]->Resize(50,22);
   sCH[6]->SetState(kButtonUp);
   fH2->AddFrame(sCH[6], f0centerx);
   sCH[7] = new TGCheckButton(fH2, "MATH4");
   sCH[7]->Resize(50,22);
   sCH[7]->SetState(kButtonUp);
   fH2->AddFrame(sCH[7], f0centerx);
   fG1->AddFrame(fH2, f0centerx);

   fV1->AddFrame(fG1, f2);

   // Selection of measurement type
   fH2 = new TGHorizontalFrame(fV1, subgroup[0], 30);
   lab = new TGLabel(fH2, "Scope use type:");
   fH2->AddFrame(lab, f0center2d);
   sMeasType = new TGComboBox(fH2, 200);
   sMeasType->AddEntry("No waveform analysis", 0);
   sMeasType->AddEntry("Waveform acquisition", 1);
   sMeasType->AddEntry("Measurement", 2);
   sMeasType->Resize(150,22);
   sMeasType->Select(0);
   fH2->AddFrame(sMeasType, f0center2d);
   fV1->AddFrame(fH2, f2);

   // Link waveform analysis to CAMAC acquisition
   sCamaclink = new TGCheckButton(fV1, "Link waveform to CAMAC acquisition");
   sCamaclink->Resize(200,22);
   sCamaclink->SetState(kButtonUp);
   fV1->AddFrame(sCamaclink, f0centerx);

   // Custom command interface for the scope
   lab = new TGLabel(fV1, "Custom scope command:");
   fV1->AddFrame(lab, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,10,2) );
   fH2 = new TGHorizontalFrame(fV1, subgroup[0], 30);
   scopeCommand = new TGTextEntry(fH2, "");
   scopeCommand->Resize(subgroup[0]-45,22);
   fH2->AddFrame(scopeCommand, f2);
   sendScopeCustom = new TGTextButton(fH2, "Send");
   sendScopeCustom->SetTextJustify(36);
   sendScopeCustom->SetWrapLength(-1);
   sendScopeCustom->Resize(80,22);
   fH2->AddFrame(sendScopeCustom, f0centery);
   fV1->AddFrame(fH2, f0);

   // Return value for custom scope command
   lab = new TGLabel(fV1, "Return:");
   fV1->AddFrame(lab, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,10,2) );
   scopeReturn = new TGTextEntry(fV1, "");
   scopeReturn->Resize(subgroup[0],22);
   fV1->AddFrame(scopeReturn, f2);

   fH1->AddFrame(fV1, f0);

   // Wave measurement type
   fV1 = new TGVerticalFrame(fH1, subgroup[0], subgroup[1]/3, kFixedWidth);
   fH2 = new TGHorizontalFrame(fV1, subgroup[0], 30);
   lab = new TGLabel(fH2, "Meas. type:");
   fH2->AddFrame(lab, f0center2d);
   sMeasgroup = new TGComboBox(fH2, 200);
   for(int i = 0; i < 11; i++)
      sMeasgroup->AddEntry(allMeasNames[i], i);
   sMeasgroup->Resize(150,22);
   sMeasgroup->Select(4);
   fH2->AddFrame(sMeasgroup, f0center2d);
   fV1->AddFrame(fH2, f2);

   // Initialize current acquisition settings
   scopeInit = new TGTextButton(fV1, "Initialize scope");
   scopeInit->SetTextJustify(36);
   scopeInit->SetWrapLength(-1);
   scopeInit->Resize(80,22);
   fV1->AddFrame(scopeInit, f0centerx);

   fH1->AddFrame(fV1, f0);
   fT1->AddFrame(fH1, f1);

   mdiFrame->AddFrame(setTab, f0);

   // Bottom pane (File controls)
   subgroup[0] = subwin[0]-20;
   subgroup[1] = subwin[1]/3-30; //2*(3*((winWidth/6)-5))/5+10;
   fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], subgroup[1] /*1*(3*((winWidth/6)-5))/5+15*/ , kFixedWidth | kFixedHeight);
   fG1 = new TGGroupFrame(fH1, "Event/Data file controls");

   // Number of events
   fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH2, "Number of events:");
   fH2->AddFrame(lab, f0centery);
   evtNum = new TGNumberEntry(fH2, 10000, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative);
   evtNum->Resize(80,22);
   fH2->AddFrame(evtNum, f0centery);
   fG1->AddFrame(fH2, f2);

   // Time stamp display
   fH2 = new TGHorizontalFrame(fG1,600,200);
   lab = new TGLabel(fH2, "Time stamp:");
   fH2->AddFrame(lab, f0centery);
   timeStamp = new TGTextEntry(fH2, "");
   timeStamp->Resize(440,22);
   timeStamp->SetState(kFALSE); // time stamp is read-only
   fH2->AddFrame(timeStamp, f0centery);
   fG1->AddFrame(fH2, f2);

   // Save to file
   fH2 = new TGHorizontalFrame(fG1,600,200);
   lab = new TGLabel(fH2, "Save to file:");
   fH2->AddFrame(lab, f0centery);
   char *cTemp;
   cTemp = new char[256];
   sprintf(cTemp, "./results/test%s", histExt);
   fileName = new TGTextEntry(fH2, cTemp);
   delete[] cTemp;
   fileName->Resize(400,22);
   fileName->SetState(kFALSE);
   fH2->AddFrame(fileName, f0centery);
   saveFile = new TGTextButton(fH2, "...");
   saveFile->SetTextJustify(36);
   saveFile->SetWrapLength(-1);
   saveFile->Resize(80,22);
   fH2->AddFrame(saveFile, f0centery);
//   mdiFrame->AddFrame(fH2, f0);
   fG1->AddFrame(fH2, f2);
   fH1->AddFrame(fG1, f1);
   // Bottom pane (File controls)
   mdiFrame->AddFrame(fH1, f0);

   subgroup[0] = subwin[0]-70;
   fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30);
   fH2 = new TGHorizontalFrame(fH1, 3*subgroup[0]/4, 30, kFixedWidth);
   measStart = new TGTextButton(fH2, "Start acquisition");
   measStart->SetTextJustify(36);
   measStart->SetWrapLength(-1);
   measStart->Resize(80,22);
   fH2->AddFrame(measStart, f0center2d);

   ULong_t fcolor;
   gClient->GetColorByName("red", fcolor);

   busyLabel = new TGLabel(fH2, "Busy"); //, fTextGC->GetGC(), labelfont, kChildFrame);
   busyLabel->SetTextJustify(36);
   busyLabel->Resize(80,22);
   busyLabel->Disable();
   busyLabel->SetTextColor(fcolor);
   fH2->AddFrame(busyLabel, f0center2d);

   curProgress = new TGHProgressBar(fH2, TGProgressBar::kStandard, 150);
   curProgress->ShowPosition();
   curProgress->SetRange(0,100);
   curProgress->SetBarColor("green");
   fH2->AddFrame(curProgress, f0center2d);
   fH1->AddFrame(fH2, f0centerx);
   mdiFrame->AddFrame(fH1, f2);

   mdiFrame->SetMdiHints(kMdiMinimize | kMdiMaximize);
   mdiFrame->SetWindowName("Main measurement window");
   mdiFrame->MapSubwindows();
   mdiFrame->Layout();
   mdiFrame->Move((winWidth/6),0);
// Main window -----------------------------------------------------------------------------

// Histogram pane --------------------------------------------------------------------------
   subwin[0] = 2*((winWidth/6)-5); subwin[1] = (int)(2.5*((winHeight/5)-5))-5;
   histogramPane = new TGMdiSubwindow(fMainFrame, subwin[0], subwin[1]);
   mdiFrame = histogramPane->GetMdiFrame();

   histCanvas = new TRootEmbeddedCanvas("histCanvas",mdiFrame,900,900);
   mdiFrame->AddFrame(histCanvas, f1);
   TCanvas *gCanvas = histCanvas->GetCanvas();
   gCanvas->SetGridx();
   gCanvas->SetGridy();

   mdiFrame->SetMdiHints(kMdiMinimize | kMdiMaximize);
   mdiFrame->SetWindowName("Histogram");
   mdiFrame->MapSubwindows();
   mdiFrame->Layout();
   mdiFrame->Move(4*((winWidth/6)-5)+10,0);
// Histogram pane --------------------------------------------------------------------------

// Histogram file selection pane -----------------------------------------------------------
   subwin[0] = 4*((winWidth/6)-5); subwin[1] = 2*((winHeight/5)-5)+15;
   histogramPaneFile = new TGMdiSubwindow(fMainFrame, subwin[0]+5, subwin[1]);
   mdiFrame = histogramPaneFile->GetMdiFrame();

   // Open browser for file selection 
   subgroup[0] = subwin[0]-10;
   fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30);
   lab = new TGLabel(fH1, "File selection:");
   fH1->AddFrame(lab, f0centery);

   selectDir = new TGTextButton(fH1, "...");
   selectDir->SetTextJustify(36);
   selectDir->SetWrapLength(-1);
   selectDir->Resize(80,22);
   fH1->AddFrame(selectDir, f0centery);
   mdiFrame->AddFrame(fH1, f2);

   // List view of the opened files
   fileList = new TGListBox(mdiFrame,1);
   fileList->GetVScrollbar();
   fileList->Resize(300, (3*subwin[1]/7)-10 );
   mdiFrame->AddFrame(fileList, f2);

   // Multiple file selection toggle, previous/next controls, clear list and edit header
   fH1 = new TGHorizontalFrame(mdiFrame, subgroup[0], 30);
   multiSelect = new TGCheckButton(fH1, "Multiple file select");
   multiSelect->Resize(50,22);
   multiSelect->SetState(kButtonUp);
   fH1->AddFrame(multiSelect, f0);

   multiSelectAll = new TGCheckButton(fH1, "Select all listed files");
   multiSelectAll->Resize(50,22);
   multiSelectAll->SetState(kButtonUp);
   fH1->AddFrame(multiSelectAll, f0);

   TGTextButton *clearList = new TGTextButton(fH1, "Clear list");
   clearList->SetTextJustify(36);
   clearList->SetWrapLength(-1);
   clearList->Resize(80,22);
   fH1->AddFrame(clearList, f0right);

   TGTextButton *editHeader = new TGTextButton(fH1, "Edit header");
   editHeader->SetTextJustify(36);
   editHeader->SetWrapLength(-1);
   editHeader->Resize(80,22);
   fH1->AddFrame(editHeader, f0right);

   nextFile = new TGTextButton(fH1, ">>");
   nextFile->SetTextJustify(36);
   nextFile->SetWrapLength(-1);
   nextFile->Resize(80,22);
   fH1->AddFrame(nextFile, f0right);

   prevFile = new TGTextButton(fH1, "<<");
   prevFile->SetTextJustify(36);
   prevFile->SetWrapLength(-1);
   prevFile->Resize(80,22);
   fH1->AddFrame(prevFile, f0right);
   mdiFrame->AddFrame(fH1, f2);

   // Header information of opened file
   fG1 = new TGGroupFrame(mdiFrame, "Opened file header information");
   fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH1, "Time:");
   fH1->AddFrame(lab, f0centery);
   disptime = new TGTextEntry(fH1, "");
   disptime->Resize(440,22);
   disptime->SetState(kFALSE);
   fH1->AddFrame(disptime, f0centery);
   fG1->AddFrame(fH1, f2);

   fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH1, "Bias voltage:");
   fH1->AddFrame(lab, f0centery);
   dispbias = new TGNumberEntry(fH1, 0.00, 4, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEAAnyNumber);
   dispbias->Resize(80,22);
   dispbias->SetState(kFALSE);
   fH1->AddFrame(dispbias, f0centery);

   lab = new TGLabel(fH1, "Position:");
   fH1->AddFrame(lab, f0centery);
   disppos = new TGTextEntry(fH1, "");
   disppos->Resize(200,22);
   disppos->SetState(kFALSE);
   fH1->AddFrame(disppos, f0centery);

   lab = new TGLabel(fH1, "Temperature:");
   fH1->AddFrame(lab, f0centery);
   disptemp = new TGNumberEntry(fH1, 0.0, 6, 999, TGNumberFormat::kNESRealOne, TGNumberFormat::kNEAAnyNumber);
   disptemp->Resize(80,22);
   disptemp->SetState(kFALSE);
   fH1->AddFrame(disptemp, f0centery);

   lab = new TGLabel(fH1, "Angle:");
   fH1->AddFrame(lab, f0centery);
   dispangle = new TGNumberEntry(fH1, 0.0, 6, 999, TGNumberFormat::kNESRealOne, TGNumberFormat::kNEAAnyNumber);
   dispangle->Resize(80,22);
   dispangle->SetState(kFALSE);
   fH1->AddFrame(dispangle, f0centery);
   fG1->AddFrame(fH1, f2);

   fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH1, "Laser settings:");
   fH1->AddFrame(lab, f0centery);
   displaser = new TGTextEntry(fH1, "");
   displaser->Resize(440,22);
   displaser->SetState(kFALSE);
   fH1->AddFrame(displaser, f0centery);
   fG1->AddFrame(fH1, f2);
   mdiFrame->AddFrame(fG1, f2);

   mdiFrame->SetMdiHints(kMdiMinimize);
   mdiFrame->SetWindowName("Histogram file selection");
   mdiFrame->MapSubwindows();
   mdiFrame->Layout();
   mdiFrame->Move(0,3*((winHeight/5)-5)-5);
// Histogram file selection pane -----------------------------------------------------------

// Histogram controls pane -----------------------------------------------------------------
   subwin[0] = 2*((winWidth/6)-5); subwin[1] = (int)(2.5*((winHeight/5)-5))+10;
   histogramPaneCtr = new TGMdiSubwindow(fMainFrame, subwin[0], subwin[1]);
   mdiFrame = histogramPaneCtr->GetMdiFrame();

   // Control for histogram X range
   subgroup[0] = subwin[0]-6;
   fG1 = new TGGroupFrame(mdiFrame, "Histogram display");
   fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH1, "ADC range (min, max):");
   fH1->AddFrame(lab, f0centery);
   adcMinRange = new TGNumberEntry(fH1, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber);
   adcMinRange->Resize(80,22);
   fH1->AddFrame(adcMinRange, f0centery);
   adcMaxRange = new TGNumberEntry(fH1, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber);
   adcMaxRange->Resize(80,22);
   fH1->AddFrame(adcMaxRange, f0centery);
   fG1->AddFrame(fH1, f2);

   // TDC window for getting data
   fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH1, "TDC range (min, max):");
   fH1->AddFrame(lab, f0centery);
   tdcMinwindow = new TGNumberEntry(fH1, 0.0, 6, 999, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEAAnyNumber);
   tdcMinwindow->Resize(80,22);
   fH1->AddFrame(tdcMinwindow, f0centery);
   tdcMaxwindow = new TGNumberEntry(fH1, 221.8, 6, 999, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEAAnyNumber);
   tdcMaxwindow->Resize(80,22);
   fH1->AddFrame(tdcMaxwindow, f0centery);
   fG1->AddFrame(fH1, f2);

   // Y axis range settings
   fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH1, "Y range (min, max):");
   fH1->AddFrame(lab, f0centery);
   yMinRange = new TGNumberEntry(fH1, 0, 6, 999, TGNumberFormat::kNESRealOne, TGNumberFormat::kNEAAnyNumber);
   yMinRange->Resize(80,22);
   fH1->AddFrame(yMinRange, f0centery);
   yMaxRange = new TGNumberEntry(fH1, 0, 6, 999, TGNumberFormat::kNESRealOne, TGNumberFormat::kNEAAnyNumber);
   yMaxRange->Resize(80,22);
   fH1->AddFrame(yMaxRange, f0centery);
   fG1->AddFrame(fH1, f2);

   // Select the channel to display
   fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   lab = new TGLabel(fH1, "Display channel:");
   fH1->AddFrame(lab, f0centery);
   selectCh = new TGNumberEntry(fH1, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, (NCH->GetNumber())-1);
   selectCh->Resize(40,22);
   fH1->AddFrame(selectCh, f0centery);

   changeADC = new TGTextButton(fH1, "ADC");
   changeADC->AllowStayDown(kTRUE);
   changeADC->SetDown(kTRUE);
   fMenuHisttype->CheckEntry(M_ANALYSIS_HISTTYPE_1DADC);
   changeADC->SetTextJustify(36);
   changeADC->SetWrapLength(-1);
   changeADC->Resize(60,22);
   fH1->AddFrame(changeADC, f0centery);

   changeTDC = new TGTextButton(fH1, "TDC");
   changeTDC->AllowStayDown(kTRUE);
   changeTDC->SetTextJustify(36);
   changeTDC->SetWrapLength(-1);
   changeTDC->Resize(60,22);
   fH1->AddFrame(changeTDC, f0centery);

   changeADCTDC = new TGTextButton(fH1, "ADC/TDC");
   changeADCTDC->AllowStayDown(kTRUE);
   changeADCTDC->SetTextJustify(36);
   changeADCTDC->SetWrapLength(-1);
   changeADCTDC->Resize(60,22);
   fH1->AddFrame(changeADCTDC, f0centery);
   
   change2Dsurf = new TGTextButton(fH1, "Surf 2D");
   change2Dsurf->AllowStayDown(kTRUE);
   change2Dsurf->SetTextJustify(36);
   change2Dsurf->SetWrapLength(-1);
   change2Dsurf->Resize(60,22);
   fH1->AddFrame(change2Dsurf, f0);
   fG1->AddFrame(fH1, f2);

   logscale = new TGCheckButton(fG1, "Logarithmic scale ON/OFF");
   logscale->Resize(50,22);
   logscale->SetState(kButtonUp);
   fG1->AddFrame(logscale, f0centerx);

   // Export the selected files
   fH1 = new TGHorizontalFrame(fG1, subgroup[0], 100);
   fH2 = new TGHorizontalFrame(fH1, subgroup[0], 100);
   lab = new TGLabel(fH2, "Export selected histograms:");
   fH2->AddFrame(lab, f0centery);

   exportHist = new TGTextButton(fH2, "Export");
   exportHist->SetTextJustify(36);
   exportHist->SetWrapLength(-1);
   exportHist->Resize(80,22);
   fH2->AddFrame(exportHist, f0centery);
   fH1->AddFrame(fH2, f0centerx);
   fG1->AddFrame(fH1, f2);
   mdiFrame->AddFrame(fG1, f2);

   // Fitting controls for ADC spectrum
   fG1 = new TGGroupFrame(mdiFrame, "Fit Settings");
   fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   fH2 = new TGHorizontalFrame(fH1, subgroup[0], 30);
   lab = new TGLabel(fH2, "Peak sigma:");
   fH2->AddFrame(lab, f0centery);
   fitSigma = new TGNumberEntry(fH2, 1.2, 3, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEANonNegative);
   fitSigma->Resize(60,22);
   fH2->AddFrame(fitSigma, f0centery);

   lab = new TGLabel(fH2, " Signal/Noise treshold:");
   fH2->AddFrame(lab, f0centery);
   fitTresh = new TGNumberEntry(fH2, 5.0E-3, 3, 999, TGNumberFormat::kNESReal, TGNumberFormat::kNEANonNegative);
   fitTresh->Resize(60,22);
   fH2->AddFrame(fitTresh, f0centery);
   fH1->AddFrame(fH2, f0centerx);
   fG1->AddFrame(fH1, f2);

   fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   fH2 = new TGHorizontalFrame(fH1, subgroup[0], 30);
   lab = new TGLabel(fH2, "Background interpolation:");
   fH2->AddFrame(lab, f0centery);
   fitInter = new TGNumberEntry(fH2, 7, 3, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative);
   fitInter->Resize(60,22);
   fH2->AddFrame(fitInter, f0centery);
   fH1->AddFrame(fH2, f0centerx);
   fG1->AddFrame(fH1, f2);

   fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   fH2 = new TGHorizontalFrame(fH1, subgroup[0], 30);
   lab = new TGLabel(fH2, "Peak fit max. acceptable error:");
   fH2->AddFrame(lab, f0centery);
   accError = new TGNumberEntry(fH2, 0.15, 3, 999, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEANonNegative);
   accError->Resize(60,22);
   fH2->AddFrame(accError, f0centery);
   fH1->AddFrame(fH2, f0centerx);
   fG1->AddFrame(fH1, f2);

   fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
   fH2 = new TGHorizontalFrame(fH1, subgroup[0], 30);
   lab = new TGLabel(fH2, "Peak min. limit:");
   fH2->AddFrame(lab, f0centery);
   minPeak = new TGNumberEntry(fH2, 4, 3, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 2, 20);
   minPeak->Resize(50,22);
   fH2->AddFrame(minPeak, f0centery);

   lab = new TGLabel(fH2, " Pedestal lower limit:");
   fH2->AddFrame(lab, f0centery);
   pedesLow = new TGNumberEntry(fH2, 0.00, 3, 999, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEANonNegative);
   pedesLow->Resize(60,22);
   fH2->AddFrame(pedesLow, f0centery);
   fH1->AddFrame(fH2, f0centerx);
   fG1->AddFrame(fH1, f2);

   exfitplots = new TGCheckButton(fG1, "Export fitting plots ON/OFF");
   exfitplots->Resize(50,22);
   exfitplots->SetState(kButtonUp);
   fG1->AddFrame(exfitplots, f0centerx);
   mdiFrame->AddFrame(fG1, f2);

   mdiFrame->SetMdiHints(kMdiMinimize);
   mdiFrame->SetWindowName("Histogram controls");
   mdiFrame->MapSubwindows();
   mdiFrame->Layout();
   mdiFrame->Move(4*((winWidth/6)-5)+10,(int)(2.5*((winHeight/5)-5)));
// Histogram controls pane -----------------------------------------------------------------

   // Action connections
   voltscanOn->Connect("Clicked()", "TGAppMainFrame", this, "EnableVoltScan()");
   surfscanOn->Connect("Clicked()", "TGAppMainFrame", this, "EnableSurfScan()");
   zscanOn->Connect("Clicked()", "TGAppMainFrame", this, "EnableZaxisScan()");
//   histogramOn->Connect("Clicked()", "TGAppMainFrame", this, "HistogramToggle()");
   vHardlimit->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "VoltageLimit()");
   (vHardlimit->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "VoltageLimit()");
   NCH->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "ChannelLimit()");
   (NCH->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "ChannelLimit()");
   cleanOn->Connect("Clicked()", "TGAppMainFrame", this, "CleanPlotToggle()");
   oscConnect->Connect("Clicked()", "TGAppMainFrame", this, "ConnectToScope()");
   vOutSet->Connect("Clicked()", "TGAppMainFrame", this, "SetVoltOut()");
   vOutGet->Connect("Clicked()", "TGAppMainFrame", this, "GetVoltOut()");
   vOutReset->Connect("Clicked()", "TGAppMainFrame", this, "ResetVoltOut()");
   positionSet->Connect("Clicked()", "TGAppMainFrame", this, "SetPosition()");
   positionGet->Connect("Clicked()", "TGAppMainFrame", this, "GetPosition()");
   positionHome->Connect("Clicked()", "TGAppMainFrame", this, "HomePosition()");
   saveFile->Connect("Clicked()", "TGAppMainFrame", this, "SaveFile()");
   measStart->Connect("Clicked()", "TGAppMainFrame", this, "StartAcq()");
   selectDir->Connect("Clicked()", "TGAppMainFrame", this, "SelectDirectory()");
   multiSelect->Connect("Clicked()", "TGAppMainFrame", this, "ListMultiSelect()");
   multiSelectAll->Connect("Clicked()", "TGAppMainFrame", this, "ListSelectAll()");
   editHeader->Connect("Clicked()", "TGAppMainFrame", this, "HeaderEdit()");
   prevFile->Connect("Clicked()", "TGAppMainFrame", this, "FileListNavigation(=-2)");
   nextFile->Connect("Clicked()", "TGAppMainFrame", this, "FileListNavigation(=-3)");
   fileList->Connect("DoubleClicked(Int_t)", "TGAppMainFrame", this, "FileListNavigation(Int_t)");
   clearList->Connect("Clicked()", "TGListBox", fileList, "RemoveAll()");

   adcMinRange->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "SetHistRange()");
   (adcMinRange->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "SetHistRange()");
   adcMaxRange->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "SetHistRange()");
   (adcMaxRange->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "SetHistRange()");
   yMinRange->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "SetHistRange()");
   (yMinRange->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "SetHistRange()");
   yMaxRange->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "SetHistRange()");
   (yMaxRange->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "SetHistRange()");
   tdcMinwindow->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "SetHistRange()");
   (tdcMinwindow->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "SetHistRange()");
   tdcMaxwindow->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "SetHistRange()");
   (tdcMaxwindow->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "SetHistRange()");
   changeADC->Connect("Clicked()", "TGAppMainFrame", this, "ChangeHisttype(=0)");
   changeTDC->Connect("Clicked()", "TGAppMainFrame", this, "ChangeHisttype(=1)");
   changeADCTDC->Connect("Clicked()", "TGAppMainFrame", this, "ChangeHisttype(=2)");
   change2Dsurf->Connect("Clicked()", "TGAppMainFrame", this, "ChangeHisttype(=3)");
   selectCh->Connect("ValueSet(Long_t)", "TGAppMainFrame", this, "ChangeChannel()");
   (selectCh->GetNumberEntry())->Connect("ReturnPressed()", "TGAppMainFrame", this, "ChangeChannel()");
   logscale->Connect("Clicked()", "TGAppMainFrame", this, "SetHistRange()");
   exportHist->Connect("Clicked()", "TGAppMainFrame", this, "HistogramExport()");

   scopeInit->Connect("Clicked()", "TGAppMainFrame", this, "InitializeScope()");
   sendScopeCustom->Connect("Clicked()", "TGAppMainFrame", this, "CustomScopeCommand()");
   sMeasType->Connect("Selected(Int_t)", "TGAppMainFrame", this, "SelectedMeasType(Int_t)");

   started = kFALSE;

   for(int i = 0; i < 8; i++) sCH[i]->SetEnabled(kFALSE);
   sMeasType->SetEnabled(kFALSE);
   sCamaclink->SetEnabled(kFALSE);
   scopeCommand->SetEnabled(kFALSE);
   sendScopeCustom->SetEnabled(kFALSE);
   sMeasgroup->SetEnabled(kFALSE);
   scopeInit->SetEnabled(kFALSE);

   EnableVoltScan();
   EnableSurfScan();
   EnableZaxisScan();

   // Testing canvas for scope waveforms
   wCanvas = new TCanvas("wCanvas", "Waveform canvas", 600, 300);
}

//---------------------------------------------------------------
// Opening a new subwindow 

void TGAppMainFrame::OpenWindow(int winid)
{
   /* WinID:
    * - 1 = fieldpoint temperature sensor
    * - 2 = file header editor
   */   

   TGMdiFrame *mdiFrame;

   // Generic horizontal and vertical frames
   TGHorizontalFrame *fH1, *fH2;
   TGGroupFrame *fG1;
   TGLabel *lab;

   int subwin[2];
   int subgroup[2];

   char ctemp[256];

// Fieldpoint pane -------------------------------------------------------------------------
   if(winid == 1)
   {
      time_t rtime;
      int yearrange[2];

      subwin[0] = 3*((winWidth/4)-5); subwin[1] = (int)(2*((winHeight/3)-5))+10;
      fieldpointPane = new TGMdiSubwindow(fMainFrame, subwin[0], subwin[1]);
      mdiFrame = fieldpointPane->GetMdiFrame();
    
      subgroup[0] = subwin[0]-10;
      subgroup[1] = 7*subwin[1]/12;

      // Display canvas for temperature sensor
      displayCanvas = new TRootEmbeddedCanvas("displayCanvas",mdiFrame,subgroup[0],subgroup[1]);
      mdiFrame->AddFrame(displayCanvas, f0centerx);
      TCanvas *gCanvas = displayCanvas->GetCanvas();
      gCanvas->SetGridx();
      gCanvas->SetGridy();

      fG1 = new TGGroupFrame(mdiFrame, "Temperature sensor settings");
      // Channel selector
      fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
      lab = new TGLabel(fH1, "Fieldpoint channel:");
      fH1->AddFrame(lab, f0centery);
      tempCh = new TGComboBox(fH1, 200);
      tempCh->AddEntry("0", 0);
      tempCh->AddEntry("1", 1);
      tempCh->AddEntry("2", 2);
      tempCh->AddEntry("3", 3);
      tempCh->AddEntry("4", 4);
      tempCh->AddEntry("5", 5);
      tempCh->AddEntry("6", 6);
      tempCh->AddEntry("7", 7);
      tempCh->Resize(50,22);
      tempCh->Select(1);
      fH1->AddFrame(tempCh, f0centery);
      fG1->AddFrame(fH1, f2);

      // Start and stop time ------------------------
      time(&rtime);

      lab = new TGLabel(fG1, "Start time:");
      fG1->AddFrame(lab, f0);
      fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
      // Start day
      lab = new TGLabel(fH1, "\tDay: ");
      fH1->AddFrame(lab, f0centery);
      tempDay[0] = new TGComboBox(fH1, 200);
      for(int i = 0; i < 31; i++)
      {
         sprintf(ctemp, "%d", i+1);
         tempDay[0]->AddEntry(ctemp, i);
      }
      tempDay[0]->Resize(50,22);
      tempDay[0]->Select((int)(localtime(&rtime))->tm_mday-1);
      fH1->AddFrame(tempDay[0], f0centery);

      // Start month
      lab = new TGLabel(fH1, " Month: ");
      fH1->AddFrame(lab, f0centery);
      tempMonth[0] = new TGComboBox(fH1, 200);
      tempMonth[0]->AddEntry("January", 0);
      tempMonth[0]->AddEntry("February", 1);
      tempMonth[0]->AddEntry("March", 2);
      tempMonth[0]->AddEntry("April", 3);
      tempMonth[0]->AddEntry("May", 4);
      tempMonth[0]->AddEntry("June", 5);
      tempMonth[0]->AddEntry("July", 6);
      tempMonth[0]->AddEntry("August", 7);
      tempMonth[0]->AddEntry("September", 8);
      tempMonth[0]->AddEntry("October", 9);
      tempMonth[0]->AddEntry("November", 10);
      tempMonth[0]->AddEntry("December", 11);
      tempMonth[0]->Resize(80,22);
      tempMonth[0]->Select((int)(localtime(&rtime))->tm_mon);
      fH1->AddFrame(tempMonth[0], f0centery);

      // Start year
      yearrange[0] = 2010;
      yearrange[1] = (int)(localtime(&rtime))->tm_year+1900;

      lab = new TGLabel(fH1, " Year: ");
      fH1->AddFrame(lab, f0centery);
      tempYear[0] = new TGComboBox(fH1, 200);
      for(int i = 0; i < (yearrange[1]-yearrange[0])+1; i++)
      {
         sprintf(ctemp, "%d", yearrange[1]-i);
         tempYear[0]->AddEntry(ctemp, i);
      }
      tempYear[0]->Resize(60,22);
      tempYear[0]->Select(0);
      fH1->AddFrame(tempYear[0], f0centery);

      // Start hour
      lab = new TGLabel(fH1, " Hour: ");
      fH1->AddFrame(lab, f0centery);
      tempHour[0] = new TGComboBox(fH1, 200);
      for(int i = 0; i < 24; i++)
      {
         if(i < 10)
            sprintf(ctemp, "0%d", i);
         else
            sprintf(ctemp, "%d", i);
         tempHour[0]->AddEntry(ctemp, i);
      }
      tempHour[0]->Resize(50,22);
      tempHour[0]->Select(7);
      fH1->AddFrame(tempHour[0], f0centery);

      // Start minute
      lab = new TGLabel(fH1, " Minute: ");
      fH1->AddFrame(lab, f0centery);
      tempMinute[0] = new TGComboBox(fH1, 200);
      for(int i = 0; i < 60; i++)
      {
         if(i < 10)
            sprintf(ctemp, "0%d", i);
         else
            sprintf(ctemp, "%d", i);
         tempMinute[0]->AddEntry(ctemp, i);
      }
      tempMinute[0]->Resize(50,22);
      tempMinute[0]->Select(0);
      fH1->AddFrame(tempMinute[0], f0centery);

      // Start second
      lab = new TGLabel(fH1, " Second: ");
      fH1->AddFrame(lab, f0centery);
      tempSecond[0] = new TGComboBox(fH1, 200);
      for(int i = 0; i < 60; i++)
      {
         if(i < 10)
            sprintf(ctemp, "0%d", i);
         else
            sprintf(ctemp, "%d", i);
         tempSecond[0]->AddEntry(ctemp, i);
      }
      tempSecond[0]->Resize(50,22);
      tempSecond[0]->Select(0);
      fH1->AddFrame(tempSecond[0], f0centery);

      // Get start time from file
      lab = new TGLabel(fH1, " ");
      fH1->AddFrame(lab, f0centery);
      tempFile[0] = new TGTextButton(fH1, "Get from file...");
      tempFile[0]->SetTextJustify(36);
      tempFile[0]->SetWrapLength(-1);
      tempFile[0]->Resize(100,22);
      fH1->AddFrame(tempFile[0], f0centery);

      fG1->AddFrame(fH1, f2);

      // Use the end time or not
      tempEndOn = new TGCheckButton(fG1, "Draw to last time point (ON/OFF)");
      tempEndOn->Resize(100,22);
      tempEndOn->SetState(kButtonUp);
      fG1->AddFrame(tempEndOn, f0);

      lab = new TGLabel(fG1, "End time:");
      fG1->AddFrame(lab, f0);
      fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
      // End day
      lab = new TGLabel(fH1, "\tDay: ");
      fH1->AddFrame(lab, f0centery);
      tempDay[1] = new TGComboBox(fH1, 200);
      for(int i = 0; i < 31; i++)
      {
         sprintf(ctemp, "%d", i+1);
         tempDay[1]->AddEntry(ctemp, i);
      }
      tempDay[1]->Resize(50,22);
      tempDay[1]->Select((int)(localtime(&rtime))->tm_mday-1);
      fH1->AddFrame(tempDay[1], f0centery);

      // End month
      lab = new TGLabel(fH1, " Month: ");
      fH1->AddFrame(lab, f0centery);
      tempMonth[1] = new TGComboBox(fH1, 200);
      tempMonth[1]->AddEntry("January", 0);
      tempMonth[1]->AddEntry("February", 1);
      tempMonth[1]->AddEntry("March", 2);
      tempMonth[1]->AddEntry("April", 3);
      tempMonth[1]->AddEntry("May", 4);
      tempMonth[1]->AddEntry("June", 5);
      tempMonth[1]->AddEntry("July", 6);
      tempMonth[1]->AddEntry("August", 7);
      tempMonth[1]->AddEntry("September", 8);
      tempMonth[1]->AddEntry("October", 9);
      tempMonth[1]->AddEntry("November", 10);
      tempMonth[1]->AddEntry("December", 11);
      tempMonth[1]->Resize(80,22);
      tempMonth[1]->Select((int)(localtime(&rtime))->tm_mon);
      fH1->AddFrame(tempMonth[1], f0centery);

      // End year
      time(&rtime);
      yearrange[0] = 2010;
      yearrange[1] = (int)(localtime(&rtime))->tm_year+1900;

      lab = new TGLabel(fH1, " Year: ");
      fH1->AddFrame(lab, f0centery);
      tempYear[1] = new TGComboBox(fH1, 200);
      for(int i = 0; i < (yearrange[1]-yearrange[0])+1; i++)
      {
         sprintf(ctemp, "%d", yearrange[1]-i);
         tempYear[1]->AddEntry(ctemp, i);
      }
      tempYear[1]->Resize(60,22);
      tempYear[1]->Select(0);
      fH1->AddFrame(tempYear[1], f0centery);

      // End hour
      lab = new TGLabel(fH1, " Hour: ");
      fH1->AddFrame(lab, f0centery);
      tempHour[1] = new TGComboBox(fH1, 200);
      for(int i = 0; i < 24; i++)
      {
         if(i < 10)
            sprintf(ctemp, "0%d", i);
         else
            sprintf(ctemp, "%d", i);
         tempHour[1]->AddEntry(ctemp, i);
      }
      tempHour[1]->Resize(50,22);
      tempHour[1]->Select(18);
      fH1->AddFrame(tempHour[1], f0centery);

      // End minute
      lab = new TGLabel(fH1, " Minute: ");
      fH1->AddFrame(lab, f0centery);
      tempMinute[1] = new TGComboBox(fH1, 200);
      for(int i = 0; i < 60; i++)
      {
         if(i < 10)
            sprintf(ctemp, "0%d", i);
         else
            sprintf(ctemp, "%d", i);
         tempMinute[1]->AddEntry(ctemp, i);
      }
      tempMinute[1]->Resize(50,22);
      tempMinute[1]->Select(0);
      fH1->AddFrame(tempMinute[1], f0centery);

      // End second
      lab = new TGLabel(fH1, " Second: ");
      fH1->AddFrame(lab, f0centery);
      tempSecond[1] = new TGComboBox(fH1, 200);
      for(int i = 0; i < 60; i++)
      {
         if(i < 10)
            sprintf(ctemp, "0%d", i);
         else
            sprintf(ctemp, "%d", i);
         tempSecond[1]->AddEntry(ctemp, i);
      }
      tempSecond[1]->Resize(50,22);
      tempSecond[1]->Select(0);
      fH1->AddFrame(tempSecond[1], f0centery);

      // Get start time from file
      lab = new TGLabel(fH1, " ");
      fH1->AddFrame(lab, f0centery);
      tempFile[1] = new TGTextButton(fH1, "Get from file...");
      tempFile[1]->SetTextJustify(36);
      tempFile[1]->SetWrapLength(-1);
      tempFile[1]->Resize(100,22);
      fH1->AddFrame(tempFile[1], f0centery);

      fG1->AddFrame(fH1, f2);
      // Start and stop time ------------------------
      
      // Control buttons
      fH2 = new TGHorizontalFrame(fG1, subgroup[0], 30);
      fH1 = new TGHorizontalFrame(fH2, subgroup[0], 30);
      updateTemp = new TGTextButton(fH1, "Update");
      updateTemp->SetTextJustify(36);
      updateTemp->SetWrapLength(-1);
      updateTemp->Resize(80,22);
      fH1->AddFrame(updateTemp, f0);

      exportTemp = new TGTextButton(fH1, "Export");
      exportTemp->SetTextJustify(36);
      exportTemp->SetWrapLength(-1);
      exportTemp->Resize(80,22);
      fH1->AddFrame(exportTemp, f0);

/*      closeTemp = new TGTextButton(fH1, "Close");
      closeTemp->SetTextJustify(36);
      closeTemp->SetWrapLength(-1);
      closeTemp->Resize(80,22);
      fH1->AddFrame(closeTemp, f0);*/
      fH2->AddFrame(fH1, f0centerx);

      fG1->AddFrame(fH2, f2);
      
      mdiFrame->AddFrame(fG1, f1);
    
      mdiFrame->SetMdiHints(kMdiMinimize | kMdiMaximize | kMdiClose);
      mdiFrame->SetWindowName("Fieldpoint FP RTD 122 temperature sensor");
      mdiFrame->MapSubwindows();
      mdiFrame->Layout();
      mdiFrame->Move(1*((winWidth/12)-5)+10,(int)(1*((winHeight/12)-5)));

      // Action connections
      updateTemp->Connect("Clicked()", "TGAppMainFrame", this, "UpdateTempPlot()");
      tempEndOn->Connect("Clicked()", "TGAppMainFrame", this, "TempEndToggle()");
      exportTemp->Connect("Clicked()", "TGAppMainFrame", this, "ExportTempPlot()");
      tempFile[0]->Connect("Clicked()", "TGAppMainFrame", this, "GetTempFile(=0)");
      tempFile[1]->Connect("Clicked()", "TGAppMainFrame", this, "GetTempFile(=1)");
//      closeTemp->Connect("Clicked()", "TGAppMainFrame", this, "UpdateTempPlot()");
   }
// Fieldpoint pane -------------------------------------------------------------------------
//
// Header editor pane ----------------------------------------------------------------------
   else if(winid == 2)
   {
      subwin[0] = 12*((winWidth/16)-5); subwin[1] = (int)(1*((winHeight/3)-10));
      headerPane = new TGMdiSubwindow(fMainFrame, subwin[0], subwin[1]);
      mdiFrame = headerPane->GetMdiFrame();
    
      subgroup[0] = subwin[0]-10;
      subgroup[1] = 7*subwin[1]/12;

      // Changing header info (no timestamp change possible)
      fG1 = new TGGroupFrame(mdiFrame, "Header edit information");
      fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
      biasedittick = new TGCheckButton(fH1, "Bias voltage edit: ");
      biasedittick->Resize(80,22);
      biasedittick->SetState(kButtonUp);
      fH1->AddFrame(biasedittick, f0centerx);
      biasedit = new TGNumberEntry(fH1, 0.00, 4, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEANonNegative);
      biasedit->Resize(80,22);
      biasedit->SetState(kFALSE);
      fH1->AddFrame(biasedit, f0centery);
      fG1->AddFrame(fH1, f0);

      fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
      posedittick = new TGCheckButton(fH1, "Table position edit (X, Y, Z): ");
      posedittick->Resize(80,22);
      posedittick->SetState(kButtonUp);
      fH1->AddFrame(posedittick, f0centerx);
      for(int i = 0; i < 3; i++)
      {
         posedit[i] = new TGNumberEntry(fH1, 0, 6, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber);
         posedit[i]->Resize(80,22);
         posedit[i]->SetState(kFALSE);
         fH1->AddFrame(posedit[i], f0centery);
      }
      fG1->AddFrame(fH1, f0);

      fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
      tempedittick = new TGCheckButton(fH1, "Chamber temperature edit: ");
      tempedittick->Resize(80,22);
      tempedittick->SetState(kButtonUp);
      fH1->AddFrame(tempedittick, f0centerx);
      tempedit = new TGNumberEntry(fH1, 0.00, 6, 999, TGNumberFormat::kNESRealOne, TGNumberFormat::kNEAAnyNumber);
      tempedit->Resize(80,22);
      tempedit->SetState(kFALSE);
      fH1->AddFrame(tempedit, f0centery);
      fG1->AddFrame(fH1, f0);

      fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
      angleedittick = new TGCheckButton(fH1, "Incidence angle edit: ");
      angleedittick->Resize(80,22);
      angleedittick->SetState(kButtonUp);
      fH1->AddFrame(angleedittick, f0centerx);
      angleedit = new TGNumberEntry(fH1, 0.00, 6, 999, TGNumberFormat::kNESRealOne, TGNumberFormat::kNEAAnyNumber);
      angleedit->Resize(80,22);
      angleedit->SetState(kFALSE);
      fH1->AddFrame(angleedit, f0centery);
      fG1->AddFrame(fH1, f0);

      fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
      laseredittick = new TGCheckButton(fH1, "Laser settings edit: ");
      laseredittick->Resize(80,22);
      laseredittick->SetState(kButtonUp);
      fH1->AddFrame(laseredittick, f0centerx);
      laseredit = new TGTextEntry(fH1, "");
      laseredit->Resize(440,22);
      laseredit->SetState(kFALSE);
      fH1->AddFrame(laseredit, f0centery);
      fG1->AddFrame(fH1, f0);

      ULong_t fcolor;
      gClient->GetColorByName("red", fcolor);

      lab = new TGLabel(fG1, "Note: Tick checkbox in front of each header information you wish to change (for security, they are unticked by default).");
      fG1->AddFrame(lab, f0centerx);
      lab = new TGLabel(fG1, "Warning: Using button \"Edit header\" will edit headers in all files currently selected in the Histogram file selection window.");
      lab->SetTextColor(fcolor);
      fG1->AddFrame(lab, f0centerx);

      mdiFrame->AddFrame(fG1, f2);

      editHead = new TGTextButton(mdiFrame, "Edit header");
      editHead->SetTextJustify(36);
      editHead->SetWrapLength(-1);
      editHead->Resize(80,22);
      mdiFrame->AddFrame(editHead, f0centerx);
    
      mdiFrame->SetMdiHints(kMdiMinimize | kMdiMaximize | kMdiClose);
      mdiFrame->SetWindowName("Edit datafile header");
      mdiFrame->MapSubwindows();
      mdiFrame->Layout();
      mdiFrame->Move(1*((winWidth/12)-5)-30,(int)(1*((winHeight/12)-5)));

      // Action connections
      biasedittick->Connect("Clicked()", "TGAppMainFrame", this, "EditTickToggle(=1)");
      posedittick->Connect("Clicked()", "TGAppMainFrame", this, "EditTickToggle(=2)");
      tempedittick->Connect("Clicked()", "TGAppMainFrame", this, "EditTickToggle(=3)");
      angleedittick->Connect("Clicked()", "TGAppMainFrame", this, "EditTickToggle(=4)");
      laseredittick->Connect("Clicked()", "TGAppMainFrame", this, "EditTickToggle(=5)");
      editHead->Connect("Clicked()", "TGAppMainFrame", this, "headeredit()");
/*      updateTemp->Connect("Clicked()", "TGAppMainFrame", this, "UpdateTempPlot()");
      tempEndOn->Connect("Clicked()", "TGAppMainFrame", this, "TempEndToggle()");
      exportTemp->Connect("Clicked()", "TGAppMainFrame", this, "ExportTempPlot()");
      tempFile[0]->Connect("Clicked()", "TGAppMainFrame", this, "GetTempFile(=0)");
      tempFile[1]->Connect("Clicked()", "TGAppMainFrame", this, "GetTempFile(=1)");
*/   }
// Header editor pane ----------------------------------------------------------------------
//
   else
      printf("Window not implemented yet.\n");
}

//---------------------------------------------------------------
// Closing the main application window and checking the about information

void TGAppMainFrame::CloseWindow()
{
   gApplication->Terminate(0);
}

Bool_t TGAppMainFrame::About()
{
   int ret = 0;

   new TGMsgBox(gClient->GetRoot(), fMain,
                fMain->GetWindowName(), "This is an application.",
                kMBIconQuestion, kMBClose, &ret);

   if(debug == 1)
      if(ret == kMBClose)
         printf("Closing the About window (%d).\n", ret);

   return kFALSE;
}

//---------------------------------------------------------------
// Subwindow constructor definition (& layout) and close subwindow action

TGMdiSubwindow::TGMdiSubwindow(TGMdiMainFrame *main, int w, int h)
{
   // Create a new subwindow
   fMdiFrame = new TGMdiFrame(main, w, h);
   fMdiFrame->Connect("CloseWindow()", "TGMdiSubwindow", this, "CloseWindow()");  // setting here to =0 -> will always ask before closing window
   fMdiFrame->DontCallClose();          // only let this window close if Yes is pressed when closing window

}

Bool_t TGMdiSubwindow::CloseWindow()
{
/*   int ret = 0;

   new TGMsgBox(gClient->GetRoot(), fMdiFrame,
             fMdiFrame->GetWindowName(), "Really want to close the window?",
             kMBIconExclamation, kMBYes | kMBNo, &ret);
   if (ret == kMBYes) return fMdiFrame->CloseWindow();

   return kFALSE;*/
   return fMdiFrame->CloseWindow();
}

//---------------------------------------------------------------
// Main function

void windowed_test()
{
   new TGAppMainFrame(gClient->GetRoot(), winWidth, winHeight);
}

//#ifdef STANDALONE
int main(int argc, char **argv)
{
   TApplication theApp("MdiTest", &argc, argv);

   windowed_test();

   theApp.Run();

   return 0;
}
//#endif