/// <summary> /// method to tally to detector /// </summary> /// <param name="photon">photon data needed to tally</param> public void Tally(Photon photon) { if (!IsWithinDetectorAperture(photon)) { return; } var ir = DetectorBinning.WhichBin(DetectorBinning.GetRho(photon.DP.Position.X, photon.DP.Position.Y), Rho.Count - 1, Rho.Delta, Rho.Start); var totalTime = photon.DP.TotalTime; for (int iw = 0; iw < Omega.Count; iw++) { double freq = Omega.AsEnumerable().ToArray()[iw]; Mean[ir, iw] += photon.DP.Weight * (Math.Cos(-2 * Math.PI * freq * totalTime) + Complex.ImaginaryOne * Math.Sin(-2 * Math.PI * freq * totalTime)); if (TallySecondMoment) // 2nd moment is E[xx*]=E[xreal^2]+E[ximag^2] { SecondMoment[ir, iw] += photon.DP.Weight * (Math.Cos(-2 * Math.PI * freq * totalTime)) * photon.DP.Weight * (Math.Cos(-2 * Math.PI * freq * totalTime)) + photon.DP.Weight * (Math.Sin(-2 * Math.PI * freq * totalTime)) * photon.DP.Weight * (Math.Sin(-2 * Math.PI * freq * totalTime)); } } TallyCount++; }
/// <summary> /// method to tally given two consecutive photon data points /// </summary> /// <param name="previousDP">previous data point</param> /// <param name="dp">current data point</param> /// <param name="currentRegionIndex">index of region photon current is in</param> public void TallySingle(PhotonDataPoint previousDP, PhotonDataPoint dp, int currentRegionIndex) { var totalTime = dp.TotalTime; var ix = DetectorBinning.WhichBin(dp.Position.X, X.Count - 1, X.Delta, X.Start); var iy = DetectorBinning.WhichBin(dp.Position.Y, Y.Count - 1, Y.Delta, Y.Start); var iz = DetectorBinning.WhichBin(dp.Position.Z, Z.Count - 1, Z.Delta, Z.Start); var weight = _absorptionWeightingMethod(previousDP, dp, currentRegionIndex); var regionIndex = currentRegionIndex; if (weight != 0.0) { for (int iw = 0; iw < Omega.Count; iw++) { double freq = Omega.AsEnumerable().ToArray()[iw]; Mean[ix, iy, iz, iw] += (weight / _ops[regionIndex].Mua) * (Math.Cos(-2 * Math.PI * freq * totalTime) + Complex.ImaginaryOne * Math.Sin(-2 * Math.PI * freq * totalTime)); if (TallySecondMoment) { _tallyForOnePhoton[ix, iy, iz, iw] += (weight / _ops[regionIndex].Mua) * (Math.Cos(-2 * Math.PI * freq * totalTime) + Complex.ImaginaryOne * Math.Sin(-2 * Math.PI * freq * totalTime)); } TallyCount++; } } }
/// <summary> /// method to tally given two consecutive photon data points /// </summary> /// <param name="previousDP">previous data point</param> /// <param name="dp">current data point</param> /// <param name="currentRegionIndex">index of region photon current is in</param> public void TallySingle(PhotonDataPoint previousDP, PhotonDataPoint dp, int currentRegionIndex) { var totalTime = dp.TotalTime; var ir = DetectorBinning.WhichBin(DetectorBinning.GetRho(dp.Position.X, dp.Position.Y), Rho.Count - 1, Rho.Delta, Rho.Start); var iz = DetectorBinning.WhichBin(dp.Position.Z, Z.Count - 1, Z.Delta, Z.Start); var weight = _absorptionWeightingMethod(previousDP, dp, currentRegionIndex); // Note: GetVolumeAbsorptionWeightingMethod in Initialize method determines the *absorbed* weight // so for fluence this weight is divided by Mua var regionIndex = currentRegionIndex; if (weight != 0.0) { for (int iw = 0; iw < Omega.Count; iw++) { double freq = Omega.AsEnumerable().ToArray()[iw]; Mean[ir, iz, iw] += (weight / _ops[regionIndex].Mua) * (Math.Cos(-2 * Math.PI * freq * totalTime) + Complex.ImaginaryOne * Math.Sin(-2 * Math.PI * freq * totalTime)); if (TallySecondMoment) { _tallyForOnePhoton[ir, iz, iw] += (weight / _ops[regionIndex].Mua) * (Math.Cos(-2 * Math.PI * freq * totalTime) + Complex.ImaginaryOne * Math.Sin(-2 * Math.PI * freq * totalTime)); } } TallyCount++; } }