Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/advanced/ChargeExchangeMC/src/CexmcReconstructor.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 /*
 27  * ============================================================================
 28  *
 29  *       Filename:  CexmcReconstructor.cc
 30  *
 31  *    Description:  reconstructor base class
 32  *
 33  *        Version:  1.0
 34  *        Created:  02.12.2009 16:21:15
 35  *       Revision:  none
 36  *       Compiler:  gcc
 37  *
 38  *         Author:  Alexey Radkov (), 
 39  *        Company:  PNPI
 40  *
 41  * ============================================================================
 42  */
 43 
 44 #include "CexmcReconstructor.hh"
 45 #include "CexmcReconstructorMessenger.hh"
 46 #include "CexmcEnergyDepositStore.hh"
 47 #include "CexmcRunManager.hh"
 48 
 49 
 50 CexmcReconstructor::CexmcReconstructor() : hasBasicTrigger( false ),
 51     epDefinitionAlgorithm( CexmcEntryPointBySqrtEDWeights ),
 52     epDepthDefinitionAlgorithm( CexmcEntryPointDepthPlain ),
 53     csAlgorithm( CexmcSelectAllCrystals ), useInnerRefCrystal( false ),
 54     epDepth( 0 ), theAngle( 0 ), calorimeterEDLeftAdjacent( 0 ),
 55     calorimeterEDRightAdjacent( 0 ), collectEDInAdjacentCrystals( false ),
 56     targetEPInitialized( false ), messenger( NULL )
 57 {
 58     G4RunManager *      runManager( G4RunManager::GetRunManager() );
 59     const CexmcSetup *  setup( static_cast< const CexmcSetup * >(
 60                                 runManager->GetUserDetectorConstruction() ) );
 61     calorimeterGeometry = setup->GetCalorimeterGeometry();
 62     targetTransform = setup->GetTargetTransform();
 63     calorimeterLeftTransform = setup->GetCalorimeterLeftTransform();
 64     calorimeterRightTransform = setup->GetCalorimeterRightTransform();
 65 
 66     messenger = new CexmcReconstructorMessenger( this );
 67 }
 68 
 69 
 70 CexmcReconstructor::~CexmcReconstructor()
 71 {
 72     delete messenger;
 73 }
 74 
 75 
 76 void  CexmcReconstructor::Reconstruct(
 77                                     const CexmcEnergyDepositStore *  edStore )
 78 {
 79     ReconstructEntryPoints( edStore );
 80     if ( hasBasicTrigger )
 81         ReconstructTargetPoint();
 82     if ( hasBasicTrigger )
 83         ReconstructAngle();
 84 }
 85 
 86 
 87 G4bool  CexmcReconstructor::HasFullTrigger( void ) const
 88 {
 89     return hasBasicTrigger;
 90 }
 91 
 92 
 93 void  CexmcReconstructor::ReconstructEntryPoints(
 94                                     const CexmcEnergyDepositStore *  edStore )
 95 {
 96     G4int     columnLeft( edStore->calorimeterEDLeftMaxX );
 97     G4int     rowLeft( edStore->calorimeterEDLeftMaxY );
 98     G4int     columnRight( edStore->calorimeterEDRightMaxX );
 99     G4int     rowRight( edStore->calorimeterEDRightMaxY );
100     G4double  crystalLength( calorimeterGeometry.crystalLength );
101 
102     if ( useInnerRefCrystal )
103     {
104         TransformToAdjacentInnerCrystal( columnLeft, rowLeft );
105         TransformToAdjacentInnerCrystal( columnRight, rowRight );
106     }
107 
108     calorimeterEPLeftPosition.setX( 0 );
109     calorimeterEPLeftPosition.setY( 0 );
110     calorimeterEPLeftPosition.setZ( -crystalLength / 2 + epDepth );
111     calorimeterEPLeftDirection.setX( 0 );
112     calorimeterEPLeftDirection.setY( 0 );
113     calorimeterEPLeftDirection.setZ( 0 );
114     calorimeterEPRightPosition.setX( 0 );
115     calorimeterEPRightPosition.setY( 0 );
116     calorimeterEPRightPosition.setZ( -crystalLength / 2 + epDepth );
117     calorimeterEPRightDirection.setX( 0 );
118     calorimeterEPRightDirection.setY( 0 );
119     calorimeterEPRightDirection.setZ( 0 );
120 
121     G4bool  edInAdjacentCrystalsCollected( false );
122 
123     switch ( epDefinitionAlgorithm )
124     {
125     case CexmcEntryPointInTheCenter :
126         break;
127     case CexmcEntryPointInTheCenterOfCrystalWithMaxED :
128         {
129             G4int     nCrystalsInColumn(
130                                     calorimeterGeometry.nCrystalsInColumn );
131             G4int     nCrystalsInRow( calorimeterGeometry.nCrystalsInRow );
132             G4double  crystalWidth( calorimeterGeometry.crystalWidth );
133             G4double  crystalHeight( calorimeterGeometry.crystalHeight );
134 
135             calorimeterEPLeftPosition.setX(
136                 ( G4double( columnLeft ) - G4double( nCrystalsInRow ) / 2 ) *
137                                         crystalWidth  + crystalWidth / 2 );
138             calorimeterEPLeftPosition.setY(
139                 ( G4double( rowLeft ) - G4double( nCrystalsInColumn ) / 2 ) *
140                                         crystalHeight + crystalHeight / 2 );
141             calorimeterEPRightPosition.setX(
142                 ( G4double( columnRight ) - G4double( nCrystalsInRow ) / 2 ) *
143                                         crystalWidth  + crystalWidth / 2 );
144             calorimeterEPRightPosition.setY(
145                 ( G4double( rowRight ) - G4double( nCrystalsInColumn ) / 2 ) *
146                                         crystalHeight + crystalHeight / 2 );
147         }
148         break;
149     case CexmcEntryPointByLinearEDWeights :
150     case CexmcEntryPointBySqrtEDWeights :
151         {
152             G4double  x( 0 );
153             G4double  y( 0 );
154 
155             CalculateWeightedEPPosition( edStore->calorimeterEDLeftCollection,
156                                          rowLeft, columnLeft, x, y,
157                                          calorimeterEDLeftAdjacent );
158             calorimeterEPLeftPosition.setX( x );
159             calorimeterEPLeftPosition.setY( y );
160             CalculateWeightedEPPosition( edStore->calorimeterEDRightCollection,
161                                          rowRight, columnRight, x, y,
162                                          calorimeterEDRightAdjacent );
163             calorimeterEPRightPosition.setX( x );
164             calorimeterEPRightPosition.setY( y );
165 
166             if ( csAlgorithm == CexmcSelectAdjacentCrystals )
167                 edInAdjacentCrystalsCollected = true;
168         }
169         break;
170     default :
171         break;
172     }
173 
174     switch ( epDepthDefinitionAlgorithm )
175     {
176     case CexmcEntryPointDepthPlain :
177         break;
178     case CexmcEntryPointDepthSphere :
179         {
180             G4double  calorimeterEPLeftRadiusOfTheSphere(
181                              calorimeterLeftTransform.NetTranslation().mag() +
182                              calorimeterEPLeftPosition.z() );
183             G4double  calorimeterEPLeftRadiusOfTheSphere2(
184                                       calorimeterEPLeftRadiusOfTheSphere *
185                                       calorimeterEPLeftRadiusOfTheSphere );
186             G4double  calorimeterEPLeftPositionX2(
187                                             calorimeterEPLeftPosition.x() *
188                                             calorimeterEPLeftPosition.x() );
189             G4double  calorimeterEPLeftPositionY2(
190                                             calorimeterEPLeftPosition.y() *
191                                             calorimeterEPLeftPosition.y() );
192             G4double  calorimeterEPLeftPositionZOffset(
193                            calorimeterEPLeftRadiusOfTheSphere - std::sqrt(
194                                   calorimeterEPLeftRadiusOfTheSphere2 -
195                                   calorimeterEPLeftPositionX2 -
196                                   calorimeterEPLeftPositionY2 ) );
197             G4double  calorimeterEPRightRadiusOfTheSphere(
198                               calorimeterRightTransform.NetTranslation().mag() +
199                               calorimeterEPRightPosition.z() );
200             G4double  calorimeterEPRightRadiusOfTheSphere2(
201                                        calorimeterEPRightRadiusOfTheSphere *
202                                        calorimeterEPRightRadiusOfTheSphere );
203             G4double  calorimeterEPRightPositionX2(
204                                             calorimeterEPRightPosition.x() *
205                                             calorimeterEPRightPosition.x() );
206             G4double  calorimeterEPRightPositionY2(
207                                             calorimeterEPRightPosition.y() *
208                                             calorimeterEPRightPosition.y() );
209             G4double  calorimeterEPRightPositionZOffset(
210                             calorimeterEPRightRadiusOfTheSphere - std::sqrt(
211                                     calorimeterEPRightRadiusOfTheSphere2 -
212                                     calorimeterEPRightPositionX2 -
213                                     calorimeterEPRightPositionY2 ) );
214             calorimeterEPLeftPosition.setZ( calorimeterEPLeftPosition.z() -
215                                             calorimeterEPLeftPositionZOffset );
216             calorimeterEPRightPosition.setZ( calorimeterEPRightPosition.z() -
217                                          calorimeterEPRightPositionZOffset );
218         }
219         break;
220     default :
221         break;
222     }
223 
224     calorimeterEPLeftWorldPosition = calorimeterLeftTransform.TransformPoint(
225                                                  calorimeterEPLeftPosition );
226     calorimeterEPLeftWorldDirection = calorimeterLeftTransform.TransformAxis(
227                                                  calorimeterEPLeftDirection );
228     calorimeterEPRightWorldPosition = calorimeterRightTransform.TransformPoint(
229                                                  calorimeterEPRightPosition );
230     calorimeterEPRightWorldDirection = calorimeterRightTransform.TransformAxis(
231                                                  calorimeterEPRightDirection );
232 
233     if ( collectEDInAdjacentCrystals && ! edInAdjacentCrystalsCollected )
234     {
235         CollectEDInAdjacentCrystals( edStore->calorimeterEDLeftCollection,
236                                      rowLeft, columnLeft,
237                                      calorimeterEDLeftAdjacent );
238         CollectEDInAdjacentCrystals( edStore->calorimeterEDRightCollection,
239                                      rowRight, columnRight,
240                                      calorimeterEDRightAdjacent );
241     }
242 
243     hasBasicTrigger = true;
244 }
245 
246 
247 void  CexmcReconstructor::ReconstructTargetPoint( void )
248 {
249     if ( ! targetEPInitialized )
250     {
251         targetEPWorldPosition = targetTransform.TransformPoint(
252                                                     G4ThreeVector( 0, 0, 0 ) );
253         targetEPWorldDirection.setX( 0 );
254         targetEPWorldDirection.setY( 0 );
255         targetEPWorldDirection.setZ( 1 );
256 
257         targetEPPosition = targetTransform.Inverse().TransformPoint(
258                                                     targetEPWorldPosition );
259         targetEPDirection = targetTransform.Inverse().TransformAxis(
260                                                     targetEPWorldDirection );
261         targetEPInitialized = true;
262     }
263 
264     hasBasicTrigger = true;
265 }
266 
267 
268 void  CexmcReconstructor::ReconstructAngle( void )
269 {
270     G4ThreeVector  epLeft( calorimeterEPLeftWorldPosition -
271                            targetEPWorldPosition );
272     G4ThreeVector  epRight( calorimeterEPRightWorldPosition -
273                             targetEPWorldPosition );
274     theAngle = epLeft.angle( epRight );
275 
276     hasBasicTrigger = true;
277 }
278 
279 
280 void  CexmcReconstructor::CollectEDInAdjacentCrystals(
281                         const CexmcEnergyDepositCalorimeterCollection &  edHits,
282                         G4int  row, G4int  column, G4double &  ed )
283 {
284     G4int  i( 0 );
285 
286     for ( CexmcEnergyDepositCalorimeterCollection::const_iterator
287                                 k( edHits.begin() ); k != edHits.end(); ++k )
288     {
289         if ( i - row > 1 || i - row < -1 )
290         {
291             ++i;
292             continue;
293         }
294 
295         G4int  j( 0 );
296         for ( CexmcEnergyDepositCrystalRowCollection::const_iterator
297                   l( k->begin() ); l != k->end(); ++l )
298         {
299             if ( j - column > 1 || j - column < -1 )
300             {
301                 ++j;
302                 continue;
303             }
304             ed += *l;
305             ++j;
306         }
307         ++i;
308     }
309 }
310 
311 
312 void  CexmcReconstructor::CalculateWeightedEPPosition(
313                 const CexmcEnergyDepositCalorimeterCollection &  edHits,
314                 G4int  row, G4int  column, G4double &  x, G4double &  y,
315                 G4double &  ed )
316 {
317     G4int     nCrystalsInColumn( calorimeterGeometry.nCrystalsInColumn );
318     G4int     nCrystalsInRow( calorimeterGeometry.nCrystalsInRow );
319     G4double  crystalWidth( calorimeterGeometry.crystalWidth );
320     G4double  crystalHeight( calorimeterGeometry.crystalHeight );
321 
322     G4int     i( 0 );
323     G4double  xWeightsSum( 0 );
324     G4double  yWeightsSum( 0 );
325     G4double  energyWeightsSum( 0 );
326 
327     if ( csAlgorithm == CexmcSelectAdjacentCrystals )
328         ed = 0.;
329 
330     for ( CexmcEnergyDepositCalorimeterCollection::const_iterator
331                                 k( edHits.begin() ); k != edHits.end(); ++k )
332     {
333         if ( csAlgorithm == CexmcSelectAdjacentCrystals &&
334                                          ( i - row > 1 || i - row < -1 ) )
335         {
336             ++i;
337             continue;
338         }
339 
340         G4int  j( 0 );
341         for ( CexmcEnergyDepositCrystalRowCollection::const_iterator
342                   l( k->begin() ); l != k->end(); ++l )
343         {
344             if ( csAlgorithm == CexmcSelectAdjacentCrystals &&
345                                          ( j - column > 1 || j - column < -1 ) )
346             {
347                 ++j;
348                 continue;
349             }
350 
351             if ( csAlgorithm == CexmcSelectAdjacentCrystals )
352                 ed += *l;
353             
354             G4double  xInCalorimeterOffset(
355                         ( G4double( j ) - G4double( nCrystalsInRow ) / 2 ) *
356                         crystalWidth  + crystalWidth / 2 );
357             G4double  energyWeight(
358                         epDefinitionAlgorithm ==
359                                         CexmcEntryPointBySqrtEDWeights ?
360                                                         std::sqrt( *l ) : *l );
361             xWeightsSum += energyWeight * xInCalorimeterOffset;
362             G4double  yInCalorimeterOffset(
363                         ( G4double( i ) - G4double( nCrystalsInColumn ) / 2 ) *
364                         crystalHeight  + crystalHeight / 2 );
365             yWeightsSum += energyWeight * yInCalorimeterOffset;
366             energyWeightsSum += energyWeight;
367             ++j;
368         }
369         ++i;
370     }
371 
372     x = xWeightsSum / energyWeightsSum;
373     y = yWeightsSum / energyWeightsSum;
374 }
375 
376