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
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
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
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
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 UINT32* data = 0;
00262
00263
00264 switch (width) {
00265
00266 case SR_WD_16:{
00267 UINT16* data16;
00268 in.get(&data16, size);
00269 data=new UINT32[size];
00270 for (unsigned i=0; i<size; ++i){
00271 data[i]=data16[i];
00272 }
00273 delete[] data16;
00274 break;
00275 }
00276 case SR_WD_32: {
00277 in.get(&data, size);
00278 break;
00279 }
00280 default : {
00281 ostringstream oss; oss << "Dont know how to interpret data of width " << width;
00282 throw UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00283 }
00284 }
00285
00286 if (size != expectedSize){
00287 delete[] data;
00288 ostringstream msg;
00289 msg << "RawScanResultIS::readSliceData. Expected and actual sizes not equal. Expected: "
00290 << expectedSize << " but actual: "
00291 << size << "; (DataWidth="<<width<<")";
00292 throw StreamCorruptedException(msg.str(), __FILE__, __LINE__);
00293 }
00294
00295 for (int j=0; j<npoints; ++j) {
00296 int ipt=ascending ? j : npoints-j-1;
00297 for (unsigned int i=0; i<nChannelLink; ++i) {
00298
00299 link0->SetBinContent(link0->GetBin(i+1,j+1), data[ipt*2048 + i]);
00300 link1->SetBinContent(link1->GetBin(i+1,j+1), data[ipt*2048 + i+1024]);
00301 }
00302 }
00303
00304
00305 try{
00306 helper.setNumberOccupancyHists(nChipModule);
00307 for (unsigned ichip=0; ichip<nChipModule; ++ichip){
00308 createOccupancyHistogram(helper, raw, ichip);
00309 shared_ptr<TH2D> occ = helper.getOccupancyPerEvent(ichip);
00310 if (occ.get()==0) {
00311 ostringstream oss;
00312 oss << "Occupancy histogram does not exist, module"
00313 << raw.getHeader().getModuleName() << " chip " << ichip << endl;
00314 throw LogicError(oss.str(), __FILE__, __LINE__);
00315 }
00316
00317 for (int j=0; j<npoints; ++j) {
00318 int ipt=ascending ? j : npoints-j-1;
00319
00320
00321 double empty_events= raw.getPoints().getNEvents(ipt);
00322 for (int ibin=1; ibin<occ->GetNbinsX(); ++ibin){
00323 unsigned word = getOccWordPosition(ichip, ibin-1, ipt);
00324 occ->SetBinContent(ibin+1, j+1, data[word]);
00325 empty_events-=data[word];
00326 }
00327 occ->SetBinContent(1, j+1, empty_events);
00328 }
00329 occ->SetEntries(1);
00330 }
00331 }catch(Sct::LogicError& e){
00332 std::cout << "Occupancy per event data " << raw.getHeader().getUniqueID() << std::endl;
00333 std::cout << e.what() << std::endl;
00334 e.sendToMrs();
00335 }
00336 delete[] data;
00337 }
00338
00339 void RawScanResultStreamer_v3::createOccupancyHistogram(const RawScanResultIOHelper& helper, const RawScanResult& raw, unsigned ichip){
00340
00341
00342 std::ostringstream oss;
00343 oss << raw.getHeader().getModuleName() << "_OccEvent_Chip_" << ichip;
00344 const char* name=oss.str().c_str();
00345
00346
00347 const unsigned nEdgesX=1+128/4 + 1;
00348 Double_t edgesX[nEdgesX];
00349 edgesX[0] = -0.5;
00350 edgesX[1] = 0.5;
00351 for(int i=2; i<nEdgesX; i++) {
00352 edgesX[i] = (i-1)*4+0.5;
00353 }
00354
00355
00356 const SctData::ScanPoints& points = raw.getPoints();
00357 const double* edgesY = points.getEdgesAscending();
00358
00359
00360 auto_ptr<TH2D> occ ( new TH2D(name, name, nEdgesX-1, edgesX, points.getNPoints(), edgesY) );
00361
00362
00363 occ->SetXTitle("Channel count");
00364 occ->SetYTitle(raw.getHeader().getVariable().getVariableName().c_str());
00365
00366
00367 delete[] edgesY;
00368
00369
00370 if (!occ.get()) {
00371 throw LogicError("Could not make occupancy histogram", __FILE__, __LINE__);
00372 }
00373
00374
00375 helper.setOccupancyPerEvent(ichip, occ);
00376 }
00377
00379 unsigned RawScanResultStreamer_v3::getOccWordPosition(unsigned ichip, unsigned ibin, unsigned ipt){
00380 return 128*6
00381 + (ichip/6)*1024
00382 + (ichip%6)*32
00383 + ibin
00384 + 2048 * ipt;
00385 }
00386
00387 }
00388 }