/// <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++;
            }
        }
示例#4
0
        /// <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++;
            }
        }
示例#9
0
        /// <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++;
            }
        }
示例#10
0
        /// <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++;
        }
示例#12
0
        /// <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++;
            }
        }
示例#13
0
        /// <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++;
        }
示例#14
0
        /// <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++;
        }
示例#15
0
        /// <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++;
        }
示例#16
0
        /// <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++;
        }
示例#17
0
        /// <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++;
        }
示例#18
0
        /// <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++;
        }
示例#19
0
        /// <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++;
            }
        }
示例#21
0
        /// <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++;
        }
示例#23
0
        /// <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++;
        }
示例#25
0
        /// <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++;
            }
        }
示例#26
0
        /// <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++;
        }
示例#27
0
        /// <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++;
            }
        }
示例#29
0
        /// <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++;
        }
示例#30
0
        /// <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++;
        }