CMS 3D CMS Logo

Public Member Functions | Private Member Functions | Private Attributes

TrackingMaterialProducer Class Reference

#include <TrackingMaterialProducer.h>

Inheritance diagram for TrackingMaterialProducer:
SimProducer Observer< const BeginOfJob * > Observer< const BeginOfEvent * > Observer< const BeginOfTrack * > Observer< const G4Step * > Observer< const EndOfTrack * > SimWatcher

List of all members.

Public Member Functions

 TrackingMaterialProducer (const edm::ParameterSet &)
virtual ~TrackingMaterialProducer ()

Private Member Functions

bool isSelected (const G4VTouchable *touch)
void produce (edm::Event &, const edm::EventSetup &)
void update (const BeginOfTrack *)
 This routine will be called when the appropriate signal arrives.
void update (const EndOfTrack *)
 This routine will be called when the appropriate signal arrives.
void update (const G4Step *)
 This routine will be called when the appropriate signal arrives.
void update (const BeginOfJob *)
 This routine will be called when the appropriate signal arrives.
void update (const BeginOfEvent *)
 This routine will be called when the appropriate signal arrives.

Private Attributes

bool m_primaryTracks
std::vector< std::string > m_selectedNames
std::vector< const
G4LogicalVolume * > 
m_selectedVolumes
MaterialAccountingTrack m_track
std::vector
< MaterialAccountingTrack > * 
m_tracks

Detailed Description

Definition at line 24 of file TrackingMaterialProducer.h.


Constructor & Destructor Documentation

TrackingMaterialProducer::TrackingMaterialProducer ( const edm::ParameterSet iPSet)

Definition at line 70 of file TrackingMaterialProducer.cc.

References HDQMDatabaseProducer::config, edm::ParameterSet::getParameter(), m_primaryTracks, m_selectedNames, and m_tracks.

{
  edm::ParameterSet config = iPSet.getParameter<edm::ParameterSet>("TrackingMaterialProducer");
  m_selectedNames       = config.getParameter< std::vector<std::string> >("SelectedVolumes");
  m_primaryTracks       = config.getParameter<bool>("PrimaryTracksOnly");
  m_tracks              = 0;

  produces< std::vector<MaterialAccountingTrack> >();
}    
TrackingMaterialProducer::~TrackingMaterialProducer ( void  ) [virtual]

Definition at line 81 of file TrackingMaterialProducer.cc.

{
}

Member Function Documentation

bool TrackingMaterialProducer::isSelected ( const G4VTouchable *  touch) [private]

Definition at line 250 of file TrackingMaterialProducer.cc.

References i, and m_selectedVolumes.

Referenced by update().

{
  for (size_t i = 0; i < m_selectedVolumes.size(); ++i)
    if (m_selectedVolumes[i]->IsAncestor( touchable->GetVolume() ) or m_selectedVolumes[i] == touchable->GetVolume()->GetLogicalVolume())
      return true;

  return false;
}
void TrackingMaterialProducer::produce ( edm::Event iEvent,
const edm::EventSetup iSetup 
) [private, virtual]

Implements SimProducer.

Definition at line 241 of file TrackingMaterialProducer.cc.

References m_tracks, edm::Event::put(), and testEve_cfg::tracks.

{
  // transfer ownership to the Event
  std::auto_ptr<std::vector<MaterialAccountingTrack> > tracks( m_tracks );
  iEvent.put( tracks );
  m_tracks = 0;
}
void TrackingMaterialProducer::update ( const BeginOfTrack ) [private, virtual]

This routine will be called when the appropriate signal arrives.

Implements Observer< const BeginOfTrack * >.

Definition at line 112 of file TrackingMaterialProducer.cc.

References m_primaryTracks, m_track, and MaterialAccountingTrack::reset().

{
  m_track.reset();

  // prevent secondary tracks from propagating
  G4Track* track = const_cast<G4Track*>((*event)());
  if (m_primaryTracks and track->GetParentID() != 0) {
    track->SetTrackStatus(fStopAndKill);
  }
}
void TrackingMaterialProducer::update ( const EndOfTrack ) [private, virtual]

This routine will be called when the appropriate signal arrives.

Implements Observer< const EndOfTrack * >.

Definition at line 213 of file TrackingMaterialProducer.cc.

References gather_cfg::cout, MaterialAccountingTrack::detectors(), MaterialAccountingStep::energyLoss(), MaterialAccountingStep::length(), m_primaryTracks, m_track, m_tracks, MaterialAccountingStep::radiationLengths(), MaterialAccountingTrack::steps(), and MaterialAccountingTrack::summary().

{
  const G4Track * track = (*event)();
  if (m_primaryTracks and track->GetParentID() != 0)
    return;

  m_tracks->push_back(m_track);

  // LogDebug
  std::cout << "this track took " << m_track.steps().size() << " steps, and passed through " << m_track.detectors().size() << " sensitive detectors" << std::endl;
  std::cout << "\ttrack length:      " << m_track.summary().length()           << " cm" << std::endl;
  std::cout << "\tradiation lengths: " << m_track.summary().radiationLengths() << std::endl;
  std::cout << "\tenergy loss:       " << m_track.summary().energyLoss()       << " MeV" << std::endl;

  /* 
  for (unsigned int i = 0; i < m_track.detectors().size(); ++i) {
    std::cout << m_track.detectors()[i].volume()->GetName() 
              << "\tR: " << m_track.detectors()[i].position().perp() 
              << "\tZ: " << m_track.detectors()[i].position().z() << std::endl;
    std::cout << "\tsegment length:    " << m_track.detectors()[i].material().length()           << " cm" << std::endl;
    std::cout << "\tradiation lengths: " << m_track.detectors()[i].material().radiationLengths() << std::endl;
    std::cout << "\tenergy loss:       " << m_track.detectors()[i].material().energyLoss()       << " MeV" << std::endl;
  }
  */
  std::cout << std::endl;
}
void TrackingMaterialProducer::update ( const G4Step *  ) [private, virtual]

This routine will be called when the appropriate signal arrives.

Implements Observer< const G4Step * >.

Definition at line 125 of file TrackingMaterialProducer.cc.

References MaterialAccountingTrack::enterDetector(), GetSensitiveVolume(), GetTransform(), isSelected(), MaterialAccountingTrack::leaveDetector(), testEve_cfg::level, m_track, pos, position, MaterialAccountingTrack::step(), and X0.

{
  const G4TouchableHistory* touchable = (G4TouchableHistory*)(step->GetTrack()->GetTouchable());
  if (not isSelected( touchable )) {
    //std::cout << "\t[...] skipping " << touchable->GetVolume()->GetName() << std::endl;
    return;
  }

  // material and step proterties
  const G4Material* material = touchable->GetVolume()->GetLogicalVolume()->GetMaterial();
  double length = step->GetStepLength() / cm;          // mm -> cm
  double X0 = material->GetRadlen() / cm;              // mm -> cm
  double Ne = material->GetElectronDensity() * cm3;    // 1/mm3 -> 1/cm3
  double Xi = Ne / 6.0221415e23 * 0.307075 / 2.;        // MeV / cm
  double radiationLengths = length / X0;                // 
  double energyLoss       = length * Xi;                // MeV
  //double energyLoss = step->GetDeltaEnergy()/MeV;  should we use this??

  G4ThreeVector globalPosPre  = step->GetPreStepPoint()->GetPosition();
  G4ThreeVector globalPosPost = step->GetPostStepPoint()->GetPosition();
  GlobalPoint globalPositionIn(  globalPosPre.x()  / cm, globalPosPre.y()  / cm, globalPosPre.z() / cm );    // mm -> cm
  GlobalPoint globalPositionOut( globalPosPost.x() / cm, globalPosPost.y() / cm, globalPosPost.z() / cm );   // mm -> cm

  // check for a sensitive detector 
  bool enter_sensitive = false;
  bool leave_sensitive = false;
  double cosThetaPre  = 0.0;
  double cosThetaPost = 0.0;
  int level = 0;
  const G4VPhysicalVolume* sensitive = 0;
  GlobalPoint position;
  boost::tuples::tie(sensitive, level) = GetSensitiveVolume(touchable);
  if (sensitive) {
    const G4VSolid &          solid     = *touchable->GetSolid( level );
    const G4AffineTransform & transform = GetTransform( touchable, level );
    G4ThreeVector pos = transform.Inverse().TransformPoint( G4ThreeVector( 0., 0., 0. ) );
    position = GlobalPoint( pos.x() / cm, pos.y() / cm, pos.z() / cm );  // mm -> cm
    
    G4ThreeVector localPosPre   = transform.TransformPoint( globalPosPre );
    EInside       statusPre     = solid.Inside( localPosPre );
    if (statusPre == kSurface) {
      enter_sensitive = true;
      G4ThreeVector globalDirPre  = step->GetPreStepPoint()->GetMomentumDirection();
      G4ThreeVector localDirPre   = transform.TransformAxis( globalDirPre );
      G4ThreeVector normalPre     = solid.SurfaceNormal( localPosPre );
      cosThetaPre  = normalPre.cosTheta( -localDirPre );
    }
    
    G4ThreeVector localPosPost  = transform.TransformPoint( globalPosPost );
    EInside       statusPost    = solid.Inside( localPosPost );
    if (statusPost == kSurface) {
      leave_sensitive = true;
      G4ThreeVector globalDirPost = step->GetPostStepPoint()->GetMomentumDirection();
      G4ThreeVector localDirPost  = transform.TransformAxis( globalDirPost );
      G4ThreeVector normalPost    = solid.SurfaceNormal( localPosPost );
      cosThetaPost = normalPost.cosTheta( localDirPost );
    }
  }
    
  // update track accounting
  if (enter_sensitive)
    m_track.enterDetector( sensitive, position, cosThetaPre );
  m_track.step(MaterialAccountingStep( length, radiationLengths, energyLoss, globalPositionIn, globalPositionOut ));
  if (leave_sensitive)
    m_track.leaveDetector( sensitive, cosThetaPost );

  /*
  for (int i = touchable->GetHistoryDepth(); i > 0; --i)
    std::cout << touchable->GetVolume(i)->GetName() << "::";
  std::cout << touchable->GetVolume()->GetName() << std::endl;
  std::cout << "\tmade of " << material->GetName();
  if (sensitive) {
    std::cout << " (inside sensitive " << sensitive->GetName() << ")";
    if (enter_sensitive)
      std::cout << " (in: cos(theta) = " << cosThetaPre << ")";
    if (leave_sensitive)
      std::cout << " (out: cos(theta) = " << cosThetaPost << ")";
  }
  std::cout << std::endl;
  std::cout << "\tStep length:       " << length << " cm" << std::endl;
  std::cout << "\tRadiation lengths: " << radiationLengths << " \t\t(X0: " << X0 << " cm)" << std::endl;
  std::cout << "\tEnergy loss:       " << energyLoss << " MeV  \t(Xi: " << Xi << " MeV/cm)" << std::endl;
  std::cout << std::endl;
  */
}
void TrackingMaterialProducer::update ( const BeginOfJob ) [private, virtual]

This routine will be called when the appropriate signal arrives.

Implements Observer< const BeginOfJob * >.

Definition at line 86 of file TrackingMaterialProducer.cc.

References benchmark_cfg::cerr, gather_cfg::cout, GetVolume(), m_selectedNames, and m_selectedVolumes.

{
  // INFO
  std::cout << "TrackingMaterialProducer: List of the selected volumes: " << std::endl;
  for (std::vector<std::string>::const_iterator volume_name = m_selectedNames.begin(); volume_name != m_selectedNames.end(); ++volume_name) {
    const G4LogicalVolume* volume = GetVolume(*volume_name);
    if (volume) {
      std::cout << '\t' << *volume_name << std::endl;
      m_selectedVolumes.push_back( volume );
    } else {
      // FIXME: throw an exception ?
      std::cerr << "TrackingMaterialProducer::update(const BeginOfJob*): WARNING: selected volume \"" << *volume_name << "\" not found in geometry " << std::endl;
    }
  }
  std::cout << std::endl;
}
void TrackingMaterialProducer::update ( const BeginOfEvent ) [private, virtual]

This routine will be called when the appropriate signal arrives.

Implements Observer< const BeginOfEvent * >.

Definition at line 105 of file TrackingMaterialProducer.cc.

References m_tracks.

{
  m_tracks = new std::vector<MaterialAccountingTrack>();
}

Member Data Documentation

Definition at line 46 of file TrackingMaterialProducer.h.

Referenced by TrackingMaterialProducer(), and update().

std::vector<std::string> TrackingMaterialProducer::m_selectedNames [private]

Definition at line 47 of file TrackingMaterialProducer.h.

Referenced by TrackingMaterialProducer(), and update().

std::vector<const G4LogicalVolume *> TrackingMaterialProducer::m_selectedVolumes [private]

Definition at line 48 of file TrackingMaterialProducer.h.

Referenced by isSelected(), and update().

Definition at line 49 of file TrackingMaterialProducer.h.

Referenced by update().

Definition at line 50 of file TrackingMaterialProducer.h.

Referenced by produce(), TrackingMaterialProducer(), and update().