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

RawCurrentInjectDataBlock.cxx

Go to the documentation of this file.
00001 
00002 // $Id: RawCurrentInjectDataBlock.cxx,v 1.10 2004/01/29 18:14:19 rhatcher Exp $
00003 // 
00004 // RawCurrentInjectDataBlock  
00005 // 
00006 // RawCurrentInjectDataBlock holds a block of QIE current injection data
00007 //
00008 // Author:  R. Hatcher 2002.07.15
00009 //
00011 
00012 #include "RawData/RawCurrentInjectDataBlock.h"
00013 #include "TMath.h"
00014 
00015 UInt_t RawCurrentInjectDataBlock::fgDebugFlags = 0;
00016 
00017 #include "MessageService/MsgService.h"
00018 CVSID("$Id: RawCurrentInjectDataBlock.cxx,v 1.10 2004/01/29 18:14:19 rhatcher Exp $");
00019 #include "MessageService/MsgFormat.h"
00020 
00021 #include "RawData/RawBlockRegistry.h"
00022 REGISTERRAWBLOCK(RawCurrentInjectDataBlock,kMdBlockCurrentInjectData,0);
00023 
00024 ClassImp(RawCurrentInjectDataBlock)
00025 
00026 enum ECurrInjBlkPos {
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_ncalpts_v0 = 5,
00034    indx_daqvals_v0 = 6,
00035    indx_crateid    = 5,
00036    indx_ncalpts    = 6,
00037    indx_nloc       = 7,
00038    indx_daqvals    = 8,
00039    zzzz_last       = indx_daqvals
00040 };
00041  
00042 struct CurrInjPoint
00043 {
00044   long              nEntries;
00045   long unsigned int sum;
00046   long unsigned int sum_sqr_high;
00047   long unsigned int sum_sqr_low;
00048 };
00049 const UInt_t currInjPointIntSize = sizeof(CurrInjPoint)/sizeof(Int_t);
00050  
00051 const UInt_t illegalLocation = 0xFFFFFFFF;
00052 
00053 //_____________________________________________________________________________
00054 RawCurrentInjectDataBlock::RawCurrentInjectDataBlock()
00055   : RawDataBlock()
00056 {
00057    // Default constructor
00058 }
00059 
00060 //_____________________________________________________________________________
00061 RawCurrentInjectDataBlock::RawCurrentInjectDataBlock(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   numCalPoints          crateid
00074    //  6     --n/a--             numCalPoints
00075    //  7     --n/a--             nlocations
00076   /*
00077    * The data then has the following format:
00078    *  unsigned long dacValue[numCalPoints]; -- values of the current injection
00079    *     
00080    * then repeating data structure until 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 RawCurrentInjectDataBlock::~RawCurrentInjectDataBlock()
00094 {
00095    // dtor
00096 }
00097 
00098 //____________________________________________________________________________
00099 RawCurrentInjectDataBlock& 
00100 RawCurrentInjectDataBlock::operator=(const RawCurrentInjectDataBlock& 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 RawCurrentInjectDataBlock::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 RawCurrentInjectDataBlock::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 RawCurrentInjectDataBlock::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 Int_t RawCurrentInjectDataBlock::GetCrateIdInfo() const
00139 {
00140    // get the crate id word
00141    if (GetMinorId() <= 0) return -1; //didn't exist in this version
00142    if (fSize > indx_crateid) return fRawBlock[indx_crateid];
00143    return -1;
00144 }
00145 //_____________________________________________________________________________
00146 UInt_t RawCurrentInjectDataBlock::GetNumCalPoints() const
00147 {
00148    // get the number of calibration points
00149    int indx_ncalpts_v = indx_ncalpts;
00150    if (GetMinorId() <= 0) indx_ncalpts_v = indx_ncalpts_v0;
00151    if (fSize > indx_ncalpts_v) return fRawBlock[indx_ncalpts_v];
00152    return 0;
00153 }
00154 
00155 //_____________________________________________________________________________
00156 const Int_t* RawCurrentInjectDataBlock::GetDacValues() const
00157 {
00158    // get the number of calibration points
00159    int indx_daqvals_v = indx_daqvals;
00160    if (GetMinorId() <= 0) indx_daqvals_v = indx_daqvals_v0;
00161    if (fSize > indx_daqvals_v) return (const Int_t*)(fRawBlock+indx_daqvals_v);
00162    return 0;
00163 }
00164 
00165 //_____________________________________________________________________________
00166 Int_t RawCurrentInjectDataBlock::GetDacValue(UInt_t indx) const
00167 {
00168    // get a daq value point
00169    UInt_t ncalpts = GetNumCalPoints();
00170    if (indx >= ncalpts) { // zero based indexing
00171      MSG("RawData",Msg::kError)
00172        << "indx " << indx << " out of range: there are only "
00173        << ncalpts << " dac values " << endl;
00174      return 0;
00175    }
00176    int indx_daqvals_v = indx_daqvals;
00177    if (GetMinorId() <= 0) indx_daqvals_v = indx_daqvals_v0;
00178    if ((unsigned long)fSize > indx_daqvals_v+indx) 
00179      return (UInt_t)fRawBlock[indx_daqvals_v+indx];
00180    return 0;
00181 }
00182 
00183 //_____________________________________________________________________________
00184 UInt_t RawCurrentInjectDataBlock::GetNumLocations() const
00185 {
00186    // calculate how many distinct locations are recorded
00187    // each might have a different number of points recorded
00188 
00189    UInt_t minor = GetMinorId();
00190    UInt_t nloc_unpacked = FillLocStart();
00191    if (minor > 0) {
00192      UInt_t nloc_stored = fRawBlock[indx_nloc];
00193      if (nloc_stored != nloc_unpacked)
00194        MSG("RawData",Msg::kError)
00195          << " Unpacking found " << nloc_unpacked
00196          << " 'location', while data claims " << nloc_stored 
00197          << " were stored" << endl;
00198    }
00199    return nloc_unpacked;
00200 
00201 }
00202 
00203 //_____________________________________________________________________________
00204 UInt_t RawCurrentInjectDataBlock::GetLocation(UInt_t indx) const
00205 {
00206    // report "location" associated with sub-block index by "indx"
00207 
00208    UInt_t nloc = FillLocStart();
00209    if ( indx >= nloc) { // zero based indexing
00210      MSG("RawData",Msg::kError)
00211        << "indx " << indx << " out of range: there are only "
00212        << nloc << " entries" << endl;
00213      return illegalLocation;
00214    }
00215    return fLocation[indx];
00216 }
00217 
00218 //_____________________________________________________________________________
00219 UInt_t RawCurrentInjectDataBlock::GetNumPoints(UInt_t loc) const
00220 {
00221 
00222    // treat each sub-block as indexed by "location"
00223 
00224    FillLocStart();
00225    const Int_t* ptr = fLocStart[loc];  // this is "location"
00226    return *(ptr+1);                    // this is "nPoints"
00227 }
00228 
00229 //_____________________________________________________________________________
00230 UInt_t RawCurrentInjectDataBlock::GetNumEntries(UInt_t loc, UInt_t ipt) const
00231 {
00232    // the number of entries that went into the sub-sub-block
00233    // related to "location" and point # "ipt"
00234 
00235    const CurrInjPoint* ptr = (const CurrInjPoint*)StartOfLocPoint(loc,ipt);
00236    if (!ptr) return 0;
00237    return ptr->nEntries;
00238 }
00239 
00240 //_____________________________________________________________________________
00241 Double_t RawCurrentInjectDataBlock::GetMean(UInt_t loc, UInt_t ipt) const
00242 {
00243    // the "range" that the sub-sub-block corresponds to
00244    // "location" and point # "ipt"
00245 
00246    const CurrInjPoint* ptr = (const CurrInjPoint*)StartOfLocPoint(loc,ipt);
00247    if (!ptr) return 0;
00248    if (!ptr->nEntries) return 0; // don't divide by zero
00249    return (Double_t)ptr->sum/(Double_t)ptr->nEntries;
00250 }
00251 
00252 //_____________________________________________________________________________
00253 Double_t RawCurrentInjectDataBlock::GetRms(UInt_t loc, UInt_t ipt) const
00254 {
00255    // the RMS that the sub-sub-block corresponds to
00256    // "location" and point # "ipt"
00257 
00258    const CurrInjPoint* ptr = (const CurrInjPoint*)StartOfLocPoint(loc,ipt);
00259    if (!ptr) return 0;
00260    if (!ptr->nEntries) return 0; // don't divide by zero
00261    Double_t n     = (Double_t)ptr->nEntries;
00262    Double_t sumx  = (Double_t)ptr->sum;
00263    unsigned long long isumx2 = GetSumSqr(loc,ipt);
00264    Double_t sumx2 = (Double_t)isumx2;
00265    Double_t mean  = sumx/n;
00266    return TMath::Sqrt(sumx2/n - mean*mean);
00267 
00268 }
00269 
00270 //_____________________________________________________________________________
00271 UInt_t RawCurrentInjectDataBlock::GetSum(UInt_t loc, UInt_t ipt) const
00272 {
00273    // the sum that the sub-sub-block corresponds to
00274    // "location" and point # "ipt"
00275 
00276    const CurrInjPoint* ptr = (const CurrInjPoint*)StartOfLocPoint(loc,ipt);
00277    if (!ptr) return 0;
00278    return ptr->sum;
00279 
00280 }
00281 
00282 //_____________________________________________________________________________
00283 unsigned long long RawCurrentInjectDataBlock::GetSumSqr(UInt_t loc, UInt_t ipt) const
00284 {
00285    // the sum^2 that the sub-sub-block corresponds to
00286    // "location" and point # "ipt"
00287 
00288    const CurrInjPoint* ptr = (const CurrInjPoint*)StartOfLocPoint(loc,ipt);
00289    if (!ptr) return 0;
00290    unsigned long long sum2 =
00291      ( (unsigned long long)ptr->sum_sqr_high << 32) | ( ptr->sum_sqr_low );
00292    return sum2;
00293 
00294 }
00295 
00296 //_____________________________________________________________________________
00297 void RawCurrentInjectDataBlock::FillCrateId() const
00298 {
00299    // unpack crate info
00300    if (!fCrateId.IsNull()) return;
00301    if (GetMinorId() <= 0) {
00302      fCrateId.SetDetector(GetBlockId().GetDetector());
00303      MSG("RawData",Msg::kWarning)
00304        << " No crate info for minor version " << GetMinorId() << endl;
00305      return;
00306    }
00307    fCrateId = RawChannelId(GetBlockId().GetDetector(),GetCrateIdInfo(),0x1fff);
00308 }
00309 
00310 //_____________________________________________________________________________
00311 UInt_t RawCurrentInjectDataBlock::FillLocStart() const
00312 {
00313    // calculate how many distinct locations are recorded
00314    // each might have a different number of points recorded
00315    // fill vector of pointers to start of each location's data
00316    // if already filled just return
00317 
00318    if (!fLocStart.empty()) return fLocStart.size();
00319 
00320    UInt_t ncalpts = GetNumCalPoints();
00321    int indx_daqvals_v = indx_daqvals;
00322    if (GetMinorId() <= 0) indx_daqvals_v = indx_daqvals_v0;
00323    const Int_t *ptr = 
00324          fRawBlock + indx_daqvals_v + ncalpts; // start of packed data
00325    const Int_t *end = fRawBlock + fSize;       // one beyond end
00326 
00327    while ( ptr < end ) {
00328      Int_t loc  = *ptr;
00329      Int_t npts = *(ptr+1);
00330      // bitch wildly if already an entry for this "location"
00331      if (fLocStart[loc]) 
00332        MSG("RawData",Msg::kError)
00333          << " Already have an sub-block unit for 'location' 0x"
00334          << hex << setfill('0') << setw(8) << loc 
00335          << setfill(' ') << dec << endl
00336          << " at offset 0x" 
00337          << hex << setfill('0') << setw(8) << (fLocStart[loc]-fRawBlock) 
00338          << setfill(' ') << dec
00339          << " found again at 0x" 
00340          << hex << setfill('0') << setw(8) << (ptr-fRawBlock) 
00341          << setfill(' ') << dec
00342          << endl;
00343      fLocation.push_back(loc);
00344      fLocStart[loc] = ptr;
00345      // skip loc+npts + npts*(entries,range,s,s2)
00346      Int_t skip = 2 + npts*currInjPointIntSize;  
00347      ptr += skip;
00348    }
00349 
00350    if ( ptr != end ) 
00351      MSG("RawData",Msg::kError) << endl
00352        << "FillLocStart() unpacking did not end evenly at block boundary" 
00353        << endl;
00354    
00355    return fLocStart.size();
00356 }
00357 
00358 //_____________________________________________________________________________
00359 const Int_t* RawCurrentInjectDataBlock::StartOfLocPoint(UInt_t loc, UInt_t ipt) const
00360 {
00361 
00362    // treat each sub-block as indexed by "location"
00363    // sub-sub-structures are indexed by "iptr" and offset by fixed amounts
00364 
00365    FillLocStart();  // make sure we've scanned to find each sub-block
00366    const Int_t* ptr = fLocStart[loc];
00367    if (!ptr) {
00368      MSG("RawData",Msg::kError)
00369        << " No entry for 'location' 0x" 
00370        << hex << setfill(' ') << setw(8) << loc 
00371        << setfill(' ') << dec << endl;
00372      return 0;
00373    }
00374    UInt_t npts = *(ptr+1); // this is "nPoints";
00375    if ( ipt >= npts ) { // zero based indexing
00376      MSG("RawData",Msg::kError)
00377        << "ipt " << ipt << " for 'location' 0x" 
00378        << hex << setfill(' ') << setw(8) << loc << setfill(' ') << dec
00379        << " that has only " << npts << " points" << endl;
00380      return 0;
00381    }
00382    // 2 skips loc+npoints, each struct is 4 long 
00383    ptr += (2 + ipt*currInjPointIntSize); 
00384    return ptr;
00385 }
00386 
00387 //_____________________________________________________________________________
00388 std::ostream& RawCurrentInjectDataBlock::FormatToOStream(std::ostream& os, 
00389                                                          Option_t *option) const
00390 {
00391 
00392    RawDataBlock::FormatToOStream(os,option);
00393    if (option[0] == 'X') return os;
00394    
00395    // additional block specific formatted output is done here
00396 
00397    os << " Run " << GetRun() << " SubRun " << GetSubRun()
00398       << " RunType " << GetRunType() << endl;
00399    if (GetMinorId()>0) {
00400      FillCrateId();
00401      os << " CrateId " << fCrateId.AsString("C") << ", ";
00402    }
00403    UInt_t ndacv = GetNumCalPoints();
00404    const Int_t* dacv  = GetDacValues();
00405    os << " " << ndacv << " Dac Values" << endl;
00406    for (UInt_t idacv = 0; idacv < ndacv; ++idacv) {
00407      os << "   [" << setw(3) << idacv << "] " 
00408         << setw(5) << dacv[idacv];
00409      if (idacv%4==3) os << endl;
00410    }
00411    if ((ndacv-1)%4!=3) os << endl;
00412 
00413    UInt_t nloc = GetNumLocations();
00414    os << " " << nloc << " 'locations' "<< endl;
00415 
00416    // xx'location' 
00417    // xxxx[123] range      entries    mean        RMS
00418    //   0x12345678 has ?? points
00419    //     [123] 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890
00420    os << "            -----  entries         mean          RMS        Sum       SumSqr" << endl;
00421    for (UInt_t indx = 0; indx < nloc; ++indx) {
00422      UInt_t loc = GetLocation(indx);
00423      UInt_t npt = GetNumPoints(loc);
00424      os << "  location 0x" 
00425         << hex << setfill('0') << setw(8) << loc << setfill(' ') << dec
00426         << " ( index = " << setw(3) << indx << " )"
00427         << " has " << npt << " points" << endl;
00428      for (UInt_t ipt = 0; ipt < npt; ++ipt) {
00429        os << "   [" << setw(3) << ipt << "] "
00430          //<< setw(8) << GetRange(loc,ipt) << " "
00431           << "         "
00432           << setw(8)  << GetNumEntries(loc,ipt) << " "
00433           << setw(12) << GetMean(loc,ipt) << " "
00434           << setw(12) << GetRms(loc,ipt) << " "
00435           << setw(10) << GetSum(loc,ipt) << " "
00436           << setw(12) << GetSumSqr(loc,ipt)
00437           << endl;
00438      }
00439    }
00440    return os;
00441 }
00442 
00443 //_____________________________________________________________________________

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