Serious problem with pointers and CERN root !

Dear Coders,

I will try to put the question through a simplest (but complete) representation of my original program. I have a macro that I use to analyze particle physics data using CERN's ROOT software. Here's the macro

code-1
analysis.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>

using namespace std;

//main macro

void analysis()
{
     TString filen1; //file name variable
     char input_ROOT[200];
     
     cout <<"Insert the file name"<<endl;
     cin>>filen1;


     TFile *f = TFile::Open(input_ROOT);
     TTree *tree = (TTree*)f->Get("Tree");

     const int n_entry = tree->GetEntries(); // # of entries in the tree

     TBranch *branch1 = tree->GetBranch("Particle1");
     TBranch *branch1 = tree->GetBranch("Particle2");

     int arr1[16], arr2[16];
     vector <double> charge, mass, energy;

     int *particle1_mass = &arr1[0], *particle2_mass = &arr2[0];
     int *particle1_charge = &arr1[1], *particle2_charge = &arr2[1];
     int *particle1_energy = &arr1[2], *particle2_energy = &arr2[2];

     branch1->SetAddress(&p1[0]);
     branch1->SetAddress(&p1[0]);


     for (int i = 0; i < n_entry; ++i)
     {
           branch1->GetEntry(i); //extracts the data from branch particle1
           //conditions
           const bool cond_charge1 = *particle1_charge > 0;
           
           if(cond_charge1)
           {
                  mass.push_back(*particle1_charge);
                  charge.push_back(*particle1_mass);
                   
            }  

       }

 }



This code works perfectly on my CERN-ROOT shell and produces desired results. But the problem arises when I try to do the following:

// Case 2
analysis.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>

using namespace std;

//main macro

void analysis()
{
     TString filen1; //file name variable
     char input_ROOT[200];
     
     cout <<"Insert the file name"<<endl;
     cin>>filen1;


     TFile *f = TFile::Open(input_ROOT);
     TTree *tree = (TTree*)f->Get("Tree");

     const int n_entry = tree->GetEntries(); // # of entries in the root tree

     //TBranch *branch1 = tree->GetBranch("Particle1");
     //TBranch *branch1 = tree->GetBranch("Particle2");
     // instead of the above two, I do
     TBranch *branch[1];
     branch[0] = tree->GetBranch("Particle1");
     branch[1] = tree->GetBranch("Particle2");


     //int arr1[3], arr2[3];
     //instead of the above I do
     int  arr[3][3];
     vector <double> charge, mass, energy;
     
      
     //we rename the pointers
     // particle1,2_x goes to particle[i]_x

     int *particle[2];

     particle_mass[0] = &arr[0][0],   particle_mass[1] = &arr[1][0];
     particle_charge[0] = &arr[0][1], particle_charge[1] = &arr[1][1];
     particle_energy[0] = &arr[0][2], particle_energy[1] = &arr[1][2];

     branch[0]->SetAddress(&arr[0][0]);
     branch[1]->SetAddress(&arr[1][0]);

     
     for (int i = 0; i < n_entr; ++i)
     {
           branch[1]->GetEntry(i); //extracts the data from branch particle1
           //conditions
           const bool cond_charge1 = *particle[0]_charge > 0;
           
           if(cond_charge1)
           {
                  mass.push_back(*particle1_charge);
                  charge.push_back(*particle1_mass);
                   
            }  

       }

 }



This code doesn't show syntax errors but the pointers don't seem to work ! The boolean condition always returns 0 ! I have no clue about how to fix this. Please help. One might think that it's a CERN-ROOT issue and should be posted in relevant forum ! I don't think so, it's purely a C++ error I believe.
Last edited on
Several things don't make sense there.
line 41
 
    int *particle[1];

an array of pointers to integers is declared. Its size is 1. Therefore, the one and only valid element is particle[0].

I've no idea what this is.
 
particle[0]_mass

sticking the characters "_mass" immediately after the array element doesn't look like any syntax I can recognise.
It gives a compile error
[Error] expected ';' before '_mass'


In addition, there is a practical difficulty in trying to compile the code, since it depends upon classes and headers which are not part of standard C++, so any comments I make could only be a starting point, rather than a complete answer.
Sorry, the array size in my real program is actually [2], I don't know why I typed [1] here !
particle[0]_mass this again is a typo here not in my real code, it should be [code]particle_mass[0][/code\



>"since it depends upon classes and headers which are not part of standard C++"

I understand that, but I guess one can ignore those classes and start by assuming that the data is coming from an external file. One can start from the declaration pointers.
particle[0]_mass this again is a typo here not in my real code, it should be particle_mass[0]
ok but particle_mass is now not declared.

Perhaps the best approach is to just post your actual code, don't try editing it, or retyping it. Simple copy and paste.
closed account (48T7M4Gy)
const bool cond_charge1 = *particle1_charge > 0;
An interesting piece of C++ whatever it means.
@kemort it means I am going to select only positively charged particles.
I have solved the problem. The source of the problem lies not in c++ but in the ROOT file. Root file has its tree, branch structure and leafs inside each branches. In the above example, I have a root file named filen1, which has one tree and it has 2 branches: Particle1 and Particle2, but it has 4 leafs in each branches namely spin, charge , mass and energy. So in the step where I am assigning the addresses to these variables, I have to maintain there order perfectly, while using an array, spin should be the 0th element then charge and so on. If I mess up the order, the conditions will be wrong and hence the code will return bogus results. So the correct code will be:

1
2
3
4
     particle_spin[0] =      &arr[0][0],   particle_spin[1] =      &arr[1][0];
     particle_mass[0] =      &arr[0][1],   particle_mass[1] =    &arr[1][1];
     particle_energy[0] = &arr[0][2],   particle_energy[1] = &arr[1][2];
     particle_charge[0] = &arr[0][3],   particle_charge[1] = &arr[1][3];


And in fact I can use two dimensional array for the other parameters too, by identifying their order. So the above assignments will now look like:


1
2
3
4
5
6
7
     for(i = 0; i < 2; ++i)
     {
             for(j = 0; j < 5; ++j)
             {
                       param[i][j] =      &arr[i][j];
             }
     }


I have to keep in mind that, in param[i][j], i = 0, 1 would be particle 1, 2 respectively and j = 0, 1, 2, 3, 4 would mean spin, mass, energy, charge respectively.


Of course an order like that is expected but as I am almost an absolute newbie in C++ and ROOT, it took time to understand this.

Anyways.. thanks everyone.
but it has 4 leafs in each branches namely spin, charge , mass and energy ... I have to maintain there order perfectly,

The code-table you show has order spin - mass - energy - charge. Anyways, since you say you've solved the problem you've probably made the necessary edits somewhere. What I really wanted to say was:
1. instead of using POD (plain-old-data) you may also consider setting up a struct on the following lines:
1
2
3
4
5
6
7
8

struct Particle
{
	double _spin;
	double _charge;
	double _mass;
	double _energy;
}

Data from files can then be read into Particle objects directly, and ...
2. instead of C-style arrays you're using now do consider standard library containers (vector, list, set ... the choices are many ) to store your data. It is quite easy to retain the order of the data from the file if you so wish, sort, print and do all sorts of operations on the data stored within any standard library container using algorithms and iterators and you don't have to worry about fixed sizes, the containers can resize as more data come in. Here is a (slightly dated but still v useful) containers' cheat sheet: http://homepages.e3.net.nz/~djm/cppcontainers.html
@gunnerfunner you suggestions are extremely useful and in fact I will implement them once I learn about all those new cool features. As I had mentioned (probably somewhere) that I am really new to programming, a little experience I had in fortran 77, years ago. Hopefully in a few weeks I will be able to learn at least these essential features.


Thanks a lot.

closed account (48T7M4Gy)
@kemort it means I am going to select only positively charged particles.


Thanks , I can see why you're having problems with ROOT rather than C++.
C++ would say while(*particle1_charge > 0) ... etc or similar
But I thought I can always define a boolean type variable and directly apply it in the conditions, I believe it's a C++ feature, isn't it ? But are you saying using while(*particle1_charge > 0) ... etc would make my life simpler ? I might actually try this one out too.


Thanks
These two pieces of code would achieve the same result:
1
2
3
           const bool cond_charge1 = *particle1_charge > 0;
           
           if (cond_charge1)



 
          if (*particle1_charge > 0)


Both are correct. The first is longer and probably a little harder to read, it doesn't seem to be of any benefit here. There are times when bool variables are useful, to store some result which will be used later, but it isn't necessary here.
closed account (48T7M4Gy)
@nathatanu0

Yes a while loop appears to me to be simpler, clearer and all that's required.

You can apply a bool type to do what you want but I have never seen that particular way before - a new experience for me and having checked elsewhere I think a lot of people would be surprised - of course I can't say it's new for everybody though.

You could also write:

1
2
3
4
5
bool test_positive = false; // ie initialise a bool variable
if( *particle1_charge > 0)
    test_positive = false;
else
    test_positive = true;


But this is all terribly convoluted when you can test the sign directly so much more simply.

As an overall observation I think you can possibly gain a lot by using standard C++ if your ' C++ derivative' ROOT can accommodate it. I saw what ROOT can do and since it's very specialised maybe standard C++ isn't an option.

If it can be an option I think you will find gunnerfunners advice to be very worthwhile considering. ( A small point, starting variable names with and underscore is not a good convention, but this doesn't alter the power of structs and classes. )



kemort: you're right, I started off with m_member, etc; then got lazy and ditched the 'm', it's going right back on. Thanks
closed account (48T7M4Gy)
Cheers, gunnerfunner. Your comments on containers etc were vital whereas the underscore is probably as you know a suggestion by Stroustrup to avoid naming conflicts with system variables, ie keep them in an underscore world of their own.

(FWIW: given the way most IDE's work I'd just call them spin, charge, mass, energy and you end up with Particle electron with electron.charge etc which has a nice ring to it. )
Yeah I realize now the danger of underscores while learning about including headers etc.
closed account (48T7M4Gy)
A bit more that on the esoterica of underscores I raised. Keep in mind underscores inside the name are good coding practice especially for making the code as self documenting as possible :)

http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier
Thanks a lot kemort, I see particle physicists using underscores too often.
Topic archived. No new replies allowed.