Th1 scaling axis

root [2] .x scaleaxis.cpp(0,10,0)
In file included from input_line_10:1:
scaleaxis.cpp:40:10: error: use of undeclared identifier 'a'
  invoke(a,b,c, &scaleaxis);
         ^
scaleaxis.cpp:40:12: error: use of undeclared identifier 'b'
  invoke(a,b,c, &scaleaxis);
           ^
scaleaxis.cpp:40:14: error: use of undeclared identifier 'c'
  invoke(a,b,c, &scaleaxis);
             ^
scaleaxis.cpp:40:18: error: use of undeclared identifier 'scaleaxis'
  invoke(a,b,c, &scaleaxis);
                 ^
scaleaxis.cpp:41:19: error: use of undeclared identifier 'a'
  cout << "a=" << a << "b=" << b << "c=" << c << endl;
                  ^
scaleaxis.cpp:41:32: error: use of undeclared identifier 'b'
  cout << "a=" << a << "b=" << b << "c=" << c << endl;
                               ^
scaleaxis.cpp:41:45: error: use of undeclared identifier 'c'
  cout << "a=" << a << "b=" << b << "c=" << c << endl;
                                            ^
scaleaxis.cpp:42:7: error: use of undeclared identifier 'a'
  v = a + b*x + c*x*x;
      ^
scaleaxis.cpp:42:11: error: use of undeclared identifier 'b'
  v = a + b*x + c*x*x;
          ^
scaleaxis.cpp:42:17: error: use of undeclared identifier 'c'
  v = a + b*x + c*x*x;

scaleaxis.cpp (1.7 KB)

Yes, the error message is correct. See your code:

Double_t ScaleX(Double_t x)
{
  Double_t v;
  invoke(a,b,c, &scaleaxis);
  cout << "a=" << a << "b=" << b << "c=" << c << endl;
  v = a + b*x + c*x*x;
  return v;
}

Hi @couet,

I replaced

Double_t ScaleX(Double_t x)

by

Double_t ScaleX(Double_t x, double a, double b, double c, void scaleaxis(double a, double b, double c))

but I got this error

root [0]
Processing scaleaxis.cpp...
In file included from input_line_8:1:
scaleaxis.cpp:40:3: error: no matching function for call to 'invoke'
  invoke(a,b,c, &scaleaxis);
  ^~~~~~
scaleaxis.cpp:32:6: note: candidate function not viable: no known conversion from 'void (**)(double, double, double)' to 'void (*)(double, double, double)' for 4th argument; remove &
void invoke(double a, double b, double c, void (*func)(double, double, double))
     ^
software/gcc/10.2.0/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../include/c++/10.2.0/functional:85:5: note: candidate template ignored: substitution failure [with _Callable = double &, _Args = <double &, double &, void (**)(double, double, double)>]: no type named 'type' in 'std::invoke_result<double &, double &, double &, void (**)(double, double, double)>'
    invoke(_Callable&& __fn, _Args&&... __args)
    ^
In file included from input_line_8:1:
SimulazioniFatte/21Nepgamma/Risonanza_6998/scaleaxis.cpp:76:2: error: no matching function for call to 'ScaleXaxis'
        ScaleXaxis(h,ScaleX);
        ^~~~~~~~~~
SimulazioniFatte/21Nepgamma/Risonanza_6998/scaleaxis.cpp:65:6: note: candidate function not viable: no known conversion from 'Double_t (Double_t, double, double, double, void (*)(double, double, double))' (aka 'double (double, double, double, double, void (*)(double, double, double))') to 'Double_t (*)(Double_t)' (aka 'double (*)(double)') for 2nd argument
void ScaleXaxis(TH1 *h, Double_t (*Scale)(Double_t))

then I also removed the & (As written in the error) but now I get

Processing scaleaxis.cpp...
In file included from input_line_8:1:
scaleaxis.cpp:76:2: error: no matching function for call to 'ScaleXaxis'
        ScaleXaxis(h,ScaleX);
        ^~~~~~~~~~
scaleaxis.cpp:65:6: note: candidate function not viable: no known conversion from 'Double_t (Double_t, double, double, double, void (*)(double, double, double))' (aka 'double (double, double, double, double, void (*)(double, double, double))') to 'Double_t (*)(Double_t)' (aka 'double (*)(double)') for 2nd argument
void ScaleXaxis(TH1 *h, Double_t (*Scale)(Double_t))

scaleaxis.cpp (1.8 KB)

you call:

	ScaleXaxis(h,ScaleX);

But you do not have a such function (matching this signature).

Then, I replaced

void ScaleAxis(TAxis *a, Double_t (*Scale)(Double_t))

by

void ScaleAxis(TAxis *a, Double_t (*Scale)(Double_t, double, double, double, void(double, double, double)))

but I got

root [0]
Processing scaleaxis.cpp...
In file included from input_line_8:1:
scaleaxis.cpp:53:63: error: too few arguments to function call, expected 5, have 1
      for(Int_t i = 0; i < X.GetSize(); i++) X[i] = Scale(X[i]);
                                                    ~~~~~     ^
scaleaxis.cpp:59:33: error: too few arguments to function call, expected 5, have 1
              Scale(a->GetXmin()),
              ~~~~~             ^
scaleaxis.cpp:60:33: error: too few arguments to function call, expected 5, have 1
              Scale(a->GetXmax()));
              ~~~~~             ^
scaleaxis.cpp:68:3: error: no matching function for call to 'ScaleAxis'
  ScaleAxis(h->GetXaxis(), Scale);
  ^~~~~~~~~
scaleaxis.cpp:47:6: note: candidate function not viable: no known conversion from 'Double_t (*)(Double_t)' (aka 'double (*)(double)') to 'Double_t (*)(Double_t, double, double, double, void (*)(double, double, double))' (aka 'double (*)(double, double, double, double, void (*)(double, double, double))') for 2nd argument
void ScaleAxis(TAxis *a, Double_t (*Scale)(Double_t, double, double, double, void(double, double, double)))
     ^
scaleaxis.cpp:76:2: error: no matching function for call to 'ScaleXaxis'
        ScaleXaxis(h,ScaleX);
        ^~~~~~~~~~
scaleaxis.cpp:65:6: note: candidate function not viable: no known conversion from 'Double_t (Double_t, double, double, double, void (*)(double, double, double))' (aka 'double (double, double, double, double, void (*)(double, double, double))') to 'Double_t (*)(Double_t)' (aka 'double (*)(double)') for 2nd argument
void ScaleXaxis(TH1 *h, Double_t (*Scale)(Double_t))
     ^
root [1]

and I’m not sure that I’m going to the right way, because in your link, the function was called as

cout << invoke(20, 10, &multiply) << '\n' ;

i.e. using the &, on the contrary, in my case the compiler asked to remove the &…then I’m not sure that I’m not making other mistakes

scaleaxis.cpp (1.8 KB)

That’s really elementary C++

your function’s signature is:

Double_t ScaleX(Double_t x, double a, double b, double c, void scaleaxis(double a, double b, double c))

And you call it with:

Scale(X[i]);

That’s why you get this error… read C++ doc …

I replaced

for(Int_t i = 0; i < X.GetSize(); i++) X[i] = Scale(X[i],a,b,c,scalexaxis);

by

for(Int_t i = 0; i < X.GetSize(); i++) X[i] = Scale(X[i],a,b,c,scalexaxis);

but I got

root [0]
Processing scaleaxis.cpp...
In file included from input_line_8:1:
scaleaxis.cpp:53:66: error: use of undeclared identifier 'b'
      for(Int_t i = 0; i < X.GetSize(); i++) X[i] = Scale(X[i],a,b,c,scalexaxis);
                                                                 ^
scaleaxis.cpp:53:68: error: use of undeclared identifier 'c'
      for(Int_t i = 0; i < X.GetSize(); i++) X[i] = Scale(X[i],a,b,c,scalexaxis);
                                                                   ^
scaleaxis.cpp:53:70: error: use of undeclared identifier 'scalexaxis'
      for(Int_t i = 0; i < X.GetSize(); i++) X[i] = Scale(X[i],a,b,c,scalexaxis);
                                                                     ^
scaleaxis.cpp:59:33: error: too few arguments to function call, expected 5, have 1
              Scale(a->GetXmin()),
              ~~~~~             ^
scaleaxis.cpp:60:33: error: too few arguments to function call, expected 5, have 1
              Scale(a->GetXmax()));
              ~~~~~             ^
scaleaxis.cpp:68:3: error: no matching function for call to 'ScaleAxis'
  ScaleAxis(h->GetXaxis(), Scale);
  ^~~~~~~~~
scaleaxis.cpp:47:6: note: candidate function not viable: no known conversion from 'Double_t (*)(Double_t)' (aka 'double (*)(double)') to 'Double_t (*)(Double_t, double, double, double, void (*)(double, double, double))' (aka 'double (*)(double, double, double, double, void (*)(double, double, double))') for 2nd argument
void ScaleAxis(TAxis *a, Double_t (*Scale)(Double_t, double, double, double, void(double, double, double)))
     ^
scaleaxis.cpp:76:2: error: no matching function for call to 'ScaleXaxis'
        ScaleXaxis(h,ScaleX);
        ^~~~~~~~~~
scaleaxis.cpp:65:6: note: candidate function not viable: no known conversion from 'Double_t (Double_t, double, double, double, void (*)(double, double, double))' (aka 'double (double, double, double, double, void (*)(double, double, double))') to 'Double_t (*)(Double_t)' (aka 'double (*)(double)') for 2nd argument
void ScaleXaxis(TH1 *h, Double_t (*Scale)(Double_t))
     ^
root [1]

then I also replaced

void ScaleAxis(TAxis *a, Double_t (*Scale)(Double_t))

by

void ScaleAxis(TAxis *a, Double_t (*Scale)(Double_t, double, double, double, void(double, double, double)))
and added the invoke function in this function too, but still doesn’t work

Processing scaleaxis.cpp...
In file included from input_line_8:1:
scaleaxis.cpp:50:12: error: use of undeclared identifier 'b'
  invoke(a,b,c, scaleaxis);
           ^
scaleaxis.cpp:50:14: error: use of undeclared identifier 'c'
  invoke(a,b,c, scaleaxis);
             ^
scaleaxis.cpp:50:17: error: use of undeclared identifier 'scaleaxis'
  invoke(a,b,c, scaleaxis);
                ^
scaleaxis.cpp:54:66: error: use of undeclared identifier 'b'
      for(Int_t i = 0; i < X.GetSize(); i++) X[i] = Scale(X[i],a,b,c,scalexaxis);
                                                                 ^
scaleaxis.cpp:54:68: error: use of undeclared identifier 'c'
      for(Int_t i = 0; i < X.GetSize(); i++) X[i] = Scale(X[i],a,b,c,scalexaxis);
                                                                   ^
/nfs/luna02/casaburf/SimulazioniFatte/21Nepgamma/Risonanza_6998/scaleaxis.cpp:54:70: error: use of undeclared identifier 'scalexaxis'
      for(Int_t i = 0; i < X.GetSize(); i++) X[i] = Scale(X[i],a,b,c,scalexaxis);
                                                                     ^
scaleaxis.cpp:60:33: error: too few arguments to function call, expected 5, have 1
              Scale(a->GetXmin()),
              ~~~~~             ^
scaleaxis.cpp:61:33: error: too few arguments to function call, expected 5, have 1
              Scale(a->GetXmax()));
              ~~~~~             ^
scaleaxis.cpp:69:3: error: no matching function for call to 'ScaleAxis'
  ScaleAxis(h->GetXaxis(), Scale);
  ^~~~~~~~~
scaleaxis.cpp:47:6: note: candidate function not viable: no known conversion from 'Double_t (*)(Double_t)' (aka 'double (*)(double)') to 'Double_t (*)(Double_t, double, double, double, void (*)(double, double, double))' (aka 'double (*)(double, double, double, double, void (*)(double, double, double))') for 2nd argument
void ScaleAxis(TAxis *a, Double_t (*Scale)(Double_t, double, double, double, void scaleaxis(double a, double b, double c)))
     ^
scaleaxis.cpp:77:2: error: no matching function for call to 'ScaleXaxis'
        ScaleXaxis(h,ScaleX);
        ^~~~~~~~~~
scaleaxis.cpp:66:6: note: candidate function not viable: no known conversion from 'Double_t (Double_t, double, double, double, void (*)(double, double, double))' (aka 'double (double, double, double, double, void (*)(double, double, double))') to 'Double_t (*)(Double_t)' (aka 'double (*)(double)') for 2nd argument
void ScaleXaxis(TH1 *h, Double_t (*Scale)(Double_t))
     ^
root [1]

scaleaxis.cpp (1.9 KB)

Same as before, the compiler tells you exactly what’s wrong:

use of undeclared identifier 'b'

Means exactly that: you are using a variable which is not declared. Again basic: In C++ all variable MUST be declared. So: declare them …

I made some changes based on the errors I got step by step.
Then I got this error

root [0]
Processing scaleaxis.cpp...
In file included from input_line_8:1:
scaleaxis.cpp:70:52: error: too few arguments to function call, expected 5, have 4
  ScaleAxis(h->GetXaxis(), Scale(c0,c1,c2,scaleaxis));
                           ~~~~~                   ^
scaleaxis.cpp:78:15: error: no matching function for call to 'ScaleX'
        ScaleXaxis(h,ScaleX(c0,c1,c2,scaleaxis));
                     ^~~~~~
scaleaxis.cpp:37:10: note: candidate function not viable: requires 5 arguments, but 4 were provided
Double_t ScaleX(Double_t x, double c0, double c1, double c2, void scaleaxis(double c0, double c1, double c2))
         ^
root [1]

using this macro

scaleaxis.cpp (2.2 KB)

then I replaced

ScaleAxis(h->GetXaxis(), Scale(c0,c1,c2,scaleaxis));

by

ScaleAxis(h->GetXaxis(), Scale(Double_t x, c0,c1,c2,scaleaxis));

and
ScaleXaxis(h,ScaleX(c0,c1,c2,scaleaxis));

by

ScaleXaxis(h,ScaleX(Double_t x,c0,c1,c2,scaleaxis));

but now I get

root [0]
Processing scaleaxis.cpp...
In file included from input_line_8:1:
scaleaxis.cpp:70:34: error: unexpected type name 'Double_t': expected expression
  ScaleAxis(h->GetXaxis(), Scale(Double_t x,c0,c1,c2,scaleaxis));
                                 ^
scaleaxis.cpp:78:22: error: unexpected type name 'Double_t': expected expression
        ScaleXaxis(h,ScaleX(Double_t x,c0,c1,c2,scaleaxis));
                            ^
root [1]

scaleaxis.cpp (2.3 KB)

Hi @couet, do you know how to solve it?

This is simple C++ . Check your code the error message is clear.
And please fix this kind of thing:

void invoke(double c0, double c1, double c2, void (*func)(double, double, double))
{
    return c0,c1,c2;
}

How tdo you ecpect this to work ? invoke is void … and even if it was double how do you expect the return with 3 values to work ?

Here is a working code. Start from that and adjuste it as you need:

double ScaleX(double x, double c0, double c1, double c2)
{
   double v;
   v = c0 + c1*x + c2*x*x;
   return v;
}

double invoke(double x, double c0, double c1, double c2, double (*func)(double, double, double, double))
{
   return func(x, c0, c1, c2);
}

void scaleaxis()
{
   double x  = 3;
   double c0 = 0;
   double c1 = 1;
   double c2 = 2;
   cout << invoke(x, c0, c1, c2, &ScaleX) << '\n';
}
root [0] 
Processing scaleaxis.C...
21
root [1] 

Thank you @couet, I tried this code

scaleaxis.cpp (1.8 KB)

but always getting error

root [0]
Processing scaleaxis.cpp...
In file included from input_line_8:1:
/nfs/luna02/casaburf/SimulazioniFatte/21Nepgamma/Risonanza_6998/scaleaxis.cpp:81:2: error: no matching function for call to 'ScaleXaxis'
        ScaleXaxis(h, c0, c1, c2, ScaleX);
        ^~~~~~~~~~
/nfs/luna02/casaburf/SimulazioniFatte/21Nepgamma/Risonanza_6998/scaleaxis.cpp:65:6: note: candidate function not viable: no known conversion from 'Double_t (Double_t, double, double, double)' (aka 'double (double, double, double, double)') to 'Double_t (*)(Double_t)' (aka 'double (*)(double)') for 5th argument
void ScaleXaxis(TH1 *h, double c0, double c1, double c2, Double_t (*Scale)(Double_t))
     ^

send me filein.hist

Here.

The following code is correct C++ wise. You can run it with:

root [0] .x scaleaxis.cpp(1,2,3)
a = 1, b = 2, c = 3
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
root [1] 
double ScaleX(double x, double a, double b, double c)
{
  double v;
  v = a + b*x + c*x*x;
  return v;
}


void ScaleAxis(TAxis *axis, double a, double b, double c, double (*Scale)(double, double, double, double))
{
   if (!axis) return;
   if (axis->GetXbins()->GetSize()) {
      TArrayD X(*(axis->GetXbins()));
      for(Int_t i = 0; i < X.GetSize(); i++) X[i] = Scale(X[i], a, b, c);
      axis->Set((X.GetSize() - 1), X.GetArray());
   } else {
      axis->Set(axis->GetNbins(),
              Scale(axis->GetXmin(), a, b, c),
              Scale(axis->GetXmax(), a, b, c));
   }
   return;
}


void scaleaxis(double a, double b, double c) {
   cout << "a = " << a << ", b = " << b << ", c = " << c << endl;

   TFile *RootIn = TFile::Open("filein.hist","READ");
   TFile *RootOut = new TFile("fileout.hist","RECREATE");
   TH1F *h = (TH1F*)RootIn->Get("zint");
   if (!h) return;

   TAxis *XAxis = h->GetXaxis();
   ScaleAxis(XAxis, a, b, c, &ScaleX);

   h->ResetStats();
   h->Draw();
   h->Write();
   RootOut->Write();
   RootIn->Close();
   RootOut->Close();
}

Now I let you fisnish it and check if does what you need. That’s your job.

Read the comments in the source code of the original ScaleAxis function.

Thank you @couet, your code works!

I also modiefied to try to use the ScaleXaxis function.

scaleaxis.cpp (1.7 KB)

and looks like to work too!

@Wile_E_Coyote what comment are you referring?

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.