Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Related Pages

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   
00093   ostringstream name; name << raw.getUniqueID() << "_link" << ilink;
00094   auto_ptr<TH2D> link_hist (new TH2D(name.str().c_str(), name.str().c_str(), nbinsx, -0.5, nbinsx-0.5,
00095                      raw.getPoints().getNPoints(), bins));
00096   
00097   delete [] bins;
00098   
00099   link_hist->SetEntries(1);
00100   helper.setScanData(ilink, link_hist);
00101 }
00102 
00103 void RawScanResultStreamer_v3::readData(IStream& in, RawScanResult& raw) const {
00104     unsigned int size;
00105     unsigned short type;
00106     unsigned short width;
00107     in >> size >> type >> width;
00108     helper.setDataType(type);
00109 
00110     switch (type) {
00111     case SR_DT_SLICE:
00112         readSliceData(size, width, in, raw);
00113         return;
00114     case SR_DT_ROOTHIST:
00115         readRootData(size, width, in, raw);
00116         return;
00117     case SR_DT_RAWHIST:
00118         readRawData(size, width, in, raw);
00119         return;
00120     default:
00121     ostringstream oss;
00122     oss << "RawScanResultIS::refreshData Unknown data format: " << type << " size was: " << size;
00123         throw VersionNotSupportedException(oss.str(), __FILE__, __LINE__); 
00124     }
00125 }
00126 
00127 void RawScanResultStreamer_v3::readRootData(unsigned int isize, unsigned short width, IStream& in, RawScanResult& raw) const {
00128 
00129   unsigned short original_type;
00130   in >> original_type;
00131   helper.setDataType(original_type);
00132 
00133     for (unsigned ilink=0; ilink<2; ++ilink){
00134       double* data;
00135       unsigned int size = 0;
00136       in.get(&data, size);    
00137       
00138       unsigned size_y= raw.getPoints().getNPoints() + 2 ;
00139       if (size % size_y !=0 ) {
00140     ostringstream oss;
00141     oss << "RawScanResultIS::readRootData.  Link " << ilink << " size = " << size << ", not divisible by " << size_y;
00142     throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00143       }
00144       unsigned size_x=size/size_y;
00145       if (size_x<=1){
00146     ostringstream oss;
00147     oss << "X-size of root data must be 2 or greater! Got "<< size_x;
00148     throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00149       }
00150       setHistSize(raw, size_x-2, ilink);
00152       for (unsigned int i=0; i<size; ++i) {
00153         helper.getScanData(ilink)->SetBinContent(i, data[i]);
00154       }
00155       delete [] data;
00156     }
00157 
00158     unsigned nOcc = 0;  in >> nOcc;
00159     helper.setNumberOccupancyHists(nOcc);
00160     for (unsigned iOcc=0; iOcc<nOcc; ++iOcc){
00161       createOccupancyHistogram(helper, raw, iOcc);
00162       shared_ptr<TH2D> occ = helper.getOccupancyPerEvent(iOcc);
00163       if (!occ.get()) throw LogicError("Failed to create occupancy histogram", __FILE__, __LINE__);
00164       double* occ_data;
00165       unsigned int size = 0;
00166       in.get(&occ_data, size);
00167       
00168       const unsigned expectedSize=(occ->GetNbinsX()+2)*(occ->GetNbinsY()+2);
00169 
00170       if ( size!= expectedSize ){
00171     ostringstream oss;
00172     oss << "Occupancy Histogram data size was " << size
00173         << " expected " << expectedSize << " (Chip " << iOcc<<")";
00174     throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00175       }
00176       for (unsigned ibin=0; ibin<size; ++ibin){
00177     occ->SetBinContent(ibin, occ_data[ibin]);
00178       }
00179       delete [] occ_data;
00180     }
00181 }
00182 
00183 void RawScanResultStreamer_v3::readRawData(unsigned int isize, unsigned short width, IStream& in, RawScanResult& raw) const {
00184   int npoints = raw.getPoints().getNPoints();
00185   unsigned wid_mult = width==SR_WD_16 ? 1 : width==SR_WD_32 ? 2 : width==SR_WD_64 ? 4 : 0;
00186   unsigned quotient = npoints * wid_mult;
00187   if (quotient==0 || isize % quotient != 0) {
00188     ostringstream oss; oss << "Data size  = " << isize << " but trying to divide by " << quotient;
00189     throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00190   } 
00191   unsigned x_size = isize / quotient;
00192 
00193   for (unsigned ilink=0; ilink<2; ++ilink){
00194     setHistSize(raw, x_size, ilink);
00195   }
00196   
00197   TH2D* link0 = helper.getScanData(0);
00198   TH2D* link1 = helper.getScanData(1);
00199 
00200   unsigned size=0;
00201   bool ascending=raw.getPoints().ascending();
00202   switch (width) {
00203   case SR_WD_16:{
00204     UINT16* data = 0;
00205     in.get(&data, size);
00206     if (size!=isize){
00207       ostringstream oss; oss << "Size (" << size << ") dosent match header size(" << isize << ")";
00208       throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00209     }
00210     for (int j=0; j<npoints; ++j) {
00211       int ipt=ascending ? j : npoints-j-1;
00212       for (unsigned int i=0; i<x_size; ++i) {
00213     //+1 because bin 0 is underflow
00214     link0->SetBinContent(link0->GetBin(i+1,j+1), data[ipt*x_size*2 + i]);
00215     link1->SetBinContent(link1->GetBin(i+1,j+1), data[ipt*x_size*2 + i+x_size]);
00216       }
00217     }
00218     delete[] data; return;
00219   }
00220   case SR_WD_32: {
00221     UINT32* data = 0;
00222     in.get(&data, size);
00223     if (size!=isize){
00224       ostringstream oss; oss << "Size (" << size << ") dosent match header size(" << isize << ")";
00225       throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00226     }
00227     for (int j=0; j<npoints; ++j) {
00228       int ipt=ascending ? j : npoints-j-1;
00229       for (unsigned int i=0; i<x_size; ++i) {
00230     //+1 because bin 0 is underflow
00231     link0->SetBinContent(link0->GetBin(i+1,j+1), data[ipt*x_size*2 + i]);
00232     link1->SetBinContent(link1->GetBin(i+1,j+1), data[ipt*x_size*2 + i+x_size]);
00233       }
00234     }
00235     delete[] data; return;
00236   }
00237   default : {
00238     ostringstream oss; oss << "Dont know how to interpret data of width " << width;
00239     throw UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00240   }
00241   }
00242 }
00243 
00244 void RawScanResultStreamer_v3::readSliceData(unsigned int isize, unsigned short width, IStream& in, RawScanResult& raw) const {
00245     int npoints = raw.getPoints().getNPoints();
00246     unsigned expectedSize=2048u * npoints;
00247 
00248     //cout << width << endl;
00249     if (isize != expectedSize) 
00250     throw StreamCorruptedException("RawScanResultIS::readSliceData. Expected and header sizes not equal.  Expected: " + lexical_cast<string>(expectedSize) + 
00251                        " but header: " + lexical_cast<string>(isize), __FILE__, __LINE__);
00252     
00253     setHistSize(raw, nChannelLink, 0);
00254     setHistSize(raw, nChannelLink, 1);
00255     
00256     TH2D* link0 = helper.getScanData(0);
00257     TH2D* link1 = helper.getScanData(1);
00258     unsigned int size = 0;
00259     bool ascending=raw.getPoints().ascending();
00260 
00261     typedef unsigned DATA_TYPE;
00262     DATA_TYPE* data; // standard data type to convert to...
00263     bool data_needs_deleted=false;
00264 
00265     // copy or reinterpret data as correct size:
00266     switch (width) {
00267       //------------------------------------------------------------------------
00268     case SR_WD_16:{
00269       UINT16* data16 = 0;
00270       in.get(&data16, size);
00271       if (sizeof(DATA_TYPE)==sizeof(UINT16)){
00272     data=reinterpret_cast<DATA_TYPE*>(data16);   // move ptr
00273       }else{
00274     //  std::cout << "RawScanResultStreamer_v3 Data size " << sizeof(DATA_TYPE)
00275     //        << "(trial) vs actual " << sizeof(UINT16)<< " -> copy16" << std::endl; 
00276     data_needs_deleted=true;
00277     data=new DATA_TYPE[size];
00278     for (unsigned i=0; i<size; ++i){
00279       data[i]=data16[i];  // copy
00280     }
00281       }
00282       break;
00283     }
00284     case SR_WD_32: {
00285       UINT32* data32 = 0;
00286       in.get(&data32, size);
00287       if (sizeof(DATA_TYPE)==sizeof(UINT32)){
00288     data=reinterpret_cast<DATA_TYPE*>(data32);
00289       }else{
00290     //std::cout << "RawScanResultStreamer_v3 Data size " << sizeof(DATA_TYPE)
00291     //    << "(trial) vs actual " << sizeof(UINT32)<< " -> copy32" << std::endl; 
00292     data_needs_deleted=true;
00293     data=new DATA_TYPE[size];
00294     for (unsigned i=0; i<size; ++i){
00295       data[i]=data32[i];  // copy
00296     }
00297       }
00298       break;
00299     }
00300     default : {
00301       ostringstream oss; oss << "Dont know how to interpret data of width " << width;
00302       throw UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00303     }
00304     }
00305     if (size != expectedSize){
00306       ostringstream msg;
00307       msg << "RawScanResultIS::readSliceData. Expected and actual sizes not equal.  Expected: "
00308       << expectedSize << " but actual: "
00309       << size << "; (DataWidth="<<width<<")";
00310       throw StreamCorruptedException(msg.str(), __FILE__, __LINE__);
00311     }
00312     
00313     for (int j=0; j<npoints; ++j) {
00314       int ipt=ascending ? j : npoints-j-1;
00315       for (unsigned int i=0; i<nChannelLink; ++i) {
00316     //+1 because 5in 0 is underflow
00317     link0->SetBinContent(link0->GetBin(i+1,j+1), data[ipt*2048 + i]);
00318     link1->SetBinContent(link1->GetBin(i+1,j+1), data[ipt*2048 + i+1024]);
00319       }
00320     }
00321     // Also get Occupancy histogram information from the 
00322     // memory location where the absent chips "6,7", "14,15" would be
00323     try{
00324       helper.setNumberOccupancyHists(nChipModule);
00325       for (unsigned ichip=0; ichip<nChipModule; ++ichip){
00326     createOccupancyHistogram(helper, raw, ichip);
00327     shared_ptr<TH2D> occ = helper.getOccupancyPerEvent(ichip);
00328     if (occ.get()==0) {
00329       ostringstream oss;
00330       oss << "Occupancy histogram does not exist, module"
00331           << raw.getHeader().getModuleName() << " chip " << ichip << endl;
00332       throw LogicError(oss.str(), __FILE__, __LINE__);
00333     } 
00334     // loop over scan points
00335     for (int j=0; j<npoints; ++j) {
00336       int ipt=ascending ? j : npoints-j-1;
00337           // calculate empty events from number of events - number of events with any data
00338       // loop over histogram bins
00339           double empty_events= raw.getPoints().getNEvents(ipt);
00340       for (int ibin=1; ibin<occ->GetNbinsX(); ++ibin){
00341         unsigned word = getOccWordPosition(ichip, ibin-1, ipt);
00342         occ->SetBinContent(ibin+1, j+1, data[word]);
00343             empty_events-=data[word];
00344       }
00345       occ->SetBinContent(1, j+1, empty_events);
00346     }
00347     occ->SetEntries(1);
00348       }
00349     }catch(Sct::LogicError& e){
00350       std::cout << "Occupancy per event data " << raw.getHeader().getUniqueID() << std::endl;
00351       std::cout << e.what() << std::endl;
00352       e.sendToMrs();
00353     }
00354     if (data_needs_deleted) delete[] data;
00355 }
00356 
00357   void RawScanResultStreamer_v3::createOccupancyHistogram(const RawScanResultIOHelper& helper, const RawScanResult& raw, unsigned ichip){
00358 
00359     // name
00360     std::ostringstream oss;
00361     oss << raw.getHeader().getModuleName() << "_OccEvent_Chip_" << ichip;
00362     const char* name=oss.str().c_str();
00363 
00364     // xbins
00365     const unsigned nEdgesX=1+128/4 + 1;
00366     Double_t edgesX[nEdgesX];
00367     edgesX[0] = -0.5;
00368     edgesX[1] =  0.5;
00369     for(int i=2; i<nEdgesX; i++) {
00370       edgesX[i] = (i-1)*4+0.5;
00371     }
00372 
00373     // ybins
00374     const SctData::ScanPoints& points = raw.getPoints();
00375     const double* edgesY = points.getEdgesAscending();
00376 
00377     // create
00378     auto_ptr<TH2D> occ ( new TH2D(name, name, nEdgesX-1, edgesX, points.getNPoints(), edgesY) );
00379     
00380     // axis titles
00381     occ->SetXTitle("Channel count");
00382     occ->SetYTitle(raw.getHeader().getVariable().getVariableName().c_str());
00383     
00384     // clean up
00385     delete[] edgesY;
00386 
00387     // check
00388     if (!occ.get()) {
00389       throw LogicError("Could not make occupancy histogram", __FILE__, __LINE__);
00390     }
00391 
00392     // set
00393     helper.setOccupancyPerEvent(ichip, occ);
00394   }
00395 
00397   unsigned RawScanResultStreamer_v3::getOccWordPosition(unsigned ichip, unsigned ibin, unsigned ipt){
00398     return 128*6                                     // skip 6 chips worth of data
00399       + (ichip/6)*1024                               // + offset for link
00400       + (ichip%6)*32                                 // + start of chip 
00401       + ibin                                         // + bin
00402       + 2048 * ipt;                                  // + offset for data point
00403   }
00404 
00405 }
00406 }

Generated on Sat Jul 31 14:18:10 2004 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5