0

I have a TTree that has several branches which include Muon.PT, Muon.Phi, Muon.Eta, Muon.Charge that I am trying to work with. The data type of my branches is as follows:

 *Br  309 :Muon.PT   : Float_t PT[Muon_]                                      *
 *Entries :    20000 : Total  Size=     477624 bytes  File Size  =     405824 *
 *Baskets :       41 : Basket Size=      27648 bytes  Compression=   1.17     *
 *............................................................................*
 *Br  310 :Muon.Eta  : Float_t Eta[Muon_]                                     *
 *Entries :    20000 : Total  Size=     477669 bytes  File Size  =     414560 *
 *Baskets :       41 : Basket Size=      27648 bytes  Compression=   1.15     *
 *............................................................................*
 *Br  311 :Muon.Phi  : Float_t Phi[Muon_]                                     *
 *Entries :    20000 : Total  Size=     477669 bytes  File Size  =     414521 *
 *Baskets :       41 : Basket Size=      27648 bytes  Compression=   1.15     *
 *..........................................................................

When I want to create a vector that have elements from the Branch arrays,

:
:
  RVec<float> Muon_PT;
  RVec<float> Muon_Eta;
  RVec<float> Muon_Phi;
  RVec<int> Muon_Charge;
  if(Muon.Charge[1] != Muon.Charge[2])
      {
        ROOT::Math::PtEtaPhiMVector m1((Muon.PT)[1], Muon.Eta[1], Muon.Phi[1], 0.1);
        ROOT::Math::PtEtaPhiMVector m2((Muon.PT)[2], Muon.Eta[2], Muon.Phi[2], 0.1);
:
:

I get the error that

/mnt/c/1/MG5_aMC_v2_6_6/triplet2s/Events/run_01/selectMuon.c:45:23: error: declaration of reference variable 'Muon' requires an initializer
  const RVec<float> & Muon.PT;
                      ^~~~
/mnt/c/1/MG5_aMC_v2_6_6/triplet2s/Events/run_01/selectMuon.c:45:27: error: expected ';' at end of declaration
  const RVec<float> & Muon.PT;
                          ^
                          ;
/mnt/c/1/MG5_aMC_v2_6_6/triplet2s/Events/run_01/selectMuon.c:46:23: error: redefinition of 'Muon'
  const RVec<float> & Muon.Eta;
                      ^

etc with a segmentation violation. Other variations (e.g. writing instead RVec> reco_zz_to_4l(rvec_f (Muon.PT), rvec_f (Muon.Eta), rvec_f (Muon.Phi)), would also give me:

/mnt/c/1/MG5_aMC_v2_6_6/trisignal/Events/run_01/selectMuon.C:81:44: error: use of undeclared identifier ‘Muon’
RVec<RVec<size_t>> reco_zz_to_4l(rvec_f (Muon.PT), rvec_f (Muon.Eta), rvec_f (Muon.Phi), rvec_…

How can I pass the strings as a parameter and avoid the error use of undeclared identifier "Muon"? Is there a fix to both these errors?

*****EDIT***** My full code that produces the error is below:

#include <vector>
#include <string>
#include "ROOT/RDataFrame.hxx"
#include "ROOT/RVec.hxx"
#include "ROOT/RDF/RInterface.hxx"
#include "TCanvas.h"
#include "TH1D.h"
#include "TLatex.h"
#include "TLegend.h"
#include "Math/Vector4Dfwd.h"
#include "TStyle.h"
using namespace ROOT::VecOps;
using RNode = ROOT::RDF::RNode;
using rvec_f = const RVec<float> &;
using rvec_i = const RVec<int> &;
const auto z_mass = 91.2;


//-------------------------------------Looking at Leptons -----------------------------------------

void selectMuon()
{

  TH1F *histZMass = new TH1F("mass", "M_{inv}(Z[1]); M_inv (GeV/c^2); Events", 50, 0.0, 1500);
  TH1F *histDiMuonMass = new TH1F("mass", "M_{inv}(Z[3]Z[5]); M_inv (GeV/c^2); Events", 50, 0.0, 1500);

  //
  ROOT::EnableImplicitMT();
  ROOT::RDataFrame df("Delphes", "tag_1_delphes_events.root");
  auto colNames = df.GetColumnNames();
// Print columns' names
for (auto &&colName : colNames) std::cout << colName << std::endl;
  auto m = df.Define("muon_mass", [] { return ROOT::RVec<float>(49254, 0.1); });
  /*
  double muonpt(const RVec<float> &Muon.PT);
  auto pt = df.Define("muon_pt", muonpt, {"Muon_PT"} );
  double muoneta(const RVec<float> &Muon.Eta);
  auto eta = df.Define("muon_eta", muoneta, {"Muon.Eta"} );
  double muonphi(const RVec<float> &Muon.Phi);
  auto phi = df.Define("muon_phi", muonphi, {"Muon.Phi"} );
  double muoncharge(const RVec<float> &Muon.Charge);
  auto charge = df.Define("muon_charge", muoncharge, {"Muon.Charge"} );
  */
  const RVec<float> & Muon.PT;
  const RVec<float> & Muon.Eta;
  const RVec<float> & Muon.Phi;
  const RVec<int> & Muon.Charge;

  //RVec<RVec<size_t>> reco_zz_to_4l(rvec_f pt, rvec_f eta, rvec_f phi, rvec_f m, rvec_i charge);
  RVec<RVec<size_t>> idx(2);
  idx[0].reserve(2); idx[1].reserve(2);
  //auto idx_cmb = Combinations(Muon_PT, 2);
  auto best_mass = -1;
  size_t best_i1 = 0; size_t best_i2 = 0;
  for (size_t i = 0; i < Muon.Charge.size(); i++)
  {
      const auto i1 = idx_cmb[0][i];
      const auto i2 = idx_cmb[1][i];

      if(Muon.Charge[1] != Muon.Charge[2])
      {
        ROOT::Math::PtEtaPhiMVector m1((Muon.PT)[1], Muon.Eta[1], Muon.Phi[1], 0.1);
        ROOT::Math::PtEtaPhiMVector m2((Muon.PT)[2], Muon.Eta[2], Muon.Phi[2], 0.1);

        const auto this_mass = (m1 + m2).M();
        //histDiMuonMass->Fill(this_mass.M());
        if (std::abs(z_mass - this_mass) < std::abs(z_mass - best_mass)) 
        {
            best_mass = this_mass;
            best_i1 = i1;
            best_i2 = i2;
         }
         histDiMuonMass->Fill(this_mass);

   // Request cut-flow report
   auto report = df.Report();
// Reconstruct two Z candidates from four leptons of the same kind

   // Produce plot
   /*
   gStyle->SetOptStat(0); gStyle->SetTextFont(42);
   auto c = new TCanvas("c", "", 800, 700);
   c->SetLogx(); c->SetLogy();
   h->SetTitle("");
   h->GetXaxis()->SetTitle("m_{#mu#mu} (GeV)"); h->GetXaxis()->SetTitleSize(0.04);
   h->GetYaxis()->SetTitle("N_{Events}"); h->GetYaxis()->SetTitleSize(0.04);
   h->DrawClone();
   TLatex label; label.SetNDC(true);
   label.DrawLatex(0.175, 0.740, "#eta");
   label.DrawLatex(0.205, 0.775, "#rho,#omega");
   label.DrawLatex(0.270, 0.740, "#phi");
   label.DrawLatex(0.400, 0.800, "J/#psi");
   label.DrawLatex(0.415, 0.670, "#psi'");
   label.DrawLatex(0.485, 0.700, "Y(1,2,3S)");
   label.DrawLatex(0.755, 0.680, "Z");
   label.SetTextSize(0.040); label.DrawLatex(0.100, 0.920, "#bf{CMS Open Data}");
   label.SetTextSize(0.030); label.DrawLatex(0.630, 0.920, "#sqrt{s} = 8 TeV, L_{int} = 11.6 fb^{-1}");
   c->SaveAs("dimuon_spectrum.pdf");
   */
   // Print cut-flow report
   report->Print();

   }

   idx[0].emplace_back(best_i1);
   idx[0].emplace_back(best_i2);
   // Reconstruct second Z from remaining lepton pair
   for (size_t i = 0; i < 4; i++) 
   {
      if (i != best_i1 && i != best_i2)
       {
         idx[1].emplace_back(i);
       } 
   }
   // Return indices of the pairs building two Z bosons
   return idx;

//}

//  - - - - - - - - - - - - - - Drawing the Histograms - - - - - - - - - - - - - - - - - - - - - -   

} // end of event for loop
usernew
  • 125
  • 1
  • 13
  • I don't think `const RVec & Muon.PT;` is valid syntax. Did you mean `const RVec & PT;` or `const RVec & Muon::PT = ;`? Also show the code where the error occurs (at C:\1\MG5_aMC_v2_6_6\triplet2s\Events\run_01\selectMuon.c) – Artyer Mar 02 '20 at 23:34
  • What would be the correct syntax if my Branch Name is Muon.PT and not PT? That is if I go to my ROOT terminal and fill my histogram with "PT" I get an empty histogram until I fill it with "Muon.PT". However, it isn't working in my code. I will provide my full code – usernew Mar 02 '20 at 23:38
  • The error is quite descriptive. You are trying to declare a variable of *reference* type, and reference cannot be null. Reference always refers to (or points to) a real object. What exactly are you trying to do in the line `const RVec & Muon.PT;`? – Yksisarvinen Mar 02 '20 at 23:41
  • It is my attempt to define the variables so that I can create a vector from it with the PtEtaPhiM vector from ROOT – usernew Mar 02 '20 at 23:42
  • If I write const RVec & Muon::PT = < something > how can I write it such that something are the values in my Branch – usernew Mar 02 '20 at 23:46
  • I'm afraid that I have no idea how this library works. One thing for certain, names with dots are not valid in C++. Dot is an operator to access class members. `Muon.PT` will be always interpreted as "*give me member called `PT` from object called `Muon`*" (outside of strings of course, those are not compiled). To declare a variable, you should drop reference (`&`) and probably `const` (else it cannot be modified), but I cannot guess what is the actual code that you need here. – Yksisarvinen Mar 02 '20 at 23:55
  • I see that you have been asking quite a lot of questions regarding C++ and this framework recently. We have a list of [good books for learning C++](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Maybe learning C++ from scratch (without any library) would make it easier for you to use the framework? – Yksisarvinen Mar 03 '20 at 00:00
  • Yes, I understand the issue with the Dot. If I remove it then the code does run however, I get this error: terminate called after throwing an instance of 'std::runtime_error' what(): Cannot make unique combinations of size 2 from vector of size 0. and I believe it does not recognize what MuonPT is, right? – usernew Mar 03 '20 at 00:00
  • @Yksisarvinen Yes, I have been looking into different resources to learn C++ since I also need to work with this framework. I appreciate the reference as well. – usernew Mar 03 '20 at 00:05
  • @Yksisarvinen I changed my branch names to get rid of the Dot issue. But now I get an empty histogram. Do you know how to fix that? – usernew Mar 03 '20 at 00:43
  • The program leaks. `histZMass` and `histDiMuonMass` are `new`ed but then they are just forgotten. – Ted Lyngmo Mar 03 '20 at 01:02
  • @TedLyngmo Do you mind explaining a little further what you mean. How can I solve that issue? – usernew Mar 03 '20 at 01:15
  • @TedLyngmo It actually seems like the problem is that it is still not reading the values from my Branches. When I write: auto idx_cmb = Combinations(Muon_PT, 2); I get Warning in : Replacing existing TH1: mass (Potential memory leak). terminate called after throwing an instance of 'std::runtime_error' what(): Cannot make unique combinations of size 2 from vector of size 0 – usernew Mar 03 '20 at 01:48
  • @usernew You do `TH1F *histZMass = new TH1F(...);` and `TH1F *histDiMuonMass = new TH1F(...);` but you don't `delete` any of those pointers. It's also not clear what you use them for. You do `histDiMuonMass->Fill(...);` but where does the result go? Both pointers are just forgotten after that. – Ted Lyngmo Mar 03 '20 at 08:27

0 Answers0