Skip to content
Snippets Groups Projects
DetectorConstruction.cc 8.35 KiB
Newer Older
Chad Lantz's avatar
Chad Lantz committed
// ********************************************************************
// * License and Disclaimer                                           *
// *                                                                  *
// * The  Geant4 software  is  copyright of the Copyright Holders  of *
// * the Geant4 Collaboration.  It is provided  under  the terms  and *
// * conditions of the Geant4 Software License,  included in the file *
// * LICENSE and available at  http://cern.ch/geant4/license .  These *
// * include a list of copyright holders.                             *
// *                                                                  *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work  make  any representation or  warranty, express or implied, *
// * regarding  this  software system or assume any liability for its *
// * use.  Please see the license in the file  LICENSE  and URL above *
// * for the full disclaimer and the limitation of liability.         *
// *                                                                  *
// * This  code  implementation is the result of  the  scientific and *
// * technical work of the GEANT4 collaboration.                      *
// * By using,  copying,  modifying or  distributing the software (or *
// * any work based  on the software)  you  agree  to acknowledge its *
// * use  in  resulting  scientific  publications,  and indicate your *
// * acceptance of all terms of the Geant4 Software license.          *
// ********************************************************************
//
clantz's avatar
clantz committed
/// \file /src/DetectorConstruction.cc
/// \brief Implementation of the DetectorConstruction class
Chad Lantz's avatar
Chad Lantz committed
//
//
clantz's avatar
clantz committed
#include "DetectorConstruction.hh"
#include "Materials.hh"
clantz's avatar
clantz committed
#include "PMTSD.hh"
Chad Lantz's avatar
Chad Lantz committed

#include <math.h>

// GEANT4 //
Chad Lantz's avatar
Chad Lantz committed
#include "G4Element.hh"
clantz's avatar
clantz committed
#include "G4SDManager.hh"
Chad Lantz's avatar
Chad Lantz committed
#include "G4LogicalBorderSurface.hh"
#include "G4LogicalSkinSurface.hh"
#include "G4OpticalSurface.hh"
#include "G4ThreeVector.hh"
#include "G4PVPlacement.hh"
#include "G4SystemOfUnits.hh"
#include "G4Tubs.hh"
#include "G4Trd.hh"
#include "G4SubtractionSolid.hh"
#include "G4NistManager.hh"
#include "G4VisAttributes.hh"
#include "G4Colour.hh"
clantz's avatar
clantz committed

clantz's avatar
clantz committed
#ifdef G4LIB_USE_GDML
#include "G4GDMLParser.hh"
clantz's avatar
clantz committed
#endif
clantz's avatar
clantz committed
#ifdef CADMESH
clantz's avatar
clantz committed
#endif
Chad Lantz's avatar
Chad Lantz committed

/*
 *
 */
clantz's avatar
clantz committed
DetectorConstruction::DetectorConstruction()
Chad Lantz's avatar
Chad Lantz committed
 : G4VUserDetectorConstruction(){
   materials = Materials::getInstance();
}


/*
 *
 */
clantz's avatar
clantz committed
DetectorConstruction::~DetectorConstruction(){
clantz's avatar
clantz committed
/* Detector construction is currently all done here
 * Breaking out into modules may be done later
Chad Lantz's avatar
Chad Lantz committed
 */
clantz's avatar
clantz committed
G4VPhysicalVolume* DetectorConstruction::Construct(){
Chad Lantz's avatar
Chad Lantz committed
  //Set up the materials
  materials->UseOpticalMaterials(true);
  materials->DefineOpticalProperties();
  G4Material* Air = materials->Air;
  G4Material* Al = materials->Al;
  G4Material* Silica = materials->pQuartz;

clantz's avatar
clantz committed
  //Set the lightguide height. Hardcoded for now,
  //should be determined by the model dimensions
clantz's avatar
clantz committed
  G4double lgHeight = 339.*mm/2;
Chad Lantz's avatar
Chad Lantz committed

  bool checkOverlaps = false;

  //----------------- Define the world volume -----------------//
  m_solidWorld =
    new G4Box("World", //name
              0.25*m,  //sizeX
              0.25*m,  //sizeY
              0.5*m);  //sizeZ

  m_logicWorld =
    new G4LogicalVolume(m_solidWorld, //solid
                        Air,          //material
                        "World");     //name

  m_physWorld =
    new G4PVPlacement(0,                  //no rotation
                      G4ThreeVector(),    //at (0,0,0)
                      m_logicWorld,       //logical volume
                      "World",            //name
                      0,                  //mother  volume
                      false,              //no boolean operation
                      0,                  //copy number
                      checkOverlaps);     //overlaps checking

  G4VisAttributes* boxVisAtt_world= new G4VisAttributes(G4VisAttributes::Invisible);
Chad Lantz's avatar
Chad Lantz committed

	m_logicWorld ->SetVisAttributes(boxVisAtt_world);


  //----------------- Make the light guide -----------------//
clantz's avatar
clantz committed
  ////////////////////This got all sorts of fucked up. I'll probably drop GDML support or make it required
  materials->AlSurface->SetSigmaAlpha(fRoughness);

  //If we have defined a CAD file, use it
  if(filename != ""){

    // CAD model rotation.
    G4RotationMatrix * rot = new G4RotationMatrix();
    rot->rotateZ(90*deg);
    rot->rotateY(-90*deg);

clantz's avatar
clantz committed
    //Import the cad model and place it
    #ifdef CADMESH
    if(filetype != "gdml"){
      CADMesh* mesh = new CADMesh((char*) filename.c_str());
      mesh->SetScale(mm);
      mesh->SetOffset( G4ThreeVector(-20*cm, 0, 0) );
      mesh->SetReverse(false);

      cad_logical =
        new G4LogicalVolume(mesh->TessellatedMesh(), //solid
                            Al,                      //material
                            "LightGuide");           //name
    }
    #elif defined G4LIB_USE_GDML
    if(filetype == "gdml"){
      fParser.Read(fReadFile);
      break;
    }
    if(filetype == "step"){
      cad_logical = fParser.ParseST(filename,Air,Al);
    }

    if(cad_logical !=0 ){
      cad_physical =
        new G4PVPlacement(0, //rot,
                          G4ThreeVector(0,0,lgHeight-(3*cm)),
                          cad_logical,
                          "cad_physical",
                          m_logicWorld,
                          false,
                          0);
    }

    //If output to GDML if requested and supported
    #ifdef G4LIB_USE_GDML
      if(GDMLoutput != ""){
        G4GDMLParser* gdml = new G4GDMLParser();
        gdml->Write("GDMLoutput",cad_physical);
      }
clantz's avatar
clantz committed
    #endif
clantz's avatar
clantz committed
    //Make the surface optically reflective
    G4LogicalSkinSurface* alumLSS =
      new G4LogicalSkinSurface("AlSkinSurface",
                               cad_logical,
                               materials->AlSurface );

Chad Lantz's avatar
Chad Lantz committed
  }else{
    //Create a trapezoidal air light guide made of aluminum sheet
    G4double thickness = 1.0*mm;
    G4double LengthX   = 89.75*mm/2;
    G4double LengthY   = 164.*mm/2;
clantz's avatar
clantz committed
    G4double PMTwindow = 45.969*mm/2;
    G4double HeightZ   = lgHeight;
Chad Lantz's avatar
Chad Lantz committed

    //Aluminum outter
    G4Trd* outter =
      new G4Trd("BasicLightGuide",
                LengthX+thickness,
                PMTwindow+thickness,
                LengthY+thickness,
                PMTwindow+thickness,
                HeightZ+thickness);
    //Air inner
    G4Trd* inner =
      new G4Trd("AirVolume",
                LengthX,
                PMTwindow,
                LengthY,
                PMTwindow,
                HeightZ+2.0*mm);

    //Subtract material to hollow out the light guide
    G4SubtractionSolid* LightGuide =
      new G4SubtractionSolid("BasicLightGuide",
                             outter,
                             inner);

    G4LogicalVolume* logicLightGuide =
      new G4LogicalVolume(LightGuide,
                          Al,
                          "BasicLightGuide");

    G4VPhysicalVolume*  physLightGuide =
      new G4PVPlacement(0,
                        G4ThreeVector(0, 0, HeightZ),
                        logicLightGuide,
                        "BasicLightGuide",
                        m_logicWorld,
                        false,
                        0);

    G4LogicalSkinSurface* alumLSS =
      new G4LogicalSkinSurface("AlSkinSurface",
                               logicLightGuide,
                               materials->AlSurface );
Chad Lantz's avatar
Chad Lantz committed

clantz's avatar
clantz committed
  }//end else
Chad Lantz's avatar
Chad Lantz committed


  //----------------- Define PMT window -----------------//
  double PMTradius = 65.0/2*mm;
  G4SDManager* SDman = G4SDManager::GetSDMpointer();
clantz's avatar
clantz committed
  PMTSD* PMT = new PMTSD("MyPMT");
  SDman->AddNewDetector( PMT );

  G4Tubs* solidPMT =
    new G4Tubs("PMT",     //name
              0.0*mm,     //Inner radius
              PMTradius,  //Outter radius
              0.5*mm,     //Height
              0.0*deg,    //Rotation start
              360.0*deg); //Sweep

  G4LogicalVolume* logicPMT =
    new G4LogicalVolume(solidPMT,   //solid
                        Air,        //material
                        "PMT");     //name

  G4VPhysicalVolume*  physPMT =
    new G4PVPlacement(0,
clantz's avatar
clantz committed
                      G4ThreeVector(0, 0, 2*lgHeight + 1.5*mm),
                      logicPMT,
                      "PMT",
                      m_logicWorld,
                      false,
                      0);

  logicPMT->SetSensitiveDetector( PMT );
Chad Lantz's avatar
Chad Lantz committed

  return m_physWorld;
}