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