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); }
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() }); }