er  dev
ERBeamDetSetup.cxx
1 /********************************************************************************
2  * Copyright (C) Joint Institute for Nuclear Research *
3  * *
4  * This software is distributed under the terms of the *
5  * GNU Lesser General Public Licence version 3 (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
8 #include "ERBeamDetSetup.h"
9 
10 #include <ostream>
11 
12 #include "TGeoTube.h"
13 #include "TError.h"
14 #include "TMath.h"
15 #include "TGeoManager.h"
16 #include "TGeoMatrix.h"
17 #include "TGeoCompositeShape.h"
18 #include "TGeoSphere.h"
19 #include "TGeoNode.h"
20 #include "TROOT.h"
21 #include <Riostream.h>
22 #include <TDOMParser.h>
23 #include <TXMLAttr.h>
24 #include <TXMLNode.h>
25 #include <TList.h>
26 #include "TSystem.h"
27 
28 #include "FairRootManager.h"
29 #include "FairRun.h"
30 #include "FairRuntimeDb.h"
31 #include "FairGeoLoader.h"
32 #include "FairGeoMedium.h"
33 #include "FairGeoInterface.h"
34 #include "FairGeoBuilder.h"
35 #include "FairGeoMedia.h"
36 #include "FairLogger.h"
37 
38 #include "ERSupport.h"
39 
40 using namespace std;
41 
42 
43 ERBeamDetSetup* ERBeamDetSetup::fInstance = NULL;
44 Double_t ERBeamDetSetup::fTargetR = 0;
45 Int_t ERBeamDetSetup::fMWPCCount = 0;
46 Int_t ERBeamDetSetup::fToFCount = 0;
47 Double_t ERBeamDetSetup::fDistanceBetweenToF = 0;
48 Double_t ERBeamDetSetup::fDistanceBetweenMWPC = 0;
49 map<Int_t, map<Int_t, map<Int_t, ERBeamDetWire*>>>ERBeamDetSetup::fWires;
50 // ----- ToF parameters -----------------------------------------------------
51 vector<Double_t> ERBeamDetSetup::fPlasticX;
52 vector<Double_t> ERBeamDetSetup::fPlasticY;
53 vector<Double_t> ERBeamDetSetup::fPlasticZ;
54 vector<TString> ERBeamDetSetup::fPlasticMedia;
55 // --------------------------------------------------------------------------
56 // ----- MWPC parameters ----------------------------------------------------
57 vector<Double_t> ERBeamDetSetup::fGasVolX;
58 vector<Double_t> ERBeamDetSetup::fGasVolY;
59 vector<Double_t> ERBeamDetSetup::fGasVolZ;
60 vector<Double_t> ERBeamDetSetup::fGasStripX;
61 vector<Double_t> ERBeamDetSetup::fGasStripY;
62 vector<Double_t> ERBeamDetSetup::fGasStripZ; //cm
63 vector<Double_t> ERBeamDetSetup::fGasPlaneXOffset;
64 vector<Double_t> ERBeamDetSetup::fGasPlaneYOffset;
65 vector<Double_t> ERBeamDetSetup::fDistBetweenXandY;
66 vector<Double_t> ERBeamDetSetup::fCathodeThickness;
67 vector<Double_t> ERBeamDetSetup::fKaptonWindowThickness;
68 vector<Double_t> ERBeamDetSetup::fAnodeWireDiameter;
69 vector<TString> ERBeamDetSetup::fKaptonWindowMedia;
70 vector<TString> ERBeamDetSetup::fCathodeMedia;
71 vector<TString> ERBeamDetSetup::fAnodeWireMedia;
72 vector<TString> ERBeamDetSetup::fGasMedia;
73 vector<Bool_t> ERBeamDetSetup::fMWPCInvNumberingOrderX;
74 vector<Bool_t> ERBeamDetSetup::fMWPCInvNumberingOrderY;
75 // --------------------------------------------------------------------------
76 // ------ fPosition of detector's parts relative to zero ---------------------
77 vector<Double_t> ERBeamDetSetup::fPositionToF;
78 vector<Double_t> ERBeamDetSetup::fPositionMWPC;
79 // -------- fTarget parameters -----------------------------------------------
80 Double_t ERBeamDetSetup::fTargetH2R = 3.; //cm
81 Double_t ERBeamDetSetup::fTargetH2Z = 1e-3; //cm
82 Double_t ERBeamDetSetup::fTargetShellThicknessSide = 1e-5;
83 Double_t ERBeamDetSetup::fTargetShellThicknessZ = 1e-5;
84 Bool_t ERBeamDetSetup::fSensitiveTargetIsSet = false;
85 
86 TString ERBeamDetSetup::fParamsXmlFileName = "";
87 vector<TString> ERBeamDetSetup::fToFType;
88 vector<TString> ERBeamDetSetup::fMWPCType;
89 Bool_t ERBeamDetSetup::fGeoFromContainerIsRead = kFALSE;
90 
91 
92 
93 ERBeamDetSetup::ERBeamDetSetup() {
94  LOG(DEBUG) << "ERBeamDetSetup initialized! "<< FairLogger::endl;
95 }
96 //-------------------------------------------------------------------------
97 ERBeamDetSetup::~ERBeamDetSetup() {
98 }
99 //-------------------------------------------------------------------------
100 void ERBeamDetSetup::AddMWPC(TString type, Double_t position) {
101  fPositionMWPC.push_back(position);
102  fMWPCType.push_back(type);
103  fMWPCInvNumberingOrderX.push_back(false);
104  fMWPCInvNumberingOrderY.push_back(false);
105  fMWPCCount++;
106 }
107 //-------------------------------------------------------------------------
108 void ERBeamDetSetup::AddToF(TString type, Double_t position) {
109  fPositionToF.push_back(position);
110  fToFType.push_back(type);
111  fToFCount++;
112 }
113 //-------------------------------------------------------------------------
115  fMWPCInvNumberingOrderX.back() = true;
116 }
117 //-------------------------------------------------------------------------
119  fMWPCInvNumberingOrderY.back() = true;
120 }
121 //-------------------------------------------------------------------------
122 void ERBeamDetSetup::GetTransInMotherNode (TGeoNode const* node, Double_t trans[3]) {
123  memcpy(trans, node->GetMatrix()->GetTranslation(), sizeof(double)*3);
124 }
125 //-------------------------------------------------------------------------
126 void ERBeamDetSetup::GetGeoParamsFromParContainer() {
127  if (fGeoFromContainerIsRead) {
128  return ;
129  }
130  // --- Catch absence of TGeoManager
131  if ( ! gGeoManager ) {
132  std::cerr << "ERBeamDetSetup: cannot initialise without TGeoManager!"<< std::endl;
133  }
134 
135  gGeoManager->CdTop();
136  TGeoNode* cave = gGeoManager->GetCurrentNode();
137  TGeoNode* beamDet = NULL;
138  for (Int_t iNode = 0; iNode < cave->GetNdaughters(); iNode++) {
139  TString name = cave->GetDaughter(iNode)->GetName();
140  if ( name.Contains("BeamDet", TString::kIgnoreCase) ) {
141  beamDet = cave->GetDaughter(iNode);
142  break;
143  }
144  }
145 
146  // ---- Getting MWPC geometry parameters---------------------------------
147  TGeoNode* mwpc = NULL;
148  TGeoNode* mwpcStation = NULL;
149  Double_t mwpcStationZ;
150  Double_t mwpcStationZ1;
151  Double_t mwpcStationZ2;
152  TGeoMatrix* mwpcLocalPos;
153  Double_t mwpcMasterPos[3];
154  TGeoNode* plane = NULL;
155  TGeoNode* wire = NULL;
156  Int_t mwpcNb = 0;
157  for (Int_t iNode = 0; iNode < beamDet->GetNdaughters(); iNode++) {
158  TString name = beamDet->GetDaughter(iNode)->GetName();
159  if (name.Contains("MWPC", TString::kIgnoreCase) ) {
160  mwpc = beamDet->GetDaughter(iNode);
161  mwpcStationZ = mwpc->GetMatrix()->GetTranslation()[2];
162  (name.EndsWith("1", TString::kIgnoreCase)) ? mwpcStationZ1 = mwpcStationZ
163  : mwpcStationZ2 = mwpcStationZ;
164  mwpcStation = mwpc->GetDaughter(0);
165  //--------------------------------------------------------------------
166  for (Int_t planeNb = 0; planeNb < mwpcStation->GetNdaughters(); planeNb++) {
167  plane = mwpcStation->GetDaughter(planeNb);
168 
169  for (Int_t wireNb = 0; wireNb < plane->GetNdaughters(); wireNb++) {
170  wire = plane->GetDaughter(wireNb);
171  Double_t wireCoordInPlane[3];
172  Double_t wireCoordInStation[3];
173  Double_t wireCoordInDetector[3];
174  Double_t wireCoordGlob[3];
175  GetTransInMotherNode(wire, wireCoordInPlane);
176  plane->LocalToMaster(wireCoordInPlane, wireCoordInStation);
177  mwpcStation->LocalToMaster(wireCoordInStation, wireCoordInDetector);
178  mwpc->LocalToMaster(wireCoordInDetector, wireCoordGlob);
179  TString wirePlaneOrient;
180  if (planeNb == 0) {
181  wirePlaneOrient = "X";
182  fWires[mwpcNb][planeNb].insert(std::make_pair(wireNb, new ERBeamDetWire(wireCoordGlob[0],
183  wireCoordGlob[1],
184  wireCoordGlob[2])));
185  } else {
186  wirePlaneOrient = "Y";
187  fWires[mwpcNb][planeNb].insert(std::make_pair(wireNb, new ERBeamDetWire(wireCoordGlob[0],
188  wireCoordGlob[1],
189  wireCoordGlob[2])));
190  }
191 
192  LOG(DEBUG) << "Wire" << wirePlaneOrient << " " << wireNb
193  << " position (" << fWires[mwpcNb][planeNb][wireNb]->fGlobX << ", "
194  << fWires[mwpcNb][planeNb][wireNb]->fGlobY << ", "
195  << fWires[mwpcNb][planeNb][wireNb]->fGlobZ << ") cm" << FairLogger::endl;
196  }
197  }
198  mwpcNb++;
199  }
200  }
201  // Stations located simmetrically relative to local center
202  fDistanceBetweenMWPC = TMath::Abs(mwpcStationZ1 - mwpcStationZ2);
203  LOG(DEBUG) << "The distance between MWPC stations: " << fDistanceBetweenMWPC << " cm;" << FairLogger::endl;
204  //-----------------------------------------------------------------------
205  // ---- Getting tofPlastic geometry parameters ---------------------------------
206  TGeoNode* tofPlastic = NULL;
207  Double_t tofPlastic1Pos, tofPlastic2Pos;
208  for (Int_t iNode = 0; iNode < beamDet->GetNdaughters(); iNode++) {
209  TString name = beamDet->GetDaughter(iNode)->GetName();
210  if ( name.Contains("plastic", TString::kIgnoreCase) ) {
211  tofPlastic = beamDet->GetDaughter(iNode);
212  fPositionToF.push_back(tofPlastic->GetMatrix()->GetTranslation()[2]);
213  }
214  }
215  fToFCount = fPositionToF.size();
216  fDistanceBetweenToF = TMath::Abs(fPositionToF[0] - fPositionToF[GetToFCount() - 1]);
217  LOG(DEBUG)<< "The distance between plastics: " << fDistanceBetweenToF << " cm;" << FairLogger::endl;
218  //-----------------------------------------------------------------------
219  // ---- Getting fTarget geometry parameters ------------------------------
220  TGeoNode* fTarget = NULL;
221  for (Int_t iNode = 0; iNode < beamDet->GetNdaughters(); iNode++) {
222  TString name = beamDet->GetDaughter(iNode)->GetName();
223  if ( name.Contains("Target", TString::kIgnoreCase) ) {
224  fTarget = beamDet->GetDaughter(iNode);
225  TGeoNode* shell = fTarget->GetDaughter(0);
226  TGeoNode* h2 = shell->GetDaughter(0);
227  TGeoTube* h2Tube = (TGeoTube*)h2->GetVolume()->GetShape();
228  fTargetR = h2Tube->GetRmax();
229  LOG(DEBUG)<< "Target radius " << fTargetR << " cm;" << FairLogger::endl;
230  break;
231  }
232  }
233  fGeoFromContainerIsRead = kTRUE;
234  LOG(DEBUG) << "ERBeamDetSetup: read parameters from parContainer! "<< FairLogger::endl;
235 }
236 //--------------------------------------------------------------------------------------------------
237 ERBeamDetSetup* ERBeamDetSetup::Instance(){
238  if (fInstance == NULL)
239  return new ERBeamDetSetup();
240  else
241  return fInstance;
242 }
243 //--------------------------------------------------------------------------------------------------
244 Int_t ERBeamDetSetup::SetParContainers(){
245  // Get run and runtime database
246  FairRun* run = FairRun::Instance();
247  if ( ! run ) Fatal("SetParContainers", "No analysis run");
248 
249  FairRuntimeDb* rtdb = run->GetRuntimeDb();
250  if ( ! rtdb ) Fatal("SetParContainers", "No runtime database");
251 
252 }
253 //--------------------------------------------------------------------------------------------------
254 Double_t ERBeamDetSetup::GetWireGlobX(const TString& digi_branch_name, const ERChannel channel) {
255  return GetWireGlobCoord(digi_branch_name, channel, &ERBeamDetWire::fGlobX);
256 }
257 //--------------------------------------------------------------------------------------------------
258 Double_t ERBeamDetSetup::GetWireGlobY(const TString& digi_branch_name, const ERChannel channel){
259  return GetWireGlobCoord(digi_branch_name, channel, &ERBeamDetWire::fGlobY);
260 }
261 //--------------------------------------------------------------------------------------------------
262 Double_t ERBeamDetSetup::GetWireGlobZ(const TString& digi_branch_name, const ERChannel channel){
263  return GetWireGlobCoord(digi_branch_name, channel, &ERBeamDetWire::fGlobZ);
264 }
265 //--------------------------------------------------------------------------------------------------
266 Double_t ERBeamDetSetup::GetWireGlobCoord(const TString& digi_branch_name, ERChannel channel,
267  float ERBeamDetWire::* coord) {
268  const auto mwpc_and_plane = GetMwpcAndPlaneNumbers(digi_branch_name);
269  return fWires.at(mwpc_and_plane.first).at(mwpc_and_plane.second).at(channel)->*coord;
270 }
271 //--------------------------------------------------------------------------------------------------
272 std::pair<unsigned short, unsigned short> ERBeamDetSetup::
273 GetMwpcAndPlaneNumbers(const TString& digi_branch_name) {
274  if (digi_branch_name == "BeamDetMWPCDigiX1") {
275  return {0, 0};
276  } else if (digi_branch_name == "BeamDetMWPCDigiY1") {
277  return {0, 1};
278  } else if (digi_branch_name == "BeamDetMWPCDigiX2") {
279  return {1, 0};
280  } else if (digi_branch_name == "BeamDetMWPCDigiY2") {
281  return {1, 1};
282  } else {
283  LOG(FATAL) << "Unknown MWPC branch name " << digi_branch_name << FairLogger::endl;
284  }
285 }
286 //--------------------------------------------------------------------------------------------------
287 void ERBeamDetSetup::GetToFParameters(TXMLNode *node) {
288  node = node->GetNextNode();
289  for(Int_t i = 0; i < fToFCount; i++) {
290  TXMLNode* curNode = node;
291  for(; curNode; curNode = curNode->GetNextNode()) {
292  LOG(DEBUG) << "Parsing ToF " << curNode->GetNodeName() << FairLogger::endl;
293  TList *attrList;
294  TXMLAttr *attr = 0;
295  if (curNode->HasAttributes()){
296  attrList = curNode->GetAttributes();
297  TIter next(attrList);
298  while ((attr=(TXMLAttr*)next())) {
299  if (!strcasecmp("id", attr->GetName())) {
300  break;
301  }
302  }
303  }
304  else {
305  continue;
306  }
307  LOG(DEBUG) << "ToF type " << fToFType[i] << " " << attr->GetValue() << FairLogger::endl;
308  if(!strcasecmp(fToFType[i], attr->GetValue())) {
309  LOG(DEBUG) << "Tof value " << attr->GetValue() << FairLogger::endl;
310  TXMLNode* curNode2 = curNode->GetChildren();
311  for(; curNode2; curNode2 = curNode2->GetNextNode()) {
312  if(!strcasecmp(curNode2->GetNodeName(), "plasticGeometry")) {
313  attrList = curNode2->GetAttributes();
314  attr = 0;
315  TIter nextPlasticAttr(attrList);
316  while ((attr=(TXMLAttr*)nextPlasticAttr())) {
317  if (!strcasecmp("X", attr->GetName())) {
318  fPlasticX.push_back(atof(attr->GetValue()));
319  }
320  if (!strcasecmp("Y", attr->GetName())) {
321  fPlasticY.push_back(atof(attr->GetValue()));
322  }
323  if (!strcasecmp("Z", attr->GetName())) {
324  fPlasticZ.push_back(atof(attr->GetValue()));
325  }
326  }
327  }
328  if(!strcasecmp(curNode2->GetNodeName(), "plasticMedia")) {
329  fPlasticMedia.push_back(curNode2->GetText());
330  }
331  }
332  }
333  }
334  }
335 }
336 //--------------------------------------------------------------------------------------------------
337 void ERBeamDetSetup::GetMWPCParameters(TXMLNode *node) {
338  node = node->GetNextNode();
339  for(Int_t i = 0; i < fMWPCCount; i++) {
340  TXMLNode* curNode = node;
341  for(; curNode; curNode = curNode->GetNextNode()) {
342  //cout << "Pasrsing ToF " << node->GetNodeName() << endl;
343  TList *attrList;
344  TXMLAttr *attr = 0;
345  if (curNode->HasAttributes()){
346  attrList = curNode->GetAttributes();
347  TIter next(attrList);
348  while ((attr=(TXMLAttr*)next())) {
349  if (!strcasecmp("id", attr->GetName())) {
350  break;
351  }
352  }
353  }
354  else {
355  continue;
356  }
357  //LOG(DEBUG) << "Pasrsing MWPC " << node->GetNodeName() << FairLogger::endl;
358  if(!strcasecmp(fMWPCType[i], attr->GetValue())) {
359  TXMLNode* curNode2 = curNode->GetChildren();
360  for(; curNode2; curNode2 = curNode2->GetNextNode()) {
361  if(!strcasecmp(curNode2->GetNodeName(), "gasVolGeometry")) {
362  attrList = curNode2->GetAttributes();
363  attr = 0;
364  TIter nextGasVolAttr(attrList);
365  while ((attr=(TXMLAttr*)nextGasVolAttr())) {
366  if (!strcasecmp("X", attr->GetName())) {
367  fGasVolX.push_back(atof(attr->GetValue()));
368  }
369  if (!strcasecmp("Y", attr->GetName())) {
370  fGasVolY.push_back(atof(attr->GetValue()));
371  }
372  if (!strcasecmp("Z", attr->GetName())) {
373  fGasVolZ.push_back(atof(attr->GetValue()));
374  }
375  }
376  }
377  if(!strcasecmp(curNode2->GetNodeName(), "gasStripGeometry")) {
378  attrList = curNode2->GetAttributes();
379  attr = 0;
380  TIter nextGasStripAttr(attrList);
381  while ((attr=(TXMLAttr*)nextGasStripAttr())) {
382  if (!strcasecmp("X", attr->GetName())) {
383  fGasStripX.push_back(atof(attr->GetValue()));
384  }
385  if (!strcasecmp("Y", attr->GetName())) {
386  fGasStripY.push_back(atof(attr->GetValue()));
387  }
388  if (!strcasecmp("Z", attr->GetName())) {
389  fGasStripZ.push_back(atof(attr->GetValue()));
390  }
391  }
392  }
393  if(!strcasecmp(curNode2->GetNodeName(), "gasPlanesOffset")) {
394  attrList = curNode2->GetAttributes();
395  attr = 0;
396  TIter nextGasStripAttr(attrList);
397  while ((attr=(TXMLAttr*)nextGasStripAttr())) {
398  if (!strcasecmp("X", attr->GetName())) {
399  fGasPlaneXOffset.push_back(atof(attr->GetValue()));
400  }
401  if (!strcasecmp("Y", attr->GetName())) {
402  fGasPlaneYOffset.push_back(atof(attr->GetValue()));
403  }
404  }
405  }
406  if(!strcasecmp(curNode2->GetNodeName(), "distBetweenXandYStrips")) {
407  fDistBetweenXandY.push_back(atof(curNode2->GetText()));
408  }
409  if(!strcasecmp(curNode2->GetNodeName(), "cathodeThickness")) {
410  fCathodeThickness.push_back(atof(curNode2->GetText()));
411  }
412  if(!strcasecmp(curNode2->GetNodeName(), "kaptonWindowThickness")) {
413  fKaptonWindowThickness.push_back(atof(curNode2->GetText()));
414  }
415  if(!strcasecmp(curNode2->GetNodeName(), "anodeWireDiameter")) {
416  fAnodeWireDiameter.push_back(atof(curNode2->GetText()));
417  }
418  if(!strcasecmp(curNode2->GetNodeName(), "kaptonWindowMedia")) {
419  fKaptonWindowMedia.push_back(curNode2->GetText());
420  }
421  if(!strcasecmp(curNode2->GetNodeName(), "cathodeMedia")) {
422  fCathodeMedia.push_back(curNode2->GetText());
423  }
424  if(!strcasecmp(curNode2->GetNodeName(), "anodeWireMedia")) {
425  fAnodeWireMedia.push_back(curNode2->GetText());
426  }
427  if(!strcasecmp(curNode2->GetNodeName(), "gasMedia")) {
428  fGasMedia.push_back(curNode2->GetText());
429  }
430  }
431  }
432  }
433  }
434 }
435 //--------------------------------------------------------------------------------------------------
436 Double_t ERBeamDetSetup::GetDistanceBetweenToF(Int_t tof1Ind, Int_t tof2Ind) {
437  return TMath::Abs(fPositionToF[tof1Ind] - fPositionToF[tof2Ind]);
438 }
439 //--------------------------------------------------------------------------------------------------
440 void ERBeamDetSetup::PrintDetectorParameters(void) {
441  LOG(DEBUG) << "------------------------------------------------" << "\r\n";
442  LOG(DEBUG) << "Detector's parameters from " << fParamsXmlFileName << "\r\n";
443  LOG(DEBUG) << "------------------------------------------------" << "\r\n";
444  LOG(DEBUG) << "ToFs parameters:" << "\r\n";
445  for(Int_t i = 0; i < fToFCount; i++) {
446  LOG(DEBUG) << "ToF_"+TString::Itoa(i+1, 10) << " is " << fToFType[i] << " with parameters:" << "\r\n"
447  << "\tpositionZ = " << fPositionToF[i] << "\r\n"
448  << "\tX = " << fPlasticX[i]
449  << "; Y = " << fPlasticY[i]
450  << "; Z = " << fPlasticZ[i] << "\r\n"
451  << "\tplasticMedia = " << fPlasticMedia[i] << "\r\n" << "\r\n";
452  }
453  LOG(DEBUG) << "------------------------------------------------" << "\r\n";
454  LOG(DEBUG) << "MWPCs parameters:" << "\r\n";
455  for(Int_t i = 0; i < fMWPCCount; i++) {
456  LOG(DEBUG) << "MWPC_"+TString::Itoa(i+1, 10) << " is " << fMWPCType[i] << " with parameters: " << "\r\n"
457  << "\tpositionZ = " << fPositionMWPC[i] << "\r\n"
458  << "\tGasVolX = " << fGasVolX[i]
459  << "; GasVolY = " << fGasVolY[i]
460  << "; GasVolZ = " << fGasVolZ[i] << "\r\n"
461  << "\tGasStripX = " << fGasStripX[i]
462  << "; GasStripY = " << fGasStripY[i]
463  << "; GasStripZ = " << fGasStripZ[i] << "\r\n"
464  << "\tDistance between X & Y strips = " << fDistBetweenXandY[i] << "\r\n"
465  << "\tCathode thickness = " << fCathodeThickness[i] << "\r\n"
466  << "\tKaptonWindow thickness = " << fKaptonWindowThickness[i] << "\r\n"
467  << "\tWire diameter = " << fAnodeWireDiameter[i] << "\r\n"
468  << "\tKaptonWindow media = " << fKaptonWindowMedia[i] << "\r\n"
469  << "\tCathode media = " << fCathodeMedia[i] << "\r\n"
470  << "\tAnodeWire media = " << fAnodeWireMedia[i] << "\r\n"
471  << "\tgasStrip media = " << fGasMedia[i] << "\r\n" << "\r\n";
472  }
473 }
474 //--------------------------------------------------------------------------------------------------
475 void ERBeamDetSetup::PrintDetectorParametersToFile(TString fileName) {
476  ofstream listingFile;
477  listingFile.open(fileName);
478  listingFile << "------------------------------------------------" << "\r\n";
479  listingFile << "Detector's parameters from " << fParamsXmlFileName << "\r\n";
480  listingFile << "------------------------------------------------" << "\r\n";
481  listingFile << "ToFs parameters:" << "\r\n";
482  for(Int_t i = 0; i < fToFCount; i++) {
483  listingFile << "ToF_"+TString::Itoa(i+1, 10) << " is " << fToFType[i] << " with parameters:" << "\r\n"
484  << "\tpositionZ = " << fPositionToF[i] << "\r\n"
485  << "\tX = " << fPlasticX[i]
486  << "; Y = " << fPlasticY[i]
487  << "; Z = " << fPlasticZ[i] << "\r\n"
488  << "\tplasticMedia = " << fPlasticMedia[i] << "\r\n" << "\r\n";
489  }
490  listingFile << "------------------------------------------------" << "\r\n";
491  listingFile << "MWPCs parameters:" << "\r\n";
492  for(Int_t i = 0; i < fMWPCCount; i++) {
493  listingFile << "MWPC_"+TString::Itoa(i+1, 10) << " is " << fMWPCType[i] << " with parameters: " << "\r\n"
494  << "\tpositionZ = " << fPositionMWPC[i] << "\r\n"
495  << "\tGasVolX = " << fGasVolX[i]
496  << "; GasVolY = " << fGasVolY[i]
497  << "; GasVolZ = " << fGasVolZ[i] << "\r\n"
498  << "\tGasStripX = " << fGasStripX[i]
499  << "; GasStripY = " << fGasStripY[i]
500  << "; GasStripZ = " << fGasStripZ[i] << "\r\n"
501  << "\tDistance between X & Y strips = " << fDistBetweenXandY[i] << "\r\n"
502  << "\tCathode thickness = " << fCathodeThickness[i] << "\r\n"
503  << "\tKaptonWindow thickness = " << fKaptonWindowThickness[i] << "\r\n"
504  << "\tWire diameter = " << fAnodeWireDiameter[i] << "\r\n"
505  << "\tKaptonWindow media = " << fKaptonWindowMedia[i] << "\r\n"
506  << "\tCathode media = " << fCathodeMedia[i] << "\r\n"
507  << "\tAnodeWire media = " << fAnodeWireMedia[i] << "\r\n"
508  << "\tgasStrip media = " << fGasMedia[i] << "\r\n" << "\r\n";
509  }
510 }
511 //--------------------------------------------------------------------------------------------------
512 void ERBeamDetSetup::ParseXmlParameters() {
513  TDOMParser *domParser;//
514  //gROOT->ProcessLine(".O 0");
515  domParser = new TDOMParser;
516  domParser->SetValidate(false); // do not validate with DTD
517  Int_t parsecode = domParser->ParseFile(fParamsXmlFileName);
518  if (parsecode < 0) {
519  cerr << domParser->GetParseCodeMessage(parsecode) << FairLogger::endl;
520  // return -1;
521  }
522  TXMLNode *rootNode = domParser->GetXMLDocument()->GetRootNode();
523  TXMLNode *detPartNode = rootNode->GetChildren()->GetNextNode();//->GetChildren();
524  TXMLNode *curNode;
525  LOG(DEBUG) << "Cmp ToF " << FairLogger::endl;
526 
527  for ( ; detPartNode; detPartNode = detPartNode->GetNextNode()) { // detector's part
528  if(!strcasecmp(detPartNode->GetNodeName(), "ToFTypes")) {
529  LOG(DEBUG) << "Cmp ToF " << detPartNode->GetNodeName() << FairLogger::endl;
530  GetToFParameters(detPartNode->GetChildren());
531  }
532  if(!strcasecmp(detPartNode->GetNodeName(), "MWPCTypes")) {
533  // LOG(DEBUG) << "Cmp MWPC " << detPartNode->GetNodeName() << FairLogger::endl;
534  GetMWPCParameters(detPartNode->GetChildren());
535  }
536  }
537  //return 0;
538 }
539 //--------------------------------------------------------------------------------------------------
540 void ERBeamDetSetup::ConstructGeometry() {
541  ParseXmlParameters();
542  PrintDetectorParameters();
543  // ----- BeamDet parameters -------------------------------------------------
544  Double_t transTargetX = 0.;
545  Double_t transTargetY = 0.;
546  Double_t transTargetZ = 0.;
547  // --------------------------------------------------------------------------
548  // Create a global translation
549  Float_t global_X = 0.;
550  Float_t global_Y = 0.;
551  Float_t global_Z = 0.;
552  //Create gloabal Rotation
553  TGeoRotation *fGlobalRotation = new TGeoRotation();
554  fGlobalRotation->RotateX(0.);
555  fGlobalRotation->RotateY(0.);
556  fGlobalRotation->RotateZ(0.);
557  // Create a zero rotation
558  TGeoRotation *fZeroRotation = new TGeoRotation();
559  fZeroRotation->RotateX(0.);
560  fZeroRotation->RotateY(0.);
561  fZeroRotation->RotateZ(0.);
562  // Create a 90 degree rotation around Z axis
563  TGeoRotation *f90ZRotation = new TGeoRotation();
564  f90ZRotation->RotateX(0.);
565  f90ZRotation->RotateY(0.);
566  f90ZRotation->RotateZ(90.);
567  // Create a 270 degree rotation around Z axis
568  TGeoRotation *f270ZRotation = new TGeoRotation();
569  f270ZRotation->RotateX(0.);
570  f270ZRotation->RotateY(0.);
571  f270ZRotation->RotateZ(270.);
572  // Create a 180 degree rotation around Z axis
573  TGeoRotation *f180ZRotation = new TGeoRotation();
574  f180ZRotation->RotateX(0.);
575  f180ZRotation->RotateY(0.);
576  f180ZRotation->RotateZ(180.);
577  // Create a 90 degree rotation around X axis
578  TGeoRotation *f90XRotation = new TGeoRotation();
579  f90XRotation->RotateX(90.);
580  f90XRotation->RotateY(0.);
581  f90XRotation->RotateZ(0.);
582 
583  TGeoRotation *fRotationY = new TGeoRotation();
584  fRotationY->RotateX(0.);
585  fRotationY->RotateY(30.);
586  fRotationY->RotateZ(0.);
587 
588  TGeoManager* gGeoMan = NULL;
589  // ------- Load media from media file -----------------------------------
590  FairGeoLoader* geoLoad = FairGeoLoader::Instance();
591  FairGeoInterface* geoFace = geoLoad->getGeoInterface();
592  TString geoPath = gSystem->Getenv("VMCWORKDIR");
593  TString medFile = geoPath + "/geometry/media.geo";
594  geoFace->setMediaFile(medFile);
595  geoFace->readMedia();
596  gGeoMan = gGeoManager;
597  // ------- Geometry file name (output) ----------------------------------
598  TString geoFileName = geoPath + "/geometry/beamdet.temp.root";
599  // ----------------- Get and create the required media -----------------
600  FairGeoMedia* geoMedia = geoFace->getMedia();
601  FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
602 
603  // ----- Create media for ToF -----------------------------------------------
604  vector<FairGeoMedium*> mPlastic;
605  vector<TGeoMedium*> pMedPlastic;
606  for(Int_t i = 0; i < fToFCount; i++) {
607  mPlastic.push_back(geoMedia->getMedium(fPlasticMedia[i]));
608  if ( ! mPlastic[i] ) Fatal("Main", "FairMedium Plastic not found");
609  geoBuild->createMedium(mPlastic[i]);
610  pMedPlastic.push_back(gGeoMan->GetMedium(fPlasticMedia[i]));
611  if ( ! pMedPlastic[i] ) Fatal("Main", "Medium Plastic not found");
612  }
613  // ----- Create media for MWPC ----------------------------------------------
614  vector<FairGeoMedium*> mCF4;
615  vector<TGeoMedium*> pMedCF4;
616  vector<FairGeoMedium*> mKaptonWindow;
617  vector<TGeoMedium*> pMedKaptonWindow;
618  vector<FairGeoMedium*> mCathode;
619  vector<TGeoMedium*> pMedCathode;
620  vector<FairGeoMedium*> mAnodeWire;
621  vector<TGeoMedium*> pMedAnodeWire;
622  for(Int_t i = 0; i < fMWPCCount; i++) {
623  mCF4.push_back(geoMedia->getMedium(fGasMedia[i]));
624  if ( ! mCF4[i] ) Fatal("Main", "FairMedium for gasStrip not found");
625  geoBuild->createMedium(mCF4[i]);
626  pMedCF4.push_back(gGeoMan->GetMedium(fGasMedia[i]));
627  if ( ! pMedCF4[i] ) Fatal("Main", "Medium for gasStrip not found");
628 
629  mKaptonWindow.push_back(geoMedia->getMedium(fKaptonWindowMedia[i]));
630  if ( ! mKaptonWindow[i] )
631  LOG(FATAL) << "FairMedium " << fKaptonWindowMedia[i] << " not found" << FairLogger::endl;
632  geoBuild->createMedium(mKaptonWindow[i]);
633  pMedKaptonWindow.push_back(gGeoMan->GetMedium(fKaptonWindowMedia[i]));
634  if ( ! pMedKaptonWindow[i] )
635  LOG(FATAL) << "Medium " << fKaptonWindowMedia[i] << " not found" << FairLogger::endl;
636  mCathode.push_back(geoMedia->getMedium(fCathodeMedia[i]));
637  if ( ! mCathode[i] )
638  LOG(FATAL) << "FairMedium " << fCathodeMedia[i] << " not found" << FairLogger::endl;
639  geoBuild->createMedium(mCathode[i]);
640  pMedCathode.push_back(gGeoMan->GetMedium(fCathodeMedia[i]));
641  if ( ! pMedCathode[i] )
642  LOG(FATAL) << "Medium " << fCathodeMedia[i] << " not found" << FairLogger::endl;
643  mAnodeWire.push_back(geoMedia->getMedium(fAnodeWireMedia[i]));
644  if ( ! mAnodeWire[i] )
645  LOG(FATAL) << "FairMedium " << fAnodeWireMedia[i] << " not found" << FairLogger::endl;
646  geoBuild->createMedium(mAnodeWire[i]);
647  pMedAnodeWire.push_back(gGeoMan->GetMedium(fAnodeWireMedia[i]));
648  if ( ! pMedAnodeWire[i] )
649  LOG(FATAL) << "Medium " << fAnodeWireMedia[i] << " not found" << FairLogger::endl;
650  }
651  // ------ Create media for Target -------------------------------------------
652  FairGeoMedium* mH2 = geoMedia->getMedium("H2");
653  if ( ! mH2 ) Fatal("Main", "FairMedium H2 not found");
654  geoBuild->createMedium(mH2);
655  TGeoMedium* pH2 = gGeoMan->GetMedium("H2");
656  if ( ! pH2 ) Fatal("Main", "Medium H2 not found");
657 
658  FairGeoMedium* mSteel = geoMedia->getMedium("Steel");
659  if ( ! mSteel ) Fatal("Main", "FairMedium Steel not found");
660  geoBuild->createMedium(mSteel);
661  TGeoMedium* pSteel = gGeoMan->GetMedium("Steel");
662  if ( ! pSteel ) Fatal("Main", "Medium vacuum not found");
663  // ------ Create vacuum media -----------------------------------------------
664  FairGeoMedium* vacuum = geoMedia->getMedium("vacuum");
665  if ( ! vacuum ) Fatal("Main", "FairMedium vacuum not found");
666  geoBuild->createMedium(vacuum);
667  TGeoMedium* pMed0 = gGeoMan->GetMedium("vacuum");
668  if ( ! pMed0 ) Fatal("Main", "Medium vacuum not found");
669  //------------------------- VOLUMES -----------------------------------------
670  // -------------- Create geometry and top volume -------------------------
671  gGeoMan = (TGeoManager*)gROOT->FindObject("FAIRGeom");
672  //gGeoMan->SetName("BeamDetGeom");
673  TGeoVolume* top = new TGeoVolumeAssembly("TOP");
674  //gGeoMan->SetTopVolume(top);
675  TGeoVolume* beamdet = new TGeoVolumeAssembly("beamdet");
676  //TGeoVolume* MWPC = new TGeoVolumeAssembly("MWPC");
677  TGeoVolume* target = new TGeoVolumeAssembly("target");
678 
679  // ---------------- Target --------------------------------------------------
680  if (fSensitiveTargetIsSet) {
681  Double_t fTargetShellR = fTargetH2R + fTargetShellThicknessSide;
682  Double_t fTargetShellZ = fTargetH2Z/2 + fTargetShellThicknessZ;
683 
684  TGeoVolume *targetH2 = gGeoManager->MakeTube("targetBodyH2", pH2, 0, fTargetH2R, fTargetH2Z/2);
685  TGeoVolume *targetShell = gGeoManager->MakeTube("targetShell", pSteel, 0, fTargetShellR, fTargetShellZ);
686 
687  targetShell->AddNode(targetH2, 1, new TGeoCombiTrans(.0, .0, .0, fZeroRotation));
688  target->AddNode(targetShell, 1, new TGeoCombiTrans(.0,.0,.0, fZeroRotation));
689 
690  beamdet->AddNode(target, 1, new TGeoCombiTrans(transTargetX, transTargetY, transTargetZ, fZeroRotation));
691  }
692  // ----------------- MWPC ---------------------------------------------------
693  vector<TGeoVolume*> gasVol;
694  vector<TGeoVolume*> MWPC;
695  vector<TGeoVolume*> gasStrip;
696  vector<TGeoVolume*> gasPlane;
697  vector<TGeoVolume*> anodeWire;
698 
699  for(Int_t i = 0; i < fMWPCCount; i++) {
700  gasVol.push_back(gGeoManager->MakeBox("MWPCVol_" + fMWPCType[i], pMedCF4[i],
701  fGasVolX[i]/2 + abs(fGasPlaneXOffset[i]),
702  fGasVolY[i]/2 + abs(fGasPlaneYOffset[i]),
703  fGasVolZ[i]/2));
704  MWPC.push_back(gGeoManager->MakeBox("MWPC_" + fMWPCType[i], pMedKaptonWindow[i],
705  fGasVolX[i]/2 + abs(fGasPlaneXOffset[i]),
706  fGasVolY[i]/2 + abs(fGasPlaneYOffset[i]),
707  fGasVolZ[i]/2 + fKaptonWindowThickness[i]));
708  gasStrip.push_back(gGeoManager->MakeBox("gasStrip_" + fMWPCType[i], pMedCF4[i],
709  fGasStripX[i]/2, fGasStripY[i]/2, fGasStripZ[i]/2));
710  gasPlane.push_back(gGeoManager->MakeBox("gasPlane_" + fMWPCType[i], pMedCathode[i],
711  fGasVolX[i]/2, fGasVolY[i]/2, fGasStripZ[i]/2 + fCathodeThickness[i]));
712  anodeWire.push_back(gGeoManager->MakeTube("anodeWire_" + fMWPCType[i], pMedAnodeWire[i],
713  0, fAnodeWireDiameter[i] / 2, fGasStripY[i]/2));
714  }
715  // ---------------- ToF -----------------------------------------------------
716 
717  TGeoVolume* fictitiousFirstPlastic; // fictitious first plastic for correct data reading from ParContainer
718  fictitiousFirstPlastic = gGeoManager->MakeBox("plastic_Fictitous", pMed0,
719  fPlasticX[0]/2, fPlasticY[0]/2, fPlasticZ[0]/2);
720  vector<TGeoVolume*> plastic;
721  for(Int_t i = 0; i < fToFCount; i++) {
722  plastic.push_back(gGeoManager->MakeBox("plastic_" + fToFType[i], pMedPlastic[i],
723  fPlasticX[i]/2, fPlasticY[i]/2, fPlasticZ[i]/2));
724  }
725  //------------------ STRUCTURE ---------------------------------------------
726  // ----------------- MWPC ---------------------------------------------------
727  for(Int_t i = 0; i < fMWPCCount; i++) {
728  gasStrip[i]->AddNode(anodeWire[i], 1, new TGeoCombiTrans(0, 0, 0, f90XRotation));
729  Int_t gasCount = (fGasVolX[i]/2) / (fGasStripX[i]);
730  Double_t gasPosX;
731  for(Int_t i_gas = 1; i_gas <= 2*gasCount; i_gas++)
732  {
733  gasPosX = fGasVolX[i]/2 - fGasStripX[i] * (i_gas - 1) - fGasStripX[i]/2;
734  gasPlane[i]->AddNode(gasStrip[i], i_gas, new TGeoCombiTrans(gasPosX, 0, 0, fZeroRotation));
735  }
736 
737  if (fMWPCInvNumberingOrderX[i]) {
738  // X-plane insert
739  gasVol[i]->AddNode(gasPlane[i], 1, new TGeoCombiTrans(fGasPlaneXOffset[i],
740  0,
741  -fDistBetweenXandY[i] / 2,
742  fZeroRotation));
743  } else {
744  // X-plane insert
745  gasVol[i]->AddNode(gasPlane[i], 1, new TGeoCombiTrans(fGasPlaneXOffset[i],
746  0,
747  -fDistBetweenXandY[i] / 2,
748  f180ZRotation));
749  }
750  if (fMWPCInvNumberingOrderY[i]) {
751  // Y-plane insert
752  gasVol[i]->AddNode(gasPlane[i], 2, new TGeoCombiTrans(0,
753  fGasPlaneYOffset[i],
754  fDistBetweenXandY[i] / 2,
755  f90ZRotation));
756  } else {
757  // Y-plane insert
758  gasVol[i]->AddNode(gasPlane[i], 2, new TGeoCombiTrans(0,
759  fGasPlaneYOffset[i],
760  fDistBetweenXandY[i] / 2,
761  f270ZRotation));
762  }
763  MWPC[i]->AddNode(gasVol[i], 1, new TGeoCombiTrans(0, 0, 0, fZeroRotation));
764  beamdet->AddNode(MWPC[i], i+1, new TGeoCombiTrans(global_X, global_Y, fPositionMWPC[i], fGlobalRotation));
765  }
766  // ---------------- ToF -----------------------------------------------------
767  for(Int_t i = 0; i < fToFCount; i++) {
768  beamdet->AddNode(plastic[i], i + 1, new TGeoCombiTrans(global_X, global_Y, fPositionToF[i], fGlobalRotation));
769  }
770 
771  top->AddNode(beamdet, 1, new TGeoCombiTrans(global_X ,global_Y, global_Z, fGlobalRotation));
772  // --------------- Finish -----------------------------------------------
773  //gGeoMan->CloseGeometry();
774  //gGeoMan->CheckOverlaps(0.001);
775  //gGeoMan->PrintOverlaps();
776  //gGeoMan->Test();
777 
778  //gGeoManager = gGeoMan;
779 
780  TFile* geoFile = new TFile(geoFileName, "RECREATE");
781  top->Write();
782  geoFile->Close();
783  // --------------------------------------------------------------------------
784 }
785 //--------------------------------------------------------------------------------------------------
786 TString ERBeamDetSetup::GetToFType(Int_t number)
787 {
788  if (number >= fToFType.size() || number < 0)
789  LOG(FATAL) << "Wrong ToF number was requested!" << FairLogger::endl;
790  return fToFType[number];
791 }
792 //--------------------------------------------------------------------------------------------------
793 ClassImp(ERBeamDetSetup)
static void SetMWPCnumberingInvOrderY()
Sets the inverse order of wires numbering in an Y plane. The inverse order of numbering it is the ord...
static void SetMWPCnumberingInvOrderX()
Sets the inverse order of wires numbering in an X plane. The inverse order of numbering it is the ord...
static std::pair< unsigned short, unsigned short > GetMwpcAndPlaneNumbers(const TString &digi_branch_name)
Returns mwpc and plane indexies by branch name.
static void GetTransInMotherNode(TGeoNode const *node, Double_t trans[3])
Returns translation of the certain node in a mother node frame.