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 <time.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, *fMenuWindow, *fMenuHelp;
TGPopupMenu *fMenuHisttype;
TGMdiSubwindow *settingsPane, *mainSubwindow, *histogramPane, *histogramPaneFile, *histogramPaneCtr;
void InitMenu();
void MeasurementLayout();
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 SaveFile();
void StartAcq();
void SelectDirectory();
void ListMultiSelect();
void ListSelectAll();
void FileListNavigation(int pn);
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);
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 RunMeas(void *ptr, int runCase, int zaxisscan);
};
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;
// ROOT file variable structure -----------
struct EventHeader {
int nrch;
int timestamp;
double biasvolt;
int xpos;
int ypos;
int zpos;
double temperature;
char laserinfo[256];
} evtheader;
struct EventData {
int adcdata[8];
int tdcdata[8];
} evtdata;
TFile *inroot;
TFile *outroot;
//---------------------------------------------------------------
// Global variables
TGCheckButton *voltscanOn;
TGCheckButton *surfscanOn;
TGCheckButton *zscanOn;
TGTextEntry *oscIP;
TGTextButton *oscConnect;
TGCheckButton *histogramOn;
TGNumberEntry *vHardlimit;
TGNumberEntry *NCH;
TGTextEntry *laserInfo;
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;
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;
TGCheckButton *exfitplots;
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(debugSig)
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(debugSig)
printf("Outfile (remove_from_last): %s\n", outname);
}
// 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;
}
// 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;
char buf[BSIZE];
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'
printf("Connecting to oscilloscope.\n");
retTemp = gScopeDaq->connect(IPaddr);
scopeState = 1; // For testing instead of making a real connection
#else
scopeState = 1;
#endif
}
else
{
scopeState = -1;
printf("Please enter a valid scope IP address.\n");
}
}
else if(oscOn == 1)
{
#if WORKSTAT == 'I'
printf("Disconnecting from oscilloscope.\n");
retTemp = gScopeDaq->disconnect(IPaddr);
scopeState = -1; // For testing instead of making a real disconnection
#else
scopeState = -1;
#endif
}
if(scopeState >= 0)
{
setTab->SetEnabled(1, kTRUE);
setTab->SetEnabled(2, kTRUE);
oscIP->SetEnabled(kFALSE);
oscConnect->SetText("Disconnect");
oscConnect->SetTextJustify(36);
oscConnect->SetWrapLength(-1);
oscConnect->Resize(60,22);
oscOn = 1;
}
else
{
setTab->SetEnabled(1, kFALSE);
setTab->SetEnabled(2, kFALSE);
oscIP->SetEnabled(kTRUE);
oscConnect->SetText("Connect");
oscConnect->SetTextJustify(36);
oscConnect->SetWrapLength(-1);
oscConnect->Resize(60,22);
oscOn = 0;
}
}
// 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
}
// 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)
{
double fparam[2], fparamerr[2], meanval;
TLatex *latex;
char ctemp[256];
int sortindex[nrp];
TCanvas *canvas = new TCanvas("canv","canv",900,1200);
canvas->Divide(1,3);
TGraphErrors *gr1 = new TGraphErrors(nrp, volt, psep1, volterr, pseperr1);
TGraphErrors *gr2 = new TGraphErrors(nrp, volt, psep2, volterr, pseperr2);
TGraphErrors *gr3 = new TGraphErrors(nrp, volt, psep3, volterr, pseperr3);
if(!cleanPlots)
gr1->SetTitle("1st - 2nd peak separation");
else
gr1->SetTitle();
gr1->SetLineColor(kBlue);
gr1->SetMarkerColor(kBlue);
gr1->SetMarkerStyle(20);
gr1->SetMarkerSize(0.6);
if(!cleanPlots)
gr2->SetTitle("2nd - 3rd peak separation");
else
gr2->SetTitle();
gr2->SetLineColor(kMagenta);
gr2->SetMarkerColor(kMagenta);
gr2->SetMarkerStyle(21);
gr2->SetMarkerSize(0.4);
if(!cleanPlots)
gr3->SetTitle("3rd - 4th peak separation");
else
gr3->SetTitle();
gr3->SetLineColor(kGreen);
gr3->SetMarkerColor(kGreen);
gr3->SetMarkerStyle(22);
gr3->SetMarkerSize(0.6);
// 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]-(volt[1]-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])) );
// 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]-(volt[1]-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])) );
// 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]-(volt[1]-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])) );
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 = 5;
int p = 0;
double dtemp;
double volt[files->GetSize()], volterr[files->GetSize()], sep[3][files->GetSize()], seperr[3][files->GetSize()];
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; }
}
for(int m = 0; m < files->GetSize(); m++)
{
for(int i = 0; i < 20; i++) { meanparam[20] = 0; meanparamerr[20] = 0; }
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] = 3;
par[3*i+2] = (double)fitSigma->GetNumber();
// printf("Peak %d: %f\n", i+1, xp);
}
// 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;
while(1)
{
if( (fparam[j] < 1.E-30) || (fparamerr[j] < 1.E-10) )
break;
else
{
if(fparam[j] > 0)
{
meanparam[nrfit] = fparam[j];
meanparamerr[nrfit] = fparamerr[j];
nrfit++;
}
}
j+=3;
}
// Write out parameters to a file
fp = fopen(paramname, "a");
fprintf(fp, "%d\t", nrfit);
TMath::Sort(nrfit, meanparam, sortindex, kFALSE);
for(int i = 0; i < nrfit; i++)
{
if(debugSig)
printf("Peak %d: %lf\t%lf\n", i+1, 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);
}
// Get points for mean peak values and create a breakdown voltage plot
if(nrfit >= peaklimit)
{
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]]);
volt[p] = dtemp;
volterr[p] = 1.e-4;
if(debugSig)
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]);
// Accept only the points with a small enough error
if( (seperr[0][p]/sep[0][p] < accError->GetNumber()) && (seperr[1][p]/sep[1][p] < accError->GetNumber()) && (seperr[2][p]/sep[2][p] < accError->GetNumber()) )
p++;
else
printf("Point (at %.2lfV) rejected due to 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]);
}
if(q == 1) break;
}
// 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);
}
}
// 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);
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(debugSig)
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(debugSig)
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(debugSig)
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(debugSig)
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(debugSig)
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);
}
}
void TGAppMainFrame::RunMeas(void *ptr, int runCase, int zaxisscan)
{
printf("Start of Run, run case %d\n", runCase);
float progVal;
char ctemp[256];
char fname[256];
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(runCase < 10)
sprintf(fname, "%s_0000%d%s", ctemp, runCase, histExt);
else if( (runCase >= 10) && (runCase < 100) )
sprintf(fname, "%s_000%d%s", ctemp, runCase, histExt);
else if( (runCase >= 100) && (runCase < 1000) )
sprintf(fname, "%s_00%d%s", ctemp, runCase, histExt);
else if( (runCase >= 1000) && (runCase < 10000) )
sprintf(fname, "%s_0%d%s", ctemp, runCase, histExt);
else if( (runCase >= 10000) && (runCase < 100000) )
sprintf(fname, "%s_%d%s", ctemp, runCase, histExt);
}
else if(zaxisscan == 1)
{
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 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 = 25.0; // Still to do!!!
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);
}
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)
{
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;
}
meas_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();
delete header_data;
delete meas_data;
outroot->Close();
}
// Start the acquisition
void TGAppMainFrame::StartAcq()
{
// 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(5);
vOut->SetNumber(currentVoltage);
printf("Continuing...\n");
// Here comes function to start histogramming <<<<<<<<<<<<<<<<<<<<<<<<
RunMeas((void*)0, i, 0);
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);
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);
sleep(4);
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);
// 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);
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 );
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);
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(debugSig)
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!!!
}
}
// Display the currently selected histogram in file list
void TGAppMainFrame::DisplayHistogram(char* histfile, int histtype)
{
if(debugSig)
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);
header_data->SetBranchAddress("laserinfo", &evtheader.laserinfo);
header_data->GetEntry(0);
char histtime[256];
GetTime(evtheader.timestamp, histtime);
if(debugSig)
{
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);
printf("- Temperature: %lf\n", evtheader.temperature);
printf("- Laser and filter settings: %s\n", 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);
}*/
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(debugSig)
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(debugSig)
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(debugSig)
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_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);
// 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)");
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("&Windows"),fMenuWindow,fMenuBarItemLayout);
fMenuBar->AddPopup(new TGHotString("&Help"), fMenuHelp, fMenuBarItemLayout);
}
//---------------------------------------------------------------
// 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);
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");
fH1 = new TGHorizontalFrame(fT1, subwin[0], subgroup[1], kFixedHeight);
lab = new TGLabel(fH1, "Waveform controls");
fH1->AddFrame(lab, f0center2d);
fT1->AddFrame(fH1, f0);
// Wave measurements tab
fT1 = setTab->AddTab("Measurement");
fH1 = new TGHorizontalFrame(fT1, subwin[0], subgroup[1], kFixedHeight);
lab = new TGLabel(fH1, "Waveform measurement controls");
fH1->AddFrame(lab, f0center2d);
fT1->AddFrame(fH1, f0);
mdiFrame->AddFrame(setTab, f0);
// Disable the two tabs regarding the Scope if not connected to one
setTab->SetEnabled(1,kFALSE);
setTab->SetEnabled(2,kFALSE);
// 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, (subwin[1]/2)-10 );
mdiFrame->AddFrame(fileList, f2);
// Multiple file selection toggle, previous/next controls and clear list
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);
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);
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]-10;
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);
lab = new TGLabel(fH1, "Peak sigma:");
fH1->AddFrame(lab, f0centery);
fitSigma = new TGNumberEntry(fH1, 1.5, 3, 999, TGNumberFormat::kNESRealThree, TGNumberFormat::kNEANonNegative);
fitSigma->Resize(60,22);
fH1->AddFrame(fitSigma, f0centery);
fG1->AddFrame(fH1, f2);
fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
lab = new TGLabel(fH1, "Signal/Noise treshold:");
fH1->AddFrame(lab, f0centery);
fitTresh = new TGNumberEntry(fH1, 5.0E-3, 3, 999, TGNumberFormat::kNESReal, TGNumberFormat::kNEANonNegative);
fitTresh->Resize(60,22);
fH1->AddFrame(fitTresh, f0centery);
fG1->AddFrame(fH1, f2);
fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
lab = new TGLabel(fH1, "Background interpolation:");
fH1->AddFrame(lab, f0centery);
fitInter = new TGNumberEntry(fH1, 8, 3, 999, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative);
fitInter->Resize(60,22);
fH1->AddFrame(fitInter, f0centery);
fG1->AddFrame(fH1, f2);
fH1 = new TGHorizontalFrame(fG1, subgroup[0], 30);
lab = new TGLabel(fH1, "Peak fit max. acceptable error:");
fH1->AddFrame(lab, f0centery);
accError = new TGNumberEntry(fH1, 0.15, 3, 999, TGNumberFormat::kNESRealTwo, TGNumberFormat::kNEANonNegative);
accError->Resize(60,22);
fH1->AddFrame(accError, f0centery);
fG1->AddFrame(fH1, f2);
exfitplots = new TGCheckButton(fG1, "Export fitting plots ON/OFF");
exfitplots->Resize(50,22);
exfitplots->SetState(kButtonDown);
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()");
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()");
started = kFALSE;
EnableVoltScan();
EnableSurfScan();
EnableZaxisScan();
}
//---------------------------------------------------------------
// 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;
// if(noq == 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;
// }
// else
// 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