//////////////////////////////////////////////////////////////////////////
// //
// ATLFParticle //
// //
// Graphics interface to event generators particle //
//////////////////////////////////////////////////////////////////////////
#include <TROOT.h>
#include "TMCParticle.h"
#include "TClonesArray.h"
#include "TPolyLine3D.h"
#include "TCanvas.h"
#include <TList.h>
#include <TMath.h>
#include "ATLFParticle.h"
#include "ATLFMCMaker.h"
#include "ATLFast.h"
#include "ATLFDisplay.h"
const Int_t kRECONS = BIT(16);
ClassImp(ATLFParticle)
//_____________________________________________________________________________
ATLFParticle::ATLFParticle(const char * name) :TNamed(name,name)
{
// Create list to support list of particles
m_Particles = new TList();
m_Display = (ATLFDisplay*)gATLFast->Display();
}
//_____________________________________________________________________________
ATLFParticle::~ATLFParticle()
{
if (m_Particles) m_Particles->Delete();
delete m_Particles;
}
//_____________________________________________________________________________
void ATLFParticle::Clear(Option_t *)
{
// Delete graphics temporary objects
m_Particles->Delete();
}
//_____________________________________________________________________________
void ATLFParticle::Delete(Option_t *)
{
// Dummy
}
//_____________________________________________________________________________
Int_t ATLFParticle::DistancetoPrimitive(Int_t px, Int_t py)
{
// scan list of particles
TClonesArray *particles = gATLFast->MCMaker()->Fruits();
Int_t uid, dist;
TIter next(m_Particles);
TPolyLine3D *line;
while((line=(TPolyLine3D*)next())) {
dist = line->DistancetoPrimitive(px, py);
if (dist < 2) {
uid = line->GetUniqueID();
m_MCParticle = (TMCParticle*)particles->UncheckedAt(uid);
if (!m_MCParticle) continue;
m_Line = line;
SetName(m_MCParticle->GetName());
gPad->SetSelected(this);
gPad->SetCursor(kCross);
return 0;
}
}
return 999;
}
//______________________________________________________________________________
void ATLFParticle::ExecuteEvent(Int_t event, Int_t , Int_t )
{
switch (event) {
case kButton1Down:
gGXW->SetLineColor(-1);
gPad->AbsCoordinates(kTRUE);
m_Line->SetLineColor(6);
m_Line->SetLineWidth(6);
m_Line->Paint();
break;
case kMouseMotion:
break;
case kButton1Motion:
break;
case kButton1Up:
gGXW->SetLineColor(-1);
m_Line->SetLineColor(kYellow);
m_Line->SetLineWidth(1);
m_Line->Paint();
gPad->AbsCoordinates(kFALSE);
}
}
//______________________________________________________________________________
char *ATLFParticle::GetObjectInfo(Int_t , Int_t )
{
static char info[100];
sprintf(info,"px=%f, py=%f, pz=%f, E=%f",
m_MCParticle->GetPx(),
m_MCParticle->GetPy(),
m_MCParticle->GetPz(),
m_MCParticle->GetEnergy());
return info;
}
//______________________________________________________________________________
TPolyLine3D *ATLFParticle::HelixCurve(Float_t field, Float_t pmom, Float_t *vin)
{
// Estimate step size in function of field.
// Create a 3-D polyline with points computed with this step size
Float_t step = 10;
const Int_t kMAXSTEP = 2000;
Float_t sx[kMAXSTEP], sy[kMAXSTEP], sz[kMAXSTEP];
if (pmom > 0) step = 10*pmom;
if (step > 100) step = 100;
if (step < .5) step = .5;
Float_t vout[6];
Int_t i,j;
sx[0] = vin[0];
sy[0] = vin[1];
sz[0] = vin[2];
Int_t nsteps = 1;
Float_t rin = Display()->Rin();
Float_t zout = Display()->Zout();
for (i=1;i<kMAXSTEP;i++) {
HelixStep(field,step,pmom,vin,vout);
if (TMath::Abs(vout[2]) > zout) break;
if (vout[0]*vout[0] + vout[1]*vout[1] > 1.1*rin*rin) break;
sx[nsteps] = vout[0];
sy[nsteps] = vout[1];
sz[nsteps] = vout[2];
nsteps++;
for (j=0;j<6;j++) vin[j] = vout[j];
}
if (nsteps < 2) return 0;
TPolyLine3D *line = new TPolyLine3D(nsteps,sx, sy,sz);
line->SetBit(kCanDelete);
return line;
}
//______________________________________________________________________________
void ATLFParticle::HelixStep(Float_t field, Float_t step, Float_t pmom, Float_t *vin, Float_t *vout)
{
// extrapolate track with parameters in vector vin in a constant field
// oriented along Z axis (in tesla/meters).
// Output in vector vout
// vin[0-->6] = x,y,z,px,py,pz
// translated to C++ from GEANT3 routine GHELX3
Float_t sint, sintt, tsint, cos1t, sin2;
// units are tesla,centimeters,gev/c
const Float_t ec = 2.9979251e-3;
Float_t h4 = field*ec;
Float_t hp = vin[2];
Float_t tet = -h4*step/pmom;
if (TMath::Abs(tet) > 0.15) {
sint = TMath::Sin(tet);
sintt = sint/tet;
tsint = (tet-sint)/tet;
sin2 = TMath::Sin(0.5*tet);
cos1t = 2*sin2*sin2/tet;
} else {
tsint = tet*tet/6;
sintt = 1 - tsint;
sint = tet*sintt;
cos1t = 0.5*tet;
}
Float_t f1 = step*sintt;
Float_t f2 = step*cos1t;
Float_t f3 = step*tsint*hp;
Float_t f4 = -tet*cos1t;
Float_t f5 = sint;
Float_t f6 = tet*cos1t*hp;
vout[0] = vin[0] + (f1*vin[3] - f2*vin[4]);
vout[1] = vin[1] + (f1*vin[4] + f2*vin[3]);
vout[2] = vin[2] + (f1*vin[5] + f3);
vout[3] = vin[3] + (f4*vin[3] - f5*vin[4]);
vout[4] = vin[4] + (f4*vin[4] + f5*vin[3]);
vout[5] = vin[5] + (f4*vin[5] + f6);
}
//_____________________________________________________________________________
void ATLFParticle::Paint(Option_t *option)
{
// Paint particles generated by ATLFMCMaker
// Only particles above m_PTcut are drawn
// Particle trajectory is computed along an helix in a constant field
// clean list of particles
m_Particles->Delete();
TClonesArray *particles = gATLFast->MCMaker()->Fruits();
Int_t nparticles = particles->GetEntriesFast();
TMCParticle *part;
Float_t pmom, vx, vy, vz, pt;
Float_t vin[6];
Float_t field = 2; // 2 tesla
Int_t KF, aKF, charge;
for (Int_t i=0;i<nparticles;i++) {
part = (TMCParticle*)particles->UncheckedAt(i);
if (part->GetKS() != 1) continue;
KF = part->GetKF();
aKF = TMath::Abs(KF);
charge = gATLFast->MCMaker()->Charge(KF);
pt = TMath::Sqrt(part->GetPx()*part->GetPx() + part->GetPy()*part->GetPy());
if (pt < gATLFast->Display()->PTcut()) continue;
if (charge == 0 && pt < gATLFast->Display()->PTcutEGMUNU()) continue;
pmom = TMath::Sqrt(part->GetPx()*part->GetPx() + part->GetPy()*part->GetPy() + part->GetPz()*part->GetPz());
vx = part->GetVx();
vy = part->GetVy();
vz = part->GetVz();
vin[0] = vx;
vin[1] = vy;
vin[2] = vz;
vin[3] = part->GetPx()/pmom;
vin[4] = part->GetPy()/pmom;
vin[5] = part->GetPz()/pmom;
TPolyLine3D *line = HelixCurve(charge*field/3, pmom, vin);
if (line == 0) continue;
m_Particles->Add(line);
if (part->GetLineColor() == 1) {
if (charge == 0) part->SetLineStyle(2);
part->SetLineColor(kYellow);
if (aKF == 11) part->SetLineColor(kRed);
if (aKF == 13) part->SetLineColor(kMagenta);
if (aKF == 22) part->SetLineColor(kGreen);
}
line->SetUniqueID(i);
if (!part->TestBit(kRECONS)) {
part->SetLineColor(7);
part->SetLineWidth(1);
}
line->SetLineColor(part->GetLineColor());
line->SetLineStyle(part->GetLineStyle());
line->SetLineWidth(part->GetLineWidth());
line->Paint(option);
}
}
//______________________________________________________________________________
void ATLFParticle::SetLineAttributes()
{
//*-*-*-*-*-*-*-*-*Invoke the DialogCanvas Line attributes*-*-*-*-*-*-*
//*-* =======================================
gROOT->SetSelectedPrimitive(m_MCParticle);
m_MCParticle->SetLineAttributes();
}
//______________________________________________________________________________
void ATLFParticle::SizeParticles() const
{
TIter next(m_Particles);
TPolyLine3D *line;
while((line=(TPolyLine3D*)next())) {
line->Sizeof3D();
}
}
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.