00001 #define ROOTHISTCNV_RCWNTUPLECNV_CPP
00002
00003 #define ALLOW_ALL_TYPES
00004
00005
00006 #include <cstdio>
00007
00008
00009 #include "GaudiKernel/xtoa.h"
00010 #include "GaudiKernel/CnvFactory.h"
00011 #include "GaudiKernel/INTupleSvc.h"
00012
00013 #include "GaudiKernel/MsgStream.h"
00014 #include "GaudiKernel/NTuple.h"
00015
00016 #include "RCWNTupleCnv.h"
00017
00018 #include "TTree.h"
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 static CnvFactory<RootHistCnv::RCWNTupleCnv> s_factory;
00031 const ICnvFactory& RootHistRCWNTupleCnvFactory = s_factory;
00032
00033
00035 StatusCode RootHistCnv::RCWNTupleCnv::declare(long , INTuple* ) {
00036 MsgStream log(msgSvc(), "RCWNTupleCnv");
00037
00038
00039 return StatusCode::FAILURE;
00040 }
00041
00042
00043
00044 template <class T> void analyzeItem(std::string typ,
00045 const NTuple::_Data<T>* it,
00046 std::string& desc,
00047 std::string& block_name,
00048 long& size) {
00049
00050 std::string full_name, var_name;
00051 full_name = it->name();
00052 RootHistCnv::parseName(full_name,block_name,var_name);
00053
00054 long item_size = (sizeof(T) < 4) ? 4 : sizeof(T);
00055 long dimension = it->length();
00056 long ndim = it->ndim()-1;
00057 char text[132];
00058 desc += var_name;
00059 if ( it->hasIndex() || it->length() > 1 ) {
00060 desc += "[";
00061 }
00062 for ( int i = 0; i < ndim; i++ ) {
00063 desc += ::_itoa(it->dim(i), text, 10);
00064 desc += "][";
00065 }
00066 if ( it->hasIndex() ) {
00067 std::string ind_blk, ind_var;
00068 std::string ind = it->index();
00069 RootHistCnv::parseName(ind,ind_blk,ind_var);
00070 if (ind_blk != block_name) {
00071 std::cerr << "ERROR: Index for CWNT variable " << ind_var
00072 << " is in a differnt block: " << ind_blk << std::endl;
00073 }
00074 desc += ind_var;
00075 }
00076 else if ( it->dim(ndim) > 1 ) {
00077 desc += ::_itoa(it->dim(ndim), text, 10);
00078 }
00079
00080 if ( it->hasIndex() || it->length() > 1 ) {
00081 desc += "]";
00082 }
00083
00084 desc += typ;
00085 size += item_size * dimension;
00086
00087 }
00088
00089
00090
00092 StatusCode RootHistCnv::RCWNTupleCnv::book(long , const std::string& , INTuple* nt) {
00093 MsgStream log(msgSvc(), "RCWNTupleCnv");
00094
00095
00096
00097 std::string rt_path, rt_fid, rt_id, rt_lid;
00098 TTree* rtree;
00099
00100 DataObject* pObj = dynamic_cast<DataObject*>(nt);
00101 if (pObj != 0) {
00102 rt_lid = pObj->localPath();
00103 rt_id = "t" + rt_lid.substr(1,rt_lid.length()-1);
00104 rt_fid = pObj->fullpath();
00105 rt_path = pObj->location();
00106 } else {
00107 log << MSG::ERROR << "dynamic cast failed" << endreq;
00108 return StatusCode::FAILURE;
00109 }
00110
00111 if (findNTuple(rt_fid,rtree).isFailure()) {
00112
00113 rtree = new TTree(rt_id.c_str(),nt->title().c_str());
00114
00115
00116
00117
00118
00119 regNTuple(rt_fid,rtree);
00120
00121
00122
00123 std::string block_name,var_name;
00124 long size = 0;
00125 long cursize, oldsize = 0;
00126 std::vector<long> item_size;
00127 std::vector<std::pair<std::string,std::string> > item_name;
00128
00129 const INTuple::ItemContainer& cols = nt->items();
00130 for (INTuple::ItemContainer::const_iterator i = cols.begin();
00131 i != cols.end(); ++i ) {
00132
00133 std::string item = "";
00134 switch( (*i)->type() ) {
00135
00136 case DataTypeInfo::INT:
00137 analyzeItem(rootVarType( (*i)->type() ),
00138 dynamic_cast<const NTuple::_Data<int>*>(*i),item,
00139 block_name,size);
00140 break;
00141 case DataTypeInfo::SHORT:
00142 analyzeItem(rootVarType( (*i)->type() ),
00143 dynamic_cast<const NTuple::_Data<short>*>(*i),item,
00144 block_name,size);
00145 break;
00146 case DataTypeInfo::LONG:
00147 analyzeItem(rootVarType( (*i)->type() ),
00148 dynamic_cast<const NTuple::_Data<long>*>(*i),item,
00149 block_name,size);
00150 break;
00151 case DataTypeInfo::UCHAR:
00152 analyzeItem(rootVarType( (*i)->type() ),
00153 dynamic_cast<const NTuple::_Data<unsigned char>*>(*i),
00154 item,block_name,size);
00155 break;
00156 case DataTypeInfo::USHORT:
00157 analyzeItem(rootVarType( (*i)->type() ),
00158 dynamic_cast<const NTuple::_Data<unsigned short>*>(*i),
00159 item,block_name,size);
00160 break;
00161 case DataTypeInfo::UINT:
00162 analyzeItem(rootVarType( (*i)->type() ),
00163 dynamic_cast<const NTuple::_Data<unsigned int>*>(*i),
00164 item,block_name,size);
00165 break;
00166 case DataTypeInfo::ULONG:
00167 analyzeItem(rootVarType( (*i)->type() ),
00168 dynamic_cast<const NTuple::_Data<unsigned long>*>(*i),
00169 item,block_name,size);
00170 break;
00171 case DataTypeInfo::DOUBLE:
00172 analyzeItem(rootVarType( (*i)->type() ),
00173 dynamic_cast<const NTuple::_Data<double>*>(*i),item,
00174 block_name,size);
00175 break;
00176 case DataTypeInfo::FLOAT:
00177 analyzeItem(rootVarType( (*i)->type() ),
00178 dynamic_cast<const NTuple::_Data<float>*>(*i),item,
00179 block_name,size);
00180 break;
00181 default:
00182 break;
00183 }
00184
00185 item_name.push_back(std::pair<std::string,std::string>(block_name,item));
00186 cursize = size - oldsize;
00187 item_size.push_back(size-cursize);
00188 oldsize = size;
00189 }
00190 char* buff = new char[size];
00191 nt->setBuffer(buff);
00192
00193 std::string block_desc = "";
00194 char *buf_pos = buff;
00195
00196 std::vector<std::pair<std::string,std::string> >::const_iterator itr,itr1,end;
00197 end = item_name.end();
00198 int cnt = 0;
00199 int pos = 0;
00200 bool inblk;
00201
00202 std::string cur_blk;
00203
00204
00205 for (itr=item_name.begin(); itr!=end; ++itr) {
00206 cur_blk = (*itr).first;
00207 inblk = true;
00208 itr1 = itr;
00209 block_desc = "";
00210 pos += cnt;
00211 cnt = 0;
00212
00213 while ( inblk ) {
00214 if ( itr1+1 == end ) {
00215 inblk = false;
00216 } else if ( (itr1+1)->first != cur_blk ) {
00217 inblk = false;
00218 }
00219
00220 block_desc += itr1->second + ":";
00221
00222 ++cnt;
00223 ++itr1;
00224 }
00225
00226 itr = itr1 - 1;
00227
00228 buf_pos = buff + item_size[pos];
00229 block_desc.erase(block_desc.length()-1,1);
00230
00231
00232
00233
00234 rtree->Branch(item_name[pos].first.c_str(), const_cast<char*>(buf_pos),
00235 block_desc.c_str());
00236 log << MSG::INFO << "ID " << rt_id << ": added branch: "
00237 << item_name[pos].first << " : " << block_desc << endreq;
00238
00239 }
00240
00241
00242 log << MSG::INFO << "Booked TTree with ID: " << rt_id
00243 << " \"" << nt->title() << "\" in directory "
00244 << getDirectory() << endreq;
00245
00246
00247 return StatusCode::SUCCESS;
00248
00249 }
00250
00251 log << MSG::ERROR << "Column wise ROOT Tree " << rt_fid << " already exists."
00252 << endreq;
00253 return StatusCode::FAILURE;
00254 }
00255
00256
00257
00259 StatusCode RootHistCnv::RCWNTupleCnv::writeData(long , INTuple* nt) {
00260
00261 MsgStream log(msgSvc(), "RCWNTupleCnv");
00262
00263
00264 std::string rt_id, rt_fid, rt_path;
00265 TTree* rtree = 0;
00266
00267 DataObject* pObj = dynamic_cast<DataObject*>(nt);
00268 if (pObj != 0) {
00269 rt_fid = pObj->fullpath();
00270 rt_path = pObj->location();
00271 } else {
00272 log << MSG::ERROR << "dynamic cast failed" << endreq;
00273 return StatusCode::FAILURE;
00274 }
00275
00276 if ( findNTuple(rt_fid,rtree).isFailure() ) {
00277 log << MSG::ERROR << "tree ID: " << rt_fid << " not found in treemap"
00278 << endreq;
00279 return StatusCode::FAILURE;
00280 }
00281
00282 const INTuple::ItemContainer& cols = nt->items();
00283 char * tar = nt->buffer();
00284 for (INTuple::ItemContainer::const_iterator i = cols.begin(); i != cols.end(); i++ ) {
00285 switch( (*i)->type() ) {
00286 case DataTypeInfo::BOOL:
00287 tar += saveItem(tar, (bool*)(*i)->buffer(), (*i)->length());
00288 break;
00289 case DataTypeInfo::CHAR:
00290 tar += saveItem(tar, (char*)(*i)->buffer(), (*i)->length());
00291 break;
00292 case DataTypeInfo::SHORT:
00293 tar += saveItem(tar, (short*)(*i)->buffer(), (*i)->length());
00294 break;
00295 case DataTypeInfo::INT:
00296 tar += saveItem(tar, (int*)(*i)->buffer(), (*i)->length());
00297 break;
00298 case DataTypeInfo::LONG:
00299 tar += saveItem(tar, (long*)(*i)->buffer(), (*i)->length());
00300 break;
00301 case DataTypeInfo::UCHAR:
00302 tar += saveItem(tar, (unsigned char*)(*i)->buffer(), (*i)->length());
00303 break;
00304 case DataTypeInfo::USHORT:
00305 tar += saveItem(tar, (unsigned short*)(*i)->buffer(), (*i)->length());
00306 break;
00307 case DataTypeInfo::UINT:
00308 tar += saveItem(tar, (unsigned int*)(*i)->buffer(), (*i)->length());
00309 break;
00310 case DataTypeInfo::ULONG:
00311 tar += saveItem(tar, (unsigned long*)(*i)->buffer(), (*i)->length());
00312 break;
00313 case DataTypeInfo::FLOAT:
00314 tar += saveItem(tar, (float*)(*i)->buffer(), (*i)->length());
00315 break;
00316 case DataTypeInfo::DOUBLE:
00317 tar += saveItem(tar, (double*)(*i)->buffer(), (*i)->length());
00318 break;
00319 default:
00320 break;
00321 }
00322 }
00323
00324
00325 rtree->Fill();
00326
00327 nt->reset();
00328
00329 return StatusCode::SUCCESS;
00330
00331 }
00332
00333
00334
00336 StatusCode RootHistCnv::RCWNTupleCnv::readData(long , INTuple* , long ) {
00337 MsgStream log(msgSvc(), "RCWNTupleCnv");
00338
00339
00340 return StatusCode::FAILURE;
00341 }
00342
00343
00344
00346 StatusCode RootHistCnv::RCWNTupleCnv::load(long , INTuple*& ) {
00347
00348 MsgStream log(msgSvc(), "RCWNTupleCnv");
00349
00350
00351 return StatusCode::FAILURE;
00352
00353 }
00354
00355