ModTypeZDC.cc 11.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//
// ********************************************************************
// * License and Disclaimer                                           *
// *                                                                  *
// * The  Geant4 software  is  copyright of the Copyright Holders  of *
// * the Geant4 Collaboration.  It is provided  under  the terms  and *
// * conditions of the Geant4 Software License,  included in the file *
// * LICENSE and available at  http://cern.ch/geant4/license .  These *
// * include a list of copyright holders.                             *
// *                                                                  *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work  make  any representation or  warranty, express or implied, *
// * regarding  this  software system or assume any liability for its *
// * use.  Please see the license in the file  LICENSE  and URL above *
// * for the full disclaimer and the limitation of liability.         *
// *                                                                  *
// * This  code  implementation is the result of  the  scientific and *
// * technical work of the GEANT4 collaboration.                      *
// * By using,  copying,  modifying or  distributing the software (or *
// * any work based  on the software)  you  agree  to acknowledge its *
// * use  in  resulting  scientific  publications,  and indicate your *
// * acceptance of all terms of the Geant4 Software license.          *
// ********************************************************************
//
// Michael Phipps
// For an explanation of the hierarchy scheme see: https://twiki.cern.ch/twiki/bin/view/Atlas/ZdcSimulation#Geometry_Implementation_Develope

#include "ModTypeZDC.hh"

#include "G4GeometryManager.hh"
#include "G4SolidStore.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4MaterialTable.hh"

#include "G4SDManager.hh"

#include "G4Box.hh"
#include "G4Para.hh"
#include "G4Tubs.hh"
#include "G4LogicalVolume.hh"
#include "G4PVPlacement.hh"
#include "G4SystemOfUnits.hh"
#include "G4VisAttributes.hh"
#include "G4Colour.hh"

#include <stdio.h>

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

52
ModTypeZDC::ModTypeZDC(const int cn, G4ThreeVector& pos,
53
	      G4LogicalVolume* mother)
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
  : m_modNum( cn ),  m_pos( pos ), m_logicMother( mother )
{}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

	ModTypeZDC::ModTypeZDC(const int cn, ModTypeZDC* right)
		: m_modNum( cn )
	{
		m_nAbsorbers 			 = right->m_nAbsorbers;
		m_pos				 			 = new G4ThreeVector(right->m_pos);
		m_fiberDim 	 			 = new G4ThreeVector(right->m_fiberDim);
		m_absDim 		 			 = new G4ThreeVector(right->m_absDim);
		m_HousingThickness = right->m_HousingThickness;
		m_GapThickness 		 = right->m_GapThickness;
		m_logicMother			 = right->m_logicMother;
	}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

ModTypeZDC::ModTypeZDC(const int cn, G4LogicalVolume* mother)
  : m_modNum( cn ), m_logicMother( mother )
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
{}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

ModTypeZDC::ModTypeZDC()
  : m_modNum( 0 ), m_pos(G4ThreeVector()), m_logicMother(NULL),
{}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

ModTypeZDC::~ModTypeZDC()
{}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

void ModTypeZDC::Construct(){
  DefineMaterials();
  ConstructDetector();
}


//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

void ModTypeZDC::ConstructDetector()
{
100
101
102
103
104
105
106
107
	bool BUFFER, CLADDING;
	G4double fiberMaxDia;
	//FiberDimension x=Core, y=Cladding, z=Buffer diameters
	BUFFER   = ( m_fiberDiam->z() == 0.0 ) ? false : true;
	CLADDING = ( m_fiberDiam->y() == 0.0 ) ? false : true;
	if 		 (BUFFER)  fiberMaxDia = m_fiberDiam->z();
	else if(CLADDING)fiberMaxDia = m_fiberDiam->y();
	else						 fiberMaxDia = m_fiberDiam->x();
108
109

  // geometric constants
110
  float xStartStrip; // middle of left most strip -- note this strip doesn't actually exist since the sets on the edge have 5 strips instead of 6
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  float stripPitch;  // distance between center of each rod ie) the diameter of one strip
  float zStartW; 		 // position where first tungsten plate gets placed
  float zStartRad; 	 // position where first radiator gap gets placed

  float modLengthZ = m_absDim->z()*m_nAbsorbers + m_GapThickness*m_nAbsorbers;
  zPitch = m_absDim->z()+ m_GapThickness;
  zStartW = -1*modLengthZ/2 + m_GapThickness + m_absDim->z()/2;
  zStartRad = -1*modLengthZ/2 + m_GapThickness/2;
  stripPitch = fiberMaxDia;
  xStartStrip = -1*(m_absDim->x()%fiberMaxDia)*stripPitch/2 + stripPitch/2;
  float modWidthX = (m_absDim->x()%fiberMaxDia)*stripPitch;
  if (modWidthX == 0) modWidthX = m_absDim->x(); // the case where you are defining a solid absorber block with no active channels
  float modHeightY = m_absDim->y();
  float boxLengthZ = modLengthZ + m_HousingThickness*2;
125
126

  //  std::cout << " modcustom boxLengthZ " << boxLengthZ << std::endl;
127
128
129
130
  float boxWidthX = modWidthX + m_HousingThickness*2;
  float boxHeightY = modHeightY + m_HousingThickness*2;


131

132
  //----------------------------------------------
133
134
  // Housing
  //----------------------------------------------
135

136
137
138
139
  m_HousingBox     = new G4Box("SteelCasing", boxWidthX*mm/2.0 ,boxHeightY*mm/2.0  , boxLengthZ*mm/2.0);
  m_ModuleBox      = new G4Box("ModuleCasing", modWidthX*mm/2.0 ,modHeightY*mm/2.0  , modLengthZ*mm/2.0);
  m_HousingLogical = new G4LogicalVolume(m_SteelBox           ,m_matHousing, "Steel_Logical");
  m_ModuleLogical  = new G4LogicalVolume(m_ModuleBox          ,m_materials->Air, "Module_Logical");
140
141

  char name[256];
142
  int cn = m_modNum;
143
  sprintf(name,"ZDC%d_Case_Physical", m_modNum);
144
145
  G4RotationMatrix* nullRotation = new G4RotationMatrix();
  G4ThreeVector  pos;
146
  pos = G4ThreeVector(0,0,0);
147
  m_HousingPhysical = new G4PVPlacement(nullRotation,m_pos,m_HousingLogical,name,m_logicMother,false,cn,checkOverlaps);
148

149
150
  sprintf(name,"ZDC%d_Air_Physical", cn);
  m_ModulePhysical = new G4PVPlacement(nullRotation,pos,m_ModuleLogical,name,m_HousingLogical,false,cn,checkOverlaps);
151

152
153
154
155
  G4VisAttributes* moduleColor = new G4VisAttributes( G4Colour::Gray() );
  m_ModuleLogical->SetVisAttributes( moduleColor );


156
  //----------------------------------------------
157
158
159
  // Quartz
  //----------------------------------------------

160
161
162
163
164
165
166
167
168
169
170
171
172
  m_StripTube =
		new G4Tubs( "Fiber_Core_Tube",
							  0.0*mm,
								(m_fiberDiam->x()/2.0-0.005)*mm,
								modHeightY*mm/2.0 ,
								0.0*deg,
								360.0*deg);
  m_StripLogical =
		new G4LogicalVolume(m_StripTube,
												m_materials->pQuartz,
												"FiberCore_Logical");

	G4VisAttributes* quartzColor  = new G4VisAttributes( G4Colour::Cyan() );
173
  quartzColor->SetForceSolid(true);
174
  m_StripLogical->SetVisAttributes( quartzColor );
175
176
177
178
179
180
181
182
183
184
185
186
187
188

  if ( CLADDING ) {

    m_CladdingTube  =
			new G4Tubs( "Fiber_Cladding_Tube",
									m_fiberDiam->x()/2.0*mm - (0.005)*mm,
									(m_fiberDiam->x()/2.0*mm-0.0005*mm+m_fiberDiam->y())*mm, modHeightY*mm/2.0, 0.0*deg,
									360.0*deg);
    m_CladdingLogical =
			new G4LogicalVolume(m_CladdingTube,
													m_materials->pQuartz,
													"Fiber_Cladding_Logical");
		m_CladdingLogical->SetVisAttributes( quartzColor );
  }
189
190


191
  //----------------------------------------------
192
193
194
195
  // Plates
  //----------------------------------------------


196
197
198
199
200
201
202
203
204
205
206
  m_W = new G4Box("W",
									modWidthX*mm/2.0 ,
									m_absDim->y()/2.0,
									m_absDim->y()/2.0);
  m_WLogical =
		new G4LogicalVolume(m_W,
												m_matAbsorber,
												"W_Logical");

  G4VisAttributes* airColor = new G4VisAttributes( G4Colour::White() );
  airColor->SetForceSolid(true);
207
  m_ModuleLogical->SetVisAttributes( airColor );
208

209
  G4VisAttributes* absorberColor = new G4VisAttributes( G4Colour::Red() );
210
  absorberColor->SetForceSolid(true);
211
  m_WLogical->SetVisAttributes( absorberColor );
212

213
214
215
216
217
218
219
  int modOffset = 100000; //  just a convention to organize copy numbers for different modules

  // Quartz strip dimensions: radiator gap, group, strip
  // populate all 8 modules with quartz strips
  G4RotationMatrix* stripRotation = new G4RotationMatrix();
  stripRotation->rotateX(90.*deg);
  cn = 0;
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
	m_FiberCorePhysical.resize(m_nAbsorbers + 1);
	m_FiberCladdingPhysical.resize(m_nAbsorbers + 1);
  for(int K = 0; K < m_nAbsorbers + 1; K++ ){
    for(int M = 0; M < (m_absDim->x()%fiberMaxDia); M++ ){

	  	sprintf(name,"ZDC%d_Core%d", m_modNum, cn);
      m_CorePhysical.push_back( new G4PVPlacement(
															  stripRotation,
																G4ThreeVector((xStartStrip+(M*stripPitch))*mm,0,(zStartRad+K*zPitch)*mm),
																m_StripLogical,
																name,
																m_ModuleLogical,
																false,
																cn,
																checkOverlaps) );
      if ( CLADDING ) {

				sprintf(name,"ZDC%d_Cladding%d", m_modNum, cn);
				m_FiberCladdingPhysical.push_back(new G4PVPlacement(
																					stripRotation,
																					G4ThreeVector((xStartStrip+(M*stripPitch))*mm,0,(zStartRad+K*zPitch)*mm),m_CladdingLogical,
																					name,
																					m_ModuleLogical,
																					false,
																					cn,
																					checkOverlaps) );
246
247
248
249
      }
      ++cn;
    }
  }
250
  cn = 0;
251
  //  W plates (non pixel modules): Physical plates that span length of each absorber gap
252
  for(int K=0;K<m_nAbsorbers;K++) {    // 11 layers of plates
253
    char volName[256];
254
255
256
257
258
259
260
261
    sprintf(volName,"ZDC%d_Absorber%d",m_modNum, K);
    m_WPhysical.push_back( new G4PVPlacement(nullRotation,
													 G4ThreeVector(0,0,zStartW*mm+K*zPitch*mm),
													 m_WLogical,name,
													 m_ModuleLogical,
													 false,
													 cn,
													 checkOverlaps) );
262
263
    ++cn;
  }
264
265

  //----------------------------------------------
266
  // Define Surface/Border Properties
267
  //----------------------------------------------
268
269
  DefineBorderProperties();

270
  //----------------------------------------------
271
272
273
274
275
  // SD and Scoring Volumes
  //----------------------------------------------
  G4SDManager* SDman = G4SDManager::GetSDMpointer();

  //Note one SD object for each module
276
277
278
279
280
281
282
  char fiberSDname[256];
  sprintf( fiberSDname, "ZDC%d_SD", m_modNum+1);
  FiberSD* aFiberSD = new FiberSD( fiberSDname, m_modNum );
  aFiberSD->HistInitialize();
  SDman->AddNewDetector( aFiberSD );
  m_StripLogical->SetSensitiveDetector( aFiberSD );

283

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
  std::cout << "ModTypeZDC construction finished: SD name " << fiberSDname << std::endl;

}

void ModTypeZDC::SetHousingMaterial(G4String material)
{
	material.toLower();
			 if( material == "steel")  ) m_matHousing = m_materials->Steel;
	else if( material == "aluminum") m_matHousing = m_materials->Al;
	else G4cout << "Invalid housing material selection, defaulting to steel" << G4endl;
	}
}

void ModTypeZDC::SetAbsorberMaterial(G4String material)
{
	material.toLower();
300
			 if( material == "pure") 		 ) m_matHousing = m_materials->pureW;
301
302
	else if( material == "composite" ) m_matHousing = m_materials->NiW;
	else G4cout << "Invalid absorber material selection, defaulting to composite" << G4endl;
303
}