ROOT logo
/**************************************************************************
 * Copyright(c) 1998-1999, 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.                  *
 **************************************************************************/
   
/* $Id$ */
//---------------------------------------------------------------------
// Event shape utility class
// Circularity, Thrust, ... 
// Authors: Antonio Ortiz Velasquez <Antonio.Ortiz.Velasquez@cern.ch>
//          
//---------------------------------------------------------------------


#include "AliEventShape.h"

#include "AliStack.h"
#include "AliLog.h"
#include "AliMCEventHandler.h"
#include "AliMCEvent.h"

#include <TMatrixDSym.h>
#include <TVectorD.h>
#include <TMatrixDSymEigen.h>
#include <TParticle.h>
#include <TParticlePDG.h>




//____________________________________________________________________
ClassImp(AliEventShape)

//___________________________________________________________________
TArrayD * AliEventShape::GetThrustParamMC(AliMCEvent* mcEvent, Int_t  nstudymin, Double_t ptcutoff, Double_t etacutoff, Bool_t chom)
{
  /*
    This function returns an array of values of thrust. To get these values you have to do:
    TArrayD* eventshapes = 0;
    eventshapes = AliShapeEvent::GetThrustParamMC(mcEvent, 3, 1, 1, kFALSE);
    Double_t thrust=eventshapes->GetAt(0);
    Double_t thrustmin=eventshapes->GetAt(1);
    Double_t recoil=eventshapes->GetAt(2);  
    The calculus uses  primary  particles. The input parameters:
    1. nstudymin, is the minumum number of particles which you want that participate in the calculus.(default:nstudymin =3)
    2. ptcutoff, is the cut in pt applied to participants to calculate the variables.(default: ptcutoff=1)
    3. etacutoff, is the cut in acceptance applied to participants to calculate the variables.(default: etacutoff=1)
    4. if chom=kTRUE, then the calculus includes neutral particles (rejecting photons and neutrinos).
       if chom=kFALSE, then the calculus includes only charged particles (rejecting photons and neutrinos).
       Returned values: thrust->0: 2-jet event, thrust->0.5: isotropic event
       Recoil is a term which is sensitive to radiation outside from acceptance, 1>=recoil>=0,
       thrustmin, is a measure of the radiation which is perpendicular to the plane formed by beam axis and thrust axis, 2/TMath::Pi()>thrustmin>0. In the limit of 2 back-to-back jets thrusmin->0, while in the case of a uniformly distributed event thrustmin->2/TMath::Pi();
  */
  
  AliStack* stack = 0;

  stack = mcEvent->Stack();
  Double_t * ptT = 0;
  Double_t * pxT = 0;
  Double_t * pyT = 0;
  Double_t ptsuma = 0;
  Double_t pxsuma = 0;
  Double_t pysuma = 0;

  TArrayD* evsh = new TArrayD(3);  
  Int_t nPrim  = stack->GetNprimary();
  Int_t  nmctracks = 0;  
  for (Int_t iMCTracks = 0; iMCTracks < nPrim; iMCTracks++) {    
      TParticle* trackmc = stack->Particle(iMCTracks);
      if (!trackmc) continue;
      Double_t etamc =trackmc ->Eta();
      Double_t ptmc=trackmc->Pt();
      Int_t pdgCode = TMath::Abs(trackmc->GetPdgCode());
      if (TMath::Abs(etamc) > etacutoff) continue; //only particles in |eta|<=etacutoff
      if(ptmc < ptcutoff) continue;  // PT cut
      Bool_t isprimary = stack->IsPhysicalPrimary(iMCTracks);    // Check if particle is charged, and primary
      if(isprimary == 0) continue;  // only primary particles
      TParticlePDG* pdgPart =trackmc ->GetPDG();
      if(chom == 1){//include neutral particles
	  // skip photons and neutrinos
	  if (pdgCode == 22 || pdgCode == 12 || pdgCode == 14 || pdgCode == 16) continue;
	  nmctracks++;  
      }
      else{ //only charged particles
	  if (pdgPart->Charge() == 0)continue;
	  nmctracks++;     
      }
  }
  // Minimum number of particles used in the analysis
  if(nmctracks < nstudymin){
      evsh->AddAt(-2,0);
      evsh->AddAt(-2,1);
      evsh->AddAt(-2,2);
      return evsh;
  }
  
  Int_t j=0;
  pxT = new Double_t[nmctracks];
  pyT = new Double_t[nmctracks];
  ptT = new Double_t[nmctracks];
  for (Int_t i = 0; i < nmctracks; i++)
    {
      pxT[i] = 0;
      pyT[i] = 0;
      ptT[i] = 0;
    }
  for (Int_t iMCTracks = 0; iMCTracks < nPrim; ++iMCTracks) {    
      TParticle* trackmc = stack->Particle(iMCTracks);
      if (!trackmc) continue;
      Double_t etamc = trackmc ->Eta();
      Double_t pxmc  = trackmc->Px();
      Double_t pymc  = trackmc->Py();
      Double_t ptmc  = trackmc->Pt();
      Int_t pdgCode  = TMath::Abs(trackmc->GetPdgCode());
      if (TMath::Abs(etamc) > etacutoff) continue;
      if(ptmc < ptcutoff) continue;
      Bool_t isprimary = stack->IsPhysicalPrimary(iMCTracks); 
      if(isprimary==0) continue;
      TParticlePDG* pdgPart =trackmc ->GetPDG();

      if(chom==1){
	  if (pdgCode == 22 || pdgCode == 12 || pdgCode == 14 || pdgCode == 16)continue;
      } else {
	  if (pdgPart->Charge() == 0) continue;
      }
      
      ptT[j] = ptmc;
      pxT[j] = pxmc;
      pyT[j] = pymc;
      ptsuma += ptmc;
      pxsuma+=pxmc;
      pysuma+=pymc;
      j++;    
  }

  Double_t numerador = 0;
  Double_t numerador2 = 0;
  Double_t phimax = -1;  
  Double_t pFull = -1;
  Double_t pMax = 0;
  Double_t phi = 0;
  Double_t thrust = 80;
  Double_t thrustminor = 80;
  Double_t nx = 0;
  Double_t ny = 0;
  Double_t phiparam = 0;
  //Getting thrust
  for(Int_t i = 0; i < 360; ++i){
      numerador = 0;
      phiparam  = 0;
      nx = 0;
      ny = 0;
      phiparam=((TMath::Pi()) * i) / 180; // parametrization of the angle
      nx = TMath::Cos(phiparam);            // x component of an unitary vector n
      ny = TMath::Sin(phiparam);            // y component of an unitary vector n
      for(Int_t i1 = 0; i1 < nmctracks; ++i1){
	  numerador += TMath::Abs(nx * pxT[i1] + ny * pyT[i1]);//product between momentum proyection in XY plane and the unitari vector.
      }
      pFull=numerador / ptsuma;
      if(pFull > pMax)//maximization of pFull
      {
	  pMax = pFull;
	  phi = phiparam;
      }
  }

  phimax=(phi * 180) / TMath::Pi();//angular parameter of the unitary vector which maximiza thrust
  //if n vector and beam axis form a plane, then we can calculate a second unitary vector perpendicular to that plane
  Double_t nx1 = TMath::Cos(phi);
  Double_t ny1 = TMath::Sin(phi);
  for(Int_t i2 =0; i2 < nmctracks; ++i2){
      numerador2 += TMath::Abs(pxT[i2] * ny1 - nx1 * pyT[i2]);//cross product: P_{i} X n, P_{i}=(px_{i},py_{i})
  }
  thrust = 1 - pMax;//this is the value of thrust
  thrustminor = numerador2 / ptsuma;//this is the value of thrust minor
  Double_t recoil = TMath::Abs(TMath::Sqrt(pxsuma * pxsuma + pysuma * pysuma)) / (ptsuma);//factor sentsitive to radiation outside from acceptance 

  evsh->AddAt(thrust, 0);
  evsh->AddAt(thrustminor, 1);
  evsh->AddAt(recoil, 2);


  delete [] ptT;
  delete [] pxT;
  delete [] pyT;

  return evsh;  
}


Double_t AliEventShape::GetCircularityMC(AliMCEvent* mcEvent, Int_t  nstudymin, Double_t ptcutoff, Double_t etacutoff, Bool_t chom)
{
  /*
    This function returns the circularity value of the event 

    The calculus uses  primary  particles. The input parameters:
    1. nstudymin, is the minumum number of particles which you want that participate in the calculus.(default:nstudymin =3)
    2. ptcutoff, is the cut in pt applied to participants to calculate the variables.(default: ptcutoff=1)
    3. etacutoff, is the cut in acceptance applied to participants to calculate the variables.(default: etacutoff=1)
    4. if chom=kTRUE, then the calculus includes neutral particles (rejecting photons and neutrinos).
       if chom=kFALSE, then the calculus includes only charged particles (rejecting photons and neutrinos).
       1>=circularity>=0
  */


  AliStack* stack = 0;

  stack = mcEvent->Stack();

  TMatrixDSym s(2);

  Double_t s00 =  0;
  Double_t s01 =  0;
  Double_t s10 =  0;
  Double_t s11 =  0;
  Double_t ptot = 0;
  Double_t circularity = -2;
  Int_t  nmctracks = 0;  
  Int_t nPrim  = stack->GetNprimary();

  for (Int_t iMCTracks = 0; iMCTracks < nPrim; ++iMCTracks) {
    TParticle* trackmc = stack->Particle(iMCTracks);
    if (!trackmc) continue;
    Double_t etamc = trackmc ->Eta();
    Double_t ptmc  = trackmc->Pt();
    Double_t pxmc  = trackmc->Px();
    Double_t pymc  = trackmc->Py();
    Int_t pdgCode = TMath::Abs(trackmc->GetPdgCode());
    if (TMath::Abs(etamc) > etacutoff) continue;
    if (ptmc < ptcutoff) continue;
    Bool_t isprimary = stack->IsPhysicalPrimary(iMCTracks);
    if (isprimary == 0) continue;
    TParticlePDG* pdgPart = trackmc ->GetPDG();
    if(chom == kTRUE){
      // skip photons and neutrinos
      if (pdgCode == 22 || pdgCode == 12 || pdgCode == 14 || pdgCode == 16) continue; 
    }
    else{
      if (pdgPart->Charge() == 0)continue;
    }

    ptot = ptot + (ptmc * ptmc);
    s00 = s00 + (pxmc * pxmc);
    s01 = s01 + (pxmc * pymc);
    s10 = s10 + (pymc * pxmc);
    s11 = s11 + (pymc * pymc); 
    nmctracks++;
  } //track loop 


  if (nmctracks < nstudymin) {
      Printf("Too few particles, stopping");
      return -2;
  }


  
  if(ptot != 0){
    s(0,0) = s00 / ptot;
    s(0,1) = s01 / ptot;
    s(1,0) = s10 / ptot;
    s(1,1) = s11 / ptot;
    const TMatrixDSymEigen eigen(s);
    const TVectorD eigenVal=eigen.GetEigenValues();
    circularity = 2 * (1 - eigenVal(0));
  }
  return circularity;
}
  
  































 AliEventShape.cxx:1
 AliEventShape.cxx:2
 AliEventShape.cxx:3
 AliEventShape.cxx:4
 AliEventShape.cxx:5
 AliEventShape.cxx:6
 AliEventShape.cxx:7
 AliEventShape.cxx:8
 AliEventShape.cxx:9
 AliEventShape.cxx:10
 AliEventShape.cxx:11
 AliEventShape.cxx:12
 AliEventShape.cxx:13
 AliEventShape.cxx:14
 AliEventShape.cxx:15
 AliEventShape.cxx:16
 AliEventShape.cxx:17
 AliEventShape.cxx:18
 AliEventShape.cxx:19
 AliEventShape.cxx:20
 AliEventShape.cxx:21
 AliEventShape.cxx:22
 AliEventShape.cxx:23
 AliEventShape.cxx:24
 AliEventShape.cxx:25
 AliEventShape.cxx:26
 AliEventShape.cxx:27
 AliEventShape.cxx:28
 AliEventShape.cxx:29
 AliEventShape.cxx:30
 AliEventShape.cxx:31
 AliEventShape.cxx:32
 AliEventShape.cxx:33
 AliEventShape.cxx:34
 AliEventShape.cxx:35
 AliEventShape.cxx:36
 AliEventShape.cxx:37
 AliEventShape.cxx:38
 AliEventShape.cxx:39
 AliEventShape.cxx:40
 AliEventShape.cxx:41
 AliEventShape.cxx:42
 AliEventShape.cxx:43
 AliEventShape.cxx:44
 AliEventShape.cxx:45
 AliEventShape.cxx:46
 AliEventShape.cxx:47
 AliEventShape.cxx:48
 AliEventShape.cxx:49
 AliEventShape.cxx:50
 AliEventShape.cxx:51
 AliEventShape.cxx:52
 AliEventShape.cxx:53
 AliEventShape.cxx:54
 AliEventShape.cxx:55
 AliEventShape.cxx:56
 AliEventShape.cxx:57
 AliEventShape.cxx:58
 AliEventShape.cxx:59
 AliEventShape.cxx:60
 AliEventShape.cxx:61
 AliEventShape.cxx:62
 AliEventShape.cxx:63
 AliEventShape.cxx:64
 AliEventShape.cxx:65
 AliEventShape.cxx:66
 AliEventShape.cxx:67
 AliEventShape.cxx:68
 AliEventShape.cxx:69
 AliEventShape.cxx:70
 AliEventShape.cxx:71
 AliEventShape.cxx:72
 AliEventShape.cxx:73
 AliEventShape.cxx:74
 AliEventShape.cxx:75
 AliEventShape.cxx:76
 AliEventShape.cxx:77
 AliEventShape.cxx:78
 AliEventShape.cxx:79
 AliEventShape.cxx:80
 AliEventShape.cxx:81
 AliEventShape.cxx:82
 AliEventShape.cxx:83
 AliEventShape.cxx:84
 AliEventShape.cxx:85
 AliEventShape.cxx:86
 AliEventShape.cxx:87
 AliEventShape.cxx:88
 AliEventShape.cxx:89
 AliEventShape.cxx:90
 AliEventShape.cxx:91
 AliEventShape.cxx:92
 AliEventShape.cxx:93
 AliEventShape.cxx:94
 AliEventShape.cxx:95
 AliEventShape.cxx:96
 AliEventShape.cxx:97
 AliEventShape.cxx:98
 AliEventShape.cxx:99
 AliEventShape.cxx:100
 AliEventShape.cxx:101
 AliEventShape.cxx:102
 AliEventShape.cxx:103
 AliEventShape.cxx:104
 AliEventShape.cxx:105
 AliEventShape.cxx:106
 AliEventShape.cxx:107
 AliEventShape.cxx:108
 AliEventShape.cxx:109
 AliEventShape.cxx:110
 AliEventShape.cxx:111
 AliEventShape.cxx:112
 AliEventShape.cxx:113
 AliEventShape.cxx:114
 AliEventShape.cxx:115
 AliEventShape.cxx:116
 AliEventShape.cxx:117
 AliEventShape.cxx:118
 AliEventShape.cxx:119
 AliEventShape.cxx:120
 AliEventShape.cxx:121
 AliEventShape.cxx:122
 AliEventShape.cxx:123
 AliEventShape.cxx:124
 AliEventShape.cxx:125
 AliEventShape.cxx:126
 AliEventShape.cxx:127
 AliEventShape.cxx:128
 AliEventShape.cxx:129
 AliEventShape.cxx:130
 AliEventShape.cxx:131
 AliEventShape.cxx:132
 AliEventShape.cxx:133
 AliEventShape.cxx:134
 AliEventShape.cxx:135
 AliEventShape.cxx:136
 AliEventShape.cxx:137
 AliEventShape.cxx:138
 AliEventShape.cxx:139
 AliEventShape.cxx:140
 AliEventShape.cxx:141
 AliEventShape.cxx:142
 AliEventShape.cxx:143
 AliEventShape.cxx:144
 AliEventShape.cxx:145
 AliEventShape.cxx:146
 AliEventShape.cxx:147
 AliEventShape.cxx:148
 AliEventShape.cxx:149
 AliEventShape.cxx:150
 AliEventShape.cxx:151
 AliEventShape.cxx:152
 AliEventShape.cxx:153
 AliEventShape.cxx:154
 AliEventShape.cxx:155
 AliEventShape.cxx:156
 AliEventShape.cxx:157
 AliEventShape.cxx:158
 AliEventShape.cxx:159
 AliEventShape.cxx:160
 AliEventShape.cxx:161
 AliEventShape.cxx:162
 AliEventShape.cxx:163
 AliEventShape.cxx:164
 AliEventShape.cxx:165
 AliEventShape.cxx:166
 AliEventShape.cxx:167
 AliEventShape.cxx:168
 AliEventShape.cxx:169
 AliEventShape.cxx:170
 AliEventShape.cxx:171
 AliEventShape.cxx:172
 AliEventShape.cxx:173
 AliEventShape.cxx:174
 AliEventShape.cxx:175
 AliEventShape.cxx:176
 AliEventShape.cxx:177
 AliEventShape.cxx:178
 AliEventShape.cxx:179
 AliEventShape.cxx:180
 AliEventShape.cxx:181
 AliEventShape.cxx:182
 AliEventShape.cxx:183
 AliEventShape.cxx:184
 AliEventShape.cxx:185
 AliEventShape.cxx:186
 AliEventShape.cxx:187
 AliEventShape.cxx:188
 AliEventShape.cxx:189
 AliEventShape.cxx:190
 AliEventShape.cxx:191
 AliEventShape.cxx:192
 AliEventShape.cxx:193
 AliEventShape.cxx:194
 AliEventShape.cxx:195
 AliEventShape.cxx:196
 AliEventShape.cxx:197
 AliEventShape.cxx:198
 AliEventShape.cxx:199
 AliEventShape.cxx:200
 AliEventShape.cxx:201
 AliEventShape.cxx:202
 AliEventShape.cxx:203
 AliEventShape.cxx:204
 AliEventShape.cxx:205
 AliEventShape.cxx:206
 AliEventShape.cxx:207
 AliEventShape.cxx:208
 AliEventShape.cxx:209
 AliEventShape.cxx:210
 AliEventShape.cxx:211
 AliEventShape.cxx:212
 AliEventShape.cxx:213
 AliEventShape.cxx:214
 AliEventShape.cxx:215
 AliEventShape.cxx:216
 AliEventShape.cxx:217
 AliEventShape.cxx:218
 AliEventShape.cxx:219
 AliEventShape.cxx:220
 AliEventShape.cxx:221
 AliEventShape.cxx:222
 AliEventShape.cxx:223
 AliEventShape.cxx:224
 AliEventShape.cxx:225
 AliEventShape.cxx:226
 AliEventShape.cxx:227
 AliEventShape.cxx:228
 AliEventShape.cxx:229
 AliEventShape.cxx:230
 AliEventShape.cxx:231
 AliEventShape.cxx:232
 AliEventShape.cxx:233
 AliEventShape.cxx:234
 AliEventShape.cxx:235
 AliEventShape.cxx:236
 AliEventShape.cxx:237
 AliEventShape.cxx:238
 AliEventShape.cxx:239
 AliEventShape.cxx:240
 AliEventShape.cxx:241
 AliEventShape.cxx:242
 AliEventShape.cxx:243
 AliEventShape.cxx:244
 AliEventShape.cxx:245
 AliEventShape.cxx:246
 AliEventShape.cxx:247
 AliEventShape.cxx:248
 AliEventShape.cxx:249
 AliEventShape.cxx:250
 AliEventShape.cxx:251
 AliEventShape.cxx:252
 AliEventShape.cxx:253
 AliEventShape.cxx:254
 AliEventShape.cxx:255
 AliEventShape.cxx:256
 AliEventShape.cxx:257
 AliEventShape.cxx:258
 AliEventShape.cxx:259
 AliEventShape.cxx:260
 AliEventShape.cxx:261
 AliEventShape.cxx:262
 AliEventShape.cxx:263
 AliEventShape.cxx:264
 AliEventShape.cxx:265
 AliEventShape.cxx:266
 AliEventShape.cxx:267
 AliEventShape.cxx:268
 AliEventShape.cxx:269
 AliEventShape.cxx:270
 AliEventShape.cxx:271
 AliEventShape.cxx:272
 AliEventShape.cxx:273
 AliEventShape.cxx:274
 AliEventShape.cxx:275
 AliEventShape.cxx:276
 AliEventShape.cxx:277
 AliEventShape.cxx:278
 AliEventShape.cxx:279
 AliEventShape.cxx:280
 AliEventShape.cxx:281
 AliEventShape.cxx:282
 AliEventShape.cxx:283
 AliEventShape.cxx:284
 AliEventShape.cxx:285
 AliEventShape.cxx:286
 AliEventShape.cxx:287
 AliEventShape.cxx:288
 AliEventShape.cxx:289
 AliEventShape.cxx:290
 AliEventShape.cxx:291
 AliEventShape.cxx:292
 AliEventShape.cxx:293
 AliEventShape.cxx:294
 AliEventShape.cxx:295
 AliEventShape.cxx:296
 AliEventShape.cxx:297
 AliEventShape.cxx:298
 AliEventShape.cxx:299
 AliEventShape.cxx:300
 AliEventShape.cxx:301
 AliEventShape.cxx:302
 AliEventShape.cxx:303
 AliEventShape.cxx:304
 AliEventShape.cxx:305
 AliEventShape.cxx:306
 AliEventShape.cxx:307
 AliEventShape.cxx:308
 AliEventShape.cxx:309
 AliEventShape.cxx:310
 AliEventShape.cxx:311