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
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
00041 const RawScanResult& raw = dynamic_cast<const RawScanResult&>(ob);
00042 helper.set(raw);
00043
00044
00045 TH2D* link0 = helper.getScanData(0);
00046 TH2D* link1 = helper.getScanData(1);
00047 out << (link0->GetNbinsX()+2)*(link0->GetNbinsY()+2);
00048 out << SR_DT_ROOTHIST << SR_WD_64;
00049
00050
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
00075
00076
00077
00078
00079 readData(in, raw);
00080
00081
00082 }
00083
00084
00085 void RawScanResultStreamer_v3::setHistSize(RawScanResult& raw, unsigned nbinsx, short unsigned ilink) const{
00087
00088 if ( helper.getScanData(ilink) && (unsigned) helper.getScanData(ilink)->GetNbinsX()==nbinsx ) return;
00089
00090
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
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
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
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;
00260
00261
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];
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 }
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
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
00302
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
00315 for (int j=0; j<npoints; ++j) {
00316 int ipt=ascending ? j : npoints-j-1;
00317
00318
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
00338 std::ostringstream oss;
00339 oss << raw.getHeader().getModuleName() << "_OccEvent_Chip_" << ichip;
00340 const char* name=oss.str().c_str();
00341
00342
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
00352 const SctData::ScanPoints& points = raw.getPoints();
00353 const double* edgesY = points.getEdgesAscending();
00354
00355
00356 auto_ptr<TH2D> occ ( new TH2D(name, name, nEdgesX-1, edgesX, points.getNPoints(), edgesY) );
00357
00358
00359 occ->SetXTitle("Channel count");
00360 occ->SetYTitle(raw.getHeader().getVariable().getVariableName().c_str());
00361
00362
00363 delete[] edgesY;
00364
00365
00366 if (!occ.get()) {
00367 throw LogicError("Could not make occupancy histogram", __FILE__, __LINE__);
00368 }
00369
00370
00371 helper.setOccupancyPerEvent(ichip, occ);
00372 }
00373
00375 unsigned RawScanResultStreamer_v3::getOccWordPosition(unsigned ichip, unsigned ibin, unsigned ipt){
00376 return 128*6
00377 + (ichip/6)*1024
00378 + (ichip%6)*32
00379 + ibin
00380 + 2048 * ipt;
00381 }
00382
00383 }
00384 }