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);
            }
        }
        public void verify_that_GetFinalPositionAndWeight_samples_from_UnifOfXAndYAndZ_sampling_correctly()
        {
            ITissueInput tissueInput = new SingleInfiniteCylinderTissueInput();
            ITissue      tissue      = tissueInput.CreateTissue(AbsorptionWeightingType.Discrete,
                                                                PhaseFunctionType.HenyeyGreenstein, 0);

            tissue.Regions[3] = _xyzLoaderUnif.FluorescentTissueRegion;
            var xyzNorm = _xyzLoaderUnif.X.Delta * _xyzLoaderUnif.Y.Delta * _xyzLoaderUnif.Z.Delta;
            int ix, iz;

            for (int i = 0; i < 100; i++)
            {
                var photon = _fluorEmissionAOfXAndYAndZSourceUnif.GetNextPhoton(tissue);
                // verify that photons start within range of midpoints of voxels in infinite cylinder
                Assert.IsTrue((photon.DP.Position.X >= -0.5) && (photon.DP.Position.X <= 0.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 x=[-2 2] 4 bins, y=[-10 10] 1 bin, z=[0 3] 3 bins
                ix = (int)(photon.DP.Position.X + 0.5) + 1;
                iz = (int)(Math.Floor(photon.DP.Position.Z));
                // verify weight at location is equal to AOfXAndYAndZ note: setup with single y bin
                // expected: Map [ 0 1 1 0; 0 1 1 0; 0 0 0 0] row major
                // expected: A   [ 1 4 7 10; 2 5 8 11; 3 6 9 12] row major
                Assert.IsTrue(Math.Abs(photon.DP.Weight -
                                       _xyzLoaderUnif.AOfXAndYAndZ[ix, 0, iz] * xyzNorm) < 1e-6);
            }
        }
        public void verify_that_GetFinalPositionAndWeight_samples_from_CDFOfRhoAndZ_correctly()
        {
            var countArray = new int[_aOfRhoAndZDetector.Rho.Count - 1,
                                     _aOfRhoAndZDetector.Z.Count - 1];
            ITissueInput tissueInput = new SingleInfiniteCylinderTissueInput();
            ITissue      tissue      = tissueInput.CreateTissue(AbsorptionWeightingType.Discrete,
                                                                PhaseFunctionType.HenyeyGreenstein, 0);

            tissue.Regions[1] = _rhozLoaderCDF.FluorescentTissueRegion;
            for (int i = 0; i < 100; i++)
            {
                var photon = _fluorEmissionAOfRhoAndZSourceCDF.GetNextPhoton(tissue);
                // verify that photons start within range of midpoints of voxels in bounding cylinder
                var rho = Math.Sqrt(photon.DP.Position.X * photon.DP.Position.X +
                                    photon.DP.Position.Y * photon.DP.Position.Y);
                Assert.IsTrue(rho <= 3.5);
                Assert.IsTrue((photon.DP.Position.Z >= 0.5) && (photon.DP.Position.Z <= 1.5));
                Assert.IsTrue(Math.Abs(photon.DP.Weight - 1.0) < 1e-6);
                int irho = (int)(Math.Floor(rho));
                int iz   = (int)(Math.Floor(photon.DP.Position.Z));
                countArray[irho, iz] += 1;
            }
            // check that countArray is > 1 in region of AOfRhoAndZ
            Assert.AreEqual(countArray[0, 0], 2);
            Assert.AreEqual(countArray[0, 1], 4);
            Assert.AreEqual(countArray[1, 0], 11);
            Assert.AreEqual(countArray[1, 1], 7);
            Assert.AreEqual(countArray[2, 0], 12);
            Assert.AreEqual(countArray[2, 1], 19);
            Assert.AreEqual(countArray[3, 0], 22);
            Assert.AreEqual(countArray[3, 1], 23);
        }
        public void verify_that_GetFinalPositionAndWeight_samples_from_CDFOfXAndYAndZ_correctly()
        {
            var countArray = new int[_aOfXAndYAndZDetector.X.Count - 1,
                                     _aOfXAndYAndZDetector.Y.Count - 1, _aOfXAndYAndZDetector.Z.Count - 1];
            ITissueInput tissueInput = new SingleInfiniteCylinderTissueInput();
            ITissue      tissue      = tissueInput.CreateTissue(AbsorptionWeightingType.Discrete,
                                                                PhaseFunctionType.HenyeyGreenstein, 0);

            tissue.Regions[3] = _xyzLoaderCDF.FluorescentTissueRegion;
            for (int i = 0; i < 100; i++)
            {
                var photon = _fluorEmissionAOfXAndYAndZSourceCDF.GetNextPhoton(tissue);
                // verify that photons start within range of midpoints of voxels in infinite cylinder
                Assert.IsTrue((photon.DP.Position.X >= -0.5) && (photon.DP.Position.X <= 0.5));
                Assert.AreEqual(photon.DP.Position.Y, 0);
                Assert.IsTrue((photon.DP.Position.Z >= 0.5) && (photon.DP.Position.Z <= 1.5));
                Assert.IsTrue(Math.Abs(photon.DP.Weight - 1.0) < 1e-6);
                int ix = (int)(photon.DP.Position.X + 0.5) + 1;
                int iz = (int)(Math.Floor(photon.DP.Position.Z));
                countArray[ix, 0, iz] += 1;
            }
            // check that countArray is only 1 in region of infinite cylinder
            Assert.AreEqual(countArray[0, 0, 0], 0);
            Assert.AreEqual(countArray[1, 0, 0], 17);
            Assert.AreEqual(countArray[2, 0, 0], 31);
            Assert.AreEqual(countArray[3, 0, 0], 0);
            Assert.AreEqual(countArray[0, 0, 1], 0);
            Assert.AreEqual(countArray[1, 0, 1], 16);
            Assert.AreEqual(countArray[2, 0, 1], 36);
            Assert.AreEqual(countArray[3, 0, 1], 0);
            Assert.AreEqual(countArray[0, 0, 2], 0);
            Assert.AreEqual(countArray[1, 0, 2], 0);
            Assert.AreEqual(countArray[2, 0, 2], 0);
            Assert.AreEqual(countArray[3, 0, 2], 0);
            // Note: with the unit test AOfXAndYAndZ defined array the PDF is:
            // PDF[1,0,0]=16.6
            // PDF[2,0,0]=29.2
            // PDF[1,0,1]=20.8
            // PDF[2,0,1]=33.3 -> so not bad agreement
        }