59 int main(
int argc,
char **argv)
72 JParser<> zap(
"Auxiliary program for histogram operations.");
74 zap[
'f'] =
make_field(inputFile,
"<input file>:<object name>");
90 <<
"\n\t\"" << JOpera::SAME_AS_OPERATION() <<
"\" -> same as operation; or"
91 <<
"\n\t\"" << JOpera::SAME_AS_INPUT() <<
"\" -> same as input; else"
92 <<
"\n\t as specified") = JOpera::SAME_AS_OPERATION();
97 catch(
const exception &error) {
98 FATAL(error.what() << endl);
106 DEBUG(
"Input: " << *input << endl);
111 ERROR(
"File: " << input->getFullFilename() <<
" not opened." << endl);
115 const TRegexp regexp(input->getObjectName());
117 TIter iter(dir->GetListOfKeys());
119 for (TKey* key; (key = (TKey*) iter.Next()) != NULL; ) {
121 const TString tag(key->GetName());
123 DEBUG(
"Key: " << tag <<
" match = " << tag.Contains(regexp) << endl);
127 if (tag.Contains(regexp) &&
isTObject(key)) {
130 TProfile* q =
dynamic_cast<TProfile*
>(p);
133 p = q->ProjectionX();
136 if (dynamic_cast<TH1*>(p) == NULL) {
137 FATAL(
"Object " << p->GetName() <<
" not compatible with histogram operations." << endl);
140 listOfObjects.push_back(p);
148 if (listOfObjects.size() == 0) {
150 FATAL(
"Number of histograms " << listOfObjects.size() <<
" = 0." << endl);
152 }
else if (listOfObjects.size() == 1 && (opera == JOpera::Add() ||
153 opera == JOpera::Subtract() ||
154 opera == JOpera::Multiply() ||
155 opera == JOpera::Divide() ||
156 opera == JOpera::Replace())) {
160 TH1* h1 =
dynamic_cast<TH1*
>(listOfObjects[0]);
161 TF1*
f1 = (TF1*) h1->GetListOfFunctions()->First();
164 FATAL(h1->GetName() <<
" has no associated function." << endl);
167 NOTICE(h1->GetName() <<
' ' << opera <<
' ' << f1->GetName() << endl);
169 if (
name == JOpera::SAME_AS_OPERATION())
170 h3 = (TH1*) h1->Clone(opera.c_str());
171 else if (
name == JOpera::SAME_AS_INPUT())
172 h3 = (TH1*) h1->Clone(h1->GetName());
174 h3 = (TH1*) h1->Clone(
name.c_str());
176 if (opera == JOpera::Add()) {
180 }
else if (opera == JOpera::Subtract()) {
184 }
else if (opera == JOpera::Multiply()) {
188 }
else if (opera == JOpera::Divide()) {
192 }
else if (opera == JOpera::Replace()) {
199 }
else if (listOfObjects.size() == 2) {
203 TH1* h1 =
dynamic_cast<TH1*
>(listOfObjects[0]);
204 TH1* h2 =
dynamic_cast<TH1*
>(listOfObjects[1]);
206 NOTICE(h1->GetName() <<
' ' << opera <<
' ' << h2->GetName() << endl);
208 if (
name == JOpera::SAME_AS_OPERATION())
209 h3 = (TH1*) h1->Clone(opera.c_str());
210 else if (
name == JOpera::SAME_AS_INPUT())
211 h3 = (TH1*) h1->Clone(h1->GetName());
213 h3 = (TH1*) h1->Clone(
name.c_str());
215 if (opera == JOpera::Add()) {
217 h3->Add (h1, h2, +1.0, +1.0);
219 }
else if (opera == JOpera::Subtract()) {
221 h3->Add (h1, h2, +1.0, -1.0);
223 }
else if (opera == JOpera::Multiply()) {
225 h3->Multiply(h1, h2, +1.0, +1.0);
227 }
else if (opera == JOpera::Divide()) {
229 h3->Divide (h1, h2, +1.0, +1.0);
231 }
else if (opera == JOpera::add() ||
232 opera == JOpera::subtract() ||
233 opera == JOpera::multiply() ||
234 opera == JOpera::divide()) {
236 for (Int_t
i = 1;
i <= h1->GetNbinsX(); ++
i) {
238 const Double_t
x = h1->GetBinCenter (
i);
239 const Double_t w1 = h1->GetBinContent(
i);
241 const Int_t
j = h2->FindBin(x);
242 const Double_t w2 = h2->GetBinContent(j);
246 if (opera == JOpera::add()) {
250 }
else if (opera == JOpera::subtract()) {
254 }
else if (opera == JOpera::multiply()) {
258 }
else if (opera == JOpera::divide()) {
261 ERROR(
"Bin " << h2->GetName() <<
"[" << j <<
"] empty." << endl);
268 h3->SetBinContent(
i, w3);
271 }
else if (opera == JOpera::efficiency() ||
272 opera == JOpera::stdev() ||
273 opera == JOpera::sqrt()) {
275 for (Int_t
i = 1;
i <= h1->GetNbinsX(); ++
i) {
277 const Double_t y1 = h1->GetBinContent(
i);
278 const Double_t y2 = h2->GetBinContent(
i);
280 Double_t w1 = h1->GetBinError(
i);
281 Double_t w2 = h2->GetBinError(
i);
286 if (opera == JOpera::efficiency()) {
289 ERROR(
"Bin " << h2->GetName() <<
"[" <<
i <<
"] empty." << endl);
301 w3 = y3 * fabs(y3 - 1.0) * sqrt(w1*w1 + w2*w2);
304 }
else if (opera == JOpera::stdev()) {
306 w3 = sqrt(w1*w1 + w2*w2);
313 }
else if (opera == JOpera::sqrt()) {
315 y3 = (y1+y2) * (y1-y2);
325 h3->SetBinContent(
i, y3);
326 h3->SetBinError (
i, w3);
330 }
else if (opera == JOpera::Add() ||
331 opera == JOpera::Multiply()) {
337 TH1* h1 =
dynamic_cast<TH1*
>(*i);
339 NOTICE(h1->GetName() <<
' ' << opera << endl);
343 if (
name == JOpera::SAME_AS_OPERATION())
344 h3 = (TH1*) h1->Clone(opera.c_str());
345 else if (
name == JOpera::SAME_AS_INPUT())
346 h3 = (TH1*) h1->Clone(h1->GetName());
348 h3 = (TH1*) h1->Clone(
name.c_str());
352 if (opera == JOpera::Add()) {
354 h3->Add (h3, h1, +1.0, +1.0);
356 }
else if (opera == JOpera::Multiply()) {
358 h3->Multiply(h3, h1, +1.0, +1.0);
365 FATAL(
"Incompatible number of histograms " << listOfObjects.size() <<
" with option " << opera << endl);
Utility class to parse command line options.
int main(int argc, char *argv[])
const JPolynome f1(1.0, 2.0, 3.0)
Function.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
General purpose messaging.
then fatal The output file must have the wildcard in the name
Utility class to parse command line options.
bool isTObject(const TKey *key)
Check if given key corresponds to a TObject.
TDirectory * getDirectory(const JRootObjectID &id)
Get TDirectory pointer.
#define DEBUG(A)
Message macros.