WC_SD.cc

Go to the documentation of this file.
00001 //! \file
00002 //!
00003 //! Source file for Wire_Chamber sensitive detector class.
00004 //!
00005 //! The WC_SD class defines the member functions for processing the hit
00006 //! information whenever a hit is simulated in the detector.  These
00007 //! routines initialise the hit collection, process hits, and perform
00008 //! the end of event action which fills the hit information arrays.
00009 //!
00010 //! \author D.K. Hasell
00011 //! \version 1.0
00012 //! \date 2010-08-28
00013 //!
00014 //! \ingroup detector
00015 
00016 // *+****1****+****2****+****3****+****4****+****5****+****6****+****7****+****
00017 
00018 // Include the WC header files and the user header files referenced here.
00019 
00020 #include "WC_SD.h"
00021 #include "WC_Hit.h"
00022 #include "WC_Data.h"
00023 #include "WC_Messenger.h"
00024 
00025 #include "EventAction.h"
00026 
00027 // Include the GEANT4 header files referenced here.
00028 
00029 #include "G4VSensitiveDetector.hh"
00030 #include "G4HCofThisEvent.hh"
00031 #include "G4SDManager.hh"
00032 #include "G4Step.hh"
00033 #include "G4TouchableHistory.hh"
00034 #include "G4StepPoint.hh"
00035 #include "G4TouchableHandle.hh"
00036 #include "G4ThreeVector.hh"
00037 
00038 #include "Randomize.hh"
00039 
00040 // Use the standard namespace.
00041 
00042 using namespace std;
00043 
00044 // *+****1****+****2****+****3****+****4****+****5****+****6****+****7****+****
00045 
00046 // WC_SD source code.
00047 
00048 // Constructor.
00049 
00050 WC_SD::WC_SD( G4String name ) : G4VSensitiveDetector( name ) {
00051 
00052    // Insert hits collection name.
00053 
00054    collectionName.insert( "WC_HC" );
00055 
00056    // Create pointer to WC_SD Messenger.
00057 
00058    WC_Messenger::Instance()->setWC_SDptr( this );
00059 
00060    // Set defaults.
00061 
00062    WC_threshold = 1.0 * eV;
00063    WC_Xresol = 0.02 * cm;
00064    WC_Yresol = 0.10 * cm;
00065 
00066    // Initially transformations are not defined so Boolean is false.
00067 
00068    for( int i = 0; i < N_WC; ++i ) WC_Transform[i] = false;
00069 
00070 }
00071 
00072 // Destructor.
00073 
00074 WC_SD::~WC_SD(){}
00075 
00076 // Initialise hits collection.
00077 
00078 void WC_SD::Initialize( G4HCofThisEvent * HCE ) {
00079 
00080    WC_HC = new WC_HitsCollection( SensitiveDetectorName, collectionName[0] ); 
00081 
00082    static G4int HCID = -1;   
00083    if( HCID < 0 ) HCID = G4SDManager::GetSDMpointer()->
00084       GetCollectionID(collectionName[0]);
00085 
00086    HCE->AddHitsCollection( HCID, WC_HC );
00087 }
00088 
00089 // Process hits.
00090 
00091 G4bool WC_SD::ProcessHits( G4Step * step, G4TouchableHistory * ROhist ) {
00092 
00093    // Get the total energy deposited in this step.
00094 
00095    G4double edep = step->GetTotalEnergyDeposit();
00096 
00097    // Skip this hit if below threshold.
00098 
00099    if( edep < WC_threshold ) return false;
00100 
00101    // Get the PreStepPoint and the TouchableHandle.
00102 
00103    G4StepPoint * prestep = step->GetPreStepPoint();
00104 
00105    G4TouchableHandle touchable = prestep->GetTouchableHandle();
00106 
00107    // Get copy number (used to identify which WC).
00108 
00109    G4int copyno = touchable->GetCopyNumber( 0 ) +
00110       3 * touchable->GetCopyNumber( 2 );
00111 
00112    // Get the track.
00113 
00114    G4Track * track = step->GetTrack();
00115 
00116    // Get the global time and track ID.
00117 
00118    G4double time = prestep->GetGlobalTime();
00119    G4int tr = track->GetTrackID();
00120 
00121    // Get the true world and local coordinate positions.
00122 
00123    G4ThreeVector trueworld = prestep->GetPosition();
00124 
00125    // If this first time store transformation and inverse.
00126 
00127    if( !WC_Transform[copyno] ) {
00128       WC_WorldtoLocal[copyno] = touchable->GetHistory()->GetTopTransform();
00129       WC_LocaltoWorld[copyno] = WC_WorldtoLocal[copyno].Inverse();
00130       WC_Transform[copyno] = true;
00131    }
00132 
00133    G4ThreeVector Tmp = WC_WorldtoLocal[copyno].TransformPoint(trueworld);
00134 
00135    // Transform actual local coordinates into preferred OLYMPUS coordinates.
00136 
00137    G4ThreeVector truelocal = G4ThreeVector( -Tmp.y(), Tmp.x(), Tmp.z() );
00138 
00139    // Create local and world coordinates smeared by resolution.
00140 
00141    G4ThreeVector local(
00142       truelocal.x() + CLHEP::RandGauss::shoot( 0.0, WC_Xresol ),
00143       truelocal.y() + CLHEP::RandGauss::shoot( 0.0, WC_Yresol ),
00144       truelocal.z() );
00145 
00146    // Transform back to actual local coordinates.
00147 
00148    Tmp = G4ThreeVector( local.y(), -local.x(), local.z() );
00149    
00150    G4ThreeVector world = WC_LocaltoWorld[copyno].TransformPoint(Tmp);
00151 
00152    // Create a pointer to a new Hit.
00153 
00154    WC_Hit * hit = new WC_Hit();
00155 
00156    // Fill the Hit information.
00157 
00158    hit->copyno  = copyno;
00159    hit->trackid = tr;
00160    hit->edep    = edep;
00161    hit->time    = time;
00162    hit->tworld  = trueworld;
00163    hit->tlocal  = truelocal;
00164    hit->world   = world;
00165    hit->local   = local;
00166 
00167    // Add the Hit to the Hit Collection.
00168 
00169    WC_HC->insert( hit );
00170 
00171    //hit->Print();
00172 
00173    return true;
00174 }
00175 
00176 void WC_SD::EndOfEvent( G4HCofThisEvent * HCE ) {
00177 //   PrintAll(); 
00178 
00179    WC_Data * wcdata = EventAction::wcdata;
00180 
00181    wcdata->Reset();
00182 
00183    G4int N_Hits = WC_HC->entries();
00184    
00185    wcdata->nWC = N_Hits;
00186 
00187    for( G4int i = 0; i < N_Hits; ++i ) {
00188 
00189       wcdata->id.push_back( ( *WC_HC )[i]->copyno );
00190       wcdata->tr.push_back( ( *WC_HC )[i]->trackid );
00191 
00192       wcdata->e.push_back( ( *WC_HC )[i]->edep / eV );
00193       wcdata->t.push_back( ( *WC_HC )[i]->time / ns );
00194 
00195       wcdata->tx.push_back( ( *WC_HC )[i]->tworld.x() / cm );
00196       wcdata->ty.push_back( ( *WC_HC )[i]->tworld.y() / cm );
00197       wcdata->tz.push_back( ( *WC_HC )[i]->tworld.z() / cm );
00198 
00199       wcdata->txl.push_back( ( *WC_HC )[i]->tlocal.x() / cm );
00200       wcdata->tyl.push_back( ( *WC_HC )[i]->tlocal.y() / cm );
00201       wcdata->tzl.push_back( ( *WC_HC )[i]->tlocal.z() / cm );
00202 
00203       wcdata->x.push_back( ( *WC_HC )[i]->world.x() / cm );
00204       wcdata->y.push_back( ( *WC_HC )[i]->world.y() / cm );
00205       wcdata->z.push_back( ( *WC_HC )[i]->world.z() / cm );
00206 
00207       wcdata->xl.push_back( ( *WC_HC )[i]->local.x() / cm );
00208       wcdata->yl.push_back( ( *WC_HC )[i]->local.y() / cm );
00209       wcdata->zl.push_back( ( *WC_HC )[i]->local.z() / cm );
00210    }
00211 
00212 }
00213 
00214 void WC_SD::clear(){} 
00215 
00216 void WC_SD::DrawAll() {} 
00217 
00218 // Print all the hits.
00219 
00220 void WC_SD::PrintAll() {
00221    G4int N_Hits = WC_HC->entries();
00222    G4cout << "\nWC Hits Collection N_Hits = " << N_Hits << "\n" << G4endl; 
00223    for ( G4int i = 0; i < N_Hits; ++i ) (*WC_HC)[i]->Print();
00224 } 
00225 
00226 // Set/Get energy threshold.
00227 
00228 G4double WC_SD::setThreshold( G4double thres ) { return WC_threshold = thres; }
00229 G4double WC_SD::getThreshold() { return WC_threshold; }
00230 
00231 // Set/Get X resolution.
00232 
00233 G4double WC_SD::setXresol( G4double res ) { return WC_Xresol = res; }
00234 G4double WC_SD::getXresol() { return WC_Xresol; }
00235 
00236 // Set/Get Y resolution.
00237 
00238 G4double WC_SD::setYresol( G4double res ) { return WC_Yresol = res; }
00239 G4double WC_SD::getYresol() { return WC_Yresol; }
00240