EGS Brachy
An egs++ user code for rapid brachytherapy calculations
Loading...
Searching...
No Matches
/Users/marc/Developer/EGSnrc/HEN_HOUSE/user_codes/egs_brachy/egs_brachy/spec_scoring.h
Go to the documentation of this file.
1/*
2################################################################################
3#
4# egs_brachy spec_scoring.h
5# Copyright (C) 2016 Rowan Thomson, Dave Rogers, Randle Taylor, and Marc
6# Chamberland
7#
8# This file is part of egs_brachy
9#
10# egs_brachy is free software: you can redistribute it and/or modify it
11# under the terms of the GNU Affero General Public License as published
12# by the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# egs_brachy is distributed in the hope that it will be useful, but
16# WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18# Affero General Public License for more details:
19# <http://www.gnu.org/licenses/>.
20#
21################################################################################
22#
23# When egs_brachy is used for publications, please cite our paper:
24# M. J. P. Chamberland, R. E. P. Taylor, D. W. O. Rogers, and R. M. Thomson,
25# egs brachy: a versatile and fast Monte Carlo code for brachytherapy,
26# Phys. Med. Biol. 61, 8214-8231 (2016).
27#
28################################################################################
29#
30# Author: Randle Taylor, 2016
31#
32# Contributors: Marc Chamberland
33# Dave Rogers
34# Rowan Thomson
35#
36################################################################################
37*/
38
44#include <sstream>
45#include "egs_advanced_application.h"
46#include "egs_functions.h"
47#include "egs_input.h"
48#include "egs_interface2.h"
49#include "egs_scoring.h"
50#include "ginfo.h"
51#include "pubsub.h"
52
53
58
66 EGS_Float getParticleEnergy(const EGS_Particle *p, bool subtractRM=true) {
67 EGS_Float rest_mass = 0;
68 if (subtractRM && p->q != 0){
69 rest_mass = the_useful->prm;
70 }
71 return (p->E - rest_mass)*p->wt;
72 }
73
75 void scoreParticleInitialized(EGS_Particle *p) {
76 /* When particle is first initialized by getNextParticle it does not
77 * include rest mass so we tell getParticleEnergy not to subtract the
78 * rest mass here. */
80 }
81
86
91
92public:
93
98
99 publisher->subscribe(this, PARTICLE_INITIALIZED);
100 publisher->subscribe(this, PARTICLE_ESCAPING_SOURCE);
101 publisher->subscribe(this, PARTICLE_ESCAPING_GEOM);
102
103 };
104
105
107 void scoreEnergyInitialized(EGS_Float E) {
109 }
113 if (total_energy_initialized > 0) {
115 }
116 return 0;
117 };
118
119
122 EGS_Float escapingGeomRatio() {
123 if (total_energy_initialized > 0) {
125 }
126
127 return 0;
128 }
129
133 }
134
138 }
139
141 EGS_Float energyEscapingGeom() {
143 }
144
145
147 void update(EB_Message message, void *particle) {
148
149 if (message == PARTICLE_INITIALIZED) {
150 EGS_Particle *p = static_cast<EGS_Particle *>(particle);
152 } else if (message == PARTICLE_ESCAPING_SOURCE) {
153 EGS_Particle *p = static_cast<EGS_Particle *>(particle);
155 } else if (message == PARTICLE_ESCAPING_GEOM) {
156
157 EGS_Particle *p = static_cast<EGS_Particle *>(particle);
159 }
160
161 }
162
163
166
167 string sep(80, '=');
168
169 egsInformation("\n\nEnergy Initialized and Escaping\n%s\n", sep.c_str());
170 egsInformation("Total Energy Initialized : %.5G MeV", totalEnergyInitialized());
171 egsInformation(
172 "\nTotal Energy Escaping Sources : %.5G MeV (%.3f%%)",
175 );
176
177 egsInformation(
178 "\nTotal Energy Escaping Geometry: %.5G MeV (%.3f%%)\n",
181 );
182
183 }
184
185 int outputData(ostream *ofile) {
186 (*ofile) << total_energy_initialized << " ";
187 (*ofile) << energy_escaping_sources << " ";
188 (*ofile) << energy_escaping_geom << "\n";
189 return 0;
190 };
191
192 int readData(istream *ifile) {
193 (*ifile) >> total_energy_initialized;
194 (*ifile) >> energy_escaping_sources;
195 (*ifile) >> energy_escaping_geom;
196 return 0;
197 }
198
204
205 int addState(istream &data) {
206 EGS_Float total_energy_initialized_tmp;
207 EGS_Float energy_escaping_sources_tmp;
208 EGS_Float energy_escaping_geom_tmp;
209
210 data >> total_energy_initialized_tmp;
211 data >> energy_escaping_sources_tmp;
212 data >> energy_escaping_geom_tmp;
213
214 total_energy_initialized += total_energy_initialized_tmp;
215 energy_escaping_sources += energy_escaping_sources_tmp;
216 energy_escaping_geom += energy_escaping_geom_tmp;
217
218 return 0;
219 };
220
221};
222
223
261
262protected:
263
264 string format;
267 EGS_I64 cur_history;
268 EGS_I64 eff_history;
270 EGS_Float bin_width;
271 EGS_Float total_scored;
272
273 EGS_BaseSource *source;
275 bool valid;
276
277 string fextension;
281 string outputCSV(string filename);
282
284 string outputXMGR(string filename);
285
287 string outputEGSnrc(string filename);
288
290 int getBin(EGS_Float E) const;
291
292 virtual string getTitle() const {
293 return "EGS_Brachy: spectrum";
294 }
295
296 virtual string getSubTitle() const {
297 return "";
298 }
299
300 virtual string getYAxisLabel() const {
301 return "";
302 }
303
304 virtual string getXAxisLabel() const {
305 return "E / MeV";
306 }
307
308 string getFileName(string root) const {
309 return root + "." + getFileExtension();
310 }
311
312 virtual string getFileExtension() const {
313 return "spec";
314 };
315
318 virtual void getResult(int bin, EGS_Float &r, EGS_Float &dr);
319
321 string getParticleName() const {
322
323 if (particle_type == 0) {
324 return "photon";
325 } else if (particle_type == -1) {
326 return "electron";
327 } else if (particle_type == 1) {
328 return "positron";
329 }
330
331 return "";
332 }
333
334 virtual void outputTotal() {
335 egsInformation("Total quantity scored: %.3g\n", total_scored);
336 };
337
338
339public:
340
341 static const int DEFAULT_NBINS = 100;
342
343
344 int nbins;
345 EGS_ScoringArray *bins;
346 EGS_Float e_min;
347 EGS_Float e_max;
349 BaseSpectrumScorer(EGS_Input *input, EGS_BaseSource *src, GeomInfo *ginfo, Publisher *publisher);
350
352 static BaseSpectrumScorer *getSpectrumScorer(EGS_Input *inp, EGS_BaseSource *source, GeomInfo *ginfo,
353 Publisher *publisher);
354
355 virtual ~BaseSpectrumScorer();
356
357 EGS_Float getBinWidth() const;
358
359 double getParticleEnergy(const EGS_Particle *p) const;
360
365 virtual void update(EB_Message message, void *data=0);
366
368 virtual void score(EB_Message message, void *data=0) = 0;
369
370 void setEffectiveHistories(EGS_Float effective_histories);
371
374 int outputResults(string root_name);
375
376 virtual string getInfo() const {
377 return getTitle();
378 }
379
381 bool isValid() const {
382 return valid;
383 }
384
385
386 int outputData(ostream *ofile);
387
388 int readData(istream *ifile);
389
390 void resetCounter();
391
392 int addState(istream &data);
393
394
395};
396
415
416
417 void getResult(int bin, EGS_Float &r, EGS_Float &dr);
418
419 string getTitle() const {
420 return "EGS_Brachy: " + getParticleName() + " counts on surface of source";
421 }
422
423 string getSubTitle() const {
424 return "";
425 }
426
427 string getYAxisLabel() const {
428 return "counts / total counts / MeV\\S-1";
429 }
430
431 void outputTotal();
432
433 string getFileExtension() const {
434 return fextension != "" ? fextension : "surfcount";
435 }
436
437public:
438
439
440 SurfaceCountSpectrum(EGS_Input *input, EGS_BaseSource *src, GeomInfo *ginfo, Publisher *publisher):
441 BaseSpectrumScorer(input, src, ginfo, publisher) {
442
443 publisher->subscribe(this, PARTICLE_ESCAPING_SOURCE);
444 };
445
446 virtual void score(EB_Message message, void *data=0);
447
448
449};
450
451
474
475 void getResult(int bin, EGS_Float &r, EGS_Float &dr);
476
477 string getTitle() const {
478 return "EGS_Brachy: energy weighted surface " + getParticleName() + " spectrum";
479 }
480
481 string getSubTitle() const {
482 return "";
483 }
484
485 string getYAxisLabel() const {
486 return "(dR/dE)/R / MeV\\S-1";
487 }
488
489 void outputTotal();
490
491 string getFileExtension() const {
492 return fextension != "" ? fextension : "ewsurf";
493 }
494
495public:
496
497 EnergyWeightedSurfaceSpectrum(EGS_Input *input, EGS_BaseSource *src, GeomInfo *ginfo, Publisher *publisher):
498 BaseSpectrumScorer(input, src, ginfo, publisher) {
499
500 publisher->subscribe(this, PARTICLE_ESCAPING_SOURCE);
501 };
502
503 virtual void score(EB_Message message, void *data=0);
504
505
506};
507
531
532 EGS_BaseGeometry *geometry;
533 EGS_Float region_volume;
536
537
538 void getResult(int bin, EGS_Float &r, EGS_Float &dr);
539
540 string getTitle() const {
541 stringstream ss;
542 ss << "EGS_Brachy: " << getParticleName() << " fluence spectrum in region ";
543 ss << local_scoring_region << " of '"<<geometry->getName()<<"'";
544 return ss.str();
545 }
546
547 string getYAxisLabel() const {
548 return "fluence / MeV / cm\\S2";
549 }
550
551 void outputTotal();
552
553 string getFileExtension() const {
554 return fextension != "" ? fextension : "voxelflu";
555 }
556
557public:
558
559
560 FluenceSpectrumInVoxel(EGS_Input *input, EGS_BaseSource *src, GeomInfo *ginfo, Publisher *publisher):
561 BaseSpectrumScorer(input, src, ginfo, publisher) {
562
563 if (particle_type != 0) {
564 egsFatal(
565 "Energy fluence spectra may only be scored for photons. See:\n\t"
566 "https://github.com/nrc-cnrc/EGSnrc/issues/109/\n"
567 "for details."
568 );
569 }
570
571 string gname;
572 int err = input->getInput("geometry",gname);
573 if (err) {
574 egsWarning("FluenceSpectrumInVoxel: missing or invalid `geometry` input\n");
575 valid = false;
576 return;
577 }
578
579 geometry = EGS_BaseGeometry::getGeometry(gname);
580 if (!geometry) {
581 egsWarning("FluenceSpectrumInVoxel: unable to find geometry named `%s` \n", gname.c_str());
582 valid = false;
583 return;
584 }
585
586 err = input->getInput("scoring region", local_scoring_region);
587 if (err) {
588 egsWarning("FluenceSpectrumInVoxel: no `scoring region` defined. Assuming region 0\n");
590 }
591
592 if (scoring_region < 0 || local_scoring_region > geometry->regions()) {
593 egsWarning("FluenceSpectrumInVoxel: invalid region `scoring region` defined. Assuming region 0\n");
595 }
596
598 scoring_region = ginfo->localToGlobal(geomreg);
599
601
602 publisher->subscribe(this, PARTICLE_TAKING_STEP);
603
604 };
605
606
607 virtual void score(EB_Message message, void *data=0);
608
609
610};
611
612
613
637
638 EGS_BaseGeometry *geometry;
639 EGS_Float region_volume;
642
643
644 void getResult(int bin, EGS_Float &r, EGS_Float &dr);
645
646 string getTitle() const {
647 stringstream ss;
648 ss << "EGS_Brachy: " << getParticleName() << " energy fluence spectrum in region ";
649 ss << local_scoring_region << " of '"<<geometry->getName()<<"'";
650 return ss.str();
651 }
652
653 string getYAxisLabel() const {
654 return "fluence / MeV / cm\\S2";
655 }
656
657 void outputTotal();
658
659 string getFileExtension() const {
660 return fextension != "" ? fextension : "voxelflu";
661 }
662
663public:
664
665
666 EnergyFluenceSpectrumInVoxel(EGS_Input *input, EGS_BaseSource *src, GeomInfo *ginfo, Publisher *publisher):
667 BaseSpectrumScorer(input, src, ginfo, publisher) {
668
669 if (particle_type != 0) {
670 egsFatal(
671 "Energy fluence spectra may only be scored for photons. See:\n\t"
672 "https://github.com/nrc-cnrc/EGSnrc/issues/109/\n"
673 "for details."
674 );
675 }
676
677 string gname;
678 int err = input->getInput("geometry",gname);
679 if (err) {
680 egsWarning("EnergyFluenceSpectrumInVoxel: missing or invalid `geometry` input\n");
681 valid = false;
682 return;
683 }
684
685 geometry = EGS_BaseGeometry::getGeometry(gname);
686 if (!geometry) {
687 egsWarning("EnergyFluenceSpectrumInVoxel: unable to find geometry named `%s` \n", gname.c_str());
688 valid = false;
689 return;
690 }
691
692 err = input->getInput("scoring region", local_scoring_region);
693 if (err) {
694 egsWarning("EnergyFluenceSpectrumInVoxel: no `scoring region` defined. Assuming region 0\n");
696 }
697
698 if (scoring_region < 0 || local_scoring_region > geometry->regions()) {
699 egsWarning("EnergyFluenceSpectrumInVoxel: invalid region `scoring region` defined. Assuming region 0\n");
701 }
702
704 scoring_region = ginfo->localToGlobal(geomreg);
705
707
708 publisher->subscribe(this, PARTICLE_TAKING_STEP);
709
710 };
711
712
713 virtual void score(EB_Message message, void *data=0);
714
715
716};
abstract base class for scoring spectrum information
virtual string getSubTitle() const
EGS_BaseSource * source
EGS_ScoringArray * bins
spectrum scoring array
int readData(istream *ifile)
string getParticleName() const
Return name of particle we are scoring.
EGS_Float getBinWidth() const
void setEffectiveHistories(EGS_Float effective_histories)
string outputCSV(string filename)
output results to csv file
int addState(istream &data)
int nbins
number of bins to score spectrum in
virtual void getResult(int bin, EGS_Float &r, EGS_Float &dr)
set r & dr to result/uncertainty for given bin. Normalization can be done in this routine
string outputXMGR(string filename)
output results to xmgrace file
static BaseSpectrumScorer * getSpectrumScorer(EGS_Input *inp, EGS_BaseSource *source, GeomInfo *ginfo, Publisher *publisher)
factory method for creating one of the derived spectrum scoring classes
bool isValid() const
virtual void score(EB_Message message, void *data=0)=0
virtual string getTitle() const
int getBin(EGS_Float E) const
get index of bin that that E falls in
virtual string getInfo() const
virtual void update(EB_Message message, void *data=0)
Receives messages from application. This method handles NEW_HISTORY messages but delegates all other ...
virtual void outputTotal()
int outputData(ostream *ofile)
string getFileName(string root) const
virtual ~BaseSpectrumScorer()
static const int DEFAULT_NBINS
virtual string getXAxisLabel() const
EGS_Float e_max
maximum spectrum energy to score
virtual string getYAxisLabel() const
virtual string getFileExtension() const
double getParticleEnergy(const EGS_Particle *p) const
string outputEGSnrc(string filename)
output results to EGSnrc tabulated spectrum format
EGS_Float e_min
minimum spectrum energy to score
int outputResults(string root_name)
, write the scored spectrum to file with filename. Returns 0 on success, all other values indicate a ...
A class for scoring the energy fluence of particles enter a voxel of the scoring phantom geometry.
EGS_BaseGeometry * geometry
EnergyFluenceSpectrumInVoxel(EGS_Input *input, EGS_BaseSource *src, GeomInfo *ginfo, Publisher *publisher)
virtual void score(EB_Message message, void *data=0)
void getResult(int bin, EGS_Float &r, EGS_Float &dr)
set r & dr to result/uncertainty for given bin. Normalization can be done in this routine
a class to use for scoring information about total energy initialzed, escaping sources etc
void scoreParticleEscapingGeom(EGS_Particle *p)
add energy from a escaping simulation geometry to the total
EGS_Float energyEscapingGeom()
returns the total energy of particles escaping simulation geometry
EGS_Float energyEscapingSources()
returns the total paticle energy escaping source geometry
EnergyScoringStats(Publisher *publisher)
EGS_Float escapingGeomRatio()
return the ratio of energy escaping the simulation geometry to total energy initialized
void scoreEnergyInitialized(EGS_Float E)
Needed for loading data from egsdat file.
EGS_Float getParticleEnergy(const EGS_Particle *p, bool subtractRM=true)
EGS_Float total_energy_initialized
total energy of particles initialized so far
void update(EB_Message message, void *particle)
delegate messages to appropriate scoring functions
void scoreParticleEscapingSource(EGS_Particle *p)
add energy from a particle escaping a source to the total
int readData(istream *ifile)
void scoreParticleInitialized(EGS_Particle *p)
add energy from initial particle to total
int outputData(ostream *ofile)
EGS_Float totalEnergyInitialized()
returns the total energy initialized
EGS_Float energy_escaping_geom
total energy of particles escaping the simulation geometry
EGS_Float energy_escaping_sources
total energy of particles escaping the source geometry note: doesn't currently exclude particles reen...
int addState(istream &data)
EGS_Float escapingSourcesRatio()
return the ratio of energy escaping the source to total energy initialized
void outputResults()
write results to console
A class for scoring the energy weighted spectrum (normalized to total radiant energy) of particles on...
EnergyWeightedSurfaceSpectrum(EGS_Input *input, EGS_BaseSource *src, GeomInfo *ginfo, Publisher *publisher)
void getResult(int bin, EGS_Float &r, EGS_Float &dr)
set r & dr to result/uncertainty for given bin. Normalization can be done in this routine
virtual void score(EB_Message message, void *data=0)
A class for scoring the fluence of particles enter a voxel of the scoring phantom geometry.
virtual void score(EB_Message message, void *data=0)
string getFileExtension() const
string getYAxisLabel() const
FluenceSpectrumInVoxel(EGS_Input *input, EGS_BaseSource *src, GeomInfo *ginfo, Publisher *publisher)
string getTitle() const
void getResult(int bin, EGS_Float &r, EGS_Float &dr)
set r & dr to result/uncertainty for given bin. Normalization can be done in this routine
EGS_BaseGeometry * geometry
a container for organizing meta data about the geometries
Definition ginfo.h:99
int localToGlobal(GeomRegT)
Definition ginfo.cpp:492
void subscribe(Subscriber *s, EB_Message message)
Definition pubsub.h:83
A class for scoring a histogram of the number of particles escaping a source geometry.
void getResult(int bin, EGS_Float &r, EGS_Float &dr)
set r & dr to result/uncertainty for given bin. Normalization can be done in this routine
SurfaceCountSpectrum(EGS_Input *input, EGS_BaseSource *src, GeomInfo *ginfo, Publisher *publisher)
string getFileExtension() const
string getYAxisLabel() const
string getTitle() const
virtual void score(EB_Message message, void *data=0)
string getSubTitle() const
ginfo contains classes for organizing information about the geometries present in an egs_brachy simul...
pair< EGS_BaseGeometry *, int > GeomRegT
pair of geometry and local region number
Definition ginfo.h:79
A simple pub/sub module to allow various egs_brachy classes to subscribe to particle events.
EB_Message
Definition pubsub.h:54
@ PARTICLE_ESCAPING_SOURCE
Definition pubsub.h:60
@ PARTICLE_TAKING_STEP
Definition pubsub.h:58
@ PARTICLE_INITIALIZED
Definition pubsub.h:57
@ PARTICLE_ESCAPING_GEOM
Definition pubsub.h:62