![]() |
|
|
Generated: 24 Nov 2008 |
00001 // $Header: /local/reps/Gaudi/HbookCnv/src/HCWNTupleCnv.cpp,v 1.6 2006/01/10 20:11:14 hmd Exp $ 00002 #define HBOOKCNV_HCWNTUPLECNV_CPP 00003 00004 00005 #define ALLOW_ALL_TYPES 00006 00007 // Compiler include files 00008 #include <cstdio> 00009 00010 // Include files 00011 #include "GaudiKernel/xtoa.h" 00012 #include "GaudiKernel/CnvFactory.h" 00013 #include "GaudiKernel/DataTypeInfo.h" 00014 #include "GaudiKernel/INTupleSvc.h" 00015 00016 #include "GaudiKernel/MsgStream.h" 00017 #include "GaudiKernel/NTuple.h" 00018 00019 #include "HCWNTupleCnv.h" 00020 #include "NTupleInfo.h" 00021 #include "HbookDef.h" 00022 00023 //------------------------------------------------------------------------------ 00024 // 00025 // Implementation of class : HbookCnv::HCWNTupleCnv 00026 // 00027 // Author : Markus Frank 00028 // 00029 //------------------------------------------------------------------------------ 00030 00031 // Instantiation of a static factory class used by clients to create 00032 // instances of this service 00033 DECLARE_NAMESPACE_CONVERTER_FACTORY(HbookCnv,HCWNTupleCnv) 00034 00035 template <class T> void analyzeItem(const char typ, 00036 const NTuple::_Data<T>* it, 00037 std::string& desc, 00038 std::string& block_name, 00039 long& size) { 00040 00041 std::string full_name, var_name; 00042 full_name = it->name(); 00043 HbookCnv::parseName(full_name,block_name,var_name); 00044 00045 long item_size = (sizeof(T) < 4) ? 4 : sizeof(T); 00046 long dimension = it->length(); 00047 long ndim = it->ndim()-1; 00048 char text[132]; 00049 // desc += it->name(); 00050 desc += var_name; 00051 if ( it->hasIndex() || it->length() > 1 ) { 00052 desc += '('; 00053 } 00054 for ( int i = 0; i < ndim; i++ ) { 00055 desc += ::_itoa(it->dim(i), text, 10); 00056 desc += ','; 00057 } 00058 if ( it->hasIndex() ) { 00059 std::string ind_blk, ind_var; 00060 std::string ind = it->index(); 00061 HbookCnv::parseName(ind,ind_blk,ind_var); 00062 if (ind_blk != block_name) { 00063 std::cerr << "ERROR: Index for CWNT variable " << ind_var 00064 << " is in a differnt block: " << ind_blk << std::endl; 00065 } 00066 desc += ind_var; 00067 } 00068 else if ( it->dim(ndim) > 1 ) { 00069 desc += ::_itoa(it->dim(ndim), text, 10); 00070 } 00071 00072 if ( it->hasIndex() || it->length() > 1 ) { 00073 desc += ")"; 00074 } 00075 if ( typ != 'L' && typ != 'R' ) { 00076 desc += '['; 00077 desc += ::_itoa(long(it->range().lower()), text, 10); 00078 desc += ','; 00079 desc += ::_itoa(long(it->range().upper()), text, 10); 00080 desc += ']'; 00081 } 00082 desc += ':'; 00083 desc += typ; 00084 desc += '*'; 00085 desc += ::_itoa(item_size, text, 10); 00086 size += item_size * dimension; 00087 } 00088 00089 00091 StatusCode HbookCnv::HCWNTupleCnv::declare(long idh, INTuple* nt) { 00092 MsgStream log(msgSvc(), "HCWNTupleCnv"); 00093 00094 const INTuple::ItemContainer& cols = nt->items(); 00095 // char text[64]; 00096 std::string desc = ""; 00097 std::string block_name,var_name; 00098 long size = 0; 00099 size_t cnt =0; 00100 00101 long cursize, oldsize = 0; 00102 std::vector<long> item_size; 00103 std::vector<std::pair<std::string,std::string> > item_name; 00104 00105 try { 00106 for (INTuple::ItemContainer::const_iterator i = cols.begin(); i != cols.end(); i++ ) { 00107 std::string item = ""; 00108 switch( (*i)->type() ) { 00109 case DataTypeInfo::BOOL: // bool 00110 analyzeItem('L', dynamic_cast<const NTuple::_Data<bool>*>(*i),item, 00111 block_name,size); 00112 break; 00113 case DataTypeInfo::CHAR: // char 00114 analyzeItem('I', dynamic_cast<const NTuple::_Data<char>*>(*i),item, 00115 block_name,size); 00116 break; 00117 case DataTypeInfo::INT: // int 00118 analyzeItem('I', dynamic_cast<const NTuple::_Data<int>*>(*i),item, 00119 block_name,size); 00120 break; 00121 case DataTypeInfo::SHORT: // short 00122 analyzeItem('I', dynamic_cast<const NTuple::_Data<short>*>(*i),item, 00123 block_name,size); 00124 break; 00125 case DataTypeInfo::LONG: // long 00126 analyzeItem('I', dynamic_cast<const NTuple::_Data<long>*>(*i),item, 00127 block_name,size); 00128 break; 00129 case DataTypeInfo::UCHAR: // unsigned char 00130 analyzeItem('U', dynamic_cast<const NTuple::_Data<unsigned char>*>(*i), 00131 item,block_name,size); 00132 break; 00133 case DataTypeInfo::USHORT: // unsigned short 00134 analyzeItem('U', dynamic_cast<const NTuple::_Data<unsigned short>*>(*i), 00135 item,block_name,size); 00136 break; 00137 case DataTypeInfo::UINT: // unsigned int 00138 analyzeItem('U', dynamic_cast<const NTuple::_Data<unsigned int>*>(*i), 00139 item,block_name,size); 00140 break; 00141 case DataTypeInfo::ULONG: // unsigned long 00142 analyzeItem('U', dynamic_cast<const NTuple::_Data<unsigned long>*>(*i), 00143 item,block_name,size); 00144 break; 00145 case DataTypeInfo::DOUBLE: // double 00146 analyzeItem('R', dynamic_cast<const NTuple::_Data<double>*>(*i),item, 00147 block_name,size); 00148 break; 00149 case DataTypeInfo::FLOAT: // float 00150 analyzeItem('R', dynamic_cast<const NTuple::_Data<float>*>(*i),item, 00151 block_name,size); 00152 default: 00153 break; 00154 } 00155 desc += item; 00156 if ( ++cnt < cols.size() ) { 00157 desc += ", "; 00158 } 00159 00160 item_name.push_back(std::make_pair(block_name,item)); 00161 cursize = size - oldsize; 00162 item_size.push_back(size-cursize); 00163 oldsize = size; 00164 } 00165 char* buff = new char[size]; 00166 nt->setBuffer(buff); 00167 00168 // const unsigned int MAX_BLOCK_NAME = 1300; 00169 std::string block_desc = ""; 00170 char *buf_pos = buff; 00171 00172 std::vector<std::pair<std::string,std::string> >::const_iterator itr,end; 00173 end = item_name.end(); 00174 int pos = 0; 00175 00177 00178 for (itr=item_name.begin(); itr!=end; ++itr) { 00179 buf_pos = buff + item_size[pos++]; 00180 block_desc = itr->second; 00181 00182 ::HBNAME(idh, itr->first.c_str(), buf_pos, block_desc.c_str()); 00183 00184 log << MSG::DEBUG << "CWNT " << idh << ": added " 00185 << itr->first << " : " << block_desc << endreq; 00186 00187 } 00188 00189 return StatusCode::SUCCESS; 00190 } 00191 catch (...) { 00192 } 00193 return StatusCode::FAILURE; 00194 } 00195 00196 00198 StatusCode HbookCnv::HCWNTupleCnv::book(long idh, const std::string& loc, INTuple* nt) { 00199 MsgStream log(msgSvc(), "HCWNTupleCnv"); 00200 // log << MSG::DEBUG << "in HCWNTupleCnv::book" << endreq; 00201 if ( !::HEXIST( idh ) ) { 00202 NTUPLEINFO tags; 00203 memset(&tags,0, sizeof(tags)); 00204 tags.id = idh; 00205 strncpy(tags.rzdir, loc.data()+2, loc.length()-2); 00206 strncpy(tags.title, nt->title().data(), nt->title().length()); 00207 StatusCode status = ::CWNT_BOOK(tags); 00208 if ( status.isSuccess() ) { 00209 status = declare(idh, nt); 00210 if ( status.isSuccess() ) { 00211 log << MSG::INFO << "Booked Column wise HBOOK N tuple with ID:" << idh 00212 << " \"" << nt->title() 00213 << "\" in directory <" << loc << ">" << endreq; 00214 log << MSG::DEBUG; 00215 if ( log.isActive() ) ::HPRINT (idh); 00216 return StatusCode::SUCCESS; 00217 } 00218 } 00219 log << MSG::ERROR << "Column wise HBOOK N tuple " << idh 00220 << "\"" << nt->title() 00221 << "\" cannot be booked" 00222 << " in directory <" << loc << ">" << endreq; 00223 return status; 00224 } 00225 log << MSG::ERROR << "Column wise HBOOK N tuple " << idh << "\"" << nt->title() 00226 << "\" already exists in directory <" << loc << ">" << endreq; 00227 return StatusCode::FAILURE; 00228 } 00229 00230 00232 StatusCode HbookCnv::HCWNTupleCnv::writeData(long idh, INTuple* nt) { 00233 const INTuple::ItemContainer& cols = nt->items(); 00234 MsgStream log(msgSvc(), "HCWNTupleCnv"); 00235 // log << MSG::DEBUG << "in HCWNTupleCnv::writeData" << endreq; 00236 char * tar = nt->buffer(); 00237 for (INTuple::ItemContainer::const_iterator i = cols.begin(); i != cols.end(); i++ ) { 00238 switch( (*i)->type() ) { 00239 case DataTypeInfo::BOOL: // bool 00240 tar += saveItem(tar, (bool*)(*i)->buffer(), (*i)->length()); 00241 break; 00242 case DataTypeInfo::CHAR: // char 00243 tar += saveItem(tar, (char*)(*i)->buffer(), (*i)->length()); 00244 break; 00245 case DataTypeInfo::SHORT: // short 00246 tar += saveItem(tar, (short*)(*i)->buffer(), (*i)->length()); 00247 break; 00248 case DataTypeInfo::INT: // short 00249 tar += saveItem(tar, (int*)(*i)->buffer(), (*i)->length()); 00250 break; 00251 case DataTypeInfo::LONG: // short 00252 tar += saveItem(tar, (long*)(*i)->buffer(), (*i)->length()); 00253 break; 00254 case DataTypeInfo::UCHAR: // unsigned char 00255 tar += saveItem(tar, (unsigned char*)(*i)->buffer(), (*i)->length()); 00256 break; 00257 case DataTypeInfo::USHORT: // unsigned short 00258 tar += saveItem(tar, (unsigned short*)(*i)->buffer(), (*i)->length()); 00259 break; 00260 case DataTypeInfo::UINT: // unsigned short 00261 tar += saveItem(tar, (unsigned int*)(*i)->buffer(), (*i)->length()); 00262 break; 00263 case DataTypeInfo::ULONG: // unsigned short 00264 tar += saveItem(tar, (unsigned long*)(*i)->buffer(), (*i)->length()); 00265 break; 00266 case DataTypeInfo::FLOAT: // unsigned short 00267 tar += saveItem(tar, (float*)(*i)->buffer(), (*i)->length()); 00268 break; 00269 case DataTypeInfo::DOUBLE: // unsigned short 00270 tar += saveItem(tar, (double*)(*i)->buffer(), (*i)->length()); 00271 break; 00272 default: 00273 break; 00274 } 00275 } 00276 ::HFNT ( idh ); 00277 nt->reset(); 00278 return StatusCode::SUCCESS; 00279 } 00280 00281 00283 StatusCode HbookCnv::HCWNTupleCnv::readData(long idh, INTuple* ntup, long ievt) { 00284 MsgStream log(msgSvc(), "HCWNTupleCnv"); 00285 00286 long istat = 0; 00287 ievt++; 00288 ::HGNT(idh, ievt, istat); 00289 if ( istat == 0 ) { 00290 INTuple::ItemContainer& cols = ntup->items(); 00291 char * src = ntup->buffer(); 00292 for (INTuple::ItemContainer::iterator i = cols.begin(); i != cols.end(); i++ ) { 00293 switch( (*i)->type() ) { 00294 case DataTypeInfo::BOOL: // bool 00295 src += loadItem(src, (bool*)(*i)->buffer(), (*i)->length()); 00296 break; 00297 case DataTypeInfo::CHAR: // char 00298 src += loadItem(src, (char*)(*i)->buffer(), (*i)->length()); 00299 break; 00300 case DataTypeInfo::SHORT: // short 00301 src += loadItem(src, (short*)(*i)->buffer(), (*i)->length()); 00302 break; 00303 case DataTypeInfo::INT: // short 00304 src += loadItem(src, (int*)(*i)->buffer(), (*i)->length()); 00305 break; 00306 case DataTypeInfo::LONG: // short 00307 src += loadItem(src, (long*)(*i)->buffer(), (*i)->length()); 00308 break; 00309 case DataTypeInfo::UCHAR: // unsigned char 00310 src += loadItem(src, (unsigned char*)(*i)->buffer(), (*i)->length()); 00311 break; 00312 case DataTypeInfo::USHORT: // unsigned short 00313 src += loadItem(src, (unsigned short*)(*i)->buffer(), (*i)->length()); 00314 break; 00315 case DataTypeInfo::UINT: // unsigned short 00316 src += loadItem(src, (unsigned int*)(*i)->buffer(), (*i)->length()); 00317 break; 00318 case DataTypeInfo::ULONG: // unsigned short 00319 src += loadItem(src, (unsigned long*)(*i)->buffer(), (*i)->length()); 00320 break; 00321 case DataTypeInfo::FLOAT: // unsigned short 00322 src += loadItem(src, (float*)(*i)->buffer(), (*i)->length()); 00323 break; 00324 case DataTypeInfo::DOUBLE: // unsigned short 00325 src += loadItem(src, (double*)(*i)->buffer(), (*i)->length()); 00326 break; 00327 default: 00328 break; 00329 } 00330 } 00331 return StatusCode::SUCCESS; 00332 } 00333 00334 log << MSG::ERROR << "Error reading data from N tuple ID:" << idh 00335 << " " << ntup->title() 00336 << endreq; 00337 return StatusCode::FAILURE; 00338 } 00339 00340 00342 StatusCode HbookCnv::HCWNTupleCnv::load(long idh, INTuple*& refpObject) { 00343 00344 MsgStream log(msgSvc(), "HCWNTupleCnv"); 00345 00346 NTUPLEINFO tags; 00347 00348 memset(&tags,0,sizeof(tags)); 00349 00350 std::vector<std::string> blkname; 00351 std::vector<unsigned long> bufpos; 00352 unsigned long totsize = 0; 00353 00354 tags.id = idh; 00355 StatusCode status = ::CWNT_INFO(tags); 00356 00357 if ( status.isSuccess() ) { 00358 NTuple::Tuple* pObj = 0; 00359 status = m_ntupleSvc->create(CLID_ColumnWiseTuple, tags.title, pObj); 00360 INTuple* ntup = dynamic_cast<INTuple*>(pObj); 00361 try { 00362 if ( status.isSuccess() && 0 != ntup ) { 00363 long total_size = 0; 00364 for ( long size = 0, i = 0; i < tags.numVar; i++, size=0 ) { 00365 INTupleItem* item = 0; 00366 switch( tags.type[i] ) { 00367 case 'L': 00368 item = createNTupleItem(tags, i, ntup, NTuple::Range<bool>::min(), NTuple::Range<bool>::max(), size); 00369 break; 00370 case 'I': 00371 // if ( tags.size[i] <= sizeof(unsigned char)*CHAR_BIT ) 00372 // item = createNTupleItem(tags, i, ntup, NTuple::Range<char>::min(), NTuple::Range<char>::max(), size); 00373 // else if ( tags.size[i] <= sizeof(unsigned short)*CHAR_BIT ) 00374 // item = createNTupleItem(tags, i, ntup, NTuple::Range<short>::min(), NTuple::Range<short>::max(), size); 00375 // else if ( tags.size[i] <= sizeof(unsigned int)*CHAR_BIT ) 00376 // item = createNTupleItem(tags, i, ntup, NTuple::Range<int>::min(), NTuple::Range<int>::max(), size); 00377 // else 00378 item = createNTupleItem(tags, i, ntup, NTuple::Range<long>::min(), NTuple::Range<long>::max(), size); 00379 break; 00380 case 'U': 00381 // if ( tags.size[i] <= sizeof(unsigned char)*CHAR_BIT ) 00382 // item = createNTupleItem(tags, i, ntup, NTuple::Range<unsigned char>::min(), NTuple::Range<unsigned char>::max(), size); 00383 // else if ( tags.size[i] <= sizeof(unsigned short)*CHAR_BIT ) 00384 // item = createNTupleItem(tags, i, ntup, NTuple::Range<unsigned short>::min(), NTuple::Range<unsigned short>::max(), size); 00385 // else if ( tags.size[i] <= sizeof(unsigned int)*CHAR_BIT ) 00386 // item = createNTupleItem(tags, i, ntup, NTuple::Range<unsigned int>::min(), NTuple::Range<unsigned int>::max(), size); 00387 // else 00388 item = createNTupleItem(tags, i, ntup, NTuple::Range<unsigned long>::min(), NTuple::Range<unsigned long>::max(), size); 00389 break; 00390 case 'R': 00391 if ( (size_t)tags.size[i] <= sizeof(float)*CHAR_BIT ) 00392 item = createNTupleItem(tags, i, ntup, NTuple::Range<float>::min(), NTuple::Range<float>::max(), size); 00393 else 00394 item = createNTupleItem(tags, i, ntup, NTuple::Range<double>::min(), NTuple::Range<double>::max(), size); 00395 break; 00396 default: 00397 break; 00398 } 00399 if ( item ) { 00400 long ii; 00401 ntup->add(item); 00402 total_size += size; 00403 log << MSG::DEBUG << "Create Var[" << i << "]: " 00404 << item->typeName() << "["; 00405 for ( ii = 0; ii < item->ndim()-1; ii++ ) { 00406 log << item->dim(ii) << ", "; 00407 } 00408 if ( item->hasIndex() ) log << item->index() << "]"; 00409 else log << item->dim(item->ndim()) << "]"; 00410 } else { 00411 log << MSG::FATAL << "Cannot deduce type for Var[" << i << "]: "; 00412 } 00413 00414 00415 // add sizes up 00416 blkname.push_back(tags.block[i]); 00417 bufpos.push_back(totsize); 00418 totsize += size; 00419 00420 00421 log << " Name:" << tags.name[i] 00422 << " Block: " << tags.block[i] 00423 << " Index:<" << tags.index[i] <<">" 00424 << " Dim:" << tags.dim[i] 00425 << " Typ:" << tags.type[i] 00426 << " Size:" << tags.size[i] 00427 << " ["; 00428 if ( tags.type[i] == 'I' || tags.type[i] == 'U' || tags.type[i] == 'L' ) 00429 log << tags.irange[i][0] << "," << tags.irange[i][1]; 00430 else if ( tags.type[i] == 'R' ) 00431 log << tags.frange[i][0] << "," << tags.frange[i][1]; 00432 log << "]" << endreq; 00433 } 00434 log << MSG::DEBUG << "Total buffer size of NTuple: " << total_size << " Bytes." << endreq; 00435 00436 ntup->setBuffer(new char[total_size]); 00437 long ievt = 0; 00438 00439 ::HBNAME(idh," ", &ievt, "$CLEAR"); 00440 00441 log << MSG::DEBUG << "Loading block " << blkname[0] << " at offset " 00442 << bufpos[0] << endreq; 00443 00444 ::HBNAME(idh,blkname[0].c_str(),ntup->buffer(),"$SET"); 00445 00446 std::string oldblock = blkname[0]; 00447 for (unsigned int ib=1; ib<bufpos.size(); ++ib) { 00448 if (blkname[ib] != oldblock) { 00449 log << MSG::DEBUG << "Loading block " << blkname[ib] << " at offset " 00450 << bufpos[ib] << endreq; 00451 ::HBNAME(idh,blkname[ib].c_str(),(ntup->buffer())+bufpos[ib],"$SET"); 00452 oldblock = blkname[ib]; 00453 } 00454 } 00455 00456 refpObject = ntup; 00457 return StatusCode::SUCCESS; 00458 } 00459 } 00460 catch (...) { 00461 } 00462 } 00463 log << MSG::ERROR << "Error loading N tuple ID:" << idh << endreq; 00464 return StatusCode::FAILURE; 00465 }