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