Wire_Chamber.cc

Go to the documentation of this file.
00001 //! \file
00002 //!
00003 //! Source file for Wire_Chamber class.
00004 //!
00005 //! The Wire_Chamber class is used to build the WC tracking detector for the
00006 //! OLYMPUS detector simulation.
00007 //!
00008 //! \author D.K. Hasell
00009 //! \version 1.0
00010 //! \date 2010-08-28
00011 //!
00012 //! \ingroup detector
00013 
00014 // *+****1****+****2****+****3****+****4****+****5****+****6****+****7****+****
00015 
00016 // Include the WC header file and the user header files referenced here.
00017 
00018 #include "Wire_Chamber.h"
00019 #include "WC_SD.h"
00020 
00021 // Include the GEANT4 header files referenced here.
00022 
00023 #include "G4VPhysicalVolume.hh"
00024 #include "G4Trap.hh"
00025 #include "G4LogicalVolume.hh"
00026 #include "G4Material.hh"
00027 #include "G4VisAttributes.hh"
00028 #include "G4Colour.hh"
00029 #include "G4SubtractionSolid.hh"
00030 #include "G4PVPlacement.hh"
00031 #include "G4ThreeVector.hh"
00032 #include "G4RotationMatrix.hh"
00033 
00034 #include "G4SDManager.hh"
00035 
00036 // Use the standard namespace.
00037 
00038 using namespace std;
00039 
00040 // *+****1****+****2****+****3****+****4****+****5****+****6****+****7****+****
00041 
00042 // Routines in the OLYMPUS Wire_Chamber class.
00043 
00044 // Constructor.
00045 
00046 Wire_Chamber::Wire_Chamber() {}
00047 
00048 // Destructor.
00049 
00050 Wire_Chamber::~Wire_Chamber() {}
00051 
00052 // Member function to build the Wire_Chamber.
00053 
00054 void Wire_Chamber::Build( G4VPhysicalVolume * World_phys ) {
00055 
00056    // Building the WC detector.
00057 
00058    cout << "Building the Wire_Chamber.\n" << flush;
00059 
00060    // Define the outer WC trapezoid parameters.
00061    
00062    G4double TDz     = 105.2866 / 2.0 * cm;
00063    G4double TTheta  =  31.72 * degree;
00064    G4double TPhi    =  90.00 * degree;
00065    G4double TDYn    = 147.6676 / 2.0 * cm;
00066    G4double TDXnn   =  57.6334 / 2.0 * cm;
00067    G4double TDXnp   =  22.9713 / 2.0 * cm;
00068    G4double TAlphan =   0.0;
00069    G4double TDYp    = 311.6788 / 2.0 * cm;
00070    G4double TDXpn   = 143.4856 / 2.0 * cm;
00071    G4double TDXpp   =  70.3245 / 2.0 * cm;
00072    G4double TAlphap =   0.0;
00073    
00074    // Create the WC volume.
00075    
00076    G4Trap * WC_solid = new G4Trap( "WC_solid", TDz, TTheta, TPhi,
00077                                    TDYn, TDXnn, TDXnp, TAlphan,
00078                                    TDYp, TDXpn, TDXpp, TAlphap );
00079 
00080    G4LogicalVolume * WC_log = new
00081       G4LogicalVolume(  WC_solid, G4Material::GetMaterial( "G4_AIR" ),
00082                         "WC_log", 0, 0, 0, true );
00083    
00084    WC_log->SetVisAttributes( G4VisAttributes( false, G4Colour() ) );
00085 
00086    // Define the inner or gas volume WC trapezoid parameters.
00087    
00088    TDz     = ( 105.2866 + 0.025 ) / 2.0 * cm;     // Add extra to break edges.
00089    TTheta  =  31.72 * degree;
00090    TPhi    =  90.00 * degree;
00091    TDYn    = 137.2776 / 2.0 * cm;
00092    TDXnn   =  52.8602 / 2.0 * cm;
00093    TDXnp   =  20.6370 / 2.0 * cm;
00094    TAlphan =   0.0;
00095    TDYp    = 301.2888 / 2.0 * cm;
00096    TDXpn   = 121.7356 / 2.0 * cm;
00097    TDXpp   =  51.0140 / 2.0 * cm;
00098    TAlphap =   0.0;
00099    
00100    // Create the inner or gas WC volume.
00101    
00102    G4Trap * WC_gas_solid = new G4Trap( "WC_gas_solid", TDz, TTheta, TPhi,
00103                                        TDYn, TDXnn, TDXnp, TAlphan,
00104                                        TDYp, TDXpn, TDXpp, TAlphap );
00105    
00106    G4LogicalVolume * WC_gas_log = new
00107       G4LogicalVolume( WC_gas_solid, G4Material::GetMaterial( "WC_gas" ),
00108                        "WC_gas_log", 0, 0, 0, true );
00109    
00110    WC_gas_log->SetVisAttributes( G4VisAttributes( false, G4Colour() ) );
00111 
00112    // Create the WC frame solid as the difference between WC and inner (gas).
00113    
00114    G4SubtractionSolid * WC_frame_solid = new
00115       G4SubtractionSolid( "WC_frame_solid", WC_solid, WC_gas_solid );
00116    
00117    G4LogicalVolume * WC_frame_log = new
00118       G4LogicalVolume(  WC_frame_solid, G4Material::GetMaterial( "G4_Al" ),
00119                         "WC_frame_log", 0, 0, 0, true );
00120    
00121    WC_frame_log->SetVisAttributes(
00122       G4VisAttributes( true, G4Colour( 0.8, 0.8, 0 ) ) );
00123 
00124    // Define planes at the centre of the three chambers to be sensitive.
00125 
00126    // First sensitive plane.
00127 
00128    G4double ZC       =  22.0107 / 2.0 * cm;
00129 
00130    G4double nTDz     =   0.1000 / 2.0 * cm;
00131 
00132    G4double scalen    = ( ZC - nTDz ) / TDz / 2.0;
00133    G4double scalep    = ( ZC + nTDz ) / TDz / 2.0;
00134 
00135    G4double nTDYn    = TDYn  + ( TDYp  - TDYn  ) * scalen;
00136    G4double nTDXnn   = TDXnn + ( TDXpn - TDXnn ) * scalen;
00137    G4double nTDXnp   = TDXnp + ( TDXpp - TDXnp ) * scalen;
00138    G4double nTDYp    = TDYn  + ( TDYp  - TDYn  ) * scalep;
00139    G4double nTDXpn   = TDXnn + ( TDXpn - TDXnn ) * scalep;
00140    G4double nTDXpp   = TDXnp + ( TDXpp - TDXnp ) * scalep;
00141    
00142    // Create the first WC sensitive plane.
00143    
00144    G4Trap * WC_p1 = new G4Trap( "WC_p1", nTDz, TTheta, TPhi,
00145                                 nTDYn, nTDXnn, nTDXnp, TAlphan,
00146                                 nTDYp, nTDXpn, nTDXpp, TAlphap );
00147 
00148    G4LogicalVolume * WC_p1_log = new
00149       G4LogicalVolume( WC_p1, G4Material::GetMaterial( "WC_gas" ),
00150                        "WC_p1_log", 0, 0, 0, true );
00151    
00152    WC_p1_log->SetVisAttributes( G4VisAttributes( false, G4Colour() ) );   
00153 
00154    new G4PVPlacement( 0, G4ThreeVector( 0.0,
00155                                         ( ZC - TDz ) * sin( TTheta ),
00156                                         ZC - TDz ),
00157                       WC_p1_log, "WC_p1_phys", WC_gas_log, false, 0, false );
00158 
00159    // Second sensitive plane.
00160 
00161    ZC       = ( 22.0107 + 14.6 +  32.1 / 2.0 ) * cm;
00162 
00163    scalen    = ( ZC - nTDz ) / TDz / 2.0;
00164    scalep    = ( ZC + nTDz ) / TDz / 2.0;
00165 
00166    nTDYn    = TDYn  + ( TDYp  - TDYn  ) * scalen;
00167    nTDXnn   = TDXnn + ( TDXpn - TDXnn ) * scalen;
00168    nTDXnp   = TDXnp + ( TDXpp - TDXnp ) * scalen;
00169    nTDYp    = TDYn  + ( TDYp  - TDYn  ) * scalep;
00170    nTDXpn   = TDXnn + ( TDXpn - TDXnn ) * scalep;
00171    nTDXpp   = TDXnp + ( TDXpp - TDXnp ) * scalep;
00172    
00173    // Create the second WC sensitive plane.
00174    
00175    G4Trap * WC_p2 = new G4Trap( "WC_p2", nTDz, TTheta, TPhi,
00176                                   nTDYn, nTDXnn, nTDXnp, TAlphan,
00177                                   nTDYp, nTDXpn, nTDXpp, TAlphap );
00178 
00179    G4LogicalVolume * WC_p2_log = new
00180       G4LogicalVolume( WC_p2, G4Material::GetMaterial( "WC_gas" ),
00181                        "WC_p2_log", 0, 0, 0, true );
00182    
00183    WC_p2_log->SetVisAttributes( G4VisAttributes( false, G4Colour() ) );   
00184 
00185    new G4PVPlacement( 0, G4ThreeVector( 0.0,
00186                                         ( ZC - TDz ) * sin( TTheta ),
00187                                         ZC - TDz ),
00188                       WC_p2_log, "WC_p2_phys", WC_gas_log, false, 1, false );
00189 
00190    // Third sensitive plane.
00191 
00192    ZC       = ( 22.0107 + 14.6 +  32.1 + 14.6 + 21.9761 / 2.0 ) * cm;
00193 
00194    scalen    = ( ZC - nTDz ) / TDz / 2.0;
00195    scalep    = ( ZC + nTDz ) / TDz / 2.0;
00196 
00197    nTDYn    = TDYn  + ( TDYp  - TDYn  ) * scalen;
00198    nTDXnn   = TDXnn + ( TDXpn - TDXnn ) * scalen;
00199    nTDXnp   = TDXnp + ( TDXpp - TDXnp ) * scalen;
00200    nTDYp    = TDYn  + ( TDYp  - TDYn  ) * scalep;
00201    nTDXpn   = TDXnn + ( TDXpn - TDXnn ) * scalep;
00202    nTDXpp   = TDXnp + ( TDXpp - TDXnp ) * scalep;
00203    
00204    // Create the third WC sensitive plane.
00205    
00206    G4Trap * WC_p3 = new G4Trap( "WC_p3", nTDz, TTheta, TPhi,
00207                                 nTDYn, nTDXnn, nTDXnp, TAlphan,
00208                                 nTDYp, nTDXpn, nTDXpp, TAlphap );
00209 
00210    G4LogicalVolume * WC_p3_log = new
00211       G4LogicalVolume( WC_p3, G4Material::GetMaterial( "WC_gas" ),
00212                        "WC_p3_log", 0, 0, 0, true );
00213    
00214    WC_p3_log->SetVisAttributes( G4VisAttributes( false, G4Colour() ) );   
00215 
00216    new G4PVPlacement( 0, G4ThreeVector( 0.0,
00217                                         ( ZC - TDz ) * sin( TTheta ),
00218                                         ZC - TDz ),
00219                       WC_p3_log, "WC_p3_phys", WC_gas_log, false, 2, false );
00220 
00221    // Create the sensitive detectors.
00222    
00223    WC_SD * SD = new WC_SD( "OLYMPUS/WC" );
00224 
00225    G4SDManager::GetSDMpointer()->AddNewDetector( SD );      
00226    
00227    WC_p1_log->SetSensitiveDetector( SD );
00228    WC_p2_log->SetSensitiveDetector( SD );
00229    WC_p3_log->SetSensitiveDetector( SD );
00230 
00231    // Place WC_frame in WC logical volume.
00232    
00233    new G4PVPlacement( 0, G4ThreeVector(), WC_frame_log, "WC_frame_phys",
00234                       WC_log, false, 0, false );
00235    
00236    // Place WC_gas in WC logical volume.
00237    
00238    new G4PVPlacement( 0, G4ThreeVector(), WC_gas_log, "WC_gas_phys",
00239                       WC_log, false, 0, false );
00240    
00241    // Place the wire chamber in the mother volume.
00242 
00243    // Define a rotation matrix for the left sector.
00244    
00245    // NOTE after these rotations the local WC coordinate system has Z pointing
00246    // away from the target, X is vertically up, and Y points downstream.
00247 
00248    G4RotationMatrix * RotationL = new G4RotationMatrix;
00249    
00250    RotationL->rotateY( -90.0 * degree );
00251    RotationL->rotateZ( -90.0 * degree );
00252    RotationL->rotateX( 16.46 * degree );
00253    
00254    // Centre of chamber.
00255    
00256    G4double R     = 157.11 * cm;
00257    G4double Theta =  42.20 * degree;
00258    
00259    // Calculate some trig. functions.
00260    
00261    G4double costheta = cos( Theta );
00262    G4double sintheta = sin( Theta );
00263    G4double cosphi   = cos( 0.0 * degree );
00264    G4double sinphi   = sin( 0.0 * degree );
00265    
00266    // Create the WC physical volume and place it in the left sector.
00267    
00268    new G4PVPlacement( RotationL,
00269                       G4ThreeVector( R * sintheta * cosphi,
00270                                      R * sintheta * sinphi,
00271                                      R * costheta ),
00272                       "WC_phys", WC_log, World_phys, false, 0, false );
00273 
00274    // Define a new rotation matrix for the right sector.
00275 
00276    // NOTE after these rotations the local WC coordinate system has Z pointing
00277    // away from the target, X is vertically down, and Y points downstream.
00278 
00279    G4RotationMatrix * RotationR = new G4RotationMatrix;
00280    
00281    RotationR->rotateY( 90.0 * degree );
00282    RotationR->rotateZ( 90.0 * degree );
00283    RotationR->rotateX( 16.46 * degree );
00284    
00285    // Calculate some trig. functions.
00286    
00287    cosphi   = cos( 180.0 * degree );
00288    sinphi   = sin( 180.0 * degree );
00289    
00290    // Create the WC physical volume and place it in the world volume.
00291    
00292    new G4PVPlacement( RotationR,
00293                       G4ThreeVector( R * sintheta * cosphi,
00294                                      R * sintheta * sinphi,
00295                                      R * costheta ),
00296                       "WC_phys", WC_log, World_phys, false, 1, false );
00297 
00298    cout << "     Done.\n" << endl << flush;
00299 
00300    // That's All Folks !
00301 
00302    return;
00303 
00304 }
00305