source: trunk/examples/advanced/xray_fluorescence/src/XrayFluoMercuryDetectorConstruction.cc @ 1288

Last change on this file since 1288 was 807, checked in by garnier, 16 years ago

update

File size: 16.1 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: XrayFluoMercuryDetectorConstruction.cc
28// GEANT4 tag $Name: XrayFluo-V05-02-06
29//
30// Author: Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
31//
32// History:
33// -----------
34// 08 Sep 2003 Alfonso Mantero Created
35// -------------------------------------------------------------------
36
37#include "XrayFluoMercuryDetectorConstruction.hh"
38#include "XrayFluoMercuryDetectorMessenger.hh"
39#include "XrayFluoSD.hh"
40#include "G4Material.hh"
41#include "G4ThreeVector.hh"
42#include "G4Box.hh"
43#include "G4Sphere.hh"
44#include "G4Tubs.hh"
45#include "G4LogicalVolume.hh"
46#include "G4PVPlacement.hh"
47#include "G4TransportationManager.hh"
48#include "G4SDManager.hh"
49#include "G4RunManager.hh"
50#include "G4VisAttributes.hh"
51#include "G4Colour.hh"
52#include "G4ios.hh"
53#include "G4PVReplica.hh"
54#include "G4UserLimits.hh"
55#include "XrayFluoNistMaterials.hh"
56
57
58//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
59
60
61XrayFluoMercuryDetectorConstruction::XrayFluoMercuryDetectorConstruction()
62  : detectorType(0),mercuryGranularity(false), DeviceSizeX(0),
63    DeviceSizeY(0),DeviceThickness(0),
64    solidWorld(0),logicWorld(0),physiWorld(0),
65    solidHPGe(0),logicHPGe(0),physiHPGe(0),
66    solidScreen(0),logicScreen(0),physiScreen(0),
67    solidMercury (0),logicMercury(0),physiMercury (0),
68    solidOhmicPos(0),logicOhmicPos(0), physiOhmicPos(0),
69    solidOhmicNeg(0),logicOhmicNeg(0), physiOhmicNeg(0),
70    solidPixel(0),logicPixel(0), physiPixel(0),
71    screenMaterial(0),OhmicPosMaterial(0), OhmicNegMaterial(0),
72    pixelMaterial(0),mercuryMaterial(0),
73    defaultMaterial(0),HPGeSD(0)
74 
75{ 
76  materials = XrayFluoNistMaterials::GetInstance();
77
78  DefineDefaultMaterials();
79
80  NbOfPixelRows     =  1; // should be 1
81  NbOfPixelColumns  =  1; // should be 1
82  NbOfPixels        =  NbOfPixelRows*NbOfPixelColumns;
83  PixelSizeXY       = std::sqrt(40.) * mm *0.5e6; // should be std::sqrt(40) * mm
84  PixelThickness = 3.5 * mm * 1e6; //should be 3.5 mm
85 
86  G4cout << "PixelThickness(mm): "<< PixelThickness/mm << G4endl;
87  G4cout << "PixelSizeXY(cm): "<< PixelSizeXY/cm << G4endl;
88 
89  ContactSizeXY  = std::sqrt(40.) * mm * 0.5e6; //should be the same as PixelSize or lower
90
91  mercuryDia = 2 * 4880 * km ;
92  sunDia =  1390000 * km ;
93  mercurySunDistance = 57910000 * km ;
94
95 
96  OhmicNegThickness = 0.005*mm *0.5e6 ;
97  OhmicPosThickness = 0.005*mm *0.5e6 ;
98 
99  screenThickness = 5 * mm *0.5e6;
100 
101  ThetaHPGe = 135. * deg ;
102  PhiHPGe = 225. * deg  ;
103 
104 
105  distDe = (mercuryDia/2 + 400 * km);
106 
107  distScreen = distDe + (screenThickness+PixelThickness)/2+OhmicPosThickness ;
108
109  distOptic = distDe - 1.*m * 1e5;//!!!
110 
111  opticThickness = 1.* cm *0.5e6;
112  opticDia = 21. * cm *0.5e6; 
113  opticAperture = 1. * deg;
114
115  PixelCopyNb=0;
116  grainCopyNb=0;
117  G4String defaultDetectorType = "sili";
118  ComputeApparateParameters();
119  SetDetectorType(defaultDetectorType);
120 
121  // create commands for interactive definition of the apparate
122 
123  detectorMessenger = new XrayFluoMercuryDetectorMessenger(this);
124  G4cout << "XrayFluoMercuryDetectorConstruction created" << G4endl;
125}
126//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
127
128
129XrayFluoMercuryDetectorConstruction* XrayFluoMercuryDetectorConstruction::instance = 0;
130
131XrayFluoMercuryDetectorConstruction* XrayFluoMercuryDetectorConstruction::GetInstance()
132{
133  if (instance == 0)
134    {
135      instance = new XrayFluoMercuryDetectorConstruction;
136     
137    }
138  return instance;
139}
140
141void XrayFluoMercuryDetectorConstruction::SetDetectorType(G4String type)
142{
143 
144  if (type=="sili")
145    {
146      detectorType = XrayFluoSiLiDetectorType::GetInstance();
147    }
148  else if (type=="hpge")
149    {
150      detectorType = XrayFluoHPGeDetectorType::GetInstance();
151    }
152  else 
153    {
154      G4String excep = type + "detector type unknown";
155      G4Exception(excep);
156    }
157}
158
159XrayFluoVDetectorType* XrayFluoMercuryDetectorConstruction::GetDetectorType()
160{
161  return detectorType;
162}
163
164//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
165
166XrayFluoMercuryDetectorConstruction::~XrayFluoMercuryDetectorConstruction()
167 
168{ 
169  delete detectorMessenger;
170  delete detectorType;
171  G4cout << "XrayFluoMercuryDetectorConstruction deleted" << G4endl;
172}
173
174//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
175
176G4VPhysicalVolume* XrayFluoMercuryDetectorConstruction::Construct()
177{
178  return ConstructApparate();
179}
180//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
181
182void XrayFluoMercuryDetectorConstruction::DefineDefaultMaterials()
183{
184 
185 
186  //define materials of the apparate
187 
188  mercuryMaterial = materials->GetMaterial("Anorthosite");
189  screenMaterial = materials->GetMaterial("Lead");
190  pixelMaterial = materials->GetMaterial("Silicon");
191  OhmicPosMaterial = materials->GetMaterial("Copper");
192  OhmicNegMaterial = materials->GetMaterial("Lead");
193  defaultMaterial = materials->GetMaterial("Galactic");
194 
195 
196}
197
198//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
199
200G4VPhysicalVolume* XrayFluoMercuryDetectorConstruction::ConstructApparate()
201{
202  // complete the apparate parameters definition
203 
204  ComputeApparateParameters();
205 
206  //world
207 
208  solidWorld = new G4Box("World",                               //its name
209                         WorldSizeXY/2,WorldSizeXY/2,WorldSizeZ/2);     //its size
210 
211  logicWorld = new G4LogicalVolume(solidWorld,          //its solid
212                                   defaultMaterial,     //its material
213                                   "World");            //its name
214  physiWorld = new G4PVPlacement(0,                     //no rotation
215                                 G4ThreeVector(),       //at (0,0,0)
216                                 "World",               //its name
217                                 logicWorld,            //its logical volume
218                                 0,                     //its mother  volume
219                                 false,                 //no boolean operation
220                                 0);                    //copy number
221 
222  //detector
223 
224  solidHPGe = 0;  physiHPGe = 0;  logicHPGe=0;
225  solidPixel=0; logicPixel=0; physiPixel=0;
226 
227  if (DeviceThickness > 0.) 
228    {
229      solidHPGe = new G4Box("HPGeDetector",             //its name
230                            DeviceSizeX/2,DeviceSizeY/2,DeviceThickness/2);//size
231     
232     
233      logicHPGe = new G4LogicalVolume(solidHPGe,        //its solid
234                                      defaultMaterial,  //its material
235                                      "HPGeDetector");  //its name
236     
237      zRotPhiHPGe.rotateX(PhiHPGe);
238      G4double x,y,z;
239     
240      z = distDe * std::cos(ThetaHPGe);
241      y = distScreen * std::sin(ThetaHPGe);
242      x = 0.*cm;
243     
244      physiHPGe = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)), 
245                                    "HPGeDetector",     //its name
246                                    logicHPGe,  //its logical volume
247                                    physiWorld, //its mother  volume
248                                    false,              //no boolean operation
249                                    0);         //copy number
250    }
251  // Pixel
252 
253 
254 
255 
256  for ( G4int j=0; j < NbOfPixelColumns ; j++ )
257    { for ( G4int i=0; i < NbOfPixelRows ; i++ )
258      { 
259        solidPixel=0; logicPixel=0;   physiPixel=0;
260        if (PixelThickness > 0.)
261          solidPixel = new G4Box("Pixel",                       
262                                 PixelSizeXY/2,PixelSizeXY/2, PixelThickness/2);
263       
264        logicPixel = new G4LogicalVolume(solidPixel,   
265                                         pixelMaterial, //its material
266                                         "Pixel");              //its name
267       
268        /*
269          zRotPhiHPGe.rotateX(PhiHPGe);
270          G4double x,y,z;
271          z = distDe * std::cos(ThetaHPGe);
272          y =distDe * std::sin(ThetaHPGe);
273          x = 0.*cm;*/ 
274        physiPixel = new G4PVPlacement(0,             
275                                       G4ThreeVector(0,
276                                                     i*PixelSizeXY, 
277                                                     j*PixelSizeXY ),
278                                       "Pixel", 
279                                       logicPixel,       //its logical volume
280                                       physiHPGe, //its mother  volume
281                                       false,    //no boolean operation
282                                       PixelCopyNb);//copy number
283       
284       
285       
286       
287       
288       
289        // OhmicNeg
290       
291        solidOhmicNeg=0; logicOhmicNeg=0; physiOhmicNeg=0; 
292       
293        if (OhmicNegThickness > 0.) 
294          { solidOhmicNeg = new G4Box("OhmicNeg",               //its name
295                                      PixelSizeXY/2,PixelSizeXY/2,OhmicNegThickness/2); 
296         
297          logicOhmicNeg = new G4LogicalVolume(solidOhmicNeg,    //its solid
298                                              OhmicNegMaterial, //its material
299                                              "OhmicNeg");      //its name
300         
301          physiOhmicNeg = new G4PVPlacement(0,
302                                            G4ThreeVector
303                                            (0.,
304                                             0.,
305                                             (PixelThickness+OhmicNegThickness)/2),
306                                            "OhmicNeg",        //its name
307                                            logicOhmicNeg,     //its logical volume
308                                            physiHPGe,        //its mother
309                                            false,             //no boulean operat
310                                            PixelCopyNb);                //copy number
311         
312          }
313        // OhmicPos
314        solidOhmicPos=0; logicOhmicPos=0; physiOhmicPos=0; 
315       
316        if (OhmicPosThickness > 0.) 
317          { solidOhmicPos = new G4Box("OhmicPos",               //its name
318                                      PixelSizeXY/2,PixelSizeXY/2,OhmicPosThickness/2); 
319         
320          logicOhmicPos = new G4LogicalVolume(solidOhmicPos,    //its solid
321                                              OhmicPosMaterial, //its material
322                                              "OhmicPos");      //its name
323         
324          physiOhmicPos = new G4PVPlacement(0, 
325                                            G4ThreeVector(0.,
326                                                          0.,
327                                                          (-PixelThickness-OhmicPosThickness)/2), 
328                                            "OhmicPos", 
329                                            logicOhmicPos,
330                                            physiHPGe, 
331                                            false,     
332                                            PixelCopyNb); 
333         
334          }
335       
336        PixelCopyNb += PixelCopyNb; 
337        G4cout << "PixelCopyNb: " << PixelCopyNb << G4endl;
338      }
339   
340    }
341 
342  // Optics
343
344  if (DeviceThickness > 0.) 
345    {
346      solidOptic = new G4Tubs("DetectorOptic",          //its name
347                              0.,opticDia/2, opticThickness, 0.,2.*pi);//size
348     
349     
350      logicOptic = new G4LogicalVolume(solidOptic,      //its solid
351                                       defaultMaterial, //its material
352                                       "DetectorOptic");        //its name
353     
354      //zRotPhiHPGe.rotateX(PhiHPGe);
355      G4double x,y,z;
356      z = distOptic * std::cos(ThetaHPGe);
357      y = distOptic * std::sin(ThetaHPGe);
358      x = 0.*cm;
359      physiOptic = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)), 
360                                      "DetectorOptic",  //its name
361                                      logicOptic,       //its logical volume
362                                      physiWorld,       //its mother  volume
363                                      false,            //no boolean operation
364                                      0);               //copy number
365    }
366 
367
368  // Screen
369 
370  if (DeviceThickness > 0.) 
371    {
372      solidScreen = new G4Box("DetectorScreen",         //its name
373                              screenSizeXY/2,screenSizeXY/2,screenThickness/2);//size
374     
375     
376      logicScreen = new G4LogicalVolume(solidScreen,    //its solid
377                                        defaultMaterial,        //its material
378                                        "DetectorScreen");      //its name
379     
380      //zRotPhiHPGe.rotateX(PhiHPGe);
381      G4double x,y,z;
382      G4cout << "distScreen: "<< distScreen/m <<G4endl;
383      z = distScreen * std::cos(ThetaHPGe);
384      y = distScreen * std::sin(ThetaHPGe);
385      x = 0.*cm;
386      physiScreen = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)), 
387                                      "DetectorScreen", //its name
388                                      logicScreen,      //its logical volume
389                                      physiWorld,       //its mother  volume
390                                      false,            //no boolean operation
391                                      0);               //copy number
392    }
393 
394  //Mercury
395 
396 
397  solidMercury=0;  logicMercury=0;  physiMercury=0;
398  if (mercuryDia > 0.) 
399    {
400
401
402       
403
404
405
406      solidMercury = new G4Sphere("Mercury",0.,mercuryDia/2., 0., twopi, 0., pi);
407           
408      logicMercury= new G4LogicalVolume(solidMercury,   //its solid
409                                        mercuryMaterial,        //its material
410                                        "Mercury");     //its name
411     
412      physiMercury = new G4PVPlacement(0,                       //no rotation
413                                       G4ThreeVector(), //at (0,0,0)
414                                       "Mercury",       //its name
415                                       logicMercury,    //its logical volume
416                                       physiWorld,      //its mother  volume
417                                       false,           //no boolean operation
418                                       0);              //copy number
419     
420    } 
421 
422 
423  G4SDManager* SDman = G4SDManager::GetSDMpointer();   
424 
425  if(!HPGeSD)
426    {
427      HPGeSD = new XrayFluoSD ("HPGeSD",this);
428      SDman->AddNewDetector(HPGeSD);
429    }
430 
431 
432  if (logicPixel)
433    {
434      logicPixel->SetSensitiveDetector(HPGeSD);
435    }
436 
437  // Visualization attributes
438 
439
440  logicWorld->SetVisAttributes (G4VisAttributes::Invisible);
441  G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
442  G4VisAttributes * yellow= new G4VisAttributes( G4Colour(255/255. ,255/255. ,51/255. ));
443  G4VisAttributes * red= new G4VisAttributes( G4Colour(255/255. , 0/255. , 0/255. ));
444  G4VisAttributes * blue= new G4VisAttributes( G4Colour(0/255. , 0/255. ,  255/255. ));
445  G4VisAttributes * gray= new G4VisAttributes( G4Colour(128/255. , 128/255. ,  128/255. ));
446  G4VisAttributes * darkGray= new G4VisAttributes( G4Colour(95/255. , 95/255. ,  95/255. ));
447  //G4VisAttributes * green= new G4VisAttributes( G4Colour(25/255. , 255/255. ,  25/255. ));
448  yellow->SetVisibility(true);
449  yellow->SetForceSolid(true);
450  red->SetVisibility(true);
451  red->SetForceSolid(true);
452  blue->SetVisibility(true);
453  gray->SetVisibility(true);
454  gray->SetForceSolid(true);
455  simpleBoxVisAtt->SetVisibility(true);
456
457  //logicWorld->SetVisAttributes (simpleBoxVisAtt);
458 
459  logicPixel->SetVisAttributes(red);
460  logicHPGe->SetVisAttributes(G4VisAttributes::Invisible);
461 
462  logicMercury->SetVisAttributes(darkGray);
463 
464
465  logicScreen->SetVisAttributes(red);
466  logicOhmicNeg->SetVisAttributes(yellow);
467  logicOhmicPos->SetVisAttributes(yellow);
468  logicOptic->SetVisAttributes(gray);
469
470
471  if (mercuryGranularity)  logicGrain->SetVisAttributes(gray);
472
473  //always return the physical World
474   
475  PrintApparateParameters();
476
477  return physiWorld;
478}
479
480//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
481
482void XrayFluoMercuryDetectorConstruction::PrintApparateParameters()
483{
484  G4cout << "-----------------------------------------------------------------------"
485         << G4endl
486         << "The mercury is a sphere whose diamter is: "
487         << G4endl     
488         << mercuryDia/km
489         << " Km "
490         << G4endl
491         <<" Material: " << logicMercury->GetMaterial()->GetName() 
492         <<G4endl
493         <<"The Detector is a slice  " << DeviceThickness/(1.e-6*m) 
494         << " micron thick of " << pixelMaterial->GetName()<<G4endl
495         <<"-------------------------------------------------------------------------"
496         << G4endl;
497}
498//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
499
500void XrayFluoMercuryDetectorConstruction::UpdateGeometry()
501{
502
503
504  delete solidHPGe;
505  delete logicHPGe;
506  delete physiHPGe;
507  delete solidPixel;
508  delete logicPixel;
509  delete physiPixel;
510  delete solidOhmicNeg;
511  delete logicOhmicNeg;
512  delete physiOhmicNeg;
513  delete solidOhmicPos;
514  delete logicOhmicPos;
515  delete physiOhmicPos;
516  delete solidOptic;
517  delete logicOptic;
518  delete physiOptic;
519  delete solidMercury;
520  delete logicMercury;
521  delete physiMercury;
522  delete solidScreen;
523  delete logicScreen;
524  delete physiScreen;
525  delete solidWorld;
526  delete logicWorld;
527  delete physiWorld;
528
529  zRotPhiHPGe.rotateX(-1.*PhiHPGe);
530  ComputeApparateParameters(); 
531  G4RunManager::GetRunManager()->DefineWorldVolume(ConstructApparate());
532}
533
534void XrayFluoMercuryDetectorConstruction::SetMercuryMaterial(G4String newMaterial)
535{
536
537
538    G4cout << "New Mercury Material: " << newMaterial << G4endl;
539    logicMercury->SetMaterial(materials->GetMaterial(newMaterial));
540    PrintApparateParameters();
541 
542}
543
544//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
545
546
547
548
549
550
551
552
553
554
555
Note: See TracBrowser for help on using the repository browser.