// Author: Andrej Filipcic <http://merlot.ijs.si/~andrej/>,Egon Pavlica (documentation) <http://www.ses-ng.si/~pavlica/>
#include "LScope.h"
//#include "LRunState.h"
//extern LRunState* gRunState;
//____________________________________________________________________________
// The LScope Class
// ===================
// This class was created to be used with the oscilloscope LeCroy LT-344
// but with minimal changes of commands, it could be used to any gpib
// device.
//
// Basic procedure to use this class is:
// 1. create class and initialize device with LScope::Init
// 2. download the state of the device with LScope::DownloadState
// 3. set numper of aquisition points with LScope::SetNP
// 4. set device to meassure with LScope::Arm
// 5. take trace to computer with LScope::TakeTrace
// 6. get trace with LScope::GetTrace
//
//
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
#define DEBUG kTRUE
//#define DEBUG kFALSE
////////////////////////////////
// Bla desc
///////////////////
ClassImp(LScope)
//_____________________________________________________________________________
LScope::LScope(const int bufsize) {
// -*-*-*-*-*-*-*-*-*LScope default constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*
// ============================
fStrLen=bufsize;
fStrOut=new char[bufsize];
fWF=0;
//fHWF=0;
fTrace=0;
fScopeState=new LScopeState();
}
//_____________________________________________________________________________
LScope::~LScope() {
// -*-*-*-*-*-*-*-*-*LScope default destructor*-*-*-*-*-*-*-*-*-*-*-*-*-*
// ============================
delete [] fStrOut;
fStrOut=0;
delete [] fWF;
fWF=0;
delete fScopeState;
fScopeState=0;
EnableLocal(0,fInst);
}
//_____________________________________________________________________________
void LScope::ChanOn(const char* channel, Bool_t on) {
// -*-*-*-*-*-*-*-*-*Set Channel on/off*-*-*-*-*-*-*-*-*-*-*-*-*-*
// ============================
// possible values for channel are C1,C2,C3,C4 and TA,TB,TC,TD
if(on)
Sendf("%s:TRA ON",kFALSE,channel);
else
Sendf("%s:TRA OFF",kFALSE,channel);
}
//_____________________________________________________________________________
void LScope::CheckError(const char* message) {
// -*-*-*-*-*-*-*-*-*Internally used check for errors*-*-*-*-*-*-*-*-*
// ============================
if (ibsta & ERR ) {
printf("Gpib Error: %s, IBSTA %dnERC:",message,ibsta);
const int ncodes=16;
char *erc[]={"DCAS","DTAS","LACS","TACS","ATN","CIC","REM","LOK","CMPL",
"EVENT","SPOLL","RQS","SRQI","END","TIMO","ERR"};
for(int i=ncodes-1;i;i--)
if(ibsta & 1<<i) cout<<" "<<erc[i];
cout<<endl;
exit(1);
}
}
//_____________________________________________________________________________
Bool_t LScope::Init(const int address,const char* conffile) {
// -*-*-*-*-*-*-*-*-*Init gpib device*-*-*-*-*-*-*-*-*-*-*-*-*-*
// ============================
// address of device must be set!
// configuration file conffile is optional
SendIFC(0);
CheckError("SendIFC");
fInst[0]=address;
fInst[1]=NOADDR;
FindLstn(0,fInst,fRes,2);
CheckError("FindLstn");
DevClear(0,fInst[0]);
CheckError("DevClear");
EnableRemote(0,fInst);
CheckError("EnableRemote");
Send("SEQ OFF");
//Send("TDIV 20000NS;MSIZ 250K;CAL_OUTPUT CALSQ,0.5V,10kHz");
//Send("CFMT DEF9,BYTE,BIN");
SetNP(500); // default
for(int i=0;i<fNChan;i++)
fScopeState->fChanOn[i]=kFALSE;
if(strcmp(conffile,""))
Configure(conffile);
return kTRUE;
}
// Bool_t LScope::Prepare() {
// for(map<const char*,int>::iterator mi=fScopeState->fChanId.begin();mi!=fScopeState->fChanId.end();mi++) {
// Sendf("%s:TRA?",kTRUE,mi->first);
// char stmp[256];
// sscanf(fStrOut,"%*s %s",stmp);
// if(!strcmp(stmp,"ON"))
// fScopeState->fChanOn[mi->second]=kTRUE;
// //Set fVDIV and fOffset
// if(fScopeState->fChanOn[mi->second]) {
// if(fScopeState->fChanId[mi->first]<4) {
// Sendf("%s:VDIV?",kTRUE,mi->first);
// cout<<fStrOut<<endl;
// sscanf(fStrOut,"%*s %f %*s",&(fScopeState->fVDIV[mi->second]));
// Sendf("%s:OFFSET?",kTRUE,mi->first);
// sscanf(fStrOut,"%*s %f %*s",&(fScopeState->fOffset[mi->second]));
// cout<<fStrOut<<endl;
// }
// } else {
// //Sendf("%s:TRA OFF",kFALSE,mi->first);
// ;
// }
// }
// return kTRUE;
// }
//_____________________________________________________________________________
Bool_t LScope::Configure(const char* conffile) {
// -*-*-*-*-*-*-*-*Internally used for Init from file*--*-*-*-*-*-*-*
// ============================
FILE* fp=fopen(conffile,"r");
if(!fp) {
cout<<"File "<<conffile<<" does not exists!"<<endl;
return kFALSE;
}
char str[256];
while(fgets(str,256,fp)) {
cout<<"LScope::Configure: "<<str<<endl;
if(strncmp(str,"//",2) && strncmp(str,"#",1))
Send(str);
}
fclose(fp);
return kTRUE;
};
//_____________________________________________________________________________
LScope* LScope::Send(const char* str, Bool_t out) {
// -*-*-*-*-*-*-*-*-*Internally used for sending to device*-*-*-*-*-*-*-*-*
// ============================
::Send(0,fRes[0],const_cast<char*>(str),(long)strlen(str),NLend);
CheckError(str);
if(DEBUG) {
cout<<"Send:"<<str<<" "<<" ,out="<<int(out)<<endl;
}
if(out) {
//delete [] fStrOut;
//fStrOut=new char[fStrLen];
::Receive(0,fRes[0],fStrOut,fStrLen,STOPend);
// Terminate on n
char *c=index(fStrOut,'n');
c[0]='0';
if(DEBUG){
cout<<" String: "<<fStrOut<<endl;
}
}
return this;
}
//_____________________________________________________________________________
LScope* LScope::Sendf(const char *fmt, const Bool_t out, ...) {
// -*-*-*-*-*-*Internally used for sending to device like printf**-*-*-*-*-*
// ============================
va_list ap;
va_start(ap,out);
char stmp[256];
//cout<<"Ap0: "<<fmt<<endl;
//char* s=va_arg(ap,char*);
//int s=va_arg(ap,int);
//cout<<"AP "<<s<<endl;
vsprintf(stmp,fmt,ap);
va_end(ap);
Send(stmp,out);
return this;
}
//_____________________________________________________________________________
Bool_t LScope::Receive(void* output, const int length) {
// -*-*-*-*-*-*-*-*-*Internally used for receiving from device*-*-*-*-*-*-*-*-*
// ============================
::Receive(0,fRes[0],output,length,STOPend);
return kTRUE;
}
//_____________________________________________________________________________
const char* LScope::GetStrOut() const {
return fStrOut;
}
//_____________________________________________________________________________
void LScope::SetNP(const int np) {
// -*-*-*-*-*-*-*-*-*Set Number of aqusition points*-*-*-*-*-*-*-*-*
// ============================
// If this number differs from total points set with MSIZ,
// only part of the whole signal from the scope will by transfered to
// computer.
fNP=np;
delete [] fWF;
fWF=0;
delete fTrace;
fTrace=0;
Sendf("WAVEFORM_SETUP NP,%d",kFALSE,fNP);
//SetTDIV(fNP*0.2); // Set to 500MS/s
}
//_____________________________________________________________________________
void LScope::SetTDIV(const int nusec) {
// -*-*-*-*-*-*-*-*-*Set Time division *-*-*-*-*-*-*-*-*
// ============================
fScopeState->fTDIV=nusec;
Sendf("TDIV %d NS",kFALSE,nusec);
}
//_____________________________________________________________________________
void LScope::Arm() {
// -*-*-*-*-*-*-*-*-*Set device to capture*-*-*-*-*-*-*-*-*
// ============================
Send("*TRG;WAIT");
}
//_____________________________________________________________________________
float* LScope::GetWF(const char* channel, const int length, const char* source) {
// -*-*-*-*-*-*-*-*-*return array of aqusited data*-*-*-*-*-*-*-*-*
// ============================
// This function is for getting raw data. We recommend to use
// TakeTrace and GetTrace (but not both!!)
Sendf("%s:WAVEFORM? %s",kFALSE,channel,source);
char head[80];
Receive(head,13+9); //!!!!!!! correct
//cout<<"head "<<head<<endl;
int nbytes;
sscanf(&head[13],"%d",&nbytes);
//cout<<"nbytes "<<nbytes<<endl;
Receive(fStrOut,nbytes);
short int *chan;
delete [] fWF;
fWF=new float[fNP];
for(int i=0; i<(nbytes<fNP?nbytes:fNP); i+=1) {
chan=(short int*)&fStrOut[i];
fWF[i]=(*chan)/32768.*4.*GetVDIV(channel);
}
return fWF;
}
//_____________________________________________________________________________
LTrace* LScope::TakeTrace(const char* channel, const int length,
const char* source) {
// -*-*-*-*-*-*-*-*-*transfer aqusited data*-*-*-*-*-*-*-*-*
// ============================
// This is the main function to transfer data from device
// source is mostly "DAT"
strcpy(fLastChan,channel);
Sendf("%s:WAVEFORM? %s",kFALSE,channel,source);
char head[80];
Receive(head,13+9); //!!!!!!! correct
//cout<<"head "<<head<<endl;
int nbytes;
sscanf(&head[13],"%d",&nbytes);
//cout<<"nbytes "<<nbytes<<endl;
Receive(fStrOut,nbytes);
short int *chan;
delete [] fWF;
delete [] fSWF;
fWF=new float[fNP];
fSWF=new short[fNP];
for(int i=0; i<(nbytes<fNP?nbytes:fNP); i+=1) {
chan=(short int*)&fStrOut[i];
fSWF[i]=*chan;
fWF[i]=(*chan)/32768.*4.*GetVDIV(channel);
}
if(fTrace) {
fTrace->Dump();
cout<<"FTRACE: "<<fTrace->GetNP()<<endl;
}
delete fTrace;
fTrace=new LTrace(fNP);
fTrace->SetSTrace(fSWF);
fTrace->SetVMaxMin(
fScopeState->fVDIV[fScopeState->GetChanId(channel)]*4-fScopeState->fOffset[fScopeState->GetChanId(channel)],
-fScopeState->fVDIV[fScopeState->GetChanId(channel)]*4-fScopeState->fOffset[fScopeState->GetChanId(channel)]);
#warning correct
fTrace->SetTriggerDelay(fScopeState->fTriggerDelay);
fTrace->SetTimeSep(fScopeState->fTDIV*10/250000.);
//printf("MAXMIN %s %dn",channel,fScopeState->GetChanId("C2"));
//fScopeState->PrintIt();
//Set Mirror, Laser Positions;
// cout<<"AAAAA "<<runstate->fMirror.fTheta<<" "<<runstate->fMirror.fPhi<<endl;
//fTrace->GetMirror().SetXYZThPhi(runstate->fMirror);
//fTrace->GetLaser().SetXYZThPhi(runstate->fLaser);
return fTrace;
}
//_____________________________________________________________________________
LTrace* LScope::GetTrace() const {
// -*-*-*-*-*-*-*-*-*return aqusited data*-*-*-*-*-*-*-*-*
// ============================
return fTrace;
}
//_____________________________________________________________________________
TH1F* LScope::GetHWF(const int numbins,const char* title,float lp,float hp) {
// -*-*-*-*-*-*-*-*-*return histogram from transfered data*-*-*-*-*-*-*-*-*
// ============================
// Take care, that histograms can't contain 250K points!!
//if(fHWF) delete fHWF;
//if(fHWF) delete fHWF;
float lower=-fTrace->GetTimeSep()*fTrace->GetTriggerDelay()/100.*250000;
float upper=fNP*fTrace->GetTimeSep()+lower;
float lowerp=(upper-lower)*lp+lower;
float upperp=(upper-lower)*hp+lower;
char str[80];
sprintf(str,"WaveForm:%s",fLastChan);
TH1F* fHWF=new TH1F(title,title,numbins,lowerp,upperp);
if(!fTrace) return 0;
for(int i=0;i<numbins;i++) {
float sum=0;
for(int j=0;j<fNP/numbins;j++) {
sum+=(*fTrace)[i*fNP/numbins+j];
}
fHWF->SetBinContent(i,sum*numbins/fNP);
}
return fHWF;
}
//_____________________________________________________________________________
void LScope::SetVDIV(const char* vdiv,const char* channel) {
Sendf("%s:VDIV %s",kFALSE,channel,vdiv);
Sendf("%s:VDIV?",kTRUE,channel);
float f;
sscanf(fStrOut,"%*s %f %*s",&f);
fScopeState->fVDIV[fScopeState->GetChanId(channel)]=f;
};
//_____________________________________________________________________________
void LScope::SetOffset(const char* vdiv,const char* channel) {
Sendf("%s:OFFSET %s",kFALSE,channel,vdiv);
Sendf("%s:OFFSET?",kTRUE,channel);
float f;
sscanf(fStrOut,"%*s %f %*s",&f);
fScopeState->fOffset[fScopeState->GetChanId(channel)]=f;
};
//_____________________________________________________________________________
float LScope::GetVDIV(const char* channel) {
//printf("%s:VDIV %f %dn",channel,fScopeState->fVDIV[fScopeState->GetChanId(channel)],fScopeState->GetChanId("C2"));
//fScopeState->PrintIt();
return fScopeState->fVDIV[fScopeState->GetChanId(channel)];
};
//_____________________________________________________________________________
float LScope::GetOffset(const char* channel) {
printf("%s:OFSET %fn",channel,fScopeState->fOffset[fScopeState->GetChanId(channel)]);
return fScopeState->fOffset[fScopeState->GetChanId(channel)];
};
//_____________________________________________________________________________
void LScope::SetTriggerDelay(const float percent) {
fScopeState->fTriggerDelay=percent;
Sendf("TRIG_DELAY %d",percent);
}
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.