-
Notifications
You must be signed in to change notification settings - Fork 1
/
AliGMFEventContainer.cxx
237 lines (217 loc) · 8.4 KB
/
AliGMFEventContainer.cxx
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
// for the track shuffler
#include <iostream>
#include <algorithm>
#include <vector>
#include <ctime>
#include <cstdlib>
// root includes
#include "TClonesArray.h"
// custom includes
#include "AliGMFEventContainer.h"
#include "AliGMFTTreeHeader.h"
#include "AliGMFTTreeTrack.h"
ClassImp(AliGMFEventContainer)
//------------------------------------------------------------------------
AliGMFEventContainer::AliGMFEventContainer(
AliGMFTTreeHeader* event,
TClonesArray* array, Int_t eventID) : TObject()
{
// link the event
fHeader = event;
fTracks = array;
if(fHeader) fHeader->SetEventID(eventID);
}
//------------------------------------------------------------------------
void AliGMFEventContainer::SetEvent(
AliGMFTTreeHeader* event,
TClonesArray* tracks, Int_t eventID) {
// set event, only public access to avoid mixing tracks and headers
fHeader = event;
fTracks = tracks;
if(fHeader) fHeader->SetEventID(eventID);
}
//-----------------------------------------------------------------------------
Bool_t AliGMFEventContainer::Fill(AliGMFEventContainer* event) {
// fill the current event with info from another event
// just fills, does *not* create objects !!!
if(!event) return kFALSE;
// fill the event header
fHeader->Fill(event->GetHeader());
// fill the tracks
for(Int_t i(0); i < event->GetNumberOfTracks(); i++) {
if(GetTrack(i) && event->GetTrack(i)) {
GetTrack(i)->Fill(event->GetTrack(i));
} else printf(" Warning, tried to fill track %i but memory is not allocated - skipping track ! \n ", i);
}
fTrackIterator = -1;
return kTRUE;
}
//-----------------------------------------------------------------------------
void AliGMFEventContainer::Flush() {
// reset this event
if(GetHeader()) GetHeader()->Reset();
AliGMFTTreeTrack* track(0x0);
// important is that the track flag 'filled'
// is set to kFALSE
for(Int_t i(0); i < GetNumberOfTracks(); i++) {
track = GetTrack(i);
if(track) track->Reset();
}
fTrackIterator = -1;
}
//-----------------------------------------------------------------------------
void AliGMFEventContainer::FlushAndFill(AliGMFEventContainer* event) {
// clear out the event (no deallocation) and fill it with new event info
Flush();
// fill the new events
Fill(event);
}
//-----------------------------------------------------------------------------
Int_t AliGMFEventContainer::FlushOutZeroes() {
// remove any zeroes from the track index buffer
#ifdef __CLING__
// if cling is defined, use modern stuff
auto checkStatus = [&](int i) -> bool {
return GetTrack(fTrackIndexMap.at(i))->GetFilled();
};
std::remove_if(
fTrackIndexMap.begin(),
fTrackIndexMap.end(),
checkStatus);
#else
// first get the size of the index map
UInt_t lastEntry = fTrackIndexMap.size()-1;
Int_t tempEntry;
// loop over all entries in the track map
for(UInt_t i(0); i < fTrackIndexMap.size(); i++) {
if(lastEntry <= i) break;
// check if an index points to an unused track
if(!(GetTrack(fTrackIndexMap.at(i))->GetFilled())) {
// if so, find the used track with the highest index number
while(!GetTrack(fTrackIndexMap.at(lastEntry))->GetFilled()) {
lastEntry--;
}
if(lastEntry > i) {
// and then swap the used and unused track
tempEntry = fTrackIndexMap.at(i);
fTrackIndexMap.at(i) = fTrackIndexMap.at(lastEntry);
fTrackIndexMap.at(lastEntry) = tempEntry;
lastEntry--;
}
}
}
#endif
return fTrackIndexMap.size();
}
//-----------------------------------------------------------------------------
void AliGMFEventContainer::SetUsed(Bool_t used) {
// mark the header as read
fHeader->SetUsed(used);
}
//-----------------------------------------------------------------------------
void AliGMFEventContainer::PrintEventSummary() {
// print some test information of the current event
printf("\n Current event number %i \n", fHeader->GetEventID());
if(fTracks) printf(" - contains %i tracks \n", fTracks->GetEntries());
printf(" - status %i \n", (int)(fHeader->GetUsed()));
}
//_____________________________________________________________________________
void AliGMFEventContainer::Dump() const {
// 'recursive' dump of contents
TObject::Dump();
if(fHeader) {
printf(" Dumping event header \n");
fHeader->Dump();
}
if(fTracks) {
printf(" Dump array with %i tracks \n", fTracks->GetEntries());
fTracks->Dump();
}
}
//_____________________________________________________________________________
void AliGMFEventContainer::ShuffleTrackIndices() {
// the order of tracks is not necessarily 'random'
// this function shuffles the indices in the track so that the
// new index array is a random bijection of the old index array
// reset the current shuffled indices or create a new map
// if there's no old in memory
ResetTrackIndices();
// shuffle the indices
std::random_shuffle(
fTrackIndexMap.begin(),
fTrackIndexMap.end());
// then order the tracks again, to remove any 'holes'
}
//_____________________________________________________________________________
void AliGMFEventContainer::ResetTrackIndices() {
// reset the track indices to non-shuffled values
if(!fTrackIndexMap.empty()) {
fTrackIndexMap.clear();
}
for (Int_t i = 0; i < GetNumberOfTracks(); i++) fTrackIndexMap.push_back(i);
}
//_____________________________________________________________________________
AliGMFTTreeTrack* AliGMFEventContainer::GetTrack(Int_t i) {
// return the i-th track of the event
if(fTrackIndexMap.empty()) {
if(i > GetMultiplicity()) return 0x0;
return static_cast<AliGMFTTreeTrack*>(fTracks->At(i));
} else {
return static_cast<AliGMFTTreeTrack*>(fTracks->At(fTrackIndexMap.at(i)));
}
}
//_____________________________________________________________________________
AliGMFTTreeTrack* AliGMFEventContainer::GetNextTrack() {
// return the i-th filled track of the event
fTrackIterator++;
// if many tracks are skipped (not filled) these conditions can happen
if(fTrackIterator > GetMultiplicity()-1 || fTrackIterator < 0) return 0x0;
AliGMFTTreeTrack* track(0x0);
// try to get a track
if(fTrackIndexMap.empty()) {
track = static_cast<AliGMFTTreeTrack*>(fTracks->At(fTrackIterator));
} else {
track = static_cast<AliGMFTTreeTrack*>(fTracks->At(fTrackIndexMap.at(fTrackIterator)));
}
// keep trying until it's filled or we reach the end of the buffer
while(!track->GetFilled()) {
fTrackIterator++;
if(fTrackIterator > GetMultiplicity()-1) return 0x0;
if(fTrackIndexMap.empty()) {
track = static_cast<AliGMFTTreeTrack*>(fTracks->At(fTrackIterator));
} else {
track = static_cast<AliGMFTTreeTrack*>(fTracks->At(fTrackIndexMap.at(fTrackIterator)));
}
}
return track;
}
//_____________________________________________________________________________
void AliGMFEventContainer::ResetTrack(Int_t i) {
// reset track at index i
AliGMFTTreeTrack* track = GetTrack(i);
if(track) track->Reset();
}
//_____________________________________________________________________________
Int_t AliGMFEventContainer::FindEmptyTrack() {
// find a slot of the tclones array that has an empty track in it,
// return the index to that element, or -1 when no track is found
AliGMFTTreeTrack* track(0x0);
for(Int_t i = 0; i < GetNumberOfTracks(); i++) {
track = GetTrack(i);
if(track && !track->GetUsed()) return i;
}
return -1;
}
//_____________________________________________________________________________
AliGMFTTreeTrack* AliGMFEventContainer::FindOrCreateEmptyTrack() {
// find a slot of the tclones array that has an empty track in it,
// return the index to that element, or add a new track if no track was found
Int_t trackIdx(FindEmptyTrack());
if(trackIdx < 0) {
// create a new track
trackIdx = GetNumberOfTracks();
new((*fTracks)[trackIdx]) AliGMFTTreeTrack();
}
return GetTrack(trackIdx);
}
//_____________________________________________________________________________