ModTypeZDC.cc 11.4 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
//
// ********************************************************************
// * 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"
30
#include "FiberSD.hh"
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

#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......

53
ModTypeZDC::ModTypeZDC(const int cn, G4LogicalVolume* mother, G4ThreeVector* pos)
54
  : m_modNum( cn ), m_pos( pos ), m_fiberDiam (new G4ThreeVector(1.5,0.,0.)),
55
	  m_absDim(new G4ThreeVector(90.,180.,11.)), m_logicMother( mother )
56
57
{
	m_materials = Materials::getInstance();
58
59
	m_matAbsorber = m_materials->NiW;
	m_matHousing  = m_materials->Steel;
60
}
61
62
63

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

64
65
66
ModTypeZDC::ModTypeZDC(const int cn, ModTypeZDC* right)
	: m_modNum( cn )
{
67
		m_nAbsorbers 			 = right->m_nAbsorbers;
68
69
70
		m_pos				 			 = new G4ThreeVector(*right->m_pos);
		m_fiberDiam 	 		 = new G4ThreeVector(*right->m_fiberDiam);
		m_absDim 		 			 = new G4ThreeVector(*right->m_absDim);
71
72
		m_HousingThickness = right->m_HousingThickness;
		m_GapThickness 		 = right->m_GapThickness;
73
74
75
76
		OPTICAL 					 = right->OPTICAL;
		CHECK_OVERLAPS 		 = right->CHECK_OVERLAPS;
		m_matAbsorber 		 = right->m_matAbsorber;
		m_matHousing			 = right->m_matHousing;
77
		m_logicMother			 = right->m_logicMother;
78
79
		m_materials				 = right->m_materials;
}
80
81
82
83

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

ModTypeZDC::ModTypeZDC()
84
85
86
87
88
  : m_modNum( 0 ), m_pos(new G4ThreeVector(0.,0.,0.)), m_fiberDiam (new G4ThreeVector(1.5,0.,0.)),
	m_absDim (new G4ThreeVector(90.,180.,11.)), m_logicMother(NULL)
{
	m_materials = Materials::getInstance();
}
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

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

ModTypeZDC::~ModTypeZDC()
{}

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

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


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

void ModTypeZDC::ConstructDetector()
{
106
107
108
109
110
111
112
113
	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();
114

115

116
  // geometric constants
117
	float zPitch;
118
  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
119
120
121
122
  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

123
  float modLengthZ = m_absDim->z()*m_nAbsorbers + m_GapThickness*(m_nAbsorbers + 1 );
124
125
126
127
  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;
128
129
  xStartStrip = -1*floor(m_absDim->x()/fiberMaxDia)*stripPitch/2 + stripPitch/2;
  float modWidthX = floor(m_absDim->x()/fiberMaxDia)*stripPitch;
130
131
  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();
132
133
	float boxWidthX  = modWidthX  + m_HousingThickness*2;
	float boxHeightY = modHeightY + m_HousingThickness*2;
134
  float boxLengthZ = modLengthZ + m_HousingThickness*2;
135
136


137
  //----------------------------------------------
138
139
  // Housing
  //----------------------------------------------
140

141
  m_HousingBox     = new G4Box("SteelCasing",  boxWidthX*mm/2.0 ,boxHeightY*mm/2.0  , boxLengthZ*mm/2.0);
142
  m_ModuleBox      = new G4Box("ModuleCasing", modWidthX*mm/2.0 ,modHeightY*mm/2.0  , modLengthZ*mm/2.0);
143
144
  m_HousingLogical = new G4LogicalVolume(m_HousingBox           ,m_matHousing, 		 "Housing_Logical");
  m_ModuleLogical  = new G4LogicalVolume(m_ModuleBox            ,m_materials->Air, "Module_Logical");
145
146

  char name[256];
147
  int cn = m_modNum;
148
  sprintf(name,"ZDC%d_Case_Physical", m_modNum);
149
150
  G4RotationMatrix* nullRotation = new G4RotationMatrix();
  G4ThreeVector  pos;
151
  pos = G4ThreeVector(0,0,0);
152
  m_HousingPhysical = new G4PVPlacement(nullRotation,*m_pos,m_HousingLogical,name,m_logicMother,false,cn,CHECK_OVERLAPS);
153

154
  sprintf(name,"ZDC%d_Air_Physical", cn);
155
  m_ModulePhysical = new G4PVPlacement(nullRotation,pos,m_ModuleLogical,name,m_HousingLogical,false,cn,CHECK_OVERLAPS);
156

157
158
159
160
161
162
163
  G4VisAttributes* housingColor = new G4VisAttributes( );
	housingColor->SetColor(1.,1.,1.,.4);
  m_HousingLogical->SetVisAttributes( housingColor );


  G4VisAttributes* moduleColor = new G4VisAttributes( );
	moduleColor->SetColor(0.,0.,1.,.2);
164
165
166
  m_ModuleLogical->SetVisAttributes( moduleColor );


167
  //----------------------------------------------
168
169
170
  // Quartz
  //----------------------------------------------

171
  m_FiberCoreTube =
172
173
174
175
176
177
		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);
178
179
  m_FiberCoreLogical =
		new G4LogicalVolume(m_FiberCoreTube,
180
181
182
183
												m_materials->pQuartz,
												"FiberCore_Logical");

	G4VisAttributes* quartzColor  = new G4VisAttributes( G4Colour::Cyan() );
184
  quartzColor->SetForceSolid(true);
185
  m_FiberCoreLogical->SetVisAttributes( quartzColor );
186
187
188
189
190
191
192
193
194
195
196
197
198
199

  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 );
  }
200

201
  //----------------------------------------------
202
203
204
  // Plates
  //----------------------------------------------

205
206
207
  m_W = new G4Box("W",
									modWidthX*mm/2.0 ,
									m_absDim->y()/2.0,
208
									m_absDim->z()/2.0);
209
210
211
212
213
  m_WLogical =
		new G4LogicalVolume(m_W,
												m_matAbsorber,
												"W_Logical");

214
  G4VisAttributes* absorberColor = new G4VisAttributes( G4Colour::Red() );
215
  absorberColor->SetForceSolid(true);
216
  m_WLogical->SetVisAttributes( absorberColor );
217

218
219
220
221
222
  // Quartz strip dimensions: radiator gap, group, strip
  // populate all 8 modules with quartz strips
  G4RotationMatrix* stripRotation = new G4RotationMatrix();
  stripRotation->rotateX(90.*deg);
  cn = 0;
223
224
225
	m_FiberCorePhysical.resize(m_nAbsorbers + 1);
	m_FiberCladdingPhysical.resize(m_nAbsorbers + 1);
  for(int K = 0; K < m_nAbsorbers + 1; K++ ){
226
    for(int M = 0; M < (int)floor(m_absDim->x()/fiberMaxDia); M++ ){
227
228

	  	sprintf(name,"ZDC%d_Core%d", m_modNum, cn);
229
      m_FiberCorePhysical.at(K).push_back( new G4PVPlacement(
230
231
															  stripRotation,
																G4ThreeVector((xStartStrip+(M*stripPitch))*mm,0,(zStartRad+K*zPitch)*mm),
232
																m_FiberCoreLogical,
233
234
235
236
																name,
																m_ModuleLogical,
																false,
																cn,
237
																CHECK_OVERLAPS) );
238
239
240
      if ( CLADDING ) {

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

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

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

284

285
286
287
288
289
290
291
  std::cout << "ModTypeZDC construction finished: SD name " << fiberSDname << std::endl;

}

void ModTypeZDC::SetHousingMaterial(G4String material)
{
	material.toLower();
292
			 if( material == "steel"   ) m_matHousing = m_materials->Steel;
293
294
295
296
297
298
299
	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
301
			 if( material == "pure"  		 ) m_matAbsorber = m_materials->pureW;
	else if( material == "composite" ) m_matAbsorber = m_materials->NiW;
302
	else G4cout << "Invalid absorber material selection, defaulting to composite" << G4endl;
303
}