<!DOCTYPE HTML PUBLIC "-// IETF/DTD HTML 2.0// EN">
<html>
<!--                                             -->
<!-- Author: ROOT team (rootdev@hpsalo.cern.ch)  -->
<!--                                             -->
<!--   Date: Tue Apr  6 15:52:03 1999            -->
<!--                                             -->
<head>
<title>CalSmeared - source file</title>
<link rev=made href="mailto:rootdev@root.cern.ch">
<meta name="rating" content="General">
<meta name="objecttype" content="Manual">
<meta name="keywords" content="software development, oo, object oriented, unix, x11, motif, windows nt, c++, html, rene brun, fons rademakers">
<meta name="description" content="ROOT - An Object Oriented Framework For Large Scale Data Analysis.">
</head>
<body BGCOLOR="#ffffff" LINK="#0000ff" VLINK="#551a8b" ALINK="#ff0000" TEXT="#000000">
<a name="TopOfPage"></a>
<pre>
<b>// $Header: <a href=".././CalSmeared.html">CalSmeared</a>.cxx $</b>

#include "<a href="../CalSmeared.h">CalSmeared.h</a>"
#include "<a href="../IntObj.h">IntObj.h</a>"

ClassImp(CalSmeared)

<b>//______________________________________________________________________</b>
<b>//                                                                       </b>
<b>// <a href=".././CalSmeared.html">CalSmeared</a></b>
<b>//                                                                </b>
<b>// <a href=".././CalSmeared.html">CalSmeared</a> is the Fast MC version of a cluster (really should be</b>
<b>// inheriting from <a href="http://root.cern.ch/root/html/Event.html">Event</a> <a href="http://root.cern.ch/root/html/Cluster.html">Cluster</a> class).  In addition to minimal cluster</b>
<b>// attributes it also keeps some information on the "perfect" cluster</b>
<b>// from which it is derived.</b>

<a name="CalSmeared:CalSmeared"> </a><a href=".././CalSmeared.html#CalSmeared:CalSmeared">CalSmeared::CalSmeared</a>(<a href=".././SmearTraj.html">SmearTraj</a>&amp; traj, <a href="../ListOfTypes.html#Bool_t">Bool_t</a> hadron, <a href=".././SmearFuzz.html">SmearFuzz</a>* pFuzz,
		       <a href="http://root.cern.ch/root/html/TRandom.html">TRandom</a> *pRand)
{
<b>  // Usual constructor.  Inputs are</b>
<b>  //    -- "perfect" particle position, after propagation</b>
<b>  //    -- hadron/lepton boolean</b>
<b>  //    -- smearing parameters</b>
<b>  //    -- random number generator instance</b>

  <a href="http://root.cern.ch/root/html/McPart.html">McPart</a>*    pPart = traj.GetMc();
  <a href="../ListOfTypes.html#Int_t">Int_t</a>      partIx = traj.GetMcIx();
  <a href="../ListOfTypes.html#Double_t">Double_t</a>*  pPos = traj.GetNewPos();
  <a href="../ListOfTypes.html#Double_t">Double_t</a>*  pMom = traj.GetNewMom();

  <a href="../ListOfTypes.html#Double_t">Double_t</a> a, b;
  <a href="../ListOfTypes.html#Double_t">Double_t</a> sigma;
  <a href="../ListOfTypes.html#Float_t">Float_t</a> examineEnergy;
  <a href="../ListOfTypes.html#Int_t">Int_t</a>   absPid;

  <a href=".././CalSmeared.html#CalSmeared:sPerfect">sPerfect</a> = traj.GetS();
  <a href=".././CalSmeared.html#CalSmeared:mcContribs">mcContribs</a> = new <a href="http://root.cern.ch/root/html/TObjArray.html">TObjArray</a>(1);
  <a href=".././CalSmeared.html#CalSmeared:mcContribs">mcContribs</a>-&gt;<a href="http://root.cern.ch/root/html/TObjArray.html#TObjArray:Add">Add</a>(new <a href="http://root.cern.ch/root/html/IntObj.html">IntObj</a>(partIx));
  <a href=".././CalSmeared.html#CalSmeared:ePerfect">ePerfect</a> = pPart-&gt;GetMomentum()[3];
  <a href=".././CalSmeared.html#CalSmeared:pid1">pid1</a> = pPart-&gt;GetType();
  <a href=".././CalSmeared.html#CalSmeared:nPart">nPart</a> = 1;

  if (hadron) {
    a = pFuzz-&gt;energyHadA;
    b = pFuzz-&gt;energyHadB;
  }
  else {
    a = pFuzz-&gt;energyEmA;
    b = pFuzz-&gt;energyEmB;
  }

<b>  // Save "perfect" position vector</b>
<b>  // Don't yet know how to get from cluster start to cluster max</b>
<b>  // realistically.  For now just set them equal.</b>
  <a href=".././CalSmeared.html#CalSmeared:posClusterStart">posClusterStart</a>[0] = <a href=".././CalSmeared.html#CalSmeared:posPerfect">posPerfect</a>[0] = *pPos;
  <a href=".././CalSmeared.html#CalSmeared:posClusterStart">posClusterStart</a>[1] = <a href=".././CalSmeared.html#CalSmeared:posPerfect">posPerfect</a>[1] = *(pPos + 1);
  <a href=".././CalSmeared.html#CalSmeared:posClusterStart">posClusterStart</a>[2] = <a href=".././CalSmeared.html#CalSmeared:posPerfect">posPerfect</a>[2] = *(pPos + 2);

  <a href=".././CalSmeared.html#CalSmeared:energySigma">energySigma</a> = sigma = 
    (<a href="http://root.cern.ch/root/html/TMath.html#TMath:Sqrt">TMath::Sqrt</a>((a * a) / <a href=".././CalSmeared.html#CalSmeared:ePerfect">ePerfect</a> + b * b)) * <a href=".././CalSmeared.html#CalSmeared:ePerfect">ePerfect</a>;
  <a href=".././CalSmeared.html#CalSmeared:energy">energy</a> = pRand-&gt;Gaus(<a href=".././CalSmeared.html#CalSmeared:ePerfect">ePerfect</a>, sigma);
  if (<a href=".././CalSmeared.html#CalSmeared:energy">energy</a> &lt; 0.0) <a href=".././CalSmeared.html#CalSmeared:energy">energy</a> = 0.0;

<b>  // Now for position</b>
<b>  // First step should be to calculate shower max position from what</b>
<b>  // I've got (shower start position).  This will add something in</b>
<b>  // the direction of the momentum vector (or do I need to propagate</b>
<b>  // along a helix for charged particles in a field??) but I don't</b>
<b>  // know how to do this yet.</b>

<b>  // Then smear position in plane perp. to momentum vector.</b>
  if (hadron) {
    a = pFuzz-&gt;transHadA;
    b = pFuzz-&gt;transHadB;
  }
  else {
    a = pFuzz-&gt;transEmA;
    b = pFuzz-&gt;transEmB;
  }
<b>  // Find sigma. Use MC truth -- not smeared -- <a href=".././CalSmeared.html#CalSmeared:energy">energy</a></b>
<b>  //  sigma = sqrt((a*a)/E + (b*b))</b>
<b>  // and use it to throw a distance in transverse plane.  </b>
<b>  // Also get random phi (in same plane).  Since distance can be</b>
<b>  // negative, just let phi range from 0 to pi.</b>
  { 
    <a href="../ListOfTypes.html#Double_t">Double_t</a> transSigma = <a href="http://root.cern.ch/root/html/TMath.html#TMath:Sqrt">TMath::Sqrt</a>((a*a)/<a href=".././CalSmeared.html#CalSmeared:ePerfect">ePerfect</a> + b*b);
    <a href="../ListOfTypes.html#Double_t">Double_t</a> transDist = pRand-&gt;Gaus(0.0, transSigma);
    <a href="../ListOfTypes.html#Double_t">Double_t</a> phi =  <a href="http://root.cern.ch/root/html/TMath.html#TMath:Pi">TMath::Pi</a>() * pRand-&gt;Rndm(0);
    <a href="../ListOfTypes.html#Double_t">Double_t</a> positionOffset[3]; 
    <a href="../ListOfTypes.html#Double_t">Double_t</a> primeVec[3]; // offsets in rotated coord.
    static <a href="../ListOfTypes.html#Double_t">Double_t</a> sqrtHalf = <a href="http://root.cern.ch/root/html/TMath.html#TMath:Sqrt">TMath::Sqrt</a>(0.5);

<b>    // errors in phi and theta added in quad. should give total trans. err</b>
    <a href=".././CalSmeared.html#CalSmeared:eThetaRms">eThetaRms</a> = <a href=".././CalSmeared.html#CalSmeared:ePhiRms">ePhiRms</a> = transSigma * sqrtHalf; 

<b>    // Given offset vector in rotated system with </b>
<b>    // momentum vector ==&gt; (0, 0, mag) have offset find its coordinates</b>
<b>    // in original frame. </b>
    primeVec[0] = transDist * <a href="http://root.cern.ch/root/html/TMath.html#TMath:Cos">TMath::Cos</a>(phi);
    primeVec[1] = transDist * <a href="http://root.cern.ch/root/html/TMath.html#TMath:Sin">TMath::Sin</a>(phi);
    primeVec[2] = 0.0;
    <a href="#CalSmeared:Rotate">Rotate</a>(primeVec, pMom, &amp;positionOffset[0]);

<b>    // Add on to original position vector</b>
    for (<a href="../ListOfTypes.html#int">int</a> ix = 0; ix &lt; 3; ix++) {
      <a href=".././CalSmeared.html#CalSmeared:pos">pos</a>[ix] = <a href=".././CalSmeared.html#CalSmeared:posPerfect">posPerfect</a>[ix] + positionOffset[ix];
    }
  }

<b>  // Save polar coord. version of <a href=".././CalSmeared.html#CalSmeared:energy">energy</a> position</b>
  <a href="../ListOfTypes.html#Double_t">Double_t</a> polar[3];
  <a href="#CalSmeared:ToPolar">ToPolar</a>(&amp;<a href=".././CalSmeared.html#CalSmeared:pos">pos</a>[0], &amp;polar[0]);
  <a href=".././CalSmeared.html#CalSmeared:eTheta">eTheta</a> = polar[0];
  <a href=".././CalSmeared.html#CalSmeared:ePhi">ePhi</a> = polar[1];
  <a href=".././CalSmeared.html#CalSmeared:eR">eR</a> = polar[2];
}

<a name="CalSmeared:spewDiag"> </a><a href="../ListOfTypes.html#void">void</a> <a href=".././CalSmeared.html#CalSmeared:spewDiag">CalSmeared::spewDiag</a>(FILE* ofile) {
<b>  // More extensive spew for debugging</b>

  <a href="../ListOfTypes.html#Float_t">Float_t</a> *pOrig = ((<a href="http://root.cern.ch/root/html/McPart.html">McPart</a> *) (<a href=".././CalSmeared.html#CalSmeared:mcContribs">mcContribs</a>-&gt;<a href="http://root.cern.ch/root/html/TObjArray.html#TObjArray:First">First</a>()))-&gt;GetMomentum();
  unsigned <a href="../ListOfTypes.html#int">int</a> mcAddr = (unsigned <a href="../ListOfTypes.html#int">int</a>) <a href=".././CalSmeared.html#CalSmeared:mcContribs">mcContribs</a>-&gt;<a href="http://root.cern.ch/root/html/TObjArray.html#TObjArray:First">First</a>();
  fprintf(ofile, 
"MC addr: %i PID: %d Orig egy: %f Orig mom: ( %f, %f, %f) Smeared egy %fn",          mcAddr, <a href=".././CalSmeared.html#CalSmeared:pid1">pid1</a>, <a href=".././CalSmeared.html#CalSmeared:ePerfect">ePerfect</a>, pOrig[0], pOrig[1], pOrig[2], <a href=".././CalSmeared.html#CalSmeared:energy">energy</a>);
  fprintf(ofile, "(%f, %f, %f) =&gt; (%f, %f, %f)n", <a href=".././CalSmeared.html#CalSmeared:posPerfect">posPerfect</a>[0],
	  <a href=".././CalSmeared.html#CalSmeared:posPerfect">posPerfect</a>[1], <a href=".././CalSmeared.html#CalSmeared:posPerfect">posPerfect</a>[2], <a href=".././CalSmeared.html#CalSmeared:pos">pos</a>[0], <a href=".././CalSmeared.html#CalSmeared:pos">pos</a>[1], <a href=".././CalSmeared.html#CalSmeared:pos">pos</a>[2]);
  fprintf(ofile, "Geometric path length: %f n", <a href=".././CalSmeared.html#CalSmeared:sPerfect">sPerfect</a>);
  fprintf(ofile,"%f %f %f %f %f %f %fn", <a href="#CalSmeared:GetEnergy">GetEnergy</a>(), 
	  <a href="#CalSmeared:GetEnergyPhi">GetEnergyPhi</a>(), <a href="#CalSmeared:GetEnergyTheta">GetEnergyTheta</a>(), <a href="#CalSmeared:GetEnergyR">GetEnergyR</a>(),
	  <a href="#CalSmeared:GetEnergyPhiRms">GetEnergyPhiRms</a>(), <a href="#CalSmeared:GetEnergyThetaRms">GetEnergyThetaRms</a>(), <a href="#CalSmeared:GetEnergyRRms">GetEnergyRRms</a>());
}

<a name="CalSmeared:spew"> </a><a href="../ListOfTypes.html#void">void</a> <a href=".././CalSmeared.html#CalSmeared:spew">CalSmeared::spew</a>(FILE* ofile) {
<b>  // Typical cluster output for a fastMC cluster looks like</b>
<b>  //        <a href=".././CalSmeared.html#CalSmeared:energy">energy</a> energyPhi energyTheta energyR phiRms thetaRms rRms</b>
<b>  //        0 hits</b>
<b>  //        1 particle(s)</b>
<b>  //        xxxxxxxx</b>
<b>  //</b>
<b>  // where the quantities in the first line are floating point and</b>
<b>  // xxxxxxxx is index (in array of all MC particles) associated with </b>
<b>  // generating MC particle.</b>
<b>  //</b>
<b>  // The set of all clusters are bracketed by the lines</b>
<b>  //    yyy Clusters                          [before]   and</b>
<b>  //    end                                   [after]</b>
<b>  //</b>
<b>  //     yyy is the number of clusters to follow.</b>

  static <a href="../ListOfTypes.html#Int_t">Int_t</a> zero = 0;

<b>  //  fprintf(ofile,"<a href="http://root.cern.ch/root/html/Cluster.html">Cluster</a>n");</b>
  fprintf(ofile,"%f %f %f %f %f %f %fn", <a href="#CalSmeared:GetEnergy">GetEnergy</a>(), 
	  <a href="#CalSmeared:GetEnergyPhi">GetEnergyPhi</a>(), <a href="#CalSmeared:GetEnergyTheta">GetEnergyTheta</a>(), <a href="#CalSmeared:GetEnergyR">GetEnergyR</a>(),
	  <a href="#CalSmeared:GetEnergyPhiRms">GetEnergyPhiRms</a>(), <a href="#CalSmeared:GetEnergyThetaRms">GetEnergyThetaRms</a>(), <a href="#CalSmeared:GetEnergyRRms">GetEnergyRRms</a>());
  fprintf(ofile,"%i hit(s)n", zero);
  fprintf(ofile,"%i particle(s)n", <a href=".././CalSmeared.html#CalSmeared:nPart">nPart</a>);
  
  {
    <a href="../ListOfTypes.html#Int_t">Int_t</a> ix;
    for (ix = 0; ix &lt; <a href=".././CalSmeared.html#CalSmeared:nPart">nPart</a>; ix++) {
      fprintf(ofile, "%i n", 
	      (unsigned <a href="../ListOfTypes.html#int">int</a>) ((<a href="http://root.cern.ch/root/html/IntObj.html">IntObj</a> *)(<a href=".././CalSmeared.html#CalSmeared:mcContribs">mcContribs</a>-&gt;<a href="http://root.cern.ch/root/html/TObjArray.html#TObjArray:At">At</a>(ix)))-&gt;Getnum());
    }
  }
}

<a name="CalSmeared:ToPolar"> </a><a href="../ListOfTypes.html#void">void</a> <a href=".././CalSmeared.html#CalSmeared:ToPolar">CalSmeared::ToPolar</a>(const <a href="../ListOfTypes.html#Double_t">Double_t</a> *pRect, <a href="../ListOfTypes.html#Double_t">Double_t</a> *pPolar) {
<b>  // Given rectangular coords, compute polar and store in provided 3-vector.</b>
<b>  // (theta, phi, r).  The following conventions are used:</b>
<b>  // 0 &lt;= phi &lt; 2 pi</b>
<b>  // 0 &lt; phi &lt; pi/2 for x, y &gt; 0.  pi/2 &lt; phi &lt; pi for x &lt; 0, y &gt; 0, etc.</b>
<b>  // 0 &lt;= theta &lt; pi; theta &lt; pi/2 for z &gt; 0</b>

  <a href="../ListOfTypes.html#Double_t">Double_t</a> r;
  <a href="../ListOfTypes.html#Double_t">Double_t</a> theta;
  <a href="../ListOfTypes.html#Double_t">Double_t</a> phi;
  <a href="../ListOfTypes.html#Double_t">Double_t</a> toBeamline;

  <a href="../ListOfTypes.html#Double_t">Double_t</a> x = *pRect;
  <a href="../ListOfTypes.html#Double_t">Double_t</a> y = *(pRect + 1);
  <a href="../ListOfTypes.html#Double_t">Double_t</a> z = *(pRect + 2);

  toBeamline = x*x + y*y;
  r = <a href="http://root.cern.ch/root/html/TMath.html#TMath:Sqrt">TMath::Sqrt</a>(toBeamline + z*z);
  toBeamline = <a href="http://root.cern.ch/root/html/TMath.html#TMath:Sqrt">TMath::Sqrt</a>(toBeamline);

  pPolar[2] = r;

  if (r &lt;= 0.0) {
    pPolar[0] = 0.0;
    pPolar[1] = 0.0;

    return;
  }
  theta = <a href="http://root.cern.ch/root/html/TMath.html#TMath:ATan2">TMath::ATan2</a>(toBeamline, z);
  if (theta &lt; 0) theta += <a href="http://root.cern.ch/root/html/TMath.html#TMath:Pi">TMath::Pi</a>();

  phi = <a href="http://root.cern.ch/root/html/TMath.html#TMath:ATan2">TMath::ATan2</a>(y, x);
  if (phi &lt; 0.0)  phi += 2 * <a href="http://root.cern.ch/root/html/TMath.html#TMath:Pi">TMath::Pi</a>();

  pPolar[0] = theta;
  pPolar[1] = phi;

  return;
}

<a name="CalSmeared:Rotate"> </a><a href="../ListOfTypes.html#void">void</a> <a href=".././CalSmeared.html#CalSmeared:Rotate">CalSmeared::Rotate</a>(<a href="../ListOfTypes.html#Double_t">Double_t</a>* inVec, <a href="../ListOfTypes.html#Double_t">Double_t</a>* angleVec, 
			<a href="../ListOfTypes.html#Double_t">Double_t</a>* result)
// Rotate something  so that z axis is "returned"
// to normalVec.  That is, if angleVec has polar coords (theta, phi, r),
//  rotate about y-axis by theta, then about z-axis by phi.

{
<b>  // We need to rotate by theta, phi coordinates of momentum</b>
  <a href="../ListOfTypes.html#Double_t">Double_t</a> polar[3];
  
  <a href="#CalSmeared:ToPolar">ToPolar</a>(angleVec, polar);  // Gives us theta, phi, r for normal

  <a href="../ListOfTypes.html#Double_t">Double_t</a> temp[3];

  <a href="#CalSmeared:RotateTheta">RotateTheta</a>(polar[0], inVec, &amp;temp[0]);
  <a href="#CalSmeared:RotatePhi">RotatePhi</a>(polar[1], &amp;temp[0], result);
 
  return;
}

<a name="CalSmeared:RotateTheta"> </a><a href="../ListOfTypes.html#void">void</a> <a href=".././CalSmeared.html#CalSmeared:RotateTheta">CalSmeared::RotateTheta</a>(const <a href="../ListOfTypes.html#Double_t">Double_t</a> theta, 
			     <a href="../ListOfTypes.html#Double_t">Double_t</a> *iVec, <a href="../ListOfTypes.html#Double_t">Double_t</a> *rVec)
// Rotate about y-axis with angle theta

{
  <a href="../ListOfTypes.html#Double_t">Double_t</a> sinTheta = <a href="http://root.cern.ch/root/html/TMath.html#TMath:Sin">TMath::Sin</a>(theta);
  <a href="../ListOfTypes.html#Double_t">Double_t</a> cosTheta = <a href="http://root.cern.ch/root/html/TMath.html#TMath:Cos">TMath::Cos</a>(theta);

  *rVec = (*iVec) * cosTheta + *(iVec + 2) * sinTheta;
  *(rVec + 1) = *(iVec + 1);
  *(rVec + 2) = *iVec * (-sinTheta) + *(iVec + 2) * cosTheta;

  return;
}

<a name="CalSmeared:RotatePhi"> </a><a href="../ListOfTypes.html#void">void</a> <a href=".././CalSmeared.html#CalSmeared:RotatePhi">CalSmeared::RotatePhi</a>(const <a href="../ListOfTypes.html#Double_t">Double_t</a> phi, 
			   <a href="../ListOfTypes.html#Double_t">Double_t</a> *iVec, <a href="../ListOfTypes.html#Double_t">Double_t</a> *rVec)
// Rotate about z-axis with angle phi

{
  <a href="../ListOfTypes.html#Double_t">Double_t</a> sinPhi = <a href="http://root.cern.ch/root/html/TMath.html#TMath:Sin">TMath::Sin</a>(phi);
  <a href="../ListOfTypes.html#Double_t">Double_t</a> cosPhi = <a href="http://root.cern.ch/root/html/TMath.html#TMath:Cos">TMath::Cos</a>(phi);

  *rVec = (*iVec) * cosPhi - *(iVec + 1) * sinPhi;
  *(rVec + 1) = *iVec * (sinPhi) + *(iVec + 1) * cosPhi;
  *(rVec + 2) = *(iVec + 2);

  return;
}
</pre>

<!--SIGNATURE-->
<br>
<address>
<hr>
<center>
<a href="http://root.cern.ch/root/Welcome.html">ROOT page</a> - <a href="../ClassIndex.html">Class index</a> - <a href="#TopOfPage">Top of the page</a><br>
</center>
<hr>This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to <a href="mailto:rootdev@root.cern.ch">ROOT support</a>, or contact <a href="mailto:rootdev@root.cern.ch">the developers</a> with any questions or problems regarding ROOT.
</address>
</body>
</html>
