// 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.