Skip to content
Snippets Groups Projects
Epic.cc 22.7 KiB
Newer Older
/*****************************************************************************
 * 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 
  m_R.push_back(POS.mag());
  m_Theta.push_back(POS.theta());
  m_Phi.push_back(POS.phi());
}



//....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_InterDistance_KK = InterDistance_KK;
      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){
  for (unsigned short i = 0 ; i < m_R.size() ; i++) {
    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);
  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);
  m_EpicVolume->AddPlacedVolume(flange_vol, Tv, Rv);
  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);
 
  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)
  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
  BuildCathode(posZ_first_cathode);
  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);
  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);

}
//....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;
}