18
BASEparticle::BASEparticle() : TransferMatrixGenerator("BASEparticle") {
18
BASEparticle::BASEparticle() : TransferMatrixGenerator("BASEparticle"), usingLattice(false) {
19
19
getCurrentStream() << "Constructing BASEparticle" << std::endl;
21
21
particlesRun = false;
23
refPart = static_cast<MAUSPrimaryGeneratorAction::PGParticle*>(malloc(sizeof(MAUSPrimaryGeneratorAction::PGParticle)));
24
polynomialMatrix = static_cast<Matrix<double>*>(malloc(sizeof(Matrix<double>)));
23
refPart = NULL; polynomialMatrix = NULL; dataOut = NULL; refDataOut = NULL; particles = NULL; thirdOrderMap = NULL;
29
24
bField = Globals::GetMCFieldConstructor()->GetMagneticField();
30
25
integrator = new BfieldIntegratorMap(bField);
31
26
getCurrentStream() << "Memory allocated" << std::endl;
32
27
setDataOut(Json::Value(Json::nullValue));
33
28
setRefDataOut(Json::Value(Json::nullValue));
34
29
setParticles(Json::Value(Json::nullValue));
35
getCurrentStream() << "Values set" << std::endl;
30
_numberOfParticles = 0;
33
BASEparticle::BASEparticle(AnalyticLattice* lattice) : TransferMatrixGenerator("BASEparticle"), usingLattice(true), _lattice(lattice) {
34
getCurrentStream() << "Constructing BASEparticle using lattice" << std::endl;
38
refPart = NULL; polynomialMatrix = NULL; dataOut = NULL; refDataOut = NULL; particles = NULL; thirdOrderMap = NULL;
39
bField = lattice->getFieldGroup();
40
integrator = new BfieldIntegratorMap(bField);
41
getCurrentStream() << "Memory allocated" << std::endl;
42
setDataOut(Json::Value(Json::nullValue));
43
setRefDataOut(Json::Value(Json::nullValue));
44
setParticles(Json::Value(Json::nullValue));
45
_numberOfParticles = 0;
39
48
BASEparticle::~BASEparticle() {
41
free(polynomialMatrix);
42
delete polynomialMatrix;
49
if (refPart != NULL) delete refPart;
50
if (polynomialMatrix != NULL) delete polynomialMatrix;
54
MAUSPrimaryGeneratorAction::PGParticle BASEparticle::getRefPart() const {if (refPart == NULL) throw std::runtime_error("BASEparticle::getRefPart is NULL"); return *refPart;}
55
Json::Value BASEparticle::getParticles() const {if (particles == NULL) throw std::runtime_error("BASEparticle::getParticles is NULL"); return *particles;}
56
BTField* BASEparticle::getBField() const {if (bField == NULL) throw std::runtime_error("BASEparticle::getBField is NULL"); return bField;}
57
BfieldIntegrator* BASEparticle::getIntegrator() const {if (integrator == NULL) throw std::runtime_error("BASEparticle::getIntegrator is NULL"); return integrator;}
58
Json::Value BASEparticle::getDataOut() const {if (dataOut == NULL) throw std::runtime_error("BASEparticle::getDataOut is NULL"); return *dataOut;}
59
Json::Value BASEparticle::getRefDataOut() const {if (refDataOut == NULL) throw std::runtime_error("BASEparticle::getRefDataOut is NULL"); return *refDataOut;}
60
PolynomialMap BASEparticle::getThirdOrderMap() const {if (thirdOrderMap == NULL) throw std::runtime_error("BASEparticle::getThirdOrderMap is NULL"); return PolynomialMap(*thirdOrderMap);}
61
AnalyticLattice* BASEparticle::getLattice() const {if (usingLattice == false) throw std::runtime_error("BASEparticle::getLattice() is not in usingLattice mode. Use constructor to pass AnalyticLattice* object"); if (_lattice == NULL) throw std::runtime_error("BASEparticle::getLattice is NULL"); return _lattice;}
62
int BASEparticle::getNumberOfParticles() const {return _numberOfParticles;}
46
64
std::vector<PolynomialMap::PolynomialCoefficient> BASEparticle::get2ndOrderBlanks() {
47
65
std::vector<PolynomialMap::PolynomialCoefficient> v;
48
66
for (int i = 0; i < 4; i++) {
60
void BASEparticle::runParticles() {
61
getCurrentStream() << "Running reference particle" << std::endl;
62
Json::Value refOut = MAUSGeant4Manager::GetInstance()->RunParticle(getRefPart());
63
setRefDataOut(refOut);
64
getCurrentStream() << "Running all particles" << std::endl;
65
Json::Value out = MAUSGeant4Manager::GetInstance()->RunManyParticles(getParticles());
68
getCurrentStream() << "All particles have been run" << std::endl;
78
void BASEparticle::runParticles(double zOut) {
80
getCurrentStream() << "Running reference particle" << std::endl;
81
trackedReference = new double[8];
82
for (int i = 0; i < 8; i++)
83
trackedReference[i] = inReference[i];
84
BTTracker::integrate(zOut,trackedReference,getLattice()->getFieldGroup(),BTTracker::z, stepSize, 1.0);
85
getCurrentStream() << "Running all particles" << std::endl;
86
trackedParticles = new double[8*numberOfParticles];
87
for (int i = 0; i < 8*numberOfParticles; i++)
88
trackedParticles[i] = inParticles[i];
89
for (int i = 0; i < numberOfParticles; i++)
90
BTTracker::integrate(zOut,trackedParticles + (i*8),getLattice()->getFieldGroup(),BTTracker::z, stepSize, 1.0);
93
for (int i = 0; i < numberOfParticles; i++) {
94
getCurrentStream() << "Particle in:\n\t";
95
for (int j = 0; j < 8; j++)
96
getCurrentStream() << inParticles[(i*8) + j] << ", ";
97
getCurrentStream() << std::endl << "Particle out:\n\t";
98
for (int j = 0; j < 8; j++)
99
getCurrentStream() << trackedParticles[(i*8) + j] << ", ";
100
getCurrentStream() << std::endl << std::endl;
103
getCurrentStream() << "All particles have been run" << std::endl;
106
getCurrentStream() << "Running reference particle" << std::endl;
107
Json::Value refOut = MAUSGeant4Manager::GetInstance()->RunParticle(getRefPart());
108
setRefDataOut(refOut);
109
getCurrentStream() << "Running all particles" << std::endl;
110
Json::Value out = MAUSGeant4Manager::GetInstance()->RunManyParticles(getParticles());
113
getCurrentStream() << "All particles have been run" << std::endl;
71
117
PolynomialMap BASEparticle::buildMap(double zIn, double zOut, bool thirdOrder) {
74
120
return PolynomialMap(std::vector<PolynomialMap::PolynomialCoefficient>());
77
getCurrentStream() << "Generating particle in/out data";
79
getCurrentStream() << "..." << std::endl;
80
Json::Value refOut = getRefDataOut();
81
double refMom = refOut["primary"]["momentum"]["z"].asDouble();
82
Json::Value out = getDataOut();
83
for(int j = 0; j < out.size(); j++) {
84
loadBar(j,out.size(),50,getCurrentStream());
85
Json::Value vhit = out[j]["virtual_hits"];
86
std::pair<std::vector<double>, std::vector<double> > coords = getVirtualCoordsFromHit(vhit,refMom,zIn,zOut,thirdOrder);
87
partCoordsIn.push_back(coords.first);
88
partCoordsOut.push_back(coords.second);
91
getCurrentStream() << "\n...Generated map" << std::endl;
123
std::vector< std::vector<double> > partCoordsIn;
124
std::vector< std::vector<double> > partCoordsOut;
127
double refMom = trackedReference[7];
128
for(int j = 0; j < getNumberOfParticles(); j++) {
129
loadBar(j,getNumberOfParticles(),50,getCurrentStream());
130
std::pair<std::vector<double>, std::vector<double> > coords = getVirtualCoordsFromTracked(inParticles + (j*8), trackedParticles + (j*8),refMom,thirdOrder);
131
partCoordsIn.push_back(coords.first);
132
partCoordsOut.push_back(coords.second);
135
getCurrentStream() << "\n...Generated map" << std::endl;
138
getCurrentStream() << "Generating particle in/out data";
139
static int count = 0;
140
getCurrentStream() << "..." << std::endl;
141
Json::Value refOut = getRefDataOut();
142
double refMom = refOut["primary"]["momentum"]["z"].asDouble();
143
Json::Value out = getDataOut();
144
for(int j = 0; j < out.size(); j++) {
145
loadBar(j,out.size(),50,getCurrentStream());
146
Json::Value vhit = out[j]["virtual_hits"];
147
std::pair<std::vector<double>, std::vector<double> > coords = getVirtualCoordsFromHit(vhit,refMom,zIn,zOut,thirdOrder);
148
partCoordsIn.push_back(coords.first);
149
partCoordsOut.push_back(coords.second);
152
getCurrentStream() << "\n...Generated map" << std::endl;
93
154
if(thirdOrder) return *PolynomialMap::ConstrainedPolynomialLeastSquaresFit(partCoordsIn, partCoordsOut, 3,get2ndOrderBlanks());
94
155
return *PolynomialMap::PolynomialLeastSquaresFit(partCoordsIn, partCoordsOut, 1);
161
void BASEparticle::generateParticles() {
222
void BASEparticle::generateParticles(double zIn) {
162
223
getCurrentStream() << "Generating " << numberOfParticles << " particles..." << std::endl;
163
generateReferenceParticle();
164
Json::Value retval(Json::arrayValue);
165
for(int i = 0; i < numberOfParticles; i++) {
166
Json::Value val = getRefPart().WriteJson();
167
std::vector<double> offsets = generateRandomOffsets();
168
double x = val["position"]["x"].asDouble() + offsets[0]*sigma;
169
double y = val["position"]["y"].asDouble() + offsets[1]*sigma;
170
double z = val["position"]["z"].asDouble();
171
double px = val["momentum"]["x"].asDouble() + offsets[2]*val["momentum"]["z"].asDouble();
172
double py = val["momentum"]["y"].asDouble() + offsets[3]*val["momentum"]["z"].asDouble();
173
double pz = std::sqrt(val["momentum"]["z"].asDouble()*val["momentum"]["z"].asDouble() - px*px - py*py);
174
val["position"]["x"] = x;
175
val["position"]["y"] = y;
176
//val["position"]["z"] = z;
177
val["momentum"]["x"] = px;
178
val["momentum"]["y"] = py;
179
//val["momentum"]["z"] = pz;
180
Json::Value primary(Json::objectValue);
181
primary["primary"] = val;
184
setParticles(retval);
185
getCurrentStream() << "Reference particle: " << std::endl << JsonWrapper::JsonToString(getRefPart().WriteJson()) << std::endl;
224
generateReferenceParticle(zIn);
226
Json::Value retval(Json::arrayValue);
227
for(int i = 0; i < numberOfParticles; i++) {
228
Json::Value val = getRefPart().WriteJson();
229
std::vector<double> offsets = generateRandomOffsets();
230
double x = val["position"]["x"].asDouble() + offsets[0]*sigma;
231
double y = val["position"]["y"].asDouble() + offsets[1]*sigma;
232
double px = val["momentum"]["x"].asDouble() + offsets[2]*val["momentum"]["z"].asDouble();
233
double py = val["momentum"]["y"].asDouble() + offsets[3]*val["momentum"]["z"].asDouble();
234
double pz = std::sqrt(val["energy"].asDouble()*val["energy"].asDouble() - px*px - py*py);
235
val["position"]["x"] = x;
236
val["position"]["y"] = y;
237
val["position"]["z"] = zIn;
238
val["momentum"]["x"] = px;
239
val["momentum"]["y"] = py;
240
val["momentum"]["z"] = pz;
241
Json::Value primary(Json::objectValue);
242
primary["primary"] = val;
245
setParticles(retval);
246
_numberOfParticles = numberOfParticles;
247
getCurrentStream() << "Reference particle: " << std::endl << JsonWrapper::JsonToString(getRefPart().WriteJson()) << std::endl;
250
double* parts = new double[8*numberOfParticles];
251
for(int i = 0; i < numberOfParticles; i++) {
252
std::vector<double> offsets = generateRandomOffsets();
253
double x = inReference[1] + offsets[0]*sigma;
254
double y = inReference[2] + offsets[1]*sigma;
255
double px = inReference[5] + offsets[2]*inReference[7];
256
double py = inReference[6] + offsets[3]*inReference[7];
257
double pz = std::sqrt(refEnergy*refEnergy - px*px - py*py);
261
parts[i*8 + 3] = zIn;
262
parts[i*8 + 4] = refEnergy;
267
_numberOfParticles = numberOfParticles;
188
Matrix<double> BASEparticle::getPolynomialMatrix() {
190
getCurrentStream() << "Cannot access polynomial matrix - not initialised" << std::endl;
273
Matrix<double> BASEparticle::getPolynomialMatrix() const {
274
if(!matrixGen || polynomialMatrix == NULL) {
275
getCurrentStream() << "Cannot access polynomial matrix - not initialised using setPolynomialMatrix() method" << std::endl;
191
276
Matrix<double> blank;
194
279
return *polynomialMatrix;
197
void BASEparticle::generateReferenceParticle() {
198
setRefPart((MAUSGeant4Manager::GetInstance())->GetReferenceParticle());
282
void BASEparticle::generateReferenceParticle(double zIn) {
284
double* ret = new double[8];
285
ret[0] = 0.0; ret[1] = 0.0; ret[2] = 0.0; ret[5] = 0.0; ret[6] = 0.0;
288
ret[7] = refMomentum;
291
else setRefPart((MAUSGeant4Manager::GetInstance())->GetReferenceParticle());
201
294
double* BASEparticle::generateRandomCoordinates() {
300
void BASEparticle::advanceCell(double* coordsIn, double* coordsOut, double zIn, double zOut) {
301
for (int i = 0; i < 4; i++)
303
if (!usingLattice) return;
304
double* properCoords = new double[8];
305
properCoords[0] = 0.;
306
properCoords[1] = coordsIn[0]*sigma;
307
properCoords[2] = coordsIn[1]*sigma;
308
std::vector<double> A1 = integrator->getVectorPotentialAnalytic(properCoords[0],properCoords[1],zIn);
309
properCoords[3] = zIn;
310
properCoords[4] = refEnergy;
311
properCoords[5] = coordsIn[2]*refMomentum - A1[0]*lightSpeed/1.0e-6;
312
properCoords[6] = coordsIn[3]*refMomentum - A1[1]*lightSpeed/1.0e-6;
313
properCoords[7] = std::sqrt(refEnergy*refEnergy - properCoords[5]*properCoords[5] - properCoords[6]*properCoords[6]);
314
BTTracker::integrate(zOut,properCoords,getLattice()->getFieldGroup(),BTTracker::z, stepSize, 1.0);
315
std::vector<double> A2 = integrator->getVectorPotentialAnalytic(properCoords[0],properCoords[1],zOut);
316
coordsOut[0] = properCoords[1]/sigma;
317
coordsOut[1] = properCoords[2]/sigma;
318
coordsOut[2] = (properCoords[5] + A2[0]*lightSpeed/1.0e-6)/sigma;
319
coordsOut[3] = (properCoords[6] + A2[0]*lightSpeed/1.0e-6)/sigma;
320
delete[] properCoords;
207
323
/*void BASEparticle::TESTThirdOrderTrack() {
208
324
TestResult* test = new TestResult("Third Order Tracking Comparison");
209
325
for (int i = 0; i < 5; i++) {
441
std::pair<std::vector<double>, std::vector<double> > BASEparticle::getVirtualCoordsFromTracked(double* particlesIn, double* particlesOut, double refMom, bool thirdOrder) {
442
//initial kinetic variables
443
double x1 = particlesIn[1];
444
double y1 = particlesIn[2];
445
double px1 = particlesIn[5];
446
double py1 = particlesIn[6];
447
double z1 = particlesIn[3];
449
//final kinetic variables
450
double x2 = particlesOut[1];
451
double y2 = particlesOut[2];
452
double px2 = particlesOut[5];
453
double py2 = particlesOut[6];
454
double z2 = particlesOut[3];
456
//conversion to canonical momenta
457
std::vector<double> A1 = integrator->getVectorPotentialAnalytic(x1,y1,z1);
458
std::vector<double> A2 = integrator->getVectorPotentialAnalytic(x2,y2,z2);
460
//from T m * {fundamental charge unit} -> MeV/c is lightSpeed (m s^-1) / 1,000,000
461
px1 += A1[0] * lightSpeed / 1.0e6;
462
py1 += A1[1] * lightSpeed / 1.0e6;
463
px2 += A2[0] * lightSpeed / 1.0e6;
464
py2 += A2[1] * lightSpeed / 1.0e6;
466
//rescaling to dimensionless MARYLIE variables
476
/*getCurrentStream() << "Particle IN: z = " << step1["position"]["z"] << std::endl;
477
getCurrentStream() << "x = " << x1 << " y = " << y1 << " px = " << px1 << " py = " << py1 << std::endl;
478
getCurrentStream() << "Particle OUT: z = " << step2["position"]["z"] << std::endl;
479
getCurrentStream() << "x = " << x2 << " y = " << y2 << " px = " << px2 << " py = " << py2 << "\n" << std::endl;*/
481
std::vector<double> phaseCoordIn(4);
482
std::vector<double> phaseCoordOut(4);
484
phaseCoordIn[0] = x1;
485
phaseCoordIn[1] = y1;
486
phaseCoordIn[2] = px1;
487
phaseCoordIn[3] = py1;
489
phaseCoordOut[0] = x2;
490
phaseCoordOut[1] = y2;
491
phaseCoordOut[2] = px2;
492
phaseCoordOut[3] = py2;
494
std::pair<std::vector<double>, std::vector<double> > retval(phaseCoordIn, phaseCoordOut);
326
500
void BASEparticle::TESTConfig(Json::Value config) {
327
501
TestResult* test = new TestResult("Json Config");
337
double BASEparticle::float_tolerance() {
341
const char* BASEparticle::getIdentifier() {
342
return "First Order Polynomial Matrix";
511
void saveEllipseDataToFile(TransferMatrixGenerator* map, double zIn, double zOut, std::vector<double> initialScales, const char* filename) {
512
std::ostringstream sstream;
513
sstream << lattice_locale << "/" << filename << "/ellipse_data_" << filename << ".txt";
514
std::ofstream stream(sstream.str().c_str(), std::ofstream::out | std::ofstream::trunc);
515
if (!stream.is_open()) {
516
throw InvalidFileException("LieMap::saveStabilityDataToFile",filename);
518
static const int timesRoundEllipse = 70;
521
for (int i = 0; i < initialScales.size(); i++) {
522
loadBar(i,initialScales.size(),75,getCurrentStream());
523
double* coords = new double[4];
524
coords[0] = initialScales[i];
526
coords[2] = initialScales[i];
528
double* coordsOut = new double[4];
529
for (int j = 0; j <= timesRoundEllipse; j++) {
530
map->advanceCell(coords, coordsOut,zIn,zOut);
532
if (coordsOut[0] > 1. || coordsOut[2] > 1.) break;
533
stream << coordsOut[0]*sigma << "\t" << coordsOut[2]*refMomentum << "\n";
537
coordsOut = new double[4];
545
std::cerr << "Stability data saved in file " << filename << std::endl;