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 typedef unsigned DATA_TYPE;
00262 DATA_TYPE* data;
00263 bool data_needs_deleted=false;
00264
00265
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);
00273 }else{
00274
00275
00276 data_needs_deleted=true;
00277 data=new DATA_TYPE[size];
00278 for (unsigned i=0; i<size; ++i){
00279 data[i]=data16[i];
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
00291
00292 data_needs_deleted=true;
00293 data=new DATA_TYPE[size];
00294 for (unsigned i=0; i<size; ++i){
00295 data[i]=data32[i];
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
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
00322
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
00335 for (int j=0; j<npoints; ++j) {
00336 int ipt=ascending ? j : npoints-j-1;
00337
00338
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
00360 std::ostringstream oss;
00361 oss << raw.getHeader().getModuleName() << "_OccEvent_Chip_" << ichip;
00362 const char* name=oss.str().c_str();
00363
00364
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
00374 const SctData::ScanPoints& points = raw.getPoints();
00375 const double* edgesY = points.getEdgesAscending();
00376
00377
00378 auto_ptr<TH2D> occ ( new TH2D(name, name, nEdgesX-1, edgesX, points.getNPoints(), edgesY) );
00379
00380
00381 occ->SetXTitle("Channel count");
00382 occ->SetYTitle(raw.getHeader().getVariable().getVariableName().c_str());
00383
00384
00385 delete[] edgesY;
00386
00387
00388 if (!occ.get()) {
00389 throw LogicError("Could not make occupancy histogram", __FILE__, __LINE__);
00390 }
00391
00392
00393 helper.setOccupancyPerEvent(ichip, occ);
00394 }
00395
00397 unsigned RawScanResultStreamer_v3::getOccWordPosition(unsigned ichip, unsigned ibin, unsigned ipt){
00398 return 128*6
00399 + (ichip/6)*1024
00400 + (ichip%6)*32
00401 + ibin
00402 + 2048 * ipt;
00403 }
00404
00405 }
00406 }