| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
RootTool.h
Go to the documentation of this file.
1 /*
2 * Gaudi namespace declaration
3 */
4 namespace Gaudi {
5
15 class RootTool : virtual public RootDataConnection::Tool {
16 public:
18 RootTool(RootDataConnection* con) { c = con; }
20 virtual TBranch* getBranch(CSTR section, CSTR branch_name) {
21 std::string n = branch_name+".";
22 for(int i=0, m=n.length()-1; i<m; ++i) if ( !isalnum(n[i]) ) n[i]='_';
23 TTree* t = c->getSection(section);
24 TBranch* b = t ? t->GetBranch(n.c_str()) : 0;
25 if ( !b ) b = t ? t->GetBranch(branch_name.c_str()) : 0;
26 if ( b ) b->SetAutoDelete(kFALSE);
27 return b;
28 }
30 virtual int loadRefs(CSTR section, CSTR cnt, unsigned long entry, RootObjectRefs& refs) {
31 TBranch* b = getBranch(section,cnt+"#R");
32 RootObjectRefs* prefs = &refs;
33 if ( b ) {
34 b->SetAddress(&prefs);
35 int nb = b->GetEntry(entry);
36 if ( nb >= 1 ) {
37 const MergeSections& ms = c->mergeSections();
38 if ( !ms.empty() ) {
39 MsgStream& msg = msgSvc();
40 msgSvc() << MSG::VERBOSE;
41 pair<const RootRef*,const ContainerSection*> ls = c->getMergeSection(cnt,entry);
42 if ( ls.first ) {
43 if ( ls.first->dbase >= 0 ) {
44 // Now patch the references and links 'en block' to be efficient
45 // First the leafs from the TES
46 if ( msg.isActive() ) {
47 msg << "Refs: LS [" << entry << "] -> "
48 << ls.first->dbase << "," << ls.first->container
49 << "," << ls.first->link
50 << "," << ls.first->entry
51 << endmsg;
52 }
53 for(size_t j=0, n=refs.refs.size(); j<n; ++j) {
54 RootRef& r = refs.refs[j];
55 if ( r.entry>= 0 && r.dbase >= 0 ) {
56 int db = r.dbase + ls.first->dbase;
57 if ( c->getDb(db) == c->fid() ) {
58 if ( r.dbase ) r.dbase += ls.first->dbase;
59 if ( r.container ) r.container += ls.first->container;
60 if ( r.link ) r.link += ls.first->link;
61 const string& rc = c->getCont(r.container);
62 MergeSections::const_iterator k = ms.find(rc);
63 if ( k != ms.end() ) {
64 const ContainerSections& cs = (*k).second;
65 r.entry = ( ls.first->entry >= 0 && ls.first->entry < (int)cs.size() )
66 ? cs[ls.first->entry].start + r.entry : -1;
67 if ( msg.isActive() ) {
68 msg << "Add link [" << r.entry
69 << "," << ls.first->entry
70 << "," << ls.first->container
71 << "," << r.container
72 << "," << r.entry
73 << "] to -> " << rc << endmsg;
74 }
75 }
76 else {
77 msg << MSG::WARNING << c->fid() << " [" << c->getDb(db)
78 << "] Evt:" << entry << " Invalid link to " << rc << endmsg;
79 msg << MSG::VERBOSE;
80 }
81 }
82 }
83 }
85 for(vector<int>::iterator i=refs.links.begin(); i!=refs.links.end();++i) {
86 (*i) += ls.first->link;
87 }
88 }
89 return nb;
90 }
91 return -1;
92 }
93 return nb;
94 }
95 }
96 return -1;
97 }
99 void addParam(ParamMap& c, char* p) {
100 char* q = strchr(p,'=');
101 if ( q ) {
102 *q = 0;
103 c.push_back(make_pair(p,++q));
104 }
105 }
107 void addEntry(StringVec& c, char* val) { c.push_back(val); }
109 template <class C, class F> StatusCode readBranch(TTree* t, const char* nam, C& v, F pmf) {
110 char text[2048];
111 TBranch* b = t->GetBranch(nam);
112 if ( b ) {
113 TLeaf* l = b->GetLeaf(nam);
114 if ( l ) {
115 StatusCode sc = StatusCode::SUCCESS;
116 b->SetAddress(text);
117 msgSvc() << MSG::VERBOSE;
118 for(Long64_t i=0, n=b->GetEntries(); i<n; ++i) {
119 if ( b->GetEntry(i)>0 ) {
120 char* p = (char*)l->GetValuePointer();
121 msgSvc() << "Add Value[" << b->GetName() << "]:" << p << endmsg;
122 (this->*pmf)(v,p);
123 }
124 else {
125 sc = RootDataConnection::ROOT_READ_ERROR;
126 }
127 }
128 return sc;
129 }
130 }
131 msgSvc() << MSG::ERROR << "Failed to read '" << nam << "' table." << endmsg;
132 return RootDataConnection::ROOT_READ_ERROR;
133 }
135 bool get(const string& dsc, pair<string,ContainerSection>& e) {
136 if ( dsc != "[END-OF-SECTION]" ) {
137 size_t id1 = dsc.find("[CNT=");
138 size_t id2 = dsc.find("[START=");
139 size_t id3 = dsc.find("[LEN=");
140 if ( id1 != string::npos && id2 != string::npos && id3 != string::npos ) {
141 string tmp;
142 string cnt = dsc.substr(id1+5, id2-1-5);
143 int section_start = ::atoi((tmp=dsc.substr(id2+7,id3-id2-8)).c_str());
144 int section_length = ::atoi((tmp=dsc.substr(id3+5,dsc.find("]",id3+5)-id3-5)).c_str());
145 e.first = cnt;
146 e.second = ContainerSection(section_start,section_length);
147 return true;
148 }
149 }
150 e.first = "";
151 e.second = ContainerSection(-1,-1);
152 return false;
153 }
155 void analyzeMergeMap(StringVec& tmp) {
156 StringVec::const_iterator i;
157 LinkSections& ls = linkSections();
158 MergeSections& ms = mergeSections();
159 pair<string,ContainerSection> e;
160 MsgStream& msg = msgSvc();
161 RootRef r;
162 int cnt = 0;
163 ls.clear();
164 ms.clear();
165 msg << MSG::VERBOSE;
166 r.dbase = r.container = r.link = r.clid = r.svc = r.entry = 0;
167 for(i=tmp.begin(); i!=tmp.end();++i) {
168 if ( get(*i,e) ) {
169 msg << "Added Merge Section:" << e.first << endmsg;
170 ms[e.first].push_back(e.second);
171 if ( e.first == "Links" )
172 r.link = e.second.start;
173 else if ( e.first == "Containers" )
174 r.container = e.second.start;
175 else if ( e.first == "Databases" )
176 r.dbase = e.second.start;
177 else if ( e.first == "Params" )
178 r.svc = e.second.start;
179 }
180 else if ( (*i) == "[END-OF-SECTION]" ) {
181 r.entry = cnt;
182 if ( msg.isActive() ) {
183 msg << "Link Section [" << r.entry << "," << ls.size()
184 << "] -> D:" << r.dbase
185 << " C:" << r.container
186 << " L:" << r.link
187 << " P:" << r.svc
188 << endmsg;
189 }
190 ls.push_back(r);
191 cnt++;
192 }
193 }
194 }
196 StatusCode readRefs() {
197 TTree* t = (TTree*)c->file()->Get("Sections");
198 StatusCode sc(StatusCode::SUCCESS,true);
199 StringVec tmp;
200 if ( t && !(sc=readBranch(t, "Sections", tmp, &RootTool::addEntry)).isSuccess() )
201 return sc;
202 else if ( refs() ) {
203 analyzeMergeMap(tmp);
204 if ( !(sc=readBranch(refs(),"Databases", dbs(), &RootTool::addEntry)).isSuccess() )
205 return sc;
206 if ( !(sc=readBranch(refs(),"Containers",conts(), &RootTool::addEntry)).isSuccess() )
207 return sc;
208 if ( !(sc=readBranch(refs(),"Links", links(), &RootTool::addEntry)).isSuccess() )
209 return sc;
210 if ( !(sc=readBranch(refs(),"Params", params(), &RootTool::addParam)).isSuccess() )
211 return sc;
212 return sc;
213 }
214 return StatusCode::FAILURE;
215 }
217 string getEntry(const string& c) { return c; }
219 string getParam(const pair<string,string>& p) { return p.first+"="+p.second; }
221 template <class C, class F> StatusCode saveBranch(const char* nam, C& v, F pmf) {
222 Long64_t i, n;
223 string val, typ = nam;
224 StatusCode sc = StatusCode::SUCCESS;
225 TDirectory::TContext ctxt(c->file());
226 TBranch* b = refs()->GetBranch(nam);
227 if ( !b ) b = refs()->Branch(nam,0,(typ+"/C").c_str());
228 if ( b ) {
229 for(i=b->GetEntries(), n=Long64_t(v.size()); i<n; ++i) {
230 val = (this->*pmf)(v[size_t(i)]);
231 b->SetAddress((char*)val.c_str());
232 msgSvc() << MSG::VERBOSE << "Save Value[" << b->GetName() << "]:" << val << endmsg;
233 if ( b->Fill() < 0 ) sc = StatusCode::FAILURE;
234 }
235 return sc;
236 }
237 return StatusCode::FAILURE;
238 }
240 StatusCode saveRefs() {
241 if ( refs() ) {
242 if ( !saveBranch("Databases", dbs(), &RootTool::getEntry).isSuccess() )
243 return StatusCode::FAILURE;
244 if ( !saveBranch("Containers",conts(), &RootTool::getEntry).isSuccess() )
245 return StatusCode::FAILURE;
246 if ( !saveBranch("Links", links(), &RootTool::getEntry).isSuccess() )
247 return StatusCode::FAILURE;
248 if ( !saveBranch("Params", params(),&RootTool::getParam).isSuccess() )
249 return StatusCode::FAILURE;
250 return StatusCode::SUCCESS;
251 }
252 return StatusCode::FAILURE;
253 }
254 };
255 }