Files
geant4/examples/advanced/ChargeExchangeMC/src/CexmcReconstructor.cc
T
2016-06-09 16:46:55 +02:00

376 lines
15 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/*
* ============================================================================
*
* Filename: CexmcReconstructor.cc
*
* Description: reconstructor base class
*
* Version: 1.0
* Created: 02.12.2009 16:21:15
* Revision: none
* Compiler: gcc
*
* Author: Alexey Radkov (),
* Company: PNPI
*
* ============================================================================
*/
#include "CexmcReconstructor.hh"
#include "CexmcReconstructorMessenger.hh"
#include "CexmcEnergyDepositStore.hh"
#include "CexmcRunManager.hh"
CexmcReconstructor::CexmcReconstructor() : hasBasicTrigger( false ),
epDefinitionAlgorithm( CexmcEntryPointBySqrtEDWeights ),
epDepthDefinitionAlgorithm( CexmcEntryPointDepthPlain ),
csAlgorithm( CexmcSelectAllCrystals ), useInnerRefCrystal( false ),
epDepth( 0 ), theAngle( 0 ), calorimeterEDLeftAdjacent( 0 ),
calorimeterEDRightAdjacent( 0 ), collectEDInAdjacentCrystals( false ),
targetEPInitialized( false ), messenger( NULL )
{
G4RunManager * runManager( G4RunManager::GetRunManager() );
const CexmcSetup * setup( static_cast< const CexmcSetup * >(
runManager->GetUserDetectorConstruction() ) );
calorimeterGeometry = setup->GetCalorimeterGeometry();
targetTransform = setup->GetTargetTransform();
calorimeterLeftTransform = setup->GetCalorimeterLeftTransform();
calorimeterRightTransform = setup->GetCalorimeterRightTransform();
messenger = new CexmcReconstructorMessenger( this );
}
CexmcReconstructor::~CexmcReconstructor()
{
delete messenger;
}
void CexmcReconstructor::Reconstruct(
const CexmcEnergyDepositStore * edStore )
{
ReconstructEntryPoints( edStore );
if ( hasBasicTrigger )
ReconstructTargetPoint();
if ( hasBasicTrigger )
ReconstructAngle();
}
G4bool CexmcReconstructor::HasFullTrigger( void ) const
{
return hasBasicTrigger;
}
void CexmcReconstructor::ReconstructEntryPoints(
const CexmcEnergyDepositStore * edStore )
{
G4int columnLeft( edStore->calorimeterEDLeftMaxX );
G4int rowLeft( edStore->calorimeterEDLeftMaxY );
G4int columnRight( edStore->calorimeterEDRightMaxX );
G4int rowRight( edStore->calorimeterEDRightMaxY );
G4double crystalLength( calorimeterGeometry.crystalLength );
if ( useInnerRefCrystal )
{
TransformToAdjacentInnerCrystal( columnLeft, rowLeft );
TransformToAdjacentInnerCrystal( columnRight, rowRight );
}
calorimeterEPLeftPosition.setX( 0 );
calorimeterEPLeftPosition.setY( 0 );
calorimeterEPLeftPosition.setZ( -crystalLength / 2 + epDepth );
calorimeterEPLeftDirection.setX( 0 );
calorimeterEPLeftDirection.setY( 0 );
calorimeterEPLeftDirection.setZ( 0 );
calorimeterEPRightPosition.setX( 0 );
calorimeterEPRightPosition.setY( 0 );
calorimeterEPRightPosition.setZ( -crystalLength / 2 + epDepth );
calorimeterEPRightDirection.setX( 0 );
calorimeterEPRightDirection.setY( 0 );
calorimeterEPRightDirection.setZ( 0 );
G4bool edInAdjacentCrystalsCollected( false );
switch ( epDefinitionAlgorithm )
{
case CexmcEntryPointInTheCenter :
break;
case CexmcEntryPointInTheCenterOfCrystalWithMaxED :
{
G4int nCrystalsInColumn(
calorimeterGeometry.nCrystalsInColumn );
G4int nCrystalsInRow( calorimeterGeometry.nCrystalsInRow );
G4double crystalWidth( calorimeterGeometry.crystalWidth );
G4double crystalHeight( calorimeterGeometry.crystalHeight );
calorimeterEPLeftPosition.setX(
( G4double( columnLeft ) - G4double( nCrystalsInRow ) / 2 ) *
crystalWidth + crystalWidth / 2 );
calorimeterEPLeftPosition.setY(
( G4double( rowLeft ) - G4double( nCrystalsInColumn ) / 2 ) *
crystalHeight + crystalHeight / 2 );
calorimeterEPRightPosition.setX(
( G4double( columnRight ) - G4double( nCrystalsInRow ) / 2 ) *
crystalWidth + crystalWidth / 2 );
calorimeterEPRightPosition.setY(
( G4double( rowRight ) - G4double( nCrystalsInColumn ) / 2 ) *
crystalHeight + crystalHeight / 2 );
}
break;
case CexmcEntryPointByLinearEDWeights :
case CexmcEntryPointBySqrtEDWeights :
{
G4double x( 0 );
G4double y( 0 );
CalculateWeightedEPPosition( edStore->calorimeterEDLeftCollection,
rowLeft, columnLeft, x, y,
calorimeterEDLeftAdjacent );
calorimeterEPLeftPosition.setX( x );
calorimeterEPLeftPosition.setY( y );
CalculateWeightedEPPosition( edStore->calorimeterEDRightCollection,
rowRight, columnRight, x, y,
calorimeterEDRightAdjacent );
calorimeterEPRightPosition.setX( x );
calorimeterEPRightPosition.setY( y );
if ( csAlgorithm == CexmcSelectAdjacentCrystals )
edInAdjacentCrystalsCollected = true;
}
break;
default :
break;
}
switch ( epDepthDefinitionAlgorithm )
{
case CexmcEntryPointDepthPlain :
break;
case CexmcEntryPointDepthSphere :
{
G4double calorimeterEPLeftRadiusOfTheSphere(
calorimeterLeftTransform.NetTranslation().mag() +
calorimeterEPLeftPosition.z() );
G4double calorimeterEPLeftRadiusOfTheSphere2(
calorimeterEPLeftRadiusOfTheSphere *
calorimeterEPLeftRadiusOfTheSphere );
G4double calorimeterEPLeftPositionX2(
calorimeterEPLeftPosition.x() *
calorimeterEPLeftPosition.x() );
G4double calorimeterEPLeftPositionY2(
calorimeterEPLeftPosition.y() *
calorimeterEPLeftPosition.y() );
G4double calorimeterEPLeftPositionZOffset(
calorimeterEPLeftRadiusOfTheSphere - std::sqrt(
calorimeterEPLeftRadiusOfTheSphere2 -
calorimeterEPLeftPositionX2 -
calorimeterEPLeftPositionY2 ) );
G4double calorimeterEPRightRadiusOfTheSphere(
calorimeterRightTransform.NetTranslation().mag() +
calorimeterEPRightPosition.z() );
G4double calorimeterEPRightRadiusOfTheSphere2(
calorimeterEPRightRadiusOfTheSphere *
calorimeterEPRightRadiusOfTheSphere );
G4double calorimeterEPRightPositionX2(
calorimeterEPRightPosition.x() *
calorimeterEPRightPosition.x() );
G4double calorimeterEPRightPositionY2(
calorimeterEPRightPosition.y() *
calorimeterEPRightPosition.y() );
G4double calorimeterEPRightPositionZOffset(
calorimeterEPRightRadiusOfTheSphere - std::sqrt(
calorimeterEPRightRadiusOfTheSphere2 -
calorimeterEPRightPositionX2 -
calorimeterEPRightPositionY2 ) );
calorimeterEPLeftPosition.setZ( calorimeterEPLeftPosition.z() -
calorimeterEPLeftPositionZOffset );
calorimeterEPRightPosition.setZ( calorimeterEPRightPosition.z() -
calorimeterEPRightPositionZOffset );
}
break;
default :
break;
}
calorimeterEPLeftWorldPosition = calorimeterLeftTransform.TransformPoint(
calorimeterEPLeftPosition );
calorimeterEPLeftWorldDirection = calorimeterLeftTransform.TransformAxis(
calorimeterEPLeftDirection );
calorimeterEPRightWorldPosition = calorimeterRightTransform.TransformPoint(
calorimeterEPRightPosition );
calorimeterEPRightWorldDirection = calorimeterRightTransform.TransformAxis(
calorimeterEPRightDirection );
if ( collectEDInAdjacentCrystals && ! edInAdjacentCrystalsCollected )
{
CollectEDInAdjacentCrystals( edStore->calorimeterEDLeftCollection,
rowLeft, columnLeft,
calorimeterEDLeftAdjacent );
CollectEDInAdjacentCrystals( edStore->calorimeterEDRightCollection,
rowRight, columnRight,
calorimeterEDRightAdjacent );
}
hasBasicTrigger = true;
}
void CexmcReconstructor::ReconstructTargetPoint( void )
{
if ( ! targetEPInitialized )
{
targetEPWorldPosition = targetTransform.TransformPoint(
G4ThreeVector( 0, 0, 0 ) );
targetEPWorldDirection.setX( 0 );
targetEPWorldDirection.setY( 0 );
targetEPWorldDirection.setZ( 1 );
targetEPPosition = targetTransform.Inverse().TransformPoint(
targetEPWorldPosition );
targetEPDirection = targetTransform.Inverse().TransformAxis(
targetEPWorldDirection );
targetEPInitialized = true;
}
hasBasicTrigger = true;
}
void CexmcReconstructor::ReconstructAngle( void )
{
G4ThreeVector epLeft( calorimeterEPLeftWorldPosition -
targetEPWorldPosition );
G4ThreeVector epRight( calorimeterEPRightWorldPosition -
targetEPWorldPosition );
theAngle = epLeft.angle( epRight );
hasBasicTrigger = true;
}
void CexmcReconstructor::CollectEDInAdjacentCrystals(
const CexmcEnergyDepositCalorimeterCollection & edHits,
G4int row, G4int column, G4double & ed )
{
G4int i( 0 );
for ( CexmcEnergyDepositCalorimeterCollection::const_iterator
k( edHits.begin() ); k != edHits.end(); ++k )
{
if ( i - row > 1 || i - row < -1 )
{
++i;
continue;
}
G4int j( 0 );
for ( CexmcEnergyDepositCrystalRowCollection::const_iterator
l( k->begin() ); l != k->end(); ++l )
{
if ( j - column > 1 || j - column < -1 )
{
++j;
continue;
}
ed += *l;
++j;
}
++i;
}
}
void CexmcReconstructor::CalculateWeightedEPPosition(
const CexmcEnergyDepositCalorimeterCollection & edHits,
G4int row, G4int column, G4double & x, G4double & y,
G4double & ed )
{
G4int nCrystalsInColumn( calorimeterGeometry.nCrystalsInColumn );
G4int nCrystalsInRow( calorimeterGeometry.nCrystalsInRow );
G4double crystalWidth( calorimeterGeometry.crystalWidth );
G4double crystalHeight( calorimeterGeometry.crystalHeight );
G4int i( 0 );
G4double xWeightsSum( 0 );
G4double yWeightsSum( 0 );
G4double energyWeightsSum( 0 );
if ( csAlgorithm == CexmcSelectAdjacentCrystals )
ed = 0.;
for ( CexmcEnergyDepositCalorimeterCollection::const_iterator
k( edHits.begin() ); k != edHits.end(); ++k )
{
if ( csAlgorithm == CexmcSelectAdjacentCrystals &&
( i - row > 1 || i - row < -1 ) )
{
++i;
continue;
}
G4int j( 0 );
for ( CexmcEnergyDepositCrystalRowCollection::const_iterator
l( k->begin() ); l != k->end(); ++l )
{
if ( csAlgorithm == CexmcSelectAdjacentCrystals &&
( j - column > 1 || j - column < -1 ) )
{
++j;
continue;
}
if ( csAlgorithm == CexmcSelectAdjacentCrystals )
ed += *l;
G4double xInCalorimeterOffset(
( G4double( j ) - G4double( nCrystalsInRow ) / 2 ) *
crystalWidth + crystalWidth / 2 );
G4double energyWeight(
epDefinitionAlgorithm ==
CexmcEntryPointBySqrtEDWeights ?
std::sqrt( *l ) : *l );
xWeightsSum += energyWeight * xInCalorimeterOffset;
G4double yInCalorimeterOffset(
( G4double( i ) - G4double( nCrystalsInColumn ) / 2 ) *
crystalHeight + crystalHeight / 2 );
yWeightsSum += energyWeight * yInCalorimeterOffset;
energyWeightsSum += energyWeight;
++j;
}
++i;
}
x = xWeightsSum / energyWeightsSum;
y = yWeightsSum / energyWeightsSum;
}