17 #include "cetlib_except/exception.h"
26 fEnableSimSpatialSCE = pset.get<
bool>(
"EnableSimSpatialSCE");
27 fEnableSimEfieldSCE = pset.get<
bool>(
"EnableSimEfieldSCE");
29 fEnableCalSpatialSCE = pset.get<
bool>(
"EnableCalSpatialSCE");
30 fEnableCalEfieldSCE = pset.get<
bool>(
"EnableCalEfieldSCE");
32 if((fEnableSimSpatialSCE ==
true) || (fEnableSimEfieldSCE ==
true))
34 fRepresentationType = pset.get<std::string>(
"RepresentationType");
35 fInputFilename = pset.get<std::string>(
"InputFilename");
38 cet::search_path sp(
"FW_SEARCH_PATH");
39 sp.find_file(fInputFilename, fname);
41 std::unique_ptr<TFile> infile(
new TFile(fname.c_str(),
"READ"));
44 throw cet::exception(
"SpaceChargeSBND") <<
"Could not find the space charge effect file '" << fname <<
"'!\n";
47 if(fRepresentationType ==
"Voxelized_TH3"){
48 std::cout <<
"begin loading voxelized TH3s..." << std::endl;
51 TH3F* hTrueFwdX = (TH3F*) infile->Get(
"TrueFwd_Displacement_X");
52 TH3F* hTrueFwdY = (TH3F*) infile->Get(
"TrueFwd_Displacement_Y");
53 TH3F* hTrueFwdZ = (TH3F*) infile->Get(
"TrueFwd_Displacement_Z");
54 TH3F* hTrueBkwdX = (TH3F*) infile->Get(
"TrueBkwd_Displacement_X");
55 TH3F* hTrueBkwdY = (TH3F*) infile->Get(
"TrueBkwd_Displacement_Y");
56 TH3F* hTrueBkwdZ = (TH3F*) infile->Get(
"TrueBkwd_Displacement_Z");
57 TH3F* hTrueEFieldX = (TH3F*) infile->Get(
"True_ElecField_X");
58 TH3F* hTrueEFieldY = (TH3F*) infile->Get(
"True_ElecField_Y");
59 TH3F* hTrueEFieldZ = (TH3F*) infile->Get(
"True_ElecField_Z");
65 hTrueFwdX->SetDirectory(0);
66 hTrueFwdY->SetDirectory(0);
67 hTrueFwdZ->SetDirectory(0);
68 hTrueBkwdX->SetDirectory(0);
69 hTrueBkwdY->SetDirectory(0);
70 hTrueBkwdZ->SetDirectory(0);
71 hTrueEFieldX->SetDirectory(0);
72 hTrueEFieldY->SetDirectory(0);
73 hTrueEFieldZ->SetDirectory(0);
76 SCEhistograms = {hTrueFwdX, hTrueFwdY, hTrueFwdZ,
77 hTrueBkwdX, hTrueBkwdY, hTrueBkwdZ,
78 hTrueEFieldX, hTrueEFieldY, hTrueEFieldZ};
81 std::cout <<
"...finished loading TH3s" << std::endl;
82 }
else if(fRepresentationType ==
"Parametric")
84 for(
int i = 0; i < initialSpatialFitPolN[0] + 1; i++)
86 for(
int j = 0; j < intermediateSpatialFitPolN[0] + 1; j++)
88 gSpatialGraphX[i][j] = (TGraph*)infile->Get(Form(
"deltaX/g%i_%i", i, j));
91 intermediateSpatialFitFunctionX[i] =
new TF1(Form(
"intermediateSpatialFitFunctionX_%i", i), Form(
"pol%i", intermediateSpatialFitPolN[0]));
93 for(
int i = 0; i < initialSpatialFitPolN[1] + 1; i++)
95 for(
int j = 0; j < intermediateSpatialFitPolN[1] + 1; j++)
97 gSpatialGraphY[i][j] = (TGraph*)infile->Get(Form(
"deltaY/g%i_%i", i, j));
100 intermediateSpatialFitFunctionY[i] =
new TF1(Form(
"intermediateSpatialFitFunctionY_%i", i), Form(
"pol%i", intermediateSpatialFitPolN[1]));
102 for(
int i = 0; i < initialSpatialFitPolN[2] + 1; i++)
104 for(
int j = 0; j < intermediateSpatialFitPolN[2] + 1; j++)
106 gSpatialGraphZ[i][j] = (TGraph*)infile->Get(Form(
"deltaZ/g%i_%i", i, j));
109 intermediateSpatialFitFunctionZ[i] =
new TF1(Form(
"intermediateSpatialFitFunctionZ_%i", i), Form(
"pol%i", intermediateSpatialFitPolN[2]));
112 initialSpatialFitFunctionX =
new TF1(
"initialSpatialFitFunctionX", Form(
"pol%i", initialSpatialFitPolN[0]));
113 initialSpatialFitFunctionY =
new TF1(
"initialSpatialFitFunctionY", Form(
"pol%i", initialSpatialFitPolN[1]));
114 initialSpatialFitFunctionZ =
new TF1(
"initialSpatialFitFunctionZ", Form(
"pol%i", initialSpatialFitPolN[2]));
116 for(
int i = 0; i < initialEFieldFitPolN[0] + 1; i++)
118 for(
int j = 0; j < intermediateEFieldFitPolN[0] + 1; j++)
120 gEFieldGraphX[i][j] = (TGraph*)infile->Get(Form(
"deltaEx/g%i_%i", i, j));
123 intermediateEFieldFitFunctionX[i] =
new TF1(Form(
"intermediateEFieldFitFunctionX_%i", i), Form(
"pol%i", intermediateEFieldFitPolN[0]));
125 for(
int i = 0; i < initialEFieldFitPolN[1] + 1; i++)
127 for(
int j = 0; j < intermediateEFieldFitPolN[1] + 1; j++)
129 gEFieldGraphY[i][j] = (TGraph*)infile->Get(Form(
"deltaEy/g%i_%i", i, j));
132 intermediateEFieldFitFunctionY[i] =
new TF1(Form(
"intermediateEFieldFitFunctionY_%i", i), Form(
"pol%i", intermediateEFieldFitPolN[1]));
134 for(
int i = 0; i < initialEFieldFitPolN[2] + 1; i++)
136 for(
int j = 0; j < intermediateEFieldFitPolN[2] + 1; j++)
138 gEFieldGraphZ[i][j] = (TGraph*)infile->Get(Form(
"deltaEz/g%i_%i", i, j));
141 intermediateEFieldFitFunctionZ[i] =
new TF1(Form(
"intermediateEFieldFitFunctionZ_%i", i), Form(
"pol%i", intermediateEFieldFitPolN[2]));
144 initialEFieldFitFunctionX =
new TF1(
"initialEFieldFitFunctionX", Form(
"pol%i", initialEFieldFitPolN[0]));
145 initialEFieldFitFunctionY =
new TF1(
"initialEFieldFitFunctionY", Form(
"pol%i", initialEFieldFitPolN[1]));
146 initialEFieldFitFunctionZ =
new TF1(
"initialEFieldFitFunctionZ", Form(
"pol%i", initialEFieldFitPolN[2]));
148 std::cout <<
"fRepresentationType not known!!!" << std::endl;
153 if(fEnableCorrSCE ==
true)
173 return fEnableSimSpatialSCE;
179 return fEnableSimEfieldSCE;
191 return fEnableCalSpatialSCE;
197 return fEnableCalEfieldSCE;
203 std::vector<double> thePosOffsets;
204 double xx=point.X(), yy=point.Y(), zz=point.Z();
206 if(fRepresentationType ==
"Voxelized_TH3"){
208 if(xx<-199.999){xx=-199.999;}
209 else if(xx>199.999){xx=199.999;}
210 if(yy<-199.999){yy=-199.999;}
211 else if(yy>199.999){yy=199.999;}
212 if(zz<0.001){zz=0.001;}
213 else if(zz>499.999){zz=499.999;}
216 if (xx < 0) { corr = -1; }
217 double offset_x=0., offset_y=0., offset_z=0.;
218 offset_x = corr*SCEhistograms.at(0)->Interpolate(xx,yy,zz);
219 offset_y = SCEhistograms.at(1)->Interpolate(xx,yy,zz);
220 offset_z = SCEhistograms.at(2)->Interpolate(xx,yy,zz);
221 thePosOffsets = {offset_x, offset_y, offset_z};
223 }
else if(fRepresentationType ==
"Parametric"){
224 if(IsInsideBoundaries(point.X(), point.Y(), point.Z()) ==
false){
225 thePosOffsets.resize(3, 0.0);
228 thePosOffsets = GetPosOffsetsParametric(xx, yy, zz);
229 for(
int i=0; i<3; i++){thePosOffsets[i]=100.*thePosOffsets[i];}
233 thePosOffsets.resize(3, 0.0);
236 return { thePosOffsets[0], thePosOffsets[1], thePosOffsets[2] };
242 std::vector<double> theCalPosOffsets;
243 double xx=point.X(), yy=point.Y(), zz=point.Z();
245 if(fRepresentationType ==
"Voxelized_TH3"){
247 if(xx<-199.999){xx=-199.999;}
248 else if(xx>199.999){xx=199.999;}
249 if(yy<-199.999){yy=-199.999;}
250 else if(yy>199.999){yy=199.999;}
251 if(zz<0.001){zz=0.001;}
252 else if(zz>499.999){zz=499.999;}
254 if ((TPCid == 0)
and (xx > -2.5)) { xx = -2.5; }
255 if ((TPCid == 1)
and (xx < 2.5)) { xx = 2.5; }
256 double offset_x=0., offset_y=0., offset_z=0.;
257 offset_x = SCEhistograms.at(3)->Interpolate(xx,yy,zz);
258 offset_y = SCEhistograms.at(4)->Interpolate(xx,yy,zz);
259 offset_z = SCEhistograms.at(5)->Interpolate(xx,yy,zz);
260 theCalPosOffsets = {offset_x, offset_y, offset_z};
262 }
else if(fRepresentationType ==
"Parametric"){
264 std::cout <<
"Change Representation Type to Voxelized TH3 if you want to use the backward offset function" << std::endl;
265 theCalPosOffsets.resize(3, 0.0);
268 return { theCalPosOffsets[0], theCalPosOffsets[1], theCalPosOffsets[2] };
276 std::vector<double> thePosOffsetsParametric;
278 double xValNew = TransformX(xVal);
279 double yValNew = TransformY(yVal);
280 double zValNew = TransformZ(zVal);
282 thePosOffsetsParametric.push_back(GetOnePosOffsetParametric(xValNew, yValNew, zValNew,
"X"));
283 thePosOffsetsParametric.push_back(GetOnePosOffsetParametric(xValNew, yValNew, zValNew,
"Y"));
284 thePosOffsetsParametric.push_back(GetOnePosOffsetParametric(xValNew, yValNew, zValNew,
"Z"));
286 return thePosOffsetsParametric;
295 for(
int i = 0; i < 99; i++)
297 for(
int j = 0; j < 99; j++)
305 for(
int i = 0; i < initialSpatialFitPolN[0] + 1; i++)
307 for(
int j = 0; j < intermediateSpatialFitPolN[0] + 1; j++)
309 parA[i][j] = gSpatialGraphX[i][j]->Eval(zValNew);
311 intermediateSpatialFitFunctionX[i]->SetParameters(parA[i]);
316 for(
int i = 0; i < initialSpatialFitPolN[1] + 1; i++)
318 for(
int j = 0; j < intermediateSpatialFitPolN[1] + 1; j++)
320 parA[i][j] = gSpatialGraphY[i][j]->Eval(zValNew);
322 intermediateSpatialFitFunctionY[i]->SetParameters(parA[i]);
327 for(
int i = 0; i < initialSpatialFitPolN[2] + 1; i++)
329 for(
int j = 0; j < intermediateSpatialFitPolN[2] + 1; j++)
331 parA[i][j] = gSpatialGraphZ[i][j]->Eval(zValNew);
333 intermediateSpatialFitFunctionZ[i]->SetParameters(parA[i]);
350 double offsetValNew = 0.0;
353 for(
int i = 0; i < initialSpatialFitPolN[0] + 1; i++)
355 parB[i] = intermediateSpatialFitFunctionX[i]->Eval(aValNew);
357 initialSpatialFitFunctionX->SetParameters(parB);
358 offsetValNew = initialSpatialFitFunctionX->Eval(bValNew);
362 for(
int i = 0; i < initialSpatialFitPolN[1] + 1; i++)
364 parB[i] = intermediateSpatialFitFunctionY[i]->Eval(aValNew);
366 initialSpatialFitFunctionY->SetParameters(parB);
367 offsetValNew = initialSpatialFitFunctionY->Eval(bValNew);
371 for(
int i = 0; i < initialSpatialFitPolN[2] + 1; i++)
373 parB[i] = intermediateSpatialFitFunctionZ[i]->Eval(aValNew);
375 initialSpatialFitFunctionZ->SetParameters(parB);
376 offsetValNew = initialSpatialFitFunctionZ->Eval(bValNew);
385 std::vector<double> theEfieldOffsets;
386 double xx=point.X(), yy=point.Y(), zz=point.Z();
387 double offset_x=0., offset_y=0., offset_z=0.;
389 if(fRepresentationType ==
"Voxelized_TH3"){
391 if(xx<-199.999){xx=-199.999;}
392 else if(xx>199.999){xx=199.999;}
393 if(yy<-199.999){yy=-199.999;}
394 else if(yy>199.999){yy=199.999;}
395 if(zz<0.001){zz=0.001;}
396 else if(zz>499.999){zz=499.999;}
397 offset_x = SCEhistograms.at(6)->Interpolate(xx, yy, zz);
398 offset_y = SCEhistograms.at(7)->Interpolate(xx, yy, zz);
399 offset_z = SCEhistograms.at(8)->Interpolate(xx, yy, zz);
401 theEfieldOffsets = {offset_x, offset_y, offset_z};
403 }
else if(fRepresentationType ==
"Parametric"){
405 if(IsInsideBoundaries(point.X(), point.Y(), point.Z()) ==
false){
406 theEfieldOffsets.resize(3, 0.0);
410 theEfieldOffsets = GetEfieldOffsetsParametric(point.X(), point.Y(), point.Z());
414 theEfieldOffsets[0] = -1.0 * theEfieldOffsets[0] / (100.0 * DriftField);
415 theEfieldOffsets[1] = -1.0 * theEfieldOffsets[1] / (100.0 * DriftField);
416 theEfieldOffsets[2] = -1.0 * theEfieldOffsets[2] / (100.0 * DriftField);
420 return { theEfieldOffsets[0], theEfieldOffsets[1], theEfieldOffsets[2] };
426 std::vector<double> theEfieldOffsetsParametric;
428 double xValNew = TransformX(xVal);
429 double yValNew = TransformY(yVal);
430 double zValNew = TransformZ(zVal);
432 theEfieldOffsetsParametric.push_back(GetOneEfieldOffsetParametric(xValNew, yValNew, zValNew,
"X"));
433 theEfieldOffsetsParametric.push_back(GetOneEfieldOffsetParametric(xValNew, yValNew, zValNew,
"Y"));
434 theEfieldOffsetsParametric.push_back(GetOneEfieldOffsetParametric(xValNew, yValNew, zValNew,
"Z"));
436 return theEfieldOffsetsParametric;
445 for(
int i = 0; i < 99; i++)
447 for(
int j = 0; j < 99; j++)
455 for(
int i = 0; i < initialEFieldFitPolN[0] + 1; i++)
457 for(
int j = 0; j < intermediateEFieldFitPolN[0] + 1; j++)
459 parA[i][j] = gEFieldGraphX[i][j]->Eval(zValNew);
461 intermediateEFieldFitFunctionX[i]->SetParameters(parA[i]);
466 for(
int i = 0; i < initialEFieldFitPolN[1] + 1; i++)
468 for(
int j = 0; j < intermediateEFieldFitPolN[1] + 1; j++)
470 parA[i][j] = gEFieldGraphY[i][j]->Eval(zValNew);
472 intermediateEFieldFitFunctionY[i]->SetParameters(parA[i]);
477 for(
int i = 0; i < initialEFieldFitPolN[2] + 1; i++)
479 for(
int j = 0; j < intermediateEFieldFitPolN[2] + 1; j++)
481 parA[i][j] = gEFieldGraphZ[i][j]->Eval(zValNew);
483 intermediateEFieldFitFunctionZ[i]->SetParameters(parA[i]);
501 double offsetValNew = 0.0;
504 for(
int i = 0; i < initialEFieldFitPolN[0] + 1; i++)
506 parB[i] = intermediateEFieldFitFunctionX[i]->Eval(aValNew);
508 initialEFieldFitFunctionX->SetParameters(parB);
509 offsetValNew = initialEFieldFitFunctionX->Eval(bValNew);
513 for(
int i = 0; i < initialEFieldFitPolN[1] + 1; i++)
515 parB[i] = intermediateEFieldFitFunctionY[i]->Eval(aValNew);
517 initialEFieldFitFunctionY->SetParameters(parB);
518 offsetValNew = initialEFieldFitFunctionY->Eval(bValNew);
522 for(
int i = 0; i < initialEFieldFitPolN[2] + 1; i++)
524 parB[i] = intermediateEFieldFitFunctionZ[i]->Eval(aValNew);
526 initialEFieldFitFunctionZ->SetParameters(parB);
527 offsetValNew = initialEFieldFitFunctionZ->Eval(bValNew);
541 double xValNew = (2.0 / 1.965) * fabs(xVal);
559 return (zVal / 100.0);
567 bool isInside =
true;
569 if((xVal < -196.5) || (xVal > 196.5) || (yVal < -200.0) || (yVal > 200.0) || (zVal < 0) || (zVal > 500.0))
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
std::vector< double > GetPosOffsetsParametric(double xVal, double yVal, double zVal) const
bool IsInsideBoundaries(double xVal, double yVal, double zVal) const
geo::Vector_t GetEfieldOffsets(geo::Point_t const &point) const override
bool Configure(fhicl::ParameterSet const &pset)
double TransformZ(double zVal) const
bool EnableSimEfieldSCE() const override
bool EnableSimSpatialSCE() const override
SpaceChargeSBND(fhicl::ParameterSet const &pset)
std::vector< double > GetEfieldOffsetsParametric(double xVal, double yVal, double zVal) const
double TransformY(double yVal) const
double GetOneEfieldOffsetParametric(double xVal, double yVal, double zVal, std::string axis) const
double TransformX(double xVal) const
bool EnableCalEfieldSCE() const override
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
geo::Vector_t GetPosOffsets(geo::Point_t const &point) const override
geo::Vector_t GetCalPosOffsets(geo::Point_t const &point, int const &TPCid=1) const override
bool EnableCalSpatialSCE() const override
bool Update(uint64_t ts=0)
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
BEGIN_PROLOG could also be cout
double GetOnePosOffsetParametric(double xVal, double yVal, double zVal, std::string axis) const