I am trying to plot the invariant mass of the Z boson from two decayed muons. I am using MadGraph and Root. MadGraph simulates the events (p p > Z > mu+ and mu-) and creates a .root file that contains the events. I called the simulation eventgeneration.
To use Root to analyze the data and draw the histogram, I have to write my code in C++. Here is the code:
#ifdef __CLING__
R__LOAD_LIBRARY(libDelphes)
#include "TFile.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TH1F.h"
#include <iostream>
#include "classes/DelphesClasses.h"
#include "external/ExRootAnalysis/ExRootTreeReader.h"
#include "external/ExRootAnalysis/ExRootResult.h"
#else
class ExRootTreeReader;
class ExRootResult;
using namespace std;
#endif
void readEvents(const char *inputFile)
{
gSystem->Load("libDelphes");
TChain chain("Delphes");
chain.Add(inputFile);
ExRootTreeReader *treeReader = new ExRootTreeReader(&chain);
Long64_t numberOfEntries = treeReader->GetEntries();
TTree *tree = new TTree(&chain);
TClonesArray *branchMuon = treeReader->UseBranch("Muon");
//Long64_t numberOfMuons = branchMuon->GetEntries();
TClonesArray *branchElectron = treeReader->UseBranch("Electron");
Long64_t numberOfElectrons = branchElectron->GetEntries();
cout << "There are " << numberOfEntries << " entries in your ntuple" << endl;
UInt_t Muons;
Float_t MuonEta1;
Float_t MuonPhi1;
Float_t MuonPt1;
Float_t MuonEta2;
Float_t MuonPhi2;
Float_t MuonPt2;
tree->SetBranchAddress("MuonEta1", &MuonEta1);
tree->SetBranchAddress("MuonPhi1", &MuonPhi1);
tree->SetBranchAddress("MuonPt1", &MuonPt1);
tree->SetBranchAddress("MuonEta2", &MuonEta2);
tree->SetBranchAddress("MuonPhi2", &MuonPhi2);
tree->SetBranchAddress("MuonPt2", &MuonPt2);
TH1F *histDiMuonMass = new TH1F("mass", "M_{inv}(mu+[1], mu-[2]); M_inv (GeV/c^2); Events", 50, 0.0, 1500);
for(Int_t entry = 0; entry < numberOfEntries; ++entry)
{
treeReader->ReadEntry(entry);
Long64_t numberOfMuons = branchMuon->GetEntries();
//Muons += entry;
//Muon *muon1, *muon2, *muon3, *muon4;
TLorentzVector muon1;
TLorentzVector muon2;
muon1.SetPtEtaPhiM(MuonPt1, MuonEta1, MuonPhi1, 0.1);
muon2.SetPtEtaPhi(MuonPt2, MuonEta2, MuonPhi2, 0.1);
if(branchMuon->GetEntries() == 4)
{
TLorentzVector Z = muon1 + muon2;
histDiMuonMass->Fill(Z.M());
}
}
cout << "There are " << Muons << " entries in your ntuple" << endl;
histDiMuonMass->Draw();
}
Then in the root terminal I type: \
.x examples/readEvents.C("../eventgeneration/Events/run_01/tag_1_delphes_events.root")
However, I get the following error:
In file included from input_line_1563:1:
/mnt/c/1/MG5_aMC_v2_6_6/Delphes/examples/readEvents.C:30:20: error: no matching constructor for initialization of 'TTree'
TTree *tree = new TTree(&chain);
^ ~~~~~~
/home/cucip/builddir/include/TTree.h:295:4: note: candidate constructor not viable: no known conversion from 'TChain *' to 'const TTree' for 1st argument; remove &
TTree(const TTree& tt) = delete;
^
/home/cucip/builddir/include/TTree.h:291:4: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
TTree();
^
/home/cucip/builddir/include/TTree.h:292:4: note: candidate constructor not viable: requires at least 2 arguments, but 1 was provided
TTree(const char* name, const char* title, Int_t splitlevel = 99, TDirectory* dir = gDirectory);
^
In file included from input_line_1563:1:
/mnt/c/1/MG5_aMC_v2_6_6/Delphes/examples/readEvents.C:72:8: error: no member named 'SetPtEtaPhi' in 'TLorentzVector'
muon2.SetPtEtaPhi(MuonPt2, MuonEta2, MuonPhi2, 0.1);
Does anybody see what could cause this error and how I can fix it?
Many thanks!
By calling new TTree(&chain) you're trying to call a constructor for a TTree and you provide it with a TChain * (the type of chain is TChain, so &chain is a pointer to a TChain).
The constructors for TTree https://root.cern/doc/v618/classTTree.html take either no argument or two const char* (usually string literals or .Data() of a TString or .c_str() of a std::string or the output of ROOT's Form …).
It looks like you try to call the deleted constructor TTree(const TTree&tt)=delete, which doesn't work for several reasons:
you're providing a pointer to a TTree instead of a TTree by reference (not even sure from the top of my head if casting from TChain to TTree would work if the & wasn't there.
the constructor is deleted, so it doesn't actually exist and cannot be called.
However, from the looks of it, you want to use your TChain as a TTree*, which doesn't require any code from your side to begin with because a TChain already is a TTree by inheritance. So, you can use chain. instead of tree->, or (if having a pointer variable is really more desirable for reasons that I don't see in the example) create a TTree* (i.e. create only the pointer to a TTree, instead of creating the actual TTree on the heap and get a pointer to it from the new operator) by doing something like
TTree* tree = &chain;
I have an annoying problem with Visual Studio. Indeed, I am in the design of a compiler, and I have a file reserved for error messages. It works with a dictionary (std::map): code → message.
However, the changes made to the dictionary do not seem to affect the program, which reacts as if no changes had been made.
It would be difficult for me to explain more clearly with words, so I recorded a video. (It does not belong to the site, sorry, I did not find how to include it i, this post).
As you can see, we use a function that displays the error message as it gets it from the dictionary :
std::map<ErrorCodes, std::string> Messages;
...
std::string ErrMessage = Messages[code];
I do not understand why the changes made do not affect the program as intended. It seems that Visual Studio no longer compiles part of the code...
Indeed, in the recording, we can see that the error message displayed in the console is the [E29] (the old one before the [E80]), and that the message displayed is not the one that corresponds with the enumeration either.
The problem may seem simple, but I honestly do not see where it might lie...
EDIT:
Here is a more detailed explanation:
In the video, the program running in the console is mine. "Compilation not success" is my own error message, and it is normal that it is displayed.
Here is the call code of the error call display:
exception.ThrowError(exception.E0080);
E0080 is the error listing code, here are the error message files :
*.hpp:
class Exception {
public:
enum ErrorCodes {
E0000,
E0001, // Can't load file
E0002, // Can't find header file
E0003, // Expected file name
E0004, // Unexpected token
E0005, // Expected Identifier
E0006, // Value without storage object
E0007, // Already existing object
E0008, // Redefined preprocessor definition
E0009, // Redefined variable
E0010, // Redefined function
E0011, // Redefined object
E0012, // Redefined rule
E0013, // Redefined value
E0014, // Undefined identifier
E0015, // Buoyage symbol missing
E0016, // Expected end of line symbol (';')
E0017, // Unexpected character
E0018, // Unknown token
E0019, // Non-close comment
E0020, // Non-compliant typing
E0021, // Use of uninitialized data
E0022, // Unacceptable suffix
E0023, // Invalid keyword combination
E0024, // Declaration not in accordance with non-local use
E0025, // Incompatible value with type / object defined
E0026, // Constant value too wide
E0027, // Too much initialization value in a static size array
E0028, // Non-conforming identifier
E0029, // Expected statement
E0030, // Wrong identifier format (the expected format is ASCII)
E0031, // Wrong pointer initialization
E0032, // Non-valid literal suffix
E0033, // No object can have the identifier 'vanaur'
E0034, // Non-existent object field
E0035, // Non-existent object method
E0036, // Missing function call arguments
E0037, // A rvalue cannot be accessed via the pointers
E0038, // The use of a pointer is unacceptable in this context
E0039, // A reference cannot be made to a constant value
E0040, // Invalid assembler code in external expression
E0041, // The types of the two objects do not match in the image assignment
E0042, // Only a defined object can be destroyed by the delete operator
E0043, // Empty template
E0044, // Object not existing in this namespace
E0045, // Typage temptation with a non-instanciated structure
E0046, // Temptation to access a private field of the object
E0047, // Temptation to access a private method of the object
E0048, // Invalid operator
E0049, // Reserved identifier
E0050, // Wrong usage of postfix and prefix operator
E0051, // Temptation to access an inaccessible element in a table
E0052, // The main function can only have 3 arguments variation
E0053, // This function is not defined as being able to return an array
E0054, // A non-instanciated structure cannot be used as an object instance with the keyword 'new'.
E0055, // Wrong choice of the anonymous string concatenation operator (between '^' and'+')
E0056, // An object can only inherit from one other object
E0057, // Incorrect 'typename' value
E0058, // Incorrect 'typesize' value
E0059, // The identifier of a process ('proc') cannot contain spaces
E0060, // The identifier of a process ('proc') cannot contain balises
E0061, // An exception cannot be thrown out of a function
E0062, // Syntax error
E0063, // The increment value of an iteration (with step) must be numerical
E0064, // An anonymous array serving as an iterator to a for loop cannot be empty
E0065, // Wrong ternary condition format
E0066, // A 'ret' instruction must only fit on one instruction (one line = one ';')
E0067, // Division by zero
E0068, // Wrong enumeration value
E0069, // 'Upon' block members cannot contain expressions other than 'it'
E0070, // A match/case expression must contain at least one 'case' expression before using 'default'
E0071, // Unknown error
E0072, // Undefined object
E0073, // Not a valid math expression
E0074, // Expected character
E0075, // Unbalanced brackets
E0076, // Non-ascii character detected
E0077, // The current version of Arlia only accepts constant values as optional function parameters
E0078, // Undefined type
E0079, // Statement not recognised in this context
E0080, // Invalid statement
};
void ThrowError(ErrorCodes, char);
void ThrowError(ErrorCodes, std::string);
void ThrowError(ErrorCodes, token_t);
void ThrowError(ErrorCodes, token_t, Expr);
void ThrowError(ErrorCodes, Expr);
private:
std::map<ErrorCodes, std::string> Messages =
{
{ E0001, " Can't load file" },
{ E0002, " Can't find header file" },
{ E0003, " Expected file name" },
{ E0004, " Unexpected token" },
{ E0005, " Expected Identifier" },
{ E0006, " Value without storage object" },
{ E0007, " Already existing object" },
{ E0008, " Redefined preprocessor definition" },
{ E0009, " Redefined variable" },
{ E0010, " Redefined function" },
{ E0011, " Redefined object" },
{ E0012, " Redefined rule" },
{ E0013, " Redefined value" },
{ E0014, " Undefined identifier" },
{ E0015, " Buoyage symbol missing" },
{ E0016, " Expected end of line symbol (';')" },
{ E0017, " Unexpected character" },
{ E0018, " Unknown token" },
{ E0019, " Non-close comment" },
{ E0020, " Non-compliant typing" },
{ E0021, " Use of uninitialized data" },
{ E0022, " Unacceptable suffix" },
{ E0023, " Invalid keyword combination" },
{ E0024, " Declaration not in accordance with non-local use" },
{ E0025, " Incompatible value with type / object defined" },
{ E0026, " Constant value too wide" },
{ E0027, " Too much initialization value in a static size array" },
{ E0028, " Non-conforming identifier" },
{ E0029, " Expected statement" },
{ E0030, " Wrong identifier format (the expected format is ASCII)" },
{ E0031, " Wrong pointer initialization" },
{ E0032, " Non-valid literal suffix" },
{ E0033, " No object can have the identifier 'vanaur'" },
{ E0034, " Non-existent object field" },
{ E0035, " Non-existent object method" },
{ E0036, " Missing function call arguments" },
{ E0037, " A rvalue cannot be accessed via the pointers" },
{ E0038, " The use of a pointer is unacceptable in this context" },
{ E0039, " A reference cannot be made to a constant value" },
{ E0040, " Invalid assembler code in external expression" },
{ E0041, " The types of the two objects do not match in the image assignment" },
{ E0042, " Only a defined object can be destroyed by the delete operator" },
{ E0043, " Empty template" },
{ E0044, " Object not existing in this namespace" },
{ E0045, " Typage temptation with a non-instanciated structure" },
{ E0046, " Temptation to access a private field of the object" },
{ E0047, " Temptation to access a private method of the object" },
{ E0048, " Invalid operator" },
{ E0049, " Reserved identifier" },
{ E0050, " Wrong usage of postfix and prefix operator" },
{ E0051, " Temptation to access an inaccessible element in a table" },
{ E0052, " The main function can only have 3 arguments variation" },
{ E0053, " This function is not defined as being able to return an array" },
{ E0054, " A non-instanciated structure cannot be used as an object instance with the keyword 'new'" },
{ E0055, " Wrong choice of the anonymous string concatenation operator (between '^' and'+')" },
{ E0056, " An object can only inherit from one other object" },
{ E0057, " Incorrect 'typename' value" },
{ E0058, " Incorrect 'typesize' value" },
{ E0059, " The identifier of a process ('proc') cannot contain spaces" },
{ E0060, " The identifier of a process ('proc') cannot contain balises" },
{ E0061, " An exception cannot be thrown out of a function" },
{ E0062, " Syntax error" },
{ E0063, " The increment value of an iteration (with step) must be numerical" },
{ E0064, " An anonymous array serving as an iterator to a for loop cannot be empty" },
{ E0065, " Wrong ternary condition format" },
{ E0066, " A 'ret' instruction must only fit on one instruction (one line = one ';')" },
{ E0067, " Division by zero" },
{ E0068, " Wrong enumeration value" },
{ E0069, " 'Upon' block members cannot contain expressions other than 'it'" },
{ E0070, " A match/case expression must contain at least one 'case' expression before using 'default'" },
{ E0071, " Unknown error" },
{ E0072, " Undefined object" },
{ E0073, " Not a valid math expression" },
{ E0074, " Expected character" },
{ E0075, " Unbalanced brackets" },
{ E0076, " Non-ascii character detected" },
{ E0077, " The current version of Arlia only accepts constant values as optional function parameters" },
{ E0078, " Undefined type" },
{ E0079, " Statement not recognised in this context" },
{ E0080, " Invalid statement" },
{ E0000, " ... " }
};
};
The *.cpp just implements the functions as follows :
ThrowError(ErrorCodes code) {
colored_message_error("[ E" + std::to_string(code) + " ]" + Messages[code], Color::yellow);
}
As you can see, the list contains 80 + 1 elements. And E0080 has 80 as index in the enumeration.
When I try to access it:
exception.ThrowError(exception.E0080);
my program doesn't seem to want to update the information. That is, the enumeration constant sent to the function: in fact, the program displays the value I set before it (E29).
It's exactly like I'm doing this:
exception.ThrowError(exception.E0029);
So, no, it's most likely not a stupid debugging or compiling problem (I still know how to use a compiler ^^). It seems strange that Visual Studio does not update this new data (how ? why ? is it ?).