Marlin  01.17.01
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SimpleFastMCProcessor.cc
Go to the documentation of this file.
1 #include "marlin/MarlinConfig.h" // defines MARLIN_CLHEP / MARLIN_AIDA
2 
4 
9 #include "marlin/ErrorOfSigma.h"
10 
11 
12 //--- LCIO headers
13 #include "IMPL/LCCollectionVec.h"
16 
17 
18 #ifdef MARLIN_AIDA
19 #include <marlin/AIDAProcessor.h>
20 #include <AIDA/IHistogramFactory.h>
21 #include <AIDA/ICloud1D.h>
22 //#include <AIDA/ICloud2D.h>
23 #include <AIDA/IHistogram1D.h>
24 #include <AIDA/IProfile1D.h>
25 #include <AIDA/IDataPointSetFactory.h>
26 #include <AIDA/IDataPointSet.h>
27 #include <AIDA/IDataPoint.h>
28 #include <AIDA/IMeasurement.h>
29 #include <AIDA/IManagedObject.h>
30 #include <AIDA/ITree.h>
31 #include <AIDA/IAxis.h>
32 #endif // MARLIN_AIDA
33 
34 #include <iostream>
35 #include <cmath>
36 
37 using namespace lcio ;
38 
39 
40 namespace marlin{
41 
42 
44 
45 
46  SimpleFastMCProcessor::SimpleFastMCProcessor() : Processor("SimpleFastMCProcessor"),
47  _factory(NULL),
48  _nRun(-1),
49  _nEvt(-1)
50  {
51 
52  // modify processor description
53  _description = "SimpleFastMCProcessor creates ReconstrcutedParticles from MCParticles "
54  "according to the resolution given in the steering file." ;
55 
56 
57  // register steering parameters: name, description, class-variable, default value
58 
59  registerInputCollection( LCIO::MCPARTICLE,
60  "InputCollectionName" ,
61  "Name of the MCParticle input collection" ,
63  std::string("MCParticle") ) ;
64 
65 
66  registerOutputCollection( LCIO::RECONSTRUCTEDPARTICLE,
67  "RecoParticleCollectionName" ,
68  "Name of the ReconstructedParticles output collection" ,
70  std::string("ReconstructedParticles") ) ;
71 
72  registerOutputCollection( LCIO::LCRELATION,
73  "MCTruthMappingCollectionName" ,
74  "Name of the MCTruthMapping output collection" ,
76  std::string("MCTruthMapping") ) ;
77 
78 
79  registerProcessorParameter( "MomentumCut" ,
80  "No reconstructed particles are produced for smaller momenta (in [GeV])" ,
81  _momentumCut ,
82  float( 0.001 ) ) ;
83 
84  FloatVec chResDefault ;
85  chResDefault.push_back( 5e-5 ) ;
86  chResDefault.push_back( 0.00 ) ;
87  chResDefault.push_back( 3.141593/2. ) ;
88 
89  registerProcessorParameter( "ChargedResolution" ,
90  "Resolution of charged particles in polar angle range: d(1/P) th_min th_max" ,
92  chResDefault ,
93  chResDefault.size() ) ;
94 
95  FloatVec gammaResDefault ;
96  gammaResDefault.push_back( 0.01 ) ;
97  gammaResDefault.push_back( 0.10 ) ;
98  gammaResDefault.push_back( 0.00 ) ;
99  gammaResDefault.push_back( 3.141593/2. ) ;
100 
101  registerProcessorParameter( "PhotonResolution" ,
102  "Resolution dE/E=A+B/sqrt(E/GeV) of photons in polar angle range: A B th_min th_max" ,
104  gammaResDefault ,
105  gammaResDefault.size() ) ;
106 
107  FloatVec hadronResDefault ;
108  hadronResDefault.push_back( 0.04 ) ;
109  hadronResDefault.push_back( 0.50 ) ;
110  hadronResDefault.push_back( 0.00 ) ;
111  hadronResDefault.push_back( 3.141593/2. ) ;
112 
113  registerProcessorParameter( "NeutralHadronResolution" ,
114  "Resolution dE/E=A+B/sqrt(E/GeV) of neutral hadrons in polar angle range: A B th_min th_max" ,
116  hadronResDefault ,
117  hadronResDefault.size() ) ;
118 
119 
120 
121  }
122 
123 
125 
126  // usually a good idea to
127  printParameters() ;
128 
129  _nRun = 0 ;
130  _nEvt = 0 ;
131 
132 
133 
134  _factory = 0 ;
135 
136 #ifdef MARLIN_CLHEP
137 
138  SimpleParticleFactory* simpleFactory = new SimpleParticleFactory() ;
139 
140  simpleFactory->registerIFourVectorSmearer( new SimpleTrackSmearer( _initChargedRes ), CHARGED ) ;
141  simpleFactory->registerIFourVectorSmearer( new SimpleClusterSmearer( _initPhotonRes ), PHOTON ) ;
142  simpleFactory->registerIFourVectorSmearer( new SimpleClusterSmearer( _initNeutralHadronRes ), NEUTRAL_HADRON ) ;
143  simpleFactory->setMomentumCut( _momentumCut ) ;
144 
145  _factory = simpleFactory ;
146 
147  streamlog_out( MESSAGE ) << " SimpleFastMCProcessor::init() : registering SimpleParticleFactory " << std::endl ;
148 
149 #endif // MARLIN_CLHEP
150 
151  }
152 
153 
155  _nRun++ ;
156  }
157 
158 
159  void SimpleFastMCProcessor::processEvent( LCEvent * evt ) {
160 
161  const LCCollection* mcpCol = evt->getCollection( _inputCollectionName ) ;
162 
163  LCCollectionVec* recVec = new LCCollectionVec( LCIO::RECONSTRUCTEDPARTICLE ) ;
164 
165  LCRelationNavigator relNav( LCIO::RECONSTRUCTEDPARTICLE , LCIO::MCPARTICLE ) ;
166 
167  for(int i=0; i<mcpCol->getNumberOfElements() ; i++){
168 
169  MCParticle* mcp = dynamic_cast<MCParticle*> ( mcpCol->getElementAt( i ) ) ;
170 
171  // if( mcp->getDaughters().size() == 0 ) { // stable particles only
172 
173  if( mcp->getGeneratorStatus() == 1 ) { // stable particles only
174 
175  ReconstructedParticle* rec = 0 ;
176 
177  if( _factory != 0 )
178  rec = _factory->createReconstructedParticle( mcp ) ;
179 
180  if( rec != 0 ) {
181  recVec->addElement( rec ) ;
182  relNav.addRelation( rec , mcp ) ;
183  }
184  }
185 
186  }
187  recVec->setDefault( true ) ;
188 
189  evt->addCollection( recVec, _recoParticleCollectionName ) ;
190  evt->addCollection( relNav.createLCCollection() , _mcTruthCollectionName ) ;
191 
192 
193  _nEvt ++ ;
194  }
195 
196 
197 
198  void SimpleFastMCProcessor::check( LCEvent * evt ) {
199 
200 
201 #ifdef MARLIN_AIDA
202 
203  // define a histogram pointer
204  static AIDA::ICloud1D* hChargedRes ;
205 
206  static AIDA::ICloud1D* hChargedEnergy ;
207  static AIDA::ICloud1D* hPhotonEnergy ;
208  static AIDA::ICloud1D* hHadronEnergy ;
209  //~ static AIDA::ICloud1D* hLostEnergy ;
210 
211  static AIDA::IHistogram1D* hPhotonRes ;
212  static AIDA::IHistogram1D* hHadronRes ;
213 
214  static AIDA::IProfile1D* hGamHelperP1 ;
215  static AIDA::IProfile1D* hHadHelperP1 ;
216 
217 
218  if( isFirstEvent() ) {
219 
220  hChargedRes = AIDAProcessor::histogramFactory(this)->
221  createCloud1D( "hChargedRes", "dP/P for charged tracks", 100 ) ;
222 
223 
224  hChargedEnergy = AIDAProcessor::histogramFactory(this)->
225  createCloud1D( "hChargedEnergy", "E/GeV for charged particles", 100 ) ;
226 
227  hPhotonEnergy = AIDAProcessor::histogramFactory(this)->
228  createCloud1D( "hPhotonEnergy", "E/GeV for photons", 100 ) ;
229 
230  hHadronEnergy = AIDAProcessor::histogramFactory(this)->
231  createCloud1D( "hHadronEnergy", "E/GeV for neutral hadrons", 100 ) ;
232 
233  //~ hLostEnergy = AIDAProcessor::histogramFactory(this)->
234  //~ createCloud1D( "hLostEnergy", "E/GeV for not reconstructed particles", 100 ) ;
235 
236 
237  hPhotonRes = AIDAProcessor::histogramFactory(this)->
238  createHistogram1D( "hPhotonRes", "dE/E for photons", 100, -2.,2. ) ;
239 
240  hHadronRes = AIDAProcessor::histogramFactory(this)->
241  createHistogram1D( "hHadronRes", "dE/E for neutral hadrons", 100, -2., 2. ) ;
242 
243 
244  hGamHelperP1 = AIDAProcessor::histogramFactory(this)->
245  createProfile1D( "hGamHelperP1", " helper profile of energy spread", 10, 0.,20. ) ;
246 
247  hHadHelperP1 = AIDAProcessor::histogramFactory(this)->
248  createProfile1D( "hHadHelperP1", " helper profile of energy spread", 10, 0.,20. ) ;
249  }
250 
251 
252  // fill histogram from LCIO data :
253 
254  LCCollection* recCol = evt->getCollection(_recoParticleCollectionName ) ;
255 
256  LCCollection* relCol = evt->getCollection( _mcTruthCollectionName ) ;
257 
258  if( relCol == 0 ) {
259  streamlog_out( WARNING ) << "SimpleFastMCProcessor::check no collection found: MCTruthMapping" << std::endl ;
260  return ;
261  }
262 
263  LCRelationNavigator relNav( relCol ) ;
264 
265  if( recCol != 0 ){
266 
267  int nRec = recCol->getNumberOfElements() ;
268 
269  for(int i=0; i< nRec ; i++){
270 
271  ReconstructedParticle* rec = dynamic_cast<ReconstructedParticle*>( recCol->getElementAt( i ) ) ;
272 
273  const LCObjectVec& mcps = relNav.getRelatedToObjects( rec ) ;
274 
275  MCParticle* mcp = dynamic_cast<MCParticle*>( mcps[0] ) ; // we have a 1-1 relation here
276 
277 
278  if( rec->getType() == CHARGED) {
279 
280  double recP = std::sqrt( rec->getMomentum()[0] * rec->getMomentum()[0] +
281  rec->getMomentum()[1] * rec->getMomentum()[1] +
282  rec->getMomentum()[2] * rec->getMomentum()[2] ) ;
283 
284  double mcpP = std::sqrt( mcp->getMomentum()[0] * mcp->getMomentum()[0] +
285  mcp->getMomentum()[1] * mcp->getMomentum()[1] +
286  mcp->getMomentum()[2] * mcp->getMomentum()[2] ) ;
287 
288  hChargedRes->fill( ( recP - mcpP ) / recP ) ;
289 
290  hChargedEnergy->fill( rec->getEnergy() ) ;
291 
292  } else { // not charged
293 
294  double rE = rec->getEnergy() ;
295  double mE = mcp->getEnergy() ;
296 
297  double dEoverE = ( rE - mE ) / mE ;
298 
299  if( rec->getType() == PHOTON) {
300 
301  hPhotonEnergy->fill( mE ) ;
302  hGamHelperP1->fill( mE , dEoverE ) ;
303  hPhotonRes->fill( dEoverE , mE ) ;
304 
305  }
306  else if( rec->getType() == NEUTRAL_HADRON ) {
307 
308  // if( mE > 0.9 && mE < 1.1 ){
309 
310  hHadronRes->fill( dEoverE , mE ) ;
311  hHadronEnergy->fill( mE ) ;
312  hHadHelperP1->fill( mE , dEoverE ) ;
313 
314  // }
315 
316 
317  }
318 
319  } // not charged
320 
321  } // for nReco
322 
323  } // recoCol != 0
324 
325 #endif // MARLIN_AIDA
326 
327 
328  }
329 
330 
332 
333  streamlog_out( MESSAGE4 ) << "SimpleFastMCProcessor::end() " << name()
334  << " processed " << _nEvt << " events in " << _nRun << " runs "
335  << std::endl ;
336 
337 #ifdef MARLIN_AIDA_IGNORE_FOR_NOW
338  // FIXME:
339  // RAIDA does not support DataPoint sets and AIDA in generall does not allow to create a histogramm
340  // with 'faked' entries from another source (i.e. bin mean, bin error, ...)
341 
342  // create data sets for the energy resolution in the calorimeter
343 
344  AIDA::IProfile1D* hGamHelperP1 = 0 ;
345  AIDA::IManagedObject* obj = AIDAProcessor::tree(this)->find("hGamHelperP1") ;
346  if( obj != 0 ) hGamHelperP1 = static_cast<AIDA::IProfile1D*>( obj->cast("AIDA::IProfile1D") ) ;
347 
348  AIDA::IProfile1D* hHadHelperP1 = 0 ;
349  obj = AIDAProcessor::tree(this)->find("hHadHelperP1");
350  if( obj != 0 ) hHadHelperP1 = static_cast<AIDA::IProfile1D*>( obj->cast("AIDA::IProfile1D") ) ;
351 
352 
353  AIDA::IDataPointSet* dPhotonRes = AIDAProcessor::dataPointSetFactory(this)->
354  create("dPhotonRes","dE/E vs. 1./sqrt(E/GeV)",2 ) ;
355 
356  AIDA::IDataPointSet* dHadronRes = AIDAProcessor::dataPointSetFactory(this)->
357  create("dHadronRes","dE/E vs. 1./sqrt(E/GeV)",2 ) ;
358 
359  if( hHadHelperP1 != 0 ){
360 
361  for ( int i = 0; i< hHadHelperP1->axis().bins() ; i++ ) {
362 
363  dHadronRes->addPoint() ;
364 
365  double sigma = hHadHelperP1->binRms(i) ;
366  ErrorOfSigma eos( hHadHelperP1->binEntries(i) ) ;
367 
368 // std::cout << " hadrons - sigma : " << sigma << std::endl ;
369 // std::cout << " hadrons - dSigma- : " << eos.lowerError( sigma ) << std::endl ;
370 // std::cout << " hadrons - dSigma- : " << eos.upperError( sigma ) << std::endl ;
371 // std::cout << " hadrons - entries : " << hHadHelperP1->binEntries(i) << std::endl ;
372 // std::cout << " hadrons - bin mean : " << hHadHelperP1->binMean(i) << std::endl ;
373 // std::cout << " hadrons - 1/sqrt(e) : " << 1. / std::sqrt(hHadHelperP1->binMean(i)) << std::endl ;
374 
375 
376  dHadronRes->point(i)->coordinate(0)->setValue( 1. / std::sqrt( hHadHelperP1->binMean(i) ) ) ;
377 
378  dHadronRes->point(i)->coordinate(1)->setValue( sigma ) ;
379 
380  // use symmetric errors - needed for fitting
381  double errorMean = ( eos.upperError( sigma ) + eos.lowerError( sigma ) ) / 2 ;
382 
383  dHadronRes->point(i)->coordinate(1)->setErrorPlus( errorMean ) ;
384  dHadronRes->point(i)->coordinate(1)->setErrorMinus( errorMean ) ;
385  // dHadronRes->point(i)->coordinate(1)->setErrorPlus( eos.upperError( sigma ) ) ;
386  // dHadronRes->point(i)->coordinate(1)->setErrorMinus( eos.lowerError( sigma ) ) ;
387 
388  }
389 
390  }
391 
392  if( hGamHelperP1 != 0 ){
393 
394  for ( int i = 0; i< hGamHelperP1->axis().bins() ; i++ ) {
395 
396  dPhotonRes->addPoint() ;
397 
398  double sigma = hGamHelperP1->binRms(i) ;
399  ErrorOfSigma eos( hGamHelperP1->binEntries(i) ) ;
400 
401 // std::cout << " SimpleFastMCProcessor::end(): sigma : " << sigma << std::endl ;
402 // std::cout << " SimpleFastMCProcessor::end(): dSigma- : " << eos.lowerError( sigma ) << std::endl ;
403 // std::cout << " SimpleFastMCProcessor::end(): dSigma- : " << eos.upperError( sigma ) << std::endl ;
404 // std::cout << " SimpleFastMCProcessor::end(): entries : " << hGamHelperP1->binEntries(i) << std::endl ;
405 
406  dPhotonRes->point(i)->coordinate(0)->setValue( 1. / std::sqrt( hGamHelperP1->binMean(i) ) ) ;
407 
408  dPhotonRes->point(i)->coordinate(1)->setValue( sigma ) ;
409 
410  // use symmetric errors - needed for fitting
411  double errorMean = ( eos.upperError( sigma ) + eos.lowerError( sigma ) ) / 2 ;
412 
413  dPhotonRes->point(i)->coordinate(1)->setErrorPlus( errorMean ) ;
414  dPhotonRes->point(i)->coordinate(1)->setErrorMinus( errorMean ) ;
415  // dPhotonRes->point(i)->coordinate(1)->setErrorPlus( eos.upperError( sigma ) ) ;
416  // dPhotonRes->point(i)->coordinate(1)->setErrorMinus( eos.lowerError( sigma ) ) ;
417 
418  }
419  }
420 #endif // MARLIN_AIDA_IGNORE_FOR_NOW
421 
422  }
423 }
424 
virtual void processRunHeader(LCRunHeader *run)
Called for every run.
Small helper class that computes the lower and upper error of sigma assuming a normal distribution...
Definition: ErrorOfSigma.h:13
void registerProcessorParameter(const std::string &parameterName, const std::string &parameterDescription, T &parameter, const T &defaultVal, int setSize=0)
Register a steering variable for this processor - call in constructor of processor.
Definition: Processor.h:254
FloatVec _initNeutralHadronRes
Resolutions of photons.
void registerOutputCollection(const std::string &collectionType, const std::string &parameterName, const std::string &parameterDescription, std::string &parameter, const std::string &defaultVal, int setSize=0)
Specialization of registerProcessorParameter() for a parameter that defines an output collection - ca...
Definition: Processor.h:282
FloatVec _initChargedRes
Resolutions of charged particles.
SimpleFastMCProcessor aSimpleFastMCProcessor
virtual const std::string & name() const
Return name of this processor.
Definition: Processor.h:132
void registerInputCollection(const std::string &collectionType, const std::string &parameterName, const std::string &parameterDescription, std::string &parameter, const std::string &defaultVal, int setSize=0)
Specialization of registerProcessorParameter() for a parameter that defines an input collection - can...
Definition: Processor.h:268
T endl(T...args)
float _momentumCut
Momentum cut in GeV.
STL class.
void printParameters()
Print the parameters and their values depending on the given verbosity level.
Definition: Processor.h:156
T push_back(T...args)
virtual void init()
Initializes ...
IRecoParticleFactory * _factory
The particle factory.
std::string _inputCollectionName
Input collection name.
A simple smearing &quot;Monte Carlo&quot; processor.
std::string _recoParticleCollectionName
Ouput collection names.
T size(T...args)
bool isFirstEvent()
True if first event in processEvent(evt) - use this e.g.
Definition: Processor.h:198
FloatVec _initPhotonRes
Resolutions of photons.
virtual lcio::ReconstructedParticle * createReconstructedParticle(const lcio::MCParticle *mcp)=0
The actual factory method that creates a new ReconstructedParticle for the given MCParticle.
Base class for Marlin processors.
Definition: Processor.h:64
T sqrt(T...args)
virtual void end()
Called after data processing for clean up.
std::string _description
Describes what the processor does.
Definition: Processor.h:452
virtual void check(LCEvent *evt)
Creates some checkplots.
virtual void processEvent(LCEvent *evt)
Updates all registered conditions handlers and adds the data to the event.