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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*****************************************************************************
* Copyright (C) 2009-2024 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: Audrey Chatillon contact address: audrey.chatillon@cea.fr *
* *
* Creation Date : décembre 2024 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class describe Epic simulation *
* *
*---------------------------------------------------------------------------*
* Comment: *
* *
*****************************************************************************/
// C++ headers
#include <sstream>
#include <cmath>
#include <limits>
//G4 Geometry object
#include "G4Tubs.hh"
#include "G4Box.hh"
//G4 sensitive
#include "G4SDManager.hh"
#include "G4MultiFunctionalDetector.hh"
//G4 various object
#include "G4Material.hh"
#include "G4Transform3D.hh"
#include "G4PVPlacement.hh"
#include "G4VisAttributes.hh"
#include "G4Colour.hh"
#include "G4SubtractionSolid.hh"
// NPTool header
#include "Epic.hh"
#include "CalorimeterScorers.hh"
#include "InteractionScorers.hh"
#include "RootOutput.h"
#include "MaterialManager.hh"
#include "NPSDetectorFactory.hh"
#include "NPOptionManager.h"
#include "NPSHitsMap.hh"
// CLHEP header
#include "CLHEP/Random/RandGauss.h"
using namespace std;
using namespace CLHEP;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
namespace Epic_NS{
// Energy and time Resolution
const double EnergyThreshold = 0.1*MeV;
const double ResoTime = 4.5*ns ;
const double ResoEnergy = 1.0*MeV ;
// Fission Chamber
const double Cu_Thickness = 17*micrometer;
const double Kapton_Thickness = 50*micrometer;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Epic Specific Method
Epic::Epic(){
m_Event = new TEpicData() ;
m_EpicScorer = 0;
m_EpicVolume = 0;
// RGB Color + Transparency
m_VisFCWall = new G4VisAttributes(G4Colour(0.1,0.5,0.7,1));
m_VisAl = new G4VisAttributes(G4Colour(0.839,0.803,0.803,1));
m_VisTi = new G4VisAttributes(G4Colour(0.776,0.662,0.662,0.5));
m_VisGasAK = new G4VisAttributes(G4Colour(0.576,0.662,0.662,0.3));
m_VisGasKK = new G4VisAttributes(G4Colour(0.576,0.662,0.662,0.5));
m_VisCu = new G4VisAttributes(G4Colour(0.70, 0.40, 0. ,1));
m_VisRogers4003C = new G4VisAttributes(G4Colour(0.60, 0.60, 0.2 ,1));
m_GasMaterial = "CF4";
m_Pressure = 1.*bar;
}
Epic::~Epic(){
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Epic::AddDetector(G4ThreeVector POS){
// Convert the POS value to R theta Phi as Spherical coordinate is easier in G4
audrey.chatillon
committed
m_R.push_back(POS.mag());
m_Theta.push_back(POS.theta());
m_Phi.push_back(POS.phi());
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
130
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Virtual Method of NPS::VDetector class
// Read stream at Configfile to pick-up parameters of detector (Position,...)
// Called in DetecorConstruction::ReadDetextorConfiguration Method
void Epic::ReadConfiguration(NPL::InputParser parser){
vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("Epic");
if(NPOptionManager::getInstance()->GetVerboseLevel())
cout << "//// " << blocks.size() << " detectors found " << endl;
vector<string> cart = {"POS","GasMaterial","Pressure"};
for(unsigned int i = 0 ; i < blocks.size() ; i++){
if(blocks[i]->HasTokenList(cart)){
if(NPOptionManager::getInstance()->GetVerboseLevel())
cout << endl << "//// Epic " << i+1 << endl;
G4ThreeVector Pos = NPS::ConvertVector(blocks[i]->GetTVector3("POS","mm"));
string GasMaterial = blocks[i]->GetString("GasMaterial");
double Pressure = blocks[i]->GetDouble("Pressure","bar");
double Distance_AK = blocks[i]->GetDouble("Distance_AK","mm");
double InterDistance_KK = blocks[i]->GetDouble("InterDistance_KK","mm");
int nA = blocks[i]->GetInt("nAnodes");
AddDetector(Pos);
m_GasMaterial = GasMaterial;
m_Pressure = Pressure;
m_Distance_AK = Distance_AK;
m_nA = nA;
}
else{
cout << "ERROR: check your input file formatting " << endl;
exit(1);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Construct detector and inialise sensitive part.
// Called After DetecorConstruction::AddDetector Method
void Epic::ConstructDetector(G4LogicalVolume* world){
audrey.chatillon
committed
for (unsigned short i = 0 ; i < m_R.size() ; i++) {
audrey.chatillon
committed
G4double wX = m_R[i] * sin(m_Theta[i] ) * cos(m_Phi[i] ) ;
G4double wY = m_R[i] * sin(m_Theta[i] ) * sin(m_Phi[i] ) ;
G4double wZ = m_R[i] * cos(m_Theta[i] ) ;
G4ThreeVector Det_pos = G4ThreeVector(wX, wY, wZ) ;
// Building Detector reference frame
G4double ii = cos(m_Theta[i]) * cos(m_Phi[i]);
G4double jj = cos(m_Theta[i]) * sin(m_Phi[i]);
G4double kk = -sin(m_Theta[i]);
G4ThreeVector Y(ii,jj,kk);
G4ThreeVector w = Det_pos.unit();
G4ThreeVector u = w.cross(Y);
G4ThreeVector v = w.cross(u);
v = v.unit();
u = u.unit();
G4RotationMatrix* Rot = new G4RotationMatrix(0,0,0);
BuildEpic()->MakeImprint(world, Det_pos, Rot, i);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4AssemblyVolume* Epic::BuildEpic(){
m_EpicVolume = new G4AssemblyVolume();
G4RotationMatrix *Rv=new G4RotationMatrix(0,0,0);
G4ThreeVector Tv;
Tv.setX(0); Tv.setY(0); Tv.setZ(0);
// --- Get Material
G4Material* Al_material = MaterialManager::getInstance()->GetMaterialFromLibrary("Al");
G4Material* Cu_material = MaterialManager::getInstance()->GetMaterialFromLibrary("Cu");
G4Material* Ti_material = MaterialManager::getInstance()->GetMaterialFromLibrary("Ti");
G4Material* Rogers_material = MaterialManager::getInstance()->GetMaterialFromLibrary("Rogers4003C");
G4Material* gas_material = MaterialManager::getInstance()->GetGasFromLibrary(m_GasMaterial, m_Pressure, 300*kelvin);
// --- PCB (6 layers of Cu)
double posY_PCB = -85.0*mm; // @the 6-Cu layers
double PCB_width = 180.0*mm;
double PCB_length = 330.0*mm;
double PCB_Rogers_height = 1.6*mm;
double PCB_Cu_height = 6*35.*um;
G4Box* PCB_Rogers_solid = new G4Box("PCB_Rogers",0.5*PCB_width,0.5*PCB_Rogers_height,0.5*PCB_length);
G4Box* PCB_Cu_solid = new G4Box("PCB_Cu",0.5*PCB_width,0.5*PCB_Cu_height,0.5*PCB_length);
G4LogicalVolume* PCB_Rogers_vol = new G4LogicalVolume(PCB_Rogers_solid, Rogers_material,"PCB_Rogers_logic",0,0,0);
G4LogicalVolume* PCB_Cu_vol = new G4LogicalVolume(PCB_Cu_solid, Cu_material,"PCB_Cu_logic",0,0,0);
PCB_Rogers_vol->SetVisAttributes(m_VisRogers4003C);
Tv.setY(posY_PCB + 0.5*PCB_Cu_height + 0.5*PCB_Rogers_height);
m_EpicVolume->AddPlacedVolume(PCB_Rogers_vol, Tv, Rv);
PCB_Cu_vol->SetVisAttributes(m_VisCu);
Tv.setY(posY_PCB);
m_EpicVolume->AddPlacedVolume(PCB_Cu_vol, Tv, Rv);
// --- FLANGE IN ALUMINIUM
double flange_full_width = PCB_width;
double flange_full_length = PCB_length;
double flange_full_height = 5.*mm; double posY_flange = posY_PCB - 0.5*PCB_Cu_height - 0.5*flange_full_height ;
double flange_open_width = 150.0*mm;
double flange_open_height = 5.1*mm;
double flange_open1_length = 74.5*mm; double posZ_open1 = -89.5*mm;
double flange_open2_length = 85.0*mm; double posZ_open2 = 0.0*mm;
double flange_open3_length = 42.0*mm; double posZ_open3 = 73.5*mm;
G4Box* flange_full = new G4Box("flange_full" , 0.5*flange_full_width , 0.5*flange_full_height, 0.5*flange_full_length);
G4Box* flange_open1 = new G4Box("flange_open1", 0.5*flange_open_width , 0.5*flange_open_height, 0.5*flange_open1_length);
G4Box* flange_open2 = new G4Box("flange_open1", 0.5*flange_open_width , 0.5*flange_open_height, 0.5*flange_open2_length);
G4Box* flange_open3 = new G4Box("flange_open1", 0.5*flange_open_width , 0.5*flange_open_height, 0.5*flange_open3_length);
G4VSolid* flange_int1 = (G4VSolid*) new G4SubtractionSolid("flange_int1" ,flange_full,flange_open1,0,G4ThreeVector(0,0,posZ_open1));
G4VSolid* flange_int2 = (G4VSolid*) new G4SubtractionSolid("flange_int2" ,flange_int1,flange_open2,0,G4ThreeVector(0,0,posZ_open2));
G4VSolid* flange_final = (G4VSolid*) new G4SubtractionSolid("flange_final",flange_int2,flange_open3,0,G4ThreeVector(0,0,posZ_open3));
G4LogicalVolume* flange_vol = new G4LogicalVolume(flange_final, Al_material, "flange_logic", 0,0,0);
flange_vol->SetVisAttributes(m_VisAl);
Tv.setY(posY_flange);
m_EpicVolume->AddPlacedVolume(flange_vol, Tv, Rv);
// --- FRAME IN ALUMINIUM
double frame_foot_full_width = flange_full_width;
double frame_foot_full_length = flange_full_length;
double frame_foot_full_height = 2.*mm; double posY_frame_foot = posY_PCB + 0.5*PCB_Cu_height + PCB_Rogers_height + 0.5*frame_foot_full_height ;
double frame_foot_open_width = flange_full_width - 2.*13.*mm;
double frame_foot_open_length = flange_full_length - 2.*13.*mm;
double frame_foot_open_height = flange_open_height;
G4Box* frame_foot_full = new G4Box("frame_foot_full", 0.5*frame_foot_full_width, 0.5*frame_foot_full_height, 0.5*frame_foot_full_length);
G4Box* frame_foot_open = new G4Box("frame_foot_open", 0.5*frame_foot_open_width, 0.5*frame_foot_open_height, 0.5*frame_foot_open_length);
249
250
251
252
253
254
255
256
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
286
287
288
289
G4VSolid* frame_foot = (G4VSolid*) new G4SubtractionSolid("frame_int1",frame_foot_full,frame_foot_open,0,G4ThreeVector(0,0,0));
G4LogicalVolume* frame_foot_final_vol = new G4LogicalVolume(frame_foot, Al_material, "frame_foot_logic", 0,0,0);
frame_foot_final_vol->SetVisAttributes(m_VisAl);
Tv.setY(posY_frame_foot);
m_EpicVolume->AddPlacedVolume(frame_foot_final_vol, Tv, Rv);
double frame_full_width = frame_foot_open_width;
double frame_full_length = frame_foot_open_length;
double frame_full_height = flange_full_height + 155.5*mm; double posY_frame = posY_PCB + 0.5*PCB_Cu_height + PCB_Rogers_height + 0.5*frame_full_height ;
double frame_open_width = frame_full_width - 2.*2.*mm;
double frame_open_length = frame_full_length - 2.*2.*mm;
double frame_open_height = frame_full_height - 2.*mm;
double frame_open_side_width = frame_foot_full_width;
double frame_open_side_length = frame_full_length - 2.*15.*mm;
double frame_open_side_height = frame_full_height - 2.*15.*mm;
double frame_open_front_width = frame_full_width - 2.*15.*mm;
double frame_open_front_length = frame_foot_full_length ;
double frame_open_front_height = frame_full_height - 2.*15.*mm;
double frame_open_top_width = frame_full_width - 2.*15.*mm;
double frame_open_top_length = frame_full_length - 2.*15.*mm;
double frame_open_top_height = 2.1*mm;
G4Box* frame_full = new G4Box("frame_full" , 0.5*frame_full_width, 0.5*frame_full_height, 0.5*frame_full_length);
G4Box* frame_open1 = new G4Box("frame_open1", 0.5*frame_open_width, 0.5*frame_open_height, 0.5*frame_open_length);
G4Box* frame_open2 = new G4Box("frame_open2", 0.5*frame_open_side_width, 0.5*frame_open_side_height, 0.5*frame_open_side_length);
G4Box* frame_open3 = new G4Box("frame_open3", 0.5*frame_open_front_width, 0.5*frame_open_front_height, 0.5*frame_open_front_length);
G4Box* frame_open4 = new G4Box("frame_open4", 0.5*frame_open_top_width, 0.5*frame_open_top_height, 0.5*frame_open_top_length);
G4VSolid* frame_int1 = (G4VSolid*) new G4SubtractionSolid("frame_int1",frame_full, frame_open1,0,G4ThreeVector(0,-1.01*mm,0));
G4VSolid* frame_int2 = (G4VSolid*) new G4SubtractionSolid("frame_int2",frame_int1, frame_open2,0,G4ThreeVector(0,0,0));
G4VSolid* frame_int3 = (G4VSolid*) new G4SubtractionSolid("frame_int3",frame_int2, frame_open3,0,G4ThreeVector(0,0,0));
G4VSolid* frame_int4 = (G4VSolid*) new G4SubtractionSolid("frame_int4",frame_int3, frame_open4,0,G4ThreeVector(0,0.5*frame_full_height-1.*mm,0));
G4LogicalVolume* frame_final_vol = new G4LogicalVolume(frame_int4, Al_material, "frame_logic", 0,0,0);
frame_final_vol->SetVisAttributes(m_VisAl);
Tv.setY(posY_frame);
m_EpicVolume->AddPlacedVolume(frame_final_vol, Tv, Rv);
//--- TITANE WINDOWS (TO DO)
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
double window_front_width = 142.0*mm;
double window_front_length = 0.1*mm;
double window_front_height = 150.0*mm;
G4Box* window_front = new G4Box("window_front", 0.5*window_front_width, 0.5*window_front_height, 0.5*window_front_length);
G4LogicalVolume* window_front_vol = new G4LogicalVolume(window_front, Ti_material,"window_front_logic",0,0,0);
window_front_vol->SetVisAttributes(m_VisTi);
Tv.setY(posY_frame);
Tv.setZ(-0.5*frame_open_length*mm);
m_EpicVolume->AddPlacedVolume(window_front_vol, Tv, Rv);
Tv.setZ(0.5*frame_open_length*mm);
m_EpicVolume->AddPlacedVolume(window_front_vol, Tv, Rv);
double window_side_width = 0.1*mm;
double window_side_length = 290.0*mm;
double window_side_height = 150.0*mm;
G4Box* window_side = new G4Box("window_side", 0.5*window_side_width, 0.5*window_side_height, 0.5*window_side_length);
G4LogicalVolume* window_side_vol = new G4LogicalVolume(window_side, Ti_material,"window_side_logic",0,0,0);
window_side_vol->SetVisAttributes(m_VisTi);
Tv.setX(0.5*frame_open_width*mm);
Tv.setZ(0);
m_EpicVolume->AddPlacedVolume(window_side_vol, Tv, Rv);
Tv.setX(-0.5*frame_open_width*mm);
m_EpicVolume->AddPlacedVolume(window_side_vol, Tv, Rv);
double window_top_width = 142.0*mm;
double window_top_length = 290.0*mm;
double window_top_height = 0.1*mm;
G4Box* window_top = new G4Box("window_top", 0.5*window_top_width, 0.5*window_top_height, 0.5*window_top_length);
G4LogicalVolume* window_top_vol = new G4LogicalVolume(window_top, Ti_material,"window_top_logic",0,0,0);
window_top_vol->SetVisAttributes(m_VisTi);
Tv.setX(0);
Tv.setY(posY_frame + 0.5*frame_full_height - 2.*mm);
Tv.setZ(0);
m_EpicVolume->AddPlacedVolume(window_top_vol, Tv, Rv);
//--- CENTRAL PART OF THE FISSION CHAMBER
// - Cathodes (TO DO : rajouter les depots)
// - Anodes
// - gas volumes : active gas_AK and gas_KK
double posZ_first_cathode = -1.*(double)m_nA*m_Distance_AK*mm - (double)std::trunc(0.5*m_nA)*m_InterDistance_KK*mm;
// Build the first cathode and the first anode
BuildAnode(posZ_first_cathode + m_Distance_AK*mm);
// Build the central pairs of cathodes back to back, the anodes and the gas_KK
G4Tubs* gas_KK_solid = new G4Tubs("gas_KK",0,37.*mm,0.5*m_InterDistance_KK,0,360*deg);
G4LogicalVolume* gas_KK_vol = new G4LogicalVolume(gas_KK_solid, gas_material,"logic_gas_KK",0,0,0);
gas_KK_vol->SetVisAttributes(m_VisGasKK);
for(int i=1; i<m_nA; i++){
double posZ_current_cathode = posZ_first_cathode + (double)i*2.*m_Distance_AK*mm + (double)(i-0.5)*m_InterDistance_KK*mm ;
BuildCathode(posZ_current_cathode - 0.5*m_InterDistance_KK*mm);
Tv.setY(0);
Tv.setZ(posZ_current_cathode);
m_EpicVolume->AddPlacedVolume(gas_KK_vol, Tv, Rv);
BuildCathode(posZ_current_cathode + 0.5*m_InterDistance_KK*mm);
BuildAnode(posZ_current_cathode + 0.5*m_InterDistance_KK*mm + m_Distance_AK*mm);
// Build the last cathode
BuildCathode(posZ_first_cathode + (double)m_nA*2.*m_Distance_AK*mm + (double)(m_nA-1)*m_InterDistance_KK*mm);
// --- UNACTIVE GAS VOLUME TO DO ?
// Gas Volume //
double gas_height = 15.8*cm;
double gas_width = 14.8*cm;
double gas_length = 29.8*cm;
G4Box* gas_solid = new G4Box("Gas_solid", 0.5*gas_width, 0.5*gas_height, 0.5*gas_length);
G4LogicalVolume* gas_volume = new G4LogicalVolume(gas_solid, gas_material, "gas_logic", 0, 0, 0);
//gas_volume->SetSensitiveDetector(m_EpicScorer);
//m_VisGas->SetForceWireframe(true);
gas_volume->SetVisAttributes(m_VisGas);
m_EpicVolume->AddPlacedVolume(gas_volume, Tv, Rv);
return m_EpicVolume;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Epic::BuildCathode(double Zpos){
// Al plate:
// thickness = 12 um
// external radius = 37 mm
G4Tubs* Al_plate_solid = new G4Tubs("Al_plate",0,37.*mm,6.*micrometer,0,360*deg);
G4Material* Al_material = MaterialManager::getInstance()->GetMaterialFromLibrary("Al");
G4LogicalVolume* Al_vol = new G4LogicalVolume(Al_plate_solid, Al_material,"logic_AlK",0,0,0);
Al_vol->SetVisAttributes(m_VisAl);
G4RotationMatrix *Rv=new G4RotationMatrix(0,0,0);
G4ThreeVector Tv;
Tv.setX(0); Tv.setY(0); Tv.setZ(0);
Tv.setZ(Zpos);
m_EpicVolume->AddPlacedVolume(Al_vol, Tv, Rv);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Epic::BuildAnode(double Zpos){
G4RotationMatrix *Rv=new G4RotationMatrix(0,0,0);
G4ThreeVector Tv;
Tv.setX(0); Tv.setY(0); Tv.setZ(0);
// Get Material
G4Material* Cu_material = MaterialManager::getInstance()->GetMaterialFromLibrary("Cu");
G4Material* Kapton_material = MaterialManager::getInstance()->GetMaterialFromLibrary("Kapton");
G4Material* gas_material = MaterialManager::getInstance()->GetGasFromLibrary(m_GasMaterial, m_Pressure, 300*kelvin);
// Cu plate: 17 um
G4Tubs* Cu_plate_solid = new G4Tubs("Cu_plate",0,37.*mm,0.5*Epic_NS::Cu_Thickness,0,360*deg);
G4LogicalVolume* Cu_vol = new G4LogicalVolume(Cu_plate_solid, Cu_material,"logic_CuA",0,0,0);
Cu_vol->SetVisAttributes(m_VisCu);
// Kapton: 50 um
G4Tubs* Kapton_solid = new G4Tubs("Kapton",0,37.*mm,0.5*Epic_NS::Kapton_Thickness,0,360*deg);
G4LogicalVolume* Kapton_vol = new G4LogicalVolume(Kapton_solid, Kapton_material,"logic_KaptonA",0,0,0);
Kapton_vol->SetVisAttributes(m_VisFCWall);
// Sensitive gas volumes before and after anode (TO DO, several slices instead of a unique gas volume)
G4Tubs* gas_AK_solid = new G4Tubs("gas_AK",0,37.*mm,0.5*m_Distance_AK,0,360*deg);
G4LogicalVolume* gas_AK_vol = new G4LogicalVolume(gas_AK_solid, gas_material,"logic_gas_AK",0,0,0);
gas_AK_vol->SetSensitiveDetector(m_EpicScorer);
gas_AK_vol->SetVisAttributes(m_VisGasAK);
// Build
Tv.setZ(Zpos-0.5*m_Distance_AK*mm);
m_EpicVolume->AddPlacedVolume(gas_AK_vol, Tv, Rv);
Tv.setZ(Zpos-0.5*Epic_NS::Kapton_Thickness-0.5*Epic_NS::Cu_Thickness);
m_EpicVolume->AddPlacedVolume(Cu_vol, Tv, Rv);
Tv.setZ(Zpos);
m_EpicVolume->AddPlacedVolume(Kapton_vol, Tv, Rv);
Tv.setZ(Zpos+0.5*Epic_NS::Kapton_Thickness+0.5*Epic_NS::Cu_Thickness);
m_EpicVolume->AddPlacedVolume(Cu_vol, Tv, Rv);
Tv.setZ(Zpos+0.5*m_Distance_AK*mm);
m_EpicVolume->AddPlacedVolume(gas_AK_vol, Tv, Rv);
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Add Detector branch to the EventTree.
// Called After DetecorConstruction::AddDetector Method
void Epic::InitializeRootOutput(){
RootOutput *pAnalysis = RootOutput::getInstance();
TTree *pTree = pAnalysis->GetTree();
if(!pTree->FindBranch("Epic")){
pTree->Branch("Epic", "TEpicData", &m_Event) ;
}
pTree->SetBranchAddress("Epic", &m_Event) ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Read sensitive part and fill the Root tree.
// Called at in the EventAction::EndOfEventAvtion
void Epic::ReadSensitive(const G4Event* ){
m_Event->Clear();
///////////
// Calorimeter scorer
CalorimeterScorers::PS_Calorimeter* Scorer= (CalorimeterScorers::PS_Calorimeter*) m_EpicScorer->GetPrimitive(0);
unsigned int size = Scorer->GetMult();
for(unsigned int i = 0 ; i < size ; i++){
vector<unsigned int> level = Scorer->GetLevel(i);
double Energy = RandGauss::shoot(Scorer->GetEnergy(i),Epic_NS::ResoEnergy);
if(Energy>Epic_NS::EnergyThreshold){
double Time = RandGauss::shoot(Scorer->GetTime(i),Epic_NS::ResoTime);
int DetectorNbr = level[0];
m_Event->SetEnergy(DetectorNbr,Energy);
m_Event->SetTime(DetectorNbr,Time);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
////////////////////////////////////////////////////////////////
void Epic::InitializeScorers() {
// This check is necessary in case the geometry is reloaded
bool already_exist = false;
m_EpicScorer = CheckScorer("EpicScorer",already_exist) ;
if(already_exist)
return ;
// Otherwise the scorer is initialised
vector<int> level; level.push_back(0);
G4VPrimitiveScorer* Calorimeter= new CalorimeterScorers::PS_Calorimeter("Calorimeter",level, 0) ;
//G4VPrimitiveScorer* Interaction= new InteractionScorers::PS_Interactions("Interaction",ms_InterCoord, 0) ;
//and register it to the multifunctionnal detector
m_EpicScorer->RegisterPrimitive(Calorimeter);
//m_EpicScorer->RegisterPrimitive(Interaction);
G4SDManager::GetSDMpointer()->AddNewDetector(m_EpicScorer) ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
////////////////////////////////////////////////////////////////////////////////
// Construct Method to be pass to the DetectorFactory //
////////////////////////////////////////////////////////////////////////////////
NPS::VDetector* Epic::Construct(){
return (NPS::VDetector*) new Epic();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
////////////////////////////////////////////////////////////////////////////////
// Registering the construct method to the factory //
////////////////////////////////////////////////////////////////////////////////
extern"C" {
class proxy_nps_Epic{
public:
proxy_nps_Epic(){
NPS::DetectorFactory::getInstance()->AddToken("Epic","Epic");
NPS::DetectorFactory::getInstance()->AddDetector("Epic",Epic::Construct);
}
};
proxy_nps_Epic p_nps_Epic;
}