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