void BIEventAction::EndOfEventAction(const G4Event *event) { G4HCofThisEvent *hce = event->GetHCofThisEvent(); if (!hce) { G4cout << "HCE not found: EndOfEventAction@BIEventAction" << G4endl; exit(0); } BICommonHitsCollection *hitsCollection = static_cast<BICommonHitsCollection *>(hce->GetHC(fHitsCollectionID)); if (!hitsCollection) { G4cout << "HC not found: EndOfEventAction@BIEventAction" << G4endl; exit(0); } G4AnalysisManager *anaMan = G4AnalysisManager::Instance(); const G4int kHit = hitsCollection->entries(); for (G4int iHit = 0; iHit < kHit; iHit++) { BICommonHit *newHit = (*hitsCollection)[iHit]; G4double depositEnergy = newHit->GetDepositEnergy(); anaMan->FillNtupleDColumn(0, 0, depositEnergy); G4ThreeVector position = newHit->GetPosition(); anaMan->FillNtupleDColumn(0, 1, position.x()); anaMan->FillNtupleDColumn(0, 2, position.y()); anaMan->AddNtupleRow(0); } }
// Process hits. G4bool base_SD::ProcessHits( G4Step * step, G4TouchableHistory * /*ROhist*/ ) { MCDetectorHit hit; hit.Edep=step->GetTotalEnergyDeposit(); G4StepPoint * prestep = step->GetPreStepPoint(); G4StepPoint * poststep = step->GetPostStepPoint(); G4TouchableHandle touchable = prestep->GetTouchableHandle(); hit.id=touchable->GetCopyNumber(); if (hit.id>=2000) { plugin->debug(0,"Hit id is too large... bailing out \n"); exit(-1); } G4Track * track = step->GetTrack(); hit.time = prestep->GetGlobalTime(); hit.track = track->GetTrackID(); // Get the true world and local coordinate positions. G4ThreeVector trueworld = ( prestep->GetPosition() + poststep->GetPosition() ) / 2.0; // If this first time store transformation and inverse. if( !transformValid[hit.id] ) { if (WorldtoLocal.size()<hit.id+1) //too small { WorldtoLocal.resize(hit.id+1); LocaltoWorld.resize(hit.id+1); } WorldtoLocal[hit.id] = touchable->GetHistory()->GetTopTransform(); LocaltoWorld[hit.id] = WorldtoLocal[hit.id].Inverse(); transformValid[hit.id] = true; } G4ThreeVector Tmp = WorldtoLocal[hit.id].TransformPoint(trueworld); hit.world=TVector3(trueworld.x(),trueworld.y(),trueworld.z()); hit.local=TVector3(Tmp.x(),Tmp.y(),Tmp.z()); // find average momentum G4ThreeVector mom=0.5*(prestep->GetMomentum()+poststep->GetMomentum()); hit.fourmomentum.SetXYZM(mom.x()/MeV,mom.y()/MeV,mom.z()/MeV,prestep->GetMass()/MeV); mom=WorldtoLocal[hit.id].TransformAxis(mom); hit.localmomentum=TVector3(mom.x(),mom.y(),mom.z()); data->hits.push_back(hit); return true; }
uint64_t GflashCalorimeterSD::cellID(const G4GFlashSpot& aSpot) { dd4hep::sim::Geant4VolumeManager volMgr = dd4hep::sim::Geant4Mapping::instance().volumeManager(); dd4hep::VolumeID volID = volMgr.volumeID(aSpot.GetTouchableHandle()()); if (m_seg.isValid()) { G4ThreeVector global = aSpot.GetEnergySpot()->GetPosition(); G4ThreeVector local = aSpot.GetTouchableHandle()->GetHistory()->GetTopTransform().TransformPoint(global); dd4hep::Position loc(local.x() * MM_2_CM, local.y() * MM_2_CM, local.z() * MM_2_CM); dd4hep::Position glob(global.x() * MM_2_CM, global.y() * MM_2_CM, global.z() * MM_2_CM); dd4hep::VolumeID cID = m_seg.cellID(loc, glob, volID); return cID; } return volID; }
/// Store Geant4 point and step information into tracker hit structure. Geant4Tracker::Hit& Geant4Tracker::Hit::storePoint(const G4Step* step, const G4StepPoint* pnt) { G4Track* trk = step->GetTrack(); G4ThreeVector pos = pnt->GetPosition(); G4ThreeVector mom = pnt->GetMomentum(); truth.trackID = trk->GetTrackID(); truth.pdgID = trk->GetDefinition()->GetPDGEncoding(); truth.deposit = step->GetTotalEnergyDeposit(); truth.time = trk->GetGlobalTime(); position.SetXYZ(pos.x(), pos.y(), pos.z()); momentum.SetXYZ(mom.x(), mom.y(), mom.z()); length = 0; return *this; }
long long Geant4SensitiveDetector::getCellID(G4Step* s) { StepHandler h(s); Geant4VolumeManager volMgr = Geant4Mapping::instance().volumeManager(); VolumeID volID = volMgr.volumeID(h.preTouchable()); Segmentation seg = m_readout.segmentation(); if ( seg.isValid() ) { G4ThreeVector global = 0.5 * ( h.prePosG4()+h.postPosG4()); G4ThreeVector local = h.preTouchable()->GetHistory()->GetTopTransform().TransformPoint(global); Position loc(local.x()*MM_2_CM, local.y()*MM_2_CM, local.z()*MM_2_CM); Position glob(global.x()*MM_2_CM, global.y()*MM_2_CM, global.z()*MM_2_CM); VolumeID cID = seg.cellID(loc,glob,volID); return cID; } return volID; }
void FastSimModelTracker::DoIt(const G4FastTrack& aFastTrack, G4FastStep& aFastStep) { // Calculate the position of the particle at the end of volume const G4Track* track = aFastTrack.GetPrimaryTrack(); G4ThreeVector spin = track->GetPolarization() ; G4FieldTrack aFieldTrack('t'); G4FieldTrackUpdator::Update(&aFieldTrack,track); G4double retSafety= -1.0; ELimited retStepLimited; G4FieldTrack endTrack('a'); G4double currentMinimumStep= 10*m; // TODO change that to sth connected to particle momentum and geometry G4PathFinder* fPathFinder = G4PathFinder::GetInstance(); fPathFinder->ComputeStep( aFieldTrack, currentMinimumStep, 0, track->GetCurrentStepNumber(), retSafety, retStepLimited, endTrack, track->GetVolume() ); aFastStep.ProposePrimaryTrackFinalPosition( endTrack.GetPosition() ); // Smear particle's momentum according to the tracker resolution G4ThreeVector Psm = track->GetMomentum(); m_smearTool->smearMomentum(Psm); G4ThreeVector DeltaP = track->GetMomentum() - Psm; G4double Ekinorg = track->GetKineticEnergy(); aFastStep.ClearDebugFlag(); // to disable Geant checks on energy aFastStep.ProposePrimaryTrackFinalKineticEnergyAndDirection(Ekinorg+DeltaP.mag(), Psm.unit()); // Keep track of smeared momentum if(track->GetParentID()==0) { ParticleInformation* info = dynamic_cast<ParticleInformation*>(track->GetDynamicParticle()->GetPrimaryParticle()->GetUserInformation()); info->setSmeared(true); info->setEndStatus(1); // how it is defined ???? as in HepMC ? info->setEndMomentum(Psm); info->setVertexPosition( track->GetVertexPosition()); } }
void FastSimModelTracker::DoIt(const G4FastTrack& aFastTrack, G4FastStep& aFastStep) { // Calculate the position of the particle at the end of volume const G4Track* track = aFastTrack.GetPrimaryTrack(); G4ThreeVector spin = track->GetPolarization() ; G4FieldTrack theFieldTrack = G4FieldTrack( track->GetPosition(), track->GetMomentumDirection(), 0.0, track->GetKineticEnergy(), track->GetDynamicParticle()->GetDefinition()->GetPDGMass(), 0.0, track->GetGlobalTime(), // Lab. track->GetProperTime(), // Part. &spin) ; G4double retSafety= -1.0; ELimited retStepLimited; G4FieldTrack endTrack('a'); G4double currentMinimumStep= 10*m; // TODO change that to sth connected to particle momentum and geometry G4PathFinder* fPathFinder = G4PathFinder::GetInstance(); fPathFinder->ComputeStep( theFieldTrack, currentMinimumStep, 0, track->GetCurrentStepNumber(), retSafety, retStepLimited, endTrack, track->GetVolume() ); aFastStep.ProposePrimaryTrackFinalPosition( endTrack.GetPosition() ); // Smear particle's momentum according to the tracker resolution (set in SimpleSmear) G4ThreeVector Psm = track->GetMomentum(); m_smearTool->smearMomentum(Psm); G4ThreeVector DeltaP = track->GetMomentum() - Psm; G4double Ekinorg = track->GetKineticEnergy(); aFastStep.ClearDebugFlag(); // to disable Geant checks on energy aFastStep.ProposePrimaryTrackFinalKineticEnergyAndDirection(Ekinorg+DeltaP.mag(), Psm.unit()); }
void BIEventAction::EndOfEventAction(const G4Event *event) { G4HCofThisEvent *hce = event->GetHCofThisEvent(); if (!hce) { G4cout << "HCE not found: EndOfEventAction@BIEventAction" << G4endl; exit(0); } BICommonHitsCollection *hitsCollection = static_cast<BICommonHitsCollection *>(hce->GetHC(fHitsCollectionID)); if (!hitsCollection) { G4cout << "HC not found: EndOfEventAction@BIEventAction" << G4endl; exit(0); } //G4int eventID = event->GetEventID(); G4AnalysisManager *anaMan = G4AnalysisManager::Instance(); G4double cellPitch = 9.*mm; const G4int kHit = hitsCollection->entries(); for (G4int iHit = 0; iHit < kHit; iHit++) { BICommonHit *newHit = (*hitsCollection)[iHit]; G4double depositEnergy = newHit->GetDepositEnergy(); G4ThreeVector position = newHit->GetPosition(); G4int xPos = G4int((position.x() + 6*cellPitch) / cellPitch); G4int yPos = G4int((position.y() + 4*cellPitch) / cellPitch); anaMan->FillH2(0, xPos, yPos, depositEnergy); } }
uint64_t cellID(const DD4hep::Geometry::Segmentation& aSeg, const G4Step& aStep, bool aPreStepPoint) { DD4hep::Simulation::Geant4VolumeManager volMgr = DD4hep::Simulation::Geant4Mapping::instance().volumeManager(); DD4hep::Geometry::VolumeManager::VolumeID volID = volMgr.volumeID(aStep.GetPreStepPoint()->GetTouchable()); if (aSeg.isValid()) { G4ThreeVector global; if (aPreStepPoint) { global = aStep.GetPreStepPoint()->GetPosition(); } else { global = 0.5 * (aStep.GetPreStepPoint()->GetPosition() + aStep.GetPostStepPoint()->GetPosition()); } G4ThreeVector local = aStep.GetPreStepPoint()->GetTouchable()->GetHistory()->GetTopTransform().TransformPoint(global); DD4hep::Geometry::Position loc(local.x() * MM_2_CM, local.y() * MM_2_CM, local.z() * MM_2_CM); DD4hep::Geometry::Position glob(global.x() * MM_2_CM, global.y() * MM_2_CM, global.z() * MM_2_CM); DD4hep::Geometry::VolumeManager::VolumeID cID = aSeg.cellID(loc, glob, volID); return cID; } return volID; }
void BIEventAction::EndOfEventAction(const G4Event *event) { G4HCofThisEvent *hce = event->GetHCofThisEvent(); if (!hce) { G4cout << "HCE not found: EndOfEventAction@BIEventAction" << G4endl; exit(0); } BICommonHitsCollection *hitsCollection = static_cast<BICommonHitsCollection *>(hce->GetHC(fHitsCollectionID)); if (!hitsCollection) { G4cout << "HC not found: EndOfEventAction@BIEventAction" << G4endl; exit(0); } G4int eventID = event->GetEventID(); G4AnalysisManager *anaMan = G4AnalysisManager::Instance(); const G4int kHit = hitsCollection->entries(); for (G4int iHit = 0; iHit < kHit; iHit++) { BICommonHit *newHit = (*hitsCollection)[iHit]; if(fForGrid){ G4double depositEnergy = newHit->GetDepositEnergy(); anaMan->FillNtupleDColumn(0, 0, depositEnergy); G4ThreeVector position = newHit->GetPosition(); anaMan->FillNtupleDColumn(0, 1, position.x()); anaMan->FillNtupleDColumn(0, 2, position.y()); G4int trackID = newHit->GetTrackID(); anaMan->FillNtupleIColumn(0, 3, trackID); G4int pdgCode = newHit->GetPDGCode(); anaMan->FillNtupleIColumn(0, 4, pdgCode); } else { anaMan->FillNtupleIColumn(0, 0, eventID); // EventID G4int pdgCode = newHit->GetPDGCode(); anaMan->FillNtupleIColumn(0, 1, pdgCode); G4double depositEnergy = newHit->GetDepositEnergy(); anaMan->FillNtupleDColumn(0, 2, depositEnergy); G4double time = newHit->GetTime(); anaMan->FillNtupleDColumn(0, 3, time); G4String volumeName = newHit->GetVolumeName(); anaMan->FillNtupleSColumn(0, 4, volumeName); G4ThreeVector position = newHit->GetPosition(); anaMan->FillNtupleDColumn(0, 5, position.x()); anaMan->FillNtupleDColumn(0, 6, position.y()); anaMan->FillNtupleDColumn(0, 7, position.z()); G4ThreeVector prePosition = newHit->GetPrePosition(); anaMan->FillNtupleDColumn(0, 8, prePosition.x()); anaMan->FillNtupleDColumn(0, 9, prePosition.y()); anaMan->FillNtupleDColumn(0, 10, prePosition.z()); G4ThreeVector momentum = newHit->GetMomentum(); anaMan->FillNtupleDColumn(0, 11, momentum.x()); anaMan->FillNtupleDColumn(0, 12, momentum.y()); anaMan->FillNtupleDColumn(0, 13, momentum.z()); G4int isLast = newHit->GetIsLast(); anaMan->FillNtupleIColumn(0, 14, isLast); G4int trackID = newHit->GetTrackID(); anaMan->FillNtupleIColumn(0, 15, trackID); } anaMan->AddNtupleRow(0); } }
// This function, when registered with the Geant4 run manager should be executed // on each execution step to provide position (or any other information) about // the propagated tracks for visualization void MCPropVis::UserSteppingAction(const G4Step* step) { // Get the track ID for this step. int cid = step->GetTrack()->GetTrackID(); // std::cout<<"Step! "<<cid<<" "<<step->GetTrack()->GetParticleDefinition()->GetParticleName()<<"\n"; // Container index for the track information int ind = -1; // Intiallize to -1 to indicate index not yet found // If the track ID is the previous one save the search, else search through // the known tracks for the right one if (cid == lid) ind = lind; else { for (unsigned int j=0; j<ids.size(); j++) { if (ids[j] == cid) { ind = j; break; } } } // If the index hasn't been set after this, create a new track set, get the // particle type, and set the track's properties if (ind == -1) { ids.push_back(cid); tracks.push_back(new TEveLine); hits.push_back(new TEvePointSet); ind = ids.size()-1; // Index is the end of the vector // Particle type G4String type = step->GetTrack()->GetParticleDefinition()->GetParticleName(); // std::cout<<cid<<" "<<type<<"\n"; // Set color based on particle type Color_t color; if (type.compare("proton") == 0) color = kBlue; else if (type.compare("e+") == 0) color = kYellow-2; else if (type.compare("e-") == 0) color = kRed; else if (type.compare("gamma") == 0) color = kGreen; else if (type.compare("neutron") == 0) color = kCyan; else if (type.compare("mu+") == 0) color = kGray+1; else if (type.compare("mu-") == 0) color = kBlack; else if (type.compare("pi+") == 0) color = kCyan+3; else if (type.compare("pi-") == 0) color = kOrange; else color = kViolet; tracks[ind]->SetMainColor(color); tracks[ind]->SetLineColor(color); hits[ind]->SetMainColor(color); // Register the visualization set with the manager gEve->AddElement(tracks[ind]); gEve->AddElement(hits[ind]); } // Save the current IDs for the next step lid = cid; lind = ind; // Add this step point to the appropriate track object G4ThreeVector poss = step->GetPreStepPoint()->GetPosition(); tracks[ind]->SetNextPoint(poss.x()/10,poss.y()/10,poss.z()/10); gEve->AddElement(tracks[ind]); // Check to see if the step is in a sensitive detector. If so, draw it as a // hit point if (step->GetPreStepPoint()->GetSensitiveDetector()) { hits[ind]->SetNextPoint(poss.x()/10,poss.y()/10,poss.z()/10); gEve->AddElement(hits[ind]); } // std::cout<<(step->GetTrack()->GetParticleDefinition()->GetParticleName())<<"\n"; }
unsigned int GSMS::MaskConfig::imprintMask(G4VPhysicalVolume* wptr) { //clean up for(int i=0; i<m_mask.size(); i++) { if(m_mask[i]) delete m_mask[i]; } m_mask.clear(); /* if(m_assembly) { std::vector<G4VPhysicalVolume*>::iterator iter = m_assembly->GetVolumesIterator(); for(int i=0;i<m_assembly->TotalImprintedVolumes();iter++,i++) { G4VPhysicalVolume* ptr = *iter; if(ptr) delete ptr; *iter = NULL; } delete m_assembly; }; m_assembly = new G4AssemblyVolume; */ G4VPhysicalVolume* world = NULL; if(wptr) world = wptr; else GSMS::GSMS::getWorld(&world); std::cerr << world << std::endl; try { G4VSolid* s_element = NULL; G4VSolid* s_mask = NULL; /* s_mask = new G4Tubs( "mask", 0., m_radius+m_ethick*1.5, m_eheight/2, 0.*deg, 360.*deg ); */ if(m_etype == "Box") { s_element = new G4Box( "element", m_ewidth/2, m_ethick/2, m_eheight/2); } else if(m_etype == "Segment") { s_element = new G4Box( "element", m_ewidth/2, m_ethick/2, m_eheight/2); } else return GSMS_ERR; G4Material* element_mat = NULL; G4Material* mask_mat = NULL; if(!__SUCCEEDED(GSMS::GSMS::getMaterial(m_emat,&element_mat)) || !__SUCCEEDED(GSMS::GSMS::getMaterial("Air",&mask_mat))) return GSMS_ERR; G4LogicalVolume* element_log = new G4LogicalVolume( s_element, element_mat, "element_log"); ///////////// /* G4LogicalVolume* mask_log = new G4LogicalVolume( s_mask, mask_mat, "mask_log" ); G4VPVParameterisation* mask_param = new MaskElement( this ); G4VPhysicalVolume* mask_phys = new G4PVParameterised( "mask_phys", element_log, mask_log, kUndefined, m_ecount, mask_param ); */ //////////// G4RotationMatrix mR; //mask G4ThreeVector mT(0.,0.,0.); //mask G4double local_time,angle,angle_offset; local_time = angle = angle_offset = 0.0; if(!__SUCCEEDED(GSMS::getTime(&local_time))) return GSMS_ERR; angle_offset = (m_speed * local_time); std::cerr << "Mask angle offset: " << angle_offset*360/2/pi << std::endl; for(int i=0;i<m_ecount;i++) if(!isTransparent(i)) { G4RotationMatrix mRe; //element G4ThreeVector mTe; //element angle = ( (float)i/(float)m_ecount*2*pi + angle_offset ); G4float xoff = (m_radius+m_ethick)*cos(angle); G4float yoff = (m_radius+m_ethick)*sin(angle); G4float zoff = 0.; mTe.setX(xoff); mTe.setY(yoff); mTe.setZ(zoff); mRe.rotateZ(pi/2 + angle); G4VPhysicalVolume* mask_phys = new G4PVPlacement( G4Transform3D(mRe,G4ThreeVector(xoff,yoff,zoff)), element_log, "element_phys", world->GetLogicalVolume(), false, i ); // &mRe, // G4ThreeVector(xoff,yoff,zoff), // "mask_phys", // element_log, // world, // false, // 0); m_mask.push_back(mask_phys); //m_assembly->AddPlacedVolume(element_log,mTe,&mRe); std::cerr << "Element " << i << " at angle " << angle*360/2/pi << " xOff = " << xoff << " yOff = " << yoff << " zOff = " << zoff << std::endl; }; // m_assembly->MakeImprint(world->GetLogicalVolume(),mT,&mR, true); G4VisAttributes* element_vis = new G4VisAttributes(GSMS_COLOR_ELEMENT); element_vis->SetVisibility(true); element_vis->SetForceSolid(true); element_log->SetVisAttributes(element_vis); //////////// } catch(...) { return GSMS_ERR; }; return GSMS_OK; };