/// <summary> /// method to tally reflected photon by determining cumulative MT in each tissue subregion and binning in MT /// </summary> /// <param name="photon">Photon (includes HistoryData)</param> public void Tally(Photon photon) { if (!IsWithinDetectorAperture(photon)) { return; } // calculate the radial and time bin of reflected photon var ir = DetectorBinning.WhichBin(DetectorBinning.GetRho(photon.DP.Position.X, photon.DP.Position.Y), Rho.Count - 1, Rho.Delta, Rho.Start); for (int i = 0; i < NumSubregions; i++) { var timeInSubRegion = DetectorBinning.GetTimeDelay(photon.History.SubRegionInfoList[i].PathLength, _tissue.Regions[i].RegionOP.N); // make sure floating point round in Photon's update to S and subsequently to PathLength in SRIL doesn't get tallied if (timeInSubRegion > 1e-14) { var it = DetectorBinning.WhichBin(timeInSubRegion, Time.Count - 1, Time.Delta, Time.Start); // tally Continuous Absorption Weighting (CAW) var tally = Math.Exp(-_tissue.Regions[i].RegionOP.Mua * photon.History.SubRegionInfoList[i].PathLength); Mean[ir, i, it] += tally; if (TallySecondMoment) { SecondMoment[ir, i, it] += tally * tally; } } } TallyCount++; }
/// <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; } // ray trace exit location and direction to location at ZPlane var positionAtZPlane = LayerTissueRegionToolbox.RayExtendToInfinitePlane( photon.DP.Position, photon.DP.Direction, ZPlane); // WhichBin to match ROfRhoAndTimeDetector var ir = DetectorBinning.WhichBin(DetectorBinning.GetRho(positionAtZPlane.X, positionAtZPlane.Y), Rho.Count - 1, Rho.Delta, Rho.Start); var it = DetectorBinning.WhichBin(photon.DP.TotalTime, Time.Count - 1, Time.Delta, Time.Start); if ((ir != -1) && (it != -1)) { double weightFactor = _absorbAction( photon.History.SubRegionInfoList.Select(c => c.NumberOfCollisions).ToList(), photon.History.SubRegionInfoList.Select(p => p.PathLength).ToList(), _perturbedOps, _referenceOps, _perturbedRegionsIndices); Mean[ir, it] += photon.DP.Weight * weightFactor; if (TallySecondMoment) { SecondMoment[ir, it] += photon.DP.Weight * weightFactor * photon.DP.Weight * weightFactor; } TallyCount++; } }
/// <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; } // WhichBin to match ROfXAndY var ix = DetectorBinning.WhichBin(photon.DP.Position.X, X.Count - 1, X.Delta, X.Start); var iy = DetectorBinning.WhichBin(photon.DP.Position.Y, Y.Count - 1, Y.Delta, Y.Start); if ((ix != -1) && (iy != -1)) { double weightFactor = _absorbAction( photon.History.SubRegionInfoList.Select(c => c.NumberOfCollisions).ToList(), photon.History.SubRegionInfoList.Select(p => p.PathLength).ToList(), _perturbedOps, _referenceOps, _perturbedRegionsIndices); Mean[ix, iy] += photon.DP.Weight * weightFactor; if (TallySecondMoment) { SecondMoment[ix, iy] += photon.DP.Weight * weightFactor * photon.DP.Weight * weightFactor; } 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 iz = DetectorBinning.WhichBin(dp.Position.Z, Z.Count - 1, Z.Delta, Z.Start); // using Acos, -1<Uz<1 goes to pi<theta<0, so first bin is most forward directed angle var ia = DetectorBinning.WhichBin(Math.Acos(dp.Direction.Uz), Angle.Count - 1, Angle.Delta, Angle.Start); var weight = _absorptionWeightingMethod(previousDP, dp, currentRegionIndex); if (weight != 0.0) { var x = dp.Position.X; var fxArray = Fx.AsEnumerable().ToArray(); for (int ifx = 0; ifx < fxArray.Length; ifx++) { double freq = fxArray[ifx]; var sinNegativeTwoPiFX = Math.Sin(-2 * Math.PI * freq * x); var cosNegativeTwoPiFX = Math.Cos(-2 * Math.PI * freq * x); // convert to Hz-sec from GHz-ns 1e-9*1e9=1 var deltaWeight = (weight / _ops[currentRegionIndex].Mua) * (cosNegativeTwoPiFX + Complex.ImaginaryOne * sinNegativeTwoPiFX); Mean[ifx, iz, ia] += deltaWeight; if (TallySecondMoment) { _tallyForOnePhoton[ifx, iz, ia] += deltaWeight; } TallyCount++; } } }
public void verify_that_GetFinalPositionAndWeight_samples_from_UnifOfRhoAndZ_sampling_correctly() { ITissueInput tissueInput = new SingleInfiniteCylinderTissueInput(); ITissue tissue = tissueInput.CreateTissue(AbsorptionWeightingType.Discrete, PhaseFunctionType.HenyeyGreenstein, 0); tissue.Regions[1] = _xyzLoaderUnif.FluorescentTissueRegion; for (int i = 0; i < 100; i++) { var photon = _fluorEmissionAOfRhoAndZSourceUnif.GetNextPhoton(tissue); // verify that photons start within range of midpoints of voxels in infinite cylinder Assert.IsTrue(photon.DP.Position.X <= 3.5); Assert.AreEqual(photon.DP.Position.Y, 0); Assert.IsTrue((photon.DP.Position.Z >= 0.5) && (photon.DP.Position.Z <= 1.5)); // verify sampling is proceeding in coded sequence // detector center=(0,0,1) radius=4, rho=[0 4] 4 bins, z=[0 2] 2 bins var ir = DetectorBinning.WhichBin(DetectorBinning.GetRho( photon.DP.Position.X, photon.DP.Position.Y), _rhozLoaderUnif.Rho.Count - 1, _rhozLoaderUnif.Rho.Delta, _rhozLoaderUnif.Rho.Start); var iz = DetectorBinning.WhichBin(photon.DP.Position.Z, _rhozLoaderUnif.Z.Count - 1, _rhozLoaderUnif.Z.Delta, _rhozLoaderUnif.Z.Start); var rhozNorm = (_rhozLoaderUnif.Rho.Start + (ir + 0.5) * _rhozLoaderUnif.Rho.Delta) * 2.0 * Math.PI * _rhozLoaderUnif.Rho.Delta * _rhozLoaderUnif.Z.Delta; // verify weight at location is equal to AOfRhoAndZ note: setup with single y bin // expected: Map [ 1 1 1 1; 1 1 1 1] row major // expected: A [ 1 3 5 7; 2 4 6 8] row major Assert.IsTrue(Math.Abs(photon.DP.Weight - _rhozLoaderUnif.AOfRhoAndZ[ir, iz] * rhozNorm) < 1e-6); } }
/// <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; } // WhichBin to match pMCROfRho which matches ROfRho var ir = DetectorBinning.WhichBin(DetectorBinning.GetRho(photon.DP.Position.X, photon.DP.Position.Y), Rho.Count - 1, Rho.Delta, Rho.Start); if (ir != -1) { double weightFactor = _absorbAction( photon.History.SubRegionInfoList.Select(c => c.NumberOfCollisions).ToList(), photon.History.SubRegionInfoList.Select(p => p.PathLength).ToList(), _perturbedOps); Mean[ir] += photon.DP.Weight * weightFactor; if (TallySecondMoment) { SecondMoment[ir] += photon.DP.Weight * weightFactor * photon.DP.Weight * weightFactor; } TallyCount++; } }
/// <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; } // WhichBin to match ROfRhoAndTimeDetector var ir = DetectorBinning.WhichBin(DetectorBinning.GetRho(photon.DP.Position.X, photon.DP.Position.Y), Rho.Count - 1, Rho.Delta, Rho.Start); var it = DetectorBinning.WhichBin(photon.DP.TotalTime, Time.Count - 1, Time.Delta, Time.Start); if ((ir != -1) && (it != -1)) { double weightFactor = _absorbAction( photon.History.SubRegionInfoList.Select(c => c.NumberOfCollisions).ToList(), photon.History.SubRegionInfoList.Select(p => p.PathLength).ToList(), _perturbedOps, _referenceOps, _perturbedRegionsIndices); Mean[ir, it] += photon.DP.Weight * weightFactor; if (TallySecondMoment) { SecondMoment[ir, it] += photon.DP.Weight * weightFactor * photon.DP.Weight * weightFactor; } 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 x = dp.Position.X; var fxArray = Fx.AsEnumerable().ToArray(); 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) { for (int ifx = 0; ifx < fxArray.Length; ifx++) { double freq = fxArray[ifx]; var sinNegativeTwoPiFX = Math.Sin(-2 * Math.PI * freq * x); var cosNegativeTwoPiFX = Math.Cos(-2 * Math.PI * freq * x); // convert to Hz-sec from GHz-ns 1e-9*1e9=1 var deltaWeight = weight * (cosNegativeTwoPiFX + Complex.ImaginaryOne * sinNegativeTwoPiFX); Mean[ifx, iz] += (deltaWeight / _ops[regionIndex].Mua); if (TallySecondMoment) // 2nd moment is E[xx*]=E[xreal^2]+E[ximag^2] { _tallyForOnePhoton[ifx, iz] += (deltaWeight / _ops[regionIndex].Mua) * (deltaWeight / _ops[regionIndex].Mua) * cosNegativeTwoPiFX * cosNegativeTwoPiFX + (deltaWeight / _ops[regionIndex].Mua) * (deltaWeight / _ops[regionIndex].Mua) * sinNegativeTwoPiFX * sinNegativeTwoPiFX; } } TallyCount++; } }
/// <summary> /// method to tally to detector /// </summary> /// <param name="photon">photon data needed to tally</param> public void Tally(Photon photon) { var dp = photon.DP; var ia = DetectorBinning.WhichBin(Math.Acos(photon.DP.Direction.Uz), Angle.Count - 1, Angle.Delta, Angle.Start); if (ia != -1) { var x = dp.Position.X; var fxArray = Fx.AsEnumerable().ToArray(); for (int ifx = 0; ifx < fxArray.Length; ifx++) { double freq = fxArray[ifx]; var sinNegativeTwoPiFX = Math.Sin(-2 * Math.PI * freq * x); var cosNegativeTwoPiFX = Math.Cos(-2 * Math.PI * freq * x); // convert to Hz-sec from GHz-ns 1e-9*1e9=1 var deltaWeight = dp.Weight * (cosNegativeTwoPiFX + Complex.ImaginaryOne * sinNegativeTwoPiFX); Mean[ifx, ia] += deltaWeight; if (TallySecondMoment) // 2nd moment is E[xx*]=E[xreal^2]+E[ximag^2] { var deltaWeight2 = dp.Weight * dp.Weight * cosNegativeTwoPiFX * cosNegativeTwoPiFX + dp.Weight * dp.Weight * sinNegativeTwoPiFX * sinNegativeTwoPiFX; SecondMoment[ifx, ia] += deltaWeight2; } } TallyCount++; } }
/// <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 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++; } }
/// <summary> /// method to tally to detector /// </summary> /// <param name="photon">photon data needed to tally</param> public void Tally(Photon photon) { var ia = DetectorBinning.WhichBin(Math.Acos(photon.DP.Direction.Uz), Angle.Count - 1, Angle.Delta, Angle.Start); Mean[ia] += photon.DP.Weight; if (TallySecondMoment) { SecondMoment[ia] += photon.DP.Weight * photon.DP.Weight; } TallyCount++; }
/// <summary> /// method to tally to detector /// </summary> /// <param name="photon">photon data needed to tally</param> public void Tally(Photon photon) { var ir = DetectorBinning.WhichBin(DetectorBinning.GetRho(photon.DP.Position.X, photon.DP.Position.Y), Rho.Count - 1, Rho.Delta, Rho.Start); Mean[ir] += photon.DP.Weight; if (TallySecondMoment) { SecondMoment[ir] += photon.DP.Weight * photon.DP.Weight; } TallyCount++; }
/// <summary> /// method to tally to detector /// </summary> /// <param name="photon">photon data needed to tally</param> public void Tally(Photon photon) { var ix = DetectorBinning.WhichBin(photon.DP.Position.X, X.Count - 1, X.Delta, X.Start); var iy = DetectorBinning.WhichBin(photon.DP.Position.Y, Y.Count - 1, Y.Delta, Y.Start); Mean[ix, iy] += photon.DP.Weight; if (TallySecondMoment) { SecondMoment[ix, iy] += photon.DP.Weight * photon.DP.Weight; } TallyCount++; }
/// <summary> /// method to tally to detector /// </summary> /// <param name="photon">photon data needed to tally</param> public void Tally(Photon photon) { // if exiting tissue top surface, Uz < 0 => Acos in [pi/2, pi] var ia = DetectorBinning.WhichBin(Math.Acos(photon.DP.Direction.Uz), Angle.Count - 1, Angle.Delta, Angle.Start); var ir = DetectorBinning.WhichBin(DetectorBinning.GetRho(photon.DP.Position.X, photon.DP.Position.Y), Rho.Count - 1, Rho.Delta, Rho.Start); Mean[ir, ia] += photon.DP.Weight; if (TallySecondMoment) { SecondMoment[ir, ia] += photon.DP.Weight * photon.DP.Weight; } TallyCount++; }
/// <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); Mean[ir] += photon.DP.Weight / photon.DP.Direction.Uz; if (TallySecondMoment) { SecondMoment[ir] += (photon.DP.Weight / photon.DP.Direction.Uz) * (photon.DP.Weight / photon.DP.Direction.Uz); } TallyCount++; }
/// <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 it = DetectorBinning.WhichBin(photon.DP.TotalTime, Time.Count - 1, Time.Delta, Time.Start); Mean[ir, it] += photon.DP.Weight; if (TallySecondMoment) { SecondMoment[ir, it] += photon.DP.Weight * photon.DP.Weight; } 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 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); if (weight != 0.0) { Mean[ir, iz] += weight; if (TallySecondMoment) { _tallyForOnePhoton[ir, iz] += weight; } TallyCount++; } }
/// <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 dp = photon.DP; var x = dp.Position.X; // WhichBin to match ROfFxAndTime var it = DetectorBinning.WhichBin(dp.TotalTime, Time.Count - 1, Time.Delta, Time.Start); if (it != -1) { double weightFactor = _absorbAction( photon.History.SubRegionInfoList.Select(c => c.NumberOfCollisions).ToArray(), photon.History.SubRegionInfoList.Select(p => p.PathLength).ToArray(), _perturbedOps, _referenceOps, _perturbedRegionsIndices); for (int ifx = 0; ifx < _fxArray.Length; ++ifx) { double freq = _fxArray[ifx]; var sinNegativeTwoPiFX = Math.Sin(-2 * Math.PI * freq * x); var cosNegativeTwoPiFX = Math.Cos(-2 * Math.PI * freq * x); /* convert to Hz-sec from MHz-ns 1e-6*1e9=1e-3 */ // convert to Hz-sec from GHz-ns 1e-9*1e9=1 var deltaWeight = dp.Weight * weightFactor * (cosNegativeTwoPiFX + Complex.ImaginaryOne * sinNegativeTwoPiFX); Mean[ifx, it] += deltaWeight; if (TallySecondMoment) // 2nd moment is E[xx*]=E[xreal^2]+E[ximag^2] { var deltaWeight2 = dp.Weight * dp.Weight * weightFactor * weightFactor * cosNegativeTwoPiFX * cosNegativeTwoPiFX + dp.Weight * dp.Weight * weightFactor * weightFactor * sinNegativeTwoPiFX * sinNegativeTwoPiFX; // second moment of complex tally is square of real and imag separately SecondMoment[ifx, it] += deltaWeight2; } } TallyCount++; } }
/// <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 ix = DetectorBinning.WhichBin(photon.DP.Position.X, X.Count - 1, X.Delta, X.Start); var iy = DetectorBinning.WhichBin(photon.DP.Position.Y, Y.Count - 1, Y.Delta, Y.Start); var it = DetectorBinning.WhichBin(photon.DP.TotalTime, Time.Count - 1, Time.Delta, Time.Start); Mean[ix, iy, it] += photon.DP.Weight; if (TallySecondMoment) { SecondMoment[ix, iy, it] += photon.DP.Weight * photon.DP.Weight; } TallyCount++; }
/// <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); double maxDepth = photon.History.HistoryData.Max(d => d.Position.Z); var id = DetectorBinning.WhichBin(maxDepth, MaxDepth.Count - 1, MaxDepth.Delta, MaxDepth.Start); Mean[ir, id] += photon.DP.Weight; // mean integrated over max depth = R(rho) if (TallySecondMoment) { SecondMoment[ir, id] += photon.DP.Weight * photon.DP.Weight; } TallyCount++; }
/// <summary> /// method to tally to detector /// </summary> /// <param name="photon">photon data needed to tally</param> public void Tally(Photon photon) { var ir = DetectorBinning.WhichBin(DetectorBinning.GetRho(photon.DP.Position.X, photon.DP.Position.Y), Rho.Count - 1, Rho.Delta, Rho.Start); if (ir != -1) { double weightFactor = _absorbAction( photon.History.SubRegionInfoList.Select(c => c.NumberOfCollisions).ToList(), photon.History.SubRegionInfoList.Select(p => p.PathLength).ToList(), _perturbedOps, _referenceOps, _perturbedRegionsIndices); Mean[ir] += photon.DP.Weight * weightFactor; if (TallySecondMoment) { SecondMoment[ir] += photon.DP.Weight * weightFactor * photon.DP.Weight * weightFactor; } TallyCount++; } }
/// <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 ix = DetectorBinning.WhichBin(photon.DP.Position.X, X.Count - 1, X.Delta, X.Start); var iy = DetectorBinning.WhichBin(photon.DP.Position.Y, Y.Count - 1, Y.Delta, Y.Start); double maxDepth = photon.History.HistoryData.Max(d => d.Position.Z); var id = DetectorBinning.WhichBin(maxDepth, MaxDepth.Count - 1, MaxDepth.Delta, MaxDepth.Start); Mean[ix, iy, id] += photon.DP.Weight; if (TallySecondMoment) { SecondMoment[ix, iy, id] += photon.DP.Weight * photon.DP.Weight; } 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 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) { Mean[ix, iy, iz] += weight; if (TallySecondMoment) { _tallyForOnePhoton[ix, iy, iz] += weight; } TallyCount++; } }
/// <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; } // ray trace exit location and direction to location at ZPlane var positionAtZPlane = LayerTissueRegionToolbox.RayExtendToInfinitePlane( photon.DP.Position, photon.DP.Direction, ZPlane); var ix = DetectorBinning.WhichBin(positionAtZPlane.X, X.Count - 1, X.Delta, X.Start); var iy = DetectorBinning.WhichBin(positionAtZPlane.Y, Y.Count - 1, Y.Delta, Y.Start); Mean[ix, iy] += photon.DP.Weight; if (TallySecondMoment) { SecondMoment[ix, iy] += photon.DP.Weight * photon.DP.Weight; } 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 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) { Mean[ir, iz] += weight / _ops[regionIndex].Mua; if (TallySecondMoment) { _tallyForOnePhoton[ir, iz] += weight / _ops[regionIndex].Mua; } 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 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); // using Acos, -1<Uz<1 goes to pi<theta<0, so first bin is most forward directed angle var ia = DetectorBinning.WhichBin(Math.Acos(dp.Direction.Uz), Angle.Count - 1, Angle.Delta, Angle.Start); var weight = _absorptionWeightingMethod(previousDP, dp, currentRegionIndex); var regionIndex = currentRegionIndex; if (weight != 0.0) { Mean[ir, iz, ia] += weight / _ops[regionIndex].Mua; if (TallySecondMoment) { _tallyForOnePhoton[ir, iz, ia] += weight / _ops[regionIndex].Mua; } TallyCount++; } }
/// <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; } // if exiting tissue top surface, Uz < 0 => Acos in [pi/2, pi] var ix = DetectorBinning.WhichBin(photon.DP.Position.X, X.Count - 1, X.Delta, X.Start); var iy = DetectorBinning.WhichBin(photon.DP.Position.Y, Y.Count - 1, Y.Delta, Y.Start); // using Acos, -1<Uz<1 goes to pi<theta<0, so first bin is most forward directed angle var it = DetectorBinning.WhichBin(Math.Acos(photon.DP.Direction.Uz), Theta.Count - 1, Theta.Delta, Theta.Start); var ip = DetectorBinning.WhichBin(Math.Atan2(photon.DP.Direction.Uy, photon.DP.Direction.Ux), Phi.Count - 1, Phi.Delta, Phi.Start); Mean[ix, iy, it, ip] += photon.DP.Weight; if (TallySecondMoment) { SecondMoment[ix, iy, it, ip] += photon.DP.Weight * photon.DP.Weight; } TallyCount++; }
/// <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; } // ray trace exit location and direction to location at ZPlane in air var positionAtHeight = LayerTissueRegionToolbox.RayExtendToInfinitePlane( photon.DP.Position, photon.DP.Direction, ZPlane); var ir = DetectorBinning.WhichBin(DetectorBinning.GetRho(positionAtHeight.X, positionAtHeight.Y), Rho.Count - 1, Rho.Delta, Rho.Start); double maxDepth = photon.History.HistoryData.Max(d => d.Position.Z); var id = DetectorBinning.WhichBin(maxDepth, MaxDepth.Count - 1, MaxDepth.Delta, MaxDepth.Start); Mean[ir, id] += photon.DP.Weight; // mean integrated over max depth = R(rho) if (TallySecondMoment) { SecondMoment[ir, id] += photon.DP.Weight * photon.DP.Weight; } TallyCount++; }