Java source code of 'hephysics.particle.LParticle'

package hephysics.particle;

import hephysics.vec.Hep3Vector;
import hephysics.vec.HepLorentzVector;
import java.io.Serializable;
import java.util.Formatter;
import java.util.Random;
import java.lang.Math;
import jhplot.gui.HelpBrowser;

/**
 * A class representing a Lorentz particle. It is based on four-Lorentz vector
 * and extends HepLorentzVector. A particle can be represented by either
 * (px,py,pz,E) or (x,y,z,time). In addition, you can define name, mass,charge
 * and a parent particle as an object.
 * 
 * 
 * @author Sergei Chekanov
 */
public class LParticle extends HepLorentzVector implements
		Comparable, Serializable {

	static final long serialVersionUID = -6544699016896436061L;
	protected double mass;
	protected String name;
	protected LParticle parent;
	protected double charge;

	/**
	 * Define a dummy particle. Set Px,Py,Pz,mass to zero.
	 * 
	 */
	public LParticle() {
		super(0.0, 0.0, 0.0, 0.0);
		this.name = "";
		this.mass = 0;
		this.charge = 0;
		this.energy = 0;
	}

	/**
	 * Define a particle with a name. Set Px,Py,Pz,mass to zero.
	 * 
	 * @param name
	 *            particle name
	 */
	public LParticle(String name) {
		super(0.0, 0.0, 0.0, 0.0);
		this.name = name;
		this.mass = 0;
		this.charge = 0;
		this.energy = 0;
	}

	/**
	 * Define a particle with a name and mass. Set Px,Py,Pz to zero.
	 * 
	 * @param name
	 *            particle name
	 * @param mass
	 *            mass
	 */
	public LParticle(String name, double mass) {
		super(0.0, 0.0, 0.0, 0.0);
		this.name = name;
		this.mass = mass;
		this.charge = 0;
		this.energy = 0;
	}

	/**
	 * Define a 3-momentum or X,Y,Z position. Energy and mass are set to 0.
	 * 
	 * @param px
	 *            Px (or X_)
	 * @param py
	 *            Py (or Y)
	 * @param pz
	 *            Pz (or Z)
	 */
	public LParticle(double px, double py, double pz) {
		super(0.0, px, py, pz);
		this.mass = 0;
		this.charge = 0;
		this.energy = 0;
	}

	/**
	 * Set Px,Py,Pz (or x,y,z)
	 * 
	 * @param px
	 * @param py
	 * @param pz
	 */
	public void setPxPyPz(double px, double py, double pz) {
		setPx(px);
		setPy(py);
		setPz(pz);
	}

	/**
	 * Set Px,Py,Pz and energy of a particle
	 * 
	 * @param px
	 *            Px momentum
	 * @param py
	 *            Py momentum
	 * @param pz
	 *            Pz momentum
	 * @param e
	 *            energy
	 */
	public void setPxPyPzE(double px, double py, double pz, double e) {
		setPx(px);
		setPy(py);
		setPz(pz);
		setE(e);
	}

	/**
	 * Set x,y,z and time for a particle (vertex position)
	 * 
	 * @param x
	 *            X position
	 * @param y
	 *            Y position
	 * @param z
	 *            Z position
	 * @param t
	 *            time
	 */
	public void setXYZT(double x, double y, double z, double t) {
		setPx(x);
		setPy(y);
		setPz(z);
		setT(t);
	}

	/**
	 * Define a particle in momentum or coordinate space.
	 * 
	 * @param px
	 *            Px (or X position)
	 * @param py
	 *            Py (or Y position)
	 * @param pz
	 *            Pz (or Z position)
	 * @param energy
	 *            energy (or time)
	 * @param mass
	 *            mass
	 */
	public LParticle(double px, double py, double pz, double energy, double mass) {
		super(px, py, pz, energy);
		this.mass = mass;
		this.charge = 0;
	}

	/**
	 * Define a particle in momentum or 4-space time. Mass is set to 0
	 * 
	 * @param px
	 *            Px or X position
	 * @param py
	 *            Py or Y position
	 * @param pz
	 *            Pz or Z position
	 * 
	 * @param energy
	 *            energy or time
	 */
	public LParticle(double px, double py, double pz, double energy) {
		super(px, py, pz, energy);
		this.mass = 0;
		this.charge = 0;
	}

	/**
	 * Define a Lorentz particle in momentum or coordinate space.
	 * 
	 * @param name
	 *            Name of particle
	 * @param px
	 *            px (or X)
	 * @param py
	 *            py (or Y)
	 * @param pz
	 *            pz (or Z)
	 * @param energy
	 *            energy or time
	 * @param mass
	 *            mass
	 */
	public LParticle(String name, double px, double py, double pz,
			double energy, double mass) {
		super(px, py, pz, energy);
		this.name = name;
		this.mass = mass;
		this.charge = 0;
	}

	/**
	 * Set a parent particle
	 * 
	 * @param parent
	 *            parent particle
	 */
	public void setParent(LParticle parent) {
		this.parent = parent;
	}

	/**
	 * Scale all components (Px,Py,Px,E) by a factor C. Keep mass unchanged.
	 * This means all components are multiplied by this factor.
	 * 
	 * @param scale
	 *            factor used to multiply Px,Py,Pz,E components.
	 * 
	 */
	public void scalePxPyPzE(double scale) {
		setPx(px() * scale);
		setPy(py() * scale);
		setPz(pz() * scale);
		setE(e() * scale);
	}

	/**
	 * Scale all components (X,Y,Z,T) by a factor This means all components are
	 * multiplied by this factor.
	 * 
	 * @param scale
	 *            factor used to multiply X,Y,Z,T components.
	 * 
	 */
	public void scaleXYZT(double scale) {
		setX(x() * scale);
		setY(y() * scale);
		setZ(z() * scale);
		setT(t() * scale);
	}

	/**
	 * Divide all components (Px,Py,Px,E) by a factor C. Useful for varints
	 * (integer) representation.
	 * 
	 * @param scale
	 *            factor used to divide Px,Py,Pz,E
	 * 
	 */
	public void dividePxPyPzE(double scale) {
		setPx(px() / scale);
		setPy(py() / scale);
		setPz(pz() / scale);
		setE(e() / scale);
	}

	/**
	 * Get a parent particle
	 * 
	 * @return parent
	 */
	public LParticle getParent() {
		return this.parent;
	}

	/**
	 * Add 2 particle
	 * 
	 * @param another
	 *            particle to be edded
	 */
	public void add(LParticle another) {

		setPx(v.x() + another.v3().x());
		setPy(v.y() + another.v3().y());
		setPz(v.z() + another.v3().z());
		this.energy = this.energy + another.getE();
		this.t = this.t + another.getT();
		this.name = this.name + "+" + another.getName();
		this.charge = this.charge + another.getCharge();
	}

	/**
	 * Get a mass
	 * 
	 * @return mass
	 */
	public double getMass() {
		return mass;
	}

	/**
	 * Get a mass
	 * 
	 * @return mass
	 */
	public double mass() {
		return mass;
	}

	/**
	 * Get a name
	 * 
	 * @return name
	 */
	public String getName() {
		return name;
	}

	/**
	 * Get a 3-vector woth (Px,Py,Pz) or (X,Y,Z)
	 */
	public Hep3Vector getV3() {
		return this.getV3();
	}

	/**
	 * Set a mass
	 * 
	 * @param mass
	 *            Mass
	 */
	public void setMass(double mass) {
		this.mass = mass;
	}

	/**
	 * Get a hash code
	 */
	public int hashCode() {
		return hashCode() + (int) Double.doubleToRawLongBits(energy);
	}

	/**
	 * Set HepLorentzVector using theta angle, phi and total momentum P. e =
	 * sqrt(P*P + mass*mass); 
* pX = P*sin(theta)*cos(phi);
* pY = P*sin(theta)*sin(phi);
* pZ = P*cos(theta); *

* * @param theta * theta * @param phi * phi * @param P * momentum * @return */ public void setThetaPhiP(double theta, double phi, double P) { double e = Math.sqrt(P * P + getMass() * getMass()); double pX = P * Math.sin(theta) * Math.cos(phi); double pY = P * Math.sin(theta) * Math.sin(phi); double pZ = P * Math.cos(theta); setV3(pX, pY, pZ); setE(e); } /** * Set 4-momentum of a particle using transverse momentum (pt), * pseudorapidity (Eta) and azimuthal angle (phi) and energy. *

* * @param pt * transverse momentum of a particle. * @param eta * eta (pseudorapidity) . * @param phi * azimuthal angle * @param e * energy */ public void setPtEtaPhiE(double pt, double eta, double phi, double e) { double apt = Math.abs(pt); double px = apt * Math.cos(phi); double py = apt * Math.sin(phi); double pz = apt * Math.sinh(eta); setPxPyPzE(px, py, pz, e); } /** * Set 4-momentum of a particle using transverse momentum (pt), * pseudorapidity (eta) and azimuthal angle (phi) and mass (m). In this * case, the energy is Math.sqrt(px*px+py*py+pz*pz-m*m). *

* * @param pt * transverse momentum of a particle. * @param eta * eta (pseudorapidity) . * @param phi * azimuthal angle * @param m * mass */ public void setPtEtaPhiM(double pt, double eta, double phi, double m) { double apt = Math.abs(pt); double px = apt * Math.cos(phi); double py = apt * Math.sin(phi); double pz = apt * Math.sinh(eta); this.mass = m; double ee = px * px + py * py + pz * pz - m * m; if (ee < 0) ee = 0; else ee = Math.sqrt(ee); setPxPyPzE(px, py, pz, ee); } /** * Magnitude * * @return */ public double abs() { return Math.sqrt(skp(this)); } /** * Set charge * * @param charge * charge */ public void setCharge(double charge) { this.charge = charge; } /** * Get charge * * @return */ public double getCharge() { return charge; } /** * Angle between 2 vectors in rad * * @param momentum * parent particle * @return angle in rad */ public double angle(LParticle momentum) { if (abs() <= 0.0D || momentum.abs() <= 0.0D) return 0.0D; else return Math.acos(skp(momentum) / abs() / momentum.abs()); } /** * Get calculated mass as sqrt(e*e-px**2-py**2-pz**2) * * @return */ public double calcMass() { double s = energy * energy - skp(this); if (s > 0) return Math.sqrt(s); else return -1 * Math.sqrt(-1.0 * s); } /** * Evaluates 4-vector of decay product in the rest frame of parent. * * @param prod1 * first decay product * @param prod2 * second decay product * @param randomRotate * is Phi randomly rotated? * @return */ public void twoBodyDecay(LParticle prod1, LParticle prod2, boolean randomRotate) { double m1 = prod1.getMass(); double m2 = prod2.getMass(); double m = mass; // check if particle m can decay if (m < m1 + m2) { System.out .println("twoBodyDecay parent mass is less than sum of products."); prod1.setV3(0., 0., 0.); prod2.setV3(0., 0., 0.); return; } // CM energies and momentum double e1 = (m * m + m1 * m1 - m2 * m2) / (2.0 * m); double e2 = (m * m - m1 * m1 + m2 * m2) / (2.0 * m); double P = Math.sqrt(e1 * e1 - m1 * m1); double ran1 = 0; double ran2 = 0; if (randomRotate) { Random r = new Random(); ran1 = r.nextDouble(); ran2 = r.nextDouble(); } // Isotropic random angles double theta = Math.acos(2.0 * ran1 - 1.0); double phi = 2.0 * Math.PI * ran2; double pX = P * Math.sin(theta) * Math.cos(phi); double pY = P * Math.sin(theta) * Math.sin(phi); double pZ = P * Math.cos(theta); // set the 4-momenta prod1.setV3(pX, pY, pZ); prod1.setE(e1); prod2.setV3(-pX, -pY, -pZ); prod2.setE(e2); } /** * Lorentz Boost * * @param parent * parent particle */ public void boost(LParticle parent) { // beta and gamma values double betax = parent.v3().x() / parent.e(); double betay = parent.v3().y() / parent.e(); double betaz = parent.v3().z() / parent.e(); double beta2 = betax * betax + betay * betay + betaz * betaz; double gamma = 1.0 / Math.sqrt(1.0 - beta2); double dot = betax * v.x() + betay * v.y() + betaz * v.z(); double prod = gamma * (gamma * dot / (1.0 + gamma) + energy); double pX = v.x() + betax * prod; double pY = v.y() + betay * prod; double pZ = v.z() + betaz * prod; double e = gamma * (energy + dot); setV3(pX, pY, pZ); this.energy = e; this.parent = parent; } /** * Convert to string */ public String toString() { Formatter formatter = new Formatter(); formatter.format("M=%9.4g,E=%9.4g,T=%9.4g", mass, energy, t); String sname = String.format("%10s", name); return new String(sname + " " + v.toString() + ", " + formatter.out().toString()); } /** * Make an exact copy of this particle * * @return new copy */ public LParticle copy() { LParticle tmp = new LParticle(getName(), pz(), pz(), pz(), e(), getMass()); tmp.setParent(getParent()); setT(t()); setCharge(getCharge()); return tmp; } /** * Print particle */ public void print() { System.out.println(toString()); } /** * Show online documentation. */ public void doc() { String a = this.getClass().getName(); a = a.replace(".", "/") + ".html"; new HelpBrowser(HelpBrowser.JHPLOT_HTTP + a); } /** * Comparator. using perp2 for comparison (in increasing order) * * @param o * @return */ public int compareTo(LParticle o) { int tmp =0; if (perp2() < o.perp2()) tmp = 1; if (perp2()> o.perp2()) tmp = -1; return tmp; } }