RawScanResultStreamer_v3.cpp

00001 #include "RawScanResultStreamer_v3.h"
00002 #include "Sct/SctNames.h"
00003 #include "Sct/SctParameters.h"
00004 #include "Sct/LogicErrors.h"
00005 #include "Sct/VersionNotSupportedException.h"
00006 #include "Sct/UnsupportedOperationError.h"
00007 #include "../RawScanResult.h"
00008 #include "../ConfigurationVariable.h"
00009 #include "ScanResultWriter/dataTypes.h"
00010 
00011 #include "TH2.h"
00012 
00013 #include <iostream>
00014 #include <sstream>
00015 #include <boost/lexical_cast.hpp>
00016 
00017 using namespace std;
00018 using namespace Sct;
00019 using namespace boost;
00020 
00021 namespace SctData {
00022 namespace IO {
00023 
00024 /* READ NOTES ON STREAMERS AND VERSIONS BEFORE EDITING THIS FILE! */
00025 unsigned RawScanResultStreamer_v3::s_version=3;
00026 
00027 RawScanResultStreamer_v3::RawScanResultStreamer_v3() throw() {}
00028 
00029 bool RawScanResultStreamer_v3::inMap = IOManager::addToMap("SctData::RawScanResult",  auto_ptr<Streamer>(new RawScanResultStreamer_v3()));
00030 
00031 shared_ptr<Streamable> RawScanResultStreamer_v3::read(IStream& in, const IOManager& manager) const {
00032     shared_ptr<Streamable> ad (&helper.create());
00033     read(in, *ad, manager);
00034     return ad;
00035 }
00036 
00037 void RawScanResultStreamer_v3::write(OStream& out, const Streamable& ob, const IOManager& manager) const {
00038     manager.writeImpl(out, ob, "SctData::ScanResult");
00039 
00040     //Downcast should always work!
00041     const RawScanResult& raw = dynamic_cast<const RawScanResult&>(ob);
00042     helper.set(raw);
00043 
00044     //Now publish data - we publish using the ROOTHIST format.
00045     TH2D* link0 = helper.getScanData(0);
00046     TH2D* link1 = helper.getScanData(1);
00047     out << (link0->GetNbinsX()+2)*(link0->GetNbinsY()+2);   //Note, size is number in 1 link ie no bins * no points
00048     out << SR_DT_ROOTHIST << SR_WD_64;
00049     //cout << "Raw.getDataType() is " << raw.getDataType() << endl;
00050     // ROOTDATA-specific stuff:
00051     out << raw.getDataType();
00052     out.put ( link0->GetArray(), (link0->GetNbinsX()+2)*(link0->GetNbinsY()+2) );
00053     out.put ( link1->GetArray(), (link1->GetNbinsX()+2)*(link1->GetNbinsY()+2) );
00054 
00055     unsigned nOcc = raw.nOccupancyPerEvent();
00056     out << (unsigned) nOcc;
00057     for (unsigned iOcc=0; iOcc<nOcc; ++iOcc){
00058       shared_ptr<TH2D> occ = helper.getOccupancyPerEvent(iOcc);
00059       if (occ.get()==0) {
00060     ostringstream oss;
00061     oss << "No occupancy histogram for chip" << iOcc << " of " << nOcc;
00062     throw LogicError(oss.str(), __FILE__, __LINE__ );
00063       } 
00064       out.put( occ->GetArray(), (occ->GetNbinsX()+2)*(occ->GetNbinsY()+2) );
00065     }
00066 }
00067 
00068 void RawScanResultStreamer_v3::read(IStream& in, Streamable& ob, const IOManager& manager) const {
00069     manager.readImpl(in, ob, "SctData::ScanResult");
00070 
00071     RawScanResult& raw = dynamic_cast<RawScanResult&>(ob);
00072     helper.set(raw);
00073 
00074     //cout <<"Parent finished" << endl;
00075     //cout << raw.getHeader().getRunNumber() << "  " << raw.getHeader().getScanNumber()
00076     //     << "  " << raw.getHeader().getModuleName() << endl;
00077 
00078     //Now refresh and fill the data
00079     readData(in, raw);
00080     
00081     //cout <<"Done" << endl;
00082 }
00083 
00084 
00085 void RawScanResultStreamer_v3::setHistSize(RawScanResult& raw, unsigned nbinsx, short unsigned ilink) const{
00087   // check its not already the right size!
00088   if ( helper.getScanData(ilink) && (unsigned) helper.getScanData(ilink)->GetNbinsX()==nbinsx ) return;
00089 
00090   //Create hists
00091   double* bins = raw.getPoints().getEdgesAscending();
00092   ostringstream name; name << (string)raw.getUniqueID() << "_link" << ilink;
00093   auto_ptr<TH2D> link_hist (new TH2D(name.str().c_str(), name.str().c_str(), nbinsx, -0.5, nbinsx-0.5,
00094                      raw.getPoints().getNPoints(), bins));
00095   
00096   delete [] bins;
00097   
00098   link_hist->SetEntries(1);
00099   helper.setScanData(ilink, link_hist);
00100 }
00101 
00102 void RawScanResultStreamer_v3::readData(IStream& in, RawScanResult& raw) const {
00103     unsigned int size;
00104     unsigned short type;
00105     unsigned short width;
00106     in >> size >> type >> width;
00107     helper.setDataType(type);
00108 
00109     switch (type) {
00110     case SR_DT_SLICE:
00111         readSliceData(size, width, in, raw);
00112         return;
00113     case SR_DT_ROOTHIST:
00114         readRootData(size, width, in, raw);
00115         return;
00116     case SR_DT_RAWHIST:
00117         readRawData(size, width, in, raw);
00118         return;
00119     default:
00120     ostringstream oss;
00121     oss << "RawScanResultIS::refreshData Unknown data format: " << type << " size was: " << size;
00122         throw VersionNotSupportedException(oss.str(), __FILE__, __LINE__); 
00123     }
00124 }
00125 
00126 void RawScanResultStreamer_v3::readRootData(unsigned int isize, unsigned short width, IStream& in, RawScanResult& raw) const {
00127 
00128   unsigned short original_type;
00129   in >> original_type;
00130   helper.setDataType(original_type);
00131 
00132     for (unsigned ilink=0; ilink<2; ++ilink){
00133       double* data;
00134       unsigned int size = 0;
00135       in.get(&data, size);    
00136       
00137       unsigned size_y= raw.getPoints().getNPoints() + 2 ;
00138       if (size % size_y !=0 ) {
00139     ostringstream oss;
00140     oss << "RawScanResultIS::readRootData.  Link " << ilink << " size = " << size << ", not divisible by " << size_y;
00141     throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00142       }
00143       unsigned size_x=size/size_y;
00144       if (size_x<=1){
00145     ostringstream oss;
00146     oss << "X-size of root data must be 2 or greater! Got "<< size_x;
00147     throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00148       }
00149       setHistSize(raw, size_x-2, ilink);
00150       for (unsigned int i=0; i<size; ++i) {
00151         helper.getScanData(ilink)->SetBinContent(i, data[i]);
00152       }
00153       delete [] data;
00154     }
00155 
00156     unsigned nOcc = 0;  in >> nOcc;
00157     helper.setNumberOccupancyHists(nOcc);
00158     for (unsigned iOcc=0; iOcc<nOcc; ++iOcc){
00159       createOccupancyHistogram(helper, raw, iOcc);
00160       shared_ptr<TH2D> occ = helper.getOccupancyPerEvent(iOcc);
00161       if (!occ.get()) throw LogicError("Failed to create occupancy histogram", __FILE__, __LINE__);
00162       double* occ_data;
00163       unsigned int size = 0;
00164       in.get(&occ_data, size);
00165       
00166       const unsigned expectedSize=(occ->GetNbinsX()+2)*(occ->GetNbinsY()+2);
00167 
00168       if ( size!= expectedSize ){
00169     ostringstream oss;
00170     oss << "Occupancy Histogram data size was " << size
00171         << " expected " << expectedSize << " (Chip " << iOcc<<")";
00172     throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00173       }
00174       for (unsigned ibin=0; ibin<size; ++ibin){
00175     occ->SetBinContent(ibin, occ_data[ibin]);
00176       }
00177       delete [] occ_data;
00178     }
00179 }
00180 
00181 void RawScanResultStreamer_v3::readRawData(unsigned int isize, unsigned short width, IStream& in, RawScanResult& raw) const {
00182   int npoints = raw.getPoints().getNPoints();
00183   unsigned wid_mult = width==SR_WD_16 ? 1 : width==SR_WD_32 ? 2 : width==SR_WD_64 ? 4 : 0;
00184   unsigned quotient = npoints * wid_mult;
00185   if (quotient==0 || isize % quotient != 0) {
00186     ostringstream oss; oss << "Data size  = " << isize << " but trying to divide by " << quotient;
00187     throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00188   } 
00189   unsigned x_size = isize / quotient;
00190 
00191   for (unsigned ilink=0; ilink<2; ++ilink){
00192     setHistSize(raw, x_size, ilink);
00193   }
00194   
00195   TH2D* link0 = helper.getScanData(0);
00196   TH2D* link1 = helper.getScanData(1);
00197 
00198   unsigned size=0;
00199   bool ascending=raw.getPoints().ascending();
00200   switch (width) {
00201   case SR_WD_16:{
00202     UINT16* data = 0;
00203     in.get(&data, size);
00204     if (size!=isize){
00205       ostringstream oss; oss << "Size (" << size << ") dosent match header size(" << isize << ")";
00206       throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00207     }
00208     for (int j=0; j<npoints; ++j) {
00209       int ipt=ascending ? j : npoints-j-1;
00210       for (unsigned int i=0; i<x_size; ++i) {
00211     //+1 because bin 0 is underflow
00212     link0->SetBinContent(link0->GetBin(i+1,j+1), data[ipt*x_size*2 + i]);
00213     link1->SetBinContent(link1->GetBin(i+1,j+1), data[ipt*x_size*2 + i+x_size]);
00214       }
00215     }
00216     delete[] data; return;
00217   }
00218   case SR_WD_32: {
00219     UINT32* data = 0;
00220     in.get(&data, size);
00221     if (size!=isize){
00222       ostringstream oss; oss << "Size (" << size << ") dosent match header size(" << isize << ")";
00223       throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00224     }
00225     for (int j=0; j<npoints; ++j) {
00226       int ipt=ascending ? j : npoints-j-1;
00227       for (unsigned int i=0; i<x_size; ++i) {
00228     //+1 because bin 0 is underflow
00229     link0->SetBinContent(link0->GetBin(i+1,j+1), data[ipt*x_size*2 + i]);
00230     link1->SetBinContent(link1->GetBin(i+1,j+1), data[ipt*x_size*2 + i+x_size]);
00231       }
00232     }
00233     delete[] data; return;
00234   }
00235   default : {
00236     ostringstream oss; oss << "Dont know how to interpret data of width " << width;
00237     throw UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00238   }
00239   }
00240 }
00241 
00242 void RawScanResultStreamer_v3::readSliceData(unsigned int isize, unsigned short width, IStream& in, RawScanResult& raw) const {
00243     int npoints = raw.getPoints().getNPoints();
00244     unsigned expectedSize=2048u * npoints;
00245 
00246     //cout << width << endl;
00247     if (isize != expectedSize) 
00248     throw StreamCorruptedException("RawScanResultIS::readSliceData. Expected and header sizes not equal.  Expected: " + lexical_cast<string>(expectedSize) + 
00249                        " but header: " + lexical_cast<string>(isize), __FILE__, __LINE__);
00250     
00251     setHistSize(raw, nChannelLink, 0);
00252     setHistSize(raw, nChannelLink, 1);
00253     
00254     TH2D* link0 = helper.getScanData(0);
00255     TH2D* link1 = helper.getScanData(1);
00256     unsigned int size = 0;
00257     bool ascending=raw.getPoints().ascending();
00258 
00259     UINT32* data = 0; // standard data type to convert to...
00260 
00261     // copy or reinterpret data as correct size:
00262     switch (width) {
00263       //------------------------------------------------------------------------
00264     case SR_WD_16:{
00265       UINT16* data16;
00266       in.get(&data16, size);
00267       data=new UINT32[size];
00268       for (unsigned i=0; i<size; ++i){
00269         data[i]=data16[i];  // copy
00270       }
00271       delete[] data16;
00272       break;
00273     }
00274     case SR_WD_32: {
00275       in.get(&data, size);
00276       break;
00277     }
00278     default : {
00279       ostringstream oss; oss << "Dont know how to interpret data of width " << width;
00280       throw UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00281     }
00282     } // end of switch
00283     
00284     if (size != expectedSize){
00285       delete[] data;
00286       ostringstream msg;
00287       msg << "RawScanResultIS::readSliceData. Expected and actual sizes not equal.  Expected: "
00288       << expectedSize << " but actual: "
00289       << size << "; (DataWidth="<<width<<")";
00290       throw StreamCorruptedException(msg.str(), __FILE__, __LINE__);
00291     }
00292     
00293     for (int j=0; j<npoints; ++j) {
00294       int ipt=ascending ? j : npoints-j-1;
00295       for (unsigned int i=0; i<nChannelLink; ++i) {
00296     //+1 because 5in 0 is underflow
00297     link0->SetBinContent(link0->GetBin(i+1,j+1), data[ipt*2048 + i]);
00298     link1->SetBinContent(link1->GetBin(i+1,j+1), data[ipt*2048 + i+1024]);
00299       }
00300     }
00301     // Also get Occupancy histogram information from the 
00302     // memory location where the absent chips "6,7", "14,15" would be
00303     try{
00304       helper.setNumberOccupancyHists(nChipModule);
00305       for (unsigned ichip=0; ichip<nChipModule; ++ichip){
00306     createOccupancyHistogram(helper, raw, ichip);
00307     shared_ptr<TH2D> occ = helper.getOccupancyPerEvent(ichip);
00308     if (occ.get()==0) {
00309       ostringstream oss;
00310       oss << "Occupancy histogram does not exist, module"
00311           << raw.getHeader().getModuleName() << " chip " << ichip << endl;
00312       throw LogicError(oss.str(), __FILE__, __LINE__);
00313     } 
00314     // loop over scan points
00315     for (int j=0; j<npoints; ++j) {
00316       int ipt=ascending ? j : npoints-j-1;
00317           // calculate empty events from number of events - number of events with any data
00318       // loop over histogram bins
00319           double empty_events= raw.getPoints().getNEvents(ipt);
00320       for (int ibin=1; ibin<occ->GetNbinsX(); ++ibin){
00321         unsigned word = getOccWordPosition(ichip, ibin-1, ipt);
00322         occ->SetBinContent(ibin+1, j+1, data[word]);
00323             empty_events-=data[word];
00324       }
00325       occ->SetBinContent(1, j+1, empty_events);
00326     }
00327     occ->SetEntries(1);
00328       }
00329     }catch(Sct::LogicError& e){
00330       e.sendToMrs();
00331     }
00332     delete[] data;
00333   }
00334 
00335   void RawScanResultStreamer_v3::createOccupancyHistogram(const RawScanResultIOHelper& helper, const RawScanResult& raw, unsigned ichip){
00336 
00337     // name
00338     std::ostringstream oss;
00339     oss << raw.getHeader().getModuleName() << "_OccEvent_Chip_" << ichip;
00340     const char* name=oss.str().c_str();
00341 
00342     // xbins
00343     const unsigned nEdgesX=1+128/4 + 1;
00344     Double_t edgesX[nEdgesX];
00345     edgesX[0] = -0.5;
00346     edgesX[1] =  0.5;
00347     for(int i=2; i<nEdgesX; i++) {
00348       edgesX[i] = (i-1)*4+0.5;
00349     }
00350 
00351     // ybins
00352     const SctData::ScanPoints& points = raw.getPoints();
00353     const double* edgesY = points.getEdgesAscending();
00354 
00355     // create
00356     auto_ptr<TH2D> occ ( new TH2D(name, name, nEdgesX-1, edgesX, points.getNPoints(), edgesY) );
00357     
00358     // axis titles
00359     occ->SetXTitle("Channel count");
00360     occ->SetYTitle(raw.getHeader().getVariable().getVariableName().c_str());
00361     
00362     // clean up
00363     delete[] edgesY;
00364 
00365     // check
00366     if (!occ.get()) {
00367       throw LogicError("Could not make occupancy histogram", __FILE__, __LINE__);
00368     }
00369 
00370     // set
00371     helper.setOccupancyPerEvent(ichip, occ);
00372   }
00373 
00375   unsigned RawScanResultStreamer_v3::getOccWordPosition(unsigned ichip, unsigned ibin, unsigned ipt){
00376     return 128*6                                     // skip 6 chips worth of data
00377       + (ichip/6)*1024                               // + offset for link
00378       + (ichip%6)*32                                 // + start of chip 
00379       + ibin                                         // + bin
00380       + 2048 * ipt;                                  // + offset for data point
00381   }
00382 
00383 }
00384 }

Generated on Mon Feb 6 14:01:25 2006 for SCT DAQ/DCS Software - C++ by  doxygen 1.4.6