LBNFDeDxMap.cc
Go to the documentation of this file.
1 #include <sstream>
2 #include "LBNFDeDxMap.hh"
4 
6 fName(aName),
7 fPhiKeyFact(10.0), // minimum step size ih = 2*PI/10.;
8 fZKeyFact(1.0), // minimum step size in Z = 1 mm
9 fRKeyFact(10.0), // minimum step size in R = 100 microns
10 fPhiKeyMult(100000), // maximum number of Z step corresponds ~ 100 m., cell size 1 mm
11 fNumPhiSlices(6)
12 {
13 
14  if (aName == std::string("HornAConceptDesignJan2017")) {
16  }
17  if (aName == std::string("HornBConceptDesignJan2017")) {
19  }
20 }
21 // based on the geometry defined in
22 // LBNEVolumePlacements::PlaceFinalLBNFConceptHornA
23 // and
25 
26  const double phiWidth = 2.0*M_PI/fNumPhiSlices;
27  //
28  // The IO transition section, upstream. First
29  //
30  LBNFDeDxCell aCellT;
31  aCellT.G4Name = std::string("LBNFConceptHornAUpstrIOSect");
32  aCellT.MARSName = std::string("hAuA_");
33  aCellT.rWidth = 16.666666;
34  aCellT.rCenter = 43. + 0.5*aCellT.rWidth; // defining boundaries..
35  aCellT.zWidth = 250.; // oversized, for this volume, limits are in r,phi.
36  // encompass the 6+ 3 cells for this region.
37  aCellT.zCenter = -125.; // crude, but O.K.
38  aCellT.phiWidth = phiWidth;
39  aCellT.keyedByZ = false;
40  aCellT.eDep = 0.; aCellT.eDepSq = 0.; aCellT.nEntries = 0;
41 
42  for (size_t kr=0; kr != 9; kr++) {
43  if (kr == 3) aCellT.MARSName = std::string("hAuB_");
44  LBNFDeDxCell aCellR(aCellT);
45  aCellR.rCenter = aCellT.rCenter + kr*aCellT.rWidth;
46  std::ostringstream mNameStrStr; mNameStrStr << kr;
47  aCellR.MARSName += std::string(mNameStrStr.str());
48  for (size_t kPhi=0; kPhi != fNumPhiSlices; kPhi++) {
49  LBNFDeDxCell aCell(aCellR);
50  aCell.phiCenter = 0.5*aCellR.phiWidth + kPhi*aCellR.phiWidth;
51  unsigned int tag = this->getTagFromR(aCell.rCenter, aCellT.rCenter + 0.00001*aCellT.rWidth,
52  aCellT.rWidth, aCell.phiCenter);
53 // std::cerr << " LBNFDeDxMap::defineInnerCHornA, tag " << tag
54 // << " " << aCell.MARSName << " r " << aCell.rCenter << std::endl;
55  fMap.emplace(tag, aCell);
56  }
57  }
58  rStarts.push_back(aCellT.rCenter); // Only approximate, two step sizes are used above...
59  rWidths.push_back(aCellT.rWidth);
60  G4NamesInMapRTag.push_back(aCellT.G4Name);
61  //
62  // The Inner Conductor.. Note: this scheme prevents us to look at the outer conductor..
63  // Which is O.K., I was asked to look at the heating of the inner conductor only...
64  // Actually, we could use special cases, like for the water layer..
65  //
66  aCellT.G4Name = std::string("LBNFConceptHornAICCyl");
67  aCellT.MARSName = std::string("hAtz_");
68  aCellT.rWidth = 1.001; // oversize by 1 microns..
69  aCellT.rCenter = 44.; // non-defining boundaries..
70  aCellT.zWidth = 19.833861; // exact...
71  aCellT.zCenter = 0.024 + 0.5*aCellT.zWidth;
72  aCellT.phiWidth = phiWidth;
73  aCellT.keyedByZ = true;
74  aCellT.eDep = 0.;
75  for (size_t kz=0; kz != 59; kz++) {
76  LBNFDeDxCell aCellZ(aCellT);
77  aCellZ.zCenter = aCellT.zCenter + kz*aCellT.zWidth;
78  std::ostringstream mNameStrStr; mNameStrStr << kz;
79  aCellZ.MARSName = std::string("hAtz_");
80  aCellZ.MARSName += std::string(mNameStrStr.str());
81  for (size_t kPhi=0; kPhi != fNumPhiSlices; kPhi++) {
82  LBNFDeDxCell aCell(aCellZ);
83  aCell.phiCenter = 0.5*aCellZ.phiWidth + kPhi*aCellZ.phiWidth;
84  unsigned int tag = this->getTagFromZ(aCell.zCenter, aCellT.zCenter + 0.00001*aCellT.zWidth,
85  aCellT.zWidth, aCell.phiCenter);
86 // std::cerr << " LBNFDeDxMap::defineInnerCHornA, tag " << tag << " "
87 // << aCell.MARSName << " z " << aCell.zCenter << std::endl;
88  fMap.emplace(tag, aCell);
89  // Add the Water layer (for extra-credits !);
90  LBNFDeDxCell aCellW(aCell);
91  aCellW.G4Name = std::string("LBNFConceptHornAICCylWater");
92  aCellW.rCenter = 45.5;
93  aCellW.rWidth = 0.5;
94  tag += 1000000;
95  fMap.emplace(tag, aCellW);
96  }
97  }
98  zStarts.push_back(aCellT.zCenter);
99  zWidths.push_back(aCellT.zWidth);
100  G4NamesInMapZTag.push_back(std::string("LBNFConceptHornAICCyl"));
101  zStarts.push_back(aCellT.zCenter);
102  zWidths.push_back(aCellT.zWidth);
103  G4NamesInMapZTag.push_back(std::string("LBNFConceptHornAICCylWater"));
104  //
105  // The tapered section..
106  //
107  aCellT.G4Name = std::string("LBNFConceptHornAICTaper");
108  aCellT.MARSName = std::string("hAtz_");
109  aCellT.rWidth = 1.2; // largely oversized.. don't matter
110  aCellT.rCenter = 44.; // non-defining boundaries..
111  aCellT.zWidth = 19.64469; // exact
112  // ???? The length of the tapered section is 992.3 mm..
113  // perhaps a typo in the document..
114  aCellT.zWidth = 19.84469;
115  aCellT.zCenter = 1170.01 + 0.5*aCellT.zWidth;
116  aCellT.phiWidth = phiWidth;
117  aCellT.keyedByZ = true;
118  aCellT.eDep = 0.;
119  size_t nTapered = 50;
120 //
121 // We change the cell size, to check the integral.. And we found a serious bug in the cell key find algo!
122 //
123 // aCellT.zWidth *= 1.5152;
124 // nTapered = 33;
125 // aCellT.zCenter = 1170.01 + 0.5*aCellT.zWidth;
126  for (size_t kz=0; kz != nTapered; kz++) {
127  LBNFDeDxCell aCellZ(aCellT);
128  aCellZ.zCenter = aCellT.zCenter + kz*aCellT.zWidth;
129  aCellZ.rCenter = aCellT.rCenter - aCellZ.zWidth*kz*1.00776e-2; // the tapered slope..
130  std::ostringstream mNameStrStr; mNameStrStr << kz;
131  aCellZ.MARSName = std::string("hAds2z_");
132  aCellZ.MARSName += std::string(mNameStrStr.str());
133  for (size_t kPhi=0; kPhi != fNumPhiSlices; kPhi++) {
134  LBNFDeDxCell aCell(aCellZ);
135  aCell.phiCenter = 0.5*aCellZ.phiWidth + kPhi*aCellZ.phiWidth;
136  unsigned int tag = this->getTagFromZ(aCell.zCenter,aCellT.zCenter + 0.00001*aCellT.zWidth,
137  aCellT.zWidth, aCell.phiCenter);
138 // std::cerr << " LBNFDeDxMap::defineInnerCHornA, tag " << tag << aCell.MARSName << std::endl;
139  fMap.emplace(tag, aCell);
140  // Add the Water layer (for extra-credits !);
141  LBNFDeDxCell aCellW(aCell);
142  aCellW.G4Name = std::string("LBNFConceptHornAICTaperWater");
143  aCellW.rCenter = aCellZ.rCenter + 1.0 + 0.5;
144  aCellW.rWidth = 0.5;
145  tag += 1000000;
146 // std::cerr << " LBNFDeDxMap::defineInnerCHornA, tag " << tag << aCellW.MARSName << std::endl;
147  fMap.emplace(tag, aCellW);
148  }
149  }
150 
151  zStarts.push_back(aCellT.zCenter);
152  zWidths.push_back(aCellT.zWidth);
153  G4NamesInMapZTag.push_back(std::string("LBNFConceptHornAICTaper"));
154  zStarts.push_back(aCellT.zCenter);
155  zWidths.push_back(aCellT.zWidth);
156  G4NamesInMapZTag.push_back(std::string("LBNFConceptHornAICTaperWater"));
157  //
158  // The downstream I/O section..
159  //
160  aCellT.G4Name = std::string("LBNFConceptHornADownstrIOSect");
161  aCellT.MARSName = std::string("hA_dbB_");
162  aCellT.rWidth = 19.11484;
163  aCellT.rCenter = 33. + 0.5*aCellT.rWidth; // defining boundaries..
164  aCellT.zWidth = 86.; // oversized, slightly... for this volume, limits are in r,phi.
165  // encompass the 8 cells for this region.
166  aCellT.zCenter = 0.024 + 1170 + 992.8 + 0.5*aCellT.zWidth; // Fairly precise, to avoid overlap
167  // with the last segment of the tapered section..
168  aCellT.phiWidth = phiWidth;
169  aCellT.keyedByZ = false;
170  aCellT.eDep = 0.;
171  for (size_t kr=0; kr != 9; kr++) {
172  LBNFDeDxCell aCellR(aCellT);
173  aCellR.rCenter = aCellT.rCenter + kr*aCellT.rWidth;
174  std::ostringstream mNameStrStr; mNameStrStr << kr;
175  aCellR.MARSName += std::string(mNameStrStr.str());
176  for (size_t kPhi=0; kPhi != fNumPhiSlices; kPhi++) {
177  LBNFDeDxCell aCell(aCellR);
178  aCell.phiCenter = 0.5*aCellR.phiWidth + kPhi*aCellR.phiWidth;
179  unsigned int tag = this->getTagFromR(aCell.rCenter, aCellT.rCenter + 0.00001*aCellT.rWidth,
180  aCellT.rWidth, aCell.phiCenter);
181 // std::cerr << " LBNFDeDxMap::defineInnerCHornA, tag " << tag << aCell.MARSName << std::endl;
182  fMap.emplace(tag, aCell);
183  }
184  }
185  rStarts.push_back(aCellT.rCenter);
186  rWidths.push_back(aCellT.rWidth);
187  G4NamesInMapRTag.push_back(aCellT.G4Name);
188  //
189  // Special volumes, Spider support ring holder.
190  //
191  aCellT.G4Name = std::string("LBNFConceptHornARingSuppIC");
192  aCellT.MARSName = std::string("hAcoll");
193  aCellT.rWidth = 3.75;
194  aCellT.rCenter = 45.01 + 0.5*aCellT.rWidth; // defining boundaries..
195  aCellT.zWidth = 20.0;
196  aCellT.zCenter = 1084.5; // defining boundaries..
197  aCellT.keyedByZ = true;
198  for (size_t kPhi=0; kPhi != fNumPhiSlices; kPhi++) {
199  LBNFDeDxCell aCell(aCellT);
200  aCell.phiCenter = 0.5*aCell.phiWidth + kPhi*aCell.phiWidth;
201  unsigned int tag = 2000000 + this->getTagFromZ(aCell.zCenter,aCellT.zCenter + 0.00001*aCellT.zWidth,
202  aCellT.zWidth, aCell.phiCenter);
203  fMap.emplace(tag, aCell);
204 // std::cerr << " LBNFDeDxMap::defineInnerCHornA, tag " << tag << aCell.MARSName << std::endl;
205  }
206  zStarts.push_back(aCellT.zCenter);
207  zWidths.push_back(aCellT.zWidth);
208  G4NamesInMapZTag.push_back(aCellT.G4Name);
209  //
210  // Special volumes, Weld
211  //
212  aCellT.G4Name = std::string("LBNFConceptHornAWeldIC0toIC1");
213  aCellT.MARSName = std::string("hAcoll2");
214  aCellT.rWidth = 0.625;
215  aCellT.rCenter = 45.01 + 0.5*aCellT.rWidth; // defining boundaries..
216  aCellT.zWidth = 23.3;
217  aCellT.zCenter = 1140.065; // defining boundaries..
218  aCellT.keyedByZ = true;
219  for (size_t kPhi=0; kPhi != fNumPhiSlices; kPhi++) {
220  LBNFDeDxCell aCell(aCellT);
221  aCell.phiCenter = 0.5*aCell.phiWidth + kPhi*aCell.phiWidth;
222  unsigned int tag = 3000000 + this->getTagFromZ(aCell.zCenter,aCellT.zCenter + 0.00001*aCellT.zWidth,
223  aCellT.zWidth, aCell.phiCenter);
224  fMap.emplace(tag, aCell);
225 // std::cerr << " LBNFDeDxMap::defineInnerCHornA, tag " << tag << aCell.MARSName << std::endl;
226  }
227  zStarts.push_back(aCellT.zCenter);
228  zWidths.push_back(aCellT.zWidth);
229  G4NamesInMapZTag.push_back(aCellT.G4Name);
230  //
231  // Done....
232  //
233  std::cerr << " LBNFDeDxMap::defineInnerCHornA with " << fMap.size() << " cells, keep going " << std::endl;
234 }
236 
237 }
238 void LBNFDeDxMap::fill(const G4Step* aStep) {
239 
240  if (aStep->GetStepLength() < 1.0e-6) return;
241  G4StepPoint* prePtr = aStep->GetPreStepPoint();
242  G4StepPoint* postPtr = aStep->GetPostStepPoint();
243  if (prePtr == 0) return;
244  if (postPtr == 0) return;
245  G4LogicalVolume *volPre = prePtr->GetPhysicalVolume()->GetLogicalVolume();
246  if (volPre == 0) return;
247  std::string volNamePre(volPre->GetName());
248  double zStart = std::nan("");
249  double rStart = std::nan("");
250  double zWidth = std::nan("");
251  double rWidth = std::nan("");
252  bool isRelevantRTag = false;
253 // std::cerr << " LBNFDeDxMap::fill, number of RVols name " << G4NamesInMapRTag.size() << std::endl;
254  for (size_t kN=0; kN != G4NamesInMapRTag.size(); kN++) {
255  std::string volR = G4NamesInMapRTag[kN];
256 // std::cerr << " ... volR " << volR << " volNamePre " << volNamePre << std::endl;
257  if (volNamePre.find(volR.c_str()) != std::string::npos) {
258  isRelevantRTag = true;
259  rStart = rStarts[kN];
260  rWidth = rWidths[kN];
261  break;
262  }
263  }
264  bool isRelevantZTag = false;
265 // std::cerr << " LBNFDeDxMap::fill, number of ZVols name " << G4NamesInMapZTag.size() << std::endl;
266  for (size_t kN=0; kN != G4NamesInMapZTag.size(); kN++) {
267  std::string volZ = G4NamesInMapZTag[kN];
268 // std::cerr << " ... volZ " << volZ << " volNamePre " << volNamePre << std::endl;
269  if (volNamePre.find(volZ.c_str()) != std::string::npos) {
270  isRelevantZTag = true;
271  zStart = zStarts[kN];
272  zWidth = zWidths[kN];
273  break;
274  }
275  }
276  if ((!isRelevantRTag) && (!isRelevantZTag)) return;
277 // std::cerr << " LBNFDeDxMap::fill, volume " << volNamePre << " is relevant.. " << std::endl;
278 // if (isRelevantRTag) std::cerr << " R tag type... " << std::endl;
279 // if (isRelevantZTag) std::cerr << " Z tag type... " << std::endl;
280 
281  // Assume the track is a straight line. Accurate enough in the material of interest...
282  const double x = 0.5*(prePtr->GetPosition()[0] + postPtr->GetPosition()[0]);
283  const double y = 0.5*(prePtr->GetPosition()[1] + postPtr->GetPosition()[1]);
284  const double z = 0.5*(prePtr->GetPosition()[2] + postPtr->GetPosition()[2]);
285  const double r = std::sqrt(x*x + y*y);
286  double phi = std::atan2(y,x);
287  if (phi < 0.) phi += 2.0*M_PI;
288  unsigned int tag = 0;
289  if (isRelevantRTag) tag = getTagFromR(r, rStart, rWidth, phi);
290  if (isRelevantZTag) tag = getTagFromZ(z, zStart, zWidth, phi);
291  // Special cases..
292  if (volNamePre.find("Water") != std::string::npos) tag += 1000000;
293  if (volNamePre.find("RingSuppIC") != std::string::npos) tag += 2000000;
294  if (volNamePre.find("WeldIC0toIC1") != std::string::npos) tag += 3000000;
296  if (it == fMap.end()) {
297  //
298  // This sometimes occur at thedge of G4 volume. Ignore, small effect.
299 // std::cerr << " LBNFDeDxMap::fill, in vol " << volNamePre
300 // << " at r/z " << r << " / " << z << " phi " << phi << " tag " << tag
301 // << " not a valid cell " << std::endl;
302 // if (isRelevantRTag) std::cerr << " R-Map, rStart " << rStart << " rWidth " << rWidth << std::endl;
303 // if (isRelevantZTag) std::cerr << " Z-Map, zStart " << zStart << " zWidth " << zWidth << std::endl;
304  return;
305  }
306  const double edd = aStep->GetTotalEnergyDeposit();
307  const G4Track *aTr = aStep->GetTrack();
308  it->second.eDep += edd;
309  it->second.eDepSq += edd*edd;
310  const int pid= aTr->GetParticleDefinition()->GetPDGEncoding();
311  const double zPre = prePtr->GetPosition()[2];
312  const double zPost = postPtr->GetPosition()[2];
313  const double rPre = std::sqrt(prePtr->GetPosition()[0]*prePtr->GetPosition()[0] +
314  prePtr->GetPosition()[1]*prePtr->GetPosition()[1]);
315  const double rPost = std::sqrt(postPtr->GetPosition()[0]*postPtr->GetPosition()[0] +
316  postPtr->GetPosition()[1]*postPtr->GetPosition()[1]);
317 // std::cerr << " DeDxMap, trkID " << aTr->GetTrackID() << " length " << aStep->GetStepLength()
318 // << " at Pre, RZ " << rPre << " / " << zPre << " Post " << rPost << " / " << zPost << std::endl
319 // << " .............. E dep " << aStep->GetTotalEnergyDeposit() << std::endl;
320  if (std::abs(aTr->GetParticleDefinition()->GetPDGCharge()) > 1.0e-30) it->second.nEntries += 1;
321  if ((tag == 2072) || (tag == 102072) || (tag == 202072) || (tag == 302072) ||
322  (tag == 402072) || (tag == 402072)) {
323  if ((fVectSpecialCell.size() < 1000000) &&
324  (std::abs(aTr->GetParticleDefinition()->GetPDGCharge()) > 1.0e-30)) {
326  aa.tag = tag;
327  aa.pid = pid;
328  aa.length = aStep->GetStepLength();
329  aa.rPre = rPre;
330  aa.zPre = zPre;
331  aa.rPost = rPost;
332  aa.zPost = zPost;
333  aa.eDep = edd;
334  aa.eKin = aTr->GetKineticEnergy();
335  fVectSpecialCell.push_back(aa);
336  }
337 
338  }
339  //
340  // What about the track coming from the inside of the horn, going back inside the IC ??
341  //
342 
343 }
344 void LBNFDeDxMap::dumpASCII(const std::string &aNameDir, int nEvts) {
345  std::string aNameOut(aNameDir);
346  aNameOut += std::string("/OutDeDxMap_") + fName + std::string(".txt");
347  std::ofstream fOut(aNameOut.c_str());
348  fOut << " tag ZOrR G4Name MARSName zC zW rC rW phiC phiW nEnt eDep sigEDep " << std::endl;
350  it != fMap.end(); it++) {
351  const double sEdd = it->second.eDep/nEvts;
352  double sigEDep = 1.412*it->second.eDep/nEvts;
353  if (it->second.nEntries > 1) {
354  const double mEdd = it->second.eDep/it->second.nEntries;
355  const double w = ((it->second.eDepSq) -
356  (it->second.nEntries) * mEdd * mEdd)/(it->second.nEntries -1);
357  sigEDep = std::sqrt(std::abs(w)) * it->second.nEntries/(nEvts*std::sqrt(it->second.nEntries));
358  }
359  fOut << " " << it->first << " " <<it->second.keyedByZ
360  << " " << it->second.G4Name << " " << it->second.MARSName
361  << " " << it->second.zCenter << " " << it->second.zWidth
362  << " " << it->second.rCenter << " " << it->second.rWidth
363  << " " << it->second.phiCenter << " " << it->second.phiWidth
364  << " " << it->second.nEntries << " " << sEdd << " " << sigEDep << std::endl;
365  }
366  fOut.close();
367  std::string aNameOut2(aNameDir);
368  aNameOut2 += std::string("/OutDeDxSpCell_") + fName + std::string(".txt");
369  std::ofstream fOut2(aNameOut2.c_str());
370  fOut2 << " k tag pid l rPre zPre rPos zPos eDep eKin " << std::endl;
371  size_t kk = 0;
373  it != fVectSpecialCell.end(); it++, kk++) {
374  fOut2 << " " << kk << " " << it->tag << " " << it->pid
375  << " " << it->length << " " << it->rPre
376  << " " << it->zPre << " " << it->rPost
377  << " " << it->zPost << " " << it->eDep
378  << " " << it->eKin << std::endl;
379  }
380  fOut2.close();
381 }
intermediate_table::iterator iterator
void fill(const G4Step *aStep)
Definition: LBNFDeDxMap.cc:238
std::string string
Definition: nybbler.cc:12
std::vector< std::string > G4NamesInMapZTag
Definition: LBNFDeDxMap.hh:60
std::vector< double > rStarts
Definition: LBNFDeDxMap.hh:63
double phiWidth
Definition: LBNFDeDxMap.hh:25
void dumpASCII(const std::string &aDirectory, int nEvt)
Definition: LBNFDeDxMap.cc:344
std::vector< LBNFDeDxEntryInCell > fVectSpecialCell
Definition: LBNFDeDxMap.hh:65
double rCenter
Definition: LBNFDeDxMap.hh:22
double zCenter
Definition: LBNFDeDxMap.hh:20
unsigned int fNumPhiSlices
Definition: LBNFDeDxMap.hh:57
intermediate_table::const_iterator const_iterator
std::vector< double > rWidths
Definition: LBNFDeDxMap.hh:64
unsigned int getTagFromZ(double z, double zStart, double zWidth, double f) const
Definition: LBNFDeDxMap.hh:80
double y
std::vector< double > zStarts
Definition: LBNFDeDxMap.hh:61
T abs(T value)
double zWidth
Definition: LBNFDeDxMap.hh:21
std::string MARSName
Definition: LBNFDeDxMap.hh:18
std::vector< double > zWidths
Definition: LBNFDeDxMap.hh:62
double z
std::string fName
Definition: LBNFDeDxMap.hh:52
void defineInnerCHornB()
Definition: LBNFDeDxMap.cc:235
std::map< unsigned int, LBNFDeDxCell > fMap
Definition: LBNFDeDxMap.hh:58
double phiCenter
Definition: LBNFDeDxMap.hh:24
double eDepSq
Definition: LBNFDeDxMap.hh:27
void defineInnerCHornA()
Definition: LBNFDeDxMap.cc:24
double rWidth
Definition: LBNFDeDxMap.hh:23
list x
Definition: train.py:276
std::vector< std::string > G4NamesInMapRTag
Definition: LBNFDeDxMap.hh:59
std::string G4Name
Definition: LBNFDeDxMap.hh:17
LBNFDeDxMap(const std::string &aName)
Definition: LBNFDeDxMap.cc:5
unsigned int getTagFromR(double r, double rStart, double rWidth, double f) const
Definition: LBNFDeDxMap.hh:71
QTextStream & endl(QTextStream &s)