All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
ChargeSpreader.cc
Go to the documentation of this file.
1 #include "ChargeSpreader.h"
2 #include "SimDigital.h"
3 
4 #include <cmath>
5 
6 #include <TFile.h>
7 #include <TTree.h>
8 
9 #include <marlin/VerbosityLevels.h>
10 #include <marlin/Exceptions.h>
11 
12 
13 using namespace marlin ;
14 
16  : chargeMap() , parameters()
17 {}
18 
20 {}
21 
22 void ChargeSpreader::addCharge(float charge, float posI, float posJ , SimDigitalGeomCellId* )
23 {
25  return ;
26 
27  float chargeTotCheck = 0 ;
28 
29  int minCellI = static_cast<int>( std::round(posI-parameters.range)/parameters.cellSize ) ;
30  int maxCellI = static_cast<int>( std::round(posI+parameters.range)/parameters.cellSize ) ;
31 
32  int minCellJ = static_cast<int>( std::round(posJ-parameters.range)/parameters.cellSize ) ;
33  int maxCellJ = static_cast<int>( std::round(posJ+parameters.range)/parameters.cellSize ) ;
34 
35  for ( int I = minCellI ; I <= maxCellI ; ++I )
36  {
37  float minI = (I-0.5f)*parameters.cellSize - posI + 0.5f*parameters.padSeparation ;
38  float maxI = (I+0.5f)*parameters.cellSize - posI - 0.5f*parameters.padSeparation ;
39 
40  for ( int J = minCellJ ; J <= maxCellJ ; ++J )
41  {
42  float minJ = (J-0.5f)*parameters.cellSize - posJ + 0.5f*parameters.padSeparation ;
43  float maxJ = (J+0.5f)*parameters.cellSize - posJ - 0.5f*parameters.padSeparation ;
44 
45  float integralResult = computeIntegral(minI , maxI , minJ , maxJ) ;
46 
47  chargeMap[I_J_Coordinates(I,J)] += charge * integralResult*normalisation ;
48 
49  if( chargeMap[I_J_Coordinates(I,J)] < 0 )
50  streamlog_out( MESSAGE ) << "!!!!!!!!!!Negative Charge!!!!!!!!!!" << std::endl
51  << " X " << posJ << " " << minJ << " " << maxJ << std::endl
52  << " Y " << posI << " " << minI << " " << maxI << std::endl ;
53 
54  chargeTotCheck += chargeMap[I_J_Coordinates(I,J)] ;
55  }
56  }
57  streamlog_out( DEBUG ) << " Charge = " << charge << " ; total splitted charge = " << chargeTotCheck << std::endl ;
58 }
59 
61  : ChargeSpreader()
62 {
63  normalisation = 1.0f ;
64 }
65 
67 {}
68 
70 {
71  assert ( parameters.erfWidth.size() == parameters.erfWeigth.size() ) ;
72 
73  float _normalisation = 0 ;
74  for ( unsigned int i = 0 ; i < parameters.erfWidth.size() ; i++ )
75  {
76  streamlog_out( DEBUG ) << "Erf function parameters " << i+1 << " : " << parameters.erfWidth[i] << ", " << parameters.erfWeigth[i] << std::endl ;
77  _normalisation += parameters.erfWeigth.at(i) * parameters.erfWidth.at(i) * parameters.erfWidth.at(i) * M_PI ;
78  }
79 
80  normalisation = 1.f/_normalisation ;
81 
82  streamlog_out( DEBUG ) << "Charge splitter normalisation factor: " << normalisation << std::endl;
83  streamlog_out( DEBUG ) << "range : " << parameters.range << " ; padseparation : " << parameters.padSeparation << std::endl;
84 }
85 
86 float GaussianSpreader::computeIntegral(float x1 , float x2 , float y1 , float y2) const
87 {
88  float integralResult = 0.0f ;
89 
90  for( unsigned int n = 0 ; n < parameters.erfWidth.size() ; n++ )
91  {
92  integralResult += fabs( std::erf(x2/parameters.erfWidth.at(n)) - std::erf(x1/parameters.erfWidth.at(n)) ) *
93  fabs( std::erf(y2/parameters.erfWidth.at(n)) - std::erf(y1/parameters.erfWidth.at(n)) ) *
94  parameters.erfWeigth.at(n)*M_PI*parameters.erfWidth.at(n)*parameters.erfWidth.at(n)/4 ;
95  }
96  return integralResult ;
97 }
98 
99 
100 
102  : ChargeSpreader()
103 {
104 }
105 
107 {}
108 
110 {
111  float _normalisation = static_cast<float>( 2*M_PI ) ;
112  normalisation = 1.0f/_normalisation ;
113 
114  streamlog_out( DEBUG ) << "Charge splitter normalisation factor: " << normalisation << std::endl ;
115  streamlog_out( DEBUG ) << "range : " << parameters.range << " ; padseparation : " << parameters.padSeparation << std::endl ;
116 }
117 
118 float ExactSpreader::computeIntegral(float x1 , float x2 , float y1 , float y2) const
119 {
120  float term1 = std::atan( y2*x2 / ( parameters.d*std::sqrt( parameters.d*parameters.d + y2*y2 + x2*x2) ) ) ;
121  float term2 = std::atan( y1*x2 / ( parameters.d*std::sqrt( parameters.d*parameters.d + y1*y1 + x2*x2) ) ) ;
122  float term3 = std::atan( y2*x1 / ( parameters.d*std::sqrt( parameters.d*parameters.d + y2*y2 + x1*x1) ) ) ;
123  float term4 = std::atan( y1*x1 / ( parameters.d*std::sqrt( parameters.d*parameters.d + y1*y1 + x1*x1) ) ) ;
124 
125  return (term1 - term2 - term3 + term4) ;
126 }
127 
128 
130  : ExactSpreader() , dMap()
131 {
132  readFile(fileName) ;
133 }
134 
136 {}
137 
138 void ExactSpreaderPerAsic::readFile(std::string fileName)
139 {
140  TFile* file = TFile::Open( fileName.c_str() , "READ") ;
141  if ( !file )
142  {
143  std::cerr << "ERROR : file " << fileName << " not found for MultiplicityChargeSplitterExactPerAsic::readFile" << std::endl ;
144  throw ;
145  }
146 
147  TTree* tree = dynamic_cast<TTree*>( file->Get("tree") ) ;
148  if ( !tree )
149  {
150  std::cerr << "ERROR : tree not present in file " << fileName << std::endl ;
151  throw ;
152  }
153 
154  int asicID ;
155  int layerID ;
156  float dAsic ;
157  std::vector<double>* position = NULL ;
158 
159  tree->SetBranchAddress("LayerID" , &layerID) ;
160  tree->SetBranchAddress("AsicID" , &asicID) ;
161  tree->SetBranchAddress("d" , &dAsic) ;
162  tree->SetBranchAddress("Position" , &position) ;
163 
164  int iEntry = 0 ;
165  while ( tree->GetEntry(iEntry++) )
166  {
167  int iAsic = static_cast<int>( (position->at(0)-10.408)/(8*10.408) ) ;
168  int jAsic = static_cast<int>( (position->at(1)-10.408)/(8*10.408) ) ;
169  int K = static_cast<int>( (position->at(2)-26.131)/26.131 + 0.5 ) ;
170 
171  if ( asicID == -1 && layerID != -1 ) //global value for layer
172  dMap.insert( std::make_pair(AsicKey(K) , dAsic) ) ;
173  else
174  dMap.insert( std::make_pair(AsicKey(K , iAsic , jAsic) , dAsic) ) ;
175  }
176  file->Close() ;
177 }
178 
179 void ExactSpreaderPerAsic::addCharge(float charge, float posI, float posJ, SimDigitalGeomCellId* cellID)
180 {
181  AsicKey asicKey(cellID->K() , (cellID->I()-1)/8 , (cellID->J()-1)/8) ;
182 
183  std::map<AsicKey, float >::iterator it = dMap.find( asicKey ) ;
184 
185  if ( it == dMap.end() )
186  {
187  it = dMap.find( AsicKey( cellID->K() ) ) ; //else search for layer mul
188  if ( it == dMap.end() )
189  parameters.d = dGlobal ;
190  else
191  parameters.d = it->second ;
192  }
193  else
194  parameters.d = it->second ;
195 
196  ExactSpreader::addCharge(charge , posI , posJ , cellID) ;
197 }
198 
virtual void addCharge(float charge, float posI, float posJ, SimDigitalGeomCellId *cellID)
virtual void addCharge(float charge, float posI, float posJ, SimDigitalGeomCellId *)
virtual ~ExactSpreader()
std::vector< float > erfWeigth
std::map< AsicKey, float > dMap
void readFile(std::string fileName)
std::map< I_J_Coordinates, float > chargeMap
virtual ~ExactSpreaderPerAsic()
virtual float computeIntegral(float x1, float x2, float y1, float y2) const =0
std::vector< float > erfWidth
virtual float computeIntegral(float x1, float x2, float y1, float y2) const
virtual void init()
virtual void init()
static const float K
std::pair< int, int > I_J_Coordinates
ChargeSpreaderParameters parameters
ExactSpreaderPerAsic(std::string fileName)
virtual ~ChargeSpreader()
virtual ~GaussianSpreader()
float computeIntegral(float x1, float x2, float y1, float y2) const