Newer
Older
/*****************************************************************************
* Copyright (C) 2009-2013 this file is part of the NPTool Project *
* *
* For the licensing terms see $NPTOOL/Licence/NPTool_Licence *
* For the list of contributors see $NPTOOL/Licence/Contributors *
*****************************************************************************/
/*****************************************************************************
* Original Author: Adrien MATTA contact address: matta@ipno.in2p3.fr *
* *
* Creation Date : November 2012 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class describe the Tiara Silicon array *
* *
*---------------------------------------------------------------------------*
* Comment: *
* *
*****************************************************************************/
// C++ headers
#include <sstream>
#include <cmath>
#include <limits>
//G4 Geometry object
#include "G4Box.hh"
#include "G4Tubs.hh"
#include "G4ExtrudedSolid.hh"
#include "G4TwoVector.hh"
//G4 sensitive
#include "G4SDManager.hh"
//G4 various object
#include "G4Material.hh"
#include "G4Transform3D.hh"
#include "G4PVPlacement.hh"
#include "G4Colour.hh"
#include "G4PVDivision.hh"
#include "G4SubtractionSolid.hh"
// NPS
#include "Tiara.hh"
#include "MaterialManager.hh"
// NPL
#include "NPOptionManager.h"
#include "RootOutput.h"
using namespace TIARA;
// CLHEP header
#include "CLHEP/Random/RandGauss.h"
using namespace std;
using namespace CLHEP;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Tiara::Tiara(){
m_EventBarrel = new TTiaraBarrelData();
m_EventHyball = new TTiaraHyballData();
// Dark Grey
SiliconVisAtt = new G4VisAttributes(G4Colour(0.3, 0.3, 0.3)) ;
// Green
PCBVisAtt = new G4VisAttributes(G4Colour(0.2, 0.5, 0.2)) ;
// Gold Yellow
PADVisAtt = new G4VisAttributes(G4Colour(0.5, 0.5, 0.2)) ;
// Light Grey
FrameVisAtt = new G4VisAttributes(G4Colour(0.5, 0.5, 0.5)) ;
// Light Blue
GuardRingVisAtt = new G4VisAttributes(G4Colour(0.1, 0.1, 0.1)) ;
m_boolChamber = false;
m_boolInner = false;
m_boolOuter = false;
m_InnerBarrelScorer = 0 ;
m_OuterBarrelScorer = 0 ;
m_HyballScorer = 0 ;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Tiara::~Tiara(){
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Virtual Method of VDetector class
// Read stream at Configfile to pick-up parameters of detector (Position,...)
// Called in DetecorConstruction::ReadDetextorConfiguration Method
void Tiara::ReadConfiguration(string Path){
ifstream ConfigFile ;
ConfigFile.open(Path.c_str()) ;
string LineBuffer ;
string DataBuffer ;
bool ReadingStatus = false ;
int VerboseLevel = NPOptionManager::getInstance()->GetVerboseLevel();
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
if (LineBuffer.compare(0, 5, "Tiara") == 0)
ReadingStatus = true;
while (ReadingStatus && ConfigFile >> DataBuffer ) {
// Comment Line
if (DataBuffer.compare(0, 1, "%") == 0) { ConfigFile.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );}
// Tiara Chamber
else if (DataBuffer=="TiaraChamber="){
if(VerboseLevel==1) G4cout << "Chamber Found " << G4endl ;
ConfigFile >> m_boolChamber;
}
// Inner Barrel case
else if (DataBuffer=="TiaraOuterBarrel="){
if(VerboseLevel==1) G4cout << "Inner Barrel found " << G4endl ;
ConfigFile >> m_boolInner;
}
// Outter Barrel case
else if (DataBuffer=="TiaraInnerBarrel="){
if(VerboseLevel==1) G4cout << "Outer Barrel found " << G4endl ;
ConfigFile >> m_boolOuter;
}
// Hyball case
else if (DataBuffer=="TiaraHyballWedge") {
if(VerboseLevel==1) G4cout << "// \n Hyball found: " << G4endl ;
bool ReadingHyball = true;
double Z,R,Phi;
bool boolZ= false;
bool boolR= false;
bool boolPhi= false;
while(ReadingHyball && ConfigFile >> DataBuffer){
if (DataBuffer.compare(0, 1, "%") == 0) {
ConfigFile.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
}
else if(DataBuffer == "Z="){
ConfigFile >> Z ;
boolZ = true;
if(VerboseLevel==1) G4cout << "\t" << DataBuffer << Z << G4endl;
}
else if(DataBuffer == "R="){
ConfigFile >> R ;
boolR = true;
if(VerboseLevel==1) G4cout <<"\t" << DataBuffer << R << G4endl;
}
else if(DataBuffer == "Phi="){
ConfigFile >> Phi ;
boolPhi = true;
if(VerboseLevel==1) G4cout <<"\t" << DataBuffer << Phi << G4endl;
G4cout << "Error: Wrong Token Sequence for Tiara Hyball : Getting out " << DataBuffer << G4endl;
exit(1);
}
if(boolPhi && boolR && boolZ){
ReadingHyball = false;
m_HyballZ.push_back(Z*mm);
m_HyballR.push_back(R*mm);
m_HyballPhi.push_back(Phi*deg);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Construct detector and inialise sensitive part.
// Called After DetecorConstruction::AddDetector Method
void Tiara::ConstructDetector(G4LogicalVolume* world){
if(m_HyballZ.size())
ConstructHyball(world);
// Read sensitive part and fill the Root tree.
// Called at in the EventAction::EndOfEventAvtion
void Tiara::ReadSensitive(const G4Event* event){
m_EventBarrel->Clear();
m_EventHyball->Clear();
G4THitsMap<G4double*>* InnerBarrelHitMap;
std::map<G4int, G4double**>::iterator InnerBarrel_itr;
G4int InnerBarrelCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("Tiara_InnerBarrelScorer/InnerBarrel");
InnerBarrelHitMap = (G4THitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(InnerBarrelCollectionID));
for (InnerBarrel_itr = InnerBarrelHitMap->GetMap()->begin() ; InnerBarrel_itr != InnerBarrelHitMap->GetMap()->end() ; InnerBarrel_itr++){
G4double* Info = *(InnerBarrel_itr->second);
// Upstream Energy
double EU = RandGauss::shoot(Info[0],ResoEnergy);
if(EU>EnergyThreshold){
m_EventBarrel->SetFrontUpstreamE(Info[3],Info[4],EU);
m_EventBarrel->SetFrontUpstreamT(Info[3],Info[4],Info[2]);
}
double ED = RandGauss::shoot(Info[1],ResoEnergy);
if(ED>EnergyThreshold){
m_EventBarrel->SetFrontDownstreamE(Info[3],Info[4],ED);
m_EventBarrel->SetFrontDownstreamT(Info[3],Info[4],Info[2]);
}
// Back Energy
double EB = RandGauss::shoot(Info[1]+Info[0],ResoEnergy);
m_EventBarrel->SetBackE(Info[3],EB);
m_EventBarrel->SetBackT(Info[3],Info[2]);
}
}
// Clear Map for next event
InnerBarrelHitMap->clear();
// OuterBarrel //
G4THitsMap<G4double*>* OuterBarrelHitMap;
std::map<G4int, G4double**>::iterator OuterBarrel_itr;
G4int OuterBarrelCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("Tiara_OuterBarrelScorer/OuterBarrel");
OuterBarrelHitMap = (G4THitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(OuterBarrelCollectionID));
for (OuterBarrel_itr = OuterBarrelHitMap->GetMap()->begin() ; OuterBarrel_itr != OuterBarrelHitMap->GetMap()->end() ; OuterBarrel_itr++){
G4double* Info = *(OuterBarrel_itr->second);
double E = RandGauss::shoot(Info[0],ResoEnergy);
if(E>EnergyThreshold){
m_EventBarrel->SetOuterE(Info[7],Info[9],E);
m_EventBarrel->SetOuterT(Info[7],Info[9],Info[1]);
}
}
// Clear Map for next event
OuterBarrelHitMap->clear();
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
// Hyball //
G4THitsMap<G4double*>* HyballHitMap;
std::map<G4int, G4double**>::iterator Hyball_itr;
G4int HyballCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("Tiara_HyballScorer/Hyball");
HyballHitMap = (G4THitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(HyballCollectionID));
// Loop on the Hyball map
for (Hyball_itr = HyballHitMap->GetMap()->begin() ; Hyball_itr != HyballHitMap->GetMap()->end() ; Hyball_itr++){
G4double* Info = *(Hyball_itr->second);
// Front Energy
double EF = RandGauss::shoot(Info[0],ResoEnergy);
if(EF>EnergyThreshold){
m_EventHyball->SetRingE(Info[7],Info[8],EF);
m_EventHyball->SetRingT(Info[7],Info[8],Info[1]);
}
// Back Energy
double EB = RandGauss::shoot(Info[1]+Info[0],ResoEnergy);
if(EB>EnergyThreshold){
m_EventHyball->SetSectorE(Info[7],Info[9],EF);
m_EventHyball->SetSectorT(Info[7],Info[9],Info[1]);
}
}
// Clear Map for next event
HyballHitMap->clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Tiara::InitializeScorers(){
//Look for previous definition of the scorer (geometry reload)
bool already_exist = false;
m_InnerBarrelScorer = CheckScorer("Tiara_InnerBarrelScorer",already_exist);
m_OuterBarrelScorer = CheckScorer("Tiara_OuterBarrelScorer",already_exist);
m_HyballScorer = CheckScorer("Tiara_HyballScorer",already_exist);
// if the scorer were created previously nothing else need to be made
if(already_exist) return;
G4VPrimitiveScorer* InnerBarrel = new SILICONSCORERS::PS_Silicon_Resistive("InnerBarrel",1,
INNERBARREL_ActiveWafer_Length,
INNERBARREL_ActiveWafer_Width,
INNERBARREL_NumberOfStrip);
m_InnerBarrelScorer->RegisterPrimitive(InnerBarrel);
G4VPrimitiveScorer* OuterBarrel = new SILICONSCORERS::PS_Silicon_Rectangle("OuterBarrel",1,
INNERBARREL_ActiveWafer_Length,
INNERBARREL_ActiveWafer_Width,
1,
OUTERBARREL_NumberOfStrip);
m_OuterBarrelScorer->RegisterPrimitive(OuterBarrel);
G4VPrimitiveScorer* Hyball= new SILICONSCORERS::PS_Silicon_Annular("Hyball",1,
HYBALL_ActiveWafer_InnerRadius,
HYBALL_ActiveWafer_OuterRadius,
-0.5*HYBALL_ActiveWafer_Angle,0.5*HYBALL_ActiveWafer_Angle,
HYBALL_NumberOfAnnularStrip,
HYBALL_NumberOfRadialStrip);
// Add All Scorer to the Global Scorer Manager
G4SDManager::GetSDMpointer()->AddNewDetector(m_InnerBarrelScorer) ;
G4SDManager::GetSDMpointer()->AddNewDetector(m_OuterBarrelScorer) ;
G4SDManager::GetSDMpointer()->AddNewDetector(m_HyballScorer) ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Tiara::InitializeRootOutput(){
TTree *pTree = RootOutput::getInstance()->GetTree();
pTree->Branch("TiaraBarrel", "TTiaraBarrelData", &m_EventBarrel) ;
pTree->Branch("TiaraHyball", "TTiaraHyballData", &m_EventHyball) ;
// This insure that the object are correctly bind in case of
// a redifinition of the geometry in the simulation
pTree->SetBranchAddress("TiaraBarrel", &m_EventBarrel) ;
pTree->SetBranchAddress("TiaraHyball", &m_EventHyball) ;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Tiara::ConstructInnerBarrel(G4LogicalVolume* world){
// Tiara Barrel
// The Barrel is made of 8 identical resistive strip detector
// The PCB is made from a G4ExtrudeSolid, because it has beveled edge
// the pcb is a substracted volume
// the wafer goes into the hole, but a 15mm part is still covered by some PCB
// the whole things is design so the local reference is the one of the wafer
// Start by making a full pcb
// We start by the definition of the point forming a PCB cross section
vector<G4TwoVector> PCBCrossSection;
double l1 = INNERBARREL_PCB_Thickness*0.5/tan(INNERBARREL_PCB_Bevel1_Theta);
double l2 = INNERBARREL_PCB_Thickness*0.5/tan(INNERBARREL_PCB_Bevel2_Theta);
PCBCrossSection.push_back(G4TwoVector(INNERBARREL_PCB_Width/2.-l2,-INNERBARREL_PCB_Thickness*0.5));
PCBCrossSection.push_back(G4TwoVector(INNERBARREL_PCB_Width/2.,0));
PCBCrossSection.push_back(G4TwoVector(INNERBARREL_PCB_Width/2.-l1,INNERBARREL_PCB_Thickness*0.5));
PCBCrossSection.push_back(G4TwoVector(-INNERBARREL_PCB_Width/2.+l1,INNERBARREL_PCB_Thickness*0.5));
PCBCrossSection.push_back(G4TwoVector(-INNERBARREL_PCB_Width/2.,0));
PCBCrossSection.push_back(G4TwoVector(-INNERBARREL_PCB_Width/2.+l2,-INNERBARREL_PCB_Thickness*0.5));
G4ExtrudedSolid* PCBFull =
new G4ExtrudedSolid("PCBFull",
PCBCrossSection,
INNERBARREL_PCB_Length/2.,
G4TwoVector(0,0),1,
G4TwoVector(0,0),1);
// A box having Wafer dimension but thicker than the PCB
// Will be used to remove material from the PCB to have space for the wafer
// Calculate the hole shift within the PCB
G4ThreeVector HoleShift = G4ThreeVector(
0,
0,
INNERBARREL_PCB_Offset-(INNERBARREL_PCB_Length/2-INNERBARREL_PCB_HoleLength/2));
G4Box* HoleShape = new G4Box("HoleShape",
INNERBARREL_ActiveWafer_Width/2.,
INNERBARREL_PCB_Thickness/2.+0.1*mm,
INNERBARREL_PCB_HoleLength/2.);
G4Box* WaferShape = new G4Box("WaferShape",
INNERBARREL_InertWafer_Width/2.,
INNERBARREL_PCB_Thickness/2.,
INNERBARREL_InertWafer_Length/2.);
G4Box* InertWaferFull = new G4Box("InertWaferFull",
INNERBARREL_InertWafer_Width/2.,
INNERBARREL_InertWafer_Length/2.);
G4Box* ActiveWafer = new G4Box("ActiveWafer",
INNERBARREL_ActiveWafer_Width/2.,
INNERBARREL_ActiveWafer_Thickness/2.,
INNERBARREL_ActiveWafer_Length/2.);
G4Box* DeadLayer = new G4Box("DeadLayer",
INNERBARREL_ActiveWafer_Width/2.,
INNERBARREL_ActiveWafer_DeadLayerThickness/2.,
INNERBARREL_ActiveWafer_Length/2.);
G4Box* ActiveWaferShape = new G4Box("ActiveWaferShape",
INNERBARREL_ActiveWafer_Width/2.,
INNERBARREL_PCB_Thickness/2.,
INNERBARREL_ActiveWafer_Length/2.);
// Substracting the hole Shape from the Stock PCB
G4SubtractionSolid* PCB_1 = new G4SubtractionSolid("PCB_1", PCBFull, HoleShape,
// Substracting the wafer space from the Stock PCB
G4SubtractionSolid* PCB = new G4SubtractionSolid("PCB", PCB_1, WaferShape,
new G4RotationMatrix,
G4ThreeVector(0,INNERBARREL_PCB_Thickness/2.-INNERBARREL_PCB_WaferDepth,0));
// Substract active part from inert part of the Wafer
G4SubtractionSolid* InertWafer = new G4SubtractionSolid("InertWafer", InertWaferFull, ActiveWaferShape,
// Master Volume that encompass everything else
G4LogicalVolume* logicBarrelDetector =
new G4LogicalVolume(PCBFull,m_MaterialVacuum,"logicBoxDetector", 0, 0, 0);
logicBarrelDetector->SetVisAttributes(G4VisAttributes::Invisible);
// Sub Volume PCB
G4LogicalVolume* logicPCB =
new G4LogicalVolume(PCB,m_MaterialPCB,"logicPCB", 0, 0, 0);
logicPCB->SetVisAttributes(PCBVisAtt);
// Sub Volume Wafer
G4LogicalVolume* logicInertWafer =
new G4LogicalVolume(InertWafer,m_MaterialSilicon,"logicInertWafer", 0, 0, 0);
logicInertWafer->SetVisAttributes(GuardRingVisAtt);
G4LogicalVolume* logicActiveWafer =
new G4LogicalVolume(ActiveWafer,m_MaterialSilicon,"logicActiveWafer", 0, 0, 0);
logicActiveWafer->SetVisAttributes(SiliconVisAtt);
G4LogicalVolume* logicDeadLayer =
new G4LogicalVolume(DeadLayer,m_MaterialSilicon,"logicActiveWaferDeadLayer", 0, 0, 0);
logicDeadLayer->SetVisAttributes(SiliconVisAtt);
// Set the sensitive volume
logicActiveWafer->SetSensitiveDetector(m_InnerBarrelScorer);
// Place the sub volumes in the master volume
// Last argument is the detector number, used in the scorer to get the
// revelant information
new G4PVPlacement(new G4RotationMatrix(0,0,0),
G4ThreeVector(0,0,0),
logicPCB,"Tiara_Barrel_PCB",logicBarrelDetector,
false,0);
0.5*(INNERBARREL_PCB_Thickness+INNERBARREL_InertWafer_Thickness)-INNERBARREL_PCB_WaferDepth
,0);
G4ThreeVector DeadLayerPositionF = WaferPosition + G4ThreeVector(0,-INNERBARREL_ActiveWafer_Thickness*0.5-INNERBARREL_ActiveWafer_DeadLayerThickness*0.5,0);
G4ThreeVector DeadLayerPositionB = WaferPosition + G4ThreeVector(0,INNERBARREL_ActiveWafer_Thickness*0.5+INNERBARREL_ActiveWafer_DeadLayerThickness*0.5,0);
new G4PVPlacement(new G4RotationMatrix(0,0,0),
WaferPosition,
logicActiveWafer,"Barrel_Wafer",
logicBarrelDetector,false,0);
new G4PVPlacement(new G4RotationMatrix(0,0,0),
DeadLayerPositionF,
logicDeadLayer,"Barrel_WaferDeadLayerFront",
logicBarrelDetector,false,0);
new G4PVPlacement(new G4RotationMatrix(0,0,0),
DeadLayerPositionB,
logicDeadLayer,"Barrel_WaferDeadLayerBack",
logicBarrelDetector,false,0);
new G4PVPlacement(new G4RotationMatrix(0,0,0),
WaferPosition,
logicInertWafer,"Barrel_Wafer_GuardRing",
logicBarrelDetector,false,0);
// The Distance from target is given by half the lenght of a detector
// plus the length of a detector inclined by 45 deg.
G4double DistanceFromTarget = INNERBARREL_PCB_Width*(0.5+sin(45*deg)) ;
for( unsigned int i = 0; i < 8; i ++){
// The following build the barrel, with detector one at the top
// and going clowise looking upstrea
// Detector are rotate by 45deg with each other
G4RotationMatrix* DetectorRotation =
new G4RotationMatrix(0*deg,0*deg,i*45*deg);
// There center is also rotated by 45deg
G4ThreeVector DetectorPosition(0,DistanceFromTarget,0);
DetectorPosition.rotate(i*45*deg,G4ThreeVector(0,0,-1));
// Place the Master volume with its two daugther volume at the final place
new G4PVPlacement(G4Transform3D(*DetectorRotation,DetectorPosition),
logicBarrelDetector,"Tiara_InnerBarrel_Detector",
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Tiara::ConstructOuterBarrel(G4LogicalVolume* world){
// Tiara Outer Barrel
// The outer Barrel is identical to the inner barrel but wider in terms of
// geometry. It feature four non resistive strip on the front face
// Start by making a full pcb
// We start by the definition of the point forming a PCB cross section
vector<G4TwoVector> PCBCrossSection;
double l1 = OUTERBARREL_PCB_Thickness*0.5/tan(OUTERBARREL_PCB_Bevel1_Theta);
double l2 = OUTERBARREL_PCB_Thickness*0.5/tan(OUTERBARREL_PCB_Bevel2_Theta);
PCBCrossSection.push_back(G4TwoVector(OUTERBARREL_PCB_Width/2.-l2,-OUTERBARREL_PCB_Thickness*0.5));
PCBCrossSection.push_back(G4TwoVector(OUTERBARREL_PCB_Width/2.,0));
PCBCrossSection.push_back(G4TwoVector(OUTERBARREL_PCB_Width/2.-l1,OUTERBARREL_PCB_Thickness*0.5));
PCBCrossSection.push_back(G4TwoVector(-OUTERBARREL_PCB_Width/2.+l1,OUTERBARREL_PCB_Thickness*0.5));
PCBCrossSection.push_back(G4TwoVector(-OUTERBARREL_PCB_Width/2.,0));
PCBCrossSection.push_back(G4TwoVector(-OUTERBARREL_PCB_Width/2.+l2,-OUTERBARREL_PCB_Thickness*0.5));
G4ExtrudedSolid* PCBFull =
new G4ExtrudedSolid("PCBFull",
PCBCrossSection,
OUTERBARREL_PCB_Length/2.,
G4TwoVector(0,0),1,
G4TwoVector(0,0),1);
// A box having Wafer dimension but thicker than the PCB
// Will be used to remove material from the PCB to have space for the wafer
// Calculate the hole shift within the PCB
G4ThreeVector HoleShift = G4ThreeVector(
0,
0,
OUTERBARREL_PCB_Offset-(OUTERBARREL_PCB_Length/2-OUTERBARREL_PCB_HoleLength/2));
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
G4Box* HoleShape = new G4Box("HoleShape",
OUTERBARREL_ActiveWafer_Width/2.,
OUTERBARREL_PCB_Thickness/2.+0.1*mm,
OUTERBARREL_PCB_HoleLength/2.);
G4Box* WaferShape = new G4Box("WaferShape",
OUTERBARREL_InertWafer_Width/2.,
OUTERBARREL_PCB_Thickness/2.,
OUTERBARREL_InertWafer_Length/2.);
// The Silicon Wafer itself
G4Box* InertWaferFull = new G4Box("InertWaferFull",
OUTERBARREL_InertWafer_Width/2.,
OUTERBARREL_ActiveWafer_Thickness/2.,
OUTERBARREL_InertWafer_Length/2.);
G4Box* ActiveWafer = new G4Box("ActiveWafer",
OUTERBARREL_ActiveWafer_Width/2.,
OUTERBARREL_ActiveWafer_Thickness/2.,
OUTERBARREL_ActiveWafer_Length/2.);
G4Box* ActiveWaferShape = new G4Box("ActiveWaferShape",
OUTERBARREL_ActiveWafer_Width/2.,
OUTERBARREL_PCB_Thickness/2.,
OUTERBARREL_ActiveWafer_Length/2.);
// Substracting the hole Shape from the Stock PCB
G4SubtractionSolid* PCB_1 = new G4SubtractionSolid("PCB_1", PCBFull, HoleShape,
// Substracting the wafer space from the Stock PCB
G4SubtractionSolid* PCB = new G4SubtractionSolid("PCB", PCB_1, WaferShape,
new G4RotationMatrix,
G4ThreeVector(0,OUTERBARREL_PCB_Thickness/2.-OUTERBARREL_PCB_WaferDepth,0));
// Substract active part from inert part of the Wafer
G4SubtractionSolid* InertWafer = new G4SubtractionSolid("InertWafer", InertWaferFull, ActiveWaferShape,
// Master Volume that encompass everything else
G4LogicalVolume* logicBarrelDetector =
new G4LogicalVolume(PCBFull,m_MaterialVacuum,"logicBoxDetector", 0, 0, 0);
logicBarrelDetector->SetVisAttributes(G4VisAttributes::Invisible);
// Sub Volume PCB
G4LogicalVolume* logicPCB =
new G4LogicalVolume(PCB,m_MaterialPCB,"logicPCB", 0, 0, 0);
logicPCB->SetVisAttributes(PCBVisAtt);
// Sub Volume Wafer
G4LogicalVolume* logicInertWafer =
new G4LogicalVolume(InertWafer,m_MaterialSilicon,"logicInertWafer", 0, 0, 0);
logicInertWafer->SetVisAttributes(GuardRingVisAtt);
G4LogicalVolume* logicActiveWafer =
new G4LogicalVolume(ActiveWafer,m_MaterialSilicon,"logicActiveWafer", 0, 0, 0);
logicActiveWafer->SetVisAttributes(SiliconVisAtt);
// Set the sensitive detector
logicActiveWafer->SetSensitiveDetector(m_OuterBarrelScorer);
// The Distance from target is given by half the lenght of a detector
// plus the length of a detector inclined by 45 deg.
G4double DistanceFromTarget = OUTERBARREL_PCB_Width*(0.5+sin(45*deg)) ;
// Place the sub volumes in the master volume
// Last argument is the detector number, used in the scorer to get the
// revelant information
new G4PVPlacement(new G4RotationMatrix(0,0,0),
G4ThreeVector(0,0,0),
logicPCB,"Tiara_OuterBarrel_PCB",logicBarrelDetector,
false,0);
G4ThreeVector WaferPosition(0,
0.5*(OUTERBARREL_PCB_Thickness+OUTERBARREL_ActiveWafer_Thickness)-OUTERBARREL_PCB_WaferDepth
,0);
new G4PVPlacement(new G4RotationMatrix(0,0,0),
WaferPosition,
logicActiveWafer,"OuterBarrel_Wafer",
logicBarrelDetector,false,0);
new G4PVPlacement(new G4RotationMatrix(0,0,0),
WaferPosition,
logicInertWafer,"OuterBarrel_Wafer_GuardRing",
logicBarrelDetector,false,0);
// The following build the barrel, with detector one at the top
// and going clowise looking upstrea
for( unsigned int i = 0; i < 8; i ++){
// Detector are rotate by 45deg with each other
G4RotationMatrix* DetectorRotation =
new G4RotationMatrix(0*deg,0*deg,i*45*deg);
// There center is also rotated by 45deg
G4ThreeVector DetectorPosition(0,DistanceFromTarget,0);
DetectorPosition.rotate(i*45*deg,G4ThreeVector(0,0,-1));
// Place the Master volume with its daugthers at the final place
new G4PVPlacement(G4Transform3D(*DetectorRotation,DetectorPosition),
logicBarrelDetector,"Tiara_OuterBarrel_Detector",
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Tiara::ConstructHyball(G4LogicalVolume* world){
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
vector<G4TwoVector> PCBCrossSection;
PCBCrossSection.push_back(G4TwoVector(28.108*mm ,-14.551*mm));
PCBCrossSection.push_back(G4TwoVector(128.808*mm,-66.683*mm));
PCBCrossSection.push_back(G4TwoVector(163.618*mm,-30.343*mm));
PCBCrossSection.push_back(G4TwoVector(163.618*mm, 30.941*mm));
PCBCrossSection.push_back(G4TwoVector(125.718*mm, 73.677*mm));
PCBCrossSection.push_back(G4TwoVector(28.108*mm , 16.473*mm));
G4ExtrudedSolid* PCBFull =
new G4ExtrudedSolid("PCBFull",
PCBCrossSection,
0.5*HYBALL_PCB_THICKNESS,
G4TwoVector(0,0),1,
G4TwoVector(0,0),1);
vector<G4TwoVector> WaferCrossSection;
WaferCrossSection.push_back(G4TwoVector(29.108*mm ,-13.943*mm ));
WaferCrossSection.push_back(G4TwoVector(123.022*mm,-62.561*mm ));
WaferCrossSection.push_back(G4TwoVector(137.00*mm ,-24.157*mm ));
WaferCrossSection.push_back(G4TwoVector(137.00*mm , 24.157*mm ));
WaferCrossSection.push_back(G4TwoVector(122.677*mm, 63.508*mm ));
WaferCrossSection.push_back(G4TwoVector(29.108*mm , 15.069*mm));
G4ExtrudedSolid* WaferFull =
new G4ExtrudedSolid("WaferFull",
WaferCrossSection,
0.5*HYBALL_ActiveWafer_Thickness,
G4TwoVector(0,0),1,
G4TwoVector(0,0),1);
G4ExtrudedSolid* WaferShape =
new G4ExtrudedSolid("WaferShape",
WaferCrossSection,
0.6*HYBALL_PCB_THICKNESS,
G4TwoVector(0,0),1,
G4TwoVector(0,0),1);
// Active Wafer
G4Tubs* ActiveWafer =
new G4Tubs("HyballActiveWafer",HYBALL_ActiveWafer_InnerRadius,
HYBALL_ActiveWafer_OuterRadius,0.5*HYBALL_ActiveWafer_Thickness,
-0.5*HYBALL_ActiveWafer_Angle,HYBALL_ActiveWafer_Angle);
G4Tubs* ActiveWaferShape =
new G4Tubs("HyballActiveWaferShape",HYBALL_ActiveWafer_InnerRadius,
HYBALL_ActiveWafer_OuterRadius,0.6*HYBALL_ActiveWafer_Thickness,
-0.5*HYBALL_ActiveWafer_Angle,HYBALL_ActiveWafer_Angle);
// Substract Active Wafer from Wafer
G4SubtractionSolid* InertWafer = new G4SubtractionSolid("Hyball_InertWafer", WaferFull, ActiveWaferShape,
new G4RotationMatrix(0,0,0),G4ThreeVector(0,0,0));
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
// Substract Wafer shape from PCB
G4SubtractionSolid* PCB = new G4SubtractionSolid("Hyball_PCB", PCBFull, WaferShape,
new G4RotationMatrix,G4ThreeVector(0,0,0));
// Logic Volume //
// Logic Mother Volume
G4LogicalVolume* logicHyball =
new G4LogicalVolume(PCBFull,m_MaterialVacuum,"logicHyball", 0, 0, 0);
logicHyball->SetVisAttributes(G4VisAttributes::Invisible);
// logic PCB
G4LogicalVolume* logicPCB =
new G4LogicalVolume(PCB,m_MaterialPCB,"logicPCB", 0, 0, 0);
logicPCB->SetVisAttributes(PCBVisAtt);
// logic Inert Wafer
G4LogicalVolume* logicIW =
new G4LogicalVolume(InertWafer,m_MaterialSilicon,"logicIW", 0, 0, 0);
logicIW->SetVisAttributes(GuardRingVisAtt);
// logic Active Wafer
G4LogicalVolume* logicAW =
new G4LogicalVolume(ActiveWafer,m_MaterialSilicon,"logicAW", 0, 0, 0);
logicAW->SetVisAttributes(SiliconVisAtt);
logicAW->SetSensitiveDetector(m_HyballScorer);
// Place all the Piece in the mother volume
new G4PVPlacement(new G4RotationMatrix(0,0,0),
G4ThreeVector(0,0,0),
logicPCB,"Hyball_PCB",
logicHyball,false,0);
new G4PVPlacement(new G4RotationMatrix(0,0,0),
G4ThreeVector(0,0,0),
logicIW,"Hyball_InertWafer",
logicHyball,false,0);
new G4PVPlacement(new G4RotationMatrix(0,0,0),
G4ThreeVector(0,0,0),
logicAW,"Hyball_ActiveWafer",
logicHyball,false,0);
for(unsigned int i = 0 ; i < m_HyballZ.size() ; i++){
// Place mother volume
new G4PVPlacement(new G4RotationMatrix(0,0,m_HyballPhi[i]),
G4ThreeVector(0,0,m_HyballZ[i]),
logicHyball,"Hyball",
world,false,i+1);
}
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Tiara::ConstructChamber(G4LogicalVolume* world){
// Vaccum Chamber of Tiara
// The chamber is made of a central cylinder surrounding the barrel Si
// Two Cone that expeand out of the central cylinder to let room for Exogam
// Two outer cylinder surrounding Hyball
// Hyball is hold on a back plate that close the Diabolo Shaped Chamber
// Making the Chamber //
// We make the individual pieces, starting from the inside to the outside
// Then we merge them together using the a G4AdditionSolid
// The whole chamber is then placed
// Central Tube
G4Tubs* solidCentralTube =
new G4Tubs("TiaraChamberCentralTube",CHAMBER_CentralTube_Inner_Radius,
CHAMBER_CentralTube_Outer_Radius,CHAMBER_CentralTube_Length/2.,
0*deg,360*deg);
// Forward-Backward Cones
G4Cons* solidOuterCone =
new G4Cons("TiaraChamberOuterCone",CHAMBER_CentralTube_Inner_Radius,
CHAMBER_CentralTube_Outer_Radius,CHAMBER_OuterCylinder_Inner_Radius,
CHAMBER_OuterCylinder_Outer_Radius,CHAMBER_OuterCone_Length/2.,
0*deg,360*deg);
// Outer Cylinder
G4Tubs* solidOuterCylinder =
new G4Tubs("TiaraChamberOuterCylinder",CHAMBER_OuterCylinder_Inner_Radius,
CHAMBER_OuterCylinder_Outer_Radius,CHAMBER_OuterCylinder_Length/2.,
0*deg,360*deg);
// Add the volume together
G4UnionSolid* solidTiaraChamberStep1 =
new G4UnionSolid("TiaraChamber", solidCentralTube, solidOuterCone,
new G4RotationMatrix,
G4ThreeVector(0,0,CHAMBER_OuterCone_Z_Pos));
G4UnionSolid* solidTiaraChamberStep2 =
new G4UnionSolid("TiaraChamber", solidTiaraChamberStep1, solidOuterCone,
new G4RotationMatrix(0,180*deg,0),
G4ThreeVector(0,0,-CHAMBER_OuterCone_Z_Pos));
G4UnionSolid* solidTiaraChamberStep3 =
new G4UnionSolid("TiaraChamber", solidTiaraChamberStep2, solidOuterCylinder,
new G4RotationMatrix,
G4ThreeVector(0,0,CHAMBER_OuterCylinder_Z_Pos));
G4UnionSolid* solidTiaraChamberStep4 =
new G4UnionSolid("TiaraChamber", solidTiaraChamberStep3, solidOuterCylinder,
new G4RotationMatrix,
G4ThreeVector(0,0,-CHAMBER_OuterCylinder_Z_Pos));
// Create Logic Volume
G4LogicalVolume* logicTiaraChamber =
new G4LogicalVolume(solidTiaraChamberStep4,m_MaterialAl,"logicTiaraChamber", 0, 0, 0);
// Visual Attribute
G4VisAttributes* ChamberVisAtt
= new G4VisAttributes(G4Colour(0.0,0.4,0.5,0.2));
logicTiaraChamber->SetVisAttributes(ChamberVisAtt);
// Place the whole chamber
new G4PVPlacement(new G4RotationMatrix(0,0,0), G4ThreeVector(0,0,0),
logicTiaraChamber,"TiaraChamber",world,false,0);
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Tiara::InitializeMaterial(){
m_MaterialSilicon = MaterialManager::getInstance()->GetMaterialFromLibrary("Si");
m_MaterialAl = MaterialManager::getInstance()->GetMaterialFromLibrary("Al");
m_MaterialPCB = MaterialManager::getInstance()->GetMaterialFromLibrary("PCB");
m_MaterialVacuum = MaterialManager::getInstance()->GetMaterialFromLibrary("Vacuum");