00001 #define ROOTHISTCNV_RNTUPLECNV_CPP
00002
00003
00004 #include "NTupleInfo.h"
00005 #include "RNTupleCnv.h"
00006 #include "RootObjAddress.h"
00007
00008 #include "GaudiKernel/CnvFactory.h"
00009 #include "GaudiKernel/DataObject.h"
00010 #include "GaudiKernel/IOpaqueAddress.h"
00011 #include "GaudiKernel/IDataProviderSvc.h"
00012 #include "GaudiKernel/IDataManagerSvc.h"
00013 #include "GaudiKernel/INTupleSvc.h"
00014 #include "GaudiKernel/IRegistry.h"
00015 #include "GaudiKernel/MsgStream.h"
00016 #include "GaudiKernel/SmartIF.h"
00017 #include "GaudiKernel/NTuple.h"
00018
00019
00020 #include "TTree.h"
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00032 RootHistCnv::RNTupleCnv::RNTupleCnv( ISvcLocator* svc, const CLID& clid )
00033 : RConverter(clid, svc) {
00034 }
00035
00036
00037
00038
00040 RootHistCnv::RNTupleCnv::~RNTupleCnv() {
00041 }
00042
00043
00044
00046 StatusCode RootHistCnv::RNTupleCnv::initialize() {
00047
00048 StatusCode status = Converter::initialize();
00049 if ( status.isSuccess() ) {
00050 m_ntupleSvc = serviceLocator()->service("NTupleSvc");
00051 if (!m_ntupleSvc.isValid()) status = StatusCode::FAILURE;
00052 }
00053 return status;
00054 }
00055
00056
00057
00059 StatusCode RootHistCnv::RNTupleCnv::finalize() {
00060
00062 m_ntupleSvc = 0;
00063 return Converter::finalize();
00064 }
00065
00066
00068 StatusCode RootHistCnv::RNTupleCnv::updateObj(IOpaqueAddress* pAddress,
00069 DataObject* pObject)
00070
00071 {
00072 MsgStream log (msgSvc(), "RNTupleCnv");
00073
00074 StatusCode status = StatusCode::FAILURE;
00075
00076 RootObjAddress *rAddr = dynamic_cast<RootObjAddress*>(pAddress);
00077
00078 if (rAddr == 0) {
00079 log << MSG::ERROR << "Could not dynamic cast to RootObjAddress" << endmsg;
00080 return StatusCode::FAILURE;
00081 }
00082
00083 TTree* rtree = (TTree*) rAddr->tObj();
00084
00085 try {
00086 unsigned long* info = (unsigned long*)pAddress->ipar();
00087 setDirectory(pAddress->par()[0]);
00088 status = readData(rtree, dynamic_cast<INTuple*>(pObject), info[1]++);
00089 }
00090 catch (...) {
00091 }
00092 return status;
00093 }
00094
00095
00097 StatusCode RootHistCnv::RNTupleCnv::createObj(IOpaqueAddress* pAddress,
00098 DataObject*& refpObject)
00099
00100 {
00101 MsgStream log (msgSvc(), "RNTupleCnv");
00102
00103 IRegistry* pReg = pAddress->registry();
00104
00105
00106
00107
00108
00109
00110 std::string ident = pReg->identifier();
00111
00112 StatusCode status = readObject(pAddress, refpObject);
00113 if ( status.isSuccess() ) {
00114 RootObjAddress *rAddr = dynamic_cast<RootObjAddress*>( pAddress );
00115 if (rAddr == 0) {
00116 log << MSG::ERROR << "Could not cast to RootObjAddress" << endmsg;
00117 return StatusCode::FAILURE;
00118 }
00119 INTuple* nt = 0;
00120 TTree* tobj = (TTree*) rAddr->tObj();
00121 status = load(tobj, nt);
00122 if (status.isSuccess()) {
00123 refpObject = dynamic_cast<DataObject*>(nt);
00124 } else {
00125 log << MSG::ERROR << "Problems loading ntuple id: " << pReg->identifier()
00126 << endmsg;
00127 }
00128 }
00129 return status;
00130 }
00131
00132
00134 StatusCode RootHistCnv::RNTupleCnv::createRep(DataObject* pObject,
00135 IOpaqueAddress*& pAddr)
00136
00137 {
00138 GlobalDirectoryRestore restore;
00139 pAddr = 0;
00140 try {
00141 IRegistry* pReg = pObject->registry();
00142 if ( 0 != pReg ) {
00143 pAddr = pReg->address();
00144 if ( 0 == pAddr ) {
00145 SmartIF<IDataManagerSvc> dataMgr(dataProvider());
00146 if ( dataMgr.isValid() ) {
00147 IRegistry* pParentReg = 0;
00148 StatusCode status = dataMgr->objectParent(pReg, pParentReg);
00149 if ( status.isSuccess() ) {
00150 IOpaqueAddress* pParAddr = pParentReg->address();
00151 if ( pParAddr ) {
00152 TDirectory* pParentDir = (TDirectory*)pParAddr->ipar()[0];
00153 if ( pParentDir ) {
00154 TTree* pTree = 0;
00155 std::string dsc = pReg->name().substr(1);
00156 gDirectory = pParentDir;
00157 status = book(dsc, dynamic_cast<INTuple*>(pObject), pTree);
00158 if ( !status.isSuccess() ) {
00159 return status;
00160 }
00161 status = createAddress(pObject, gDirectory, pTree, pAddr);
00162 if ( !status.isSuccess() ) {
00163 return status;
00164 }
00165 return writeData(pTree, dynamic_cast<INTuple*>(pObject));
00166 }
00167 }
00168 }
00169 }
00170 }
00171 else {
00172 TDirectory* pDir = (TDirectory*)pAddr->ipar()[0];
00173 RootObjAddress *rAddr = dynamic_cast<RootObjAddress*>( pAddr );
00174 if (rAddr == 0) {
00175 MsgStream log (msgSvc(), "RNTupleCnv");
00176 log << MSG::ERROR << "Could not cast to RootObjAddress" << endmsg;
00177 return StatusCode::FAILURE;
00178 }
00179 TTree* pTree = (TTree*) rAddr->tObj();
00180 gDirectory = pDir;
00181 return writeData(pTree, dynamic_cast<INTuple*>(pObject));
00182 }
00183 }
00184 }
00185 catch (...) {
00186 }
00187 MsgStream log (msgSvc(), "RNTupleCnv");
00188 log << MSG::ERROR << "Failed to create persistent N-tuple!" << endmsg;
00189 return StatusCode::FAILURE;
00190 }
00191
00192
00194 StatusCode RootHistCnv::RNTupleCnv::updateRep(IOpaqueAddress* pAddr,
00195 DataObject* pObj )
00196
00197 {
00198 MsgStream log (msgSvc(), "RNTupleCnv");
00199 if ( 0 != pAddr ) {
00200 GlobalDirectoryRestore restore;
00201 TDirectory* pDir = (TDirectory*)pAddr->ipar()[0];
00202 RootObjAddress *rAddr = dynamic_cast<RootObjAddress*>( pAddr );
00203 if (rAddr == 0) {
00204 log << MSG::ERROR << "Could not cast to RootObjAddress" << endmsg;
00205 return StatusCode::FAILURE;
00206 }
00207 TTree* pTree = (TTree*) rAddr->tObj();
00208 if ( 0 != pDir && 0 != pTree ) {
00209 gDirectory->cd(pDir->GetPath());
00210 pTree->Write("",TObject::kOverwrite);
00211 return StatusCode::SUCCESS;
00212 }
00213 }
00214 else {
00215 log << MSG::WARNING << "empty ntuple: " << pObj->registry()->identifier()
00216 << endmsg;
00217 return ( createRep(pObj,pAddr) );
00218 }
00219 return StatusCode::FAILURE;
00220 }
00221
00222
00224
00225
00226 std::string RootHistCnv::RNTupleCnv::rootVarType(int type) {
00227
00228 switch( type ) {
00229 case DataTypeInfo::SHORT: return "/S";
00230 case DataTypeInfo::INT: return "/I";
00231 case DataTypeInfo::LONG: return "/I";
00232 case DataTypeInfo::USHORT: return "/s";
00233 case DataTypeInfo::UINT: return "/i";
00234 case DataTypeInfo::ULONG: return "/i";
00235 case DataTypeInfo::FLOAT: return "/F";
00236 case DataTypeInfo::DOUBLE: return "/D";
00237 default: return "";
00238 }
00239 return "";
00240 }
00241
00242
00243 bool RootHistCnv::parseName(std::string full, std::string &blk, std::string &var) {
00244
00245 int sp;
00246 if ( (sp=full.find("/")) != -1 ) {
00247 blk = full.substr(0,sp);
00248 var = full.substr(sp+1,full.length());
00249 return true;
00250 } else {
00251 blk = "AUTO_BLK";
00252 var = full;
00253 return false;
00254 }
00255
00256 }
00257
00258
00260
00261 #define INSTANTIATE(TYP) \
00262 template INTupleItem* createNTupleItem<TYP>(std::string itemName, std::string blockName, std::string index_name, int indexRange, int arraySize, TYP minimum, TYP maximum, INTuple* tuple);
00263
00264 namespace RootHistCnv {
00265
00266 template<class TYP>
00267 INTupleItem* createNTupleItem (std::string itemName, std::string blockName,
00268 std::string indexName,
00269 int indexRange, int arraySize,
00270 TYP min, TYP max,
00271 INTuple* ntup) {
00272
00273 std::string varName;
00274 if (blockName != "") {
00275 varName = blockName + "/" + itemName;
00276 } else {
00277 varName = itemName;
00278 }
00279
00280 TYP null = 0;
00281 INTupleItem* col = 0;
00282
00283 if (min == 0 && max == 0) {
00284 min = NTuple::Range<TYP>::min();
00285 max = NTuple::Range<TYP>::max();
00286 }
00287
00288
00289 if (indexName == "") {
00290
00291 if (arraySize == 1) {
00292
00293 col = NTuple::_Item<TYP>::create(ntup, varName,
00294 typeid(TYP),
00295 min, max, null);
00296
00297 } else {
00298
00299 col = NTuple::_Array<TYP>::create(ntup, varName,
00300 typeid(TYP),
00301 "", arraySize,
00302 min, max, null);
00303 }
00304
00305 } else {
00306
00307 if (arraySize == 1) {
00308
00309 col = NTuple::_Array<TYP>::create(ntup, varName,
00310 typeid(TYP),
00311 indexName, indexRange,
00312 min, max, null);
00313 } else {
00314
00315 col = NTuple::_Matrix<TYP>::create(ntup, varName,
00316 typeid(TYP),
00317 indexName,
00318 indexRange, arraySize,
00319 min, max, null);
00320 }
00321
00322 }
00323
00324 return col;
00325
00326 }
00327
00328 INSTANTIATE(float)
00329 INSTANTIATE(double)
00330 INSTANTIATE(bool)
00331 INSTANTIATE(char)
00332 INSTANTIATE(int)
00333 INSTANTIATE(short)
00334 INSTANTIATE(long)
00335 INSTANTIATE(unsigned char)
00336 INSTANTIATE(unsigned int)
00337 INSTANTIATE(unsigned short)
00338 INSTANTIATE(unsigned long)
00339 };