示例#1
0
        private static double CalculateRatio(List <ScatterData> datas, List <int> waveLengths)
        {
            var coefficients = new Coefficients.Coefficients(Directory.GetCurrentDirectory());

            var R11 = datas[0].DetectedPhotons1 / datas[0].DetectedPhotons2;
            var R22 = datas[1].DetectedPhotons1 / datas[1].DetectedPhotons2;
            var R33 = datas[2].DetectedPhotons1 / datas[2].DetectedPhotons2;

            var R12 = R11 / R22;
            var R13 = R11 / R33;

            var alpha12 = Math.Log(R12);
            var alpha13 = Math.Log(R13);

            var alpha1 = coefficients.ObtainAbsorptionCoefficients((uint)waveLengths[0]);
            var alpha2 = coefficients.ObtainAbsorptionCoefficients((uint)waveLengths[1]);
            var alpha3 = coefficients.ObtainAbsorptionCoefficients((uint)waveLengths[2]);

            var alphaD1 = alpha1.AbsorptionBlood;
            var alphaD2 = alpha2.AbsorptionBlood;
            var alphaD3 = alpha3.AbsorptionBlood;

            var alphaO1 = alpha1.AbsorptionOxygenatedBlood;
            var alphaO2 = alpha2.AbsorptionOxygenatedBlood;
            var alphaO3 = alpha3.AbsorptionOxygenatedBlood;

            var topLine    = alpha12 * (alphaD3 + alphaD1) - alpha13 * (alphaD1 + alphaD2);
            var bottomLine = alpha13 * (alpha1.AbsorptionOxygenatedBlood - alpha2.AbsorptionOxygenatedBlood +
                                        alpha1.AbsorptionBlood - alpha2.AbsorptionBlood) -
                             alpha12 * (alpha1.AbsorptionOxygenatedBlood + alpha3.AbsorptionOxygenatedBlood -
                                        alpha1.AbsorptionBlood - alpha3.AbsorptionBlood);

            var ratio = Math.Sqrt(Math.Pow(topLine / bottomLine, 2));

            return(ratio);
        }
示例#2
0
        static void Main(string[] args)
        {
            var coefficients           = new Coefficients.Coefficients(Directory.GetCurrentDirectory());
            var absorption             = coefficients.ObtainAbsorptionCoefficients(660);
            var scatteringCoefficients = Coefficients.Coefficients.ObtainScatteringCoefficients(660);

            var data400 = Scatter.Scatterlight(450, 0.1, 0.3, 0.05, 0.05, 1, 3, 0.150, 0.9, Directory.GetCurrentDirectory());
            var data660 = Scatter.Scatterlight(660, 0.1, 0.3, 0.05, 0.05, 1, 3, 0.150, 0.9, Directory.GetCurrentDirectory());
            var data900 = Scatter.Scatterlight(900, 0.1, 0.3, 0.05, 0.05, 1, 3, 0.150, 0.9, Directory.GetCurrentDirectory());

            var datas = new List <ScatterData>
            {
                data400,
                data660,
                data900
            };
            var wavelengths = new List <int> {
                450, 660, 900
            };

            CalculateRatio(datas, wavelengths);
        }
        /// <summary>
        /// Calculates scattering through tissue for a specific wavelength
        /// </summary>
        /// <param name="wavelength">wavelength (nanometers)</param>
        /// <param name="distanceToDetector1">Distance to first detector (in cm)</param>
        /// <param name="distanceToDetector2">Distance to second detector (in cm) Det2 > Det 1</param>
        /// <param name="width">Half width of both the light source and the detectors (cm)</param>
        /// <param name="dSkin">Thickness of the skin (cm)</param>
        /// <param name="dMuscle">Thickness of the msucle (cm)</param>
        /// <param name="dBone">Thickness of the bone. Photons that go trought the bone are dropped</param>
        /// <param name="concentrationBlood">Concentration of hemoglobin ~150g/liter</param>
        /// <param name="ratioOxygen">Ration of oxygenated to deoxyganted hemoglobin (between 0 and 1)</param>
        public static ScatterData Scatterlight(uint wavelength, double distanceToDetector1, double distanceToDetector2,
                                               double width, double dSkin, double dMuscle, double dBone, double concentrationBlood, double ratioOxygen, string resourceBasePath)
        {
            /*
             * We place the two detectors as a ring around the light source
             * and bound the model volume by 5*distanceToDetector2
             *
             * For absorption, each photon is given a starting weight, which is reduced by absorption
             */

            double xBound, yBound, zBound;

            xBound = yBound = 5.0 * distanceToDetector2;
            zBound = dSkin + dMuscle + dBone;

            var coefficients = new Coefficients.Coefficients(resourceBasePath);

            var scatteringCoefficients = Coefficients.Coefficients.ObtainScatteringCoefficients(wavelength);
            var absorptionCoefficients = coefficients.ObtainAbsorptionCoefficients(wavelength);

            var absorptionCoefficient = Coefficients.Coefficients.CalculateAbsorptionCoefficient(absorptionCoefficients.AbsorptionBlood,
                                                                                                 absorptionCoefficients.AbsorptionOxygenatedBlood, concentrationBlood, ratioOxygen);

            // Assume the ares of the light emitter is 0.1 cm^2 and that contact with the skin is not perfect
            var numPhotons = 5000000; //5e6

            var randomInstance = RandomDistribution.Instance;
            var xPos           = randomInstance.UniformDistribution(-width, width, numPhotons);
            var yPos           = randomInstance.UniformDistribution(-width, width, numPhotons);
            var zPos           = randomInstance.UniformDistribution(0, 1 / scatteringCoefficients.MuSkin, numPhotons);

            var distance = new List <double>(numPhotons);

            for (int i = 0; i < numPhotons; i++)
            {
                distance.Add(0);
            }

            var amplitude = new List <double>(numPhotons);

            for (int i = 0; i < numPhotons; i++)
            {
                amplitude.Add(100);
            }

            var keepScattering = true;
            var idsInModel     = new List <int>();

            for (int i = 0; i < numPhotons; i++)
            {
                idsInModel.Add(i);
            }

            double detectedPhotons1 = 0, detectedPhotons2 = 0;
            bool   firstD1 = true, firstD2 = true;

            List <double> lengthsToD1 = new List <double>();
            List <double> lengthsToD2 = new List <double>();

            while (keepScattering)
            {
                // Remove all photons outside the model boundaries from the calculation
                //var size = xPos.Count;
                //var tempX = new List<double>(size);
                //var tempY = new List<double>(size);
                //var tempZ = new List<double>(size);
                //var tempDistance = new List<double>(size);
                //foreach (var index in idsInModel)
                //{
                //    tempX.Add(xPos[index]);
                //    tempY.Add(yPos[index]);
                //    tempZ.Add(zPos[index]);
                //    tempDistance.Add(distance[index]);
                //}
                //xPos = new List<double>(tempX);
                //yPos = new List<double>(tempY);
                //zPos = new List<double>(tempZ);
                //distance = new List<double>(tempDistance);

                var tempList = new List <double>(xPos);
                xPos     = FilterOnIndexes(xPos, idsInModel);
                yPos     = FilterOnIndexes(yPos, idsInModel);
                zPos     = FilterOnIndexes(zPos, idsInModel);
                distance = FilterOnIndexes(distance, idsInModel);

                //xPos = xPos.Where(item => idsInModel.Contains(xPos.IndexOf(item))).ToList();
                //yPos = yPos.Where(item => idsInModel.Contains(yPos.IndexOf(item))).ToList();
                //zPos = zPos.Where(item => idsInModel.Contains(zPos.IndexOf(item))).ToList();
                //distance = distance.Where(item => distance.Contains(distance.IndexOf(item))).ToList();

                //Determine which photons are in which tissue and their indexes
                amplitude = FilterOnIndexes(amplitude, idsInModel);
                //amplitude = amplitude.Where(item => idsInModel.Contains(amplitude.IndexOf(item))).ToList();

                //var idxSkin = idsInModel.Where(index => zPos[index] <= dSkin).ToList(); //TODO veranderd dit zodat het niet meer gebruik maakt van idsInModel maar gewoon de index returnt van het item in de lijst waar de waarde voor geldt
                var idxSkin = new List <int>();
                for (int i = 0; i < zPos.Count; i++)
                {
                    if (zPos[i] <= dSkin)
                    {
                        idxSkin.Add(i);
                    }
                }
                var numInSkin = idxSkin.Count;

                //var idxmuscle = idsInModel.Where(index => zPos[index] <= dMuscle && zPos[index] > dSkin).ToList();
                var idxMuscle = new List <int>();
                for (int i = 0; i < zPos.Count; i++)
                {
                    if (zPos[i] <= dMuscle && zPos[i] > dSkin)
                    {
                        idxMuscle.Add(i);
                    }
                }
                var numInMuscle = idxMuscle.Count;

                //var idxBone = idsInModel.Where(index => zPos[index] <= dBone && zPos[index] > dSkin + dMuscle).ToList();
                var idxBone = new List <int>();
                for (int i = 0; i < zPos.Count; i++)
                {
                    if (zPos[i] <= dBone && zPos[i] > dSkin + dMuscle)
                    {
                        idxBone.Add(i);
                    }
                }
                var numInBone = idxBone.Count;

                // Determine the distance each photon travels using the right scattering coefficient
                // then use angles and that length to update photon positions

                // Assume that the vast majority of blood is in the muscle not the skin or bone, hence the abs coefficient is 0
                if (numInSkin > 0)
                {
                    var data = Photons.Photons.UpdatePositions(xPos, yPos, zPos, distance, idxSkin, amplitude, numInSkin,
                                                               scatteringCoefficients.MuSkin, 0);
                    xPos      = new List <double>(data.X);
                    yPos      = new List <double>(data.Y);
                    zPos      = new List <double>(data.Z);
                    amplitude = new List <double>(data.Amplitudes);
                    distance  = new List <double>(data.TraveledDistances);
                }

                if (numInMuscle > 0)
                {
                    var data = Photons.Photons.UpdatePositions(xPos, yPos, zPos, distance, idxMuscle, amplitude, numInMuscle,
                                                               scatteringCoefficients.MuMuscle, absorptionCoefficient);
                    xPos      = new List <double>(data.X);
                    yPos      = new List <double>(data.Y);
                    zPos      = new List <double>(data.Z);
                    amplitude = new List <double>(data.Amplitudes);
                    distance  = new List <double>(data.TraveledDistances);
                }

                // As with skin, we assume no blood in the bone(not true if you include marrow) ==> abs coef is 0
                if (numInBone > 0)
                {
                    var data = Photons.Photons.UpdatePositions(xPos, yPos, zPos, distance, idxBone, amplitude, numInBone,
                                                               scatteringCoefficients.MuBone, 0);
                    xPos      = new List <double>(data.X);
                    yPos      = new List <double>(data.Y);
                    zPos      = new List <double>(data.Z);
                    amplitude = new List <double>(data.Amplitudes);
                    distance  = new List <double>(data.TraveledDistances);
                }

                // Need to remove photons that are outside the calculation bounds and count up those that are detected
                var indexes = Photons.Photons.FilterPhotons(xPos, yPos, zPos, xBound, zBound);
                idsInModel = new List <int>(indexes);
                numPhotons = idsInModel.Count;

                // Calculate the intensity at each detector
                var photons1 = Photons.Photons.DetectorPhotons(xPos, yPos, zPos, distance, amplitude,
                                                               distanceToDetector1, width);
                var lengths1 = photons1.TraveledDistances;
                detectedPhotons1 += photons1.TotalAmplitude;

                var photons2 = Photons.Photons.DetectorPhotons(xPos, yPos, zPos, distance, amplitude,
                                                               distanceToDetector2, width);
                var lengths2 = photons2.TraveledDistances;
                detectedPhotons2 += photons2.TotalAmplitude;

                if (firstD1)
                {
                    lengthsToD1 = new List <double>(lengths1);
                    firstD1     = false;
                }
                else
                {
                    lengthsToD1.AddRange(lengths1);
                }

                if (firstD2)
                {
                    lengthsToD2 = new List <double>(lengths2);
                    firstD2     = false;
                }
                else
                {
                    lengthsToD2.AddRange(lengths2);
                }

                // Check to see if we have sufficient signal-to-noise at both detectors
                keepScattering = Photons.Photons.AreWeDone(detectedPhotons1, detectedPhotons2);
            }

            if (numPhotons < 100000)
            {
                // If we run out of photons before signal-to-noise is above threshold, inject some more
                xPos.AddRange(randomInstance.UniformDistribution(-width, width, 5000000));
                yPos.AddRange(randomInstance.UniformDistribution(-width, width, 5000000));
                zPos.AddRange(randomInstance.UniformDistribution(0, 1 / scatteringCoefficients.MuSkin, 5000000));

                for (int i = 0; i < 5000000; i++)
                {
                    amplitude.Add(100);
                }

                idsInModel = Photons.Photons.FilterPhotons(xPos, yPos, zPos, xBound, zBound);
                numPhotons = idsInModel.Count;
            }

            return(new ScatterData
            {
                DetectedPhotons1 = detectedPhotons1,
                DetectedPhotons2 = detectedPhotons2,
                LengthToD1 = lengthsToD1.Average(),
                LengthToD2 = lengthsToD2.Average()
            });
        }