LCOV - code coverage report
Current view: top level - ZDC/ZDCsim - AliZDCFragment.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 144 0.7 %
Date: 2016-06-14 17:26:59 Functions: 1 9 11.1 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       7             :  * Permission to use, copy, modify and distribute this software and its   *
       8             :  * documentation strictly for non-commercial purposes is hereby granted   *
       9             :  * without fee, provided that the above copyright notice appears in all   *
      10             :  * copies and that both the copyright notice and this permission notice   *
      11             :  * appear in the supporting documentation. The authors make no claims     *
      12             :  * about the suitability of this software for any purpose. It is          *
      13             :  * provided "as is" without express or implied warranty.                  *
      14             :  **************************************************************************/
      15             : 
      16             : 
      17             : // ******************************************************************
      18             : //
      19             : //      Class for nuclear fragments formation
      20             : //
      21             : // ******************************************************************
      22             : 
      23             : // --- Standard libraries
      24             : #include <stdlib.h>
      25             : 
      26             : // --- ROOT system
      27             : #include <TRandom.h>
      28             : #include <TF1.h>
      29             : 
      30             : // --- AliRoot classes
      31             : #include "AliZDCFragment.h"
      32             :  
      33          12 : ClassImp(AliZDCFragment)
      34             :    
      35           0 : int comp(const void *i,const void *j) {return *(int *)i - *(int *)j;}
      36             : 
      37             : 
      38             : //_____________________________________________________________________________
      39           0 : AliZDCFragment::AliZDCFragment():
      40           0 :   fB(0),
      41           0 :   fZbAverage(0),
      42           0 :   fNimf(0),
      43           0 :   fZmax(0),
      44           0 :   fTau(0),
      45           0 :   fNalpha(0),
      46           0 :   fZtot(0),
      47           0 :   fNtot(0)
      48           0 : {
      49             :   //
      50             :   // Default constructor
      51             :   //
      52           0 :   for(Int_t i=0; i<=99; i++){
      53           0 :      fZZ[i] = 0;
      54           0 :      fNN[i] = 0;
      55             :   }
      56           0 : }
      57             : 
      58             : //_____________________________________________________________________________
      59             : AliZDCFragment::AliZDCFragment(Float_t b): 
      60           0 :   TNamed(" "," "),
      61           0 :   fB(b),
      62           0 :   fZbAverage(0),
      63           0 :   fNimf(0),
      64           0 :   fZmax(0),
      65           0 :   fTau(0),
      66           0 :   fNalpha(0),
      67           0 :   fZtot(0),
      68           0 :   fNtot(0)
      69           0 : {
      70             :   //
      71             :   // Standard constructor
      72             :   //
      73           0 :   for(Int_t i=0; i<=99; i++){
      74           0 :      fZZ[i] = 0;
      75           0 :      fNN[i] = 0;
      76             :   }
      77             :   
      78           0 : }
      79             : 
      80             : //_____________________________________________________________________________
      81             : void AliZDCFragment::GenerateIMF()
      82             : {
      83             : 
      84             :    // Loop variables
      85             :   Int_t i,j;
      86             : 
      87             :    // Coefficients of polynomial for average number of IMF
      88             :    const Float_t  kParamNimf[5]={0.011236,1.8364,56.572,-116.24,58.289}; 
      89             :    // Coefficients of polynomial for fluctuations on average number of IMF
      90             :    const Float_t  kParamFluctNimf[4]={-0.13176,2.9392,-5.2147,2.3092}; 
      91             :    // Coefficients of polynomial for average maximum Z of fragments
      92             :    //const Float_t  kParamZmax[4]={0.16899,14.203,-2.8284,65.036}; 
      93             :    const Float_t  kParamZmax[4]={0.16899,14.203,-2.8284,70.5}; 
      94             :    // Coefficients of polynomial for fluctuations on maximum Z of fragments
      95             :    const Float_t  kParamFluctZmax[5]={0.013782,-0.17282,1.5065,1.0654,-2.4317}; 
      96             :    // Coefficients of polynomial for exponent tau of fragments Z distribution
      97             :    const Float_t  kParamTau[3]={6.7233,-15.85,13.047};  
      98             :    //Coefficients of polynomial for average number of alphas
      99             :    const Float_t  kParamNalpha[4]={-0.68554,39.605,-68.311,30.165}; 
     100             :    // Coefficients of polynomial for fluctuations on average number of alphas
     101             :    const Float_t  kParamFluctNalpha[5]={0.283,6.2141,-17.113,17.394,-6.6084}; 
     102             :    // Coefficients of function for Pb nucleus skin
     103             :    const Float_t  kParamSkinPb[2]={0.762408, 20.};
     104             :    
     105             :    // Thickness of nuclear surface
     106             :    //const Float_t  kNuclearThick = 0.52;
     107             :    // Maximum impact parameter for U [r0*A**(1/3)]
     108             :    const Float_t  kbMaxU = 14.87;
     109             :    // Maximum impact parameter for Pb [r0*A**(1/3)]
     110             :    //const Float_t  kbMaxPb = 14.22+4*kNuclearThick;
     111             :    const Float_t  kbMaxPb = 14.22;
     112             :    // Z of the projectile
     113             :    const Float_t  kZProj = 82.;
     114             :    
     115             :    // From b(Pb) to b(U)
     116           0 :    if(fB>kbMaxPb) fB = 2*kbMaxPb-fB;
     117             :    
     118           0 :    Float_t  bU = fB*kbMaxU/kbMaxPb;
     119             :     
     120             :    // From b(U) to Zbound(U) 
     121             :    // --- A.Schuttauf et al, Nuc.Phys. A607 (1996) 457 ---------------
     122             :    // From geometrical consideration and from dsigma/dZbound for U+U,
     123             :    // which is approx. constant, the constant value is found  
     124             :    // integrating the nucleus cross surface from 0 to bmax=R1+R2 where 
     125             :    // R = 1.2*A**(1/3). This value has been measured in Aladin (U+U).
     126           0 :    Float_t  zbU = bU*bU*TMath::Pi()/7.48;
     127             :    
     128             :    //  Rescale Zbound for Pb
     129           0 :    fZbAverage = kZProj/92.*zbU;
     130             :    
     131             :    // Zbound is proportional to b**2 up to b < kbMaxPb-2*kNuclearThick
     132             :    // and then it is an increasing exponential, imposing that at 
     133             :    // b=kbMaxPb-2kNuclearThick the two functions have the same derivative
     134             :    //Float_t bCore = kbMaxPb-2*kNuclearThick;
     135           0 :    if(fB>kbMaxPb){
     136           0 :      fZbAverage = TMath::Exp(-kParamSkinPb[0]*(fB-kParamSkinPb[1]));
     137             :      //printf(" b = %1.2f fm   Z_bound %1.2f\n", fB, fZbAverage);
     138           0 :    }
     139           0 :    if(fZbAverage>kZProj) fZbAverage = kZProj;
     140           0 :    Float_t zbNorm = fZbAverage/kZProj;
     141           0 :    Float_t bNorm = fB/kbMaxPb;
     142             :    
     143             :    // From Zbound to <Nimf>,<Zmax>,tau
     144             :    // Polinomial fits to Aladin distribution
     145             :    // --- A.Schuttauf et al, Nuc.Phys. A607 (1996) 457.
     146           0 :    Float_t averageNimf = kParamNimf[0]+kParamNimf[1]*zbNorm+kParamNimf[2]*
     147           0 :            TMath::Power(zbNorm,2)+kParamNimf[3]*TMath::Power(zbNorm,3)+
     148           0 :            kParamNimf[4]*TMath::Power(zbNorm,4);
     149             :    
     150             :    // Add fluctuation: from Singh et al. 
     151           0 :    Float_t fluctNimf = kParamFluctNimf[0]+kParamFluctNimf[1]*zbNorm+
     152           0 :            kParamFluctNimf[2]*TMath::Power(zbNorm,2)+kParamFluctNimf[3]
     153           0 :            *TMath::Power(zbNorm,3);
     154           0 :    Float_t xx = gRandom->Gaus(0.0,1.0);
     155           0 :    fluctNimf = fluctNimf*xx;
     156           0 :    fNimf = Int_t(averageNimf+fluctNimf);
     157           0 :    Float_t y = gRandom->Rndm();
     158           0 :    if(y < ((averageNimf+fluctNimf)-fNimf)) fNimf += 1;
     159           0 :    if(fNimf ==0 && zbNorm>0.75) fNimf = 1;
     160             :    
     161           0 :    Float_t averageZmax = kParamZmax[0]+kParamZmax[1]*zbNorm+kParamZmax[2]*
     162           0 :            TMath::Power(zbNorm,2)+kParamZmax[3]*TMath::Power(zbNorm,3);
     163           0 :    fTau = kParamTau[0]+kParamTau[1]*zbNorm+kParamTau[2]*TMath::Power(zbNorm,2);
     164             :    
     165             :    // Add fluctuation to mean value of Zmax (see Hubele)
     166           0 :    Float_t fluctZmax = kParamFluctZmax[0]+kParamFluctZmax[1]*zbNorm+
     167           0 :            kParamFluctZmax[2]*TMath::Power(zbNorm,2)+kParamFluctZmax[3]*
     168           0 :            TMath::Power(zbNorm,3)+kParamFluctZmax[4]*TMath::Power(zbNorm,4);
     169           0 :    fluctZmax = fluctZmax*kZProj/6.;
     170           0 :    Float_t xg = gRandom->Gaus(0.0,1.0);
     171           0 :    fluctZmax = fluctZmax*xg;
     172           0 :    fZmax = (averageZmax+fluctZmax);
     173           0 :    if(fZmax>kZProj) fZmax = kZProj;
     174             :    
     175             : //   printf("\n\n ------------------------------------------------------------");   
     176             : //   printf("\n Generation of nuclear fragments\n");   
     177             : //   printf("\n fNimf = %d\n", fNimf);   
     178             : //   printf("\n fZmax = %f\n", fZmax); 
     179             : 
     180             :    // Find the number of alpha particles 
     181             :    // from Singh et al. : Pb+emulsion
     182           0 :    Float_t averageAlpha = kParamNalpha[0]+kParamNalpha[1]*zbNorm+
     183           0 :            kParamNalpha[2]*TMath::Power(zbNorm,2)+kParamNalpha[3]*
     184           0 :            TMath::Power(zbNorm,3);
     185           0 :    Float_t fluctAlpha = kParamFluctNalpha[0]+kParamFluctNalpha[1]*
     186           0 :            zbNorm+kParamFluctNalpha[2]*TMath::Power(zbNorm,2)+
     187           0 :            kParamFluctNalpha[3]*TMath::Power(zbNorm,3)+
     188           0 :            kParamFluctNalpha[4]*TMath::Power(zbNorm,4);
     189           0 :    Float_t xxx = gRandom->Gaus(0.0,1.0);
     190           0 :    fluctAlpha = fluctAlpha*xxx;
     191           0 :    fNalpha = Int_t(averageAlpha+fluctAlpha);
     192           0 :    Float_t yy = gRandom->Rndm();
     193           0 :    if(yy < ((averageAlpha+fluctAlpha)-fNalpha)) fNalpha += 1;
     194             : 
     195             :    // 2 possibilities:
     196             :    // 1) for bNorm < 0.9 ==> first remove alphas, then fragments
     197             :    // 2) for bNorm > 0.9 ==> first remove fragments, then alphas
     198             : 
     199             :    Int_t choice = 0;
     200             :    Float_t zbFrag = 0, sumZ = 0.;
     201             : 
     202           0 :    if(bNorm<=0.9) {
     203             :    // remove alpha from zbound to find zbound for fragments  (Z>=3)
     204           0 :      zbFrag = fZbAverage-fNalpha*2;
     205             :      choice = 1;
     206           0 :    }
     207             :    else {
     208             :      zbFrag = fZbAverage;
     209             :      choice = 0;
     210             :    }
     211             : //   printf("\n choice = %d, fZbAverage = %f, zbFrag = %f \n", choice, fZbAverage, zbFrag);
     212             :    
     213             :    
     214             :    // Check if zbFrag < fZmax
     215           0 :    if(zbFrag<=fZmax) {
     216           0 :      if(fNimf>0 && zbFrag>=2){
     217           0 :        fNimf = 1;
     218           0 :        fZZ[0] = Int_t(zbFrag);
     219             :        sumZ = zbFrag;
     220           0 :      }
     221             :      else {
     222           0 :        fNimf = 0;
     223             :      }
     224           0 :      return;
     225             :    }
     226             :    
     227             :    // Prepare the exponential charge distribution dN/dZ
     228           0 :    if(fZmax <= 0.01) {
     229           0 :      fNimf = 0;
     230           0 :      return;
     231             :    }
     232           0 :    if(fNimf == 0) {
     233           0 :      fNimf = 0;
     234           0 :      return;
     235             :    }
     236             :    
     237           0 :    TF1 *funTau = new TF1("funTau","1./(x**[0])",0.01,fZmax);
     238           0 :    funTau->SetParameter(0,fTau);
     239             : 
     240             :    // Extract randomly the charge of the fragments from the distribution
     241             :  
     242           0 :    Float_t * zz = new Float_t[fNimf];
     243           0 :    for(j=0; j<fNimf; j++){
     244           0 :       zz[j] =0;
     245             :    }
     246           0 :    for(i=0; i<fNimf; i++){
     247           0 :       zz[i] = Float_t(funTau->GetRandom());
     248             : //      printf("\n zz[%d] = %f \n",i,zz[i]);
     249             :    }
     250           0 :    delete funTau;
     251             :    
     252             :    // Sorting vector in ascending order with C function QSORT 
     253           0 :    qsort((void*)zz,fNimf,sizeof(Float_t),comp);
     254             : 
     255             :    
     256             : //   for(Int_t i=0; i<fNimf; i++){
     257             : //      printf("\n After sorting -> zz[%d] = %f \n",i,zz[i]);
     258             : //   }
     259             :    
     260             :    // Rescale the maximum charge to fZmax
     261           0 :    for(j=0; j<fNimf; j++){
     262           0 :      fZZ[j] = Int_t (zz[j]*fZmax/zz[fNimf-1]);
     263           0 :      if(fZZ[j]<3) fZZ[j] = 3;
     264             : //     printf("\n  fZZ[%d] = %d \n",j,fZZ[j]);
     265             :    }
     266             : 
     267           0 :    delete[] zz;
     268             :    
     269             :    // Check that the sum of the bound charges is not > than Zbound-Zalfa
     270             :    
     271           0 :    for(Int_t ii=0; ii<fNimf; ii++){
     272           0 :      sumZ += fZZ[ii];
     273             :    }
     274             :    
     275             :    Int_t k = 0;
     276           0 :    if(sumZ>zbFrag){
     277           0 :      for(i=0; i< fNimf; i++){
     278           0 :        k += 1;
     279           0 :        sumZ -= fZZ[i];
     280           0 :        if(sumZ<=zbFrag){
     281           0 :          fNimf -= (i+1);
     282           0 :          break;
     283             :        }
     284             :      }
     285             :    }
     286             :    else {
     287           0 :      if(choice == 1) return;
     288           0 :      Int_t iDiff = Int_t((zbFrag-sumZ)/2);
     289           0 :      if(iDiff<fNalpha){
     290           0 :        fNalpha=iDiff;
     291           0 :        return;
     292             :      }
     293             :      else{
     294           0 :        return;
     295             :      }
     296             :    }
     297             : 
     298           0 :    fNimf += k;
     299           0 :    for(i=0; i<fNimf; i++){
     300           0 :      fZZ[i] = fZZ[i+k];
     301             :    }
     302           0 :    fNimf -= k;
     303             :    
     304             :    sumZ=0;
     305           0 :    for(i=0; i<fNimf; i++){
     306           0 :      sumZ += fZZ[i];
     307             :    }
     308             :    
     309           0 : }
     310             : 
     311             : //_____________________________________________________________________________
     312             : void AliZDCFragment::AttachNeutrons()
     313             : {
     314             : //
     315             : // Prepare nuclear fragment by attaching a suitable number of neutrons
     316             : //
     317             :    const Float_t kAIon[68]={1.87612,2.80943,3.7284,5.60305,6.53536,
     318             :                      6.53622,8.39479,9.32699,10.2551,11.17793,
     319             :                      13.04378,14.89917,17.6969,18.62284,21.41483,
     320             :                      22.34193,25.13314,26.06034,28.85188,29.7818,
     321             :                      32.57328,33.50356,36.29447,37.22492,41.87617,
     322             :                      44.66324,47.45401,48.38228,51.17447,52.10307,
     323             :                      54.89593,53.96644,58.61856,59.54963,68.85715,
     324             :                      74.44178,78.16309,81.88358,83.74571,91.19832,
     325             :                      98.64997,106.10997,111.68821,122.86796,
     326             :                      128.45793,
     327             :                      130.32111,141.51236,
     328             :                      141.55,146.477,148.033,152.699,153.631,
     329             :                      155.802,157.357,162.022,162.984,166.2624,
     330             :                      168.554,171.349,173.4536,177.198,179.0518,
     331             :                      180.675,183.473,188.1345,190.77,193.729,
     332             :                      221.74295};
     333             :    const Int_t kZIon[68]={1,1,2,3,3,
     334             :                      4,4,5,5,6,
     335             :                      7,8,9,10,11,
     336             :                      12,13,14,15,16,
     337             :                      17,18,19,20,21,
     338             :                      22,23,24,25,26,
     339             :                      27,28,29,30,32,
     340             :                      34,36,38,40,42,
     341             :                      46,48,50,54,56,
     342             :                      58,62,
     343             :                      63,64,65,66,67,
     344             :                      68,69,70,71,72,
     345             :                      73,74,75,76,77,
     346             :                      78,79,80,81,82,
     347             :                      92};
     348             :     
     349             :    Int_t iZ, iA;  
     350             : //   printf("\n fNimf=%d\n",fNimf);  
     351             : 
     352           0 :    for(Int_t i=0; i<fNimf; i++) {
     353           0 :       for(Int_t j=0; j<68; j++) {
     354           0 :         iZ = kZIon[j];
     355           0 :         if((fZZ[i]-iZ) == 0){
     356           0 :           iA = Int_t(kAIon[j]/0.93149432+0.5);
     357           0 :           fNN[i] = iA - iZ;
     358           0 :           break;
     359             :         }
     360           0 :         else if((fZZ[i]-iZ) < 0){
     361           0 :           fZZ[i] = kZIon[j-1];
     362           0 :           iA = Int_t (kAIon[j-1]/0.93149432+0.5);
     363           0 :           fNN[i] = iA - kZIon[j-1];
     364           0 :           break;
     365             :         }
     366             :       }
     367           0 :       fZtot += fZZ[i];
     368           0 :       fNtot += fNN[i];
     369             :    }                 
     370             :    
     371             : 
     372           0 : }
     373             : 
     374             : //_____________________________________________________________________________
     375             : Float_t AliZDCFragment::DeuteronNumber()
     376             : {
     377             :     // Calculates the fraction of deuterum nucleus produced
     378             :     //
     379             :     Float_t deuteronProdPar[2] = {-0.068,0.0385};
     380           0 :     Float_t deutNum = deuteronProdPar[0] + deuteronProdPar[1]*fB;
     381           0 :     if(deutNum<0.) deutNum = 0.;
     382           0 :     return deutNum;
     383             : }

Generated by: LCOV version 1.11