projects/lcdd/trunk/include/lcdd/detectors
--- projects/lcdd/trunk/include/lcdd/detectors/OpticalCalorimeterHitProcessor.hh (rev 0)
+++ projects/lcdd/trunk/include/lcdd/detectors/OpticalCalorimeterHitProcessor.hh 2014-07-16 00:43:37 UTC (rev 3190)
@@ -0,0 +1,73 @@
+// $Header: /nfs/slac/g/lcd/cvs/lcdroot/lcdd/include/lcdd/detectors/OpticalCalorimeterHitProcessor.hh,v 1.3 2013-11-14 00:46:45 jeremy Exp $
+
+#ifndef LCDD_DETECTORS_OPTICALCALORIMETERHITPROCESSOR_HH
+#define LCDD_DETECTORS_OPTICALCALORIMETERHITPROCESSOR_HH 1
+
+// LCDD
+#include "lcdd/detectors/LegacyCalorimeterHitProcessor.hh"
+#include "lcdd/detectors/Cerenkov.hh"
+#include "lcdd/detectors/HitProcessorFactory.hh"
+
+/**
+ * @brief HitProcessor to create CalorimeterHit objects in an optical calorimeter.
+ */
+class OpticalCalorimeterHitProcessor: public LegacyCalorimeterHitProcessor {
+public:
+
+ /**
+ * An enum for the two hit collections (cerenkov and edep).
+ */
+ enum HCType {
+ eEdep = 0, eCerenkov = 1
+ };
+
+public:
+
+ /**
+ * Class constructor.
+ * @param[in] calorimeter The calorimeter SD.
+ */
+ OpticalCalorimeterHitProcessor(CalorimeterSD* calorimeter);
+
+ /**
+ * Class destructor.
+ */
+ virtual ~OpticalCalorimeterHitProcessor();
+
+ /**
+ * Process steps to produce hits.
+ * @param[in] step The G4Step object.
+ */
+ bool processHits(G4Step* step);
+
+private:
+
+ /**
+ * Get the global hit position from a pre step point.
+ * @param[in] aPreStepPoint The pre step point.
+ */
+ G4ThreeVector getGlobalHitPosition(const G4StepPoint* aPreStepPoint);
+
+private:
+
+ Cerenkov* _cerenGenerator;
+};
+
+/**
+ * The factory for creating new OpticalCalorimeterHitProcessor objects.
+ */
+class OpticalCalorimeterHitProcessorFactory: public HitProcessorFactory {
+
+public:
+
+ HitProcessor* createHitProcessor(SensitiveDetector* sd) {
+ return new OpticalCalorimeterHitProcessor(dynamic_cast<CalorimeterSD*>(sd));
+ }
+
+ const std::string& handlesType() {
+ static std::string typeName = "OpticalCalorimeterHitProcessor";
+ return typeName;
+ }
+};
+
+#endif
projects/lcdd/trunk/src/lcdd/detectors
--- projects/lcdd/trunk/src/lcdd/detectors/OpticalCalorimeterHitProcessor.cc (rev 0)
+++ projects/lcdd/trunk/src/lcdd/detectors/OpticalCalorimeterHitProcessor.cc 2014-07-16 00:43:37 UTC (rev 3190)
@@ -0,0 +1,96 @@
+// $Header: /nfs/slac/g/lcd/cvs/lcdroot/lcdd/src/lcdd/detectors/OpticalCalorimeterHitProcessor.cc,v 1.7 2013-11-14 00:46:45 jeremy Exp $
+
+// LCDD
+#include "lcdd/detectors/OpticalCalorimeterHitProcessor.hh"
+#include "lcdd/detectors/ReadoutUtil.hh"
+
+// Geant4
+#include "G4OpticalPhoton.hh"
+#include "G4TransportationManager.hh"
+#include "G4VProcess.hh"
+#include "G4Poisson.hh"
+
+OpticalCalorimeterHitProcessor::OpticalCalorimeterHitProcessor(CalorimeterSD* calorimeter) :
+ LegacyCalorimeterHitProcessor(calorimeter), _cerenGenerator(0) {
+}
+
+OpticalCalorimeterHitProcessor::~OpticalCalorimeterHitProcessor() {
+ if (_cerenGenerator != 0) {
+ delete _cerenGenerator;
+ }
+}
+
+bool OpticalCalorimeterHitProcessor::processHits(G4Step* step) {
+ // FIXME: This initialization should not happen here.
+ // Put into PhysicsManager as statically accessible.
+ if (_cerenGenerator == 0) {
+ _cerenGenerator = new Cerenkov();
+ }
+
+ G4int NCerenPhotons = 0;
+ G4Track* theTrack = step->GetTrack();
+ const G4double charge = theTrack->GetDefinition()->GetPDGCharge();
+ G4StepPoint* pPreStepPoint = step->GetPreStepPoint();
+ G4StepPoint* pPostStepPoint = step->GetPostStepPoint();
+ G4double beta = 0.5 * (pPreStepPoint->GetBeta() + pPostStepPoint->GetBeta());
+ const G4VTouchable* touch = step->GetPreStepPoint()->GetTouchable();
+ G4String thematerial = touch->GetVolume()->GetLogicalVolume()->GetMaterial()->GetName();
+ G4double MeanNumberOfPhotons = _cerenGenerator->GetAverageNumberOfPhotons(charge, beta, thematerial);
+ if (MeanNumberOfPhotons > 0.0) {
+ G4double step_length = step->GetStepLength();
+ MeanNumberOfPhotons = MeanNumberOfPhotons * step_length;
+ NCerenPhotons = (G4int) G4Poisson(MeanNumberOfPhotons);
+ } else {
+ NCerenPhotons = 0;
+ }
+
+ if (NCerenPhotons <= 0) {
+ return LegacyCalorimeterHitProcessor::processHits(step);
+ } else {
+ G4ThreeVector myPoint = step->GetPreStepPoint()->GetPosition();
+ G4StepPoint* apreStepPoint = step->GetPreStepPoint();
+ G4double theEdep = double(NCerenPhotons);
+ // get global cell pos from seg
+ G4ThreeVector globalCellPos = getGlobalHitPosition(apreStepPoint);
+ // set the seg bins
+ _calorimeter->getSegmentation()->setBins(step);
+
+ // Create an identifier.
+ Id64bit id64 = _calorimeter->makeIdentifier(step);
+
+ // Look for existing hit.
+ CalorimeterHit* hit = _calorimeter->findHit(id64);
+
+ // Was hit found?
+ if (hit == 0) {
+
+ // Hit was not found, so new one is created.
+ hit = new CalorimeterHit(id64, theEdep, globalCellPos);
+
+ // Add hit to calorimeter.
+ _calorimeter->addHit(hit, eCerenkov);
+ } else {
+ // Add energy deposition to existing hit.
+ hit->addEdep(theEdep);
+ }
+ // add McpHitContrib to this hit, setting info from step info
+ hit->addHitContribution(HitContribution(step));
+ return true;
+ } // end Cerenkov photon treatment
+}
+
+G4ThreeVector OpticalCalorimeterHitProcessor::getGlobalHitPosition(const G4StepPoint* aPreStepPoint) {
+ G4ThreeVector globalStepPos = aPreStepPoint->GetPosition();
+
+ // Figure out local step pos using touchable and global midpoint.
+ G4ThreeVector localStepPos = ReadoutUtil::transformGlobalToLocal(aPreStepPoint, globalStepPos);
+
+ // Compute local cell pos.
+ G4ThreeVector localCellPos = _calorimeter->getSegmentation()->getLocalHitPosition(localStepPos);
+
+ // Compute global cell pos.
+ G4ThreeVector globalCellPos = ReadoutUtil::transformLocalToGlobal(aPreStepPoint, localCellPos);
+
+ return globalCellPos;
+}
+