public static void OptiPng(DbStudy study) { string dcmPath = ADCM.GetStoreString(); foreach (var ser in study.series) { string outputPath = Path.Combine(dcmPath, "OUTPUT", study.case_id, study.study_uid, ser.series_uid); if (Directory.Exists(outputPath)) { var pngs = Directory.GetFiles(outputPath, "*.png"); if (pngs == null || pngs.Length < 1) { continue; } foreach (var f in pngs) { if (File.Exists(@".\OptiPNG\optipng.exe")) { // Run OPTIPNG with level 7 compression. System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo(); info.FileName = @".\OptiPNG\optipng.exe"; info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; info.Arguments = "\"" + f + "\""; // Use Process for the application. using (System.Diagnostics.Process exe = System.Diagnostics.Process.Start(info)) { exe.WaitForExit(); } } } } } }
public static void ClearCaseFiles(DbCase pcase) { string dcmPath = ADCM.GetStoreString(); foreach (var st in pcase.study_list) { string stDir = Path.Combine(dcmPath, st.study_uid); if (Directory.Exists(stDir)) { Directory.Delete(stDir, true); } } string outputPath = Path.Combine(dcmPath, "OUTPUT", pcase.case_id); if (Directory.Exists(outputPath)) { Directory.Delete(outputPath, true); } }
public static bool ZipSeries(DbStudy study) { try { string scpPath = ADCM.GetStoreString(); string outputPath = Path.Combine(scpPath, "OUTPUT", study.case_id, study.study_uid); if (!Directory.Exists(outputPath)) { throw new Exception("Output path not found: " + outputPath); } var seriesPaths = Directory.GetDirectories(outputPath); foreach (var s in seriesPaths) { //ReorderImages(s); var seriesUID = s.Substring(s.LastIndexOf(Path.DirectorySeparatorChar) + 1); string zipPath = Path.Combine(outputPath, seriesUID + ".zip"); using (ZipFile zip = new ZipFile()) { zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestSpeed; zip.AddDirectory(s); zip.Save(zipPath); } FileInfo zipInfo = new FileInfo(zipPath); double megabytes = Math.Round((zipInfo.Length / 1024f) / 1024f, 2); LOG.Write("Zip created: " + zipInfo.Name + ", " + megabytes + " MB"); LOG.InsertEvent("Zip created: " + zipInfo.Name + " - " + megabytes + "MB", "IMG", null, study.case_id, study.study_uid, seriesUID); System.Threading.Thread.Sleep(500); } LOG.InsertEvent("Successfully created ZIP files for all series in study", "IMG", null, study.case_id, study.study_uid); return(true); } catch (Exception ex) { string errorString = "Error at :" + System.Reflection.MethodBase.GetCurrentMethod().Name; LOG.Write(errorString); LOG.Write(ex.Message); LOG.InsertEvent(errorString, "IMG", ex.Message, study.case_id, study.study_uid); return(false); } }
public static void MultiFrameProcess(DbStudy study) { string dcmPath = ADCM.GetStoreString(); var seriesList = Directory.GetDirectories(Path.Combine(dcmPath, study.study_uid)); foreach (var sePath in seriesList) { var filesList = Directory.GetFiles(sePath, "*.dcm"); if (filesList.Length < 2) { continue; } for (int i = 0; i < filesList.Length; i++) { var dcm = new DicomFile(filesList[i]); dcm.Load(); int frameCount = dcm.DataSet[DicomTags.NumberOfFrames].GetInt16(0, 0); if (frameCount > 1) { string newSeriesUID = sePath + "." + i; newSeriesUID = newSeriesUID.Substring(newSeriesUID.LastIndexOf(Path.DirectorySeparatorChar) + 1); string newSeriesPath = Path.Combine(dcmPath, study.study_uid, newSeriesUID); Directory.CreateDirectory(newSeriesPath); string fileName = Path.GetFileName(filesList[i]); string oldPath = filesList[i]; string newPath = Path.Combine(newSeriesPath, fileName); File.Move(filesList[i], Path.Combine(newSeriesPath, fileName)); } } } foreach (string sePath in seriesList) { var filesCount = Directory.GetFiles(sePath); if (filesCount.Length < 1) { Directory.Delete(sePath); } } }
public static void ProcessCase(DbCase pcase) { try { LOG.Write("Checking user quotas..."); if (!CheckQuotas(pcase)) { throw new Exception("Quota exceeded"); } LOG.Write("Creating case on Radiopaedia..."); pcase.r_case_id = AUP.CreateCase(pcase); if (string.IsNullOrEmpty(pcase.r_case_id)) { throw new Exception("Unable to create case id, cannot continue"); } LOG.Write("Case created id: " + pcase.r_case_id); if (pcase.study_list == null || pcase.study_list.Count < 1) { pcase.study_list = GetStudiesForCase(pcase.case_id); if (pcase.study_list == null || pcase.study_list.Count < 1) { throw new Exception("No studies in case: " + pcase.case_id); } } foreach (var st in pcase.study_list) { LOG.InsertEvent("Starting to process case: " + pcase.case_id, "AGENT", null, pcase.case_id); LOG.Write("Creating Radiopaedia Study..."); st.r_study_id = AUP.CreateStudy(st, pcase.username, pcase.r_case_id); if (string.IsNullOrEmpty(st.r_study_id)) { throw new Exception("Unable to create study id on Radiopaedia"); } LOG.Write("Study ID created: " + st.r_study_id); LOG.Write("Study: " + st.description + "[" + st.modality + "]"); LOG.Write("Downloading..."); bool downloadComplete = ADCM.DownloadStudy(st, 0); if (!downloadComplete) { ClearCaseFiles(pcase); throw new Exception("Unable to download study - can't continue"); } LOG.Write("Download finished"); LOG.Write("Converting DCM to PNG..."); AIMG.MultiFrameProcess(st); bool convertComplete = AIMG.ConvertDcmToPng(st); if (!convertComplete) { ClearCaseFiles(pcase); throw new Exception("Unable to convert study to PNG"); } LOG.Write("Completed image conversion"); LOG.Write("Deleting excess images..."); AIMG.DeleteExcessImages(st); LOG.Write("Completed deleting excess images."); LOG.Write("Optimizing PNG's for study..."); AIMG.OptiPng(st); LOG.Write("Completed optimization."); bool zipComplete = AIMG.ZipSeries(st); if (!zipComplete) { throw new Exception("Unable to create zips for study"); } string outPath = Path.Combine(ADCM.GetStoreString(), "OUTPUT", pcase.case_id, st.study_uid); var zips = Directory.GetFiles(outPath, "*.zip"); foreach (var z in zips) { string fileName = Path.GetFileName(z); string[] sizes = { "B", "KB", "MB", "GB" }; double len = new FileInfo(z).Length; int order = 0; while (len >= 1024 && ++order < sizes.Length) { len = len / 1024; } LOG.Write(string.Format("Uploading: {2} ({0:0.##} {1})", len, sizes[order], fileName)); bool uploadedZip = AUP.UploadZip2(pcase.r_case_id, st.r_study_id, z, pcase.username, pcase.case_id, st.study_uid); if (!uploadedZip) { try { LOG.Write("Retry maxed out, copying zip to error output"); string errorFolder = Path.Combine(@".\Error_uploads\", pcase.case_id); if (!Directory.Exists(errorFolder)) { Directory.CreateDirectory(errorFolder); } string errorPath = Path.Combine(errorFolder, fileName); File.Copy(z, errorPath); } catch { continue; } } LOG.Write("Finished uploading"); } } LOG.Write("Marking case as completed"); AUP.MarkCaseComplete(pcase.r_case_id, pcase.username, pcase.case_id); SetCaseStatus(pcase, "COMPLETED", "Case fully uploaded: http://radiopaedia.org/cases/" + pcase.r_case_id); System.Threading.Thread.Sleep(1000); LOG.Write("Finished with case: " + pcase.case_id); ClearCaseFiles(pcase); LOG.InsertEvent("Finished with case: " + pcase.case_id, "AGENT", null, pcase.case_id); } catch (Exception ex) { string errorString = "Error at :" + System.Reflection.MethodBase.GetCurrentMethod().Name; LOG.Write(errorString); LOG.Write(ex.Message); LOG.InsertEvent(errorString, "AGENT", ex.Message, pcase.case_id); SetCaseStatus(pcase, "ERROR", ex.Message); ClearCaseFiles(pcase); } finally { GC.Collect(); } }
/// <summary> /// Process C-Echo and C-Store request. /// </summary> /// <param name="server"></param> /// <param name="association"></param> /// <param name="presentationID"></param> /// <param name="message"></param> void IDicomServerHandler.OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, DicomMessage message) { if (message.CommandField == DicomCommandField.CEchoRequest) { server.SendCEchoResponse(presentationID, message.MessageId, DicomStatuses.Success); return; } else if (message.CommandField != DicomCommandField.CStoreRequest) { server.SendCEchoResponse(presentationID, message.MessageId, DicomStatuses.UnrecognizedOperation); return; } else if (message.CommandField == DicomCommandField.CStoreRequest) { Platform.Log(LogLevel.Info, message.DataSet.DumpString); ClearCanvas.Common.Platform.Log(LogLevel.Info, "C-Store request for {0}.", message.MessageId); String studyInstanceUid = null; String seriesInstanceUid = null; DicomUid sopInstanceUid; String patientName = null; bool ok = message.DataSet[DicomTags.SopInstanceUid].TryGetUid(0, out sopInstanceUid); if (ok) { ok = message.DataSet[DicomTags.SeriesInstanceUid].TryGetString(0, out seriesInstanceUid); } if (ok) { ok = message.DataSet[DicomTags.StudyInstanceUid].TryGetString(0, out studyInstanceUid); } if (ok) { ok = message.DataSet[DicomTags.PatientsName].TryGetString(0, out patientName); } //if (!ok) //{ // server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID, DicomStatuses.ProcessingFailure); // return; //} try { // You can save the file by using this _storePath = ADCM.GetStoreString(); if (string.IsNullOrEmpty(_storePath)) { throw new Exception("No store path provided"); } string studyfolder = Path.Combine(_storePath, studyInstanceUid); studyfolder = Path.Combine(studyfolder, seriesInstanceUid); if (!Directory.Exists(studyfolder)) { Directory.CreateDirectory(studyfolder); } string filename = Path.Combine(studyfolder, message.DataSet[DicomTags.SopInstanceUid].ToString() + ".dcm"); DicomFile file = new DicomFile(message, filename); file.Save(filename, DicomWriteOptions.Default); ClearCanvas.Common.Platform.Log(ClearCanvas.Common.LogLevel.Info, "Sending C-Store success response."); server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID, DicomStatuses.Success); } catch (Exception ex) { ClearCanvas.Common.Platform.Log(LogLevel.Error, ex, "Unable to store request {0}.", message.MessageId); server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid != null ? sopInstanceUid.UID : string.Empty, DicomStatuses.ProcessingFailure); } } }
public static bool ConvertDcmToPng(DbStudy study) { try { string dcmPath = ADCM.GetStoreString(); string studyPath = Path.Combine(dcmPath, study.study_uid); if (!Directory.Exists(studyPath)) { throw new Exception("Study path not found"); } var allSeriesPaths = Directory.GetDirectories(studyPath); if (allSeriesPaths.Length < 1) { throw new Exception("No series subdirectories"); } foreach (var s in allSeriesPaths) { var dcmFiles = Directory.GetFiles(s, "*.dcm"); if (dcmFiles.Length < 1) { throw new Exception("No DCM files inside series path: " + s); } DicomFile tempdcm = new DicomFile(dcmFiles[0]); tempdcm.Load(); var seriesName = tempdcm.DataSet[DicomTags.SeriesDescription].GetString(0, null); var seriesUID = s.Substring(s.LastIndexOf(Path.DirectorySeparatorChar) + 1); if (string.IsNullOrEmpty(seriesName)) { seriesName = "Unamed_Series"; } APetaPoco.SetConnectionString("cn1"); var bm = APetaPoco.PpRetrieveOne <DbSeries>("Series", "[case_id] = '" + study.case_id + "' AND [series_uid] = '" + seriesUID + "'"); DbSeries dbseries = null; if (bm.Success) { dbseries = (DbSeries)bm.Data; } string outputPath = Path.Combine(dcmPath, "OUTPUT", study.case_id, study.study_uid, seriesUID); if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } //int fileCount = 0; for (int k = 0; k < dcmFiles.Length; k++) { DicomFile dcmFile = new DicomFile(dcmFiles[k]); dcmFile.Load(); int fileCount = 0; var windowWidth = dcmFile.DataSet[DicomTags.WindowWidth].ToString(); if (!string.IsNullOrEmpty(windowWidth)) { var tempSplitString = windowWidth.Split('\\'); windowWidth = tempSplitString[0]; } var windowCenter = dcmFile.DataSet[DicomTags.WindowCenter].ToString(); if (!string.IsNullOrEmpty(windowCenter)) { var tempSplitString = windowCenter.Split('\\'); windowCenter = tempSplitString[0]; } var ww = dcmFile.DataSet[DicomTags.WindowWidth].GetFloat32(0, 0); var wc = dcmFile.DataSet[DicomTags.WindowCenter].GetFloat32(0, 0); if (ww == 0 && !string.IsNullOrEmpty(windowWidth)) { if (windowWidth.Contains(".")) { var tempSplitString = windowWidth.Split('.'); ww = int.Parse(tempSplitString[0]); } else { ww = int.Parse(windowWidth); } } if (wc == 0 && !string.IsNullOrEmpty(windowCenter)) { if (windowCenter.Contains(".")) { var tempSplitString = windowCenter.Split('.'); wc = int.Parse(tempSplitString[0]); } else { wc = int.Parse(windowCenter); } } LocalSopDataSource localds = new LocalSopDataSource(dcmFile); if (!localds.IsImage) { continue; } ImageSop sop = new ImageSop(localds); int frameCount = sop.Frames.Count; var fileName = dcmFile.DataSet[DicomTags.InstanceNumber].GetInt16(0, 0); if (frameCount > 1) { for (int j = 1; j <= frameCount; j++) { GC.Collect(); Frame f = sop.Frames[j]; var jpgPath = Path.Combine(outputPath, fileName + "." + j + ".png"); Bitmap bmp = null; if (string.IsNullOrEmpty(windowWidth) || string.IsNullOrEmpty(windowCenter)) { bmp = DrawDefaultFrame(f); } else { bmp = DrawLutFrame(f, ww, wc); } if (bmp != null) { if (dbseries != null && dbseries.crop_h != null && dbseries.crop_w != null && dbseries.crop_x != null && dbseries.crop_y != null) { bmp = Crop(bmp, dbseries.crop_x.Value, dbseries.crop_y.Value, dbseries.crop_w.Value, dbseries.crop_h.Value); } SaveImage(bmp, jpgPath); } fileCount += 1; GC.Collect(); } } else { GC.Collect(); var jpgPath = Path.Combine(outputPath, fileName + ".png"); Frame f = sop.Frames[1]; Bitmap bmp = null; if (string.IsNullOrEmpty(windowWidth) || string.IsNullOrEmpty(windowCenter)) { bmp = DrawDefaultFrame(f); } else { bmp = DrawLutFrame(f, ww, wc); } if (bmp != null) { if (dbseries != null && dbseries.crop_h != null && dbseries.crop_w != null && dbseries.crop_x != null && dbseries.crop_y != null) { bmp = Crop(bmp, dbseries.crop_x.Value, dbseries.crop_y.Value, dbseries.crop_w.Value, dbseries.crop_h.Value); } SaveImage(bmp, jpgPath); } fileCount += 1; GC.Collect(); } } } LOG.InsertEvent("Successfully converted study from DCM to PNG", "IMG", null, study.case_id, study.study_uid); return(true); } catch (Exception ex) { string errorString = "Error at :" + System.Reflection.MethodBase.GetCurrentMethod().Name; LOG.Write(errorString); LOG.Write(ex.Message); LOG.InsertEvent(errorString, "IMG", ex.Message, study.case_id, study.study_uid); return(false); } }
public static void DeleteExcessImages(DbStudy study) { try { string dcmPath = ADCM.GetStoreString(); string outputPath = Path.Combine(dcmPath, "OUTPUT", study.case_id, study.study_uid); if (!Directory.Exists(outputPath)) { throw new Exception("No output path found: " + outputPath); } foreach (var ser in study.series) { string serPath = Path.Combine(outputPath, ser.series_uid); if (Directory.Exists(serPath)) { var sortedList = Directory.GetFiles(serPath, "*.png").OrderBy(f => int.Parse(Path.GetFileNameWithoutExtension(f))).ToList(); if (sortedList.Count > ser.images) { int start = 1; int end = ser.images; int stepping = 1; if (ser.start_image != null && ser.start_image > 0) { start = ser.start_image.Value; } if (ser.end_image != null && ser.end_image > 0) { end = ser.end_image.Value; } if (end > sortedList.Count) { end = sortedList.Count; } if (ser.every_image != null && ser.every_image > 0) { stepping = ser.every_image.Value; } List <string> keepPaths = new List <string>(); LOG.Write(string.Format("Start: {0}| End: {1}| Stepping: {2}", start, end, stepping)); for (int i = start - 1; i < end; i += stepping) { //LOG.Write(string.Format("[{0}] Keeping {1}", i, sortedList[i])); keepPaths.Add(sortedList[i]); } foreach (var f in sortedList) { if (!keepPaths.Contains(f)) { //LOG.Write(string.Format("Deleting {0}", f)); File.Delete(f); } } } } else { LOG.Write("No series path: " + serPath); } } } catch (Exception ex) { LOG.Write(ex.Message); } }