Dear all,
I am getting back to ROOT after a long sweet time off (several years). I am trying to organize a neat little custom tree to hold the data from some detectors. I attach the class(es) definition and the program that compiles it and fills 10 events. The detector has several (may vary) “Axes” that hold arrays of channel readouts (floats) and channel numbers to implement mapping later on. The number of channels in different hardware is different (known, I can read it from the hardware) and it would be great to have those arrays holding channels data, to be of variable size / depth.
I have class Event and the nested class Axis, and I can add axes via method AddAxis according to whatever number I read.
One way to implement variable arrays in a class I found is described here: http://www.fredosaurus.com/notes-cpp/newdelete/50dynamalloc.html
But it does not work (you will see my pathetic attempts commented out in the header file).
Anyway… how would I do it? I know it is more C++ than anything ROOT but this must be common use case. Please help!
Thank you for your reply.
I did read those items before posting ( and this is how I had arrived to what I have now ).
My case is most coincident with the “12.17 Example 4: A Tree with an Event Class” that has Track class nested in it, and used TObjectArray of those.
I still fail to see how I can define the size of an array contained within the class, by an integer supplied during the initialization of that particular instance of that class.
I do know how to do a simple tree with:
t2.Branch(“lmec”,gstep.lmec,“lmec[nmec]/I”);
This is not what I have been asking. This is not my case.
In class Axis, I have the number of channels, nchannels, amd some data, say their order numbers,
Int_t chnum [300];
and the Float_t chdata [300];
and it stays size 300. What I do want is I want it sized by the
Int_t nchannels;
when I initialize the instance of the Axis, and I want it only be nchannels deep, and NOT 300 deep.
To achieve that , I have been trying to initialize the class with a pointer, then associate pointer with the array that I will actually size appropriately for each object intsance.
There is still I think problem in paradise
It >> runs << but does not fill in the goodies, I think.
and that InconsistentHash does not promise anything good either…
Thank you for following up with me and this hiccup… No, in fact I do not see meaningful stuff in the axis. In theory, the detclass.C does not vary the size of array event to event - it is what it is, 32. So the histograms should have been there… but they are not.
Humm … okay … so you may also have a problem in the way you enter the Axis object into the TClonesArray. Can you show that code? and the result of t->Scan("evt.axis.@size","","",5,0);
The execution of the vdetclass.C will fail like that as the shared library hasn’t been loaded.
To produce the shared library, I link the C-file, from root command prompt
.L vdetclass.C+
or if that has already been done, load the shared library,
.L vdetclass_C.so
then execute detwrite() function with default arguments.
If one wants to execute it with .x then we need to rename that function into vdetclass() which I have just now done. Now your usage of valgrind starts making sense. Even so, I have never used that tool, so I had it installed. The “suppressions” could not be found,
==808== FATAL: can’t open suppressions file “/usr/opt/root/etc/valgrind-root.supp”
but we’ll nevermind for the time being.
egalyaev@EUGMSI:~/work/rootcontclass_example$ valgrind root -b -l -q vdetclass.C+
==886== Memcheck, a memory error detector
==886== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==886== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==886== Command: root -b -l -q vdetclass.C+
==886==
==886== error calling PR_SET_PTRACER, vgdb might block
Processing vdetclass.C+...
Info in <TUnixSystem::ACLiC>: creating shared library /home/egalyaev/work/rootcontclass_example/./vdetclass_C.so
detwrite: output file vdetclass.root
detwrite: start loop
Event: 0
Axis: 0
Channel[5]: 1
Channel[6]: 1.0625
Channel[7]: 1.125
Channel[8]: 1.1875
Channel[9]: 1.25
Channel[10]: 1.3125
Channel[11]: 1.375
Channel[12]: 1.4375
Channel[13]: 1.5
Channel[14]: 1.5625
Channel[15]: 1.625
Channel[16]: 1.6875
Channel[17]: 1.75
Channel[18]: 1.8125
Channel[19]: 1.875
Channel[20]: 1.9375
Channel[21]: 2
Channel[22]: 2.0625
Channel[23]: 2.125
Channel[24]: 2.1875
Channel[25]: 2.25
Channel[26]: 2.3125
Channel[27]: 2.375
Channel[28]: 2.4375
Channel[29]: 2.5
Channel[30]: 2.5625
Channel[31]: 2.625
Channel[32]: 2.6875
Channel[33]: 2.75
Channel[34]: 2.8125
Channel[35]: 2.875
Channel[36]: 2.9375
blah1!
inside AddAxis 1: naxis=0
inside AddAxis 2: naxis=1
*** Break *** segmentation violation
Root > ==886==
==886== HEAP SUMMARY:
==886== in use at exit: 0 bytes in 0 blocks
==886== total heap usage: 1 allocs, 1 frees, 72,704 bytes allocated
==886==
==886== All heap blocks were freed -- no leaks are possible
==886==
==886== For counts of detected and suppressed errors, rerun with: -v
==886== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
You subtly but fatally changed my recommendation. The .exe is essentially (there is an executable named ‘root’ and another (called by the first one) named ‘root.exe’. To get any actual information use:
valgrind root.exe -b -l -q vdetclass.C+
==808== FATAL: can’t open suppressions file “/usr/opt/root/etc/valgrind-root.supp”
humm … odd … without that file we will flooded with false negative. So I am not sure where that file is for your installation but using it would make things simpler.
I >>> almost << have it working…
At least it iterates and forms tree structure… alas, empty Axes items Maybe you can help me to beat this into shape… please. vdetclass.h (2.7 KB)