<commit_before>/**************************************************************************
 * 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.                  *
 **************************************************************************/

#include "AliESDtrack.h"
#include "AliTracker.h"
#include "AliHMPIDtrack.h"

ClassImp(AliHMPIDtrack)

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack::AliHMPIDtrack():AliKalmanTrack()
{
  //
  // def. ctor
  //
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack::AliHMPIDtrack(const AliHMPIDtrack& t):AliKalmanTrack(t)
{
  //
  // cctor.
  //
 }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack::AliHMPIDtrack(const AliESDtrack& t):AliKalmanTrack()
{
  //
  // Constructor from AliESDtrack
  //
  SetLabel(t.GetLabel());
  SetChi2(0.);
  SetMass(t.GetMass());

  Set(t.GetX(),t.GetAlpha(),t.GetParameter(),t.GetCovariance());

  if ((t.GetStatus()&AliESDtrack::kTIME) == 0) return;
  StartTimeIntegral();
  Double_t times[10]; t.GetIntegratedTimes(times); SetIntegratedTimes(times);
  SetIntegratedLength(t.GetIntegratedLength());
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack& AliHMPIDtrack::operator=(const AliHMPIDtrack &/*source*/)
{
  // ass. op.

  return *this;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::PropagateTo(Double_t xk, Double_t xx0, Double_t xrho)
{
  //
  // Propagates this track to a reference plane defined by "xk" [cm]
  // correcting for the mean crossed material.
  // Arguments:
  // "xx0"  - thickness/rad.length [units of the radiation length]
  // "xrho" - thickness*density    [g/cm^2]
  //  Returns: kTRUE if the track propagates to plane, else kFALSE

  if (xk == GetX()) {
    return kTRUE;
  }
  Double_t bz   = GetBz();
  if (!AliExternalTrackParam::PropagateTo(xk,bz)) {
    return kFALSE;
  }
  if (!AliExternalTrackParam::CorrectForMeanMaterial(xx0,xrho,GetMass())) {
    return kFALSE;
  }
  return kTRUE;
}//PropagateTo()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Rotate(Double_t alpha, Bool_t absolute)
{
  //
  // Rotates track parameters in R*phi plane
  // if absolute rotation alpha is in global system
  // otherwise alpha rotation is relative to the current rotation angle
  //

  if (absolute) {
    alpha -= GetAlpha();
  }

  return AliExternalTrackParam::Rotate(GetAlpha()+alpha);

}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Int_t AliHMPIDtrack::GetProlongation(Double_t xk, Double_t &y, Double_t &z)
{
  //
  // Find a prolongation at given x
  // Return 0 if it does not exist
  //

  Double_t bz = GetBz();

  if (!AliExternalTrackParam::GetYAt(xk,bz,y)) {
    return 0;
  }
  if (!AliExternalTrackParam::GetZAt(xk,bz,z)) {
    return 0;
  }

  return 1;

}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t   AliHMPIDtrack::PropagateToR(Double_t r,Double_t step)
{
  //
  // Propagate track to the radial position
  // Rotation always connected to the last track position
  //

  Double_t xyz0[3];
  Double_t xyz1[3];
  Double_t y;
  Double_t z;

  Double_t radius = TMath::Sqrt(GetX()*GetX() + GetY()*GetY());
  // Direction +-
  Double_t dir    = (radius > r) ? -1.0 : 1.0;

  for (Double_t x = radius+dir*step; dir*x < dir*r; x += dir*step) {

    GetXYZ(xyz0);
    Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
    Rotate(alpha,kTRUE);
    GetXYZ(xyz0);
    if (!GetProlongation(x,y,z)) return kFALSE;
    xyz1[0] = x * TMath::Cos(alpha) + y * TMath::Sin(alpha);
    xyz1[1] = x * TMath::Sin(alpha) - y * TMath::Cos(alpha);
    xyz1[2] = z;
    Double_t param[7];
    AliTracker::MeanMaterialBudget(xyz0,xyz1,param);
    if (param[1] <= 0) {
      param[1] = 100000000;
    }
    PropagateTo(x,param[1],param[0]*param[4]);

  }

  GetXYZ(xyz0);
  Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
  Rotate(alpha,kTRUE);
  GetXYZ(xyz0);
  if (!GetProlongation(r,y,z)) return kFALSE;
  xyz1[0] = r * TMath::Cos(alpha) + y * TMath::Sin(alpha);
  xyz1[1] = r * TMath::Sin(alpha) - y * TMath::Cos(alpha);
  xyz1[2] = z;
  Double_t param[7];
  AliTracker::MeanMaterialBudget(xyz0,xyz1,param);

  if (param[1] <= 0) {
    param[1] = 100000000;
  }

  return PropagateTo(r,param[1],param[0]*param[4]);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Double_t AliHMPIDtrack::GetPredictedChi2(const AliCluster3D *c) const {
  //
  // Arguments: AliCluster3D
  // Returns:   Chi2 of track for the cluster
  Double_t      p[3]={c->GetX(),       c->GetY(),       c->GetZ()};
  Double_t  covyz[3]={c->GetSigmaY2(), c->GetSigmaYZ(), c->GetSigmaZ2()};
  Double_t covxyz[3]={c->GetSigmaX2(), c->GetSigmaXY(), c->GetSigmaXZ()};
  return AliExternalTrackParam::GetPredictedChi2(p, covyz, covxyz);
}//GetPredictedChi2()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::PropagateTo(const AliCluster3D *c) {
  //
  // Arguments: AliCluster3D
  // Returns: kTRUE if the track propagates to the plane of the cluster
  Double_t      oldX=GetX(),   oldY=GetY(), oldZ=GetZ();
  Double_t      p[3]={c->GetX(), c->GetY(), c->GetZ()};
  Double_t  covyz[3]={c->GetSigmaY2(), c->GetSigmaYZ(), c->GetSigmaZ2()};
  Double_t covxyz[3]={c->GetSigmaX2(), c->GetSigmaXY(), c->GetSigmaXZ()};
  Double_t bz=GetBz();

  if(!AliExternalTrackParam::PropagateTo(p, covyz, covxyz, bz)) return kFALSE;
  if(IsStartedTimeIntegral())
    {
      Double_t d = TMath::Sqrt((GetX()-oldX)*(GetX()-oldX) + (GetY()-oldY)*(GetY()-oldY) + (GetZ()-oldZ)*(GetZ()-oldZ));
      if (GetX()<oldX) d=-d;
      AddTimeStep(d);
  }
  return kTRUE;
}//PropagateTo()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Intersect(Double_t pnt[3], Double_t norm[3]) const {
  //+++++++++++++++++++++++++++++++++++++++++
  // Origin: K. Shileev (Kirill.Shileev@cern.ch)
  // Finds point of intersection (if exists) of the helix with the plane.
  // Stores result in fX and fP.
  // Arguments: planePoint,planeNorm - the plane defined by any plane's point
  // and vector, normal to the plane
  // Returns: kTrue if helix intersects the plane, kFALSE otherwise.
  //+++++++++++++++++++++++++++++++++++++++++
  Double_t x0[3]; GetXYZ(x0); //get track position in MARS

  //estimates initial helix length up to plane
  Double_t s=(pnt[0]-x0[0])*norm[0] + (pnt[1]-x0[1])*norm[1] + (pnt[2]-x0[2])*norm[2];
  Double_t dist=99999,distPrev=dist;
  Double_t p[3],x[3];
  while(TMath::Abs(dist)>0.00001){
    //calculates helix at the distance s from x0 ALONG the helix
    Propagate(s,x,p);
    //distance between current helix position and plane
    dist=(x[0]-pnt[0])*norm[0]+(x[1]-pnt[1])*norm[1]+(x[2]-pnt[2])*norm[2];
    if(TMath::Abs(dist) >= TMath::Abs(distPrev)) {return kFALSE;}
    distPrev=dist;
    s-=dist;
  }
  //on exit pnt is intersection point,norm is track vector at that point,
  //all in MARS
  for (Int_t i=0; i<3; i++) {pnt[i]=x[i]; norm[i]=p[i];}
  return kTRUE;
}//Intersect()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void AliHMPIDtrack::Propagate(Double_t len, Double_t x[3],Double_t p[3]) const {
  //+++++++++++++++++++++++++++++++++++++++++
  // Origin: K. Shileev (Kirill.Shileev@cern.ch)
  // Extrapolate track along simple helix in magnetic field
  // Arguments: len -distance alogn helix, [cm]
  //            bz  - mag field, [kGaus]
  // Returns: x and p contain extrapolated positon and momentum
  // The momentum returned for straight-line tracks is meaningless !
  //+++++++++++++++++++++++++++++++++++++++++
  GetXYZ(x);
  Double_t bField[3];
  TGeoGlobalMagField::Instance()->Field(x,bField);
  Double_t bz = bField[2];
  if (OneOverPt() < kAlmost0 || TMath::Abs(bz) < kAlmost0Field ){ //straight-line tracks
     Double_t unit[3]; GetDirection(unit);
     x[0]+=unit[0]*len;
     x[1]+=unit[1]*len;
     x[2]+=unit[2]*len;

     p[0]=unit[0]/kAlmost0;
     p[1]=unit[1]/kAlmost0;
     p[2]=unit[2]/kAlmost0;
  } else {
     GetPxPyPz(p);
     Double_t pp=GetP();
     Double_t a = -kB2C*bz*GetSign(); ////////// what is kB2C
     Double_t rho = a/pp;
     x[0] += p[0]*TMath::Sin(rho*len)/a - p[1]*(1-TMath::Cos(rho*len))/a;
     x[1] += p[1]*TMath::Sin(rho*len)/a + p[0]*(1-TMath::Cos(rho*len))/a;
     x[2] += p[2]*len/pp;
     Double_t p0=p[0];
     p[0] = p0  *TMath::Cos(rho*len) - p[1]*TMath::Sin(rho*len);
     p[1] = p[1]*TMath::Cos(rho*len) + p0  *TMath::Sin(rho*len);
  }
}//Propagate()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Update(const AliHMPIDCluster *pClu, Double_t /*chisq*/, Int_t /*index*/)
{
  //
  // Arguments: AliCluster3D, chi sq, and clu index
  // Returns: kTRUE if the track parameters are successfully updated
  Double_t p[2]={pClu->GetY(), pClu->GetZ()};
  Double_t cov[3]={pClu->GetSigmaY2(), 0., pClu->GetSigmaZ2()};
  if (!AliExternalTrackParam::Update(p,cov)) return kFALSE;

  /*
  AliTracker::FillResiduals(this,p,cov,pClu->GetVolumeId());

  Int_t n=GetNumberOfClusters();
  fIndex[n]=index;
  SetNumberOfClusters(n+1);
  SetChi2(GetChi2()+chisq);
*/
  return kTRUE;

}//Update()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<commit_msg>bux fix for B field<commit_after>/**************************************************************************
 * 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.                  *
 **************************************************************************/

#include "AliESDtrack.h"
#include "AliTracker.h"
#include "AliHMPIDtrack.h"

ClassImp(AliHMPIDtrack)

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack::AliHMPIDtrack():AliKalmanTrack()
{
  //
  // def. ctor
  //
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack::AliHMPIDtrack(const AliHMPIDtrack& t):AliKalmanTrack(t)
{
  //
  // cctor.
  //
 }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack::AliHMPIDtrack(const AliESDtrack& t):AliKalmanTrack()
{
  //
  // Constructor from AliESDtrack
  //
  SetLabel(t.GetLabel());
  SetChi2(0.);
  SetMass(t.GetMass());

  Set(t.GetX(),t.GetAlpha(),t.GetParameter(),t.GetCovariance());

  if ((t.GetStatus()&AliESDtrack::kTIME) == 0) return;
  StartTimeIntegral();
  Double_t times[10]; t.GetIntegratedTimes(times); SetIntegratedTimes(times);
  SetIntegratedLength(t.GetIntegratedLength());
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack& AliHMPIDtrack::operator=(const AliHMPIDtrack &/*source*/)
{
  // ass. op.

  return *this;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::PropagateTo(Double_t xk, Double_t xx0, Double_t xrho)
{
  //
  // Propagates this track to a reference plane defined by "xk" [cm]
  // correcting for the mean crossed material.
  // Arguments:
  // "xx0"  - thickness/rad.length [units of the radiation length]
  // "xrho" - thickness*density    [g/cm^2]
  //  Returns: kTRUE if the track propagates to plane, else kFALSE

  if (xk == GetX()) {
    return kTRUE;
  }
  Double_t bz   = -GetBz();
  if (!AliExternalTrackParam::PropagateTo(xk,bz)) {
    return kFALSE;
  }
  if (!AliExternalTrackParam::CorrectForMeanMaterial(xx0,xrho,GetMass())) {
    return kFALSE;
  }
  return kTRUE;
}//PropagateTo()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Rotate(Double_t alpha, Bool_t absolute)
{
  //
  // Rotates track parameters in R*phi plane
  // if absolute rotation alpha is in global system
  // otherwise alpha rotation is relative to the current rotation angle
  //

  if (absolute) {
    alpha -= GetAlpha();
  }

  return AliExternalTrackParam::Rotate(GetAlpha()+alpha);

}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Int_t AliHMPIDtrack::GetProlongation(Double_t xk, Double_t &y, Double_t &z)
{
  //
  // Find a prolongation at given x
  // Return 0 if it does not exist
  //

  Double_t bz = -GetBz();

  if (!AliExternalTrackParam::GetYAt(xk,bz,y)) {
    return 0;
  }
  if (!AliExternalTrackParam::GetZAt(xk,bz,z)) {
    return 0;
  }

  return 1;

}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t   AliHMPIDtrack::PropagateToR(Double_t r,Double_t step)
{
  //
  // Propagate track to the radial position
  // Rotation always connected to the last track position
  //

  Double_t xyz0[3];
  Double_t xyz1[3];
  Double_t y;
  Double_t z;

  Double_t radius = TMath::Sqrt(GetX()*GetX() + GetY()*GetY());
  // Direction +-
  Double_t dir    = (radius > r) ? -1.0 : 1.0;

  for (Double_t x = radius+dir*step; dir*x < dir*r; x += dir*step) {

    GetXYZ(xyz0);
    Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
    Rotate(alpha,kTRUE);
    GetXYZ(xyz0);
    if (!GetProlongation(x,y,z)) return kFALSE;
    xyz1[0] = x * TMath::Cos(alpha) + y * TMath::Sin(alpha);
    xyz1[1] = x * TMath::Sin(alpha) - y * TMath::Cos(alpha);
    xyz1[2] = z;
    Double_t param[7];
    AliTracker::MeanMaterialBudget(xyz0,xyz1,param);
    if (param[1] <= 0) {
      param[1] = 100000000;
    }
    PropagateTo(x,param[1],param[0]*param[4]);

  }

  GetXYZ(xyz0);
  Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
  Rotate(alpha,kTRUE);
  GetXYZ(xyz0);
  if (!GetProlongation(r,y,z)) return kFALSE;
  xyz1[0] = r * TMath::Cos(alpha) + y * TMath::Sin(alpha);
  xyz1[1] = r * TMath::Sin(alpha) - y * TMath::Cos(alpha);
  xyz1[2] = z;
  Double_t param[7];
  AliTracker::MeanMaterialBudget(xyz0,xyz1,param);

  if (param[1] <= 0) {
    param[1] = 100000000;
  }

  return PropagateTo(r,param[1],param[0]*param[4]);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Double_t AliHMPIDtrack::GetPredictedChi2(const AliCluster3D *c) const {
  //
  // Arguments: AliCluster3D
  // Returns:   Chi2 of track for the cluster
  Double_t      p[3]={c->GetX(),       c->GetY(),       c->GetZ()};
  Double_t  covyz[3]={c->GetSigmaY2(), c->GetSigmaYZ(), c->GetSigmaZ2()};
  Double_t covxyz[3]={c->GetSigmaX2(), c->GetSigmaXY(), c->GetSigmaXZ()};
  return AliExternalTrackParam::GetPredictedChi2(p, covyz, covxyz);
}//GetPredictedChi2()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::PropagateTo(const AliCluster3D *c) {
  //
  // Arguments: AliCluster3D
  // Returns: kTRUE if the track propagates to the plane of the cluster
  Double_t      oldX=GetX(),   oldY=GetY(), oldZ=GetZ();
  Double_t      p[3]={c->GetX(), c->GetY(), c->GetZ()};
  Double_t  covyz[3]={c->GetSigmaY2(), c->GetSigmaYZ(), c->GetSigmaZ2()};
  Double_t covxyz[3]={c->GetSigmaX2(), c->GetSigmaXY(), c->GetSigmaXZ()};
  Double_t bz=-GetBz();

  if(!AliExternalTrackParam::PropagateTo(p, covyz, covxyz, bz)) return kFALSE;
  if(IsStartedTimeIntegral())
    {
      Double_t d = TMath::Sqrt((GetX()-oldX)*(GetX()-oldX) + (GetY()-oldY)*(GetY()-oldY) + (GetZ()-oldZ)*(GetZ()-oldZ));
      if (GetX()<oldX) d=-d;
      AddTimeStep(d);
  }
  return kTRUE;
}//PropagateTo()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Intersect(Double_t pnt[3], Double_t norm[3]) const {
  //+++++++++++++++++++++++++++++++++++++++++
  // Origin: K. Shileev (Kirill.Shileev@cern.ch)
  // Finds point of intersection (if exists) of the helix with the plane.
  // Stores result in fX and fP.
  // Arguments: planePoint,planeNorm - the plane defined by any plane's point
  // and vector, normal to the plane
  // Returns: kTrue if helix intersects the plane, kFALSE otherwise.
  //+++++++++++++++++++++++++++++++++++++++++
  Double_t x0[3]; GetXYZ(x0); //get track position in MARS

  //estimates initial helix length up to plane
  Double_t s=(pnt[0]-x0[0])*norm[0] + (pnt[1]-x0[1])*norm[1] + (pnt[2]-x0[2])*norm[2];
  Double_t dist=99999,distPrev=dist;
  Double_t p[3],x[3];
  while(TMath::Abs(dist)>0.00001){
    //calculates helix at the distance s from x0 ALONG the helix
    Propagate(s,x,p);
    //distance between current helix position and plane
    dist=(x[0]-pnt[0])*norm[0]+(x[1]-pnt[1])*norm[1]+(x[2]-pnt[2])*norm[2];
    if(TMath::Abs(dist) >= TMath::Abs(distPrev)) {return kFALSE;}
    distPrev=dist;
    s-=dist;
  }
  //on exit pnt is intersection point,norm is track vector at that point,
  //all in MARS
  for (Int_t i=0; i<3; i++) {pnt[i]=x[i]; norm[i]=p[i];}
  return kTRUE;
}//Intersect()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void AliHMPIDtrack::Propagate(Double_t len, Double_t x[3],Double_t p[3]) const {
  //+++++++++++++++++++++++++++++++++++++++++
  // Origin: K. Shileev (Kirill.Shileev@cern.ch)
  // Extrapolate track along simple helix in magnetic field
  // Arguments: len -distance alogn helix, [cm]
  //            bz  - mag field, [kGaus]
  // Returns: x and p contain extrapolated positon and momentum
  // The momentum returned for straight-line tracks is meaningless !
  //+++++++++++++++++++++++++++++++++++++++++
  GetXYZ(x);
  Double_t bField[3];
  TGeoGlobalMagField::Instance()->Field(x,bField);
  Double_t bz = -bField[2];
  if (OneOverPt() < kAlmost0 || TMath::Abs(bz) < kAlmost0Field ){ //straight-line tracks
     Double_t unit[3]; GetDirection(unit);
     x[0]+=unit[0]*len;
     x[1]+=unit[1]*len;
     x[2]+=unit[2]*len;

     p[0]=unit[0]/kAlmost0;
     p[1]=unit[1]/kAlmost0;
     p[2]=unit[2]/kAlmost0;
  } else {
     GetPxPyPz(p);
     Double_t pp=GetP();
     Double_t a = -kB2C*bz*GetSign(); ////////// what is kB2C
     Double_t rho = a/pp;
     x[0] += p[0]*TMath::Sin(rho*len)/a - p[1]*(1-TMath::Cos(rho*len))/a;
     x[1] += p[1]*TMath::Sin(rho*len)/a + p[0]*(1-TMath::Cos(rho*len))/a;
     x[2] += p[2]*len/pp;
     Double_t p0=p[0];
     p[0] = p0  *TMath::Cos(rho*len) - p[1]*TMath::Sin(rho*len);
     p[1] = p[1]*TMath::Cos(rho*len) + p0  *TMath::Sin(rho*len);
  }
}//Propagate()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Update(const AliHMPIDCluster *pClu, Double_t /*chisq*/, Int_t /*index*/)
{
  //
  // Arguments: AliCluster3D, chi sq, and clu index
  // Returns: kTRUE if the track parameters are successfully updated
  Double_t p[2]={pClu->GetY(), pClu->GetZ()};
  Double_t cov[3]={pClu->GetSigmaY2(), 0., pClu->GetSigmaZ2()};
  if (!AliExternalTrackParam::Update(p,cov)) return kFALSE;

  /*
  AliTracker::FillResiduals(this,p,cov,pClu->GetVolumeId());

  Int_t n=GetNumberOfClusters();
  fIndex[n]=index;
  SetNumberOfClusters(n+1);
  SetChi2(GetChi2()+chisq);
*/
  return kTRUE;

}//Update()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<|endoftext|>


<commit_before>/**************************************************************************
 * 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.                  *
 **************************************************************************/

#include "AliESDtrack.h"
#include "AliTracker.h"
#include "AliHMPIDtrack.h"

ClassImp(AliHMPIDtrack)

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack::AliHMPIDtrack():AliKalmanTrack()
{
  //
  // def. ctor
  //
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack::AliHMPIDtrack(const AliHMPIDtrack& t):AliKalmanTrack(t)
{
  //
  // cctor.
  //
 }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack::AliHMPIDtrack(const AliESDtrack& t):AliKalmanTrack()
{
  //
  // Constructor from AliESDtrack
  //
  SetLabel(t.GetLabel());
  SetChi2(0.);
  SetMass(t.GetMass());

  Set(t.GetX(),t.GetAlpha(),t.GetParameter(),t.GetCovariance());

  if ((t.GetStatus()&AliESDtrack::kTIME) == 0) return;
  StartTimeIntegral();
  Double_t times[10]; t.GetIntegratedTimes(times); SetIntegratedTimes(times);
  SetIntegratedLength(t.GetIntegratedLength());
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack& AliHMPIDtrack::operator=(const AliHMPIDtrack &/*source*/)
{
  // ass. op.

  return *this;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::PropagateTo(Double_t xk, Double_t xx0, Double_t xrho)
{
  //
  // Propagates this track to a reference plane defined by "xk" [cm]
  // correcting for the mean crossed material.
  // Arguments:
  // "xx0"  - thickness/rad.length [units of the radiation length]
  // "xrho" - thickness*density    [g/cm^2]
  //  Returns: kTRUE if the track propagates to plane, else kFALSE

  if (xk == GetX()) {
    return kTRUE;
  }
  Double_t bz   = GetBz();
  if (!AliExternalTrackParam::PropagateTo(xk,bz)) {
    return kFALSE;
  }
  if (!AliExternalTrackParam::CorrectForMeanMaterial(xx0,xrho,GetMass())) {
    return kFALSE;
  }
  return kTRUE;
}//PropagateTo()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Rotate(Double_t alpha, Bool_t absolute)
{
  //
  // Rotates track parameters in R*phi plane
  // if absolute rotation alpha is in global system
  // otherwise alpha rotation is relative to the current rotation angle
  //

  if (absolute) {
    alpha -= GetAlpha();
  }

  return AliExternalTrackParam::Rotate(GetAlpha()+alpha);

}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Int_t AliHMPIDtrack::GetProlongation(Double_t xk, Double_t &y, Double_t &z)
{
  //
  // Find a prolongation at given x
  // Return 0 if it does not exist
  //

  Double_t bz = GetBz();

  if (!AliExternalTrackParam::GetYAt(xk,bz,y)) {
    return 0;
  }
  if (!AliExternalTrackParam::GetZAt(xk,bz,z)) {
    return 0;
  }

  return 1;

}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t   AliHMPIDtrack::PropagateToR(Double_t r,Double_t step)
{
  //
  // Propagate track to the radial position
  // Rotation always connected to the last track position
  //

  Double_t xyz0[3];
  Double_t xyz1[3];
  Double_t y;
  Double_t z;

  Double_t radius = TMath::Sqrt(GetX()*GetX() + GetY()*GetY());
  // Direction +-
  Double_t dir    = (radius > r) ? -1.0 : 1.0;

  for (Double_t x = radius+dir*step; dir*x < dir*r; x += dir*step) {

    GetXYZ(xyz0);
    Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
    Rotate(alpha,kTRUE);
    GetXYZ(xyz0);
    GetProlongation(x,y,z);
    xyz1[0] = x * TMath::Cos(alpha) + y * TMath::Sin(alpha);
    xyz1[1] = x * TMath::Sin(alpha) - y * TMath::Cos(alpha);
    xyz1[2] = z;
    Double_t param[7];
    AliTracker::MeanMaterialBudget(xyz0,xyz1,param);
    if (param[1] <= 0) {
      param[1] = 100000000;
    }
    PropagateTo(x,param[1],param[0]*param[4]);

  }

  GetXYZ(xyz0);
  Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
  Rotate(alpha,kTRUE);
  GetXYZ(xyz0);
  GetProlongation(r,y,z);
  xyz1[0] = r * TMath::Cos(alpha) + y * TMath::Sin(alpha);
  xyz1[1] = r * TMath::Sin(alpha) - y * TMath::Cos(alpha);
  xyz1[2] = z;
  Double_t param[7];
  AliTracker::MeanMaterialBudget(xyz0,xyz1,param);

  if (param[1] <= 0) {
    param[1] = 100000000;
  }

  return PropagateTo(r,param[1],param[0]*param[4]);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Double_t AliHMPIDtrack::GetPredictedChi2(const AliCluster3D *c) const {
  //
  // Arguments: AliCluster3D
  // Returns:   Chi2 of track for the cluster
  Double_t      p[3]={c->GetX(),       c->GetY(),       c->GetZ()};
  Double_t  covyz[3]={c->GetSigmaY2(), c->GetSigmaYZ(), c->GetSigmaZ2()};
  Double_t covxyz[3]={c->GetSigmaX2(), c->GetSigmaXY(), c->GetSigmaXZ()};
  return AliExternalTrackParam::GetPredictedChi2(p, covyz, covxyz);
}//GetPredictedChi2()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::PropagateTo(const AliCluster3D *c) {
  //
  // Arguments: AliCluster3D
  // Returns: kTRUE if the track propagates to the plane of the cluster
  Double_t      oldX=GetX(),   oldY=GetY(), oldZ=GetZ();
  Double_t      p[3]={c->GetX(), c->GetY(), c->GetZ()};
  Double_t  covyz[3]={c->GetSigmaY2(), c->GetSigmaYZ(), c->GetSigmaZ2()};
  Double_t covxyz[3]={c->GetSigmaX2(), c->GetSigmaXY(), c->GetSigmaXZ()};
  Double_t bz=GetBz();

  if(!AliExternalTrackParam::PropagateTo(p, covyz, covxyz, bz)) return kFALSE;
  if(IsStartedTimeIntegral())
    {
      Double_t d = TMath::Sqrt((GetX()-oldX)*(GetX()-oldX) + (GetY()-oldY)*(GetY()-oldY) + (GetZ()-oldZ)*(GetZ()-oldZ));
      if (GetX()<oldX) d=-d;
      AddTimeStep(d);
  }
  return kTRUE;
}//PropagateTo()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Double_t AliHMPIDtrack::GetBz() const {
  //
  // Arguments: none
  // Returns: Bz component of the magnetic field (kG)
  //
  if (AliTracker::UniformField()) return AliTracker::GetBz();
  Double_t r[3]; GetXYZ(r);
  return AliTracker::GetBz(r);
}//GetBz()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Intersect(Double_t pnt[3], Double_t norm[3], Double_t bz) const {
  //+++++++++++++++++++++++++++++++++++++++++
  // Origin: K. Shileev (Kirill.Shileev@cern.ch)
  // Finds point of intersection (if exists) of the helix with the plane.
  // Stores result in fX and fP.
  // Arguments: planePoint,planeNorm - the plane defined by any plane's point
  // and vector, normal to the plane
  // Returns: kTrue if helix intersects the plane, kFALSE otherwise.
  //+++++++++++++++++++++++++++++++++++++++++
  Double_t x0[3]; GetXYZ(x0); //get track position in MARS

  //estimates initial helix length up to plane
  Double_t s=(pnt[0]-x0[0])*norm[0] + (pnt[1]-x0[1])*norm[1] + (pnt[2]-x0[2])*norm[2];
  Double_t dist=99999,distPrev=dist;
  Double_t x[3],p[3];
  while(TMath::Abs(dist)>0.00001){
    //calculates helix at the distance s from x0 ALONG the helix
    Propagate(s,x,p,bz);
    //distance between current helix position and plane
    dist=(x[0]-pnt[0])*norm[0]+(x[1]-pnt[1])*norm[1]+(x[2]-pnt[2])*norm[2];
    if(TMath::Abs(dist) >= TMath::Abs(distPrev)) {return kFALSE;}
    distPrev=dist;
    s-=dist;
  }
  //on exit pnt is intersection point,norm is track vector at that point,
  //all in MARS
  for (Int_t i=0; i<3; i++) {pnt[i]=x[i]; norm[i]=p[i];}
  return kTRUE;
}//Intersect()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Intersect(AliHMPIDtrack *pTrk,Double_t pnt[3], Double_t norm[3]) {
  // Finds point of intersection (if exists) of the helix with the plane.
  // Stores result in fX and fP.
  // Arguments: planePoint,planeNorm - the plane defined by any plane's point
  // and vector, normal to the plane
  // Returns: kTrue if helix intersects the plane, kFALSE otherwise.

  Double_t x0[3]; pTrk->GetXYZ(x0); //get track position in MARS
  Double_t dist=99999,distPrev=dist;
  Double_t x[3],p[3],
  pntrad= TMath::Sqrt(pnt[0]*pnt[0]+pnt[1]*pnt[1]);
  while(TMath::Abs(dist)> 0.000001){//0.00001){
    //calculates helix at the distance s from x0 ALONG the helix
    pTrk->PropagateTo(pntrad);pTrk->GetXYZ(x);pTrk->GetPxPyPz(p);
    //distance between current helix position and plane
    dist=(x[0]-pnt[0])*norm[0]+(x[1]-pnt[1])*norm[1]+(x[2]-pnt[2])*norm[2];
    pntrad=pntrad-dist*0.7;
    //Printf("--- 111 --- dist %lf",dist);
    if(TMath::Abs(2.0*dist) >= TMath::Abs(distPrev)) {return kFALSE;}
    distPrev=dist;
  }
  //on exit pnt is intersection point,norm is track vector at that point,
  //Printf("--- 222 --- dist %lf",dist);
  Printf("");
  for (Int_t i=0; i<3; i++) {pnt[i]=x[i]; norm[i]=p[i];}
  return kTRUE;
}//Intersect()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void AliHMPIDtrack::Propagate(Double_t len, Double_t x[3],Double_t p[3], Double_t bz) const {
  //+++++++++++++++++++++++++++++++++++++++++
  // Origin: K. Shileev (Kirill.Shileev@cern.ch)
  // Extrapolate track along simple helix in magnetic field
  // Arguments: len -distance alogn helix, [cm]
  //            bz  - mag field, [kGaus]
  // Returns: x and p contain extrapolated positon and momentum
  // The momentum returned for straight-line tracks is meaningless !
  //+++++++++++++++++++++++++++++++++++++++++
  GetXYZ(x);
  if (OneOverPt() < kAlmost0 || TMath::Abs(bz) < kAlmost0Field ){ //straight-line tracks
     Double_t unit[3]; GetDirection(unit);
     x[0]+=unit[0]*len;
     x[1]+=unit[1]*len;
     x[2]+=unit[2]*len;

     p[0]=unit[0]/kAlmost0;
     p[1]=unit[1]/kAlmost0;
     p[2]=unit[2]/kAlmost0;
  } else {
     GetPxPyPz(p);
     Double_t pp=GetP();
     Double_t a = -kB2C*bz*GetSign(); ////////// what is kB2C
     Double_t rho = a/pp;
     x[0] += p[0]*TMath::Sin(rho*len)/a - p[1]*(1-TMath::Cos(rho*len))/a;
     x[1] += p[1]*TMath::Sin(rho*len)/a + p[0]*(1-TMath::Cos(rho*len))/a;
     x[2] += p[2]*len/pp;
     Double_t p0=p[0];
     p[0] = p0  *TMath::Cos(rho*len) - p[1]*TMath::Sin(rho*len);
     p[1] = p[1]*TMath::Cos(rho*len) + p0  *TMath::Sin(rho*len);
  }
}//Propagate()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Update(const AliHMPIDCluster *pClu, Double_t chisq, Int_t index)
{
  //
  // Arguments: AliCluster3D, chi sq, and clu index
  // Returns: kTRUE if the track parameters are successfully updated
  Double_t p[2]={pClu->GetY(), pClu->GetZ()};
  Double_t cov[3]={pClu->GetSigmaY2(), 0., pClu->GetSigmaZ2()};
  if (!AliExternalTrackParam::Update(p,cov)) return kFALSE;

  /*
  AliTracker::FillResiduals(this,p,cov,pClu->GetVolumeId());

  Int_t n=GetNumberOfClusters();
  fIndex[n]=index;
  SetNumberOfClusters(n+1);
  SetChi2(GetChi2()+chisq);
*/
  return kTRUE;

}//Update()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<commit_msg>Protection to avoid an infinite loop on the track (suggested by PH)<commit_after>/**************************************************************************
 * 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.                  *
 **************************************************************************/

#include "AliESDtrack.h"
#include "AliTracker.h"
#include "AliHMPIDtrack.h"

ClassImp(AliHMPIDtrack)

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack::AliHMPIDtrack():AliKalmanTrack()
{
  //
  // def. ctor
  //
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack::AliHMPIDtrack(const AliHMPIDtrack& t):AliKalmanTrack(t)
{
  //
  // cctor.
  //
 }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack::AliHMPIDtrack(const AliESDtrack& t):AliKalmanTrack()
{
  //
  // Constructor from AliESDtrack
  //
  SetLabel(t.GetLabel());
  SetChi2(0.);
  SetMass(t.GetMass());

  Set(t.GetX(),t.GetAlpha(),t.GetParameter(),t.GetCovariance());

  if ((t.GetStatus()&AliESDtrack::kTIME) == 0) return;
  StartTimeIntegral();
  Double_t times[10]; t.GetIntegratedTimes(times); SetIntegratedTimes(times);
  SetIntegratedLength(t.GetIntegratedLength());
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AliHMPIDtrack& AliHMPIDtrack::operator=(const AliHMPIDtrack &/*source*/)
{
  // ass. op.

  return *this;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::PropagateTo(Double_t xk, Double_t xx0, Double_t xrho)
{
  //
  // Propagates this track to a reference plane defined by "xk" [cm]
  // correcting for the mean crossed material.
  // Arguments:
  // "xx0"  - thickness/rad.length [units of the radiation length]
  // "xrho" - thickness*density    [g/cm^2]
  //  Returns: kTRUE if the track propagates to plane, else kFALSE

  if (xk == GetX()) {
    return kTRUE;
  }
  Double_t bz   = GetBz();
  if (!AliExternalTrackParam::PropagateTo(xk,bz)) {
    return kFALSE;
  }
  if (!AliExternalTrackParam::CorrectForMeanMaterial(xx0,xrho,GetMass())) {
    return kFALSE;
  }
  return kTRUE;
}//PropagateTo()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Rotate(Double_t alpha, Bool_t absolute)
{
  //
  // Rotates track parameters in R*phi plane
  // if absolute rotation alpha is in global system
  // otherwise alpha rotation is relative to the current rotation angle
  //

  if (absolute) {
    alpha -= GetAlpha();
  }

  return AliExternalTrackParam::Rotate(GetAlpha()+alpha);

}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Int_t AliHMPIDtrack::GetProlongation(Double_t xk, Double_t &y, Double_t &z)
{
  //
  // Find a prolongation at given x
  // Return 0 if it does not exist
  //

  Double_t bz = GetBz();

  if (!AliExternalTrackParam::GetYAt(xk,bz,y)) {
    return 0;
  }
  if (!AliExternalTrackParam::GetZAt(xk,bz,z)) {
    return 0;
  }

  return 1;

}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t   AliHMPIDtrack::PropagateToR(Double_t r,Double_t step)
{
  //
  // Propagate track to the radial position
  // Rotation always connected to the last track position
  //

  Double_t xyz0[3];
  Double_t xyz1[3];
  Double_t y;
  Double_t z;

  Double_t radius = TMath::Sqrt(GetX()*GetX() + GetY()*GetY());
  // Direction +-
  Double_t dir    = (radius > r) ? -1.0 : 1.0;

  for (Double_t x = radius+dir*step; dir*x < dir*r; x += dir*step) {

    GetXYZ(xyz0);
    Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
    Rotate(alpha,kTRUE);
    GetXYZ(xyz0);
    if (!GetProlongation(x,y,z)) return kFALSE;
    xyz1[0] = x * TMath::Cos(alpha) + y * TMath::Sin(alpha);
    xyz1[1] = x * TMath::Sin(alpha) - y * TMath::Cos(alpha);
    xyz1[2] = z;
    Double_t param[7];
    AliTracker::MeanMaterialBudget(xyz0,xyz1,param);
    if (param[1] <= 0) {
      param[1] = 100000000;
    }
    PropagateTo(x,param[1],param[0]*param[4]);

  }

  GetXYZ(xyz0);
  Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
  Rotate(alpha,kTRUE);
  GetXYZ(xyz0);
  if (!GetProlongation(r,y,z)) return kFALSE;
  xyz1[0] = r * TMath::Cos(alpha) + y * TMath::Sin(alpha);
  xyz1[1] = r * TMath::Sin(alpha) - y * TMath::Cos(alpha);
  xyz1[2] = z;
  Double_t param[7];
  AliTracker::MeanMaterialBudget(xyz0,xyz1,param);

  if (param[1] <= 0) {
    param[1] = 100000000;
  }

  return PropagateTo(r,param[1],param[0]*param[4]);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Double_t AliHMPIDtrack::GetPredictedChi2(const AliCluster3D *c) const {
  //
  // Arguments: AliCluster3D
  // Returns:   Chi2 of track for the cluster
  Double_t      p[3]={c->GetX(),       c->GetY(),       c->GetZ()};
  Double_t  covyz[3]={c->GetSigmaY2(), c->GetSigmaYZ(), c->GetSigmaZ2()};
  Double_t covxyz[3]={c->GetSigmaX2(), c->GetSigmaXY(), c->GetSigmaXZ()};
  return AliExternalTrackParam::GetPredictedChi2(p, covyz, covxyz);
}//GetPredictedChi2()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::PropagateTo(const AliCluster3D *c) {
  //
  // Arguments: AliCluster3D
  // Returns: kTRUE if the track propagates to the plane of the cluster
  Double_t      oldX=GetX(),   oldY=GetY(), oldZ=GetZ();
  Double_t      p[3]={c->GetX(), c->GetY(), c->GetZ()};
  Double_t  covyz[3]={c->GetSigmaY2(), c->GetSigmaYZ(), c->GetSigmaZ2()};
  Double_t covxyz[3]={c->GetSigmaX2(), c->GetSigmaXY(), c->GetSigmaXZ()};
  Double_t bz=GetBz();

  if(!AliExternalTrackParam::PropagateTo(p, covyz, covxyz, bz)) return kFALSE;
  if(IsStartedTimeIntegral())
    {
      Double_t d = TMath::Sqrt((GetX()-oldX)*(GetX()-oldX) + (GetY()-oldY)*(GetY()-oldY) + (GetZ()-oldZ)*(GetZ()-oldZ));
      if (GetX()<oldX) d=-d;
      AddTimeStep(d);
  }
  return kTRUE;
}//PropagateTo()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Double_t AliHMPIDtrack::GetBz() const {
  //
  // Arguments: none
  // Returns: Bz component of the magnetic field (kG)
  //
  if (AliTracker::UniformField()) return AliTracker::GetBz();
  Double_t r[3]; GetXYZ(r);
  return AliTracker::GetBz(r);
}//GetBz()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Intersect(Double_t pnt[3], Double_t norm[3], Double_t bz) const {
  //+++++++++++++++++++++++++++++++++++++++++
  // Origin: K. Shileev (Kirill.Shileev@cern.ch)
  // Finds point of intersection (if exists) of the helix with the plane.
  // Stores result in fX and fP.
  // Arguments: planePoint,planeNorm - the plane defined by any plane's point
  // and vector, normal to the plane
  // Returns: kTrue if helix intersects the plane, kFALSE otherwise.
  //+++++++++++++++++++++++++++++++++++++++++
  Double_t x0[3]; GetXYZ(x0); //get track position in MARS

  //estimates initial helix length up to plane
  Double_t s=(pnt[0]-x0[0])*norm[0] + (pnt[1]-x0[1])*norm[1] + (pnt[2]-x0[2])*norm[2];
  Double_t dist=99999,distPrev=dist;
  Double_t x[3],p[3];
  while(TMath::Abs(dist)>0.00001){
    //calculates helix at the distance s from x0 ALONG the helix
    Propagate(s,x,p,bz);
    //distance between current helix position and plane
    dist=(x[0]-pnt[0])*norm[0]+(x[1]-pnt[1])*norm[1]+(x[2]-pnt[2])*norm[2];
    if(TMath::Abs(dist) >= TMath::Abs(distPrev)) {return kFALSE;}
    distPrev=dist;
    s-=dist;
  }
  //on exit pnt is intersection point,norm is track vector at that point,
  //all in MARS
  for (Int_t i=0; i<3; i++) {pnt[i]=x[i]; norm[i]=p[i];}
  return kTRUE;
}//Intersect()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Intersect(AliHMPIDtrack *pTrk,Double_t pnt[3], Double_t norm[3]) {
  // Finds point of intersection (if exists) of the helix with the plane.
  // Stores result in fX and fP.
  // Arguments: planePoint,planeNorm - the plane defined by any plane's point
  // and vector, normal to the plane
  // Returns: kTrue if helix intersects the plane, kFALSE otherwise.

  Double_t x0[3]; pTrk->GetXYZ(x0); //get track position in MARS
  Double_t dist=99999,distPrev=dist;
  Double_t x[3],p[3],
  pntrad= TMath::Sqrt(pnt[0]*pnt[0]+pnt[1]*pnt[1]);
  while(TMath::Abs(dist)> 0.000001){//0.00001){
    //calculates helix at the distance s from x0 ALONG the helix
    pTrk->PropagateTo(pntrad);pTrk->GetXYZ(x);pTrk->GetPxPyPz(p);
    //distance between current helix position and plane
    dist=(x[0]-pnt[0])*norm[0]+(x[1]-pnt[1])*norm[1]+(x[2]-pnt[2])*norm[2];
    pntrad=pntrad-dist*0.7;
    //Printf("--- 111 --- dist %lf",dist);
    if(TMath::Abs(2.0*dist) >= TMath::Abs(distPrev)) {return kFALSE;}
    distPrev=dist;
  }
  //on exit pnt is intersection point,norm is track vector at that point,
  //Printf("--- 222 --- dist %lf",dist);
  Printf("");
  for (Int_t i=0; i<3; i++) {pnt[i]=x[i]; norm[i]=p[i];}
  return kTRUE;
}//Intersect()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void AliHMPIDtrack::Propagate(Double_t len, Double_t x[3],Double_t p[3], Double_t bz) const {
  //+++++++++++++++++++++++++++++++++++++++++
  // Origin: K. Shileev (Kirill.Shileev@cern.ch)
  // Extrapolate track along simple helix in magnetic field
  // Arguments: len -distance alogn helix, [cm]
  //            bz  - mag field, [kGaus]
  // Returns: x and p contain extrapolated positon and momentum
  // The momentum returned for straight-line tracks is meaningless !
  //+++++++++++++++++++++++++++++++++++++++++
  GetXYZ(x);
  if (OneOverPt() < kAlmost0 || TMath::Abs(bz) < kAlmost0Field ){ //straight-line tracks
     Double_t unit[3]; GetDirection(unit);
     x[0]+=unit[0]*len;
     x[1]+=unit[1]*len;
     x[2]+=unit[2]*len;

     p[0]=unit[0]/kAlmost0;
     p[1]=unit[1]/kAlmost0;
     p[2]=unit[2]/kAlmost0;
  } else {
     GetPxPyPz(p);
     Double_t pp=GetP();
     Double_t a = -kB2C*bz*GetSign(); ////////// what is kB2C
     Double_t rho = a/pp;
     x[0] += p[0]*TMath::Sin(rho*len)/a - p[1]*(1-TMath::Cos(rho*len))/a;
     x[1] += p[1]*TMath::Sin(rho*len)/a + p[0]*(1-TMath::Cos(rho*len))/a;
     x[2] += p[2]*len/pp;
     Double_t p0=p[0];
     p[0] = p0  *TMath::Cos(rho*len) - p[1]*TMath::Sin(rho*len);
     p[1] = p[1]*TMath::Cos(rho*len) + p0  *TMath::Sin(rho*len);
  }
}//Propagate()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDtrack::Update(const AliHMPIDCluster *pClu, Double_t chisq, Int_t index)
{
  //
  // Arguments: AliCluster3D, chi sq, and clu index
  // Returns: kTRUE if the track parameters are successfully updated
  Double_t p[2]={pClu->GetY(), pClu->GetZ()};
  Double_t cov[3]={pClu->GetSigmaY2(), 0., pClu->GetSigmaZ2()};
  if (!AliExternalTrackParam::Update(p,cov)) return kFALSE;

  /*
  AliTracker::FillResiduals(this,p,cov,pClu->GetVolumeId());

  Int_t n=GetNumberOfClusters();
  fIndex[n]=index;
  SetNumberOfClusters(n+1);
  SetChi2(GetChi2()+chisq);
*/
  return kTRUE;

}//Update()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<|endoftext|>


<commit_before>// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

#include "CompressRGB.h"
#include "CompressionOptions.h"
#include "OutputOptions.h"

#include <nvimage/Image.h>
#include <nvimage/FloatImage.h>
#include <nvimage/PixelFormat.h>

#include <nvmath/Color.h>
#include <nvmath/half.h>

#include <nvcore/Debug.h>

using namespace nv;
using namespace nvtt;

namespace
{

	inline uint computePitch(uint w, uint bitsize)
	{
		uint p = w * ((bitsize + 7) / 8);

		// Align to 32 bits.
		return ((p + 3) / 4) * 4;
	}

	inline void convert_to_a8r8g8b8(const void * src, void * dst, uint w)
	{
		memcpy(dst, src, 4 * w);
	}

	inline void convert_to_x8r8g8b8(const void * src, void * dst, uint w)
	{
		memcpy(dst, src, 4 * w);
	}

} // namespace

// Pixel format converter.
void nv::compressRGB(const Image * image, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
{
	nvCheck(image != NULL);

	const uint w = image->width();
	const uint h = image->height();

	uint bitCount;
	uint rmask, rshift, rsize;
	uint gmask, gshift, gsize;
	uint bmask, bshift, bsize;
	uint amask, ashift, asize;

	if (compressionOptions.bitcount != 0)
	{
		bitCount = compressionOptions.bitcount;
		nvCheck(bitCount == 8 || bitCount == 16 || bitCount == 24 || bitCount == 32);

		rmask = compressionOptions.rmask;
		gmask = compressionOptions.gmask;
		bmask = compressionOptions.bmask;
		amask = compressionOptions.amask;

		PixelFormat::maskShiftAndSize(rmask, &rshift, &rsize);
		PixelFormat::maskShiftAndSize(gmask, &gshift, &gsize);
		PixelFormat::maskShiftAndSize(bmask, &bshift, &bsize);
		PixelFormat::maskShiftAndSize(amask, &ashift, &asize);
	}
	else
	{
		rsize = compressionOptions.rsize;
		gsize = compressionOptions.gsize;
		bsize = compressionOptions.bsize;
		asize = compressionOptions.asize;

		bitCount = rsize + gsize + bsize + asize;
		nvCheck(bitCount <= 32);

		ashift = 0;
		bshift = ashift + asize;
		gshift = bshift + bsize;
		rshift = gshift + gsize;

		rmask = ((1 << rsize) - 1) << rshift;
		gmask = ((1 << gsize) - 1) << gshift;
		bmask = ((1 << bsize) - 1) << bshift;
		amask = ((1 << asize) - 1) << ashift;
	}

	const uint byteCount = bitCount / 8;

	// Determine pitch.
	uint pitch = computePitch(w, bitCount);

	uint8 * dst = (uint8 *)mem::malloc(pitch + 4);

	for (uint y = 0; y < h; y++)
	{
		const Color32 * src = image->scanline(y);

		if (bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0xFF000000)
		{
			convert_to_a8r8g8b8(src, dst, w);
		}
		else if (bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0)
		{
			convert_to_x8r8g8b8(src, dst, w);
		}
		else
		{
			// Generic pixel format conversion.
			for (uint x = 0; x < w; x++)
			{
				uint c = 0;
				c |= PixelFormat::convert(src[x].r, 8, rsize) << rshift;
				c |= PixelFormat::convert(src[x].g, 8, gsize) << gshift;
				c |= PixelFormat::convert(src[x].b, 8, bsize) << bshift;
				c |= PixelFormat::convert(src[x].a, 8, asize) << ashift;

				// Output one byte at a time.
				for (uint i = 0; i < byteCount; i++)
				{
					*(dst + x * byteCount + i) = (c >> (i * 8)) & 0xFF;
				}
			}

			// Zero padding.
			for (uint x = w; x < pitch; x++)
			{
				*(dst + x) = 0;
			}
		}

		if (outputOptions.outputHandler != NULL)
		{
			outputOptions.outputHandler->writeData(dst, pitch);
		}
	}

	mem::free(dst);
}

void nv::compressRGB(const FloatImage * image, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
{
	nvCheck(image != NULL);

	const uint w = image->width();
	const uint h = image->height();

	const uint rsize = compressionOptions.rsize;
	const uint gsize = compressionOptions.gsize;
	const uint bsize = compressionOptions.bsize;
	const uint asize = compressionOptions.asize;

	nvCheck(rsize == 0 || rsize == 16 || rsize == 32);
	nvCheck(gsize == 0 || gsize == 16 || gsize == 32);
	nvCheck(bsize == 0 || bsize == 16 || bsize == 32);
	nvCheck(asize == 0 || asize == 16 || asize == 32);

	const uint bitCount = rsize + gsize + bsize + asize;
	const uint byteCount = bitCount / 8;
	const uint pitch = w * byteCount;

	uint8 * dst = (uint8 *)mem::malloc(pitch);

	for (uint y = 0; y < h; y++)
	{
		const float * rchannel = image->scanline(y, 0);
		const float * gchannel = image->scanline(y, 1);
		const float * bchannel = image->scanline(y, 2);
		const float * achannel = image->scanline(y, 3);

		union FLOAT
		{
			float f;
			uint32 u;
		};

		uint8 * ptr = dst;

		for (uint x = 0; x < w; x++)
		{
			FLOAT r, g, b, a;
			r.f = rchannel[x];
			g.f = gchannel[x];
			b.f = bchannel[x];
			a.f = achannel[x];

			if (rsize == 32) *((uint32 *)ptr) = r.u;
			else if (rsize == 16) *((uint16 *)ptr) = half_from_float(r.u);
			ptr += rsize / 8;

			if (gsize == 32) *((uint32 *)ptr) = g.u;
			else if (gsize == 16) *((uint16 *)ptr) = half_from_float(g.u);
			ptr += gsize / 8;

			if (bsize == 32) *((uint32 *)ptr) = b.u;
			else if (bsize == 16) *((uint16 *)ptr) = half_from_float(b.u);
			ptr += bsize / 8;

			if (asize == 32) *((uint32 *)ptr) = a.u;
			else if (asize == 16) *((uint16 *)ptr) = half_from_float(a.u);
			ptr += asize / 8;
		}

		if (outputOptions.outputHandler != NULL)
		{
			outputOptions.outputHandler->writeData(dst, pitch);
		}
	}

	mem::free(dst);
}
<commit_msg>Fix linux includes.<commit_after>// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

#include "CompressRGB.h"
#include "CompressionOptions.h"
#include "OutputOptions.h"

#include <nvimage/Image.h>
#include <nvimage/FloatImage.h>
#include <nvimage/PixelFormat.h>

#include <nvmath/Color.h>
#include <nvmath/Half.h>

#include <nvcore/Debug.h>

using namespace nv;
using namespace nvtt;

namespace
{

	inline uint computePitch(uint w, uint bitsize)
	{
		uint p = w * ((bitsize + 7) / 8);

		// Align to 32 bits.
		return ((p + 3) / 4) * 4;
	}

	inline void convert_to_a8r8g8b8(const void * src, void * dst, uint w)
	{
		memcpy(dst, src, 4 * w);
	}

	inline void convert_to_x8r8g8b8(const void * src, void * dst, uint w)
	{
		memcpy(dst, src, 4 * w);
	}

} // namespace

// Pixel format converter.
void nv::compressRGB(const Image * image, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
{
	nvCheck(image != NULL);

	const uint w = image->width();
	const uint h = image->height();

	uint bitCount;
	uint rmask, rshift, rsize;
	uint gmask, gshift, gsize;
	uint bmask, bshift, bsize;
	uint amask, ashift, asize;

	if (compressionOptions.bitcount != 0)
	{
		bitCount = compressionOptions.bitcount;
		nvCheck(bitCount == 8 || bitCount == 16 || bitCount == 24 || bitCount == 32);

		rmask = compressionOptions.rmask;
		gmask = compressionOptions.gmask;
		bmask = compressionOptions.bmask;
		amask = compressionOptions.amask;

		PixelFormat::maskShiftAndSize(rmask, &rshift, &rsize);
		PixelFormat::maskShiftAndSize(gmask, &gshift, &gsize);
		PixelFormat::maskShiftAndSize(bmask, &bshift, &bsize);
		PixelFormat::maskShiftAndSize(amask, &ashift, &asize);
	}
	else
	{
		rsize = compressionOptions.rsize;
		gsize = compressionOptions.gsize;
		bsize = compressionOptions.bsize;
		asize = compressionOptions.asize;

		bitCount = rsize + gsize + bsize + asize;
		nvCheck(bitCount <= 32);

		ashift = 0;
		bshift = ashift + asize;
		gshift = bshift + bsize;
		rshift = gshift + gsize;

		rmask = ((1 << rsize) - 1) << rshift;
		gmask = ((1 << gsize) - 1) << gshift;
		bmask = ((1 << bsize) - 1) << bshift;
		amask = ((1 << asize) - 1) << ashift;
	}

	const uint byteCount = bitCount / 8;

	// Determine pitch.
	uint pitch = computePitch(w, bitCount);

	uint8 * dst = (uint8 *)mem::malloc(pitch + 4);

	for (uint y = 0; y < h; y++)
	{
		const Color32 * src = image->scanline(y);

		if (bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0xFF000000)
		{
			convert_to_a8r8g8b8(src, dst, w);
		}
		else if (bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0)
		{
			convert_to_x8r8g8b8(src, dst, w);
		}
		else
		{
			// Generic pixel format conversion.
			for (uint x = 0; x < w; x++)
			{
				uint c = 0;
				c |= PixelFormat::convert(src[x].r, 8, rsize) << rshift;
				c |= PixelFormat::convert(src[x].g, 8, gsize) << gshift;
				c |= PixelFormat::convert(src[x].b, 8, bsize) << bshift;
				c |= PixelFormat::convert(src[x].a, 8, asize) << ashift;

				// Output one byte at a time.
				for (uint i = 0; i < byteCount; i++)
				{
					*(dst + x * byteCount + i) = (c >> (i * 8)) & 0xFF;
				}
			}

			// Zero padding.
			for (uint x = w; x < pitch; x++)
			{
				*(dst + x) = 0;
			}
		}

		if (outputOptions.outputHandler != NULL)
		{
			outputOptions.outputHandler->writeData(dst, pitch);
		}
	}

	mem::free(dst);
}

void nv::compressRGB(const FloatImage * image, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
{
	nvCheck(image != NULL);

	const uint w = image->width();
	const uint h = image->height();

	const uint rsize = compressionOptions.rsize;
	const uint gsize = compressionOptions.gsize;
	const uint bsize = compressionOptions.bsize;
	const uint asize = compressionOptions.asize;

	nvCheck(rsize == 0 || rsize == 16 || rsize == 32);
	nvCheck(gsize == 0 || gsize == 16 || gsize == 32);
	nvCheck(bsize == 0 || bsize == 16 || bsize == 32);
	nvCheck(asize == 0 || asize == 16 || asize == 32);

	const uint bitCount = rsize + gsize + bsize + asize;
	const uint byteCount = bitCount / 8;
	const uint pitch = w * byteCount;

	uint8 * dst = (uint8 *)mem::malloc(pitch);

	for (uint y = 0; y < h; y++)
	{
		const float * rchannel = image->scanline(y, 0);
		const float * gchannel = image->scanline(y, 1);
		const float * bchannel = image->scanline(y, 2);
		const float * achannel = image->scanline(y, 3);

		union FLOAT
		{
			float f;
			uint32 u;
		};

		uint8 * ptr = dst;

		for (uint x = 0; x < w; x++)
		{
			FLOAT r, g, b, a;
			r.f = rchannel[x];
			g.f = gchannel[x];
			b.f = bchannel[x];
			a.f = achannel[x];

			if (rsize == 32) *((uint32 *)ptr) = r.u;
			else if (rsize == 16) *((uint16 *)ptr) = half_from_float(r.u);
			ptr += rsize / 8;

			if (gsize == 32) *((uint32 *)ptr) = g.u;
			else if (gsize == 16) *((uint16 *)ptr) = half_from_float(g.u);
			ptr += gsize / 8;

			if (bsize == 32) *((uint32 *)ptr) = b.u;
			else if (bsize == 16) *((uint16 *)ptr) = half_from_float(b.u);
			ptr += bsize / 8;

			if (asize == 32) *((uint32 *)ptr) = a.u;
			else if (asize == 16) *((uint16 *)ptr) = half_from_float(a.u);
			ptr += asize / 8;
		}

		if (outputOptions.outputHandler != NULL)
		{
			outputOptions.outputHandler->writeData(dst, pitch);
		}
	}

	mem::free(dst);
}
<|endoftext|>


<commit_before>/*
http://olimpiada.ic.unicamp.br/pratique/programacao/nivel1/2012f1p1_corrida
*/

#include <iostream>

using namespace std;

int main(){

    // VARS
    int c; // o quanto pretende correr
    int n; // comprimento da pista

    // INPUTS
    cin >> c;
    cin >> n;

    // PROCESSAMENTO
    int resto = c % n; // o C percorre completamente N o quanto
                    // for possível. Depois disso, o resto
                    // é o que, obviamente, resta pra
                    // correr.

    cout << resto << endl;

    return 0;
}
<commit_msg>Update corrida.cpp<commit_after>/*
http://olimpiada.ic.unicamp.br/pratique/programacao/nivel1/2012f1p1_corrida
*/

#include <iostream>

using namespace std;

int main(){

    // VARS
    int c; // o quanto pretende correr
    int n; // comprimento da pista

    // INPUTS
    cin >> c;
    cin >> n;

    // CÁLCULO
    int resto = c % n; // o C percorre completamente N o quanto
                    // for possível. Depois disso, o resto
                    // é o que, obviamente, resta pra
                    // correr.

    // OUTPUT
    cout << resto << endl;

    return 0;
}
<|endoftext|>


<commit_before>/*
 * Win/Dos JarLauncher.
 *
 * <pre>
 * (c) Piter.NL 2004-2013
 * </pre>
 *
 * @Author:  Piter T. de Boer
 */

#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <string>
#include "ptc/ptcutil.hpp"
#include "debug.hpp"

#define JAVA_HOME         "JAVA_HOME"

// ============================================
// vbrowser.ini properties:
// ============================================

#define JAVA_VMARGS_PROP   "java.vmargs"
#define JAVA_EXE_PROP      "java.exe"
#define JAVA_HOME_PROP     "java.home"
// actual jarfile to start:
#define JAVA_MAINJAR_PROP "java.mainjar"

// Java commands:
#define JAVAW_EXE   "javaw.exe"

#define MAX_TEXT_BUFFER 9999

/**
 * Enhanced Java Bootstrap Loader:
 * - Takes basename of executable as "main" and starts ${main}.jar
 * - optionally uses ${main}.ini as config file.
 *   For example vbrowser.exe will start vbrowser.jar and optionally use vbrowser.ini
 * - Checks Registry for default Java Installation.
 * - JAVA_HOME specifies the java location. Default is to the one from the path.
 */

char *java_vmargs = NULL;
char *java_home = NULL;
char *java_exe = NULL;
char *main_ini = NULL;
char *main_jar = NULL;

// Read ${MAIN}.ini file and parse <prop>=<value>  lines.

int readini(char *filename)
{
    FILE *fp = fopen(filename, "r");
    if (!fp)
    {
        return 0;
    }
    // ====================
    // Read "vbrowser.ini"
    // ====================

    char *line = NULL;
    DEBUGPRINTF("Reading ini file: %s\n",filename);

    do
    {
        line = Freadline(fp);
        if (line == NULL)
            break; //EOF

        if (line[0] == '#')
            continue; //comments

        if (line[0] == '[')
            continue; // section

        DEBUGPRINTF(" - parsing line: '%s'\n",line);
        char *name = NULL;
        char *value = NULL;
        int pos = Ssplit(line, '=', &name, &value);

        if (pos > 0)
        {
            if (Scompare(name, JAVA_VMARGS_PROP) == 0)
            {
                java_vmargs = value;
                DEBUGPRINTF(" + found: java.vmargs=%s\n",java_vmargs);
            }
            else if (Scompare(name, JAVA_EXE_PROP) == 0)
            {
                java_exe = value;
                DEBUGPRINTF(" + found: java.exe=%s\n",java_vmargs);
            }
            else if (Scompare(name, JAVA_HOME_PROP) == 0)
            {
                java_home = value;
                DEBUGPRINTF(" + found: java.home=%s\n",java_vmargs);
            }
            else if (Scompare(name, JAVA_MAINJAR_PROP) == 0)
            {
                main_jar = value;
                DEBUGPRINTF(" + found: java.mainjar=%s\n",java_vmargs);
            }

        }

    } while (line != NULL);

    fclose(fp);
}

#define JAVA_JRE_REGISTRY_KEY "SOFTWARE\\JavaSoft\\Java Runtime Environment"
#define JAVA_JDK_REGISTRY_KEY "SOFTWARE\\JavaSoft\\Java Development Kit"
#define JAVA_REGISTRY_CURRENT_VERSION "CurrentVersion"

const char* getRegistryJavaHome()
{
    const char *javaRegKey = JAVA_JRE_REGISTRY_KEY;
    //const char *javaRegKey =JAVA_JDK_REGISTRY_KEY ;

    int result = 0;
    char value[MAX_TEXT_BUFFER];

    // SystemRoot:
    value[0] = 0;
    DWORD bufferSize = (DWORD) MAX_TEXT_BUFFER;
    result = RegGetValue(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion", "SystemRoot",
                         RRF_RT_ANY,
                         NULL,
                         (PVOID) &value,
                         &bufferSize);

    // Could search for Java here:
    DEBUGPRINTF(" - Windows SystemRoot='%s' (result=%d)\n",value,result);

    // JDK Java Current Version
    value[0] = 0;
    bufferSize = (DWORD) MAX_TEXT_BUFFER;
    result = RegGetValue(HKEY_LOCAL_MACHINE, JAVA_JDK_REGISTRY_KEY, "CurrentVersion",
                         RRF_RT_ANY,
                         NULL,
                         (PVOID) &value,
                         &bufferSize);

    DEBUGPRINTF(" - JDK Java Version='%s' (result=%d) \n",value,result);
    const char* javaVersion = Sduplicate(value);

    // JRE Java Current Version
    value[0] = 0;
    bufferSize = (DWORD) MAX_TEXT_BUFFER;
    result = RegGetValue(HKEY_LOCAL_MACHINE, javaRegKey, "CurrentVersion",
                         RRF_RT_ANY,
                         NULL,
                         (PVOID) &value,
                         &bufferSize);

    DEBUGPRINTF(" - JRE Java Version='%s' (result=%d) \n",value,result);

    // <Current Version>\\Java Home
    std::string javaCurrentRegKey = std::string(javaRegKey) + "\\" + javaVersion;
    DEBUGPRINTF(" - javaCurrentRegKey (jre)='%s'\n",javaCurrentRegKey.c_str());

    value[0] = 0;
    bufferSize = (DWORD) MAX_TEXT_BUFFER;
    result = RegGetValue(HKEY_LOCAL_MACHINE, javaCurrentRegKey.c_str(), "JavaHome",
                         RRF_RT_ANY,
                         NULL,
                         (PVOID) &value,
                         &bufferSize);

    DEBUGPRINTF(" - JavaHome(1)='%s' (result=%d)\n",value,result);

    if (value[0] == 0) {
        DEBUGPRINTF(" - JavaHome='%s'\n","NULL!");
        return NULL;
    }

    const char *javaHome = Sduplicate(value);
    DEBUGPRINTF(" - JavaHome(2)='%s'\n",javaHome);
    return javaHome;
}

const char *nonullstring(const char *string, const char *defaultString)
{
    if (string != NULL)
        return string;

    if (defaultString != NULL)
        return defaultString;

    return "<NULL>";
}

// ===
// Main
// ===

int WINAPI WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
{
    char jcmd[MAX_PATH+256];
    char exepath[MAX_PATH+256];
    char *dirname=NULL;
    char *basename=NULL;

    // Check Startup Environment

    // get path of this executable
    GetModuleFileName(hInstance, exepath, MAX_PATH);

    // strip last part of exepath (dirname);
    char *sepc = strrchr(exepath, '\\');
    basename=strdup(sepc+1);
    sepc[0] = '\0';
    dirname=strdup(exepath);

    DEBUGPRINTF(" - dirname=%s\n",dirname);
    DEBUGPRINTF(" - full basename=%s\n",basename);

    // remove .exe: truncate
    if (strlen(basename)>4)
    {
        basename[strlen(basename)-4]=0;
    }

    // truncate exepath!
    main_jar=Sappend(basename,".jar");// default mainjar to exectuable name!
    main_ini=Sappend(basename,".ini");

    // exepath now points to basedir of installation !
    // cd to basedir of installation.
    SetCurrentDirectory(exepath);

    // ================
    // Read ${MAIN}.ini
    // ================
    // might change default settings!
    readini(main_ini);

    // Defaults if not specified in config file
    if (java_home==NULL)
    {
        java_home=getenv(JAVA_HOME);
        // Environment Variable can have quotes:
        java_home=SstripQuotes(java_home);
    }

    DEBUGPRINTF(" - getenv(JAVA_HOME)=%s\n",nonullstring(java_home,"<undefined>"));

    const char *javaRegistryHome=getRegistryJavaHome();

    DEBUGPRINTF(" - Registry JavaHome=%s\n",nonullstring(javaRegistryHome,"<undefined>"));

    // Environment variable JAVA_HOME overides Registry JavaHome (if set):
    if ((java_home==NULL) && (javaRegistryHome!=NULL))
    {
        java_home=Sduplicate(javaRegistryHome);
    }

    if (java_exe==NULL)
    {
        java_exe=Sduplicate(JAVAW_EXE);
    }

    // ***
    // Create start command:
    // ***

    char *javaws_path=NULL;

    // TODO: if $VLET_INSTALL/jre1.6/ exists use $VLET_INSTALL/jre1.6/

    if (java_home!=NULL)
    {
        sprintf(jcmd,"%s\\bin\\%s ",java_home,java_exe);
    }
    else
    {
        // No JAVA_HOME: use javaw only:
        sprintf(jcmd,"%s ",java_exe);
    }

    // keep copy of path
    javaws_path=strdup(jcmd);

    // Add optional VMArgs:
    if (java_vmargs!=NULL)
    {
        strcat(jcmd, java_vmargs);
        strcat(jcmd, " ");  // add space:
    }

    // add -jar command
    {
        // start with -jar <MAINJAR>
        strcat(jcmd,"-jar ");
        strcat(jcmd, main_jar);
        strcat(jcmd, " ");
    }

    // append other command line options:
    if ((lpCmdLine!=NULL) && (lpCmdLine[0]!=0))
    {
        strcat(jcmd, lpCmdLine);
    }

    fprintf(stderr," Jarlauncher cwd = %s\n",nonullstring(exepath,"<undefined>"));
    fprintf(stderr," Jarlauncher jar = %s\n",nonullstring(main_jar,"<undefined>"));
    fprintf(stderr," Jarlauncher ini = %s\n",nonullstring(main_ini,"<undefined>"));
    fprintf(stderr," JAVA_HOME       = %s\n",nonullstring(java_home,"<undefined>"));
    fprintf(stderr," vmarguments     = %s\n",nonullstring(java_vmargs,"")); // empty is allowed
    fprintf(stderr," arguments       = %s\n",nonullstring(lpCmdLine,""));
    fprintf(stderr," commandline     = %s\n",jcmd);// actual command
    fprintf(stderr,"\n");

    if (Scompare(lpCmdLine,"-info")==0)
    {
        // exit;
        return 0;
    }

    /* Check javaw.exe, but only if a hardcoded JAVA_HOME is given */
    if ((java_home!=NULL) && (Fexists(javaws_path)==0))
    {
        char *message=Sappend("*** Jarlauncher Exception ***\n",
                              "javaw.exe not found:",
                              javaws_path);
        fprintf(stderr,"\n*** Jarlauncher: javaw not found:%s***\n",javaws_path);
        MessageBox(NULL,message,"Java Error", MB_OK);
        return 101;
    }

    if (Fexists(main_jar)==0)
    {
        char *message=Sappend("*** Jarlauncher Exception ***\n",
                              "Jarfile doesn't exist or is unreadable:",
                              main_jar);
        //strcat(message,".");
        fprintf(stderr,"\n*** Jarlauncher: file open error:%s***\n",main_jar);
        MessageBox(NULL,message,"File Error", MB_OK);
        return 102;
    }

    // ***
    // exec
    // ***

    unsigned int result=WinExec(jcmd, SW_SHOW);

    if (result>31)
    {
        DEBUGPRINTF(" Java started...\n","");
    }
    else
    {
        fprintf(stderr,"return code=%i\n",result);

        if (result==2)
        {
            char *message=Sappend("*** Jarlauncher Exception ***\n",
                                  "Java couldn't be started or Java isn't properly installed.");
            //strcat(message,".");
            fprintf(stderr,"\n*** Jarlauncher: Java couldn't be started:%s***\n",jcmd);
            MessageBox(NULL,message,"Java Error", MB_OK);
        }
        else
        {
            char *message=Sappend("*** Jarlauncher Exception ***\n",
                                  "Unknown error occured.");
            //strcat(message,".");
            fprintf(stderr,"\n*** Jarlauncher: Unknown error:%i***\n",result);
            MessageBox(NULL,message,"Java Error", MB_OK);
        }

        return result;
    }

    return 0;
}

<commit_msg>Debugging output now prints correct values. <commit_after>/*
 * Win/Dos JarLauncher.
 *
 * <pre>
 * (c) Piter.NL 2004-2013
 * </pre>
 *
 * @Author:  Piter T. de Boer
 */

#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <string>
#include "ptc/ptcutil.hpp"
#include "debug.hpp"

#define JAVA_HOME         "JAVA_HOME"

// ============================================
// vbrowser.ini properties:
// ============================================

#define JAVA_VMARGS_PROP   "java.vmargs"
#define JAVA_EXE_PROP      "java.exe"
#define JAVA_HOME_PROP     "java.home"
// actual jarfile to start:
#define JAVA_MAINJAR_PROP "java.mainjar"

// Java commands:
#define JAVAW_EXE   "javaw.exe"

#define MAX_TEXT_BUFFER 9999

/**
 * Enhanced Java Bootstrap Loader:
 * - Takes basename of executable as "main" and starts ${main}.jar
 * - optionally uses ${main}.ini as config file.
 *   For example vbrowser.exe will start vbrowser.jar and optionally use vbrowser.ini
 * - Checks Registry for default Java Installation.
 * - JAVA_HOME specifies the java location. Default is to the one from the path.
 */

char *java_vmargs = NULL;
char *java_home = NULL;
char *java_exe = NULL;
char *main_ini = NULL;
char *main_jar = NULL;

// Read ${MAIN}.ini file and parse <prop>=<value>  lines.

int readini(char *filename)
{
    FILE *fp = fopen(filename, "r");
    if (!fp)
    {
        return 0;
    }
    // ====================
    // Read "vbrowser.ini"
    // ====================

    char *line = NULL;
    DEBUGPRINTF("Reading ini file: %s\n",filename);

    do
    {
        line = Freadline(fp);
        if (line == NULL)
            break; //EOF

        if (line[0] == '#')
            continue; //comments

        if (line[0] == '[')
            continue; // section

        DEBUGPRINTF(" - parsing line: '%s'\n",line);
        char *name = NULL;
        char *value = NULL;
        int pos = Ssplit(line, '=', &name, &value);

        if (pos > 0)
        {
            if (Scompare(name, JAVA_VMARGS_PROP) == 0)
            {
                java_vmargs = value;
                DEBUGPRINTF(" + found: java.vmargs=%s\n",java_vmargs);
            }
            else if (Scompare(name, JAVA_EXE_PROP) == 0)
            {
                java_exe = value;
                DEBUGPRINTF(" + found: java.exe=%s\n",java_exe);
            }
            else if (Scompare(name, JAVA_HOME_PROP) == 0)
            {
                java_home = value;
                DEBUGPRINTF(" + found: java.home=%s\n",java_home);
            }
            else if (Scompare(name, JAVA_MAINJAR_PROP) == 0)
            {
                main_jar = value;
                DEBUGPRINTF(" + found: java.mainjar=%s\n",main_jar);
            }
        }

    } while (line != NULL);

    fclose(fp);
}

#define JAVA_JRE_REGISTRY_KEY "SOFTWARE\\JavaSoft\\Java Runtime Environment"
#define JAVA_JDK_REGISTRY_KEY "SOFTWARE\\JavaSoft\\Java Development Kit"
#define JAVA_REGISTRY_CURRENT_VERSION "CurrentVersion"

const char* getRegistryJavaHome()
{
    const char *javaRegKey = JAVA_JRE_REGISTRY_KEY;
    //const char *javaRegKey =JAVA_JDK_REGISTRY_KEY ;

    int result = 0;
    char value[MAX_TEXT_BUFFER];

    // SystemRoot:
    value[0] = 0;
    DWORD bufferSize = (DWORD) MAX_TEXT_BUFFER;
    result = RegGetValue(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion", "SystemRoot",
                         RRF_RT_ANY,
                         NULL,
                         (PVOID) &value,
                         &bufferSize);

    // Could search for Java here:
    DEBUGPRINTF(" - Windows SystemRoot='%s' (result=%d)\n",value,result);

    // JDK Java Current Version
    value[0] = 0;
    bufferSize = (DWORD) MAX_TEXT_BUFFER;
    result = RegGetValue(HKEY_LOCAL_MACHINE, JAVA_JDK_REGISTRY_KEY, "CurrentVersion",
                         RRF_RT_ANY,
                         NULL,
                         (PVOID) &value,
                         &bufferSize);

    DEBUGPRINTF(" - JDK Java Version='%s' (result=%d) \n",value,result);
    const char* javaVersion = Sduplicate(value);

    // JRE Java Current Version
    value[0] = 0;
    bufferSize = (DWORD) MAX_TEXT_BUFFER;
    result = RegGetValue(HKEY_LOCAL_MACHINE, javaRegKey, "CurrentVersion",
                         RRF_RT_ANY,
                         NULL,
                         (PVOID) &value,
                         &bufferSize);

    DEBUGPRINTF(" - JRE Java Version='%s' (result=%d) \n",value,result);

    // <Current Version>\\Java Home
    std::string javaCurrentRegKey = std::string(javaRegKey) + "\\" + javaVersion;
    DEBUGPRINTF(" - javaCurrentRegKey (jre)='%s'\n",javaCurrentRegKey.c_str());

    value[0] = 0;
    bufferSize = (DWORD) MAX_TEXT_BUFFER;
    result = RegGetValue(HKEY_LOCAL_MACHINE, javaCurrentRegKey.c_str(), "JavaHome",
                         RRF_RT_ANY,
                         NULL,
                         (PVOID) &value,
                         &bufferSize);

    DEBUGPRINTF(" - JavaHome(1)='%s' (result=%d)\n",value,result);

    if (value[0] == 0)
    {
        DEBUGPRINTF(" - JavaHome='%s'\n","NULL!");
        return NULL;
    }

    const char *javaHome = Sduplicate(value);
    DEBUGPRINTF(" - JavaHome(2)='%s'\n",javaHome);
    return javaHome;
}

const char *nonullstring(const char *string, const char *defaultString)
{
    if (string != NULL)
        return string;

    if (defaultString != NULL)
        return defaultString;

    return "<NULL>";
}

// ===
// Main
// ===

int WINAPI WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
{
    char jcmd[MAX_PATH+256];
    char exepath[MAX_PATH+256];
    char *dirname=NULL;
    char *basename=NULL;

    // Check Startup Environment

    // get path of this executable
    GetModuleFileName(hInstance, exepath, MAX_PATH);

    // strip last part of exepath (dirname);
    char *sepc = strrchr(exepath, '\\');
    basename=strdup(sepc+1);
    sepc[0] = '\0';
    dirname=strdup(exepath);

    DEBUGPRINTF(" - dirname=%s\n",dirname);
    DEBUGPRINTF(" - full basename=%s\n",basename);

    // remove .exe: truncate
    if (strlen(basename)>4)
    {
        basename[strlen(basename)-4]=0;
    }

    // truncate exepath!
    main_jar=Sappend(basename,".jar");// default mainjar to exectuable name!
    main_ini=Sappend(basename,".ini");

    // exepath now points to basedir of installation !
    // cd to basedir of installation.
    SetCurrentDirectory(exepath);

    // ================
    // Read ${MAIN}.ini
    // ================
    // might change default settings!
    readini(main_ini);

    // Defaults if not specified in config file
    if (java_home==NULL)
    {
        java_home=getenv(JAVA_HOME);
        // Environment Variable can have quotes:
        java_home=SstripQuotes(java_home);

	DEBUGPRINTF(" - getenv(JAVA_HOME)=%s\n",nonullstring(java_home,"<undefined>"));
    }

    const char *javaRegistryHome=getRegistryJavaHome();

    DEBUGPRINTF(" - Registry JavaHome=%s\n",nonullstring(javaRegistryHome,"<undefined>"));

    // Environment variable JAVA_HOME overides Registry JavaHome (if set):
    if ((java_home==NULL) && (javaRegistryHome!=NULL))
    {
        java_home=Sduplicate(javaRegistryHome);
    }

    if (java_exe==NULL)
    {
        java_exe=Sduplicate(JAVAW_EXE);
    }

    // ***
    // Create start command:
    // ***

    char *javaws_path=NULL;

    // TODO: if $VLET_INSTALL/jre1.6/ exists use $VLET_INSTALL/jre1.6/

    if (java_home!=NULL)
    {
        sprintf(jcmd,"%s\\bin\\%s ",java_home,java_exe);
    }
    else
    {
        // No JAVA_HOME: use javaw only:
        sprintf(jcmd,"%s ",java_exe);
    }

    // keep copy of path
    javaws_path=strdup(jcmd);

    // Add optional VMArgs:
    if (java_vmargs!=NULL)
    {
        strcat(jcmd, java_vmargs);
        strcat(jcmd, " ");  // add space:
    }

    // add -jar command
    {
        // start with -jar <MAINJAR>
        strcat(jcmd,"-jar ");
        strcat(jcmd, main_jar);
        strcat(jcmd, " ");
    }

    // append other command line options:
    if ((lpCmdLine!=NULL) && (lpCmdLine[0]!=0))
    {
        strcat(jcmd, lpCmdLine);
    }

    fprintf(stderr," Jarlauncher cwd = %s\n",nonullstring(exepath,"<undefined>"));
    fprintf(stderr," Jarlauncher jar = %s\n",nonullstring(main_jar,"<undefined>"));
    fprintf(stderr," Jarlauncher ini = %s\n",nonullstring(main_ini,"<undefined>"));
    fprintf(stderr," JAVA_HOME       = %s\n",nonullstring(java_home,"<undefined>"));
    fprintf(stderr," vmarguments     = %s\n",nonullstring(java_vmargs,"")); // empty is allowed
    fprintf(stderr," arguments       = %s\n",nonullstring(lpCmdLine,""));
    fprintf(stderr," commandline     = %s\n",jcmd);// actual command
    fprintf(stderr,"\n");

    if (Scompare(lpCmdLine,"-info")==0)
    {
        // exit;
        return 0;
    }

    /* Check javaw.exe, but only if a hardcoded JAVA_HOME is given */
    if ((java_home!=NULL) && (Fexists(javaws_path)==0))
    {
        char *message=Sappend("*** Jarlauncher Exception ***\n",
                              "javaw.exe not found:",
                              javaws_path);
        fprintf(stderr,"\n*** Jarlauncher: javaw not found:%s***\n",javaws_path);
        MessageBox(NULL,message,"Java Error", MB_OK);
        return 101;
    }

    if (Fexists(main_jar)==0)
    {
        char *message=Sappend("*** Jarlauncher Exception ***\n",
                              "Jarfile doesn't exist or is unreadable:",
                              main_jar);
        //strcat(message,".");
        fprintf(stderr,"\n*** Jarlauncher: file open error:%s***\n",main_jar);
        MessageBox(NULL,message,"File Error", MB_OK);
        return 102;
    }

    // ***
    // exec
    // ***

    unsigned int result=WinExec(jcmd, SW_SHOW);

    if (result>31)
    {
        DEBUGPRINTF(" Java started...\n","");
    }
    else
    {
        fprintf(stderr,"return code=%i\n",result);

        if (result==2)
        {
            char *message=Sappend("*** Jarlauncher Exception ***\n",
                                  "Java couldn't be started or Java isn't properly installed.");
            //strcat(message,".");
            fprintf(stderr,"\n*** Jarlauncher: Java couldn't be started:%s***\n",jcmd);
            MessageBox(NULL,message,"Java Error", MB_OK);
        }
        else
        {
            char *message=Sappend("*** Jarlauncher Exception ***\n",
                                  "Unknown error occured.");
            //strcat(message,".");
            fprintf(stderr,"\n*** Jarlauncher: Unknown error:%i***\n",result);
            MessageBox(NULL,message,"Java Error", MB_OK);
        }

        return result;
    }

    return 0;
}

<|endoftext|>


<commit_before>#include <utils.h>
#include "command.h"
#include "../CommandHandler.h"
#include "../OptionParser.h"

/* full name of the command */
CMDNAME("xp");
/* description of the command */
CMDDESCR("query experience information");
/* command usage synopsis */
CMDUSAGE("$xp [-i] NUM");

#define MAX_XP 0xBEBC200

static std::string xptolvl(int x);
static std::string lvltoxp(int x);

/* xp: query experience information */
std::string CommandHandler::xp(struct cmdinfo *c)
{
	bool inv;
	int x;
	std::string lvl;

	int opt;
	OptionParser op(c->fullCmd, "i");
	static struct OptionParser::option long_opts[] = {
		{ "help", NO_ARG, 'h' },
		{ "inverse", NO_ARG, 'i' },
		{ 0, 0, 0 }
	};

	inv = false;
	while ((opt = op.getopt_long(long_opts)) != EOF) {
		switch (opt) {
		case 'h':
			return HELPMSG(CMDNAME, CMDUSAGE, CMDDESCR);
		case 'i':
			inv = true;
			break;
		case '?':
			return std::string(op.opterr());
		default:
			return "";
		}
	}

	if (op.optind() == c->fullCmd.length()
			|| (lvl = c->fullCmd.substr(op.optind())).find(' ')
			!= std::string::npos)
		return USAGEMSG(CMDNAME, CMDUSAGE);

	try {
		if ((x = std::stoi(lvl)) < 0)
			return CMDNAME + ": number cannot be negative";
	} catch (std::invalid_argument) {
		return CMDNAME + ": invalid number -- '" + lvl + "'";
	} catch (std::out_of_range) {
		return CMDNAME + ": number too large";
	}

	if (inv) {
		if (x > MAX_XP)
			return CMDNAME + ": xp cannot exceed 200m";
		return "[XP] " + utils::formatInteger(std::to_string(x))
			+ " xp: level " + xptolvl(x);
	}

	if (x < 1 || x > 126)
		return CMDNAME + ": level must be between 1-126";
	return "[XP] level " + std::to_string(x) + ": " + lvltoxp(x) + " xp";
}

/* xptolvl: calculate the level at x xp */
static std::string xptolvl(int x)
{
	int n;

	n = 1;
	x *= 4;
	x += 1;
	while (x >= 0) {
		x -= floor(n + 300 * pow(2, n / 7.0));
		++n;
	}

	return std::to_string(n - 1);
}

/* lvltoxp: return xp required for level x */
static std::string lvltoxp(int x)
{
	int n, res;

	res = 0;
	for (n = 1; n < x; ++n)
		res += floor(n + 300 * pow(2, n / 7.0));
	res = floor(0.25 * res);

	return utils::formatInteger(std::to_string(res));
}
<commit_msg>Update xp command to do level ranges<commit_after>#include <utils.h>
#include "command.h"
#include "../CommandHandler.h"
#include "../OptionParser.h"

/* full name of the command */
CMDNAME("xp");
/* description of the command */
CMDDESCR("query experience information");
/* command usage synopsis */
CMDUSAGE("$xp [-i] [-r] NUM");

#define MAX_XP 0xBEBC200

static int xptolvl(int x);
static int lvltoxp(int x);
static std::string xprange(const std::string &args);

/* xp: query experience information */
std::string CommandHandler::xp(struct cmdinfo *c)
{
	bool inv, range;
	int x;
	std::string lvl;

	int opt;
	OptionParser op(c->fullCmd, "ir");
	static struct OptionParser::option long_opts[] = {
		{ "help", NO_ARG, 'h' },
		{ "inverse", NO_ARG, 'i' },
		{ "range", NO_ARG, 'r' },
		{ 0, 0, 0 }
	};

	inv = range = false;
	while ((opt = op.getopt_long(long_opts)) != EOF) {
		switch (opt) {
		case 'h':
			return HELPMSG(CMDNAME, CMDUSAGE, CMDDESCR);
		case 'i':
			inv = true;
			break;
		case 'r':
			range = true;
			break;
		case '?':
			return std::string(op.opterr());
		default:
			return "";
		}
	}

	if (range) {
		if (inv)
			return CMDNAME + ": cannot combine -r with -i";
		return xprange(c->fullCmd.substr(op.optind()));
	}

	if (op.optind() == c->fullCmd.length()
			|| (lvl = c->fullCmd.substr(op.optind())).find(' ')
			!= std::string::npos)
		return USAGEMSG(CMDNAME, CMDUSAGE);

	try {
		if ((x = std::stoi(lvl)) < 0)
			return CMDNAME + ": number cannot be negative";
	} catch (std::invalid_argument) {
		return CMDNAME + ": invalid number -- '" + lvl + "'";
	} catch (std::out_of_range) {
		return CMDNAME + ": number too large";
	}

	if (inv) {
		if (x > MAX_XP)
			return CMDNAME + ": xp cannot exceed 200m";
		return "[XP] " + utils::formatInteger(std::to_string(x))
			+ " xp: level " + std::to_string(xptolvl(x));
	}

	if (x < 1 || x > 126)
		return CMDNAME + ": level must be between 1-126";
	return "[XP] level " + std::to_string(x) + ": "
		+ utils::formatInteger(std::to_string(lvltoxp(x))) + " xp";
}

/* xptolvl: calculate the level at x xp */
static int xptolvl(int x)
{
	int n;

	n = 1;
	x *= 4;
	x += 1;
	while (x >= 0) {
		x -= floor(n + 300 * pow(2, n / 7.0));
		++n;
	}

	return n - 1;
}

/* lvltoxp: return xp required for level x */
static int lvltoxp(int x)
{
	int n, res;

	res = 0;
	for (n = 1; n < x; ++n)
		res += floor(n + 300 * pow(2, n / 7.0));
	res = floor(0.25 * res);

	return res;
}

/* xprange: calcuate the amount of xp between the levels in args */
static std::string xprange(const std::string &args)
{
	std::string a, b;
	size_t i;
	int x, y;

	i = 0;
	/* read the first level */
	while (i < args.length() && !isspace(args[i]) && args[i] != '-')
		a += args[i++];
	if (i == args.length())
		return CMDNAME + ": must provide two levels";

	++i;
	/* read the second level */
	while (i < args.length() && !isspace(args[i]))
		b += args[i++];
	if (i != args.length())
		return CMDNAME + ": must provide two levels";

	try {
		if ((x = std::stoi(a)) < 1 || x > 126)
			return CMDNAME + ": level must be between 1-126";
	} catch (std::invalid_argument) {
		return CMDNAME + ": invalid number -- '" + a + "'";
	} catch (std::out_of_range) {
		return CMDNAME + ": number too large";
	}
	try {
		if ((y = std::stoi(b)) < 1 || y > 126)
			return CMDNAME + ": level must be between 1-126";
	} catch (std::invalid_argument) {
		return CMDNAME + ": invalid number -- '" + b + "'";
	} catch (std::out_of_range) {
		return CMDNAME + ": number too large";
	}

	if (x > y)
		return CMDNAME + ": invalid range";
	x = lvltoxp(x);
	y = lvltoxp(y);

	return "[XP] level " + a + "-" + b + ": "
		+ utils::formatInteger(std::to_string(y - x)) + " xp";
}
<|endoftext|>