QOnlineScope.hh

Go to the documentation of this file.
00001 
00008 #ifndef _QONLINE_SCOPE_HH_
00009 #define _QONLINE_SCOPE_HH_
00010 
00011 // ROOT Includes
00012 #include "QCuore.hh"
00013 #include "TH1F.h"
00014 
00015 #define DEFAULT_BUFFER_SIZE 60000 
00016 #define DEFAULT_HISTO_SIZE 10000  
00017 #define NUMBER_OF_CHANNELS 4      
00019 // shared memory structure
00020 struct QOnlineScopeBuffer_t 
00021 {
00022    unsigned long fId[NUMBER_OF_CHANNELS];    
00023    unsigned long fSize;                      
00024    unsigned long fRead[NUMBER_OF_CHANNELS];  
00025    unsigned long fWrite[NUMBER_OF_CHANNELS]; 
00026    long fHistoSize[NUMBER_OF_CHANNELS];      
00027    float fData0[DEFAULT_BUFFER_SIZE];        
00028    float fData1[DEFAULT_BUFFER_SIZE];        
00029    float fData2[DEFAULT_BUFFER_SIZE];        
00030    float fData3[DEFAULT_BUFFER_SIZE];        
00031 };
00032 
00033 class QOnlineScope {
00034 public:
00035    QOnlineScope(bool attach);
00036    
00037    virtual ~QOnlineScope();
00038    
00044    inline void Add(float data, int index=0);
00045    
00050    inline unsigned long GetLg(int index=0) const {return p_buffer->fId[index];}
00051    
00058    inline void SetLg(unsigned long lg, int index=0);
00059 
00060    // Update histogram
00061    inline TH1F* UpdateHisto(int index=0);
00062 
00063    // Get mean value and sigma of the histogram (on Y axis!)
00064    void GetMeanSigma(double &mean, double &rms, int index=0);
00065    
00066    // Getters for getting Mean or Sigma individually
00067    const double GetMean(int index=0);
00068    const double GetSigma(int index=0);
00069    
00070 private:
00071    
00072    int  fHandle;
00073    int  fShmid;                        // shared memory id
00074    bool fOwn;                          // true if owner of shared memory
00075    QOnlineScopeBuffer_t *p_buffer;     // shared memory buffer pointer
00076    TH1F *fHisto[NUMBER_OF_CHANNELS];   // root histogram with scope plot
00077    float *GetData(int index);          // return pointer to buffer corresponding to index
00078    
00079 };
00080 
00081 
00082 //_____________________________________________________________________________
00083 inline void QOnlineScope::SetLg(unsigned long lg,int index) 
00084 {
00085    //
00086   // set new logical channel 
00087   // all buffer is cleared
00088   //
00089 
00090   if (lg == GetLg(index)) return;
00091   if (fHisto[index]) delete fHisto[index];
00092   
00093   fHisto[index]=0;
00094   p_buffer->fId[index] = lg;
00095   p_buffer->fRead[index]=0;
00096   p_buffer->fWrite[index]=0;
00097   
00098   return;
00099 }
00100 
00101 
00102 //_____________________________________________________________________________
00103 inline float*  QOnlineScope::GetData(int index) 
00104 {
00105   //
00106   // Get the right buffer
00107   //
00108   
00109   switch(index) 
00110   {
00111   case 1:
00112     return p_buffer->fData1; 
00113     break;
00114   case 2: 
00115     return p_buffer->fData2; 
00116     break;
00117   case 3: 
00118     return p_buffer->fData3; 
00119     break;
00120   case 0: 
00121   default:
00122     return p_buffer->fData0; 
00123     break;
00124   }
00125 }
00126                         
00127 
00128 //_____________________________________________________________________________
00129 inline void QOnlineScope::Add(float data, int index) 
00130 {
00131   //
00132   // Add data to buffer 
00133   //
00134   
00135   float *pData=GetData(index);
00136   pData[p_buffer->fWrite[index]] = data;
00137   p_buffer->fWrite[index]++;
00138   if (p_buffer->fWrite[index] == p_buffer->fSize)
00139     p_buffer->fWrite[index]=0;
00140 }
00141 
00142 //_____________________________________________________________________________
00143 inline TH1F *QOnlineScope::UpdateHisto(int index) 
00144 {
00145   if (GetLg(index)==0) return (TH1F*)0;
00146   
00147   if (NULL == fHisto[index]) 
00148   {
00149     char title[200];
00150     char name[200];
00151     sprintf(title,"Scope");
00152     sprintf(name,"Real Time Waveform Channel=%lu",GetLg(index));
00153     fHisto[index] = new TH1F(title,name,p_buffer->fHistoSize[index],0.,10.);
00154   } 
00155   
00156   // get available number of words in buffer 
00157   int nw = p_buffer->fWrite[index] - p_buffer->fRead[index];
00158   
00159   if (nw<0) nw += p_buffer->fSize;
00160   
00161   // do nothing if there are not enough new samples
00162   if (nw<200) return fHisto[index];
00163   
00164   if (nw>200) nw=200;
00165     
00166   float *pData = GetData(index);
00167     
00168   // update histogram shifting data to left 
00169   if (nw > p_buffer->fHistoSize[index]) 
00170   {
00171     nw = p_buffer->fHistoSize[index];
00172     for(int i=0; i<p_buffer->fHistoSize[index]; i++) 
00173     {
00174       int j = (p_buffer->fRead[index]+i)%p_buffer->fSize;
00175       fHisto[index]->SetBinContent(i+1,pData[j]);
00176     }
00177   }
00178   else 
00179   {
00180     for(int i=1; i<=p_buffer->fHistoSize[index]-nw; i++) 
00181     {
00182       double val =  fHisto[index]->GetBinContent(i+nw);
00183       fHisto[index]->SetBinContent(i,val);
00184     }
00185     for(int i=0; i<nw; i++) 
00186     {
00187       int j = (p_buffer->fRead[index]+i)%p_buffer->fSize;
00188       fHisto[index]->SetBinContent(p_buffer->fHistoSize[index]-nw+i+1,pData[j]);
00189     }
00190   }     
00191     
00192   // release data 
00193   p_buffer->fRead[index] += nw;
00194   if (p_buffer->fRead[index] >= p_buffer->fSize)
00195     p_buffer->fRead[index] -= p_buffer->fSize;
00196     
00197   return fHisto[index];
00198 }
00199 
00200 #endif // _QONLINE_SCOPE_HH_

Generated on Fri Mar 6 13:40:40 2009 for CUORE Software by  doxygen 1.5.1