001
002
003 #include "JetTagTools/LikelihoodMultiDTool.h"
004
005 #include "GaudiKernel/DataObject.h"
006 #include "GaudiKernel/MsgStream.h"
007 #include "JetTagTools/HistoHelperRoot.h"
008 #include <string>
009 #include <utility>
010 #include <vector>
011 #include <cmath>
012
013 #include "GaudiKernel/ITHistSvc.h"
014 #include "TH1.h"
015 #include "TH2.h"
016 #include "TH3.h"
017
018 namespace Analysis
019 {
020
021 LikelihoodMultiDTool::LikelihoodMultiDTool(const std::string& t, const std::string& n, const IInterface* p) :
022 AlgTool(t,n,p),
023 m_histoSvc(0),
024
025 m_useTheseLhVariables(std::vector<std::string>()),
026 m_mapOfAllHistos(std::vector<std::map<std::string, TH1*>* >()),
027 m_histoLimitsMap1D(std::map< std::string, HistoLimits>() ),
028 m_histoLimitsMap2D(std::map< std::string, HistoLimits>() ),
029 m_histoLimitsMap3D(std::map< std::string, HistoLimits>() ),
030 m_lhVariableValues(std::vector<Slice> ()),
031 m_likelihoodVector(std::vector<double>()),
032 m_nhis1D(0),
033 m_nhis2D(0),
034 m_nhis3D(0),
035 m_DoInterpol(false),
036 m_WriteSmoothedHistos(false),
037 m_nbHypotheses(2),
038 m_nSmooth1D(1),
039 m_normProb(true)
040 {
041 declareInterface<LikelihoodMultiDTool>(this);
042 declareProperty("WriteSmoothedHistos", m_WriteSmoothedHistos);
043 declareProperty("NSmooth1D", m_nSmooth1D);
044 declareProperty("NormalizeProb", m_normProb);
045 }
046
047 LikelihoodMultiDTool::~LikelihoodMultiDTool()
048 {
049 for (std::vector< std::map<std::string, TH1*>* >::iterator itr = m_mapOfAllHistos.begin();
050 itr != m_mapOfAllHistos.end(); ++itr) delete (*itr);
051 }
052
053 StatusCode LikelihoodMultiDTool::initialize()
054 {
055 MsgStream mlog(msgSvc(),name());
056
057 StatusCode sc = service("THistSvc", m_histoSvc);
058 if (sc.isFailure())
059 {
060 mlog << MSG::FATAL << "THistSvc not found!" << endreq;
061 return StatusCode::FAILURE;
062 }
063
064 return StatusCode::SUCCESS;
065 }
066
067 StatusCode LikelihoodMultiDTool::finalize()
068 {
069 return StatusCode::SUCCESS;
070 }
071
072 void LikelihoodMultiDTool::prepareHistosFromFile(const std::string& refFileName) {
073 MsgStream mlog(msgSvc(),name());
074 mlog<<MSG::DEBUG<<"refFileName= "<<refFileName<<endreq;
075
076 std::map<std::string, TH1*>* tmpHistoMap = new std::map<std::string, TH1*>();
077
078 for (std::vector<std::string>::iterator itr = m_useTheseLhVariables.begin() ;
079 itr != m_useTheseLhVariables.end() ; ++itr ) {
080 std::string histoName = *itr;
081 std::vector<std::string> grades;
082
083
084
085 std::vector<std::string> words;
086 mlog<<MSG::DEBUG<<"decoding histoName= "<<histoName<<endreq;
087 const std::string delim("_");
088 std::string::size_type sPos, sEnd, sLen;
089 sPos = histoName.find_first_not_of(delim);
090 while ( sPos != std::string::npos ) {
091 sEnd = histoName.find_first_of(delim, sPos);
092 if(sEnd==std::string::npos) sEnd = histoName.length();
093 sLen = sEnd - sPos;
094 std::string word = histoName.substr(sPos,sLen);
095 mlog<<MSG::DEBUG<<" -> word = "<<word<<endreq;
096 words.push_back(word);
097 sPos = histoName.find_first_not_of(delim, sEnd);
098 }
099
100 int nGrade = words.size() - 2;
101 TH1* histoSum(0);
102 if(nGrade==0) {
103 mlog<<MSG::DEBUG<<"Histo "<<histoName<<" has "<<nGrade<<" grade: direct retrieval"<<endreq;
104 histoSum = this->retrieveHistoFromFile(refFileName, words[1], words[0]);
105 } else if(nGrade==1) {
106 mlog<<MSG::DEBUG<<"Histo "<<histoName<<" has "<<nGrade<<" grade: direct retrieval"<<endreq;
107 histoSum = this->retrieveHistoFromFile(refFileName, words[1]+"_"+words[2], words[0]);
108 } else {
109
110 mlog<<MSG::DEBUG<<"Histo "<<histoName<<" has "<<nGrade<<" grades:"<<endreq;
111 for(int i=1;i<=nGrade;i++) {
112 mlog<<MSG::DEBUG<<" -> retrieving histo for grade "<<i
113 <<" : "<<words[1]<<" "<<words[i+1]<<endreq;
114 TH1* histo = this->retrieveHistoFromFile(refFileName, words[1]+"_"+words[i+1], words[0]);
115 mlog<<MSG::DEBUG<<" #entries= "<<histo->GetEntries()<<endreq;
116 if(1==i) {
117 histoSum = histo;
118 } else {
119 histoSum->Add(histo,1.);
120 }
121 mlog<<MSG::DEBUG<<" #entries for Sum= "<<histoSum->GetEntries()<<endreq;
122 }
123 }
124 if(histoSum) {
125
126 double norm = histoSum->Integral();
127 if(norm) {
128 if(1==histoSum->GetDimension() && m_nSmooth1D) {
129 if(histoName.find("N2T")==std::string::npos){
130 if(norm>10000)histoSum->Smooth(m_nSmooth1D);
131 else histoSum->Smooth((int)(m_nSmooth1D*100./sqrt(norm)));
132 }
133 }
134 if(2==histoSum->GetDimension()) {
135 int m2d=3;
136 if(refFileName.find("Bkg/")!=std::string::npos) m2d=5;
137 bool debug = mlog.level()<=MSG::DEBUG ? true : false;
138
139 if(histoName.find("Sip3D")==std::string::npos) HistoHelperRoot::smoothASH2D(dynamic_cast<TH2*>(histoSum), m2d, m2d, debug);
140 }
141 if(3==histoSum->GetDimension()) {
142 int m3d1=3;
143 int m3d3=2;
144 bool debug = mlog.level()<=MSG::DEBUG ? true : false;
145 HistoHelperRoot::smoothASH3D(dynamic_cast<TH3*>(histoSum), m3d1, m3d1, m3d3, debug);
146 }
147 norm = histoSum->Integral();
148 histoSum->Scale(1./norm);
149 } else {
150 mlog<<MSG::WARNING<<"Histo "<<histoName<<" is empty!"<<endreq;
151 }
152
153
154 std::string namemap = histoName;
155 if (nGrade == 0) {
156 namemap = words[0]+"_"+words[1];
157 mlog << MSG::VERBOSE << "Inserting as " << namemap << endreq;
158 tmpHistoMap->insert(std::pair<std::string, TH1*>(namemap, histoSum));
159 }
160 for(int i=1;i<=nGrade;i++) {
161 namemap = words[0] + "_" + words[1] + "_" + words[i+1];
162 mlog << MSG::VERBOSE << "Inserting as " << namemap << endreq;
163 tmpHistoMap->insert(std::pair<std::string, TH1*>(namemap, histoSum));
164 }
165
166 if (m_WriteSmoothedHistos) {
167 std::string namedir = refFileName; namedir = namedir.substr((namedir.erase(namedir.size()-1,1)).rfind('/')+1)+"/";
168 std::string namehis = histoSum->GetName();
169 mlog << MSG::VERBOSE << "Registering smoothed histogram in " << namedir << endreq;
170 TH1* histoSumClone = (TH1*)histoSum->Clone();
171 StatusCode sc = m_histoSvc->regHist("/ControlFile/"+namedir+namehis, histoSumClone);
172 if (sc.isFailure()) {
173 mlog<<MSG::ERROR<<"Cannot store the smoothed histogram in the control file !"<<endreq;
174 }
175 }
176 }
177 }
178 mlog << MSG::DEBUG <<"I found "<<m_nhis1D<<" 1D histos, "<<m_nhis2D<<" 2D histos and "<<m_nhis3D<<" 3D histos"<<endreq;
179 if (m_nhis1D+m_nhis2D+m_nhis3D) m_mapOfAllHistos.push_back(tmpHistoMap);
180 }
181
182 TH1* LikelihoodMultiDTool::retrieveHistoFromFile(const std::string& refFileName,
183 const std::string& histoName,
184 const std::string& jetPrefix) {
185 std::string fullPath(refFileName+histoName);
186 MsgStream mlog(msgSvc(),name());
187 mlog << MSG::VERBOSE << "Retrieving histo: " << fullPath << endreq;
188 bool is1D = false, is2D = false, is3D = false;
189 TH1* tmphisto(0);
190 StatusCode sc = m_histoSvc->regHist(fullPath);
191 if(sc.isFailure()) {};
192 sc = m_histoSvc->getHist(fullPath,tmphisto);
193 int dim = 0;
194 if (sc.isSuccess()) {
195 dim = tmphisto->GetDimension();
196 if (dim == 1) {
197 is1D = true;
198 m_nhis1D++;
199 } else if (dim == 2) {
200 is2D = true;
201 m_nhis2D++;
202 } else if (dim == 3) {
203 is3D = true;
204 m_nhis3D++;
205 } else {
206 mlog << MSG::DEBUG << "cannot retrieve histo " << fullPath
207 << " Unexpected dimension "<< dim << endreq;
208 return tmphisto;
209 }
210 } else {
211 mlog << MSG::DEBUG << "I COULD NOT RETRIEVE HISTO: " << fullPath << endreq;
212 return tmphisto;
213 }
214
215 unsigned int bins = (tmphisto->GetXaxis())->GetNbins();
216 double minx = (tmphisto->GetXaxis())->GetXmin();
217 double maxx = (tmphisto->GetXaxis())->GetXmax();
218 if (is1D) {
219 m_histoLimitsMap1D[jetPrefix+"_"+histoName] = HistoLimits(bins, minx, maxx);
220 mlog << MSG::DEBUG <<"Histo "<< jetPrefix+"_"+histoName << " properties: " << endreq;
221 mlog << MSG::DEBUG << bins <<" bins X between " << minx <<" and " << maxx << endreq;
222 } else if (is2D) {
223 unsigned int binsy = (tmphisto->GetYaxis())->GetNbins();
224 double miny = (tmphisto->GetYaxis())->GetXmin();
225 double maxy = (tmphisto->GetYaxis())->GetXmax();
226 m_histoLimitsMap2D[jetPrefix+"_"+histoName] = HistoLimits(bins, minx, maxx, binsy, miny, maxy);
227 mlog << MSG::DEBUG <<"Histo "<< jetPrefix+"_"+histoName << " properties: " << endreq;
228 mlog << MSG::DEBUG << bins <<" bins X between " << minx <<" and " << maxx << endreq;
229 mlog << MSG::DEBUG << binsy <<" bins Y between " << miny <<" and " << maxy << endreq;
230 } else if (is3D) {
231 unsigned int binsy = (tmphisto->GetYaxis())->GetNbins();
232 double miny = (tmphisto->GetYaxis())->GetXmin();
233 double maxy = (tmphisto->GetYaxis())->GetXmax();
234 unsigned int binsz = (tmphisto->GetZaxis())->GetNbins();
235 double minz = (tmphisto->GetZaxis())->GetXmin();
236 double maxz = (tmphisto->GetZaxis())->GetXmax();
237 m_histoLimitsMap3D[jetPrefix+"_"+histoName] = HistoLimits(bins, minx, maxx, binsy, miny, maxy, binsz, minz, maxz);
238 mlog << MSG::DEBUG <<"Histo "<< jetPrefix+"_"+histoName << " properties: " << endreq;
239 mlog << MSG::DEBUG << bins <<" bins X between " << minx <<" and " << maxx << endreq;
240 mlog << MSG::DEBUG << binsy <<" bins Y between " << miny <<" and " << maxy << endreq;
241 mlog << MSG::DEBUG << binsz <<" bins Z between " << minz <<" and " << maxz << endreq;
242 }
243 return tmphisto;
244 }
245
246 void LikelihoodMultiDTool::setLhVariableValue(std::vector<Slice>& value)
247 {
248 m_lhVariableValues=value;
249 }
250 void LikelihoodMultiDTool::setLhVariableValue(Slice& value)
251 {
252 std::vector<Slice> tmpVector;
253 tmpVector.push_back(value);
254 setLhVariableValue(tmpVector);
255 }
256
257
258 std::vector<double> LikelihoodMultiDTool::calculateLikelihood() {
259 m_likelihoodVector.clear();
260 MsgStream mlog(msgSvc(),name());
261 std::vector<double> probDensityPerEventClassAllVariables;
262 mlog<<MSG::VERBOSE <<"The sizes of the maps "<<m_mapOfAllHistos.size()<<" "<<m_nbHypotheses<<endreq;
263 probDensityPerEventClassAllVariables.resize(m_nbHypotheses);
264 for (unsigned int i = 0 ; i < m_nbHypotheses; ++i) {
265 probDensityPerEventClassAllVariables[i]=1.;
266 }
267
268
269 for (unsigned int iel = 0; iel<m_lhVariableValues.size(); iel++) {
270 int ncompo = m_lhVariableValues[iel].composites.size();
271 mlog<<MSG::VERBOSE<<"-- element "<<iel<<" "<<m_lhVariableValues[iel].name<<" has "<<ncompo<<" composites."<<endreq;
272
273
274 for (int icompo = 0;icompo<ncompo;icompo++) {
275 double sum(0.);
276 std::vector<double> tmpVector;
277 std::string histName = m_lhVariableValues[iel].composites[icompo].name;
278 int idim = m_lhVariableValues[iel].composites[icompo].atoms.size();
279 mlog<<MSG::VERBOSE<<" -- composite "<<icompo<<" histo= "<<histName<<" dim= "<<idim<<endreq;
280 if (idim == 1) {
281 const HistoLimits& histoLimits = (*(m_histoLimitsMap1D.find(histName))).second;
282
283 for (std::vector< std::map<std::string, TH1*>* >::iterator
284 itr2 = m_mapOfAllHistos.begin() ;
285 itr2 != m_mapOfAllHistos.end() ; ++itr2 ) {
286 if( (*itr2)->find(histName) != (*itr2)->end() ) {
287 TH1* tmpHisto = (*((*itr2)->find(histName))).second;
288 double value = m_lhVariableValues[iel].composites[icompo].atoms[0].value;
289 int bin((tmpHisto->GetXaxis())->FindBin(value));
290 double tmp(0);
291 if(!m_DoInterpol) {
292 if(value>= histoLimits.xmax) bin = histoLimits.bins;
293 if(value<= histoLimits.xmin) bin = 1;
294 tmp = tmpHisto->GetBinContent(bin);
295 }
296 else {
297 tmp = HistoHelperRoot::Interpol1d(value,dynamic_cast<TH1*>(tmpHisto));
298 }
299 mlog<<MSG::VERBOSE<<" (1D) value= "<<value<<" bin= "<<bin<< " f = "<<tmp<<endreq;
300 if (!m_normProb) {
301 double binw = tmpHisto->GetBinWidth(bin);
302 if(binw != 0.)tmp /= binw;
303 else mlog<<MSG::ERROR<<"Bin width is 0."<<endreq;
304 mlog<<MSG::VERBOSE<<" (1D) value= "<<value<<" bin= "<<bin<<" binw= "<<binw<< " f = "<<tmp<<endreq;
305 }
306 tmpVector.push_back(tmp);
307 sum += tmp;
308 }
309 }
310 } else if (idim == 2) {
311 const HistoLimits& histoLimits = (*(m_histoLimitsMap2D.find(histName))).second;
312 for (std::vector< std::map<std::string, TH1*>* >::iterator
313 itr2 = m_mapOfAllHistos.begin() ;
314 itr2 != m_mapOfAllHistos.end() ; ++itr2 ) {
315 if( (*itr2)->find(histName) != (*itr2)->end() ) {
316 TH1* tmpHisto = (*((*itr2)->find(histName))).second;
317 mlog<<MSG::VERBOSE<<"tmpHisto="<<tmpHisto<<endreq;
318 double valuex = m_lhVariableValues[iel].composites[icompo].atoms[0].value;
319 double valuey = m_lhVariableValues[iel].composites[icompo].atoms[1].value;
320 int binx((tmpHisto->GetXaxis())->FindBin(valuex));
321 int biny((tmpHisto->GetYaxis())->FindBin(valuey));
322 if(valuex>= histoLimits.xmax) binx = histoLimits.bins;
323 if(valuex<= histoLimits.xmin) binx = 1;
324 if(valuey>= histoLimits.ymax) biny = histoLimits.binsy;
325 if(valuey<= histoLimits.ymin) biny = 1;
326 double tmp(tmpHisto->GetBinContent(binx,biny));
327 mlog<<MSG::VERBOSE<<" (2D) value= "<<valuex<<" "<<valuey<<" bin= "<<binx<<" "<<biny<< " f = "<<tmp<<endreq;
328 if (!m_normProb) {
329 double binw = tmpHisto->GetXaxis()->GetBinWidth(binx) * tmpHisto->GetYaxis()->GetBinWidth(biny);
330 if(binw != 0.)tmp /= binw;
331 else mlog<<MSG::ERROR<<"Bin area is 0."<<endreq;
332 mlog<<MSG::VERBOSE<<" (2D) value= "<<valuex<<" "<<valuey<<" bin= "<<binx<<" "<<biny<<" binw= "<<binw<< " f = "<<tmp<<endreq;
333 }
334 tmpVector.push_back(tmp);
335 sum += tmp;
336 }
337 }
338 } else if (idim == 3) {
339 const HistoLimits& histoLimits = (*(m_histoLimitsMap3D.find(histName))).second;
340 for (std::vector< std::map<std::string, TH1*>* >::iterator
341 itr2 = m_mapOfAllHistos.begin() ;
342 itr2 != m_mapOfAllHistos.end() ; ++itr2 ) {
343 if( (*itr2)->find(histName) != (*itr2)->end() ) {
344 TH1* tmpHisto = (*((*itr2)->find(histName))).second;
345 double valuex = m_lhVariableValues[iel].composites[icompo].atoms[0].value;
346 double valuey = m_lhVariableValues[iel].composites[icompo].atoms[1].value;
347 double valuez = m_lhVariableValues[iel].composites[icompo].atoms[2].value;
348 int binx((tmpHisto->GetXaxis())->FindBin(valuex));
349 int biny((tmpHisto->GetYaxis())->FindBin(valuey));
350 int binz((tmpHisto->GetZaxis())->FindBin(valuez));
351 if(valuex>= histoLimits.xmax) binx = histoLimits.bins;
352 if(valuex<= histoLimits.xmin) binx = 1;
353 if(valuey>= histoLimits.ymax) biny = histoLimits.binsy;
354 if(valuey<= histoLimits.ymin) biny = 1;
355 if(valuez>= histoLimits.zmax) binz = histoLimits.binsz;
356 if(valuez<= histoLimits.zmin) binz = 1;
357 double tmpNoInt(tmpHisto->GetBinContent(binx,biny,binz));
358 double tmp(HistoHelperRoot::Interpol3d(valuex,valuey,valuez,dynamic_cast<TH3*>(tmpHisto)));
359 mlog<<MSG::VERBOSE<<" (3D) value= "<<valuex<<" "<<valuey<<" "<<valuez
360 <<" bin= "<<binx<<" "<<biny<<" "<<binz<<" binContent = "<<tmp<< " binContentNoInt = "<< tmpNoInt <<endreq;
361 if (!m_normProb) {
362 double binw =
363 tmpHisto->GetXaxis()->GetBinWidth(binx) *
364 tmpHisto->GetYaxis()->GetBinWidth(biny) *
365 tmpHisto->GetZaxis()->GetBinWidth(binz);
366 if(binw != 0.) {
367 tmpNoInt /= binw;
368 tmp /= binw;
369 }
370 else mlog<<MSG::ERROR<<"Bin volume is 0."<<endreq;
371 mlog<<MSG::VERBOSE<<" (3D) value= "<<valuex<<" "<<valuey<<" "<<valuez
372 <<" bin= "<<binx<<" "<<biny<<" "<<binz<<" binw= "<<binw<<" binContent = "<<tmp<< " binContentNoInt = "<< tmpNoInt <<endreq;
373 }
374 if (m_DoInterpol) {
375 tmpVector.push_back(tmp);
376 sum += tmp;
377 } else {
378 tmpVector.push_back(tmpNoInt);
379 sum += tmpNoInt;
380 }
381 }
382 }
383 } else {
384 mlog <<MSG::WARNING <<"No more that 3D pdf for the time being !"<<endreq;
385 }
386 unsigned int classCount(0);
387 for (std::vector<double>::iterator itr3 = tmpVector.begin(); itr3 != tmpVector.end(); ++itr3) {
388 if (sum != 0.) {
389 mlog<<MSG::VERBOSE<<"pb + pu = "<<sum<<endreq;
390 double p = (*itr3);
391 if (m_normProb) p /= sum;
392 probDensityPerEventClassAllVariables[classCount] *= p;
393 } else {
394 mlog<<MSG::WARNING<<"Empty bins for all hypothesis... The discriminating variables are not taken into account in this jet"<<endreq;
395 mlog<<MSG::WARNING<<"Check your inputs"<<endreq;
396 }
397 mlog<<MSG::VERBOSE<<" probDensity= "<<probDensityPerEventClassAllVariables[classCount]<<" ic= "<<classCount<<endreq;
398 classCount++;
399 }
400 mlog<<MSG::VERBOSE<<" Final probDensity= "<<probDensityPerEventClassAllVariables<<endreq;
401 }
402 }
403 mlog<<MSG::VERBOSE<<" Ending ..."<<endreq;
404 m_likelihoodVector=probDensityPerEventClassAllVariables;
405 return m_likelihoodVector;
406 }
407
408 std::vector<double> LikelihoodMultiDTool::tagLikelihood()
409 {
410 return m_likelihoodVector;
411 }
412
413 void LikelihoodMultiDTool::printStatus()
414 {
415 MsgStream mlog(msgSvc(),name());
416 unsigned int num = m_mapOfAllHistos.size();
417 mlog << MSG::INFO << "Currently I hold histos of " << num << " input files" << endreq;
418
419 }
420
421 double LikelihoodMultiDTool::getEff(const std::string& refFileName, const std::string& histoName, const std::string& mode)
422 {
423 MsgStream mlog(msgSvc(),name());
424
425 StatusCode scs = SUCCESS, scg = SUCCESS;
426 std::string fullPathSel(refFileName+histoName+"Eff"+mode);
427 std::string fullPathGen(refFileName+histoName+"Norm"+mode);
428 mlog << MSG::VERBOSE << "Retrieving histo for efficiency computation: " << fullPathSel << endreq;
429 mlog << MSG::VERBOSE << "Retrieving histo for efficiency computation: " << fullPathGen << endreq;
430 TH1 *sel(0), *gen(0);
431 scs = m_histoSvc->regHist(fullPathSel);
432 scg = m_histoSvc->regHist(fullPathGen);
433 if (scs.isSuccess() && scg.isSuccess()) {
434 scs = m_histoSvc->getHist(fullPathSel,sel);
435 scg = m_histoSvc->getHist(fullPathGen,gen);
436 if (sel && gen && scs.isSuccess() && scg.isSuccess()) {
437 double nsel = sel->GetEntries();
438 double ngen = gen->GetEntries();
439 if (ngen != 0) {
440 mlog << MSG::VERBOSE << "N RecSvx = " << nsel << " in a total of "<< ngen << " jets." << endreq;
441 return nsel/ngen;
442 } else {
443 mlog << MSG::ERROR << "Pb in computing Svx efficiency " << nsel << " "<< ngen << endreq;
444 return 0.;
445 }
446 }
447 } else {
448
449 scs = m_histoSvc->getHist(fullPathSel,sel);
450 scg = m_histoSvc->getHist(fullPathGen,gen);
451 if (sel && gen && scs.isSuccess() && scg.isSuccess()) {
452 double nsel = sel->GetEntries();
453 double ngen = gen->GetEntries();
454 if (ngen != 0) {
455 mlog << MSG::VERBOSE << "N RecSvx = " << nsel << " in a total of "<< ngen << " jets." << endreq;
456 return nsel/ngen;
457 } else {
458 mlog << MSG::ERROR << "Pb in computing Svx efficiency " << nsel << " "<< ngen << endreq;
459 return 0.;
460 }
461 }
462 }
463 mlog << MSG::ERROR << "Pb in computing Svx efficiency " << endreq;
464 return 0.;
465 }
466
467 void LikelihoodMultiDTool::addLhVariableToUse(const std::string& var) {
468 m_useTheseLhVariables.push_back(var);
469 }
470
471 }
| Due to the LXR bug, the updates fail sometimes to remove references to deleted files. The Saturday's full rebuilds fix these problems |
|
This page was automatically generated by the
LXR engine.
|
|