CDF II
CDF KITS
source navigation ]
diff markup ]
identifier search ]
freetext search ]
file search ]
 
Architecture: i386 ]
Version: 4.10.4 ] [ 4.10.5 ] [ 4.8.4 ] [ 4.8.4l3s ] [ 4.8.5 ] [ 4.9.0 ] [ 4.9.1 ] [ 4.9.1.hpt3 ] [ 4.9.1hpt3 ] [ 4.9.1top1 ] [ 5.0.0 ] [ 5.1.0 ] [ 5.1.0beamonly ] [ 5.1.1 ] [ 5.2.0 ] [ 5.3.0 ] [ 5.3.1 ] [ 5.3.1dsp ] [ 5.3.3 ] [ 5.3.3_nt ] [ 5.3.4 ] [ 6.1.1 ] [ 6.1.1b ] [ 6.1.2 ] [ 6.1.3 ] [ 6.1.4 ] [ 6.1.4int3 ] [ 6.1.4mc ] [ 6.1.4mc_a ] [ 6.1.6 ] [ development ]

001 //***************************************************************************
002 //*  C++ version of  Minimum Bias event generator  adopated from mbr        *
003 //*  Anwar Ahmad Bhatti            December 24, 1998                        *
004 //*
005 //*
006 //* Anwar May 5,99 Update code to conform with fnalp/development version
007 //*                1)include user scale factor for multiplicity,minimum=2
008 //*                2)add "epsilon parameter' for mass generation
009 //*                3)change energy/momentum balancing routine **3==>alpha
010 //*                4)rapidity plateaue, 0.35*log(mass) ==>0.40*log(mass)
011 //*                5)additional user switches
012 //*                 
013 //* Mary Convery Oct 20, 1999
014 //*                1)bug fixes
015 //*                2)add talk-to parameters
016 //*                3)add new methods of Double and Single Diffractive 
017 //*                  event generation (cf CDF 4947) as defaults;
018 //*                  old methods can be switched on
019 //*                 
020 //***************************************************************************
021 // Rev:    aug 29 2001 lena:   clean up - removed USE_ROOT_ and gEvent
022 //         aug 30 2001 lena:   added ct and genId; change printout;
023 //         Apr 08 2002 anwar:  fix gcc problem
024 //         Nov 05 2002 anwar:  Move add_particle_HepEvt from MinBias MinBiasModule.cc
025 #include <string>
026 #include <math.h>
027 
028 #include "Framework/APPFramework.hh"
029 //#include "evt/evt.h"
030 //#include "evt/Event.hh"
031 #include "inc/misc.hh"
032 #include "r_n/CdfRn.hh"
033 #include "CLHEP/Random/RandFlat.h"
034 #include "CLHEP/Random/RandGaussT.h"
035 #include "CLHEP/Random/RandomEngine.h"
036 #include "generatorMods/MinBiasConstants.hh"
037 #include "generatorMods/MinBiasModule.hh"
038 
039 #include "stdhep_i/CdfHepevt.hh"
040 #include "AbsEnv/AbsEnv.hh"
041 #include "SimulationObjects/HEPG_StorableBank.hh"
042 #include "Edm/Handle.hh"
043 
044 #include <sstream>
045 using std::ostream;
046 using std::cout;
047 using std::endl;
048 using std::ostringstream ;
049 
050 //void add_particle_HepEvt(int type,int firstMother,int lastMother,
051 //                                    int status,double p[4],double mass);
052 
053 const char* MinBiasModule::genId = "mbr";
054 const long MinBiasModule::_defaultRandomSeed1 = 92253591;
055 const long MinBiasModule::_defaultRandomSeed2 = 35476;
056 
057 HepRandomEngine* MinBiasModule::minBiasEngine = 0;
058 
059 //----------------
060 // Constructors --
061 //----------------
062 
063 MinBiasModule::MinBiasModule()
064   : AbsGenModule( MinBiasModule::genId,"Minimum Bias AC++ module"),
065     _process( "process", this, 1 ),
066     _pbeam( "pbeam", this, 900.0 ),
067     _scale( "mult_scale", this, 1.15 ),
068     _rprot( "rel_prot", this, 1.0 ),
069     _rneutr( "rel_neutr", this, 1.0 ),
070     _isdp( "sd_p_only", this, 0 ),
071     _isdpb( "sd_pbar_only", this, 0 ),
072     _sdvers( "sd_vers", this, 1 ),
073     _icont( "no_resonance", this, 0 ),
074     _ddvers( "dd_vers", this, 1 ),
075     _ammin( "mmin", this, sqrt(1.5) ),
076     _ammax( "mmax", this, -1. ),
077     _ximax( "ximax", this, 0.15 ),
078     _ximin( "ximin", this, -1. ),
079     _dymin( "dymin", this, 2.3 ),
080     _epsilon( "epsilon", this, 0.104 ),
081     _sigpomp( "sigpomp", this, 2.82 ),
082     _alpha( "alpha", this, 0.25 ),
083     _randomSeed1("RandomSeed1",this,MinBiasModule::_defaultRandomSeed1),
084     _randomSeed2("RandomSeed2",this,MinBiasModule::_defaultRandomSeed2)
085 {
086   _process.addDescription(
087 "  Choose a combination of Hard Core, Double-, Single-Diffractive, Elastic:\n\
088    Process type=1*HC+10*DD+100*SD+1000*EL, eg 101=HC+SD\n\
089     Do not add leading Zeros\n\
090     Default: generate hard core (inelastic, non-diffractive) events only (1)");
091   _pbeam.addDescription(
092 "  Enter the beam energy in GeV (900)");
093   _scale.addDescription(
094 "  Enter the multiplicity scale factor (1.15)");
095   _rprot.addDescription(
096 "  Enter the relative probability for the nucleon in the decay of diffracted\n\
097     masses to be a (anti)proton (1)");
098   _rneutr.addDescription(
099 "  Enter the relative probability for the nucleon in the decay of diffracted\n\
100     masses to be a (anti)neutron (1)");
101   _isdp.addDescription(
102 "  Generate single diffraction of the proton only: 0=false 1=true (0)");
103   _isdpb.addDescription(
104 "  Generate single diffraction of the antiproton only: 0=false 1=true (0)");
105   _sdvers.addDescription(
106 "  New/old version of generating single diffractive events and cross section\n\
107     New version (1999) uses renormalized gap probability, old version can\n\
108     generate resonances at low energies: 0=old 1=new (1)");
109   _icont.addDescription(
110 "  Do not include resonances in single diffraction: 0=resonances 1=no res (0)\n\
111     Used only in old SD version");
112   _ddvers.addDescription(
113 "  New/old version of generating double diffractive events and cross section\n\
114     New version (1999) uses renormalized gap probability, old version events\n\
115     always generated with t=1: 0=old 1=new (1)");
116   _ammin.addDescription(
117 "  Enter the minimum diffractive mass in GeV (sqrt(1.5))\n\
118     Used in old SD/DD version and new DD dy_max=log(s/mmin^4)");
119   _ammax.addDescription(
120 "  Enter the maximum diffractive mass in GeV (else will set to sqrt(0.15s))\n\
121     Used only in old SD version, set ximax for new");
122   _ximax.addDescription(
123 "  Enter the maximum single diffractive pomeron momentum fraction\n\
124     xi=1-x_F (0.15)\n\
125     Used only in new SD version.");
126   _ximin.addDescription(
127 "  Enter the minimum single diffractive pomeron momentum fraction\n\
128     xi=1-x_F (0.)\n\
129     Default will be set to 1.5/s.  Used only in new SD version.");
130   _dymin.addDescription(
131 "  Enter the minimum double diffractive rapidity gap width (2.3)\n\
132     Used only in new DD version.  Note dy_max=log(s/mmin^4)");
133   _epsilon.addDescription(
134 "  Enter the value of epsilon to be used in the diffractive mass \n\
135     distributions (0.104)");
136   _sigpomp.addDescription(
137 "  Enter the value of the total pomeron-proton cross section in mb (2.82)");
138   _alpha.addDescription(
139 "  Enter the value of alpha' to be used in the pomeron trajectory (0.25)");
140 
141   commands( )->append( &_process);
142   commands( )->append( &_pbeam);
143   commands( )->append( &_scale);
144   commands( )->append( &_rprot);
145   commands( )->append( &_rneutr);
146   commands( )->append( &_isdp);
147   commands( )->append( &_isdpb);
148   commands( )->append( &_sdvers);
149   commands( )->append( &_icont);
150   commands( )->append( &_ddvers);
151   commands( )->append( &_ammin);
152   commands( )->append( &_ammax);
153   commands( )->append( &_ximax);
154   commands( )->append( &_ximin);
155   commands( )->append( &_dymin);
156   commands( )->append( &_epsilon);
157   commands( )->append( &_sigpomp);
158   commands( )->append( &_alpha);
159 
160 // Initialize the relevant submenu
161   _randomNumberMenu.initialize("RandomNumberMenu",this);
162   _randomNumberMenu.initTitle("MinBiasModule random number menu");
163   commands()->append(&_randomNumberMenu);
164   
165   // Add the commands to the menu
166   _randomNumberMenu.commands()->append(&_randomSeed1);
167   _randomNumberMenu.commands()->append(&_randomSeed2);
168   
169   ostringstream tmpSstream1;
170   ostringstream tmpSstream2;
171   
172   // Describe them
173   tmpSstream1 << "      \t\t\tSeed #1 for the random number generator"
174               << "\n\t\t\t(default " << _randomSeed1.value() << ").";
175   _randomSeed1.addDescription(tmpSstream1.str());
176   tmpSstream2 << "      \t\t\tSeed #2 for the random number generator"
177               << "\n\t\t\t(default " << _randomSeed2.value() << ").";  
178   _randomSeed2.addDescription(tmpSstream2.str());
179 }
180 
181 //--------------
182 // Destructor --
183 //--------------
184 
185 MinBiasModule::~MinBiasModule() { }
186 
187 //_____________________________________________________________________________
188 int MinBiasModule::callGenerator(AbsEvent* event){
189   CdfHepevt* hepevt = CdfHepevt::Instance();
190   hepevt->clearCommon();
191   
192   mbr_generate_event();
193   return 0;
194 }
195 
196 //_____________________________________________________________________________
197 AppResult  MinBiasModule::genBeginJob(){
198 
199   CdfRn* rn = CdfRn::Instance();
200   if ( !rn->isReadingFromFile() ) {
201     rn->SetEngineSeeds(_randomSeed1.value(), 
202                        _randomSeed2.value(),MinBiasModule::genId);
203   }
204 
205   MinBiasModule::minBiasEngine = CdfRn::Instance()->GetEngine(MinBiasModule::genId);
206 
207   initEvent();
208 
209   return AppResult::OK;
210 }
211 
212 //_____________________________________________________________________________
213 AppResult  MinBiasModule::genBeginRun(AbsEvent* anEvent){
214   return AppResult::OK;
215 }
216 
217 //_____________________________________________________________________________
218 AppResult  MinBiasModule::genEndRun(AbsEvent* anEvent){
219   return AppResult::OK;
220 }
221 
222 //_____________________________________________________________________________
223 
224 AppResult  MinBiasModule::genEndJob(){
225   return AppResult::OK;
226 }
227 
228 void MinBiasModule::fillHepevt() { writeHEPGbank(); }
229        
230 void MinBiasModule::writeHEPGbank() {
231 
232   // should work?
233   AbsEvent* event = AbsEnv::instance()->theEvent();
234   CdfHepEvt hepevt;
235   HEPG_StorableBank* hepg = hepevt.makeHEPG_Bank(event);
236 
237   if (!hepg || hepg->is_invalid()) {
238     ERRLOG(ELwarning,"MinBiasModule") << "Can't create a valid HEPG_StorableBank" << endmsg;
239     return;
240   }
241   // Add the bank to the event
242   // Get the handle
243   Handle<HEPG_StorableBank> h(hepg);
244   // Append the bank to the event
245   if ((event->append(h)).is_null()) {
246    ERRLOG(ELwarning,"MinBiasModule") << "Can't add HEPG_StorableBank to the event." << endmsg;
247     return;
248   }
249   return;
250   
251 }
252 
253 //_____________________________________________________________________________
254 void  MinBiasModule::initEvent(void){
255 
256   std::cout <<  " MBR initialization routine " << std::endl;
257 
258   stable=1;
259 
260   double  rprot,rneutr,szero,fact,aa,bb,ratsum,alpha;
261   double  sig;
262 
263   nmbr                    = 0;
264   nevhc                   = 0;
265   nevddf                  = 0;
266   nevsdf                  = 0;
267   nevela                  = 0;
268   never                   = 0;
269   nevmlg                  = 0;
270   nevkng                  = 0;
271   ierkng                  = 0;
272   iermlg                  = 0;
273   mssflg                  = 0;
274   mulflg                  = 0;
275   iknflg                  = 0;
276 
277   int  HardCore           = 0;
278   int  SingleDiffractive  = 0;
279   int  DoubleDiffractive  = 0;
280   int  ElasticScattering  = 0;
281                                 // 'Process type=1*HC+10*DD+100*SD+1000*EL',
282                                 //  by default generate hard core events only
283 //fProcess=101;                 //  do not add leading Zeros 
284   //fProcess=1111;
285   fProcess=_process.value();
286   
287   if ((fProcess%10)==1)        HardCore=1;
288   if (((fProcess/10)%10)==1)   DoubleDiffractive=1;
289   if (((fProcess/100)%10)==1)  SingleDiffractive=1;
290   if (((fProcess/1000)%10)==1) ElasticScattering=1;
291 
292 
293   // Following parameters are taken from the MBRPAR file
294   //
295       
296   MAXGEN = 5000;
297 
298   pbeam  = _pbeam.value();
299   tecm   = 2.0*sqrt(pbeam*pbeam+AMP*AMP);
300   s      = tecm*tecm;
301   rprot  = _rprot.value();
302   rneutr = _rneutr.value();
303 
304   //  Add additional parameters   from MBRPAR  anwar May 5,1999
305   
306   multiplicityScaleFactor=_scale.value();
307   epsilon = _epsilon.value();
308   icont   = _icont.value();
309   isdp    = _isdp.value();
310   isdpb   = _isdpb.value();
311 
312   flatRapidityRegion=0.4;
313                            // taken from geneta. Flat  rapidity region is
314                            // flatRapidityRegion*alog(mass)
315 
316   bElastic = 7.9+0.7*log( s/(2.*AMP*AMP));
317   b0inv    = 1.0/bElastic;
318   b0       = (2.0/3.0)*bElastic;
319 
320   ammin    = _ammin.value();
321   if (_ammax.value()<0.) {
322     ammax=sqrt(.15)*tecm;
323     std::cout << "setting mmax=" << ammax << std::endl;
324     }
325   else {
326     ammax=_ammax.value();
327   }
328 
329   //  check if the parameters are consistent
330 
331   int ierc=0;
332 
333   if (pbeam<0.0) ierc=ierc+1;
334   if(ammin<sqrt(1.5)|| ammin>tecm|| ammin>ammax) {
335     ierc=ierc+1;
336   }
337   if (ammax<sqrt(1.5)||ammax>tecm) ierc=ierc+1;
338   if (rprot < 0.0)      ierc=ierc+1;
339   if (rneutr< 0.0)      ierc=ierc+1;
340   if (rprot+rneutr==0.0)        ierc=ierc+1;
341   if (isdp==1&&isdpb==1)        ierc=ierc+1;
342 
343   if (ierc!=0) {
344     std::cout << " MBR init : error in input parameters " << std::endl;
345     return;
346   }
347 
348   pnrat=rprot/(rprot+rneutr);
349 
350   ammin2=ammin*ammin;
351   ammax2=ammax*ammax;
352 
353 
354 //  compute the normalized cross sections for each kind of event.
355 //  first compute the cross sections for this combination of
356 //  input parameters and compute the not-normalized cross section
357 //  for diffractive mass generation SGDRAT
358 //
359 
360   for(int j=0;j<4;j++){ 
361     sgrat[j]=0.;
362   }
363 
364   for(int j=0;j<5;j++){
365     sgdrat[j]=0.;
366   }
367 
368   if(ammax-ammin<1.e-6) {
369     sgdrat[0]=1.0;
370     cmlim=ammin;
371   }
372   else {
373 
374     cmlim = (ammin2>1.8) ? sqrt(ammin2):sqrt(1.8);
375     
376     if(icont==1) {
377       sgdrat[0]=1.0;
378     }
379     else {
380       if(ammin2<=2.0&&ammax2<=2.5) {
381         sgdrat[1]=.09;
382       }
383       if(ammin2<=2.6&&ammax2<=3.5) {
384         sgdrat[2]=.156;
385       }
386       if(ammin2<=4.0&&ammax2<=5.0) {
387         sgdrat[3]=.086;
388       }
389 
390       if(ammin2<1.8) {
391         rclim2 = (ammax2 < 1.8) ? ammax2 : 1.8;
392         sgdrat[4]=.113*(rclim2-ammin2)/0.3;
393         // The first resonance has to be extended to this region
394         sgdrat[1]=sgdrat[1]+.0565;
395       }
396       if(ammax2>1.8) {
397         sgdrat[0]=2.*0.68*(1.+36./s)*log(ammax/cmlim);
398       }
399     }
400   }
401 
402 
403   // The s dependence of the cross-sections was changed 
404   //  to agree with a recent fit to the highest available data
405   //  see CDF NOTE # 675    June 1988
406 
407   double a= 0.68;
408   double b=36.00;
409 
410   // single diffractive cross-section
411 
412   sigsd=a*(1.+b/s)*log(0.6+0.1*s);      
413   szero=pow(50.0,2);
414 
415   fact=pow(log(sqrt(s/szero)),2);
416 
417   alpha=0.175+0.015*fact/(1.+0.2*fact);
418   double  k=1.3;
419 
420   if(sqrt(s) <= 275.0) {
421     sig=26.3+2.*sigsd;
422     aa=1./(2.*(1-alpha));
423     bb=sig+sqrt(sig*sig+4.*k*((1.-alpha)/alpha)*sigsd*sigsd);
424     sigtot=aa*bb;     // total cross-section 
425     sig0=26.3;        // hard core cross-section  
426   }
427   else {
428     sigtot=2.*sigsd*(1.+1./sqrt(2.*alpha))/(1.-2.*alpha);
429     sig0=0.5*sigtot;
430   }
431 
432   sigel=sigtot*alpha;           // Elastic cross-section
433   sigdd=k*sigsd*sigsd/sigel;    // Double diffractive cross-section
434     
435   sigres=0.332;
436   sigres=2.*sigres;
437   sigsd =2.*sigsd;              // The Single cross-section for the collision
438                                 // is twice that of a single vertex
439 
440 
441 ///////////////////////////////////////////////////////////////
442 
443   if (_ddvers.value()+_sdvers.value() > 0) {
444 
445   double sigma0=_sigpomp.value();
446   double eps=_epsilon.value();
447   double c0=sigma0*sigma0/(16.*3.14159*0.38938);
448         //(sigma0(Pom-p)/4*sqrt(pi)*hbar*c)**2
449   double alph=_alpha.value();
450   double c1, step, fmin, fmax;
451 
452   if (_ddvers.value()==1) {
453 
454     double alph2=alph*alph;
455     double lsm=log(s/pow(ammin,4));
456     double dymax=lsm;
457 
458 //// DD gap probability normalization
459     double dymin=2.3;
460     c1=c0/(2.*alph*sigma0);
461     step=(dymax-dymin)/1000000.;
462     fmax=0.;
463     if (fabs(dymin)>0.01) {
464       fmin=c1*exp(2.*eps*dymin)*(lsm-dymin)*
465            (exp(-2.*alph*dymin*exp(-dymin))
466            -exp(-2.*alph*dymin*exp(dymin)))/dymin;
467     }
468     else {
469       fmin=c1*exp(2.*eps*dymin)*lsm*(dymin*(4.*alph)+
470            dymin*dymin*(-8.*alph2)+pow(dymin,3)*(2.*alph/3.+8.*alph2*alph))
471            -c1*exp(2.*eps*dymin)*(exp(-2.*alph*dymin*exp(-dymin))
472               -exp(-2.*alph*dymin*exp(dymin)));
473     }
474     double fluxdd=step*(fmin+fmax)/2.;
475     for(int i=0;i<999999;i++){
476       double dy=dymin+(i+1)*step;
477       double f;
478       if (dy>0.01) {
479         f=step*c1*exp(2.*eps*dy)*(lsm-dy)*
480           (exp(-2.*alph*dy*exp(-dy))-exp(-2.*alph*dy*exp(dy)))/dy;
481       }
482       else {
483         f=step*c1*exp(2.*eps*dy)*lsm*(dy*(4.*alph)+
484            dy*dy*(-8.*alph2)+pow(dy,3)*(2.*alph/3.+8.*alph2*alph))
485            -step*c1*exp(2.*eps*dy)*(exp(-2.*alph*dy*exp(-dy))
486               -exp(-2.*alph*dy*exp(dy)));
487       }
488       fluxdd=fluxdd+f;
489     }
490     if (fluxdd<1.) {
491       fluxdd=1.;
492     }
493 
494     c1=c0*pow(s,eps)/(2.*alph);
495     dymin=_dymin.value();
496     if (fabs(dymin)>0.01) {
497       fmin=c1*(lsm-dymin)*exp(eps*dymin)*
498            (exp(-2.*alph*dymin*exp(-dymin))
499            -exp(-2.*alph*dymin*exp(dymin)))/dymin;
500     }
501     else {
502       fmin=c1*lsm*exp(eps*dymin)*(dymin*(4.*alph)+
503            dymin*dymin*(-8.*alph2)+pow(dymin,3)*(2.*alph/3.+8.*alph2*alph))
504            -c1*exp(eps*dymin)*(exp(-2.*alph*dymin*exp(-dymin))
505               -exp(-2.*alph*dymin*exp(dymin)));
506     }
507     fmax=c1*(lsm-dymax)*exp(eps*dymax)*
508          (exp(-2.*alph*dymax*exp(-dymax))
509          -exp(-2.*alph*dymax*exp(dymax)))/dymax;
510     step=(dymax-dymin)/1000000.;
511     sigdd=step*(fmin+fmax)/2.;
512     ddpmax=0;
513     for(int i=0;i<999999;i++){
514       double dy=dymin+(i+1)*step;
515       double f;
516       if (dy>0.01) {
517         f=(lsm-dy)*exp(eps*dy)*(exp(-2.*alph*dy*exp(-dy))
518           -exp(-2.*alph*dy*exp(dy)))/dy;
519       }
520       else {
521         f=lsm*exp(eps*dy)*(dy*(4.*alph)+
522            dy*dy*(-8.*alph2)+pow(dy,3)*(2.*alph/3.+8.*alph2*alph))
523            -exp(eps*dy)*(exp(-2.*alph*dy*exp(-dy))
524               -exp(-2.*alph*dy*exp(dy)));
525       }
526       sigdd=sigdd+step*c1*f;
527       if (f>ddpmax) {ddpmax=f;}
528     }
529     sigdd=sigdd/fluxdd;
530   }
531 
532 
533 
534   if (_sdvers.value()==1) {
535     c0=pow(6.566,2)/(16.*3.141592654);
536     double a1=0.9;
537     double a2=0.1;
538     double b1=4.6;
539     double b2=0.6;
540     double ximin=_ximin.value();
541     if (ximin<=0.) {
542       ximin=1.5/s;
543       std::cout << "setting ximin=" << ximin << std::endl;
544     }
545     double ximax=_ximax.value();
546 
547 // SD flux integral
548     double ximaxflux=0.1;
549     double xmin=eps*(-log(ximaxflux)+b1/(2.*alph));
550     double xmax=eps*(-log(ximin)+b1/(2.*alph));
551     c1=c0/(2.*alph)*exp(-eps*b1/alph);
552     fmin=c1*exp(2.*xmin)*((a1/xmin)+a2/(xmin-eps*(b1-b2)/(2.*alph)));
553     fmax=c1*exp(2.*xmax)*((a1/xmax)+a2/(xmax-eps*(b1-b2)/(2.*alph)));
554     step=(xmax-xmin)/1000000.;
555     double fluxsd=step*(fmin+fmax)/2.;
556     for(int i=0;i<999999;i++){
557       double x=xmin+(i+1)*step;
558       fluxsd=fluxsd+step*c1*exp(2.*x)*((a1/x)+a2/(x-eps*(b1-b2)/(2.*alph)));
559     }
560     if (fluxsd<1.) {
561       fluxsd=1.;
562     }
563 
564     c1=c0*sigma0/(2.*alph)*exp(-eps*b1/(2.*alph))*(pow(s,eps)/fluxsd);
565     xmin=eps*(-log(ximax)+b1/(2.*alph));
566     fmin=c1*exp(xmin)*((a1/xmin)+a2/(xmin-eps*(b1-b2)/(2.*alph)));
567     fmax=c1*exp(xmax)*((a1/xmax)+a2/(xmax-eps*(b1-b2)/(2.*alph)));
568     step=(xmax-xmin)/1000000.;
569     sigsd=step*(fmin+fmax)/2.;
570     for(int i=0;i<999999;i++){
571       double x=xmin+(i+1)*step;
572       sigsd=sigsd+step*c1*exp(x)*((a1/x)+a2/(x-eps*(b1-b2)/(2.*alph)));
573     }
574 
575     sigsd=2.*sigsd;
576   }
577 
578     sig0=sigtot-(sigsd+sigdd+sigel);
579 
580   }
581 
582 //////////////////////////////////////////////////////////////////////
583 
584 
585   // now decide which of them must be taken into account
586   
587   for (int i=0;i<4;i++){
588     sgrat[i]=0;
589   }
590    
591   if (HardCore)            sgrat[0]=sig0;
592   if (DoubleDiffractive)   sgrat[1]=sigdd;
593   if (SingleDiffractive)   sgrat[2]=sigsd;
594   if (ElasticScattering)   sgrat[3]=sigel;
595 
596 
597   // Normalize cross section for different processes
598 
599   ratsum=0;
600   for(int i=0;i<4;i++){
601     ratsum+=sgrat[i];
602   }
603   if(ratsum==0) {
604     std::cout << " MBR init: Nothing to generate " << std::endl;
605     return;
606   }
607   else {
608     for(int i=0;i<4;i++){
609       sgrat[i]/=ratsum;
610     }
611     rate[0]=sgrat[0];
612     rate[1]=rate[0]+sgrat[1];
613     rate[2]=rate[1]+sgrat[2];
614     rate[3]=rate[2]+sgrat[3];
615   }
616 
617 
618   // Normalize mass generation cross section
619 
620   ratsum=sgdrat[0]+sgdrat[1]+sgdrat[2]+sgdrat[3]+sgdrat[4];
621   for(int i=0;i<5;i++){
622     sgdrat[i]/=ratsum;
623   }
624 
625   drate[0]=sgdrat[0];
626   drate[1]=drate[0]+sgdrat[1];
627   drate[2]=drate[1]+sgdrat[2];
628   drate[3]=drate[2]+sgdrat[3];
629   drate[4]=drate[3]+sgdrat[4];
630 
631   if(HardCore==1)          std::cout << " Inelastic scattering selected " << std::endl;
632   if(SingleDiffractive==1) std::cout << " Single diffraction   selected " << std::endl;
633   if(DoubleDiffractive==1) std::cout << " Double diffraction   selected " << std::endl;
634   if(ElasticScattering==1) std::cout << " Inelastic scattering selected " << std::endl;
635 
636   print();
637   std::cout << " MBR initialization complete " << std::endl;
638   return;
639 }
640 
641 //_____________________________________________________________________________
642 void  MinBiasModule::mbr_generate_event (void){
643 
644   //**********************************************************
645   //
646   // This is the main subroutine for event generation, which is
647   // called by the standard CDF routine CDFGEN. It is obviously
648   // a small modification of MB1 GENEV routine.
649   //
650   //==========================================================
651   //
652   //   Author:     S. Belforte
653   //                                 June 1984
654     
655   mssflg=0;  mulflg=0; iknflg=0;
656 
657 
658   // Clear current event type flags
659   inelasticEvent=0;
660   singleDiffractiveEvent=0;
661   doubleDiffractiveEvent=0;
662   elasticEvent=0;
663   
664   CdfHepevt* hepevt = CdfHepevt::Instance();
665   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
666 
667   int ierr=1;
668 
669   hepevt->HepevtPtr()->NHEP=0;
670   hepevt->HepevtPtr()->NEVHEP=++nmbr;
671 
672   //std::cout << " MBR: Generate events   " << nmbr << std::endl;
673 
674   double rnd = RandFlat::shoot(engine);
675   if(rnd<=rate[0]) {
676     nevhc++;
677     //std::cout << " MBR: Generate hard core event  " << nevhc << std::endl;
678     inelasticEvent=1;
679     ierr=hard_core_event();
680   }    
681   else if(rnd<=rate[1]) {
682     nevddf++;
683     doubleDiffractiveEvent=1;
684     // std::cout << " MBR: Generate double diffractive  event " <<nevddf << std::endl;
685     ierr=double_diffractive_event();
686   }
687   else if(rnd<=rate[2]) {
688     nevsdf++;
689     singleDiffractiveEvent=1;
690     //std::cout << " MBR: Generate single diffractive  event " <<nevsdf << std::endl;
691     ierr=single_diffractive_event();
692   }
693   else { 
694     nevela++;
695     elasticEvent=1;
696     //std::cout << " MBR: Generate elastic scattering event  " <<nevela<< std::endl;
697     ierr=elastic_event();
698   }     
699 
700   if (ierr!=0) {
701     std::cout << "MBR::generate_event: sever error  stop the program " << std::endl;
702     return;
703   }
704 
705   //  test error flags for this event
706   if (mssflg==1||mulflg==1||iknflg==1) never++;
707   if (mssflg==1) nevmsg++;
708   if (mulflg==1) nevmlg++;
709   if (iknflg==1) nevkng++;
710 
711   generate_lorentz_boost(pcmlab);
712 
713   double v1[4],v2[4];
714 
715   int numberOfParticles=hepevt->HepevtPtr()->NHEP;
716 
717   for (int i=0;i<numberOfParticles;i++){
718                                         // kludge for EGCS - still need it
719     double* hp = hepevt->HepevtPtr()->PHEP[i];     
720     for (int j=0;j<4;j++) {
721       v1[j]=hp[j];
722     }
723     add_lorentz_boost(pcmlab,v1,v2);
724 
725     for (int j=0;j<4;j++) {
726       hp[j]=v2[j];
727     }
728   }
729 
730 
731   if((nmbr%100)==0) {
732     std::cout << std::setw(6) << " MBR: " <<
733                  std::setw(6) << numberOfParticles <<
734                  std::setw(35)<< " particle generated in event # "<< 
735                  std::setw(6) << nmbr   <<
736                  std::setw(6) << nevhc  <<
737                  std::setw(6) << nevsdf <<
738                  std::setw(6) << nevddf <<
739                  std::setw(6) << nevela <<  std::endl;
740   }
741   return;
742 }
743 
744 
745 //_____________________________________________________________________________
746 
747 int  MinBiasModule::hard_core_event(void){
748 
749   //**********************************************************
750   //
751   // This subroutine generates a hard core event, i.e.
752   // it treat the whole system p+pbar as a unique
753   // mass of sqrt(s)Gev at rest in the event center
754   // of mass and invoke the routine FRAGMX to decay
755   // it in exactly the same way used for diffractive
756   // events.
757   //
758   //   Author:     S. Belforte  June 1984
759   //----------------------------------------------------------
760   //  OUTPUT:
761   //         IERR :  I*4 is the error return code:
762   //                  0 = successfull calling
763   //                  1 = unable to decay the mass probable
764   //                      error in input parameters
765   //================================================================
766 
767   CdfHepevt* hepevt = CdfHepevt::Instance();
768 
769   double p[4]={0.0,0.0,0.0,tecm};
770   add_particle_HepEvt(MBCLST,0,0,3,p,tecm);
771 
772 
773   //  PXCM is the beta of the lorentz transformation from cm-x ref system 
774   //  to event cm system
775 
776   double pxcm[4]={0.0,0.0,0.0,1.0};
777 
778 
779   int icharg=0;
780   int ngenmx=hepevt->HepevtPtr()->NHEP;
781 
782   //  std::cout << " call fragment cluster " << std::endl;
783   int ierr=fragment_cluster(ngenmx,pxcm,icharg);
784 
785   //if (ierr!=0) {
786     //std::cout << " MBR::HardCore: Fatal error, error code = 1 " << std::endl; 
787   //}
788 
789   return ierr;
790 }
791 //_____________________________________________________________________________
792 
793 int  MinBiasModule::double_diffractive_event(void){
794 
795   //**********************************************************
796   //
797   // This subroutine generates a double diffractive event, i.e.
798   // it turns both the proton and the antiproton into diffractive
799   // masses AM1 and AM2 generated indipendently by GENMAS and
800   // give them  a transverse momentum by the routine GTDDIF
801   // (Gen. T Double DIFfr.).
802   // The azimuthal angle PHI for the scatter is generated at
803   // random in [0,2pi]. Then the subroutine FRAGMX is invoched
804   // to fragment the diffracted masses. If this routine results
805   // unable to fragment Mx the program tries again with a
806   // new value for AM1 AM2, till it exceeded the maximun number
807   // of trials for each event.
808   //
809   //   Author:     S. Belforte  June 1984
810   //----------------------------------------------------------
811   //  OUTPUT:
812   //
813   //         IERR :  I*4 is the error return code:
814   //                  0 = successfull calling
815   //                  1 = unable to generate a double
816   //                      diffractive event, probable
817   //                      error in input parameters
818   //   
819   //================================================================
820 
821   double   e1,e2,p2,xf,pt,px,py,pz;
822   double   phi;
823   int maxtry=10;
824   CdfHepevt* hepevt = CdfHepevt::Instance();
825   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
826 
827   // Initialization: reset error code and trial counter
828 
829   int irept=0;
830   int ngen0=hepevt->HepevtPtr()->NHEP;
831 
832   //  start of program body
833 
834   double am1,am2,t,pt2;
835 
836   int ierr=1;
837   while(ierr!=0) {
838 
839     if(irept++>maxtry) {
840       return 1;
841     }
842 
843 ////////////////////////////////////////////////////////
844     if (_ddvers.value()==1) {
845     pt2=-1.0;
846     while(pt2<=0.0) {
847 
848       double eps=_epsilon.value();
849       double alph=_alpha.value();
850       double alph2=alph*alph;
851       double m04=pow(ammin,4);
852       double s=tecm*tecm;
853       double dymax=log(s/(m04));
854       double dymin=_dymin.value();
855 
856       double P,y,dy;
857 
858       do {
859           dy=dymin+(dymax-dymin) * RandFlat::shoot(engine);
860           if (dy>0.01)
861             P=(log(s/m04)-dy)*exp(eps*dy)*(exp(-2.*alph*dy*exp(-dy))
862               -exp(-2.*alph*dy*exp(dy)))/dy;
863           else
864             P=log(s/m04)*exp(eps*dy)*(dy*(4.*alph)+
865                dy*dy*(-8.*alph2)+pow(dy,3)*(2.*alph/3.+8.*alph2*alph))
866                -exp(eps*dy)*(exp(-2.*alph*dy*exp(-dy))
867               -exp(-2.*alph*dy*exp(dy)));
868           if (P>ddpmax) std::cout << "WARNING double_diffractive_event: ddpmax="
869             << ddpmax << " " << P << " " << dy;
870           y=ddpmax * RandFlat::shoot(engine);
871          }
872       while (y>P);
873 
874       double y0max=(log(s/m04)-dy)/2.;
875       double y0min=-y0max;
876       double y0=y0min+(y0max-y0min) * RandFlat::shoot(engine);
877 
878       am1=sqrt(tecm*exp(-y0-dy/2.));
879       am2=sqrt(tecm*exp(y0-dy/2.));
880 
881       double b=2.*alph*dy;
882       do {t=(1./b)*log( RandFlat::shoot(engine));}
883       while (-t>exp(dy));
884 
885       e1=.5*(tecm+(am1*am1-am2*am2)/tecm);
886       e2=tecm-e1;
887       p2=e1*e1-am1*am1;
888       xf=1.-(am1*am1-AMP*AMP)/s;
889 
890       pt2=xf*fabs(t)-pow((AMP*(1.-xf)),2);
891 
892     }
893     }
894     else {
895       am1=generate_diffractive_mass();
896       am2=generate_diffractive_mass();
897       // std::cout << "Double diffraction " << am1 << "  " << am2 << std::endl;
898       e1=.5*(tecm+(am1*am1-am2*am2)/tecm);
899       e2=tecm-e1;
900       p2=e1*e1-am1*am1;
901       xf=1.-(am1*am1-AMP*AMP)/s;
902       pt2=-1.0;
903       while(pt2<=0.0) {
904         t=generate_double_diffractive_t();    // always t=1.0; Loop for future upgrade anwar
905         pt2=xf*fabs(t)-pow((AMP*(1.-xf)),2);  //
906       }
907       }
908 
909 //////////////////////////////////////////////////////////////
910 
911     pt=sqrt(pt2);
912     pz=sqrt(p2-pt2);
913 
914     phi=RandFlat::shoot(engine)*twopi;
915     px=pt*cos(phi);
916     py=pt*sin(phi);
917 
918     // proton diffraction (recoil #1) and antiproton diffraction (recoil #2)
919 
920     double p1[4]={ px, py, pz,sqrt(px*px+py*py+pz*pz+am1*am1)};
921     double p2[4]={-px,-py,-pz,sqrt(px*px+py*py+pz*pz+am2*am2)}; //px->pz
922   
923     hepevt->HepevtPtr()->NHEP=ngen0;
924     add_particle_HepEvt(MBCLST,0,0,3,p1,am1);
925     int cluster1=hepevt->HepevtPtr()->NHEP;
926 
927     add_particle_HepEvt(MBCLST,0,0,3,p2,am2);
928     int cluster2=hepevt->HepevtPtr()->NHEP;
929 
930     //  P1CM and P2CM are the betas of the lorentz transformations from
931     //  cm-x ref. system to event cm system
932 
933     double p1cm[4]= {-px/e1,-py/e1,-pz/e1,e1/am1};
934     double p2cm[4]= {+px/e2,+py/e2,+pz/e2,e2/am2};
935 
936     // std::cout <<  "diffracted systems decay " << t << " "<< pt2 << " " <<pz << std::endl;
937 
938     ierr=fragment_cluster(cluster1,p1cm,1);
939     if(ierr==0) {
940       ierr=fragment_cluster(cluster2,p2cm,-1);
941     }
942   }
943   //  if(irept>1) {
944   //    std::cout <<" MBR: generate_double_diffraction tries "<<irept<<" tries."<< std::endl;
945   //  }
946   return 0;
947 }
948 
949 //_____________________________________________________________________________
950 
951 int MinBiasModule::single_diffractive_event(void){
952 
953   //**********************************************************
954   //
955   // This subroutine generates a single diffractive event, i.e.
956   // it decide at random (50% prob. each) to scatter quasi
957   // elastically the proton or the antiproton, than turns the
958   // other colliding particle into a diffracted mass MX (generated
959   // by the subroutine GENMAS) and assign it a transverse
960   // momentum by the routine GPTSDF (Gen. PT Single DiFfr.).
961   // The azimuthal angle PHI for the scatter is generated at
962   // random in [0,2pi]. Then the subroutine FRAGMX is invoched
963   // to fragment the diffracted mass. If this routine results
964   // unable to fragment Mx the program tries again with a
965   // new value for Mx, till it exceeded the maximun number
966   // of trials for each event.
967   //==========================================================
968   //
969   //   Author:     S. Belforte
970   //                                 June 1984
971   //  OUTPUT:
972   //
973   //         IERR :  I*4 is the error return code:
974   //                  0 = successfull calling
975   //                  1 = unable to generate a single
976   //                      diffractive event, probable
977   //                      error in input parameters
978   //   
979 
980   CdfHepevt* hepevt = CdfHepevt::Instance();
981   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
982 
983   int maxrpt=10;
984 
985   int ngen0=hepevt->HepevtPtr()->NHEP;
986 
987   int irept=0;
988   int ierr=1;
989 
990   while(ierr!=0) {
991     irept++;
992     if(irept>=2) {
993       mssflg=1;
994       iermsg++;
995     }
996 
997     if (irept>=maxrpt) {
998       std::cout << " MBR SnglDiff " << irept << std::endl;
999       return 1;       
1000     }
1001 
1002     //  choose proton or antiproton to scatter quasi-elastically
1003     //  ICHARG stores  the charge of Mx.
1004 
1005 
1006     int iquas,icharg,psrec;
1007     if(RandFlat::shoot(engine)>=0.5) {
1008        //  --- proton is scattered quasi-elastically
1009       iquas=1;
1010       icharg=-1;
1011       psrec=PSPRO;
1012     }
1013     else {
1014        //  --- anti-proton is scattered quasi-elastically
1015       iquas=2;
1016       icharg=1;
1017       psrec=PSPROB;
1018     }
1019 
1020     //
1021     // see if user overwrote this decision by forcing diffraction of the
1022     // proton (antiproton) only, and thus scatter for the antiproton (proton)
1023     //
1024     if(isdp==1) {
1025       iquas=2;
1026       icharg=1;
1027       psrec=PSPROB;
1028     }
1029     else {
1030       if(isdpb==1){
1031         iquas=1;
1032         icharg=-1;
1033         psrec=PSPRO;
1034       }
1035     }
1036 
1037     //   mass of diffracted system is generated according to the general
1038     //   distribution  1/M**2 in the interval 2.0 GeV - TECM and stored
1039     //   in EVSP common as information for the simulator
1040 
1041 //////////////////////////////////////////////////
1042 
1043     double amx, t, xf, ptsqr;
1044 
1045     if (_sdvers.value()==1) {
1046 
1047       double eps, alph, ximin, ximax, s;
1048 
1049       eps=_epsilon.value();
1050       alph=_alpha.value();
1051       s=tecm*tecm;
1052       ximin=_ximin.value();
1053       if (ximin<=0.) {
1054         ximin=1.5/s;
1055       }
1056       ximax=_ximax.value();
1057 
1058       double xi,P,y;
1059 
1060       ptsqr=-1.0;
1061       do {
1062         do {
1063           xi=ximin*exp((log(ximax)-log(ximin))*RandFlat::shoot(engine));
1064           P=pow(xi,-1.-eps)*(0.9/(4.6+2.*alph*log(1./xi))+
1065                              0.1/(0.6+2.*alph*log(1./xi)));
1066           y=(1./xi)*RandFlat::shoot(engine);
1067         }
1068         while (y>P);
1069 
1070         amx=sqrt(xi*s);
1071 
1072         double tmin=-AMP*AMP*xi*xi/(1-xi);
1073         do {
1074           t=tmin+log(1.- RandFlat::shoot(engine));
1075           P=pow((4.*AMP*AMP-2.8*t)/((4.*AMP*AMP-t)*pow(1.-t/0.71,2)),2)
1076             *exp(-2.*alph*log(xi)*t);
1077           y=exp(t)*RandFlat::shoot(engine);
1078         }
1079         while (y>P);
1080         xf=1.-(amx*amx-AMP*AMP)/s;
1081         ptsqr=xf*fabs(t)-pow((AMP*(1.-xf)),2);
1082       } while (ptsqr<=0.0);
1083     }
1084 
1085     else {
1086       amx=generate_diffractive_mass();
1087 
1088       t=0.0;
1089       //  generate the transferred squared momentum t
1090       // for the diffracted mass
1091       ptsqr=-1.0;
1092       do {
1093         t=generate_single_diffractive_t(amx);
1094         xf=1.-(amx*amx-AMP*AMP)/s;
1095         ptsqr=xf*fabs(t)-pow((AMP*(1.-xf)),2);
1096       } while (ptsqr<=0.0);
1097     }
1098 
1099 //////////////////////////////////////////////////////////////
1100 
1101     double erec=.5*(tecm-(amx*amx-AMP*AMP)/tecm);
1102     double psqr=erec*erec-AMP*AMP;
1103     double ex=tecm-erec;
1104     double pt=sqrt(ptsqr);
1105     double pz=sqrt(psqr-ptsqr);
1106 
1107     // PZ is positive in the direction on the proton beam (standard CDF reference system)
1108     if (iquas==2){
1109       pz=-pz;
1110     }
1111 
1112     double phi=RandFlat::shoot(engine)*twopi;
1113     double px=pt*cos(phi);
1114     double py=pt*sin(phi);
1115 
1116 
1117     //    std::cout << " MBR : SingleDiff : MX ="  << amx << " t=" << t << std::endl;
1118      
1119     //  quasi elastically scattered particle (recoil)
1120 
1121     double mass=pamass(psrec);
1122     double p1[4]={+px,+py,+pz,sqrt(px*px+py*py+pz*pz+mass*mass)};
1123     double p2[4]={-px,-py,-pz,sqrt(px*px+py*py+pz*pz+amx*amx)};
1124 
1125     hepevt->HepevtPtr()->NHEP=ngen0;
1126                                         // status code for the stable 
1127                                         // particle is 1
1128 
1129     //    add_particle_HepEvt(psrec,0,0,100+iquas,p1,pamass(psrec));
1130 
1131     add_particle_HepEvt(psrec,0,0,1,p1,pamass(psrec));
1132     add_particle_HepEvt(MBCLST,0,0,3,p2,amx);
1133 
1134     int ngenmx=hepevt->HepevtPtr()->NHEP;
1135 
1136     //PXCM is the beta of the lorentz transformation from cm-x ref.system to event cm system
1137 
1138     double pxcm[4]={px/ex,py/ex,pz/ex,ex/amx};
1139     ierr=fragment_cluster(ngenmx,pxcm,icharg);
1140   }
1141   return ierr;
1142 }
1143 
1144 //_____________________________________________________________________________
1145 
1146 int  MinBiasModule::elastic_event(void){
1147 
1148   //**********************************************************
1149   //
1150   // This subroutine generates a p-pbar pair according
1151   // to elastic angular distribution: DS/DT=EXP(-BT),
1152   // from which the theta angle is derived. Phi is uniform
1153   // in 0-2pi. The value for B comes from a formula from
1154   // K.Goulianos: Belastic = 7.9 + 0.7 *  ln( S/(2*Mp**2) ),
1155   // S being (center of mass energy)**2 and Mp the proton mass.
1156   //
1157   //   Author:     S. Belforte
1158   //                                 November 15, 1985
1159   //  OUTPUT:
1160   //
1161   //         IERR :  I*4 is the error return code:
1162   //                  0 = successfull calling
1163   //  
1164 
1165 
1166   CdfHepevt* hepevt = CdfHepevt::Instance();
1167   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
1168 
1169   // generate t according to the exponential law in the interval 0-infinity
1170 
1171    double arg=0.0;
1172    do {
1173      arg=1.0-RandFlat::shoot(engine);
1174    } while(arg==0.0);
1175 
1176    double t=fabs(b0inv*log(arg));
1177 
1178    double costh=1.0-t/(2*pbeam*pbeam);
1179    double sinth=sqrt(t/(pbeam*pbeam)-1.0/4.0*pow((t/(pbeam*pbeam)),2));
1180    double phi=RandFlat::shoot(engine)*TWOPI;
1181 
1182    double pz=pbeam*costh;
1183    double px=pbeam*sinth*cos(phi);
1184    double py=pbeam*sinth*sin(phi);
1185 
1186    double mass=pamass(PSPRO);
1187    double p1[4]={px,py,pz,sqrt(px*px+py*py+pz*pz+mass*mass)};
1188 
1189    mass=pamass(PSPROB);
1190    double p2[4]={-px,-py,-pz,sqrt(px*px+py*py+pz*pz+mass*mass)};
1191 
1192                                 // declare proton and antiproton as final
1193                                 // particles (status code = 1)
1194 
1195    add_particle_HepEvt(PSPRO ,0,0,1,p1,pamass(PSPRO));
1196    add_particle_HepEvt(PSPROB,0,0,1,p2,pamass(PSPROB));
1197 
1198    return 0;
1199 }
1200 
1201 //_____________________________________________________________________________
1202 
1203 void  MinBiasModule::generate_lorentz_boost(double pcmlab[4]){
1204   //**********************************************************
1205   //
1206   //  PCMLAB[4] : R*4 is the (beta,gamma) vector for the boost
1207 
1208    pcmlab[0]=0.0;
1209    pcmlab[1]=0.0;
1210    pcmlab[2]=0.0;
1211    pcmlab[3]=1.0;
1212 
1213 }
1214 
1215 //_____________________________________________________________________________
1216 
1217 double  MinBiasModule::generate_diffractive_mass(void){
1218 
1219   //**********************************************************
1220   //
1221   // This routine generates a diffracted mass AMX according
1222   // to a continuum distribution 1./m**2 in the input mass**2
1223   // interval plus the eventual resonance contribution. To avoid
1224   // unnecessary complications the mass distribution will not be
1225   // the naive expected one when the input mass interval
1226   // [ammin,ammax] is a narrow one in the resonance region,
1227   // anyway the mass will always fall inside that interval.
1228   //
1229   //==========================================================
1230   //
1231   //   Author:     S. Belforte
1232   //                                September 1984
1233   //
1234   //================================================================
1235 
1236  
1237   double amx=0.0; 
1238   double amx2=0.0;
1239   int MXREP=20;
1240   int irep=0;
1241 
1242   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
1243 
1244   double rnd=RandFlat::shoot(engine);
1245 
1246   if(rnd<drate[0]) {
1247     //  continuum spectrum
1248     double rnd=RandFlat::shoot(engine);
1249     if(epsilon==0) {
1250       amx=cmlim*pow((ammax/cmlim),rnd);
1251     }
1252     else {
1253       amx=cmlim*ammax/pow(((1.-rnd)*pow(ammax,(2.*epsilon))+
1254           rnd*pow(cmlim,(2.*epsilon)) ),(1./(2.*epsilon)));
1255 
1256     }
1257   }
1258   else if(rnd < drate[1]) {
1259     while (amx2<1.5||amx2>2.5||amx2<ammin2||amx2>ammax2) {
1260       amx2=RandGaussT::shoot(engine,2.2,.3);
1261       if(irep++>MXREP) return 2.2;
1262     }
1263     amx=sqrt(amx2);
1264   }
1265   else if(rnd < drate[2]) {
1266     while (amx2<2.5||amx2>4||amx2<ammin2||amx2>ammax2) {
1267       amx2=RandGaussT::shoot(engine,2.8,.3);
1268       if(irep++>MXREP) return 2.8;
1269     }
1270     amx=sqrt(amx2);
1271   }
1272   else if(rnd < drate[3]) {
1273     while (amx2<3||amx2<ammin2||amx2>ammax2) {
1274       amx2=RandGaussT::shoot(engine,4.4,.8);
1275       if(irep++>MXREP) return 4.4;
1276     }
1277     amx=sqrt(amx2);
1278   }
1279   else if(rnd<drate[4]) {
1280     //  initial rectangle
1281     amx2=ammin2+(rclim2-ammin2)*RandFlat::shoot(engine);
1282     amx=sqrt(amx2);
1283   }
1284   return amx;
1285 }
1286 
1287 //_____________________________________________________________________________
1288 
1289 void  MinBiasModule::add_lorentz_boost(double beta[4], double v1[4], double v2[4]){ 
1290   //**************************************************
1291   //*
1292   //**************************************************
1293 
1294   double bp=0;
1295   for(int i=0;i<3;i++) {
1296     bp=bp+beta[i]*v1[i];
1297   }
1298 
1299   double bpp=(bp*beta[3]/(beta[3]+1.)-v1[3])*beta[3];   
1300 
1301   v2[0]=v1[0]+beta[0]*bpp;   
1302   v2[1]=v1[1]+beta[1]*bpp;  
1303   v2[2]=v1[2]+beta[2]*bpp;   
1304   v2[3]=beta[3]*(v1[3]-bp);  
1305 
1306 }
1307 
1308 //_____________________________________________________________________________
1309 
1310 double  MinBiasModule::generate_single_diffractive_t(double amx){
1311 
1312   //**********************************************************
1313   //
1314   // This subroutine generates the t for a single diffractive
1315   // event. The distribution used is a phenomelogical one
1316   // intended to reproduce experimental exixting data.
1317   //
1318   //   Author:     S. Belforte
1319   //===========================================================
1320   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
1321   double amo=0.0;
1322   double tmax=1.0;
1323   
1324   double rad2=sqrt(2.0);
1325   
1326   double t=0.0;
1327   double b,binv,facnor;
1328   if(amx!=amo) {
1329     b=b0*(1.+.04/(pow((amx-rad2),2)+.02));
1330     facnor=1.0-exp(-b*tmax);
1331     binv=1./b;
1332     amo=amx;
1333   }
1334   double rn=RandFlat::shoot(engine);
1335   t=binv*log(1.0-rn*facnor);
1336   return t;
1337 }
1338 
1339 //_____________________________________________________________________________
1340 
1341 double  MinBiasModule::generate_double_diffractive_t(void){
1342   return 1.0;
1343 }
1344 
1345 //_____________________________________________________________________________
1346 
1347 int  MinBiasModule::average_multiplicity(double amx){
1348 
1349   //**********************************************************
1350   //
1351   // This subroutines generates the total multiplicity for
1352   // the fragmentation of the current diffractive mass, whose
1353   // value is fetched form the common variable AMX. The resulting
1354   // multiplicity is stored in the other common variable NT.
1355   // The mass actually used for multiplicity generation
1356   // is the current decaying mass AMX minus the proton mass.
1357   //   Author:     S. Belforte  July 1984
1358   //  Modified:    J. Grunhaus  June 1988
1359   //               T. Chapin    July 1989
1360   // average total multiplicity is computed from available mass AMX
1361   // avntot is the calculated average  multiplicity
1362 
1363   int multi;
1364   double  am,am2,avntot,avnstar,wmuu;
1365   int nmax;
1366 
1367   double amxold=0.0;
1368 
1369   if(amx!=amxold) {
1370     if(amx<1.1) {
1371       //' AVMUL: fragmenting mass is too low 
1372       //         it is impossible to generate even',
1373       //         ' 2 particles',/,'  Program STOPs')
1374       //stop
1375       multi=0;
1376       return multi;
1377     }
1378     else {
1379       am=amx-AMP;
1380       am2=am*am;
1381       double tmp=pow(log(am2),2);
1382       avntot=3.0/2.0*(2.0+0.13*log(am2)+.175*tmp);
1383 
1384       avntot=avntot*multiplicityScaleFactor;
1385                                   // Scale it if user desires May 5,1999
1386       if (am<=1.) avntot=2.0;
1387       avnstar=2./3.*avntot;
1388 
1389       double aa8=-0.104;
1390       double bb8=0.058;
1391       double cc8=6.0;
1392       wmuu=1.0/(aa8+bb8*log(am+cc8));
1393 
1394       nmax=1000;
1395       if (amx<2.0){ nmax=4;}
1396       if (amx<1.5){ nmax=3;}
1397       if (amx<1.3){ nmax=2;}
1398       amxold=amx;
1399     }
1400   }
1401 
1402   //     The total multiplicity is gotten from the subroutine dino
1403   //     and it is stored in the variable nt. (June 1988, J. GRUNHAUS)
1404   //  --- total multiplicity must of course be larger then 2 !
1405 
1406 
1407   do {  
1408     multi=total_multiplicity_by_dino(wmuu,avnstar);
1409   } while (multi <=1 || multi>nmax);
1410   return multi;
1411 }
1412 
1413 //_____________________________________________________________________________
1414 
1415 int MinBiasModule::two_body_decay(int ngenmx,int ip1,int ip2){
1416 
1417   //**********************************************************
1418   //
1419   // This subroutine fragment a particle into 2 bodies
1420   // with exact phase space and angular distribution
1421   // of the first one proportional to cos**2(theta)
1422   //
1423   //   Author:     S. Belforte    June 1984
1424   //----------------------------------------------------------
1425 
1426   //  INPUT:
1427   //
1428   //         NGENM : I*4 is the particle number of the system in the
1429   //                     /MbrEvt/ common
1430   //         IP1   : I*4 is the particle identifier of the first
1431   //                     product (the one to be distributed as cos**2)
1432   //         IP2   : I*4 is the particle identifier of the second body
1433   //
1434   //  OUTPUT:
1435   //
1436   //         IERR :  I*4 is the error return code:
1437   //                  0 = successfull calling
1438   //                  1 = particle mass was too low
1439   //   
1440   //================================================================
1441 
1442   CdfHepevt* hepevt = CdfHepevt::Instance();    
1443   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
1444 
1445   // Get particle masses and test parent against product masses
1446 
1447                                         // kludge for EGCS/SGI
1448   double* hp = hepevt->HepevtPtr()->PHEP[ngenmx-1];
1449   double  am0=hp[4];
1450   double  am1=pamass(ip1);
1451   double  am2=pamass(ip2);
1452 
1453   if (am0<=(am1+am2)) {
1454     //    print 1000,am1+am2,am0
1455     //(' FRA2B: attempt to fragment into a total mass of Gev a mass of only Gev')
1456     return 1;
1457   }
1458 
1459   //  compute energy and momentum for outgoing particles
1460 
1461   double e1=.5*(am0*am0+am1*am1-am2*am2)/am0;
1462   double p=sqrt(e1*e1-am1*am1);
1463 
1464   double theta = generate_random_o2();
1465   double phi=twopi*RandFlat::shoot(engine);
1466 
1467   double px=p*sin(theta)*cos(phi);
1468   double py=p*sin(theta)*sin(phi);
1469   double pz=p*cos(theta);
1470 
1471   
1472   double p1[4]={px,py,pz,sqrt(px*px+py*py+pz*pz+am1*am1)};
1473   double p2[4]={-px,-py,-pz,sqrt(px*px+py*py+pz*pz+am2*am2)};
1474 
1475   //For the decaying particle this must have been already done by caller routine (FRAGMX)
1476   // old status=103
1477   // set isthep=1 for final stateparticles
1478   
1479   add_particle_HepEvt(ip1,ngenmx,0,stable,p1,am1);
1480   add_particle_HepEvt(ip2,ngenmx,0,stable,p2,am2);
1481 
1482   return 0;
1483 }
1484 
1485 //_____________________________________________________________________________
1486 
1487 int MinBiasModule::three_body_decay(int ngenmx,int ip1,int ip2, int ip3){
1488   //********************************************************** 
1489   //
1490   // This subroutine fragment a particle into 3 bodies
1491   // with exact phase space and angular distribution
1492   // of the first body proportional to cos**2(theta)
1493   //
1494   //  This routine is a modification of routine DALITZ from
1495   //  MB1 generator of Y. Takaiwa, from where the algorithm
1496   //  for energy and momentum ripartition among the three
1497   //  outgoing particles is taken. Any question about this 
1498   //  part of the code must be addressed to Y.T.
1499   //   Author:     S. Belforte  June 1984
1500 
1501   //
1502   //  INPUT:
1503   //
1504   //         NGENM : I*4 is the particle number of the system in the 
1505   //                     /MbrEvt/ common
1506   //      IP1   : I*4 is the particl eidentifier of the first
1507   //                     decay product (the one to be distributed
1508   //                  according to cos**2(theta))
1509   //      IP2   : I*4 particle identifier for the second body
1510   //         IP3   : I*4 same as above for the third one
1511   //
1512   //  OUTPUT:
1513   //
1514   //         IERR :  I*4 is the error return code:
1515   //                  0 = successfull calling
1516   //                  1 = particle mass was too low
1517   //   
1518   //================================================================
1519 
1520   CdfHepevt* hepevt = CdfHepevt::Instance();
1521   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
1522 
1523   int ierr=0;
1524 
1525   // Get particle masses and test total producted mass against initial decaying one
1526 
1527                                         // kludge for EGCS/SGI
1528   double* hp = hepevt->HepevtPtr()->PHEP[ngenmx-1];
1529   double am0=hp[4];
1530   double am1=pamass(ip1);
1531   double am2=pamass(ip2);
1532   double am3=pamass(ip3);
1533 
1534   if (am0<=(am1+am2+am3)) {
1535     //print 1000,am1+am2+am3,am0
1536     //' FRA3B: attempt to fragment into a total mass of Gev a mass of only)
1537     ierr=1;
1538     return ierr;
1539   }
1540 
1541   //  Generate energy and momentum for outgoing particles 1 and 2
1542   //  for which they can be chosen indipendentely
1543 
1544   double dmx1=0.5*(pow(am0,2)-pow((am2+am3),2)+pow(am1,2))/am0-am1;
1545   double dmx2=0.5*(pow(am0,2)-pow((am1+am3),2)+pow(am2,2))/am0-am2;
1546 
1547   double pm1,pm2;
1548   double cost2=-2.0;
1549 
1550   while (cost2<-1.||cost2>1.) {
1551     double e1=RandFlat::shoot(engine)*dmx1+am1;
1552     double e2=RandFlat::shoot(engine)*dmx2+am2;
1553     pm1=sqrt(e1*e1-am1*am1);
1554     pm2=sqrt(e2*e2-am2*am2);
1555 
1556     cost2=(am0*am0+am1*am1+am2*am2-am3*am3-2.*(e1*am0+e2*am0-e1*e2))/(2.*pm1*pm2);
1557   }
1558 
1559   double sint2=sqrt(1.-cost2*cost2);
1560 
1561   //  generate THETA,PHI,PSI for the nucleon
1562 
1563   double theta =generate_random_o2();
1564   double phi=twopi*RandFlat::shoot(engine);
1565   double psi=twopi*RandFlat::shoot(engine);
1566 
1567   //  fix the kinematics
1568 
1569   double p1[4],p2[4],p3[4];
1570 
1571   p1[0]=pm1*sin(theta)*cos(phi);
1572   p1[1]=pm1*sin(theta)*sin(phi);
1573   p1[2]=pm1*cos(theta);
1574   p1[3]=sqrt(p1[0]*p1[0]+p1[1]*p1[1]+p1[2]*p1[2]+am1*am1);
1575 
1576   p2[0]=pm2*sint2;
1577   p2[1]=0.0;
1578   p2[2]=pm2*cost2;
1579   rotate_three_vector(phi,theta,psi,p2[0],p2[1],p2[2]);
1580   p2[3]=sqrt(p2[0]*p2[0]+p2[1]*p2[1]+p2[2]*p2[2]+am2*am2);
1581   
1582   for(int i=0;i<3;i++){
1583     p3[i]=-p1[i]-p2[i];
1584   }
1585   p3[3]=sqrt(p3[0]*p3[0]+p3[1]*p3[1]+p3[2]*p3[2]+am3*am3);
1586 
1587 
1588   add_particle_HepEvt(ip1,ngenmx,0,stable,p1,am1);
1589   int current=hepevt->HepevtPtr()->NHEP;
1590 
1591   int* hd = hepevt->HepevtPtr()->JDAHEP[ngenmx-1];
1592   hd[0]   = current;
1593 
1594   add_particle_HepEvt(ip2,ngenmx,0,stable,p2,am2);
1595   add_particle_HepEvt(ip3,ngenmx,0,stable,p3,am3);
1596   current = hepevt->HepevtPtr()->NHEP;
1597   hd[1]   = current;
1598 
1599   ierr=0;
1600   return ierr;
1601 }
1602 
1603 
1604 //_____________________________________________________________________________
1605 
1606 void  MinBiasModule::generate_one_particle_from_fire_ball(int ngenpa, int itype,int nt){
1607 
1608   //**********************************************************
1609   //
1610   // This subroutine generates from an hadronic fire-ball
1611   // one particle ( specie ITYPE in the standard CDF code).
1612   // The parent fire-ball number must be NGENPA in common
1613   // /GENP/. The subroutine also updates that common with
1614   // the new particle information.
1615   // The particle rapidity and transverse momentum are generated
1616   // in a totally uncorrelated way by means of the routines
1617   // GENETA and GENPT.
1618   //
1619   //   Author:     S. Belforte    June 1984
1620   //   Modified:   J. Grunhaus    June 1988
1621   //----------------------------------------------------------
1622   // INPUT:   NGENPA: I*4 is the parent particle number in the /GENP/ common
1623   //          ITYPE : I*4 is the type code of the particle to  be generated
1624   //-------------------------------------------------------
1625 
1626   CdfHepevt* hepevt = CdfHepevt::Instance();
1627   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
1628 
1629   double* hp  = hepevt->HepevtPtr()->PHEP[ngenpa-1];
1630   double  amx = hp[4];
1631 
1632   double y=generate_rapidiy(amx);
1633   double pt=generate_pt(amx,nt);
1634   double phi=twopi*RandFlat::shoot(engine);
1635   double mass=pamass(itype);
1636 
1637   //  compute kinematical variables using rapidity,pt and mass
1638 
1639   double px=pt*cos(phi);
1640   double py=pt*sin(phi);
1641 
1642   double pz;
1643 
1644   if(y==0.0){
1645     pz = 0.0;
1646   }
1647   else {
1648     double top=pt*pt+mass*mass;
1649     double bota=(1.+exp(2.*y))/(exp(2.*y)-1.);
1650     bota=bota*bota;
1651     double pzsq=(top/(bota-1.));
1652     pz=sqrt(pzsq)*y/fabs(y);
1653   }
1654 
1655 
1656   double p[4]={px,py,pz,sqrt(px*px+py*py+pz*pz+mass*mass)};
1657 
1658   add_particle_HepEvt(itype,ngenpa,0,stable,p,pamass(itype));
1659        
1660 }
1661 
1662 //_____________________________________________________________________________
1663 
1664 int  MinBiasModule::balance_energy_momentum(double amx,int ngen0){
1665   //*********************************************************
1666   //
1667   // This subroutine balances momentum and energy for particles
1668   // generated by FRAGMX for the current diffractive mass AMX.
1669   // Momentum balance is achieved via
1670   // a scale transformation which is exact in principle and whose
1671   // accuracy is therefore only limited by the computer precision
1672   // in calculations. Energy conservation is implemented via a 
1673   //recursive algorithm which will give a .1% precison or an
1674   // error condition (ierr=2) asking to try with new initial
1675   // choises for momenta. The energy balance algorithm will
1676   // leave unchanged the previous balanced sum of Pz, again in
1677   // the limits of computer arithmetics. This is why we can
1678   // expect at the end SUM(Px) and SUM(Py) to be <1.E-5 but
1679   // SUM(Pz) only <1.E-3 GeV.
1680 
1681   //===============================================================
1682   //
1683   //  IMPORTANT NOTE : This subroutine will work only if all
1684   //  generated particles are outgoing ones. i.e. no decay in
1685   //  the generator is allowed. Otherway the energy conservation
1686   //  algorithm has to be modified.
1687   //
1688   //===============================================================
1689   //   Author:     S. Belforte   August 1984
1690   //================================================================
1691   //
1692   //   Argument description:
1693   //
1694   //  INPUT:
1695   //
1696   //  NGEN0 : I*4 is the starting point in the GENP common
1697   //                  for the list of generated particle to be
1698   //                  balanced in energy
1699   //
1700   //  OUTPUT:
1701   //
1702   //         IERR :  I*4 is the error return code:
1703   //                  0 = successfull calling
1704   //                  1 = geometrical error: all the particles
1705   //                      are in the same side of the vertex in
1706   //                      at least one direction.NOT SEVERE.
1707   //                      Caller can safely try again.
1708   //                  2 = phisical error: there is too much
1709   //                      transverse energy or particle with
1710   //                      too high pz or energy is too close to
1711   //                      multiplicity threshold. SEVERE ERROR.
1712   //                      Caller may try again, but... not too much!
1713   //================================================================
1714 
1715   double  pzpsum,pznsum,pzscal,epscal,enscal,pxscal,pyscal;
1716 
1717   double  esum=0.;
1718   double  pxsum=0.;
1719   double  pysum=0.;
1720   double  pzsum=0.;
1721   double  apxsum=0.;
1722   double  apysum=0.;
1723   double  apzsum=0.;
1724   double  pz3sum=0.;
1725   double  alpha=3.0;
1726 
1727   double px,py,pz,mass;
1728 
1729   CdfHepevt* hepevt = CdfHepevt::Instance();
1730   int numberOfParticles=hepevt->HepevtPtr()->NHEP;
1731 
1732   if(inelasticEvent) {
1733     double smult=1.5*(-7.+7.2*pow((amx*amx),0.127));
1734     if(numberOfParticles<=0.2*smult)                                 alpha=1.5;
1735     if(numberOfParticles>=0.2*smult&&numberOfParticles<=0.400*smult) alpha=1.7;
1736     if(numberOfParticles>=0.4*smult&&numberOfParticles<=0.795*smult) alpha=2.0;
1737     if(numberOfParticles>=0.795*smult)                               alpha=3.0;
1738   }
1739 
1740 
1741 
1742   for(int i=ngen0-1;i<numberOfParticles;i++){
1743     double* hp  = hepevt->HepevtPtr()->PHEP[i];
1744     px=hp[0];
1745     py=hp[1];
1746     pz=hp[2];
1747 
1748     pxsum+=px;
1749     pysum+=py;
1750     pzsum+=pz;
1751     apxsum+=fabs(px);
1752     apysum+=fabs(py);
1753     apzsum+=fabs(pz);
1754     pz3sum+=pow(fabs(pz),alpha);
1755   }
1756 
1757    //  check that for each directions there are particles in both
1758    //  sides, otherwise it would be impossible to balance momentum
1759    //  with only a scale change
1760 
1761    if(fabs(pxsum)==apxsum || fabs(pysum)==apysum || fabs(pzsum)==apzsum) {
1762      return 1;
1763    }
1764 
1765    pxscal=pxsum/apxsum;
1766    pyscal=pysum/apysum;
1767    pzscal=pzsum/pz3sum;
1768 
1769    //-------------------------------------------------
1770    //
1771    //  Adjuste momentum in order to have sump = 0.
1772    //  The momentum shift for each particle is proportional
1773    //  to its momentum, so to distorce not too much the
1774    //  original distribution of Pt and eta. This will be done
1775    //  obviously for daughters as same as parents, but the
1776    //  new outgoing sums will be computed only on daughters,
1777    //  i.e. really outgoing particles (termination code =0).
1778 
1779    esum=0.0;
1780    apzsum=0.;
1781    pzpsum=0.;
1782    pznsum=0.;
1783 
1784    for(int i=ngen0-1;i<numberOfParticles;i++){
1785                                         // kludge for EGCS/SSGI
1786      double* hp = hepevt->HepevtPtr()->PHEP[i];
1787 
1788      px   = hp[0];
1789      py   = hp[1];
1790      pz   = hp[2];
1791      mass = hp[4];
1792 
1793      px  -= fabs(px)*pxscal;
1794      py  -= fabs(py)*pyscal;
1795      pz  -= pow(fabs(pz),alpha)*pzscal;
1796 
1797      hp[0] = px;
1798      hp[1] = py;
1799      hp[2] = pz;
1800 
1801      if(hepevt->HepevtPtr()->ISTHEP[i]==stable) {
1802        if (pz>0.) pzpsum+=pow(pz,alpha);
1803        if (pz<0.) pznsum+=pow(fabs(pz),alpha);
1804        apzsum+=fabs(pz);
1805        esum+=sqrt(pow(px,2)+pow(py,2)+pow(pz,2)+pow(mass,2));
1806      }
1807      
1808    }
1809 
1810    //  Longitudinal momemtum is now changed to have
1811    //  total energy conservation. The change is proportional
1812    //  to Pz**3 for each particle, so to blame only very forward
1813    //  and/or backward particles for energy non conservation. This
1814    //  will disturbe very little input pseudorapidity distribution,
1815    //  giving rise only to some tails which anyway must be there!
1816    //  To save at the same time SUM(Pz)=0, particles are divided
1817    //  into two groups: those with Pz>0 and those with Pz<0, for each
1818    //  group a different scale is made in order to end with abs(SUM(Pz+))
1819    //  equal to abs(SUM(Pz-)) as in the beginning. This condition is not
1820    //  always automatically guaranteeded by the algorithm an so a check
1821    //  will be made at each iteration, actually the condition will be
1822    //  that Pz does not change it sign due to the rescale. The procedure
1823    //  is iterated up to a maximum of 15 times or till the total outgoing
1824    //  energy differs from AMX by less then 0.1%. A severe error condition
1825    //  is generated if 15 iterations are made without success or if it turns
1826    //  out impossible to guarantee longitudinal momentum conservation.
1827 
1828    //  If there is more transvere energy than total requested
1829    //  energy (AMX) of course very little can be done !
1830 
1831    if((esum-apzsum)>=amx) {
1832      //std::cout << " MBR : Energy momentum balance : esum-apzsim > amx " << std::endl;
1833      return 2;
1834    }
1835 
1836 
1837    int irep=0;
1838    double test=fabs(esum-amx);
1839  
1840    while (test >0.001*amx) {
1841      if(irep++>15) {
1842        //std::cout << "MBR : Energy momentum balance : irep++>15 " << std::endl;
1843        return 2;
1844      }
1845 
1846      if(pzpsum==0.||pznsum==0.) {
1847        //std::cout << "MBR : Energy momentum balance :pzpsum==0.  " << std::endl;
1848        return 2;
1849      }
1850      else {
1851        epscal=(amx-esum)/(2.*pzpsum);
1852        enscal=(amx-esum)/(2.*pznsum);
1853      }
1854 
1855 
1856      // scale the z-componenet to balance energy-momentum
1857 
1858      esum=0.;
1859      pznsum=0.;
1860      pzpsum=0.;
1861      double pz_old;
1862 
1863      for(int i=ngen0-1;i<numberOfParticles;i++){
1864        double* hp  = hepevt->HepevtPtr()->PHEP[i];
1865        pz= hp[2];
1866        pz_old=pz;
1867 
1868        if(pz>=0){
1869          pz+=pow(pz,alpha)*epscal;
1870        }
1871        else {
1872          pz-=pow(fabs(pz),alpha)*enscal;
1873        }
1874 
1875        if(pz*pz_old>0) {
1876          hp[2]=pz;
1877        }
1878        else {
1879          //std::cout << "MBR : Energy momentum balance : wrong sign " << std::endl;
1880          return 2;
1881        }
1882         
1883        if(hepevt->HepevtPtr()->ISTHEP[i]==stable) {
1884                                         // kludge for SGI/EGCS
1885          double pz  = hp[2];
1886 
1887          if(pz>=0.) {
1888            pzpsum+=pow(pz,alpha);
1889          }
1890          else {
1891            pznsum+=pow(fabs(pz),alpha);
1892          }
1893          esum +=sqrt(hp[0]*hp[0]+hp[1]*hp[1]+hp[2]*hp[2]+hp[4]*hp[4]);
1894        }
1895      }
1896      //  test present total energy
1897      test = fabs(esum-amx);
1898    }
1899    return 0;
1900 }
1901 
1902 //_____________________________________________________________________________
1903 
1904 int  MinBiasModule::total_multiplicity_by_dino(double wmu,double avnstar){
1905   //**********************************************************
1906   //
1907   // The  Subroutine DINO  generates the total multiplicity.
1908   // It is called by AVMUL with  2 S-dependent input parameters:
1909   // WMU, an S- dependent parameter which is calculated in the
1910   // Subroutine AVMUL  and AVNSTAR, the average no. of fictitious
1911   // pseudo-particles which decay into pairs of pi+,pi_ or into
1912   // pizeros. (See CDF NOTE # 675) 
1913   // The Subroutine DINO returns the multiplicity for the present
1914   // event in the value of MULTI.
1915   //================================================================
1916   //   Author:      J. Grunhaus   June 1988
1917   //   Modified:    T. Chapin     July 1989 Corrected to give total multiplicity
1918   //================================================================
1919   //
1920   //   Argument description:
1921   //
1922   //   INPUT:
1923   //
1924   //   WMU:      R*4  IS A S-DEPENDENT PARAMETER CALCULATED IN SUB. AVMUL
1925   //   AVNSTAR:  R*4  AVERAGE NO. OF CHARGED SECONDARIES CALCULATED IN SUB. AVMUL
1926   //
1927   //   OUTPUT:   MULTI:  I*4  TOTAL MULTIPLICITY
1928   //
1929   //================================================================
1930   //    GAMA(X)=GAMMA(X/2.)*GAMMA(X/2.+0.5)/(SQRT(3.1416)*2.**(1.-X))
1931 
1932   double ztop,gmax,fact,z,gaa,xmulti;
1933   double funct;
1934   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
1935 
1936   ztop=( wmu-1.)/wmu;
1937   if(wmu<=10.) {
1938     double gamma_wmu=mbr_gamma(wmu);
1939     gmax=pow(wmu,wmu)/gamma_wmu*pow(ztop,(wmu-1.))*exp(-wmu*ztop);
1940   }
1941   else {
1942     fact=(wmu-1.)*log(ztop)+wmu*(1.-ztop)+0.5*log(wmu)-0.5*log(6.28);
1943     fact=exp(fact);
1944     gmax=fact/(1.+1./(12.*wmu));
1945   }
1946 
1947   double zmax= 8.0;
1948 
1949   do {
1950     z= RandFlat::shoot(engine)*zmax;
1951     if(wmu<=10.) {
1952       double gamma_wmu=mbr_gamma(wmu);
1953       gaa=pow(wmu,wmu)/gamma_wmu*pow(z,(wmu-1.))*exp(-wmu*z);
1954     }
1955     else {
1956       fact=(wmu-1.)*log(z)+wmu*(1.-z)+0.5*log(wmu)-0.5*log(6.28);
1957       fact=exp(fact);
1958       gaa=fact/(1.+1./(12.*wmu));
1959     }
1960     funct= RandFlat::shoot(engine)*gmax; 
1961   } while (funct > gaa);
1962 
1963       //  changed to give total multiplicity
1964 
1965   xmulti=3./2.*z*avnstar;
1966   int multi=int(xmulti);
1967   return multi;
1968 }
1969 
1970 //_____________________________________________________________________________
1971 
1972 double  MinBiasModule::generate_random_o2(void){
1973   //********************************************************** 
1974   //
1975   //  This is a general subroutine to generate random numbers
1976   //  in the interval [0,1] according to a given probability
1977   //  distribution. One has simply to change the name of the 
1978   //  routine according to the function to use, and sustituing
1979   //  
1980   //  - the desidered prob. density as right side of the definition
1981   //    of PFUN. The function does not need to be normalized,
1982   //    but must of course be strictely positive. No check
1983   //    of concistency is made.
1984   //  - the minimum and maximun range for the argument of that
1985   //    function in the right side of XMIN and XMAX.
1986   //  
1987   //   Author:     S. Belforte    June 1984
1988   //
1989   //   Argument description:
1990   //  OUTPUT:  XRAN R*4 is the generated random number in [0,1]
1991 
1992   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
1993   double xran;
1994 
1995   int    ipt;
1996   double xmin,xmax,dx,fsum,rn;
1997   double f[501];
1998   double x[501];
1999   int    init=0;
2000 
2001   // PROBABILITY DENSITY  function
2002   //  pfun(y)=1.0+cos(y)**2           inline function
2003 
2004   xmin=0.0;
2005   xmax=pi;
2006 
2007   //*********************************************************
2008   if (init==0) {
2009 
2010     // integrate and invert numerically the function PFUN
2011     // at the end F[i] will contain the normalized integral
2012     // from XMIN to I, and X[i] the value of the corrisponding
2013     // inverse function
2014 
2015     dx=(xmax-xmin)/500.0;
2016     x[0]=xmin;
2017     f[0]=0.;
2018     for(int i=0;i<500;i++){
2019       x[i+1]=x[i]+dx;
2020       f[i+1]=f[i]+pfun(x[i]-.5*dx);
2021     }
2022           
2023     fsum=f[500];
2024 
2025     //  normalize the integral
2026 
2027     for(int i=0;i<500;i++){
2028       f[i+1]=f[i+1]/fsum;
2029     }
2030     init=1;
2031   }
2032 
2033   ipt =-1;        
2034   while(ipt<0) {
2035     rn=1.1;
2036     while (rn<=0.||rn>1.) {
2037       rn=RandFlat::shoot(engine);
2038     }
2039 
2040     //   invert the integral funcion
2041     for (int i=0;i<500;i++) {
2042       ipt=i;
2043       if(rn <=f[i+1]) {
2044         ipt=i;
2045         //  interpolate linearly for better accuracy
2046         xran=x[i]+(rn-f[i])*((x[i+1]-x[i])/(f[i+1]-f[i]));
2047         return xran;
2048       }
2049     }
2050   }
2051   return 0.0;
2052 }
2053 
2054 //_____________________________________________________________________________
2055 
2056 void  MinBiasModule::rotate_three_vector(double phi,double theta,double psi,
2057                           double &x,double &y,double &z){
2058 
2059   double  ax,ay,bx;
2060 
2061   ax=x*cos(psi)-y*sin(psi);  
2062   ay=x*sin(psi)+y*cos(psi);  
2063   bx=z*sin(theta)+ax*cos(theta);   
2064 
2065   z=z*cos(theta)-ax*sin(theta);    
2066 
2067   x=bx*cos(phi)-ay*sin(phi); 
2068   y=bx*sin(phi)+ay*cos(phi); 
2069 }
2070 
2071 //_____________________________________________________________________________
2072 
2073 double  MinBiasModule::generate_rapidiy(double amx){
2074 
2075   //*********************************************************
2076   //
2077   // This subroutine generate the rapidity for a
2078   // particle from the decay of the current diffractive mass AMX
2079   // in its own center of mass, the mass and total multiplicity
2080   // are stored in the common MBRCOM. The distribution used is
2081   // a trapezoid centered around Y.average= 0 and extending
2082   // up to Y.max=ln(AMX).
2083   // Author:  S. Belforte
2084   //                                 September 1984
2085 
2086   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
2087   double y;
2088   double rn,eee,fact,rrr,bot,yyy;
2089       
2090   int count=0;
2091 
2092   eee=flatRapidityRegion;
2093                              //eee=0.35; change for 0.4 in init
2094   fact=eee*log(amx);
2095   bot=log(amx)*(1.-eee);
2096 
2097   for(;;) {
2098     rn=RandFlat::shoot(engine);        
2099     y=log(amx)*(2.*rn-1.);
2100     if ( y > -fact &&  y < fact) return y;
2101 
2102     rrr=RandFlat::shoot(engine);
2103     if(y<= -fact)  yyy=(log(amx)+y)/bot;
2104     if(y>=  fact)  yyy=(log(amx)-y)/bot;
2105     if(rrr <= yyy) return y;
2106 
2107     if (count++>500) return 0;
2108   }
2109 
2110 }
2111 
2112 //_____________________________________________________________________________
2113 
2114 double    MinBiasModule::generate_pt(double amx,int nt){
2115 
2116   //**********************************************************
2117   //
2118   // This subroutine generates the trsnsverse momentum from
2119   // a power law distribution. The mean value of Pt is in general
2120   // a raising function of the mass, but for masses below 60 GeV
2121   // the function for 60 GeV mass is used. For very low masses
2122   // (below 4 GeV) the maximum allowed Pt is fixed at the total
2123   // available energy divided by the current multiplicity.
2124   // It is an almost unmodified version of MB1 routine
2125   // PTDIST.
2126   //   Author:     S. Belforte  July 1984
2127   //================================================================
2128 
2129   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
2130   double pt;
2131   double am,ptcut,dxpt,xpt,fptsum,rn;
2132 
2133   double fpt3[501];
2134   double pt3[501];
2135 
2136   double ptmax=50.;
2137   double ptsoft=1.27;
2138   double power=4.0;
2139   double amo=0.0;
2140 
2141       //      f3(x)=x/pow((1.+x/ptsoft),power);
2142 
2143   am=amx;
2144   if (amx<60.) am=60.;
2145   ptcut=amx/double(nt);
2146   if (am!=amo) {
2147     power=4.+35.83/log(am/0.3);
2148     amo=am;
2149     dxpt=0.5*ptmax/500.;
2150     pt3[0]=0.;
2151     fpt3[0]=0.;
2152     for(int i=0;i<500;i++){
2153       xpt=double(i+1)*ptmax/500.;
2154       pt3[i+1]=xpt;
2155       fpt3[i+1]=fpt3[i]+f3(xpt-dxpt,ptsoft,power);
2156     }
2157     fptsum=fpt3[500];
2158       for(int i=0;i<500;i++){
2159         fpt3[i+1]=fpt3[i+1]/fptsum;
2160       }
2161   }
2162 
2163   int count=0;
2164 
2165   for (;;) {
2166     if(count++>500) return 0;       
2167     do {
2168       rn=RandFlat::shoot(engine);
2169     } while (rn <0.0 || rn > 1.0);
2170 
2171     for(int i=0;i<500;i++){
2172       if(rn <= fpt3[i+1]) {
2173         pt=pt3[i]+(rn-fpt3[i])*((pt3[i+1]-pt3[i])/(fpt3[i+1]-fpt3[i]));
2174         if(amx<4.0 && pt>ptcut) break;
2175         return pt;
2176       }
2177     }
2178   } 
2179 }
2180 
2181 //_____________________________________________________________________________
2182 
2183 int MinBiasModule::fragment_cluster(int ngenmx,double pxcm[4],int icharg){
2184   //
2185   //     This is a general subroutine to simulate at least in an
2186   //     approssimate way the decay of a mass AMX according to
2187   //     phenomenogical distributions of multiplicity, rapidity 
2188   //     and transverse momentum. The method is quite general
2189   //     and is intended to be used for each kind of event:
2190   //     single diffractive, double diffractive and hard core 
2191   //     collision. In any case the mass effectively used for
2192   //     generating the multiplicity is MX-M(proton) which the
2193   //     doublely available mass.
2194   //
2195   //      Author:  S.Belforte   June 1984
2196   //
2197   //   Argument description:
2198   //
2199   //  INPUT:
2200   //
2201   //         NGENM : I*4 is the particle number of the system in the
2202   //                     /GENP/ common
2203   //         PXCM[4]:R*4 is the beta of the Lorentz transformation from
2204   //                  CM-X ref. system to CM-event system
2205   //      ICHARG: I*4 is the total charge of the decaying system
2206   //
2207   //  OUTPUT:
2208   //
2209   //         IERR :  I*4 is the error return code:
2210   //                  0 = successfull calling
2211   //                  1 = unable to balance at least approximately
2212   //                      the energy in the maximun allowed number
2213   //                      of trials
2214   //
2215 
2216 
2217   CdfHepevt* hepevt = CdfHepevt::Instance();       
2218   HepRandomEngine* engine = MinBiasModule::minBiasEngine;
2219 
2220   int ngen0,nch,nn,ip1,ip2,ip3;
2221   int nnsav,ier1,nchsav;
2222   int nt;
2223   
2224   // define the maximum number of iterations of multiplicity
2225   // and kinematics generation before changing something at a higher level
2226   
2227   int mxking=10;
2228   int mxmulg=10;
2229   int imulc=0; 
2230   int ikinc=0;
2231   
2232   int ierr=0;
2233   double flag=0.0;
2234   
2235   double* hp = hepevt->HepevtPtr()->PHEP[ngenmx-1];
2236   double amx = hp[4];
2237   
2238   //std::cout << " hardcore:  index " << ngenmx << " mass  " << amx << std::endl;
2239   
2240   int currentParticle=hepevt->HepevtPtr()->NHEP;
2241   ngen0=currentParticle+1;
2242   
2243  A20: imulc=imulc+1;
2244   
2245   if(imulc>=2) {
2246     mulflg=1;
2247     iermlg++;
2248   }
2249   
2250   if(imulc>mxmulg) {
2251     //  Too many tries without producing an avent such to be balanced by BALAN.
2252     //  Return with IERR=1. The subroutine was  called for particle 
2253     // which had mass  and charge last generated multiplicity
2254     nt=0;
2255     ierr=1;
2256     return ierr;
2257   }
2258   
2259   do {
2260     do {
2261       nt=average_multiplicity(amx);
2262     }  while (nt < 2 || nt >MAXGEN);
2263     
2264     nch=0;  nn=0; ip1=0;  ip2=0;  ip3=0;
2265     
2266     //
2267     // First track is always a baryon, to have things not too wrong
2268     // for little masses. If total charge (ICHARG) =0 then it is a
2269     // hard core collision with MX=sqrt(S) and there is no need of
2270     // such baryon. If the baryon turns out to be neutral (according
2271     // to PNRAT branching ratio) a charged pi-meson is also generated
2272     // to account for charge conservation, so only a total zero
2273     // charge is left to subsequent code.
2274     
2275     
2276      if(icharg!=0) {
2277        flag= (RandFlat::shoot(engine)<pnrat);    //decide if baryion is charged
2278        if(icharg==1) {                    // proton fragments
2279          if(flag) {                       //     proton
2280            ip1=PSPRO;
2281            nch=nch+1;
2282            nt=nt-1;
2283          }
2284          else   {            //neutron + pi+
2285            ip1=PSNTN;
2286            ip2=PSPIP;
2287            nch=nch+1;
2288            nn=nn+1;
2289            nt=nt-2;
2290          }
2291        }
2292        else {                 //  antiproton fragments
2293          if(flag) {           //  antiproton
2294            ip1=PSPROB;
2295            nch=nch+1;
2296            nt=nt-1;
2297          }
2298          else {               //   antineutron + pi-
2299            ip1=PSNTNB;
2300            ip2=PSPIM;
2301            nch=nch+1;
2302            nn=nn+1;
2303            nt=nt-2;
2304          }
2305        }
2306      }   
2307 
2308      //  now compute the total number of pi0 and pi+pi- pairs to generate
2309 
2310      double n=int(0.5+double(nt)/3.*2.);
2311      if(icharg== 0 && n==1) {
2312        n=2;
2313      }
2314 
2315      // now decide for each of these N 'object' if it is a neutral
2316      // or a +- pair, this will give the total definitive multiplicity
2317      // for this fragmentation
2318 
2319      for(int i=0;i<n;i++){
2320        if(RandFlat::shoot(engine)>0.5) {
2321          nn=nn+1;
2322        }
2323        else {
2324          nch=nch+2;
2325        }
2326      }
2327      nt=nch+nn;
2328    } while (nt>MAXGEN);
2329     
2330    nchsav=nch;
2331    nnsav=nn;
2332    
2333    // Update /GENP/ informations on MX with decay informations
2334 
2335    currentParticle=hepevt->HepevtPtr()->NHEP;
2336    int* jd = hepevt->HepevtPtr()->JDAHEP[ngenmx-1];
2337    jd[0]   = currentParticle-1;
2338 
2339    //   MbrEvt.set_statusCode(ngenmx,201);
2340 
2341    // Separate 2 and 3-body decays of the diffraccted mass for which
2342    // exact phase space can be used. If only the nucleon for the two body
2343    // case has been fixed, then a pi0 it is added, a pi0 is added in any
2344    // case to the exixting nucleon-pi pair in the three body case if the
2345    // nucleon was neutral, if the nucleon was charged a pi+pi- or pi0pi0
2346    // pair is added with equal probability. If the 
2347    // total charge is zero and no nucleon was generated, then all particle
2348    // types are setted according to generated NCH and NN.
2349 
2350    if ((nt==2)&&(icharg!=0)) {
2351      if(ip2==0) ip2=PSPIZ;
2352      ier1=two_body_decay(ngenmx,ip1,ip2);
2353      if(ier1!=0) {
2354        return ier1;
2355      }
2356    }
2357    else if ((nt==3)&&(icharg!=0)) {
2358      if(flag){
2359        if(RandFlat::shoot(engine)>.5) {
2360          ip2=PSPIP;
2361          ip3=PSPIM;
2362        }
2363        else {
2364          ip2=PSPIZ;
2365          ip3=PSPIZ;
2366        }
2367      }
2368      else {
2369        ip3=PSPIZ;
2370      }
2371      ier1=three_body_decay(ngenmx,ip1,ip2,ip3);
2372      if(ier1!=0) {
2373        return ier1;
2374      }
2375    }
2376    else {
2377 
2378      ikinc=0;
2379 
2380      do {
2381        if(ip1!=0){
2382          generate_one_particle_from_fire_ball(ngenmx,ip1,nt);
2383          if(flag) {
2384            nch=nch-1;
2385          }
2386          else { 
2387            nn=nn-1;
2388          }
2389        }
2390        if(ip2!=0) {
2391          generate_one_particle_from_fire_ball(ngenmx,ip2,nt);
2392          nch=nch-1;
2393        }
2394 
2395        // Now loop over the other particles MX decays in
2396 
2397        for(int i=0;i<nch/2;i++){
2398          generate_one_particle_from_fire_ball(ngenmx,PSPIP,nt);
2399          generate_one_particle_from_fire_ball(ngenmx,PSPIM,nt);
2400        }
2401        for(int i=0;i<nn;i++){
2402          generate_one_particle_from_fire_ball(ngenmx,PSPIZ,nt);
2403        }
2404 
2405        ier1=balance_energy_momentum(amx,ngen0); 
2406 
2407        if(ier1!=0) {         // reset pointers for the new try
2408          hepevt->HepevtPtr()->NHEP=(ngen0-1);
2409          nn=nnsav;
2410          nch=nchsav;
2411 
2412          if(ier1>=2) {
2413            ikinc=ikinc+1;
2414            if(ikinc>=2) {
2415              iknflg=1;
2416              ierkng++;
2417            } 
2418            if(ikinc>mxking) {
2419              goto A20;
2420            }
2421          }
2422        }   //  ier1 != 0
2423      } while (ier1!=0);
2424    }
2425 
2426   //    Boost event to center of mass frame
2427 
2428    double v1[4],v2[4];
2429 
2430    int numberOfParticles=hepevt->HepevtPtr()->NHEP;
2431    for(int i=ngen0-1;i<numberOfParticles;i++){
2432                                         // kludge for EGCS/SGI
2433      double* hp = hepevt->HepevtPtr()->PHEP[i];
2434      for (int j=0;j<4;j++) {
2435        v1[j]=hp[j];
2436      }
2437 
2438      v1[3]=sqrt(v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2]+hp[4]*hp[4]);
2439 
2440      add_lorentz_boost(pxcm,v1,v2);
2441 
2442      for (int j=0;j<4;j++) {
2443        hp[j]=v2[j];
2444      }
2445    }
2446    return 0;
2447 }
2448 
2449 //_____________________________________________________________________________
2450 
2451 double  MinBiasModule::mbr_gamma(double x) {
2452    
2453 //Gamma function (approx from Gradshteyn+Ryzhik)
2454     double g=pow(x,(x-0.5))*exp(-x)*sqrt(2*3.141592654)*(1.+1./(12.*x)
2455         +1./(288.*x*x)-139./(51840.*x*x*x)-571./(2488320.*x*x*x*x));
2456   return g;
2457 }
2458 
2459 //_____________________________________________________________________________
2460 
2461 void MinBiasModule::print(void){
2462 
2463   std::cout <<" Minimum Bias Rockefeller Monte Carlo Generator " << std::endl;
2464   std::cout <<" Center of mass energy                 " << tecm   << std::endl;
2465   std::cout <<" Total cross section (mb)              " << sigtot << std::endl;
2466 
2467   std::cout <<" Hard Core cross section (mb)          "<<sig0  <<"   "<< sgrat[0]<<std::endl;
2468   std::cout <<" Double diffractive cross section (mb) "<<sigdd <<"   "<< sgrat[1]<<std::endl;
2469   std::cout <<" Single diffractive cross section (mb) "<<sigsd <<"   "<< sgrat[2]<<std::endl;
2470   std::cout <<" Elastic cross section (mb)            "<<sigel <<"   "<< sgrat[3]<<std::endl;
2471   std::cout <<std::endl;
2472 
2473   std::cout <<" Resonance  contribution (mb)          "<<sigres<<"   "<<std::endl;
2474   std::cout <<" Relative contribution to single diffractive events are :" << std::endl;
2475   std::cout <<"   Continuum  "  << sgdrat[0]  
2476        <<"   M**2 =2.2  "  << sgdrat[1]  
2477        <<"   M**2 =2.8  "  << sgdrat[2]  
2478        <<"   M**2 =4.4  "  << sgdrat[3] <<std::endl;
2479 
2480   std::cout <<" Initial rectangular region " << sgdrat[4] << std::endl;
2481   std::cout <<" Minimum and maximum for diffractive mass " << ammin << " " <<ammax << std::endl;
2482 
2483 
2484   std::cout <<" Incremental range for different sources "
2485        <<rate[0] <<"  "<<rate[1] <<  "  "<<rate[2] <<"  "<<rate[3]<<std::endl;
2486 
2487   std::cout <<" Incremental range for different masses "
2488        <<drate[0] <<"  "<<drate[1]<<"  "<<drate[2]<<"  "<<drate[3]<<"  "<<drate[4]<<std::endl;
2489 
2490 }
2491 //******************************************************************************
2492 //*  Minimum bias event generator  adopated from mbr                           *
2493 //*  Anwar Ahmad Bhatti            December 24, 1998                           *
2494 //*                                                                            *
2495 // *0001 Feb 22 1999 P.Murat: put in kludges for EGCS/SGI                      *
2496 //******************************************************************************
2497 
2498 void MinBiasModule::add_particle_HepEvt(int type,int firstMother,int lastMother,
2499                                     int status,double p[4],double mass){
2500 
2501   CdfHepevt* hepevt = CdfHepevt::Instance();
2502 
2503    hepevt->HepevtPtr()->NHEP=hepevt->HepevtPtr()->NHEP+1;
2504 
2505    int nhep=hepevt->HepevtPtr()->NHEP;
2506 
2507    if(nhep>=1 && nhep<=NMXHEP) {
2508      int i=nhep-1;
2509      hepevt->HepevtPtr()->IDHEP[i]  = type;
2510      hepevt->HepevtPtr()->ISTHEP[i] = status;
2511 
2512      int* hm = hepevt->HepevtPtr()->JMOHEP[i];
2513      hm[0]=firstMother;
2514      hm[1]=lastMother;
2515 
2516      int* hd = hepevt->HepevtPtr()->JDAHEP[i];
2517      hd[0]=0;
2518      hd[1]=0;
2519 
2520      double* hp = hepevt->HepevtPtr()->PHEP[i];
2521      double* hv = hepevt->HepevtPtr()->VHEP[i];
2522 
2523      for (int j=0;j<4;j++){
2524        hp[j]=p[j];
2525        hv[j]=0.0;
2526      }
2527      hp[4]=mass;
2528    }
2529 
2530 }
2531 
2532 
2533 
2534 
2535 
2536 
2537 
2538 
2539 
2540 
2541 
2542 
2543 
2544 
2545 
2546 
2547 
2548 
2549 

source navigation ] diff markup ] identifier search ] freetext search ] file search ]

This page was automatically generated by the LXR engine.
The LXR team
Valid HTML 4.01!

Send problems or questions to cdfcode@fnal.gov