ROOT logo
/**************************************************************************
 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

// Generator for particles according generic functions
//  
//  TF1 *   fFMomentum;           // momentum distribution function inGeV
//  TF1 *   fFPhi;                // phi distribution function in rad
//  TF1 *   fFTheta;              // theta distribution function in rad
//  TF3 *   fFPosition;           // position distribution function in cm
//  TF1 *   fFPdg;                // pdg distribution function  
//  We assume that the moment, postion and PDG code of particles are independent  
//  Only tracks/particle crossing the reference radius at given z range
//
// Origin: marian.ivanov@cern.ch


/*
  Example generic function for cosmic generation:
 
//
  	AliGenFunction *generCosmic = new AliGenFunction;
	generCosmic->SetNumberParticles(100);
	TF1 *fmom   = new TF1("fmom","TMath::Exp(-x/8)",0,30);
	//
	TF1 *fphi   = new TF1("fphi","TMath::Gaus(x,-TMath::Pi()/2,0.3)",-3.14,3.14);
	TF1 *ftheta = new TF1("ftheta","TMath::Gaus(x,TMath::Pi()/2,0.3)",-3.14,3.14);
	TF3 *fpos = new TF3("fpos","1+(x+y+z)*0",-2000,2000,700,701,-2000,2000);
	TF1 * fpdg= new TF1("fpdg","1*(abs(x-13)<0.1)+1*(abs(x+13)<0.1)",-300,300);
	fpdg->SetNpx(10000);  // neccessary - number of bins for generation
	generCosmic->SetVertexSmear(kPerEvent);
	generCosmic->SetFunctions(fmom,fphi,ftheta,fpos,fpdg);
	generCosmic->SetCylinder(375,-375,375);
	generCosmic->SetBkG(0.2);
	gener->AddGenerator(generCosmic,"generCosmic",1);


  
*/




#include <TParticle.h>
#include <TF1.h>
#include <TF3.h>
#include <TDatabasePDG.h>

#include "AliRun.h"
#include "AliLog.h"
#include "AliESDtrack.h"
#include "AliESDVertex.h"
#include "AliGenFunction.h"
#include "AliGenEventHeader.h"

ClassImp(AliGenFunction)

//-----------------------------------------------------------------------------
AliGenFunction::AliGenFunction():
  AliGenerator(),
  fBkG(0.),  
  fFMomentum(0),           // momentum distribution function 
  fFPhi(0),                // phi distribution function
  fFTheta(0),              // theta distribution function
  fFPosition(0),           // position distribution function 
  fFPdg(0),                // pdg distribution function  
  fRefRadius(0),           // reference radius to be crossed
  fZmin(0),                // minimal z at reference radius
  fZmax(0),                // z at reference radius
  fMaxTrial(10000)         // maximal number of attempts
{
  //
  // Default constructor
  //
  SetNumberParticles(1);
}

AliGenFunction::AliGenFunction(const AliGenFunction& func):
  AliGenerator(),
  fBkG(func.fBkG),  
  fFMomentum(func.fFMomentum),           // momentum distribution function 
  fFPhi(func.fFPhi),                     // phi distribution function
  fFTheta(func.fFTheta),                 // theta distribution function
  fFPosition(func.fFPosition),           // position distribution function 
  fFPdg(func.fFPdg),                     // pdg distribution function  
  fRefRadius(func.fRefRadius),           // reference radius to be crossed
  fZmin(func.fZmin),                     // minimal z at reference radius
  fZmax(func.fZmax),                     // z at reference radius
  fMaxTrial(10000)                       // maximal number of attempts
{
    // Copy constructor
    SetNumberParticles(1);
}

AliGenFunction & AliGenFunction::operator=(const AliGenFunction& func)
{
    // Assigment operator
      if(&func == this) return *this;
      fBkG       = func.fBkG;
      fFMomentum = func.fFMomentum; 
      fFPhi      = func.fFPhi;      
      fFTheta    = func.fFTheta;    
      fFPosition = func.fFPosition; 
      fFPdg      = func.fFPdg;      
      fRefRadius = func.fRefRadius;      
      fZmin      = func.fZmin;                
      fZmax      = func.fZmax;                
      fMaxTrial  = func.fMaxTrial;
      return *this;
}


//-----------------------------------------------------------------------------
void AliGenFunction::Generate()
{
  //
  // Generate one muon
  //
  Int_t naccepted =0;
  
  for (Int_t ipart=0; ipart<fMaxTrial && naccepted<fNpart; ipart++){
    //
    //
    //
    Float_t mom[3];
    Float_t posf[3];
    Double_t pos[3];
    Int_t pdg;
    Double_t ptot, pt,  phi, theta; 
    //
    ptot     = fFMomentum->GetRandom();
    phi      = fFPhi->GetRandom();
    theta    = fFTheta->GetRandom();
    pt     = ptot*TMath::Sin(theta);
    mom[0] = pt*TMath::Cos(phi); 
    mom[1] = pt*TMath::Sin(phi); 
    mom[2] = ptot*TMath::Cos(theta);

    //
    fFPosition->GetRandom3(pos[0],pos[1],pos[2]);
    posf[0]=pos[0];
    posf[1]=pos[1];
    posf[2]=pos[2];
    pdg = TMath::Nint(fFPdg->GetRandom());
    if (!IntersectCylinder(fRefRadius,fZmin, fZmax, pdg, posf, mom)) continue;
    //
    //
    Float_t polarization[3]= {0,0,0};
    Int_t nt;
    PushTrack(fTrackIt,-1,pdg,mom, posf, polarization,0,kPPrimary,nt);
    naccepted++;
  }

  AliGenEventHeader* header = new AliGenEventHeader("THn");
  gAlice->SetGenEventHeader(header);
  return;
}
//-----------------------------------------------------------------------------
void AliGenFunction::Init()
{
  // 
  // Initialisation, check consistency of selected ranges
  //
  printf("************ AliGenFunction ****************\n");
  printf("************************************************\n");
  if (!fFMomentum){
    AliFatal("Momentum distribution function not specified");
  }
  if (!fFPosition){
    AliFatal("Position distribution function not specified");
  }
  if (!fFPdg){
    AliFatal("PDG distribution function not specified");
  }
  if (fZmin==fZmax){
    AliFatal("Z range not specified");
  }

  return;
}

void AliGenFunction::SetFunctions(TF1 * momentum, TF1 *fphi, TF1 *ftheta,TF3 * position, TF1* pdg){
  //
  // Set the function
  //
  fFMomentum = momentum;
  fFPhi = fphi;
  fFTheta = ftheta;
  fFPosition = position;
  fFPdg = pdg;
}

void AliGenFunction::SetCylinder(Double_t refR, Double_t zmin, Double_t zmax){
  //
  // Set the cylinder geometry
  //
  fRefRadius = refR;          // reference radius to be crossed
  fZmin = zmin;               // minimal z at reference radius
  fZmax = zmax;               // maximal z at reference radius

}


//-----------------------------------------------------------------------------
Bool_t AliGenFunction::IntersectCylinder(Float_t r,Float_t zmin, Float_t zmax,Int_t pdg,
					 Float_t o[3],Float_t p[3]) const
{
  //
  // Intersection between muon and cylinder [-z,+z] with radius r
  //
  Double_t mass=0;
  if (TDatabasePDG::Instance()->GetParticle(pdg)){
    mass = TDatabasePDG::Instance()->GetParticle(13)->Mass();
  }

  Float_t en = TMath::Sqrt(mass*mass+p[0]*p[0]+p[1]*p[1]+p[2]*p[2]);
  TParticle part(pdg,0,0,0,0,0,p[0],p[1],p[2],en,o[0],o[1],o[2],0);
  AliESDtrack track(&part);
  Double_t pos[3]={0.,0.,0.},sigma[3]={0.,0.,0.};
  AliESDVertex origin(pos,sigma);

  track.RelateToVertex(&origin,fBkG,10000.);

  Float_t d0z0[2],covd0z0[3];
  track.GetImpactParameters(d0z0,covd0z0);

  // check rphi 
  if(TMath::Abs(d0z0[0])>r) return kFALSE;
  // check z
  if(d0z0[1]>zmax) return kFALSE;
  if(d0z0[1]<zmin) return kFALSE;
  //
  return kTRUE;
}
 AliGenFunction.cxx:1
 AliGenFunction.cxx:2
 AliGenFunction.cxx:3
 AliGenFunction.cxx:4
 AliGenFunction.cxx:5
 AliGenFunction.cxx:6
 AliGenFunction.cxx:7
 AliGenFunction.cxx:8
 AliGenFunction.cxx:9
 AliGenFunction.cxx:10
 AliGenFunction.cxx:11
 AliGenFunction.cxx:12
 AliGenFunction.cxx:13
 AliGenFunction.cxx:14
 AliGenFunction.cxx:15
 AliGenFunction.cxx:16
 AliGenFunction.cxx:17
 AliGenFunction.cxx:18
 AliGenFunction.cxx:19
 AliGenFunction.cxx:20
 AliGenFunction.cxx:21
 AliGenFunction.cxx:22
 AliGenFunction.cxx:23
 AliGenFunction.cxx:24
 AliGenFunction.cxx:25
 AliGenFunction.cxx:26
 AliGenFunction.cxx:27
 AliGenFunction.cxx:28
 AliGenFunction.cxx:29
 AliGenFunction.cxx:30
 AliGenFunction.cxx:31
 AliGenFunction.cxx:32
 AliGenFunction.cxx:33
 AliGenFunction.cxx:34
 AliGenFunction.cxx:35
 AliGenFunction.cxx:36
 AliGenFunction.cxx:37
 AliGenFunction.cxx:38
 AliGenFunction.cxx:39
 AliGenFunction.cxx:40
 AliGenFunction.cxx:41
 AliGenFunction.cxx:42
 AliGenFunction.cxx:43
 AliGenFunction.cxx:44
 AliGenFunction.cxx:45
 AliGenFunction.cxx:46
 AliGenFunction.cxx:47
 AliGenFunction.cxx:48
 AliGenFunction.cxx:49
 AliGenFunction.cxx:50
 AliGenFunction.cxx:51
 AliGenFunction.cxx:52
 AliGenFunction.cxx:53
 AliGenFunction.cxx:54
 AliGenFunction.cxx:55
 AliGenFunction.cxx:56
 AliGenFunction.cxx:57
 AliGenFunction.cxx:58
 AliGenFunction.cxx:59
 AliGenFunction.cxx:60
 AliGenFunction.cxx:61
 AliGenFunction.cxx:62
 AliGenFunction.cxx:63
 AliGenFunction.cxx:64
 AliGenFunction.cxx:65
 AliGenFunction.cxx:66
 AliGenFunction.cxx:67
 AliGenFunction.cxx:68
 AliGenFunction.cxx:69
 AliGenFunction.cxx:70
 AliGenFunction.cxx:71
 AliGenFunction.cxx:72
 AliGenFunction.cxx:73
 AliGenFunction.cxx:74
 AliGenFunction.cxx:75
 AliGenFunction.cxx:76
 AliGenFunction.cxx:77
 AliGenFunction.cxx:78
 AliGenFunction.cxx:79
 AliGenFunction.cxx:80
 AliGenFunction.cxx:81
 AliGenFunction.cxx:82
 AliGenFunction.cxx:83
 AliGenFunction.cxx:84
 AliGenFunction.cxx:85
 AliGenFunction.cxx:86
 AliGenFunction.cxx:87
 AliGenFunction.cxx:88
 AliGenFunction.cxx:89
 AliGenFunction.cxx:90
 AliGenFunction.cxx:91
 AliGenFunction.cxx:92
 AliGenFunction.cxx:93
 AliGenFunction.cxx:94
 AliGenFunction.cxx:95
 AliGenFunction.cxx:96
 AliGenFunction.cxx:97
 AliGenFunction.cxx:98
 AliGenFunction.cxx:99
 AliGenFunction.cxx:100
 AliGenFunction.cxx:101
 AliGenFunction.cxx:102
 AliGenFunction.cxx:103
 AliGenFunction.cxx:104
 AliGenFunction.cxx:105
 AliGenFunction.cxx:106
 AliGenFunction.cxx:107
 AliGenFunction.cxx:108
 AliGenFunction.cxx:109
 AliGenFunction.cxx:110
 AliGenFunction.cxx:111
 AliGenFunction.cxx:112
 AliGenFunction.cxx:113
 AliGenFunction.cxx:114
 AliGenFunction.cxx:115
 AliGenFunction.cxx:116
 AliGenFunction.cxx:117
 AliGenFunction.cxx:118
 AliGenFunction.cxx:119
 AliGenFunction.cxx:120
 AliGenFunction.cxx:121
 AliGenFunction.cxx:122
 AliGenFunction.cxx:123
 AliGenFunction.cxx:124
 AliGenFunction.cxx:125
 AliGenFunction.cxx:126
 AliGenFunction.cxx:127
 AliGenFunction.cxx:128
 AliGenFunction.cxx:129
 AliGenFunction.cxx:130
 AliGenFunction.cxx:131
 AliGenFunction.cxx:132
 AliGenFunction.cxx:133
 AliGenFunction.cxx:134
 AliGenFunction.cxx:135
 AliGenFunction.cxx:136
 AliGenFunction.cxx:137
 AliGenFunction.cxx:138
 AliGenFunction.cxx:139
 AliGenFunction.cxx:140
 AliGenFunction.cxx:141
 AliGenFunction.cxx:142
 AliGenFunction.cxx:143
 AliGenFunction.cxx:144
 AliGenFunction.cxx:145
 AliGenFunction.cxx:146
 AliGenFunction.cxx:147
 AliGenFunction.cxx:148
 AliGenFunction.cxx:149
 AliGenFunction.cxx:150
 AliGenFunction.cxx:151
 AliGenFunction.cxx:152
 AliGenFunction.cxx:153
 AliGenFunction.cxx:154
 AliGenFunction.cxx:155
 AliGenFunction.cxx:156
 AliGenFunction.cxx:157
 AliGenFunction.cxx:158
 AliGenFunction.cxx:159
 AliGenFunction.cxx:160
 AliGenFunction.cxx:161
 AliGenFunction.cxx:162
 AliGenFunction.cxx:163
 AliGenFunction.cxx:164
 AliGenFunction.cxx:165
 AliGenFunction.cxx:166
 AliGenFunction.cxx:167
 AliGenFunction.cxx:168
 AliGenFunction.cxx:169
 AliGenFunction.cxx:170
 AliGenFunction.cxx:171
 AliGenFunction.cxx:172
 AliGenFunction.cxx:173
 AliGenFunction.cxx:174
 AliGenFunction.cxx:175
 AliGenFunction.cxx:176
 AliGenFunction.cxx:177
 AliGenFunction.cxx:178
 AliGenFunction.cxx:179
 AliGenFunction.cxx:180
 AliGenFunction.cxx:181
 AliGenFunction.cxx:182
 AliGenFunction.cxx:183
 AliGenFunction.cxx:184
 AliGenFunction.cxx:185
 AliGenFunction.cxx:186
 AliGenFunction.cxx:187
 AliGenFunction.cxx:188
 AliGenFunction.cxx:189
 AliGenFunction.cxx:190
 AliGenFunction.cxx:191
 AliGenFunction.cxx:192
 AliGenFunction.cxx:193
 AliGenFunction.cxx:194
 AliGenFunction.cxx:195
 AliGenFunction.cxx:196
 AliGenFunction.cxx:197
 AliGenFunction.cxx:198
 AliGenFunction.cxx:199
 AliGenFunction.cxx:200
 AliGenFunction.cxx:201
 AliGenFunction.cxx:202
 AliGenFunction.cxx:203
 AliGenFunction.cxx:204
 AliGenFunction.cxx:205
 AliGenFunction.cxx:206
 AliGenFunction.cxx:207
 AliGenFunction.cxx:208
 AliGenFunction.cxx:209
 AliGenFunction.cxx:210
 AliGenFunction.cxx:211
 AliGenFunction.cxx:212
 AliGenFunction.cxx:213
 AliGenFunction.cxx:214
 AliGenFunction.cxx:215
 AliGenFunction.cxx:216
 AliGenFunction.cxx:217
 AliGenFunction.cxx:218
 AliGenFunction.cxx:219
 AliGenFunction.cxx:220
 AliGenFunction.cxx:221
 AliGenFunction.cxx:222
 AliGenFunction.cxx:223
 AliGenFunction.cxx:224
 AliGenFunction.cxx:225
 AliGenFunction.cxx:226
 AliGenFunction.cxx:227
 AliGenFunction.cxx:228
 AliGenFunction.cxx:229
 AliGenFunction.cxx:230
 AliGenFunction.cxx:231
 AliGenFunction.cxx:232
 AliGenFunction.cxx:233
 AliGenFunction.cxx:234
 AliGenFunction.cxx:235
 AliGenFunction.cxx:236
 AliGenFunction.cxx:237
 AliGenFunction.cxx:238
 AliGenFunction.cxx:239
 AliGenFunction.cxx:240
 AliGenFunction.cxx:241
 AliGenFunction.cxx:242
 AliGenFunction.cxx:243
 AliGenFunction.cxx:244
 AliGenFunction.cxx:245