EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_particle_track.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ particle tracks
5 # Copyright (C) 2015 National Research Council Canada
6 #
7 # This file is part of EGSnrc.
8 #
9 # EGSnrc is free software: you can redistribute it and/or modify it under
10 # the terms of the GNU Affero General Public License as published by the
11 # Free Software Foundation, either version 3 of the License, or (at your
12 # option) any later version.
13 #
14 # EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
17 # more details.
18 #
19 # You should have received a copy of the GNU Affero General Public License
20 # along with EGSnrc. If not, see <http://www.gnu.org/licenses/>.
21 #
22 ###############################################################################
23 #
24 # Author: Georgi Gerganov, 2009
25 #
26 # Contributors: Iwan Kawrakow
27 #
28 ###############################################################################
29 */
30 
37 #include "egs_particle_track.h"
38 
40  // calculate the new size of the vertex array
41  int new_size = m_size > 0 ? m_size*2 : 16;
42  // not enough ?? then allocate more
43  if (m_nVertices > new_size) {
44  new_size = m_nVertices;
45  }
46  Vertex **tmp = new Vertex* [new_size];
47  if (m_track) {
48  for (int i = 0; i < m_nVertices; ++i) {
49  tmp[i] = m_track[i];
50  }
51  delete [] m_track;
52  m_track = NULL;
53  }
54  m_track = tmp;
55  m_size = new_size;
56 }
57 
59  if (m_pInfo) {
60  delete m_pInfo;
61  }
62  m_pInfo = NULL;
63  if (m_track)
64  for (int i = 0; i < m_nVertices; i++) {
65  if (m_track[i]) {
66  delete m_track[i];
67  }
68  m_track[i] = NULL;
69  }
70  m_nVertices = 0;
71 }
72 
73 int EGS_ParticleTrack::writeTrack(ofstream *trsp) {
74  // no need to write the track if it has less than 2 vertices ...
75  if (m_nVertices < 2) {
76  return 1;
77  }
78  trsp->write((char *)&m_nVertices, sizeof(int));
79  trsp->write((char *)m_pInfo, sizeof(ParticleInfo));
80  for (int i = 0; i < m_nVertices; i++) {
81  trsp->write((char *)m_track[i],sizeof(Vertex));
82  }
83  return 0;
84 }
85 
87  if ((v < 0) || (v >= m_nVertices)) {
88  return NULL;
89  }
90  return (m_track[v]);
91 }
92 
94  m_track[m_nVertices] = x;
95  m_nVertices++;
96  // resize the vertex array if necessary
97  if (m_nVertices >= m_size) {
98  grow();
99  }
100 }
101 
103 
105  // buffer full ? flush it
106  if (m_nTracks >= m_bufferSize) {
107  flushBuffer();
108  }
109  m_nTracks++;
110 
111  // mark the track as being scored
112  m_isScoring[m_nTracks-1] = true;
113 }
114 
116  if (m_nTracks >= m_bufferSize) {
117  flushBuffer();
118  }
119  m_nTracks++;
120 
121  // map the track on the stack
122  m_stackMap[stackIndex] = m_nTracks-1;
123  m_isScoring[m_nTracks-1] = true;
124 }
125 
127  if (m_nTracks >= m_bufferSize) {
128  flushBuffer();
129  }
130  m_nTracks++;
131  m_isScoring[m_nTracks-1] = true;
133 }
134 
136  int save = 0;
137  if (m_trspFile) {
138  for (int i = 0; i < m_nTracks; i++) {
139  // if the particle is not being scored anymore
140  if (!m_isScoring[i]) {
141  // output it to the file and free memory
142  if (!m_buffer[i]->writeTrack(m_trspFile)) {
143  m_totalTracks++;
144  }
145  m_buffer[i]->clearTrack();
146  }
147  else {
148  // still scoring it -> save the particle
149  m_buffer[save] = m_buffer[i];
150  m_isScoring[i] = false;
151  m_isScoring[save] = true;
152  for (int idx = 0; idx < m_bufferSize; idx++) {
153  if (m_stackMap[idx] == i) {
154  m_stackMap[idx] = save;
155  break;
156  }
157  }
158  save++;
159  }
160  }
161  updateHeader();
162  }
163  m_nTracks = save;
164 }
165 
167  if (m_trspFile) {
168  ostream::off_type pos = m_trspFile->tellp();
169  m_trspFile->seekp(0,ios::beg);
170  m_trspFile->write((char *) &m_totalTracks, sizeof(int));
171  m_trspFile->seekp(pos,ios::beg);
172  }
173 }
174 
176  if ((tr < 0) || (tr >= m_nTracks)) {
177  return NULL;
178  }
179  return (m_buffer[tr]->getVertex(v));
180 }
181 
183  if (!m_isScoring[m_nTracks-1]) {
184  return;
185  }
187 }
188 
190  if (m_stackMap[stackIndex] < 0) {
191  return;
192  }
193  if (!m_isScoring[m_stackMap[stackIndex]]) {
194  return;
195  }
196  m_buffer[m_stackMap[stackIndex]]->addVertex(x);
197 }
198 
199 int EGS_ParticleTrackContainer::readDataFile(const char *filename) {
200  const char *func_name = "EGS_ParticleTrackContainer::readDataFile()";
201  ifstream *data = new ifstream(filename, ios::binary);
202  if (!data || data->fail() || !data->good()) {
203  egsWarning("%s: Unable to open track space file '%s'! No tracks loaded\n",
204  func_name, filename);
205  return -1;
206  }
207  data->read((char *)&m_totalTracks, sizeof(int));
208  egsInformation("%s: Reading %d tracks from '%s' ...\n", func_name, m_totalTracks, filename);
209  m_nTracks = 0;
210  int totalVertices = 0;
213  m_stackMap = new int [m_totalTracks];
214  m_isScoring = new bool [m_totalTracks];
215  for (int i = 0; i < m_totalTracks; i++) {
216  int nvertices;
217  m_buffer[i] = new EGS_ParticleTrack();
218  m_stackMap[i] = -1;
219  m_isScoring[i] = false;
221  data->read((char *)&nvertices,sizeof(int));
222  totalVertices += nvertices;
223  data->read((char *)pinfo,sizeof(EGS_ParticleTrack::ParticleInfo));
224  startNewTrack(pinfo);
225  for (int j = 0; j < nvertices; j++) {
227  data->read((char *)v,sizeof(EGS_ParticleTrack::Vertex));
228  addVertex(v);
229  }
230  }
231  egsInformation("%s: Tracks in memory: %d\n", func_name, m_nTracks);
232  egsInformation("%s: Total Vertices : %d\n", func_name, totalVertices);
233 
234  return 0;
235 }
236 
238  flushBuffer();
239 
240  // see how many tracks are still being scored
241  int scoring = -1;
242  if (m_isScoring) {
243  scoring = 0;
244  for (int i = 0; i < m_bufferSize; i++) {
245  if (m_isScoring[i]) {
246  scoring++;
247  }
248  }
249  }
250 
251  if (with_header) {
252  egsInformation("\nParticle track scoring results:\n");
253  egsInformation("=================================\n");
254  egsInformation(" Total events scored: %d\n", m_nEvents);
255  }
256  egsInformation(" Total tracks scored: %d\n", m_totalTracks);
257  egsInformation(" Still being scored: ");
258  if (scoring == -1) {
259  egsInformation("Unknown!?\n");
260  }
261  else {
262  egsInformation("%d\n", scoring);
263  if (scoring > 0) {
264  egsWarning(" *** There are particles still being tracked. This"
265  " should never happen if this is the end of the simulation!");
266  }
267  }
268  egsInformation(" Output file name: %s\n\n", m_trspFilename.c_str());
269 }
Vertex * getVertex(int v)
Gets vertex number v .
void grow()
Resize the array containing the vertices.
ofstream * m_trspFile
the file to which data is output
int m_totalTracks
total number of tracks registered
int readDataFile(const char *filename)
Load particle data from the file called filename .
A class representing a single track of a particle.
void updateHeader()
Update the output file&#39;s header.
void flushBuffer()
Write all track data to the file.
EGS_ParticleTrack class header file.
ParticleInfo * m_pInfo
type of the tracked particle
int writeTrack(ofstream *trsp)
Write this track to a &quot;track space&quot; file.
void addVertex(EGS_ParticleTrack::Vertex *x)
Add a vertex to the track currently being scorred.
int m_nEvents
number of events scored
void setParticleInfo(ParticleInfo *p)
Define the type of the particle being tracked.
int m_size
current size of the vertex array
EGS_ParticleTrack::Vertex * getTrackVertex(int tr, int v)
Get the v vertex from the tr track.
Structure describing the particle being tracked.
EGS_InfoFunction EGS_EXPORT egsInformation
Always use this function for reporting the progress of a simulation and any other type of information...
Structure to store the data for each interaction along the track.
EGS_ParticleTrack ** m_buffer
the tracks array
void addVertex(Vertex *x)
Add additional point of interaction (Vertex) to the track.
int m_nTracks
number of tracks currently in memory
void reportResults(bool with_header=true)
Report results from the track scoring process so far.
void clearTrack()
Deallocate particle information and vertex data.
int m_bufferSize
max number of tracks in memory
void startNewTrack()
Start scoring a new track.
string m_trspFilename
filename of output file
Vertex ** m_track
the array with the vertices
int m_nVertices
current number of vertices in track
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.