TF_SD.cc

Go to the documentation of this file.
00001 //! \file
00002 //!
00003 //! Source file for Time_of_Flight sensitive detector class.
00004 //!
00005 //! The TF_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-10-30
00013 //!
00014 //! \ingroup detector
00015 
00016 // *+****1****+****2****+****3****+****4****+****5****+****6****+****7****+****
00017 
00018 // Include the TF header files and the user header files referenced here..
00019 
00020 #include "TF_SD.h"
00021 #include "TF_Hit.h"
00022 #include "TF_Data.h"
00023 #include "TF_Messenger.h"
00024 
00025 #include "EventAction.h"
00026 
00027 // Include the GEANT4 header files used below.
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 // TF_SD source code.
00047 
00048 // Constructor.
00049 
00050 TF_SD::TF_SD( G4String name ) : G4VSensitiveDetector( name ) {
00051 
00052    // Insert hits collection name.
00053 
00054    collectionName.insert( "TF_HC" );
00055 
00056    // Create pointer to GT SD Messenger.
00057 
00058    TF_Messenger::Instance()->setTF_SDptr( this );
00059 
00060    // Set defaults.
00061 
00062    TF_threshold = 100.0 * eV;
00063    TF_Tresol    =   1.0 * ns;
00064    TF_Yresol    =  10.0 * cm;
00065 
00066    // Initially transformations are not defined so Boolean is false.
00067 
00068    for( int i = 0; i < N_TF; ++i ) TF_Transform[i] = false;
00069 }
00070 
00071 // Destructor.
00072 
00073 TF_SD::~TF_SD(){}
00074 
00075 // Initialize hits collection.
00076 
00077 void TF_SD::Initialize( G4HCofThisEvent * HCE ) {
00078 
00079    TF_HC = new TF_HitsCollection( SensitiveDetectorName, collectionName[0] ); 
00080 
00081    static G4int HCID = -1;   
00082    if( HCID < 0 ) HCID = G4SDManager::GetSDMpointer()->
00083                      GetCollectionID(collectionName[0]);
00084 
00085    HCE->AddHitsCollection( HCID, TF_HC );
00086 }
00087 
00088 // Process hits.
00089 
00090 G4bool TF_SD::ProcessHits( G4Step * step, G4TouchableHistory * ROhist ) {
00091 
00092    // Get the total energy deposited in this step.
00093 
00094    G4double edep = step->GetTotalEnergyDeposit();
00095 
00096    // Skip this hit if below threshold.
00097 
00098    if( edep < TF_threshold ) return false;
00099 
00100    // Get the PreStepPoint and the TouchableHandle.
00101 
00102    G4StepPoint * prestep = step->GetPreStepPoint();
00103 
00104    G4TouchableHandle touchable = prestep->GetTouchableHandle();
00105 
00106    // Get copy number (used to identify which TF).
00107 
00108    G4int copyno = touchable->GetCopyNumber();
00109 
00110    // Get the track.
00111 
00112    G4Track * track = step->GetTrack();
00113 
00114    // Get the global time and track ID.
00115 
00116    G4double ttime = prestep->GetGlobalTime();
00117    G4double time  = ttime + CLHEP::RandGauss::shoot( 0.0, TF_Tresol );
00118 
00119    G4int id = 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( !TF_Transform[copyno] ) {
00128       TF_WorldtoLocal[copyno] = touchable->GetHistory()->GetTopTransform();
00129       TF_LocaltoWorld[copyno] = TF_WorldtoLocal[copyno].Inverse();
00130       TF_Transform[copyno] = true;
00131    }
00132 
00133    G4ThreeVector truelocal = TF_WorldtoLocal[copyno].TransformPoint(trueworld);
00134 
00135    // Create local and world coordinates smeared by resolution.
00136 
00137    G4ThreeVector local( 0.0, 
00138       truelocal.y() + CLHEP::RandGauss::shoot( 0.0, TF_Yresol ), 0.0 );
00139 
00140    G4ThreeVector world = TF_LocaltoWorld[copyno].TransformPoint(local);
00141 
00142    // Create a pointer to a new Hit.
00143 
00144    TF_Hit * hit = new TF_Hit();
00145 
00146    // Fill the Hit information.
00147 
00148    hit->copyno  = copyno;
00149    hit->trackid = id;
00150    hit->edep    = edep;
00151    hit->ttime   = ttime;
00152    hit->time    = time;
00153    hit->tworld  = trueworld;
00154    hit->tlocal  = truelocal;
00155    hit->world   = world;
00156    hit->local   = local;
00157 
00158    // Add the Hit to the Hit Collection.
00159 
00160    TF_HC->insert( hit );
00161    
00162    //hit->Print();
00163 
00164    return true;
00165 }
00166 
00167 // Routine to process the hits at the end of an event.
00168 
00169 void TF_SD::EndOfEvent( G4HCofThisEvent * HCE ){
00170 
00171    TF_Data * tfdata = EventAction::tfdata;
00172 
00173    tfdata->Reset();
00174 
00175    G4int N_Hits = TF_HC->entries();
00176    
00177    tfdata->nTF = N_Hits;
00178 
00179    for( G4int i = 0; i < N_Hits; ++i ) {
00180 
00181       tfdata->id.push_back( ( *TF_HC )[i]->copyno );
00182       tfdata->tr.push_back( ( *TF_HC )[i]->trackid );
00183 
00184       tfdata->e.push_back( ( *TF_HC )[i]->edep / MeV );
00185       tfdata->tt.push_back( ( *TF_HC )[i]->ttime / ns );
00186       tfdata->t.push_back( ( *TF_HC )[i]->time / ns );
00187 
00188       tfdata->tx.push_back( ( *TF_HC )[i]->tworld.x() / cm );
00189       tfdata->ty.push_back( ( *TF_HC )[i]->tworld.y() / cm );
00190       tfdata->tz.push_back( ( *TF_HC )[i]->tworld.z() / cm );
00191 
00192       tfdata->txl.push_back( ( *TF_HC )[i]->tlocal.x() / cm );
00193       tfdata->tyl.push_back( ( *TF_HC )[i]->tlocal.y() / cm );
00194       tfdata->tzl.push_back( ( *TF_HC )[i]->tlocal.z() / cm );
00195 
00196       tfdata->x.push_back( ( *TF_HC )[i]->world.x() / cm );
00197       tfdata->y.push_back( ( *TF_HC )[i]->world.y() / cm );
00198       tfdata->z.push_back( ( *TF_HC )[i]->world.z() / cm );
00199 
00200       tfdata->xl.push_back( ( *TF_HC )[i]->local.x() / cm );
00201       tfdata->yl.push_back( ( *TF_HC )[i]->local.y() / cm );
00202       tfdata->zl.push_back( ( *TF_HC )[i]->local.z() / cm );
00203    }
00204 
00205 }
00206 
00207 void TF_SD::clear(){} 
00208 
00209 void TF_SD::DrawAll() {} 
00210 
00211 // Print all the hits.
00212 
00213 void TF_SD::PrintAll() {
00214    G4int N_Hits = TF_HC->entries();
00215    G4cout << "\nTF Hits Collection N_Hits = " << N_Hits << "\n" << G4endl; 
00216    for ( G4int i = 0; i < N_Hits; ++i ) (*TF_HC)[i]->Print();
00217 } 
00218 
00219 // Set/Get energy threshold.
00220 
00221 G4double TF_SD::setThreshold( G4double thres ) { return TF_threshold = thres; }
00222 G4double TF_SD::getThreshold() { return TF_threshold; }
00223 
00224 // Set/Get T resolution.
00225 
00226 G4double TF_SD::setTresol( G4double res ) { return TF_Tresol = res; }
00227 G4double TF_SD::getTresol() { return TF_Tresol; }
00228 
00229 // Set/Get Y resolution.
00230 
00231 G4double TF_SD::setYresol( G4double res ) { return TF_Yresol = res; }
00232 G4double TF_SD::getYresol() { return TF_Yresol; }