source: trunk/examples/advanced/xray_fluorescence/src/XrayFluoPlaneDetectorConstruction.cc@ 1237

Last change on this file since 1237 was 807, checked in by garnier, 17 years ago

update

File size: 18.8 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id: XrayFluoPlaneDetectorConstruction.cc
28// GEANT4 tag $Name: xray_fluo-V03-02-00
29//
30// Author: Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
31//
32// History:
33// -----------
34// 29 aug 2003 Alfonso Mantero Created
35// -------------------------------------------------------------------
36
37#include "XrayFluoPlaneDetectorConstruction.hh"
38#include "XrayFluoPlaneDetectorMessenger.hh"
39#include "XrayFluoSD.hh"
40#include "G4Material.hh"
41#include "G4ThreeVector.hh"
42#include "G4Box.hh"
43#include "G4Sphere.hh"
44#include "G4LogicalVolume.hh"
45#include "G4PVPlacement.hh"
46#include "G4TransportationManager.hh"
47#include "G4SDManager.hh"
48#include "G4RunManager.hh"
49#include "G4VisAttributes.hh"
50#include "G4Colour.hh"
51#include "G4ios.hh"
52#include "G4PVReplica.hh"
53#include "G4UserLimits.hh"
54#include "XrayFluoNistMaterials.hh"
55
56
57//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
58
59
60XrayFluoPlaneDetectorConstruction::XrayFluoPlaneDetectorConstruction()
61 : detectorType(0),planeGranularity(false), DeviceSizeX(0),
62 DeviceSizeY(0),DeviceThickness(0),
63 solidWorld(0),logicWorld(0),physiWorld(0),
64 solidHPGe(0),logicHPGe(0),physiHPGe(0),
65 solidScreen(0),logicScreen(0),physiScreen(0),
66 solidPlane (0),logicPlane(0),physiPlane (0),
67 solidOhmicPos(0),logicOhmicPos(0), physiOhmicPos(0),
68 solidOhmicNeg(0),logicOhmicNeg(0), physiOhmicNeg(0),
69 solidPixel(0),logicPixel(0), physiPixel(0),
70 screenMaterial(0),OhmicPosMaterial(0), OhmicNegMaterial(0),
71 pixelMaterial(0),planeMaterial(0),
72 defaultMaterial(0),HPGeSD(0)
73
74{
75 materials = XrayFluoNistMaterials::GetInstance();
76
77 DefineDefaultMaterials();
78
79 NbOfPixelRows = 1; // should be 1
80 NbOfPixelColumns = 1; // should be 1
81 NbOfPixels = NbOfPixelRows*NbOfPixelColumns;
82 PixelSizeXY = 5 * cm; // should be 5
83 PixelThickness = 3.5 * mm; //changed should be 3.5 mm
84
85 G4cout << "PixelThickness(mm): "<< PixelThickness/mm << G4endl;
86 G4cout << "PixelSizeXY(cm): "<< PixelSizeXY/cm << G4endl;
87
88 ContactSizeXY = 5 * cm; //should be the same as pixelSizeXY
89 planeThickness = 5 * cm;
90 planeSizeXY = 5. * m;
91
92 OhmicNegThickness = 0.005*mm;
93 OhmicPosThickness = 0.005*mm;
94
95 screenThickness = 5 * mm;
96
97 ThetaHPGe = 0. * deg;
98 PhiHPGe = 0. * deg;
99
100
101 DistDe = 0.5 * m;
102
103 distScreen = DistDe + (screenThickness+PixelThickness)/2+OhmicPosThickness ;
104
105 grainDia = 1 * mm;
106
107
108 PixelCopyNb=0;
109 grainCopyNb=0;
110 G4String defaultDetectorType = "sili";
111 ComputeApparateParameters();
112 SetDetectorType(defaultDetectorType);
113
114 // create commands for interactive definition of the apparate
115
116 detectorMessenger = new XrayFluoPlaneDetectorMessenger(this);
117 G4cout << "XrayFluoPlaneDetectorConstruction created" << G4endl;
118}
119//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
120
121
122XrayFluoPlaneDetectorConstruction* XrayFluoPlaneDetectorConstruction::instance = 0;
123
124XrayFluoPlaneDetectorConstruction* XrayFluoPlaneDetectorConstruction::GetInstance()
125{
126 if (instance == 0)
127 {
128 instance = new XrayFluoPlaneDetectorConstruction;
129
130 }
131 return instance;
132}
133
134void XrayFluoPlaneDetectorConstruction::SetDetectorType(G4String type)
135{
136
137 if (type=="sili")
138 {
139 detectorType = XrayFluoSiLiDetectorType::GetInstance();
140 }
141 else if (type=="hpge")
142 {
143 detectorType = XrayFluoHPGeDetectorType::GetInstance();
144 }
145 else
146 {
147 G4String excep = type + "detector type unknown";
148 G4Exception(excep);
149 }
150}
151
152XrayFluoVDetectorType* XrayFluoPlaneDetectorConstruction::GetDetectorType()
153{
154 return detectorType;
155}
156
157//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
158
159XrayFluoPlaneDetectorConstruction::~XrayFluoPlaneDetectorConstruction()
160
161{
162 delete detectorMessenger;
163 delete detectorType;
164 G4cout << "XrayFluoPlaneDetectorConstruction deleted" << G4endl;
165}
166
167//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
168
169G4VPhysicalVolume* XrayFluoPlaneDetectorConstruction::Construct()
170{
171 return ConstructApparate();
172}
173//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
174
175void XrayFluoPlaneDetectorConstruction::DefineDefaultMaterials()
176{
177
178
179 //define materials of the apparate
180
181 planeMaterial = materials->GetMaterial("Anorthosite");
182 screenMaterial = materials->GetMaterial("Lead");
183 pixelMaterial = materials->GetMaterial("Silicon");
184 OhmicPosMaterial = materials->GetMaterial("Copper");
185 OhmicNegMaterial = materials->GetMaterial("Lead");
186 defaultMaterial = materials->GetMaterial("Galactic");
187
188
189}
190
191//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
192
193G4VPhysicalVolume* XrayFluoPlaneDetectorConstruction::ConstructApparate()
194{
195 // complete the apparate parameters definition
196
197 //ComputeApparateParameters();
198
199 //world
200
201 solidWorld = new G4Box("World", //its name
202 WorldSizeXY/2,WorldSizeXY/2,WorldSizeZ/2); //its size
203
204 logicWorld = new G4LogicalVolume(solidWorld, //its solid
205 defaultMaterial, //its material
206 "World"); //its name
207 physiWorld = new G4PVPlacement(0, //no rotation
208 G4ThreeVector(), //at (0,0,0)
209 "World", //its name
210 logicWorld, //its logical volume
211 0, //its mother volume
212 false, //no boolean operation
213 0); //copy number
214
215 //detector
216
217 solidHPGe = 0; physiHPGe = 0; logicHPGe=0;
218 solidPixel=0; logicPixel=0; physiPixel=0;
219
220 if (DeviceThickness > 0.)
221 {
222 solidHPGe = new G4Box("HPGeDetector", //its name
223 DeviceSizeX/2,DeviceSizeY/2,DeviceThickness/2);//size
224
225
226 logicHPGe = new G4LogicalVolume(solidHPGe, //its solid
227 defaultMaterial, //its material
228 "HPGeDetector"); //its name
229
230 zRotPhiHPGe.rotateX(PhiHPGe);
231 G4double x,y,z;
232
233 z = -1. * DistDe; //* std::cos(ThetaHPGe);
234 y = 0.*cm; //distScreen * std::sin(ThetaHPGe);
235 x = 0.*cm;
236
237 physiHPGe = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)),
238 "HPGeDetector", //its name
239 logicHPGe, //its logical volume
240 physiWorld, //its mother volume
241 false, //no boolean operation
242 0); //copy number
243 }
244 // Pixel
245
246
247
248
249 for ( G4int j=0; j < NbOfPixelColumns ; j++ )
250 { for ( G4int i=0; i < NbOfPixelRows ; i++ )
251 {
252 solidPixel=0; logicPixel=0; physiPixel=0;
253 if (PixelThickness > 0.)
254 solidPixel = new G4Box("Pixel",
255 PixelSizeXY/2,PixelSizeXY/2, PixelThickness/2);
256
257 logicPixel = new G4LogicalVolume(solidPixel,
258 pixelMaterial, //its material
259 "Pixel"); //its name
260
261 /*
262 zRotPhiHPGe.rotateX(PhiHPGe);
263 G4double x,y,z;
264 z = DistDe * std::cos(ThetaHPGe);
265 y =DistDe * std::sin(ThetaHPGe);
266 x = 0.*cm;*/
267 physiPixel = new G4PVPlacement(0,
268 G4ThreeVector(0,
269 i*PixelSizeXY,
270 j*PixelSizeXY ),
271 "Pixel",
272 logicPixel, //its logical volume
273 physiHPGe, //its mother volume
274 false, //no boolean operation
275 PixelCopyNb);//copy number
276
277
278
279
280
281
282 // OhmicNeg
283
284 solidOhmicNeg=0; logicOhmicNeg=0; physiOhmicNeg=0;
285
286 if (OhmicNegThickness > 0.)
287 { solidOhmicNeg = new G4Box("OhmicNeg", //its name
288 PixelSizeXY/2,PixelSizeXY/2,OhmicNegThickness/2);
289
290 logicOhmicNeg = new G4LogicalVolume(solidOhmicNeg, //its solid
291 OhmicNegMaterial, //its material
292 "OhmicNeg"); //its name
293
294 physiOhmicNeg = new G4PVPlacement(0,
295 G4ThreeVector
296 (0.,
297 0.,
298 (PixelThickness+OhmicNegThickness)/2),
299 "OhmicNeg", //its name
300 logicOhmicNeg, //its logical volume
301 physiHPGe, //its mother
302 false, //no boulean operat
303 PixelCopyNb); //copy number
304
305 }
306 // OhmicPos
307 solidOhmicPos=0; logicOhmicPos=0; physiOhmicPos=0;
308
309 if (OhmicPosThickness > 0.)
310 { solidOhmicPos = new G4Box("OhmicPos", //its name
311 PixelSizeXY/2,PixelSizeXY/2,OhmicPosThickness/2);
312
313 logicOhmicPos = new G4LogicalVolume(solidOhmicPos, //its solid
314 OhmicPosMaterial, //its material
315 "OhmicPos"); //its name
316
317 physiOhmicPos = new G4PVPlacement(0,
318 G4ThreeVector(0.,
319 0.,
320 (-PixelThickness-OhmicPosThickness)/2),
321 "OhmicPos",
322 logicOhmicPos,
323 physiHPGe,
324 false,
325 PixelCopyNb);
326
327 }
328
329 PixelCopyNb += PixelCopyNb;
330 G4cout << "PixelCopyNb: " << PixelCopyNb << G4endl;
331 }
332
333 }
334
335 // Screen
336
337 if (DeviceThickness > 0.)
338 {
339 solidScreen = new G4Box("DetectorScreen", //its name
340 screenSizeXY/2,screenSizeXY/2,screenThickness/2);//size
341
342
343 logicScreen = new G4LogicalVolume(solidScreen, //its solid
344 defaultMaterial, //its material
345 "DetectorScreen"); //its name
346
347 //zRotPhiHPGe.rotateX(PhiHPGe);
348 G4double x,y,z;
349 G4cout << "distScreen: "<< distScreen/m <<G4endl;
350 z = -1 * distScreen; //* std::cos(ThetaHPGe);
351 y = 0.*cm; //distScreen * std::sin(ThetaHPGe);
352 x = 0.*cm;
353 physiScreen = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)),
354 "DetectorScreen", //its name
355 logicScreen, //its logical volume
356 physiWorld, //its mother volume
357 false, //no boolean operation
358 0); //copy number
359 }
360
361 //Plane
362
363 if (planeGranularity) {
364
365 solidPlane=0; logicPlane=0; physiPlane=0;
366 if (planeThickness > 0.)
367 {
368 solidPlane = new G4Box("Plane", //its name
369 planeSizeXY/2,planeSizeXY/2,planeThickness/2);//size
370
371 logicPlane= new G4LogicalVolume(solidPlane, //its solid
372 defaultMaterial, //its material
373 "Plane"); //its name
374
375 physiPlane = new G4PVPlacement(0, //no rotation
376 G4ThreeVector(), //at (0,0,0)
377 "Plane", //its name
378 logicPlane, //its logical volume
379 physiWorld, //its mother volume
380 false, //no boolean operation
381 0); //copy number
382
383 }
384
385
386
387
388 G4int nbOfGrainsX = ((G4int)(planeSizeXY/grainDia)) -1 ;
389
390 // y dim of a max density plane is 2rn-(n-1)ar, wehere a = (1-(std::sqrt(3)/2)), n is
391 // number of rows and r the radius of the grain. so the Y-dim of the plane must
392 // be greater or equal to this. It results that nmust be <= (PlaneY-a)/(1-a).
393 // Max Y shift of the planes superimposing along Z axis is minor (2/std::sqrt(3)r)
394
395 G4double a = (1.-(std::sqrt(3.)/2.));
396 G4int nbOfGrainsY = (G4int) ( ((planeSizeXY/(grainDia/2.)) -a)/(2.-a) ) -1;
397
398 // same for the z axis, but a = 2 * (std::sqrt(3) - std::sqrt(2))/std::sqrt(3)
399
400 G4double b = 2. * (std::sqrt(3.) - std::sqrt(2.))/std::sqrt(3.);
401 G4int nbOfGrainsZ = (G4int) ( ((planeThickness/(grainDia/2.)) -b)/(2.-b) )-1;
402
403 if (planeThickness > 0.){
404
405 solidGrain=0; logicGrain=0; physiGrain=0;
406 solidGrain = new G4Sphere("Grain",0.,
407 grainDia/2,0., twopi, 0., pi);
408
409 logicGrain = new G4LogicalVolume(solidGrain,
410 planeMaterial, //its material
411 "Grain"); //its name
412 G4ThreeVector grainPosition;
413 G4double grainInitPositionX = 0;
414 G4double grainInitPositionY = 0;
415 G4double grainInitPositionZ = (-1.*planeThickness/2.+grainDia/2.);
416 G4double grainStepX = grainDia = 0;
417 G4double grainStepY = grainDia*(1.-(0.5-(std::sqrt(3.)/4.)));
418 G4double grainStepZ = grainDia*std::sqrt(2./3.);
419
420 for ( G4int k=0; k < nbOfGrainsZ ; k++ ) {
421 for ( G4int j=0; j < nbOfGrainsY ; j++ ) {
422 for ( G4int i=0; i < nbOfGrainsX ; i++ ) {
423
424 // Now we identify the layer and the row where the grain is , to place it in the right position
425
426
427
428 if (k%3 == 0) { // first or (4-multiple)th layer: structure is ABCABC
429 grainInitPositionY = (-1.*planeSizeXY/2.+grainDia/2.);
430 if (j%2 ==0) { //first or (3-multiple)th row
431 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia/2.);
432 }
433
434 else if ( ((j+1) % 2) == 0 ) {
435 grainInitPositionX = (-1.*planeSizeXY/2.+ grainDia);
436 }
437
438 }
439 else if ( ((k+2) % 3) == 0 ) { // B-layer
440
441 grainInitPositionY = ( (-1.*planeSizeXY/2.) + (grainDia/2.)*(1. + (1./std::sqrt(3.)) ) );
442
443 if (j%2 ==0) { //first or (3-multiple)th row
444 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia);
445 }
446
447 else if ( (j+1)%2 == 0 ) {
448 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia/2);
449 }
450
451 }
452
453 else if ( (k+1)%3 == 0 ) { // B-layer
454
455 grainInitPositionY = (-1.*planeSizeXY/2.+(grainDia/2.)*(1.+2./std::sqrt(3.)) );
456
457 if (j%2 ==0) { //first or (3-multiple)th row
458 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia/2.);
459 }
460
461 else if ( (j+1)%2 == 0 ) {
462 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia);
463 }
464
465 }
466
467 physiGrain = new G4PVPlacement(0,
468 G4ThreeVector( grainInitPositionX + i*grainStepX,
469 grainInitPositionY + j*grainStepY,
470 grainInitPositionZ + k*grainStepZ),
471 "Grain",
472 logicGrain, //its logical volume
473 physiPlane, //its mother volume
474 false, //no boolean operation
475 grainCopyNb);//copy number
476
477 grainCopyNb = grainCopyNb +1;
478 }
479 }
480 }
481 }
482 }
483 else {
484
485 solidPlane=0; logicPlane=0; physiPlane=0;
486 if (planeThickness > 0.)
487 {
488 solidPlane = new G4Box("Plane", //its name
489 planeSizeXY/2,planeSizeXY/2,planeThickness/2);//size
490
491 logicPlane= new G4LogicalVolume(solidPlane, //its solid
492 planeMaterial, //its material
493 "Plane"); //its name
494
495 physiPlane = new G4PVPlacement(0, //no rotation
496 G4ThreeVector(), //at (0,0,0)
497 "Plane", //its name
498 logicPlane, //its logical volume
499 physiWorld, //its mother volume
500 false, //no boolean operation
501 0); //copy number
502
503 }
504 }
505
506 G4SDManager* SDman = G4SDManager::GetSDMpointer();
507
508 if(!HPGeSD)
509 {
510 HPGeSD = new XrayFluoSD ("HPGeSD",this);
511 SDman->AddNewDetector(HPGeSD);
512 }
513
514
515 if (logicPixel)
516 {
517 logicPixel->SetSensitiveDetector(HPGeSD);
518 }
519
520 // Visualization attributes
521
522 logicWorld->SetVisAttributes (G4VisAttributes::Invisible);
523 G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
524 G4VisAttributes * yellow= new G4VisAttributes( G4Colour(255/255. ,255/255. ,51/255. ));
525 G4VisAttributes * red= new G4VisAttributes( G4Colour(255/255. , 0/255. , 0/255. ));
526 G4VisAttributes * blue= new G4VisAttributes( G4Colour(0/255. , 0/255. , 255/255. ));
527 G4VisAttributes * gray= new G4VisAttributes( G4Colour(128/255. , 128/255. , 128/255. ));
528 G4VisAttributes * lightGray= new G4VisAttributes( G4Colour(178/255. , 178/255. , 178/255. ));
529 yellow->SetVisibility(true);
530 yellow->SetForceSolid(true);
531 red->SetVisibility(true);
532 red->SetForceSolid(true);
533 blue->SetVisibility(true);
534 gray->SetVisibility(true);
535 gray->SetForceSolid(true);
536 lightGray->SetVisibility(true);
537 lightGray->SetForceSolid(true);
538 simpleBoxVisAtt->SetVisibility(true);
539
540 logicPixel->SetVisAttributes(red); //modified!!!
541 logicHPGe->SetVisAttributes(blue);
542
543 logicPlane->SetVisAttributes(lightGray);
544
545
546 logicScreen->SetVisAttributes(gray);
547 logicOhmicNeg->SetVisAttributes(yellow);
548 logicOhmicPos->SetVisAttributes(yellow);
549
550
551
552 if (planeGranularity) logicGrain->SetVisAttributes(gray);
553
554 //always return the physical World
555
556 PrintApparateParameters();
557
558 return physiWorld;
559}
560
561//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
562
563void XrayFluoPlaneDetectorConstruction::PrintApparateParameters()
564{
565 G4cout << "-----------------------------------------------------------------------"
566 << G4endl
567 << "The plane is a box whose size is: "
568 << G4endl
569 << planeThickness/cm
570 << " cm * "
571 << planeSizeXY/cm
572 << " cm * "
573 << planeSizeXY/cm
574 << " cm"
575 << G4endl
576 <<" Material: " << logicPlane->GetMaterial()->GetName()
577 <<G4endl
578 <<"The Detector is a slice " << DeviceThickness/(1.e-6*m) << " micron thick of " << pixelMaterial->GetName()
579 <<G4endl
580
581
582<<"-------------------------------------------------------------------------"
583 << G4endl;
584}
585//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
586
587void XrayFluoPlaneDetectorConstruction::UpdateGeometry()
588{
589
590 delete solidHPGe;
591 delete logicHPGe;
592 delete physiHPGe;
593 delete solidPixel;
594 delete logicPixel;
595 delete physiPixel;
596 delete solidOhmicNeg;
597 delete logicOhmicNeg;
598 delete physiOhmicNeg;
599 delete solidOhmicPos;
600 delete logicOhmicPos;
601 delete physiOhmicPos;
602 delete solidPlane;
603 delete logicPlane;
604 delete physiPlane;
605 delete solidScreen;
606 delete logicScreen;
607 delete physiScreen;
608 delete solidWorld;
609 delete logicWorld;
610 delete physiWorld;
611
612 zRotPhiHPGe.rotateX(-1.*PhiHPGe);
613 G4RunManager::GetRunManager()->DefineWorldVolume(ConstructApparate());
614}
615
616
617void XrayFluoPlaneDetectorConstruction::DeleteGrainObjects()
618{
619 if (planeGranularity) {
620 delete solidGrain;
621 delete logicGrain;
622 delete physiGrain;
623 }
624
625}
626void XrayFluoPlaneDetectorConstruction::SetPlaneMaterial(G4String newMaterial)
627{
628
629
630 G4cout << "Material!!!!" << newMaterial << G4cout;
631 logicPlane->SetMaterial(materials->GetMaterial(newMaterial));
632 PrintApparateParameters();
633
634}
635
636//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
637
638
639
640
641
642
643
644
645
646
647
Note: See TracBrowser for help on using the repository browser.