65     JParser<> zap(
"Auxiliary program for histogram operations.");
 
   67     zap[
'f'] = 
make_field(inputFile,  
"<input file>:<object name>");
 
   81                                                   << 
"\n\"" << JOpera::SAME_AS_OPERATION() << 
"\" -> same as operation; or" 
   82                                                   << 
"\n\"" << JOpera::SAME_AS_INPUT()     << 
"\" -> same as input; else" 
   83                                                   << 
"\nas specified")) = JOpera::SAME_AS_OPERATION();
 
   88   catch(
const exception &error) {
 
   89     FATAL(error.what() << endl);
 
   97     DEBUG(
"Input: " << *input << endl);
 
  102       ERROR(
"File: " << input->getFullFilename() << 
" not opened." << endl);
 
  106     const TRegexp regexp(input->getObjectName());
 
  108     TIter iter(dir->GetListOfKeys());
 
  110     for (TKey* key; (key = (TKey*) iter.Next()) != NULL; ) {
 
  112       const TString tag(key->GetName());
 
  114       DEBUG(
"Key: " << tag << 
" match = " << tag.Contains(regexp) << endl);
 
  118       if (tag.Contains(regexp)) {
 
  122         if (dynamic_cast<TH2*>(p) == NULL) {
 
  123           FATAL(
"Object " << p->GetName() << 
" not compatible with histogram operations." << endl);
 
  126         listOfObjects.push_back(p);
 
  134   if        (listOfObjects.size() == 0) {
 
  136     FATAL(
"Number of histograms " << listOfObjects.size() << 
" = 0." << endl);
 
  138   } 
else if (listOfObjects.size() == 1 && (opera == JOpera::Add()      ||
 
  139                                            opera == JOpera::Subtract() ||
 
  140                                            opera == JOpera::Multiply() ||
 
  141                                            opera == JOpera::Divide())) {
 
  145     TH2* h1 = dynamic_cast<TH2*>(listOfObjects[0]);
 
  146     TF2* f1 = (TF2*) h1->GetListOfFunctions()->First();
 
  149       FATAL(h1->GetName() << 
" has no associated function." << endl);
 
  152     NOTICE(h1->GetName() << 
' ' << opera << 
' ' << f1->GetName() << endl);
 
  154     if      (name == JOpera::SAME_AS_OPERATION())
 
  155       h3 = (TH2*) h1->Clone(opera.c_str());
 
  156     else if (name == JOpera::SAME_AS_INPUT())
 
  157       h3 = (TH2*) h1->Clone(h1->GetName());
 
  159       h3 = (TH2*) h1->Clone(name.c_str());
 
  161     if        (opera == JOpera::Add()) {
 
  165     } 
else if (opera == JOpera::Subtract()) {
 
  169     } 
else if (opera == JOpera::Multiply()) {
 
  173     } 
else if (opera == JOpera::Divide()) {
 
  178   } 
else if (listOfObjects.size() == 2) {
 
  180     TH2* h1 = dynamic_cast<TH2*>(listOfObjects[0]);
 
  181     TH2* h2 = dynamic_cast<TH2*>(listOfObjects[1]);
 
  183     NOTICE(h1->GetName() << 
' ' << opera << 
' ' << h2->GetName() << endl);
 
  185     if      (name == JOpera::SAME_AS_OPERATION())
 
  186       h3 = (TH2*) h1->Clone(opera.c_str());
 
  187     else if (name == JOpera::SAME_AS_INPUT())
 
  188       h3 = (TH2*) h1->Clone(h1->GetName());
 
  190       h3 = (TH2*) h1->Clone(name.c_str());
 
  192     if        (opera == JOpera::Add()) {
 
  194       h3->Add     (h1, h2, +1.0, +1.0);
 
  196     } 
else if (opera == JOpera::Subtract()) {
 
  198       h3->Add     (h1, h2, +1.0, -1.0);
 
  200     } 
else if (opera == JOpera::Multiply()) {
 
  202       h3->Multiply(h1, h2, +1.0, +1.0);
 
  204     } 
else if (opera == JOpera::Divide()) {
 
  206       h3->Divide  (h1, h2, +1.0, +1.0);
 
  208     } 
else if (opera == JOpera::add()       ||
 
  209                opera == JOpera::subtract()  ||
 
  210                opera == JOpera::multiply()  ||
 
  211                opera == JOpera::divide()) {
 
  213       for (Int_t i1 = 1; i1 <= h1->GetNbinsX(); ++i1) {
 
  214         for (Int_t i2 = 1; i2 <= h1->GetNbinsY(); ++i2) {
 
  216           const Double_t x  = h1->GetXaxis()->GetBinCenter(i1);
 
  217           const Double_t y  = h1->GetYaxis()->GetBinCenter(i2);
 
  219           const Int_t    j1 = h2->GetXaxis()->FindBin(x);
 
  220           const Int_t    j2 = h2->GetYaxis()->FindBin(y);
 
  222           const Double_t w1 = h1->GetBinContent(i1,i2);
 
  223           const Double_t w2 = h2->GetBinContent(j1,j2);
 
  227           if        (opera == JOpera::add()) {
 
  231           } 
else if (opera == JOpera::subtract()) {
 
  235           } 
else if (opera == JOpera::multiply()) {
 
  239           } 
else if (opera == JOpera::divide()) {
 
  242               ERROR(
"Bin " << h2->GetName() << 
"[" << j1 << 
"," << j2 << 
"] empty." << endl);
 
  249           h3->SetBinContent(i1, i2, w3);
 
  253     } 
else if (opera == JOpera::efficiency()  ||
 
  254                opera == JOpera::stdev()       ||
 
  255                opera == JOpera::sqrt()) {
 
  257       for (Int_t i1 = 1; i1 <= h1->GetNbinsX(); ++i1) {
 
  258         for (Int_t i2 = 1; i2 <= h1->GetNbinsY(); ++i2) {
 
  260           const Double_t y1 = h1->GetBinContent(i1,i2);
 
  261           const Double_t y2 = h2->GetBinContent(i1,i2);
 
  263           Double_t w1 = h1->GetBinError(i1,i2);
 
  264           Double_t w2 = h2->GetBinError(i1,i2);
 
  269           if        (opera == JOpera::efficiency()) {
 
  272               ERROR(
"Bin " << h2->GetName() << 
"[" << i1 << 
"," << i2 << 
"] empty." << endl);
 
  284               w3  = y3 * fabs(y3 - 1.0) * sqrt(w1*w1 + w2*w2);
 
  287           } 
else if (opera == JOpera::stdev()) {
 
  289             w3 = sqrt(w1*w1 + w2*w2);
 
  296           } 
else if (opera == JOpera::sqrt()) {
 
  298             y3 = (y1+y2) * (y1-y2);
 
  308           h3->SetBinContent(i1, i2, y3);
 
  309           h3->SetBinError  (i1, i2, w3);
 
  314   } 
else if (opera == JOpera::Add()      ||
 
  315              opera == JOpera::Multiply()) {
 
  319       TH2* h1 = dynamic_cast<TH2*>(*i);
 
  321       NOTICE(h1->GetName() << 
' ' << opera << endl);
 
  325         if      (name == JOpera::SAME_AS_OPERATION())
 
  326           h3 = (TH2*) h1->Clone(opera.c_str());
 
  327         else if (name == JOpera::SAME_AS_INPUT())
 
  328           h3 = (TH2*) h1->Clone(h1->GetName());
 
  330           h3 = (TH2*) h1->Clone(name.c_str());
 
  334         if        (opera == JOpera::Add()) {
 
  336           h3->Add     (h3, h1, +1.0, +1.0);
 
  338         } 
else if (opera == JOpera::Multiply()) {
 
  340           h3->Multiply(h3, h1, +1.0, +1.0);
 
  347     FATAL(
"Incompatible number of histograms " << listOfObjects.size() << 
" with option " << opera << endl);