public static void GetRingAndDetectorForXY(int aPosition, UInt16 XPlus, UInt16 XMinus, UInt16 YPlus, UInt16 YMinus, out int Ring, out int Detector) { var blockNumber = (aPosition >> 4) & 0xFF; var ringGroup = aPosition & 0xF; var i = blockNumber * 15 + EventConverter.iForX(XPlus, XMinus); var j = ringGroup * 15 + EventConverter.jForY(YPlus, YMinus); Detector = i; Ring = j; }
public bool Detect(Photon ph, out PETSingleEvent se) { se = new PETSingleEvent(); if (ph.Status != stat.Finished) { return(false); } //to cylindrical double azimuthalAngle = Math.Atan2(ph.CurrentPosition.Y, ph.CurrentPosition.X); if (azimuthalAngle < 0) { azimuthalAngle += 2 * Math.PI; } //double rc = Math.Sqrt(ph.CurrentPosition.X * ph.CurrentPosition.X + ph.CurrentPosition.Y * ph.CurrentPosition.Y + ph.CurrentPosition.Z * ph.CurrentPosition.Z) * Math.Sin(ph.Theta); double rc = Math.Sqrt(ph.CurrentPosition.X * ph.CurrentPosition.X + ph.CurrentPosition.Y * ph.CurrentPosition.Y); double z0 = ph.CurrentPosition.Z; var tmpAngle = Math.Asin(rc / this.RingRadius * Math.Sin(azimuthalAngle - ph.Phi)); //var tmpAngle = this.Phi - azimuthalAngle - Math.Asin(rc / ringRadius * Math.Sin(azimuthalAngle - this.Phi)); var psi = tmpAngle + ph.Phi; //угол регистрации if (psi < 0) { psi += 2 * Math.PI; } if (psi >= 2 * Math.PI) { psi -= 2 * Math.PI; } var block = (int)(psi / (2 * Math.PI) * this.BlocksCount); // номер блока детекторов var r1 = Math.Sqrt(this.RingRadius * this.RingRadius + rc * rc - 2 * this.RingRadius * rc * Math.Cos(azimuthalAngle - psi)); var dz = (r1 / Math.Tan(ph.Theta)) / this.BlockSize; z0 /= this.BlockSize; var blockRing = (int)Math.Floor(z0 + dz + this.RingsCount / 2.0); // номер кольца блоков //double s = Math.Sqrt((this.CurrentPosition.X - ringRadius * Math.Cos(psi)) * (this.CurrentPosition.X - ringRadius * Math.Cos(psi)) + // (this.CurrentPosition.Y - ringRadius * Math.Sin(psi)) * (this.CurrentPosition.Y - ringRadius * Math.Sin(psi)) + // (this.CurrentPosition.Z - dz * blockSide) * (this.CurrentPosition.Z - dz * blockSide)) + this.Path; //this.Time += s / (3e11); if (blockRing >= 0 && blockRing < this.RingsCount) { se.Position = (UInt16)(((block & 0x3F) << 4) | (blockRing & 0xF)); se.Timestamp = (UInt32)(ph.Time); var I = (byte)((psi - block * 2 * Math.PI / this.BlocksCount) / (2 * Math.PI / (this.BlocksCount * this.DetectorsPerBlock))); var J = (byte)((z0 + dz + this.RingsCount / 2.0) * this.DetectorsPerBlock) % this.DetectorsPerBlock; EventConverter.GetXYFromIJ(I, (byte)J, ph.Energy, out se.XPlus, out se.XMinus, out se.YPlus, out se.YMinus); return(true); } return(false); }
public void Build(string path) { var sins = new double[numSins][, ]; for (int i = 0; i < numSins; i++) { sins[i] = new double[indexer.NumDirs, indexer.NumLines]; } Bitmap bmp = new Bitmap(1024, 1024); Graphics gr = Graphics.FromImage(bmp); gr.TranslateTransform(bmp.Width / 2f, bmp.Height / 2f); List <string> fileList = new List <string>(); if (Directory.Exists(path)) { DirectoryInfo di = new DirectoryInfo(path); FileSystemInfo[] files = di.GetFileSystemInfos(); foreach (var file in files) { fileList.Add(file.FullName); } } foreach (var file in fileList) { var clist = WorkWithFiles.ReadCoincList(file); foreach (var c in clist) { PETDigitalCoincidenceTOF cIJ = new PETDigitalCoincidenceTOF(); EventConverter.CalculateDigitalCoincidenceTOF(c, ref cIJ); int Ring1 = indexer.GetRing(c.Position1, cIJ.J1); int Ring2 = indexer.GetRing(c.Position2, cIJ.J2); var sinidx = Ring1 + Ring2; if (sinidx >= numSins) { continue; } int Dir = indexer.GetDir(c.Position1, c.Position2, cIJ.I1, cIJ.I2); int Line = indexer.GetLine(c.Position1, c.Position2, cIJ.I1, cIJ.I2); //if (isDebug && ++cnt % 1000 == 0) //{ // gr.DrawLine(Pens.White, 410 * (float)Math.Cos(Math.PI * Detector1 / 360), 410 * (float)Math.Sin(Math.PI * Detector1 / 360), // 410 * (float)Math.Cos(Math.PI * Detector2 / 360), 410 * (float)Math.Sin(Math.PI * Detector2 / 360)); //} if (Line < 0) { continue; } sins[sinidx][Dir, Line]++; } } if (!Directory.Exists(outDir)) { Directory.CreateDirectory(outDir); } for (int i = 0; i < numSins; i++) { Sinogram sino = new Sinogram(sins[i], AnglesDistribution.Uniform(0, Math.PI, indexer.NumDirs)); Stream ostream = File.Create(string.Format("{0}\\{1}", outDir, string.Format("{0}.sg", i))); //using (StreamWriter w = new StreamWriter(ostream, Encoding.UTF8)) using (ostream) { Sinogram.SaveSinogramToStream(ostream, sino); } Sinogram.DumpSinogram(sins[i], string.Format("{0}\\{1}.png", outDir, i)); //if (isDebug) // bmp.Save(string.Format("{0}\\lines.png", arg.OutDir)); } }