Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

RawLinearizedDataBlock.cxx

Go to the documentation of this file.
00001 
00002 // $Id: RawLinearizedDataBlock.cxx,v 1.9 2003/07/10 19:36:29 rhatcher Exp $
00003 // 
00004 // RawLinearizedDataBlock 
00005 // 
00006 // RawLinearizedDataBlock holds a block of linearized QIE data
00007 //
00008 // Author:  R. Hatcher 2002.07.15
00009 //
00011 
00012 #include "RawData/RawLinearizedDataBlock.h"
00013 #include "TMath.h"
00014 
00015 UInt_t RawLinearizedDataBlock::fgDebugFlags = 0;
00016 
00017 #include "MessageService/MsgService.h"
00018 CVSID("$Id: RawLinearizedDataBlock.cxx,v 1.9 2003/07/10 19:36:29 rhatcher Exp $");
00019 #include "MessageService/MsgFormat.h"
00020 
00021 #include "RawData/RawBlockRegistry.h"
00022 REGISTERRAWBLOCK(RawLinearizedDataBlock,kMdBlockLinearizedData,0);
00023 
00024 ClassImp(RawLinearizedDataBlock)
00025 
00026 enum ELinearizedDataBlkPos {
00027    indx_size      = 0,
00028    indx_checksum  = 1,
00029    indx_blockid   = 2,
00030    indx_run       = 3,
00031    indx_subrun    = 4,
00032    indx_runtype   = indx_subrun,
00033    indx_sec       = 5,
00034    indx_nsec      = 6,
00035    indx_tf_v0     = 7,
00036    zzzz_last_v0   = 8,
00037    indx_crateid   = 7,
00038    indx_tf        = 8,
00039    indx_nloc      = 9,
00040    zzzz_last      = 10
00041 };
00042 
00043 struct LinDataPoint 
00044 {
00045   long              nEntries;
00046   long unsigned int sum;
00047   long unsigned int sum_sqr_high;
00048   long unsigned int sum_sqr_low;
00049 };
00050 const UInt_t linDataPointIntSize = sizeof(LinDataPoint)/sizeof(Int_t);
00051 
00052 const UInt_t illegalLocation = 0xFFFFFFFF;
00053 //_____________________________________________________________________________
00054 RawLinearizedDataBlock::RawLinearizedDataBlock()
00055   : RawDataBlock()
00056 {
00057    // Default constructor
00058 }
00059 
00060 //_____________________________________________________________________________
00061 RawLinearizedDataBlock::RawLinearizedDataBlock(const Int_t *block)
00062    : RawDataBlock(block)
00063 {
00064    //  stored block format is:
00065    //---------------------
00066    //      version 0             version 1
00067    //  0   # words in block      # words in block      
00068    //  1   checksum              checksum              
00069    //  2   Block Id              Block Id              
00070    //-----                                             
00071    //  3   run #                 run #                 
00072    //  4   {subrun #| run type}  {subrun #| run type}  
00073    //  5   trigger time (sec)    trigger time (sec)    
00074    //  6   trigger time (nsec)   trigger time (nsec)   
00075    //  7   timeframe #           crateid
00076    //  8     --n/a--             timeframe #           
00077    //  9     --n/a--             nlocations
00078   /*
00079    * The data has the following reapeating structure until
00080    * all channels are completed:
00081    *           long unsigned int  location;  -- bit packed
00082    *           long               nPoints;
00083    * nPoints * struct  {  long             nEntries;
00084    *                      long unsigned int sum;
00085    *                      long unsigned int sum_sqr(high word);
00086    *                      long unsigned int sum_sqr(low word);
00087    *                   }
00088    */
00089 
00090 }
00091 
00092 //_____________________________________________________________________________
00093 RawLinearizedDataBlock::~RawLinearizedDataBlock()
00094 {
00095    // dtor
00096 }
00097 
00098 //____________________________________________________________________________
00099 RawLinearizedDataBlock& 
00100 RawLinearizedDataBlock::operator=(const RawLinearizedDataBlock& rhs)
00101 {
00102    // deep copy assignment 
00103    if (this != &rhs) {
00104      RawDataBlock::operator=(rhs);
00105      fCrateId = rhs.fCrateId;
00106      // clear these to allow them to be re-filled
00107      fLocation.clear();
00108      fLocStart.clear();
00109    }
00110    return *this;
00111 }
00112 
00113 //_____________________________________________________________________________
00114 Int_t RawLinearizedDataBlock::GetRun() const
00115 {
00116    // get the run number
00117    if (fSize > indx_run) return fRawBlock[indx_run];
00118    return -1;
00119 }
00120  
00121 //_____________________________________________________________________________
00122 Short_t RawLinearizedDataBlock::GetSubRun() const
00123 {
00124    // get the subrun number
00125    if (fSize > indx_subrun) return (fRawBlock[indx_subrun]>>16)&0xffff;
00126    return -1;
00127 }
00128  
00129 //_____________________________________________________________________________
00130 Short_t RawLinearizedDataBlock::GetRunType() const
00131 {
00132    // get the run type
00133    if (fSize > indx_runtype) return fRawBlock[indx_runtype]&0xffff;
00134    return -1;
00135 }
00136  
00137 //_____________________________________________________________________________
00138 VldTimeStamp RawLinearizedDataBlock::GetTimeStamp() const
00139 {
00140    // get the trigger time
00141    if (fSize > indx_nsec)
00142       return VldTimeStamp(fRawBlock[indx_sec],fRawBlock[indx_nsec]);
00143  
00144    return VldTimeStamp((time_t)0,(Int_t)0);
00145 }
00146  
00147 //_____________________________________________________________________________
00148 Int_t RawLinearizedDataBlock::GetCrateIdInfo() const
00149 {
00150    // get the crate id word
00151    if (GetMinorId() <= 0) return -1; // didn't exist in this version
00152    if (fSize > indx_crateid) return fRawBlock[indx_crateid];
00153    return -1;
00154 }
00155 
00156 //_____________________________________________________________________________
00157 Int_t RawLinearizedDataBlock::GetTimeFrameNum() const
00158 {
00159    // get the timeframe number
00160    int indx_tf_v = indx_tf;
00161    if (GetMinorId() <= 0) indx_tf_v--; 
00162    if (fSize > indx_tf_v) return fRawBlock[indx_tf_v];
00163    return -1;
00164 }
00165 
00166 //_____________________________________________________________________________
00167 UInt_t RawLinearizedDataBlock::GetNumLocations() const
00168 {
00169    // calculate how many distinct locations are recorded
00170    // each might have a different number of points recorded
00171 
00172    UInt_t minor = GetMinorId();
00173    UInt_t nloc_unpacked = FillLocStart();
00174    if (minor > 0) {
00175      UInt_t nloc_stored = fRawBlock[indx_nloc];
00176      if (nloc_stored != nloc_unpacked)
00177        MSG("RawData",Msg::kError)
00178          << " Unpacking found " << nloc_unpacked
00179          << " 'location', while data claims " << nloc_stored 
00180          << " were stored" << endl;
00181    }
00182    return nloc_unpacked;
00183 }
00184 
00185 //_____________________________________________________________________________
00186 UInt_t RawLinearizedDataBlock::GetLocation(UInt_t indx) const
00187 {
00188    // report "location" associated with sub-block index by "indx"
00189 
00190    UInt_t nloc = FillLocStart();
00191    if ( indx >= nloc) { // zero based indexing
00192      MSG("RawData",Msg::kError)
00193        << "indx " << indx << " out of range: there are only "
00194        << nloc << " entries" << endl;
00195      return illegalLocation;
00196    }
00197    return fLocation[indx];
00198 }
00199 
00200 //_____________________________________________________________________________
00201 UInt_t RawLinearizedDataBlock::GetNumPoints(UInt_t loc) const
00202 {
00203 
00204    // treat each sub-block as indexed by "location"
00205 
00206    FillLocStart();
00207    const Int_t* ptr = fLocStart[loc];  // this is "location"
00208    return *(ptr+1);                    // this is "nPoints"
00209 }
00210 
00211 //_____________________________________________________________________________
00212 UInt_t RawLinearizedDataBlock::GetNumEntries(UInt_t loc, UInt_t ipt) const
00213 {
00214    // the number of entries that went into the sub-sub-block
00215    // related to "location" and point # "ipt"
00216 
00217    const LinDataPoint* ptr = (const LinDataPoint*)StartOfLocPoint(loc,ipt);
00218    if (!ptr) return 0;
00219    return ptr->nEntries;
00220 }
00221 
00222 //_____________________________________________________________________________
00223 Double_t RawLinearizedDataBlock::GetMean(UInt_t loc, UInt_t ipt) const
00224 {
00225    // the "range" that the sub-sub-block corresponds to
00226    // "location" and point # "ipt"
00227 
00228    const LinDataPoint* ptr = (const LinDataPoint*)StartOfLocPoint(loc,ipt);
00229    if (!ptr) return 0;
00230    if (!ptr->nEntries) return 0; // don't divide by zero
00231    return (Double_t)ptr->sum/(Double_t)ptr->nEntries;
00232 }
00233 
00234 //_____________________________________________________________________________
00235 Double_t RawLinearizedDataBlock::GetRms(UInt_t loc, UInt_t ipt) const
00236 {
00237    // the RMS that the sub-sub-block corresponds to
00238    // "location" and point # "ipt"
00239 
00240    const LinDataPoint* ptr = (const LinDataPoint*)StartOfLocPoint(loc,ipt);
00241    if (!ptr) return 0;
00242    if (!ptr->nEntries) return 0; // don't divide by zero
00243    Double_t n     = (Double_t)ptr->nEntries;
00244    Double_t sumx  = (Double_t)ptr->sum;
00245    unsigned long long isumx2 = GetSumSqr(loc,ipt);
00246    Double_t sumx2 = (Double_t)isumx2;
00247    Double_t mean  = sumx/n;
00248    return TMath::Sqrt(sumx2/n - mean*mean);
00249 
00250 }
00251 
00252 //_____________________________________________________________________________
00253 UInt_t RawLinearizedDataBlock::GetSum(UInt_t loc, UInt_t ipt) const
00254 {
00255    // the sum that the sub-sub-block corresponds to
00256    // "location" and point # "ipt"
00257 
00258    const LinDataPoint* ptr = (const LinDataPoint*)StartOfLocPoint(loc,ipt);
00259    if (!ptr) return 0;
00260    return ptr->sum;
00261 
00262 }
00263 
00264 //_____________________________________________________________________________
00265 unsigned long long RawLinearizedDataBlock::GetSumSqr(UInt_t loc, UInt_t ipt) const
00266 {
00267    // the sum^2 that the sub-sub-block corresponds to
00268    // "location" and point # "ipt"
00269 
00270    const LinDataPoint* ptr = (const LinDataPoint*)StartOfLocPoint(loc,ipt);
00271    if (!ptr) return 0;
00272    unsigned long long sum2 = 
00273      ( (unsigned long long)ptr->sum_sqr_high << 32) | ( ptr->sum_sqr_low );
00274    return sum2;
00275 
00276 }
00277 
00278 //_____________________________________________________________________________
00279 Double_t RawLinearizedDataBlock::GetMean(UInt_t loc) const
00280 {
00281    // the "range" that the sub-sub-block corresponds to
00282    // "location", averaged over all points
00283 
00284    // use 'long long' to accumulate multiple points
00285    // before conversion to double to avoid potential loss of precision
00286    unsigned long long sumofentries = 0;
00287    unsigned long long sumofsums = 0;
00288 
00289    UInt_t npts = GetNumPoints(loc);
00290    for (UInt_t ipt = 0; ipt < npts; ++ipt) {
00291      const LinDataPoint* ptr = (const LinDataPoint*)StartOfLocPoint(loc,ipt);
00292      sumofentries += ptr->nEntries;
00293      sumofsums    += ptr->sum;
00294    }
00295    if (sumofentries) return 0; // don't divide by zero
00296    return (Double_t)sumofsums/(Double_t)sumofentries;
00297 }
00298 
00299 //_____________________________________________________________________________
00300 Double_t RawLinearizedDataBlock::GetRms(UInt_t loc) const
00301 {
00302    // the RMS that the sub-sub-block corresponds to
00303    // "location", averaged over all points
00304 
00305    // use 'long long' to accumulate multiple points
00306    // before conversion to double to avoid potential loss of precision
00307    unsigned long long sumofentries = 0;
00308    unsigned long long sumofsums = 0;
00309    unsigned long long sumofsumsqrs = 0;
00310 
00311    UInt_t npts = GetNumPoints(loc);
00312    for (UInt_t ipt = 0; ipt < npts; ++ipt) {
00313      const LinDataPoint* ptr = (const LinDataPoint*)StartOfLocPoint(loc,ipt);
00314      sumofentries += ptr->nEntries;
00315      sumofsums    += ptr->sum;
00316      //sumofsumsqrs += ptr->sum_sqr;
00317      unsigned long long this_sum_sqr =
00318        ( (unsigned long long)ptr->sum_sqr_high << 32) | ( ptr->sum_sqr_low );
00319      sumofsumsqrs += this_sum_sqr;
00320    }
00321    if (sumofentries) return 0; // don't divide by zero
00322    Double_t mean = (Double_t)sumofsums/(Double_t)sumofentries;
00323    Double_t sumx2byn = (Double_t)sumofsumsqrs/(Double_t)sumofentries;
00324    return TMath::Sqrt(sumx2byn - mean*mean);
00325 
00326 }
00327 
00328 //_____________________________________________________________________________
00329 void RawLinearizedDataBlock::FillCrateId() const
00330 {
00331    // unpack crate info
00332    if (!fCrateId.IsNull()) return;
00333    if (GetMinorId() <= 0) {
00334      fCrateId.SetDetector(GetBlockId().GetDetector());
00335      MSG("RawData",Msg::kWarning)
00336        << " No crate info for minor version " << GetMinorId() << endl;
00337      return;
00338    }
00339    fCrateId = RawChannelId(GetBlockId().GetDetector(),GetCrateIdInfo(),0x1fff);
00340 }
00341 
00342 //_____________________________________________________________________________
00343 UInt_t RawLinearizedDataBlock::FillLocStart() const
00344 {
00345    // calculate how many distinct locations are recorded
00346    // each might have a different number of points recorded
00347    // fill vector of pointers to start of each location's data
00348    // if already filled just return
00349 
00350    if (!fLocStart.empty()) return fLocStart.size();
00351    
00352    int zzzz_last_v = zzzz_last;
00353    if (GetMinorId() <= 0) zzzz_last_v = zzzz_last_v0;
00354    const Int_t *ptr = fRawBlock + zzzz_last_v; // start of packed data
00355    const Int_t *end = fRawBlock + fSize;       // one beyond end
00356 
00357    while ( ptr < end ) {
00358      Int_t loc  = *ptr;
00359      Int_t npts = *(ptr+1);
00360      // bitch wildly if already an entry for this "location"
00361      if (fLocStart[loc]) 
00362        MSG("RawData",Msg::kError)
00363          << " Already have an sub-block unit for 'location' 0x"
00364          << hex << setfill('0') << setw(8) << loc 
00365          << setfill(' ') << dec << endl
00366          << " at offset 0x" 
00367          << hex << setfill('0') << setw(8) << (fLocStart[loc]-fRawBlock) 
00368          << setfill(' ') << dec
00369          << " found again at 0x" 
00370          << hex << setfill('0') << setw(8) << (ptr-fRawBlock) 
00371          << setfill(' ') << dec
00372          << endl;
00373      fLocation.push_back(loc);
00374      fLocStart[loc] = ptr;
00375      // skip loc+npts + npts*(entries,range,s,s2)
00376      Int_t skip = 2 + npts*linDataPointIntSize;  
00377      ptr += skip;
00378    }
00379 
00380    if ( ptr != end ) 
00381      MSG("RawData",Msg::kError) << endl
00382        << "FillLocStart() unpacking did not end evenly at block boundary" 
00383        << endl;
00384    
00385    return fLocStart.size();
00386 }
00387 
00388 //_____________________________________________________________________________
00389 const Int_t* RawLinearizedDataBlock::StartOfLocPoint(UInt_t loc, UInt_t ipt) const
00390 {
00391 
00392    // treat each sub-block as indexed by "location"
00393    // sub-sub-structures are indexed by "iptr" and offset by fixed amounts
00394 
00395    FillLocStart();  // make sure we've scanned to find each sub-block
00396    const Int_t* ptr = fLocStart[loc];
00397    if (!ptr) {
00398      MSG("RawData",Msg::kError)
00399        << " No entry for 'location' 0x" 
00400        << hex << setfill(' ') << setw(8) << loc 
00401        << setfill(' ') << dec << endl;
00402      return 0;
00403    }
00404    UInt_t npts = *(ptr+1); // this is "nPoints";
00405    if ( ipt >= npts ) { // zero based indexing
00406      MSG("RawData",Msg::kError)
00407        << "ipt " << ipt << " for 'location' 0x" 
00408        << hex << setfill(' ') << setw(8) << loc << setfill(' ') << dec
00409        << " that has only " << npts << " points" << endl;
00410      return 0;
00411    }
00412    // 2 skips loc+npoints, each struct is 4 long 
00413    ptr += (2 + ipt*linDataPointIntSize); 
00414    return ptr;
00415 }
00416 
00417 //_____________________________________________________________________________
00418 std::ostream& RawLinearizedDataBlock::FormatToOStream(std::ostream& os, 
00419                                                       Option_t *option) const
00420 {
00421 
00422    RawDataBlock::FormatToOStream(os,option);
00423    if (option[0] == 'X') return os;
00424    
00425    // additional block specific formatted output is done here
00426 
00427    os << " Run " << GetRun() << " SubRun " << GetSubRun()
00428       << " RunType " << GetRunType() << " TimeFrame " << GetTimeFrameNum()
00429       << endl
00430       << " TimeStamp " << GetTimeStamp().AsString("c") << endl;
00431    if (GetMinorId()>0) {
00432      FillCrateId();
00433      os << " CrateId " << fCrateId.AsString("C") << ", ";
00434    }
00435    UInt_t nloc = GetNumLocations();
00436    os << " " << nloc << " 'locations' "<< endl;
00437 
00438    // xx'location' 
00439    // xxxx[123] range      entries    mean        RMS
00440    //   0x12345678 has ?? points
00441    //     [123] 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890
00442    os << "            -----  entries         mean          RMS        Sum       SumSqr" << endl;
00443    for (UInt_t indx = 0; indx < nloc; ++indx) {
00444      UInt_t loc = GetLocation(indx);
00445      UInt_t npt = GetNumPoints(loc);
00446      os << "  location 0x" 
00447         << hex << setfill('0') << setw(8) << loc << setfill(' ') << dec
00448         << " ( index = " << setw(3) << indx << " )"
00449         << " has " << npt << " points" << endl;
00450      for (UInt_t ipt = 0; ipt < npt; ++ipt) {
00451        os << "   [" << setw(3) << ipt << "] "
00452          //<< setw(8) << GetRange(loc,ipt) << " "
00453           << "         "
00454           << setw(8)  << GetNumEntries(loc,ipt) << " "
00455           << setw(12) << GetMean(loc,ipt) << " "
00456           << setw(12) << GetRms(loc,ipt) << " "
00457           << setw(10) << GetSum(loc,ipt) << " "
00458           << setw(12) << GetSumSqr(loc,ipt)
00459           << endl;
00460      }
00461    }
00462    return os;
00463 }
00464 
00465 //_____________________________________________________________________________

Generated on Mon Feb 15 11:07:28 2010 for loon by  doxygen 1.3.9.1