00001 #include "UnObserverStepAction.h"
00002
00003 #include "Event/SimUnobservableStatisticsHeader.h"
00004
00005 #include "G4Step.hh"
00006 #include "G4StepPoint.hh"
00007 #include "G4Navigator.hh"
00008
00009 #include "RuleParser/Rules.h"
00010 #include "RuleParser/CreateRules.h"
00011
00012 #include "G4DataHelpers/IHistoryKeeper.h"
00013
00014 #include "GaudiKernel/DeclareFactoryEntries.h"
00015
00016 DECLARE_TOOL_FACTORY(UnObserverStepAction);
00017
00018 using namespace DayaBay;
00019
00020
00021 struct AddableVector : public std::vector<std::string>
00022 {
00023 AddableVector& add(const std::string& s) { push_back(s); return *this; }
00024 };
00025
00026 UnObserverStepAction::UnObserverStepAction (
00027 const std::string& type ,
00028 const std::string& name ,
00029 const IInterface* parent )
00030 : QueriableStepAction( type , name , parent )
00031 , m_Stats()
00032 {
00033
00034 m_Stats.push_back(AddableVector().add("photon_created_energy" ).add( "E" ).add( "StepNumber==1 and pdg==20022" ) );
00035 m_Stats.push_back(AddableVector().add("photon_backscatter_r" ).add( "local_r" ).add( "pdg==20022 and dAngle >= 90" ) );
00036 m_Stats.push_back(AddableVector().add("photon_forescatter_r" ).add( "local_r" ).add( "pdg==20022 and (dAngle <= 90 and dAngle > 0)" ) );
00037 m_Stats.push_back(AddableVector().add("photon_stop_r" ).add( "local_r" ).add( "(pdg==20022) and ((IsStopping == 1) and (LogicalVolumeName == '/dd/Geometry/PMT/lvPmtHemi'))" ) );
00038 m_Stats.push_back(AddableVector().add("pmt_hit" ).add( "t" ).add( "pdg==20022 and (IsStopping == 1 and (LogicalVolumeName=='/dd/Geometry/PMT/lvPmtHemi'))" ) );
00039 m_Stats.push_back(AddableVector().add("edep-water").add( "dE").add( "pdg!=20022 and (MaterialName == '/dd/Materials/Water')") );
00040 m_Stats.push_back(AddableVector().add("edep-oil").add( "dE").add( "pdg!=20022 and (MaterialName == '/dd/Materials/Oil')") );
00041 m_Stats.push_back(AddableVector().add("edep-ls").add( "dE").add( "pdg!=20022 and (MaterialName == '/dd/Materials/LiquidScintillator')") );
00042 m_Stats.push_back(AddableVector().add("edep-gdls").add( "dE").add( "pdg!=20022 and (MaterialName == '/dd/Materials/GdDopedLS')") );
00043 m_Stats.push_back(AddableVector().add("edep-acryilc").add("dE").add( "pdg!=20022 and (MaterialName == '/dd/Materials/Acrylic')") );
00044 m_Stats.push_back(AddableVector().add("edep-ad1" ).add("dE" ).add("pdg!=20022 and ((MaterialName == '/dd/Materials/LiquidScintillator' or MaterialName == '/dd/Materials/GdDopedLS') and AD==1)" ) );
00045 m_Stats.push_back(AddableVector().add("edep-ad2" ).add("dE" ).add("pdg!=20022 and ((MaterialName == '/dd/Materials/LiquidScintillator' or MaterialName == '/dd/Materials/GdDopedLS') and AD==2)" ) );
00046 m_Stats.push_back(AddableVector().add("edep-ad3" ).add("dE" ).add("pdg!=20022 and ((MaterialName == '/dd/Materials/LiquidScintillator' or MaterialName == '/dd/Materials/GdDopedLS') and AD==3)" ) );
00047 m_Stats.push_back(AddableVector().add("edep-ad4" ).add("dE" ).add("pdg!=20022 and ((MaterialName == '/dd/Materials/LiquidScintillator' or MaterialName == '/dd/Materials/GdDopedLS') and AD==4)" ) );
00048 m_Stats.push_back(AddableVector().add("qedep-ad1" ).add("qdE" ).add("pdg!=20022 and ((MaterialName == '/dd/Materials/LiquidScintillator' or MaterialName == '/dd/Materials/GdDopedLS') and AD==1)" ) );
00049 m_Stats.push_back(AddableVector().add("qedep-ad2" ).add("qdE" ).add("pdg!=20022 and ((MaterialName == '/dd/Materials/LiquidScintillator' or MaterialName == '/dd/Materials/GdDopedLS') and AD==2)" ) );
00050 m_Stats.push_back(AddableVector().add("qedep-ad3" ).add("qdE" ).add("pdg!=20022 and ((MaterialName == '/dd/Materials/LiquidScintillator' or MaterialName == '/dd/Materials/GdDopedLS') and AD==3)" ) );
00051 m_Stats.push_back(AddableVector().add("qedep-ad4" ).add("qdE" ).add("pdg!=20022 and ((MaterialName == '/dd/Materials/LiquidScintillator' or MaterialName == '/dd/Materials/GdDopedLS') and AD==4)" ) );
00052 m_Stats.push_back(AddableVector().add("mu-path-water").add( "dx").add( "(pdg==13 || pdg==-13) and MaterialName == '/dd/Materials/Water'") );
00053 m_Stats.push_back(AddableVector().add("mu-path-oil").add( "dx").add( "(pdg==13 || pdg==-13) and MaterialName == '/dd/Materials/Oil'") );
00054 m_Stats.push_back(AddableVector().add("mu-path-ls").add( "dx").add( "(pdg==13 || pdg==-13) and MaterialName == '/dd/Materials/LiquidScintillator'") );
00055 m_Stats.push_back(AddableVector().add("mu-path-gdls").add( "dx").add( "(pdg==13 || pdg==-13) and MaterialName == '/dd/Materials/GdDopedLS'") );
00056 m_Stats.push_back(AddableVector()
00057 .add("ad" ).add( "AD" )
00058 .add("expos" ).add("Ex" )
00059 .add("eypos" ).add("Ey" )
00060 .add("ezpos" ).add("Ez" )
00061 .add("et" ).add("Et" )
00062 .add("qexpos").add("qEx" )
00063 .add("qeypos").add("qEy" )
00064 .add("qezpos").add("qEz" )
00065 .add("qet" ).add("qEt" )
00066 .add( "(pdg!=20022) and (MaterialName == '/dd/Materials/LiquidScintillator' or MaterialName == '/dd/Materials/GdDopedLS')" ) );
00067
00068 declareProperty("Stats",m_Stats);
00069
00070
00071
00072 m_DetectorElementSearchPath = AddableVector()
00073 .add("/dd/Structure/DayaBay")
00074 .add("/dd/Structure/Sites")
00075 .add("/dd/Structure/Pool")
00076 .add("/dd/Structure/AD")
00077 .add("/dd/Structure/RPC");
00078
00079
00080 }
00081
00082 UnObserverStepAction::~UnObserverStepAction ()
00083 {
00084 for(size_t i=0;i<mGroups.size();i++) {
00085 if(mGroups[i].mRule) delete mGroups[i].mRule;
00086 }
00087 }
00088
00089
00090 StatusCode UnObserverStepAction::initialize()
00091 {
00092 info() << "UnObserverStepAction::initialize()" << endreq;
00093
00094 StatusCode sc = QueriableStepAction::initialize();
00095 if (sc.isFailure()) return sc;
00096
00097 sc = service("HistoryKeeper",mKeeper,true);
00098 if (sc.isFailure()) return sc;
00099
00101
00102
00103 using namespace RuleParser;
00104 using std::string;
00105
00107 ParameterList plist;
00108 QueriableStepAction::GetVertexParameterList(plist);
00109
00110
00111 for(size_t istat = 0; istat < m_Stats.size(); istat++ ){
00112 std::vector<std::string>& stat = m_Stats[istat];
00113
00114
00115 if(stat.size()%2 != 1) {
00116 err() << "Bad configuration given to the UnObserverStepAction:" << endreq;
00117 err() << " Expected strings of the form <name> : <parameter> [: <name> : <parameter> ..]: <cut>" << endreq;
00118 err() << " but got " << stat.size() << " strings"
00119
00120 << endreq;
00121 return StatusCode::FAILURE;
00122 }
00123
00124 StatGroup statgroup;
00125
00126
00127 statgroup.mRule = 0;
00128 bool compiled = RuleParser::CreateRules(stat[stat.size()-1],plist,statgroup.mRule);
00129 if(!compiled || !statgroup.mRule) {
00130 err() << "Bad configuration given to the UnObserverStepAction:" << endreq;
00131 err() << " Expected 3 strings of the form <name>,<parameter>,<cut>" << endreq;
00132 err() << " but I failed to interpret selection string: " << stat[stat.size()-1] << endreq;
00133 return StatusCode::FAILURE;
00134 }
00135 info() << "Cut group : " << stat[stat.size()-1] << endreq;
00136
00137 for(size_t isub=0; isub<(stat.size()-1)/2 ; isub+=2) {
00138
00139 std::string parname = stat[isub+1];
00140 for(std::string::iterator c = parname.begin(); c!= parname.end(); ++c) *c = tolower(*c);
00141
00142 bool foundit = false;
00143 int parid = 0;
00144 for(size_t ipar = 0; ipar < plist.size(); ipar++) {
00145 std::string temp = plist[ipar].name();
00146 for(std::string::iterator c = temp.begin(); c!= temp.end(); ++c) *c = tolower(*c);
00147 if(parname==temp) {
00148 foundit = true;
00149 parid = plist[ipar].id();
00150 }
00151 }
00152 if(!foundit) {
00153 err() << "Bad configuration given to the UnObserverStepAction:" << endreq;
00154 err() << "Didn't recognize parameter name " << parname << endreq;
00155 return StatusCode::FAILURE;
00156 }
00157
00158 info() << " Statistic " << stat[isub]
00159 << " param=" << parname << " (id=" << parid <<")"
00160 << endreq;
00161
00162 NamedStat ns;
00163 ns.mName = stat[isub];
00164 ns.mParam = parid;
00165
00166 statgroup.push_back(ns);
00167 }
00168 if(statgroup.size())
00169 mGroups.push_back(statgroup);
00170 }
00171
00172
00173 mBail = 0;
00174
00175 return StatusCode::SUCCESS;
00176 }
00177
00178 StatusCode UnObserverStepAction::finalize()
00179 {
00180 info() << "UnObserverStepAction::finalize()" << endreq;
00181 info() << "There were "<<mBail<<" bail-out warnings encountered in UserSteppingAction."<<endreq;
00182 return QueriableStepAction::finalize();
00183 }
00184
00185
00186
00187 void UnObserverStepAction::UserSteppingAction(const G4Step* g4step)
00188 {
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 QueriableStepAction::Reset(g4step,g4step->GetTrack(),g4step->GetPostStepPoint());
00207 if ( g4step->GetTrack()->GetCurrentStepNumber() == 1 )
00208
00209
00210 QueriableStepAction::Reset(g4step,g4step->GetTrack(),g4step->GetPreStepPoint());
00211
00212
00213
00214 if ( 0 && g4step->GetTrack()->GetDefinition()->GetParticleName() != "opticalphoton" )
00215 {
00216 G4StepPoint* pre = g4step->GetPreStepPoint();
00217 G4String mpre = "NONE", mpost = "NONE", status1 = "", status2 = "";
00218 G4String ppre = "NONE",ppost = "NONE",lpre = "NONE",lpost = "NONE";
00219 G4ThreeVector localPosition = 0, worldPosition = 0;
00220 if (pre) {
00221 if ( pre->GetStepStatus() == fGeomBoundary ) status1 = "Entering";
00222 G4Material* mm = pre->GetMaterial();
00223 if (mm) mpre = mm->GetName();
00224 G4TouchableHandle touch = pre->GetTouchableHandle();
00225 G4VPhysicalVolume* volume = touch->GetVolume();
00226 ppre = volume->GetName();
00227 G4LogicalVolume* lvolume = volume->GetLogicalVolume();
00228 lpre = lvolume->GetName();
00229 }
00230 else {
00231 verbose() << " THERE IS NO PRE-STEP-POINT FOR THIS STEP " << endreq;
00232 }
00233 pre = g4step->GetPostStepPoint();
00234 if (pre) {
00235 if (pre->GetStepStatus() == fGeomBoundary ) status2 = "Leaving";
00236 G4Material* mm = pre->GetMaterial();
00237 if (mm) mpost = mm->GetName();
00238 G4TouchableHandle touch = pre->GetTouchableHandle();
00239 if (touch) {
00240 worldPosition = pre->GetPosition();
00241 localPosition = touch->GetHistory()->GetTopTransform().TransformPoint( worldPosition );
00242 G4VPhysicalVolume* volume = touch->GetVolume();
00243 if (volume) {
00244 ppost = volume->GetName();
00245 G4LogicalVolume* lvolume = volume->GetLogicalVolume();
00246 if (lvolume) lpost = lvolume->GetName();
00247 }
00248 }
00249 }
00250 else {
00251 verbose() << " THERE IS NO POST-STEP-POINT FOR THIS STEP " << endreq;
00252 }
00253
00254 verbose() << "Track in " << g4step->GetTrack()->GetVolume()->GetName()
00255 << ", particle is " << g4step->GetTrack()->GetDefinition()->GetParticleName()
00256 << " Etot(MeV) " << g4step->GetTrack()->GetTotalEnergy()/MeV
00257 << " Ekin(MeV) " << g4step->GetTrack()->GetKineticEnergy()/MeV
00258 << " worldX,Y,Z " << worldPosition.x() << ", " << worldPosition.y() << ", " << worldPosition.z()
00259 << " localX,Y,Z " << localPosition.x() << ", " << localPosition.y() << ", " << localPosition.z()
00260 << " DirX,Y,Z " << g4step->GetTrack()->GetMomentumDirection().x()
00261 << ", " << g4step->GetTrack()->GetMomentumDirection().y()
00262 << ", " << g4step->GetTrack()->GetMomentumDirection().z()
00263 << " G4TrackID "<< g4step->GetTrack()->GetTrackID()
00264 << " current step# " << g4step->GetTrack()->GetCurrentStepNumber()
00265 << " step length(mm) " << g4step->GetTrack()->GetStepLength()/mm
00266 << " status " << g4step->GetTrack()->GetTrackStatus() << endreq;
00267 verbose() << " ...." << status1 << " " << status2
00268 << " prestep (current) material " << mpre << " pVol " << ppre << " lVol " << lpre
00269 << " poststep material " << mpost << " pVol " << ppost << " lVol " << lpost
00270 << endreq;
00271 }
00272
00273
00274 if ( g4step->GetTrack()->GetVolume()->GetMotherLogical() == 0x0 ) {
00275 mBail++;
00276 if (mBail <= 10) {
00277 warning() << "Bailing out because track is in " << g4step->GetTrack()->GetVolume()->GetName()
00278 << ", particle is " << g4step->GetTrack()->GetDefinition()->GetParticleName()
00279 << " with total energy(MeV) " << g4step->GetTrack()->GetTotalEnergy()/MeV
00280 << " & kinetic energy(MeV) " << g4step->GetTrack()->GetKineticEnergy()/MeV
00281 << " G4TrackID "<< g4step->GetTrack()->GetTrackID()
00282 << " current step# " << g4step->GetTrack()->GetCurrentStepNumber()
00283 << " step length(mm) " << g4step->GetTrack()->GetStepLength()/mm
00284 << " status " << g4step->GetTrack()->GetTrackStatus()
00285 << endreq;
00286 }
00287 if (mBail > 10) {
00288 debug() << "Bailing out because track is in " << g4step->GetTrack()->GetVolume()->GetName()
00289 << ", particle is " << g4step->GetTrack()->GetDefinition()->GetParticleName()
00290 << " with total energy(MeV) " << g4step->GetTrack()->GetTotalEnergy()/MeV
00291 << " & kinetic energy(MeV) " << g4step->GetTrack()->GetKineticEnergy()/MeV
00292 << " G4TrackID "<< g4step->GetTrack()->GetTrackID()
00293 << " current step# " << g4step->GetTrack()->GetCurrentStepNumber()
00294 << " step length(mm) " << g4step->GetTrack()->GetStepLength()/mm
00295 << " status " << g4step->GetTrack()->GetTrackStatus()
00296 << endreq;
00297 }
00298 if (mBail == 10) {
00299 warning() << "Additional bail-out messages will be suppressed" << endreq;
00300 }
00301 return;
00302 }
00303
00304
00305 SimUnobservableStatisticsHeader* ush = 0;
00306 StatusCode sc = mKeeper->GetCurrentUnobservable(ush);
00307 if(sc.isFailure() || (!ush)) {
00308 err() << "Problem with Keeper." << endreq;
00309 return;
00310 }
00311 assert(ush);
00312
00313 SimUnobservableStatisticsHeader::stat_map& statmap = ush->stats();
00314 if(ush->stats().size() == 0) {
00315
00316
00317 for(size_t igrp = 0; igrp < mGroups.size(); igrp++) {
00318 StatGroup& statgroup = mGroups[igrp];
00319 for(size_t istat = 0; istat < statgroup.size(); istat++ ){
00320 statmap[statgroup[istat].mName];
00321 verbose() << "Initializing group " << igrp << " stat " << istat
00322 << " name=" <<statgroup[istat].mName << " paramid=" << statgroup[istat].mParam << endreq;
00323 }
00324 }
00325 }
00326
00327 for(size_t igrp = 0; igrp < mGroups.size(); igrp++) {
00328 StatGroup& statgroup = mGroups[igrp];
00329
00330
00331 verbose() << " Group " << igrp << " statgroup.mRule->name() " << statgroup.mRule->name() << endreq;
00332 if(statgroup.mRule->select(this)) {
00333
00334 for(size_t istat = 0; istat < statgroup.size(); istat++ ){
00335 double x = 0;
00336 queryParam(statgroup[istat].mParam,x);
00337 SimStatistic& stat = statmap[statgroup[istat].mName];
00338 verbose() << "Querying group " << igrp << " stat " << istat
00339 << " name=" <<statgroup[istat].mName << " paramid=" << statgroup[istat].mParam
00340 << " and incrementing by " << x << endreq;
00341 stat.increment(x);
00342 }
00343 }
00344 }
00345
00346 }
00347