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