// %%%%%%%%%% // G4 headers // %%%%%%%%%% #include "G4SDManager.hh" #include "G4UnitsTable.hh" #include "G4ParticleTypes.hh" // %%%%%%%%%%%%% // gemc headers // %%%%%%%%%%%%% #include "identifier.h" #include "MSensitiveDetector.h" MSensitiveDetector::MSensitiveDetector(G4String name, gemc_opts opt):G4VSensitiveDetector(name), HCID(-1), gemcOpt(opt) { HCname = name; collectionName.insert(HCname); SDID = get_SDId(HCname, gemcOpt); SDID.IDshifts = set_IDshifts(SDID.IDmaxs); minEnergy = SDID.minEnergy; } MSensitiveDetector::~MSensitiveDetector(){;} void MSensitiveDetector::Initialize(G4HCofThisEvent* HCE) { Id_Set.clear(); Tr_Map.clear(); hitCollection = new MHitCollection(HCname, collectionName[0]); if(HCID < 0) HCID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]); HCE->AddHitsCollection( HCID, hitCollection ); } G4bool MSensitiveDetector::ProcessHits(G4Step* aStep, G4TouchableHistory*) { // First check on energy deposited double depe = aStep->GetTotalEnergyDeposit(); /* if(depe < minEnergy && aStep->GetTrack()->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition()) return false;*/ if(depe == 0 && aStep->GetTrack()->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition()) return false; string hd_msg1 = gemcOpt.args["LOG_MSG"].args + " New Hit: <<< "; string hd_msg2 = gemcOpt.args["LOG_MSG"].args + " > "; string catch_v = gemcOpt.args["CATCH"].args; double HIT_VERBOSITY = gemcOpt.args["HIT_VERBOSITY"].arg ; G4StepPoint *prestep = aStep->GetPreStepPoint(); G4StepPoint *poststep = aStep->GetPostStepPoint(); G4VTouchable* TH = (G4VTouchable*) aStep->GetPreStepPoint()->GetTouchable(); string name = TH->GetVolume(0)->GetName(); G4ThreeVector xyz = poststep->GetPosition(); G4ThreeVector Lxyz = prestep->GetTouchableHandle()->GetHistory() ->GetTopTransform().TransformPoint(xyz); double ctime = poststep->GetGlobalTime(); G4ThreeVector pxyz = prestep->GetMomentum(); double ene = prestep->GetTotalEnergy(); G4ThreeVector ver = aStep->GetTrack()->GetVertexPosition(); string pid = aStep->GetTrack()->GetDefinition()->GetParticleName(); vector VID = SetId(GetDetectorIdentifier(name), TH, ctime, SDID.TimeWindow); int tid = aStep->GetTrack()->GetTrackID(); int ptid = aStep->GetTrack()->GetParentID(); if(Tr_Map.find(tid) == Tr_Map.end()) { MTrackInfo trinf; trinf.pid = pid; trinf.v = ver; Tr_Map[tid] = trinf; } MPHBaseClass *ProcessHitRoutine = GetMPHClass((*MProcessHit_Map), GetDetectorHitType(name)); if(!ProcessHitRoutine) { cout << endl << hd_msg2 << " Hit Process Routine <" << GetDetectorHitType(name) << "> not found. Exiting. " << endl; exit(0); } vector PID = ProcessHitRoutine->ProcessID(VID, aStep, (*Hall_Map)[name]); if(HIT_VERBOSITY > 11 || name.find(catch_v) != string::npos) cout << endl << hd_msg2 << " Before hit Process Identification:" << endl << VID << hd_msg2 << " After: hit Process Identification:" << endl << PID << endl; set > :: iterator itid; int hit_found = 0; if(HIT_VERBOSITY > 5 || name.find(catch_v) != string::npos) cout << endl << endl << " BEGIN SEARCH for same hit in Identifier Set..." << endl; for(itid = Id_Set.begin(); itid!= Id_Set.end() && !hit_found; itid++) { if(*itid == PID) hit_found=1; if(HIT_VERBOSITY > 5 || name.find(catch_v) != string::npos) cout << " >> Current Step: " << PID << " >> Set Hit Index: " << *itid << (hit_found ? " >> FOUND at this Set Entry. " : " >> Not found yet. ") << endl; } if(HIT_VERBOSITY > 5 || name.find(catch_v) != string::npos) cout << " SEARCH ENDED." << (hit_found ? " 1 " : " No ") << "hit found in the Set." << endl << endl; // New Hit if(!hit_found) { MHit *thisHit = new MHit(); thisHit->SetPos(xyz); thisHit->SetLPos(Lxyz); thisHit->SetEdep(depe); thisHit->SetTime(ctime); thisHit->SetMom(pxyz); thisHit->SetE(ene); thisHit->SetVert(ver); thisHit->SetPID(pid); thisHit->SetId(PID); thisHit->SetTrackId(tid); thisHit->SetDetector((*Hall_Map)[name]); thisHit->SetThreshold(SDID.minEnergy); if(Tr_Map.count(ptid) > 0) { thisHit->SetmPID(Tr_Map[ptid].pid); thisHit->SetmVert(Tr_Map[ptid].v); } else { thisHit->SetmPID("unknown"); thisHit->SetmVert(G4ThreeVector(0, 0, 0)); } hitCollection->insert(thisHit); Id_Set.insert(PID); if(HIT_VERBOSITY > 3 || name.find(catch_v) != string::npos) cout << endl << hd_msg1 << endl << " > This element was not hit yet in this event. Identity:" << endl << thisHit->GetId() << " > Creating new hit by a E=" << ene/MeV << ", p=" << pxyz.mag()/MeV << " MeV " << pid << ", track ID = " << tid << ", inside Hit Collection <" << HCname << ">." << endl << " > Energy Deposited this step: " << depe/MeV << " MeV" << endl << " > Time of this step: " << G4BestUnit(ctime, "Time") << endl << " > Position of this step: " << xyz/cm << " cm" << endl << " > Local Position in volume: " << Lxyz/cm << " cm" << endl; } else { // Adding hit info only if the poststeppint remains in the volume? //if( aStep->GetPreStepPoint()->GetTouchable()->GetVolume(0) == aStep->GetPostStepPoint()->GetTouchable()->GetVolume(0)) { MHit *thisHit = find_existing_hit(PID); if(!thisHit) { cout << " Hit not found in collection but found in PID. This should never happen. Exiting." << endl; exit(0); } else { thisHit->SetPos(xyz); thisHit->SetLPos(Lxyz); thisHit->SetEdep(depe); thisHit->SetTime(ctime); thisHit->SetTrackId(tid); if(HIT_VERBOSITY > 3 || name.find(catch_v) != string::npos) cout << hd_msg2 << " Step Number " << thisHit->GetPos().size() << " inside Identity: " << endl << thisHit->GetId() << " > Adding hit inside Hit Collection <" << HCname << ">." << " by a E=" << ene/MeV << ", p=" << pxyz.mag()/MeV << " MeV " << pid << ", track ID = " << tid << endl << " > Energy Deposited this step: " << depe/MeV << " MeV" << endl << " > Time of this step: " << G4BestUnit(ctime, "Time") << " is within this element Time Window of " << SDID.TimeWindow/ns << " ns. " << endl << " > Position of this step: " << xyz/cm << " cm" << endl << " > Local Position in volume: " << Lxyz/cm << " cm" << endl; } } } return true; } void MSensitiveDetector::EndOfEvent(G4HCofThisEvent *HCE) { string hd_msg = gemcOpt.args["LOG_MSG"].args + " End of Hit Collections >> "; double HIT_VERBOSITY = gemcOpt.args["HIT_VERBOSITY"].arg ; string catch_v = gemcOpt.args["CATCH"].args; int nhitC = hitCollection->GetSize(); if(!nhitC) return; MHit *aHit; double Etot; if(HIT_VERBOSITY > 2 && nhitC) { cout << endl; cout << hd_msg << " Hit Collections <" << HCname << ">: " << nhitC << " hits." << endl; for (int i=0; iGetId()[aHit->GetId().size()-1].name; if(HIT_VERBOSITY > 4 || vname.find(catch_v) != string::npos) { cout << hd_msg << " Hit " << i + 1 << " -- total number of steps this hit: " << aHit->GetPos().size() << endl; cout << aHit->GetId(); Etot = 0; for(int e=0; eGetPos().size(); e++) Etot = Etot + aHit->GetEdep()[e]; cout << " Total energy deposited: " << Etot/MeV << " MeV" << endl; } } } } int MSensitiveDetector::get_bit_compressed_id(vector id) { string hd_msg = gemcOpt.args["LOG_MSG"].args + " Bit Compressing >> "; double HIT_VERBOSITY = gemcOpt.args["HIT_VERBOSITY"].arg ; int bitc = 0; int depth = id.size(); // check for consistency if(depth != SDID.IDnames.size()) { cout << hd_msg << " Something is wrong. Identifier size is different than SDId sizes: " << endl; cout << " id size: " << id.size() << " SDID size: " << endl; exit(0); } else { for(int i=0; i PID) { for(int i=0; iGetSize(); i++) if((*hitCollection)[i]->GetId() == PID) return (*hitCollection)[i]; return NULL; }