QCrateReceiverBuffer.hh

Go to the documentation of this file.
00001 
00034 #ifndef __QCRATERECEIVERBUFFER_HH_
00035 #define __QCRATERECEIVERBUFFER_HH_
00036 
00037 #include <string>
00038 #include <vector>
00039 #include <stdexcept>
00040 #include <unistd.h>
00041 #include <iostream>
00042 #include <zlib.h>
00043 #include <math.h> // for round()
00044 
00045 #include "QCuore.hh"
00046 #include "QError.hh"
00047 #include "QConnectedSocket.hh"
00048 
00049 #define DEFAULT_BUFFER_SIZE    60000 
00050 #define MAX_CHANNEL_FILE_SIZE  20000000 
00070 struct QBufferStructure_t {
00071    unsigned long fId;                
00072    unsigned long fNum;               
00073    unsigned long long fRead;         
00074    unsigned long long fWrite;        
00075    unsigned long long fReadFile;     
00076    unsigned long long fNotProcessed; 
00078    unsigned long long fNotBuilt;     
00080    unsigned long fCurrentRun;        
00081    bool fNotProcessedIsActive;       
00083    bool fReadPtrIsActive;            
00085    bool fNotBuiltIsActive;           
00087    bool fSaveFile;                   
00089    unsigned long fSamplingRate;     
00091    long fData[DEFAULT_BUFFER_SIZE]; 
00092 };
00093 
00094 
00095 class QCrateReceiverBuffer {
00096 public:
00097    QCrateReceiverBuffer(unsigned long ch, 
00098                         bool          attach, 
00099                         bool          OpenFiles, 
00100                         int           RunNumber=0, 
00101                         bool          offset_shm=false);
00102   
00103    virtual ~QCrateReceiverBuffer();
00104   
00105    unsigned long Size() const {return DEFAULT_BUFFER_SIZE;}
00106    
00108    char* Start() const
00109    {return 
00110        (char*)(&(p_buffer->fData[(p_buffer->fRead) % DEFAULT_BUFFER_SIZE]));}
00111 
00113    inline unsigned long GetNumberOfWords() const 
00114    {return p_buffer->fNum;}
00115 
00124    bool EnableTriggerPointer();
00125 
00127    void ReleaseTriggerPointer();
00128 
00137    bool EnableBuilderPointer();
00138 
00140    void ReleaseBuilderPointer();
00141 
00150    bool EnableReadPointer();
00151 
00153    void ReleaseReadPointer();
00154 
00160    inline void Release(unsigned int n);
00161     
00167    void Add(int n, const long* data);
00168   
00172    void AddFromNetwork(QConnectedSocket* cs);
00173 
00175    inline int GetLg() const {return p_buffer->fId;}
00176 
00178    inline int ReadToEnd() const 
00179    {return DEFAULT_BUFFER_SIZE - 
00180        (unsigned long)((p_buffer->fRead) % DEFAULT_BUFFER_SIZE);} /* used by DataSender */
00181 
00183    inline void SetProcessed(unsigned int n);
00184 
00186    inline void SetBuilt(unsigned int n);
00187 
00188    //** @brief get number of valid words still to be processed by trigger */
00189    inline unsigned long GetToBeProcessed() const
00190    {return (unsigned long)(p_buffer->fWrite - p_buffer->fNotProcessed);}
00191 
00193    inline unsigned long GetToBeBuilt() const
00194    {return (unsigned long)(p_buffer->fNotProcessed - p_buffer->fNotBuilt);}
00195 
00197    inline unsigned long GetToBeRead() const
00198    {return (unsigned long)(p_buffer->fReadFile - p_buffer->fRead);}
00199 
00201    inline unsigned long long GetProcessed() const
00202    {return p_buffer->fNotProcessed;}
00203 
00205    inline unsigned long long GetBuilt() const
00206    {return p_buffer->fNotBuilt;}
00207 
00209    inline unsigned long long GetRead() const
00210    {return p_buffer->fRead;}
00211 
00213    inline unsigned long long GetWritten() const
00214    {return p_buffer->fWrite;}
00215    
00227    inline long GetData(unsigned long long index) const;
00228 
00238    inline long GetSample(unsigned long long index) const;
00239 
00247    inline short GetTriggerFlags(unsigned long long index, unsigned long mask=0xF) const
00248    {return (short)((GetData(index) >> 17) & mask);}
00249    
00255    inline void FlagTrigger(unsigned long long index,
00256                            int                tag);
00257 
00265    inline void SetTriggerEnabled(bool enabled);
00266 
00268    void SetSamplingRate(unsigned long rate) {p_buffer->fSamplingRate = rate;}
00269 
00271    unsigned long GetSamplingRate() const
00272    {return p_buffer->fSamplingRate;}
00273 
00281    inline long long GetTimeOfSample(unsigned long long index) const;
00282 
00284    inline unsigned long long GetSampleOfTime(long long time) const;
00285 
00286    // some info on output stream
00287    void Dump();
00288 
00289    //
00290    //SDD FIXME
00291    // Following 2 methods are for debugging purposes
00292    // Remember to remove them as soon as they are no more useful
00293    //
00294    // set single bit as analyzed by event builder
00295    inline void SetScanned(unsigned long long i) 
00296    {p_buffer->fData[(i % DEFAULT_BUFFER_SIZE)] |= (1<<27);}
00297    // set single bit as analyzed by trigger algorythm
00298    inline void SetAnalyzed(unsigned long long i)
00299    {p_buffer->fData[(i % DEFAULT_BUFFER_SIZE)] |= (1<<28);}
00300    
00301 private:
00302    inline void Release();
00303 
00308    inline void SetProcessed();
00309 
00314    inline void SetBuilt();
00315 
00317    inline unsigned long GetToBeWritten() const
00318    {return (unsigned long)(p_buffer->fNotBuilt - p_buffer->fReadFile);}
00319 
00321    void WriteFile();
00322 
00324    void OpenFile();
00325 
00327    void CloseFile(bool last);
00328 
00329    int fHandle;
00330    int fShmid;                   
00331    bool fOwn;                    
00333    QBufferStructure_t *p_buffer; 
00334    gzFile zFile;                 
00335    std::string fGzFileName;      
00336    unsigned int fPartialFile;    
00337    bool fReadPtrBooked;          
00339    bool fBuilderPtrBooked;       
00342    bool fTrgPtrBooked;           
00345 };
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 //_____________________________________________________________________________
00357 inline void QCrateReceiverBuffer::SetProcessed()
00358 {
00359    p_buffer->fNotProcessed = p_buffer->fWrite;
00360   
00361    // update builder pointer if builder is inactive
00362    if(!p_buffer->fNotBuiltIsActive) SetBuilt();
00363 }
00364 
00365 
00366 //_________________register_n_words_as_processed_by_trigger____________________
00367 inline void QCrateReceiverBuffer::SetProcessed(unsigned int n)
00368 {
00369    // do nothing if no one but QCrateReceiverBuffer itself is expected to 
00370    // move this pointer
00371    if(!fTrgPtrBooked) {
00372       std::cerr << "QCrateReceiverBuffer::SetProcessed(unsigned int) Warning! "
00373          "trying to move \"trigger pointer\" without having permission!!"
00374                 << std::endl;
00375       return;
00376    }
00377 
00378    // check that fNotProcessed ptr remains smaller than fWrite ptr
00379    if(n > GetToBeProcessed()) {
00380       n = GetToBeProcessed();
00381       std::cerr << "QCrateReceiverBuffer::SetProcessed Warning! moving "
00382          "\"Processed by trigger\" pointer into an inconsistent position "
00383          "avoided!" << std::endl;
00384    }
00385 
00386    // actually update pointer
00387    p_buffer->fNotProcessed+=n;
00388 
00389    // also update fNotBuilt ptr if it is not in use
00390    if(!p_buffer->fNotBuiltIsActive) SetBuilt();
00391 }
00392 
00393 
00394 //_____private_method_used_to_update_builder_pointer_when_it_is_not_booked_____
00395 inline void QCrateReceiverBuffer::SetBuilt() 
00396 {
00397    p_buffer->fNotBuilt = p_buffer->fNotProcessed;
00398 
00399    // also update fRead pointer if it is not in use
00400    if(!p_buffer->fReadPtrIsActive) Release();
00401 }
00402 
00403 
00404 //__________________register_n_words_as_processed_by_builder___________________
00405 inline void QCrateReceiverBuffer::SetBuilt(unsigned int n) 
00406 {
00407    // do nothing if no one but QCrateReceiverBuffer itself is expected to 
00408    // move this pointer
00409    if(!fBuilderPtrBooked) {
00410       std::cerr << "QCrateReceiverBuffer::SetBuilt(unsigned int) Warning! "
00411          "trying to move \"builder pointer\" without having permission!!" 
00412                 << std::endl;
00413       return;
00414    }
00415     
00416    // check that fNotBuilt ptr remains smaller than fNotProcessed ptr
00417    if(n > GetToBeBuilt()) {
00418       n = GetToBeBuilt();
00419       std::cerr << "QCrateReceiverBuffer::SetBuilt Warning! moving "
00420          "\"Processed by Builder\" pointer into an inconsistent position "
00421          "avoided!" << std::endl;
00422    }
00423 
00424    // actually update pointer
00425    p_buffer->fNotBuilt+=n;
00426 
00427    // also update fRead pointer if it is not in use
00428    if(!p_buffer->fReadPtrIsActive) Release();
00429 }
00430 
00431 
00432 // throw away all useless words from circular buffer
00433 inline void QCrateReceiverBuffer::Release() 
00434 {
00435    // update number of valid words
00436    p_buffer->fNum -= GetToBeRead();
00437 
00438    // move read pointer
00439    p_buffer->fRead += GetToBeRead();
00440 }
00441 
00442 
00443 // throw away n words from circular buffer
00444 inline void QCrateReceiverBuffer::Release(unsigned int n)
00445 {
00446    // return if we have no permission to move fRead ptr
00447    if(!fReadPtrBooked) {
00448       std::cerr << "QCrateReceiverBuffer::Release(unsigned int) Warning: "
00449          "trying to move read pointer without having permission." << std::endl;
00450       return;
00451    }
00452   
00453    // check that read pointer remain smaller than the fNotBuilt pointer
00454    if(n > GetToBeRead())
00455    {
00456       std::cerr << "QCrateReceiverBuffer::Release Warning! avoided "
00457          "inconsistent moving of \"read\" pointer for channel " 
00458                 << p_buffer->fId << ". requested: " << n 
00459                 << ", allowed: " << GetToBeRead() << std::endl;
00460       n = GetToBeRead();
00461    }
00462   
00463    // actually increase fRead pointer
00464    p_buffer->fRead += n;
00465 
00466    // update number of valid words
00467    p_buffer->fNum -= n;
00468 }
00469 
00470 
00471 // flag trigger bts for data samples between start and stop according to 
00472 // trigger tag
00473 inline void QCrateReceiverBuffer::FlagTrigger(unsigned long long index,
00474                                               int                tag) 
00475 {
00476    if(index < p_buffer->fRead || index > p_buffer->fWrite)
00477    {
00478       QError err(QERR_SHMEM_INVALID_INDEX);
00479       err.SetDescription("In FlagTrigger(): index out of bounds");
00480       throw err;
00481    }
00482 
00483    int position = 16+tag;
00484    unsigned long circularIndex = (unsigned long)(index % DEFAULT_BUFFER_SIZE);
00485    p_buffer->fData[circularIndex] |= (1 << position);
00486    
00487 }
00488 
00489 
00490 
00491 
00492 
00493 //_____________return_time_associated_to_a_given_sample______________
00494 inline long long QCrateReceiverBuffer::GetTimeOfSample(unsigned long long index)
00495    const
00496 {
00497    const unsigned long s2Ns = 1000000000;
00498    long long time = (s2Ns * index / p_buffer->fSamplingRate);
00499    if(index < p_buffer->fRead || index > p_buffer->fWrite) time *= -1;
00500    return time;
00501 }
00502 
00503 
00504 //_____________________________GetSampleOfTime()_______________________________
00505 inline unsigned long long QCrateReceiverBuffer::GetSampleOfTime(long long time)
00506    const
00507 {
00508    // return 0 if requested sample has negative time
00509    if(time < 0) return 0;
00510    const unsigned long s2Ns = 1000000000;
00511    return (unsigned long long)(time * p_buffer->fSamplingRate / s2Ns);
00512 }
00513 
00514 //__________________________GetData()__________________________________________
00515 inline long QCrateReceiverBuffer::GetData(unsigned long long index) const
00516 {
00517    unsigned long long lastValid = ((p_buffer->fWrite)>DEFAULT_BUFFER_SIZE)?
00518       (p_buffer->fWrite)-DEFAULT_BUFFER_SIZE:0;
00519    if(index < lastValid || index > p_buffer->fWrite)
00520    {
00521       QError err(QERR_SHMEM_INVALID_INDEX);
00522       char errMsg[300];
00523       sprintf(errMsg,"In GetData(): requested buffer index (%lld) is out of "
00524               "bounds (%lld - %lld)", index, lastValid, p_buffer->fWrite);
00525       err.SetDescription(errMsg);
00526       throw err;
00527    }
00528    unsigned long circular_index=(unsigned long)(index % DEFAULT_BUFFER_SIZE); 
00529    return p_buffer->fData[circular_index];
00530 }
00531 
00532 //________________________________GetSample()__________________________________
00533 inline long QCrateReceiverBuffer::GetSample(unsigned long long index) const
00534 {
00535    const long dataMask = 0x8001FFFF;
00536    long sample = GetData(index) & dataMask;
00537 
00538    if(sample >> 31) sample |= 0x7FFE0000;
00539 
00540    return sample;
00541 }
00542 
00543 
00544 //_______________________set_trigger_enable/disable_flag_______________________
00545 inline void QCrateReceiverBuffer::SetTriggerEnabled(bool enabled)
00546 { 
00547    // determine bit to be flagged
00548    int position = 25;
00549    if(enabled) position++;
00550 
00551    // flag data
00552    p_buffer->fData[(p_buffer->fWrite % DEFAULT_BUFFER_SIZE) - 1] |= 
00553       1L << position;
00554   
00555    return;
00556 }
00557 
00558 #endif

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