CLHEP 2.4.6.4
C++ Class Library for High Energy Physics
Loading...
Searching...
No Matches
RandBreitWigner.cc
Go to the documentation of this file.
1//
2// -*- C++ -*-
3//
4// -----------------------------------------------------------------------
5// HEP Random
6// --- RandBreitWigner ---
7// class implementation file
8// -----------------------------------------------------------------------
9// This file is part of Geant4 (simulation toolkit for HEP).
10
11// =======================================================================
12// Gabriele Cosmo - Created: 5th September 1995
13// - Added methods to shoot arrays: 28th July 1997
14// J.Marraffino - Added default arguments as attributes and
15// operator() with arguments: 16th Feb 1998
16// M Fischler - put and get to/from streams 12/10/04
17// M Fischler - put/get to/from streams uses pairs of ulongs when
18// + storing doubles avoid problems with precision
19// 4/14/05
20// =======================================================================
21
22#include "CLHEP/Random/defs.h"
23#include "CLHEP/Random/RandBreitWigner.h"
24#include "CLHEP/Units/PhysicalConstants.h"
25#include "CLHEP/Random/DoubConv.h"
26#include <algorithm> // for min() and max()
27#include <cmath>
28#include <iostream>
29#include <string>
30#include <vector>
31
32namespace CLHEP {
33
34std::string RandBreitWigner::name() const {return "RandBreitWigner";}
35HepRandomEngine & RandBreitWigner::engine() {return *localEngine;}
36
38}
39
41 return fire( defaultA, defaultB );
42}
43
44double RandBreitWigner::operator()( double a, double b ) {
45 return fire( a, b );
46}
47
48double RandBreitWigner::operator()( double a, double b, double c ) {
49 return fire( a, b, c );
50}
51
52double RandBreitWigner::shoot(double mean, double gamma)
53{
54 double rval, displ;
55
56 rval = 2.0*HepRandom::getTheEngine()->flat()-1.0;
57 displ = 0.5*gamma*std::tan(rval*CLHEP::halfpi);
58
59 return mean + displ;
60}
61
62double RandBreitWigner::shoot(double mean, double gamma, double cut)
63{
64 double val, rval, displ;
65
66 if ( gamma == 0.0 ) return mean;
67 val = std::atan(2.0*cut/gamma);
68 rval = 2.0*HepRandom::getTheEngine()->flat()-1.0;
69 displ = 0.5*gamma*std::tan(rval*val);
70
71 return mean + displ;
72}
73
74double RandBreitWigner::shootM2(double mean, double gamma )
75{
76 double val, rval, displ;
77
78 if ( gamma == 0.0 ) return mean;
79 val = std::atan(-mean/gamma);
80 rval = RandFlat::shoot(val, CLHEP::halfpi);
81 displ = gamma*std::tan(rval);
82
83 return std::sqrt(mean*mean + mean*displ);
84}
85
86double RandBreitWigner::shootM2(double mean, double gamma, double cut )
87{
88 double rval, displ;
89 double lower, upper, tmp;
90
91 if ( gamma == 0.0 ) return mean;
92 tmp = std::max(0.0,(mean-cut));
93 lower = std::atan( (tmp*tmp-mean*mean)/(mean*gamma) );
94 upper = std::atan( ((mean+cut)*(mean+cut)-mean*mean)/(mean*gamma) );
95 rval = RandFlat::shoot(lower, upper);
96 displ = gamma*std::tan(rval);
97
98 return std::sqrt(std::max(0.0, mean*mean + mean*displ));
99}
100
101void RandBreitWigner::shootArray ( const int size, double* vect )
102{
103 for( double* v = vect; v != vect + size; ++v )
104 *v = shoot( 1.0, 0.2 );
105}
106
107void RandBreitWigner::shootArray ( const int size, double* vect,
108 double a, double b )
109{
110 for( double* v = vect; v != vect + size; ++v )
111 *v = shoot( a, b );
112}
113
114void RandBreitWigner::shootArray ( const int size, double* vect,
115 double a, double b,
116 double c )
117{
118 for( double* v = vect; v != vect + size; ++v )
119 *v = shoot( a, b, c );
120}
121
122//----------------
123
125 double mean, double gamma)
126{
127 double rval, displ;
128
129 rval = 2.0*anEngine->flat()-1.0;
130 displ = 0.5*gamma*std::tan(rval*CLHEP::halfpi);
131
132 return mean + displ;
133}
134
136 double mean, double gamma, double cut )
137{
138 double val, rval, displ;
139
140 if ( gamma == 0.0 ) return mean;
141 val = std::atan(2.0*cut/gamma);
142 rval = 2.0*anEngine->flat()-1.0;
143 displ = 0.5*gamma*std::tan(rval*val);
144
145 return mean + displ;
146}
147
149 double mean, double gamma )
150{
151 double val, rval, displ;
152
153 if ( gamma == 0.0 ) return mean;
154 val = std::atan(-mean/gamma);
155 rval = RandFlat::shoot(anEngine,val, CLHEP::halfpi);
156 displ = gamma*std::tan(rval);
157
158 return std::sqrt(mean*mean + mean*displ);
159}
160
162 double mean, double gamma, double cut )
163{
164 double rval, displ;
165 double lower, upper, tmp;
166
167 if ( gamma == 0.0 ) return mean;
168 tmp = std::max(0.0,(mean-cut));
169 lower = std::atan( (tmp*tmp-mean*mean)/(mean*gamma) );
170 upper = std::atan( ((mean+cut)*(mean+cut)-mean*mean)/(mean*gamma) );
171 rval = RandFlat::shoot(anEngine, lower, upper);
172 displ = gamma*std::tan(rval);
173
174 return std::sqrt( std::max(0.0, mean*mean+mean*displ) );
175}
176
178 const int size, double* vect )
179{
180 for( double* v = vect; v != vect + size; ++v )
181 *v = shoot( anEngine, 1.0, 0.2 );
182}
183
185 const int size, double* vect,
186 double a, double b )
187{
188 for( double* v = vect; v != vect + size; ++v )
189 *v = shoot( anEngine, a, b );
190}
191
193 const int size, double* vect,
194 double a, double b, double c )
195{
196 for( double* v = vect; v != vect + size; ++v )
197 *v = shoot( anEngine, a, b, c );
198}
199
200//----------------
201
203{
204 return fire( defaultA, defaultB );
205}
206
207double RandBreitWigner::fire(double mean, double gamma)
208{
209 double rval, displ;
210
211 rval = 2.0*localEngine->flat()-1.0;
212 displ = 0.5*gamma*std::tan(rval*CLHEP::halfpi);
213
214 return mean + displ;
215}
216
217double RandBreitWigner::fire(double mean, double gamma, double cut)
218{
219 double val, rval, displ;
220
221 if ( gamma == 0.0 ) return mean;
222 val = std::atan(2.0*cut/gamma);
223 rval = 2.0*localEngine->flat()-1.0;
224 displ = 0.5*gamma*std::tan(rval*val);
225
226 return mean + displ;
227}
228
230{
231 return fireM2( defaultA, defaultB );
232}
233
234double RandBreitWigner::fireM2(double mean, double gamma )
235{
236 double val, rval, displ;
237
238 if ( gamma == 0.0 ) return mean;
239 val = std::atan(-mean/gamma);
240 rval = RandFlat::shoot(localEngine.get(),val, CLHEP::halfpi);
241 displ = gamma*std::tan(rval);
242
243 return std::sqrt(mean*mean + mean*displ);
244}
245
246double RandBreitWigner::fireM2(double mean, double gamma, double cut )
247{
248 double rval, displ;
249 double lower, upper, tmp;
250
251 if ( gamma == 0.0 ) return mean;
252 tmp = std::max(0.0,(mean-cut));
253 lower = std::atan( (tmp*tmp-mean*mean)/(mean*gamma) );
254 upper = std::atan( ((mean+cut)*(mean+cut)-mean*mean)/(mean*gamma) );
255 rval = RandFlat::shoot(localEngine.get(),lower, upper);
256 displ = gamma*std::tan(rval);
257
258 return std::sqrt(std::max(0.0, mean*mean + mean*displ));
259}
260
261void RandBreitWigner::fireArray ( const int size, double* vect)
262{
263 for( double* v = vect; v != vect + size; ++v )
264 *v = fire(defaultA, defaultB );
265}
266
267void RandBreitWigner::fireArray ( const int size, double* vect,
268 double a, double b )
269{
270 for( double* v = vect; v != vect + size; ++v )
271 *v = fire( a, b );
272}
273
274void RandBreitWigner::fireArray ( const int size, double* vect,
275 double a, double b, double c )
276{
277 for( double* v = vect; v != vect + size; ++v )
278 *v = fire( a, b, c );
279}
280
281
282std::ostream & RandBreitWigner::put ( std::ostream & os ) const {
283 long pr=os.precision(20);
284 std::vector<unsigned long> t(2);
285 os << " " << name() << "\n";
286 os << "Uvec" << "\n";
287 t = DoubConv::dto2longs(defaultA);
288 os << defaultA << " " << t[0] << " " << t[1] << "\n";
289 t = DoubConv::dto2longs(defaultB);
290 os << defaultB << " " << t[0] << " " << t[1] << "\n";
291 os.precision(pr);
292 return os;
293#ifdef REMOVED
294 long pr=os.precision(20);
295 os << " " << name() << "\n";
296 os << defaultA << " " << defaultB << "\n";
297 os.precision(pr);
298 return os;
299#endif
300}
301
302std::istream & RandBreitWigner::get ( std::istream & is ) {
303 std::string inName;
304 is >> inName;
305 if (inName != name()) {
306 is.clear(std::ios::badbit | is.rdstate());
307 std::cerr << "Mismatch when expecting to read state of a "
308 << name() << " distribution\n"
309 << "Name found was " << inName
310 << "\nistream is left in the badbit state\n";
311 return is;
312 }
313 if (possibleKeywordInput(is, "Uvec", defaultA)) {
314 std::vector<unsigned long> t(2);
315 is >> defaultA >> t[0] >> t[1]; defaultA = DoubConv::longs2double(t);
316 is >> defaultB >> t[0] >> t[1]; defaultB = DoubConv::longs2double(t);
317 return is;
318 }
319 // is >> defaultA encompassed by possibleKeywordInput
320 is >> defaultB;
321 return is;
322}
323
324
325} // namespace CLHEP
326
static double longs2double(const std::vector< unsigned long > &v)
Definition: DoubConv.cc:110
static std::vector< unsigned long > dto2longs(double d)
Definition: DoubConv.cc:94
virtual double flat()=0
static HepRandomEngine * getTheEngine()
Definition: Random.cc:270
HepRandomEngine & engine()
static double shootM2(double a=1.0, double b=0.2)
static void shootArray(const int size, double *vect)
std::istream & get(std::istream &is)
static double shoot(double a=1.0, double b=0.2)
std::ostream & put(std::ostream &os) const
std::string name() const
void fireArray(const int size, double *vect)
static double shoot()
Definition: RandFlat.cc:63
bool possibleKeywordInput(IS &is, const std::string &key, T &t)
Definition: RandomEngine.h:168