ATLAS Offline Software
DivideByHist.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3 */
4 
9 #ifndef DQM_ALGORITHMS_SUMMARY_DIVIDEBYHIST_CXX
10 #define DQM_ALGORITHMS_SUMMARY_DIVIDEBYHIST_CXX
11 
12 #include <dqm_core/AlgorithmConfig.h>
14 #include <dqm_core/AlgorithmManager.h>
15 
16 #include <dqm_core/Result.h>
17 #include <dqm_core/Parameter.h>
18 
19 #include <TH1.h>
20 #include <TClass.h>
22 
24 
26 
27 #ifndef DQM_ALGORITHMS_MULTIALGORITHMTEST
29 #endif //#ifndef DQM_ALGORITHMS_MULTIALGORITHMTEST
30 
31 
33 {
34  dqm_core::AlgorithmManager::instance().registerSummaryMaker("DivideByHist",this);
35 }
36 
38 {
39 }
40 
43 {
44  return new DivideByHist();
45 }
46 
49  const dqm_core::Result & lastResult,
50  const dqm_core::ParametersMap & map)
51 {
52  //General summary maker infrastructure: (This can be resused)
53  dqm_core::Result *newresult = new dqm_core::Result();
54 
55  std::multimap<std::string,TObject*> inputs;
57 
58  dqm_core::Result * overWriteResult = 0;
59 
60  //Loop over elements of the parameter map to extract histograms and there roles, if any:
61  for (dqm_core::ParametersMap::const_iterator iter=map.begin();iter!=map.end();++iter){
62  //If weight is 0 skip this result. Allow to "turn off"
63  // results in summary makers
64  if ( iter->second->getWeight() == 0 ) {
65  ERS_DEBUG(2,"Skip result (weight 0): "<<iter->first);
66  continue;
67  }
68  TObject* inputobject = iter->second->getResult().get()->getObject();
69  if (inputobject == 0) {
70  //This is a sign that we just don't have all the parameters yet (summary makers are called every time a parameter comes in,
71  // so when the first one comes, the second one isn't in yet, so we get a null pointer).
72  newresult->status_ = lastResult.status_;
73  return newresult;
74  }
75  else {
76  //This seems to be a good object, try to find it's role and store a pointer to it if we do:
77  std::string role;
78  for (std::map<std::string,double>::const_iterator tagIter=iter->second->getResult().get()->tags_.begin();
79  tagIter != iter->second->getResult().get()->tags_.end(); ++tagIter ) {
80  std::string tag = tagIter->first;
81  size_t stringPos;
82  std::string tagType = "ConfParameter--Role--";
83  if ( (stringPos = tag.find(tagType)) != std::string::npos) {
84  stringPos += tagType.length();
85  role = tag.substr(stringPos);
86  break;
87  }
88  }
89  //Only keep objects with a valid role:
90  if(role.size() != 0) {
91  inputs.insert(std::pair<std::string,TObject*>(role,inputobject));
92  }
93  }
94  }
95 
96  if(inputs.size() < 2) {
97  newresult->status_ = lastResult.status_;
98  return newresult;
99  }
100 
101  //Extract config information from result tags in the parameter map, only extract config info from the first result
102  //found when iterating backwards which has nonzero tags.
103 
104  std::map<std::string,double > paramVecMap;
105  for (dqm_core::ParametersMap::const_reverse_iterator rIter=map.rbegin() ; rIter!=map.rend();++rIter) {
106  if( rIter->second->getResult().get()->tags_.empty() ){
107  continue;
108  }
109  for (std::map<std::string,double>::const_iterator tagIter=rIter->second->getResult().get()->tags_.begin();
110  tagIter != rIter->second->getResult().get()->tags_.end(); ++tagIter ) {
111  std::string tag = tagIter->first;
112  size_t stringPos;
113  std::string tagType;
114 
115  tagType = "ConfParameter--Role--";
116  if ( tag.find(tagType) != std::string::npos ){
117  //Already dealt with,
118  continue;
119  }
120  tagType = "ConfParameter--OverWrite";
121  if ( tag.find(tagType) != std::string::npos ){
122  //This parameter wants to be overwriten, remember this for later and continue:
123  overWriteResult = rIter->second->getResult().get();
124  //Disable updating of the parameter:
125  // rIter->second->stateChanged(false,false); (uncomment once dqm_core-01-10-00 is available)
126  continue;
127  }
128  tagType = "ConfParameter--";
129  if ( (stringPos = tag.find(tagType)) != std::string::npos ){
130  //This is a single member config parameter; add it:
131  stringPos += tagType.length();
132  algConfig.addParameter( tag.substr(stringPos),tagIter->second );
133  continue;
134  }
135  tagType = "GThreshold--";
136  if ( (stringPos = tag.find(tagType)) != std::string::npos ){
137  //This is a green threshold; add it:
138  stringPos += tagType.length();
139  algConfig.addGreenThreshold( tag.substr(stringPos),tagIter->second );
140  continue;
141  }
142  tagType = "RThreshold--";
143  if ( (stringPos = tag.find(tagType)) != std::string::npos ){
144  //This is a red threshold; add it:
145  stringPos += tagType.length();
146  algConfig.addRedThreshold( tag.substr(stringPos),tagIter->second );
147  continue;
148  }
149  if ( tag.find("ConfParameter[") != std::string::npos ){
150  std::cerr<< "MULTIOPTION PARAMETERS NO LONGER SUPPORTED; IGNORING" << std::endl;
151  // //This is an element of a configuration parameter vector; we can't add it yet
152  // stringPos = tag.find("]--") + 3;
153  // paramVecMap[tag.substr(stringPos)].push_back(tagIter->second);
154  }
155  }//end loop over result tags
156  break; //Assume that the first non-empty set of tags is all that is needed, so continue without looking at more parameters.
157  }//end loop over parameters map
158 
159  //Now loop over the paramVecMap to finish the algConfig
160  for ( std::map<std::string,double>::const_iterator pvIter=paramVecMap.begin(); pvIter!=paramVecMap.end();++pvIter){
161  algConfig.addParameter( pvIter->first, pvIter->second );
162  }
163 
164  delete newresult;
165  newresult = execute(name,inputs,algConfig);
166 
167  // Note: this is experimental and may not work:
168  if ((overWriteResult != 0) && (newresult->getObject() != 0) ) {
169 
170  //A parameter wanted to have it's result overwritten with the results of this summary maker, let us do it:
171  overWriteResult->status_ = newresult->status_;
172  overWriteResult->tags_ = newresult->tags_;
173 
174  TObject* overWriteObject = overWriteResult->getObject();
175  if ( (!overWriteObject->IsA()->InheritsFrom("TH1")) || (!newresult->getObject()->IsA()->InheritsFrom("TH1")) ) {
176  //Do nothing: overwriting a non TH1 object might be a bad idea.
177  }
178  else {
179 
180  TH1* hOverW = (TH1*) overWriteObject;
181  TH1* hResult = (TH1*) newresult->getObject();
182 
183  if (hOverW->GetDimension() == hResult->GetDimension()) {
184  hOverW->Reset();
185  hOverW->Add(hResult);
186  }
187  }
188  }
189 
190  return newresult;
191 }
192 
195  const std::multimap<std::string,TObject*> & inputs,
196  const dqm_core::AlgorithmConfig& config)
197 {
198  // dqm_core::Result *newresult = new dqm_core::Result();
199  dqm_core::Result *newresult(0);
200 
201  TH1 * hNumerator = 0;
202  TH1 * hDenominator = 0;
203  TH1 * hQuotient = 0;
204 
205  TObject * numero = 0;
206  TObject * denomino = 0;
207 
208  if( inputs.size() < 2 ){
209  throw dqm_core::BadConfig( ERS_HERE, name ,"incorrect number of arguements, number of inputs for division must be at least two");
210  }
211 
212  //Retrieve the Histograms to be divided, using their specified roles:
213  std::multimap<std::string,TObject*>::const_iterator mmItr;
214 
215  mmItr = inputs.find("Numerator");
216  if ( mmItr != inputs.end() ) {
217  numero = mmItr->second;
218  }
219  else {
220  throw dqm_core::BadConfig( ERS_HERE, name, "no object with 'Role--Numerator' was specified.");
221  }
222  mmItr = inputs.find("Denominator");
223  if ( mmItr != inputs.end() ) {
224  denomino = mmItr->second;
225  }
226  else {
227  throw dqm_core::BadConfig( ERS_HERE, name, "no object with 'Role--Denominator' was specified.");
228  }
229 
230  if( numero->IsA()->InheritsFrom("TH1") ){
231  hNumerator = (TH1*) numero;
232  }
233  else {
234  char errorStr[64];
235  sprintf(errorStr,"%s does not inherit from TH1",numero->GetName());
236  throw dqm_core::BadConfig( ERS_HERE, name, errorStr);
237  }
238  if( denomino->IsA()->InheritsFrom("TH1") ){
239  hDenominator = (TH1*) denomino;
240  }
241  else {
242  char errorStr[64];
243  sprintf(errorStr,"%s does not inherit from TH1",denomino->GetName());
244  throw dqm_core::BadConfig( ERS_HERE, name, errorStr);
245  }
246 
247  //Perform the division:
248  hQuotient = dqm_algorithms::tools::DivideByHistogram(hNumerator,hDenominator);
249 
250  //Modify the resultant histogram if requested by config:
252 
253  //Extract the name of the algorithm to run:
254  std::string algorithmName = dqm_algorithms::tools::ExtractAlgorithmName(config);
255 
256  //Run the algorithm:
257  newresult = dqm_algorithms::tools::ExecuteNamedAlgorithm(algorithmName,*hQuotient,config);
258 
259  //Make the quotient histogram the output result object
260  newresult->object_ = (boost::shared_ptr<TObject>)(TObject*)hQuotient;
261 
262  return newresult;
263 }
264 
265 #endif // #ifndef DQM_ALGORITHMS_SUMMARY_DIVIDEBYHIST_CXX
dqm_algorithms::tools::SimpleAlgorithmConfig::addRedThreshold
void addRedThreshold(std::string, double)
Definition: SimpleAlgorithmConfig.cxx:69
dqm_algorithms::summary::DivideByHist
Definition: DivideByHist.h:22
dqm_algorithms::tools::ModifyHistogram
void ModifyHistogram(TH1 *histogram, const dqm_core::AlgorithmConfig &config)
Definition: AlgorithmHelper.cxx:661
dqm_algorithms::summary::DivideByHist::clone
DivideByHist * clone()
Definition: DivideByHist.cxx:42
dqm_algorithms::tools::ExecuteNamedAlgorithm
dqm_core::Result * ExecuteNamedAlgorithm(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config)
Definition: AlgorithmHelper.cxx:640
dqm_algorithms::summary::DivideByHist::~DivideByHist
~DivideByHist()
Definition: DivideByHist.cxx:37
postInclude.inputs
inputs
Definition: postInclude.SortInput.py:15
dqm_algorithms::tools::ExtractAlgorithmName
std::string ExtractAlgorithmName(const dqm_core::AlgorithmConfig &config)
Definition: AlgorithmHelper.cxx:615
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
LArG4FSStartPointFilterLegacy.execute
execute
Definition: LArG4FSStartPointFilterLegacy.py:20
dqm_algorithms::summary::DivideByHist::DivideByHist
DivideByHist()
Definition: DivideByHist.cxx:32
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
dqm_algorithms::tools::SimpleAlgorithmConfig::addParameter
void addParameter(std::string, double)
Definition: SimpleAlgorithmConfig.cxx:51
Result
ICscStripFitter::Result Result
Definition: CalibCscStripFitter.cxx:13
dqm_algorithms::tools::SimpleAlgorithmConfig
This class provides a simple implementation of the DQMF abstract AlgorithmConfig interface which can ...
Definition: SimpleAlgorithmConfig.h:22
dqm_algorithms::summary::DivideByHist::execute
dqm_core::Result * execute(const std::string &name, const dqm_core::Result &, const dqm_core::ParametersMap &)
Definition: DivideByHist.cxx:48
dqm_algorithms::tools::DivideByHistogram
TH1 * DivideByHistogram(const TH1 *hNumerator, const TH1 *hDenominator)
Definition: AlgorithmHelper.cxx:446
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
checkRpcDigits.errorStr
string errorStr
Definition: checkRpcDigits.py:182
Bins_Diff_FromAvg.h
dqm_algorithms::tools::SimpleAlgorithmConfig::addGreenThreshold
void addGreenThreshold(std::string, double)
Definition: SimpleAlgorithmConfig.cxx:63
AlgorithmHelper.h
SimpleAlgorithmConfig.h
CaloCondBlobAlgs_fillNoiseFromASCII.tag
string tag
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:24
DivideByHist.h