Posts Tagged ‘dicom’

DICOM images downloader and cd burner

Vendredi, avril 8th, 2005

#!/usr/bin/python2.2  # Title: CDs.py # Descr: Retrieve images from IMAGEM PACS (Oracle/FTP) #        build up a dicomdir file # Author: Jean-Luc Cyr # License: (C)2005 Jean-Luc Cyr / Les systèmes médicaux IMAGEM # Created: 2005-04-08 # # Require: DCMTK utilities (dcmdjpeg, dcmconv, dcmgpdir)   # Oracle connection settings db_user = "ris_pacs" db_pass = "password" db_host = "rpdev" # FTP retrieve connection settings ftp_user = "robin" ftp_pass = "blitzkrieg" ftp_host = "192.168.2.70"  # Imports and defs ftp = "ftp://%s:%s@%s" % (ftp_user, ftp_pass, ftp_host) import cx_Oracle as db from urllib import urlretrieve import commands from os import stat  #program start HERE  #Ask for a patient id to fetch study list for patid = raw_input("Enter Pat ID:")  #Connect to db con = db.connect(db_user, db_pass, db_host) cur = con.cursor()  #Fetch study list for this patient cur.execute("select STU_DATE, STU_DESC, STU_INSTANCE_UID from study where stu_pat_id='%s' order by stu_date desc" % patid)  study = cur.fetchall()  for row in range(0,study.__len__()):     (date,desc,stuuid) = study[row]     print "%s - %s - %s" % (row+1,date,desc)  #Ask for studies to burn (index from returned list) studylist = raw_input("Enter Study (comma separated):")  stunolist = studylist.split(",") stulist="" for stuno in stunolist:     #stulist.insert(1,study[int(stuno)][2])     if stulist.__len__()>0:         stulist = "%s,'%s'" % (stulist,study[int(stuno)-1][2])     else:         stulist = "'%s'" % study[int(stuno)-1][2];  #Fetch image list (for all studies) select = "select MFS_MOUNT_POINT,COI_STUDY_INSTANCE_UID,COI_SERIES_INSTANCE_UID,COI_SOP_INSTANCE_UID from composite_object_instance,media_file_set where coi_study_instance_uid in (%s) and coi_sto_media_fset_uid = mfs_uid" % (stulist) cur.execute(select) coi = cur.fetchall()  #clean up last dicomdir and files op = commands.getoutput("rm *dcm") op = commands.getoutput("rm DICOMDIR") op = commands.getoutput("rm image.iso")  #Fetch images, convert them to the good uncompressed format #and build up the DICOMDIR file imlist=[] for row in range(0, coi.__len__()):     print "=== %s de %s ===" % (int(row)+1,coi.__len__())     (mfsuid,stuuid,seruid,coiuid) = coi[row]     url = "%s/%s/%s/%s/%s.dcm" % (ftp,mfsuid,stuuid,seruid,coiuid)     fileName = "%sdcm" % (row)     imlist.insert(1,"%s.dcm" % (coiuid))     print "*Retrieving %s" % coiuid     try:         urlretrieve(url,fileName);     except IOError:         print "Can't retrieve file"     else:         path = "/home/jlcyr/old_home/Devel/CDs";          print '*Uncompressing'             op = commands.getoutput("dcmdjpeg +te %s %s" % (fileName,fileName))         if op!="":             print op          print '*Converting to LittleEndianExplicit'         op = commands.getoutput("dcmconv +te %s %s" % (fileName,fileName))         if op!="":             print op          try:             stat("DICOMDIR")         except OSError:#file doesn't exist             print '*Creating DICOMDIR'             op = commands.getoutput("dcmgpdir +m +D DICOMDIR %s" % (fileName))             if op!="":                 print op                 op = commands.getoutput("rm %s" % (fileName))         else:             print '*Adding to DICOMDIR'                         op = commands.getoutput("dcmgpdir +A +m +D DICOMDIR %s" % (fileName))             if op!="":                 print op                 op = commands.getoutput("rm %s" % (fileName))  #Now burn the CD! print "==== Making ISO image ====" op = commands.getoutput("mkisofs *dcm DICOMDIR >image.iso") print op 


 

Dicom Worklist

Vendredi, avril 1st, 2005
#!/usr/bin/python2.3 # # Script to download a worklist file # and fetch each enumerated file # # author: Jean-Luc Cyr # created on : 2005-06-16 # for: Les systemes medicaux IMAGEM inc #   from urllib import urlopen, urlretrieve from os import makedirs, stat  #Variables globales method = "http://" listserver = "192.168.2.21" path = "/worklist/" inst = "CHUL" fileserver = "ftp://robin:blitzkrieg@192.168.2.70/" rootdir = "/home/jlcyr/dl/"  #Fonction pour downloader la liste de travail a partir du web def fetchlistweb():     print 'Retrieving worklist'     url = method + listserver + path + "worklist.php?INST_ID=" + inst     #print url     try:         page = urlopen(url).read()     except IOError:         print "Can't connect to server"         page = "Can't connect to server"     return page;  #Fonction pour downloader la liste de travail a partir de la db def fetchlistdb():     import cx_Oracle     list = "<PRE>#Liste de travail pour: CHUL\n"     destination='CHUL'     conn2 = cx_Oracle.connect('ris_pacs','password','rpdev')     cur2 = conn2.cursor()     select = "SELECT /*+ INDEX(c IDX_COI_STUDY_UID) */ DISTINCT a.AR_START_DOWNLOAD, c.COI_PAT_ID, c.COI_DATE, m.MFS_MOUNT_POINT,a.AR_STU_INSTANCE_UID, c.COI_SERIES_INSTANCE_UID, c.COI_SOP_INSTANCE_UID || '.dcm', s.STU_DESC FROM AUTO_ROUTING a, COMPOSITE_OBJECT_INSTANCE c, MEDIA_FILE_SET m, STUDY s WHERE COI_STUDY_INSTANCE_UID = AR_STU_INSTANCE_UID AND  COI_STO_MEDIA_FSET_UID = MFS_UID AND AR_STATUS = 'CREATED' AND  AR_DESTINATION = '%s' AND COI_TYPE = 'IMAGE'  AND AR_START_DOWNLOAD <= SYSDATE AND COI_STUDY_INSTANCE_UID = STU_INSTANCE_UID UNION SELECT /*+ INDEX(c1 IDX_COI_STUDY_UID) */ DISTINCT a.AR_START_DOWNLOAD, c2.COI_PAT_ID, c2.COI_DATE, m.MFS_MOUNT_POINT, c2.COI_STUDY_INSTANCE_UID, c2.COI_SERIES_INSTANCE_UID, c2.COI_SOP_INSTANCE_UID || '.dcm', s2.STU_DESC FROM AUTO_ROUTING a, COMPOSITE_OBJECT_INSTANCE c1, STUDY s1, HISTORICAL_IMAGES h, STUDY s2, COMPOSITE_OBJECT_INSTANCE c2, MEDIA_FILE_SET m WHERE a.AR_STATUS = 'CREATED' AND  a.AR_DESTINATION = '%s' AND a.AR_START_DOWNLOAD <= SYSDATE AND c1.COI_STUDY_INSTANCE_UID = a.AR_STU_INSTANCE_UID AND c1.COI_TYPE = 'IMAGE' AND a.AR_STU_INSTANCE_UID = s1.STU_INSTANCE_UID AND s1.STU_OTHER_NUMBER = h.HI_REF_EXAMCODE AND h.HI_EXAMCODE = s2.STU_OTHER_NUMBER AND s1.STU_PAT_ID = s2.STU_PAT_ID AND s1.STU_INSTANCE_UID != s2.STU_INSTANCE_UID AND s2.STU_INSTANCE_UID = c2.COI_STUDY_INSTANCE_UID AND c2.COI_TYPE = 'IMAGE' AND  c2.COI_STO_MEDIA_FSET_UID = m.MFS_UID ORDER BY 1  asc, 2, 3 desc" % (destination, destination)     items = 8     cur2.execute(select)     res2 = cur2.fetchall()     result={}     study = ""     for item in range(1,cur2.rowcount):         for cnt in range(0,items):             result[cur2.description[cnt][0]] = res2[item][cnt]         if (study!=result['AR_STU_INSTANCE_UID']):             if (study!=""):                 list += "End of Study:  "                 list += study                 list += "\n"             study=result['AR_STU_INSTANCE_UID']             list += "Start of Study:  "             list += study             list += "\n"         list += "%s/%s/%s/%s\n" % (result['MFS_MOUNT_POINT'],result['AR_STU_INSTANCE_UID'],result['COI_SERIES_INSTANCE_UID'],result["C.COI_SOP_INSTANCE_UID||'.DCM'"])     if (study!=""):         list += "End of Study:  "         list += study         list += "\n"     list += "</PRE>"     return list  #Fonction mettre des entrees dans la liste de travail def makedb():     print "Generation d'une liste de travail"     import cx_Oracle     conn2 = cx_Oracle.connect('ris_pacs','password','rpdev')     cur2 = conn2.cursor()     select = "update AUTO_ROUTING set AR_STATUS='CREATED'"     cur2.execute(select)     select = "commit"     cur2.execute(select)  #Fonction pour updater la liste de travail quand une etude est downloade def updatelist(study):     print "Updating worklist for study %s " % ( study )     url = method + listserver + path + "update_worklist.php?STU_INSTANCE_UID=" + study     #print url     try:         page = urlopen(url).read()     except IOError:         print "Can't connect to server"         page = "Can't connect to server"     print "response:%s" % ( page )  #Fonction pour downloader une image, verifier les directory etc def download(full,stu,ser,file):     url = fileserver+full     try:         stat(rootdir+stu+"/"+ser)     except OSError:         print "Local directory doesn't exist, creating it (%s)" % (rootdir+stu+"/"+ser)         makedirs(rootdir+stu+"/"+ser)      print "Retrieving object %s" % (file)     fileName= "%s%s/%s/%s" % ( rootdir, stu, ser, file )     try:         urlretrieve(url,fileName);     except IOError:         print "Can't connect to server"             print 'Done'  #Fonction pour executer une liste de travail (downloader les images et updater a chaque etude) def parse(page):     print 'Parsing worklist'     lines = page.split("\n")     for line in lines:         #print line         compo = line.split('/')                 if line[0]=='/':             download(line,compo[3],compo[4],compo[5])         else:             if (line[0:3]=="End"):                 compo = line.split(':  ')                 print line                 updatelist(compo[1])             if (line[0:5]=="Start"):                 print line  #Programme principal makedb() print 'Starting download' #parse(fetchlistweb()) parse(fetchlistdb()) print 'All work done' 


IMAGEM PACS Image retrieve

Vendredi, avril 1st, 2005

/****************************************************************************************    Class: download    Author: Jean-Luc Cyr    Copyrights: IMAGEM medicals systems    Date: 2004-11-24    Description: Connect to imagem pacs database, fetch a study list to download                 fetch anterior list for those studies and images list for study and                 anterior.  After that, connect by ftp to the server and fetch the                 images.                  FTP Connexion was released between each study.                 Database Connecion was persistant. ****************************************************************************************/  //FTP import cz.dhl.io.*; import cz.dhl.ftp.*; //ORACLE import java.sql.*; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.PreparedStatement; import oracle.jdbc.pool.OracleDataSource; //JAVA import java.io.IOException; import java.io.File; import java.util.Vector;  public class download {     //Internal exception     public class downloadException extends Exception     { 	public downloadException(){} 	public downloadException(String s){super(s);}     }      //Global variables     Connection Database;                ///< Database connection     Vector StudyList = new Vector();    ///< Study list to download     Vector AnteriorList = new Vector(); ///< Current processing study anterior list     Vector ImageList = new Vector();    ///< Current study and antorior image list      //Configuration section     String base_path = "c:/imagem/images"; ///< Local base path to store images     //String DB_Name = "jdbc:oracle:thin:@10.16.163.3:1521:orcl"; ///< Database connexion string     String DB_Name = "jdbc:oracle:thin:@192.168.1.6:1521:rpdev";     String DB_User = "ris_pacs"; ///< Database username     String DB_Pass = "password"; ///< Database password     String FTP_Name = "ftp://10.16.163.3"; ///< FTP connexion string     String FTP_User = "jlcyr"; ///< FTP Username     String FTP_Pass = "Limos1"; ///< FTP Password      ////////////////////////////////////////////////////////////////     ///Main program     public static void main( String[] args ) { 	System.out.println("Demarrage du service de transfert"); 	while (true) { 	    download test = new download(); 	    test.fetchImages(); 	}     }      ////////////////////////////////////////////////////////////////     ///Connexion à la base de donnee     public boolean dbConnect(){ 	try{ 	    DriverManager.registerDriver(new oracle.jdbc.OracleDriver()); 	} catch (SQLException ex){ 	    System.out.println("Erreur durant l'initialisation des connections "+'\n'+ex.toString()); 	} 	try{ 	    Database = DriverManager.getConnection(DB_Name,DB_User,DB_Pass); 	    Database.setAutoCommit(false); 	} catch (SQLException ex){ 	    System.out.println("Erreur durant la connection a la db ("+DB_Name+")\n"+ex.toString()); 	    return false; 	} 	return true;     }      ////////////////////////////////////////////////////////////////     ///Deconnexion de la base de donnee     public void dbDisconnect(){ 	try{ 	    Database.close(); 	} catch (Exception ex){ 	    System.out.println("Erreur a la fermeture de la connection a la db"); 	}     }      ///////////////////////////////////////////////////////////////     ///Sortir la liste des etudes a lire     public void dbSelectStudy(){ 	StudyList.clear(); 	try{ 	    ResultSet study; 	    Statement stmt1 = Database.createStatement(); 	    study = stmt1.executeQuery( 	       "SELECT STU_INSTANCE_UID FROM STUDY WHERE "+ 	       "STU_OTHER_NUMBER IN ('8255','8256','8262','8263','8264','8265','8266','8267','8268','8269') AND "+ 	       "STU_STATUS='VERIFIED' AND STU_DATE>'20041101' "+ 	       "ORDER BY STU_DATE ASC"); 	    int count = 1; 	    while (study.next()) { 		String stu = study.getString("STU_INSTANCE_UID"); 		StudyList.add(stu); 		count++; 	    }  	} catch(SQLException ex){ 	    System.out.println("Erreur a la demande de la liste d'etudes: "+ex.toString()); 	}     }      ///////////////////////////////////////////////////////////////     ///Process study list     ///Fetch anterior study     ///Fetch image list for study and anterior     ///Fetch images     public void fetchImages() { 	boolean connected = false; 	System.out.println("Connection au serveur de db"); 	if (dbConnect()) { 	    connected = true; 	    System.out.println("Connection etablie"); 	    System.out.println("Demande de la liste d'etudes"); 	    dbSelectStudy(); 	} else { 	    connected = false; 	    System.out.println("Pas de connection à la base de donnée, on arrête."); 	    return; 	}  	for (int x=0; x<StudyList.size(); x++) { 	    if (!connected) { 		System.out.println("Connection au serveur de db"); 		if (dbConnect()) { 		    connected = true; 		    System.out.println("Connection etablie"); 		} else { 		    connected = false; 		    System.out.println("Pas de connection à la base de donnée, on arrête."); 		    return; 		} 	    } 	    System.out.println("-----------------------------------------"); 	    System.out.println(StudyList.get(x)); 	    //Fetch Anterior Study List 	    System.out.println("Fetching anterior"); 	    dbSelectAnt((String)StudyList.get(x)); 	    //Fetch Image List 	    dbSelectImages((String)StudyList.get(x),false); 	    //Fetch Anterior Image List 	    int count; 	    for (count=0; count<AnteriorList.size(); count++) { 		dbSelectImages((String)AnteriorList.get(count),true); 	    }  	    System.out.println("Traitement de la liste d'etudes"); 	    //Process image list 	    if (ImageList.size()>0) { 		boolean conn = false; 		//Initialise Ftp Connexion but open it only if needed 		FtpConnect ftpc = FtpConnect.newConnect(FTP_Name); 		ftpc.setUserName(FTP_User); 		ftpc.setPassWord(FTP_Pass); 		Ftp ftp = new Ftp(); 		//Retrieve Images (if not present locally) 		File TestFile; 		String[] COI = new String[4]; 		for (count=0; count<ImageList.size(); count++) { 		    COI = ((String[])ImageList.get(count)); 		    //System.out.println(count+" "+COI[3]); 		    //System.out.println("FILE:"+base_path+"/"+COI[1]+"/"+COI[2]+"/"+COI[3]+".dcm"); 		    TestFile = new File(base_path+"/"+COI[1]+"/"+COI[2]+"/"+COI[3]+".dcm"); 		    if (!TestFile.exists()) { 			//Si on a besoin de downloader on se déconnecte de la db 			//pour eviter de faire un timeout du reseau 			if (connected) { 			    System.out.println("Deconnection de la base de donnee"); 			    dbDisconnect(); 			    connected = false; 			    System.out.println("Connection terminee"); 			} 			if (!conn) { 			    try { 				//Open ftp connexion we need it 				ftp.connect(ftpc); 				conn = true; 			    } catch (IOException e) { 				System.out.println(e); 			    } 			} 			if (ftp.isConnected()) { 			    //Retrieve image 			    retrieveImages(((String[])ImageList.get(count)),ftp); 			} 			else { 			    System.out.println("On ne peut pas transferer l'image, on a pas de connexion"); 			    conn = false; 			} 		    } 		    else { 			System.out.println("o "+TestFile.getName()); 		    } 		} 		//Close Ftp Connexion 		ftp.disconnect(); 		conn = false; 	    } 	} 	if (connected) { 	    System.out.println("Deconnection de la base de donnee"); 	    dbDisconnect(); 	    connected = false; 	    System.out.println("Connection terminee"); 	}     }      //////////////////////////////////////////////////////     ///Find anterior studies for a specific study     public void dbSelectAnt(String stu_uid) { 	AnteriorList.clear(); 	try{ 	    ResultSet study; 	    Statement stmt1 = Database.createStatement(); 	    study = stmt1.executeQuery( 				       "SELECT STU_PAT_ID,STU_OTHER_NUMBER,STU_INSTANCE_UID,STU_DATE,STU_TIME FROM STUDY WHERE "+ 				       "STU_INSTANCE_UID = '"+stu_uid+"'"); 	    study.next();  	    String pat_id = study.getString("STU_PAT_ID"); 	    String stu_on = study.getString("STU_OTHER_NUMBER"); 	    String stu_date = study.getString("STU_DATE"); 	    String stu_time = study.getString("STU_TIME");  	    System.out.println("=================="); 	    System.out.println("PATIENT: "+pat_id); 	    System.out.println("=================="); 	    //Demande les anterieurs 	    //Pour le meme patient 	    //Dans la liste de code HISTORICAL_IMAGE 	    //Le premier (plus recent) pour chaque code 	    // 	    study = stmt1.executeQuery( 				       "SELECT STU_INSTANCE_UID,STU_OTHER_NUMBER FROM STUDY WHERE "+ 				       "STU_PAT_ID = '"+pat_id+"' AND "+ 				       "STU_INSTANCE_UID != '"+stu_uid+"' AND "+ 				       "(STU_DATE<'"+stu_date+"' OR (STU_DATE='"+stu_date+"' AND STU_TIME<'"+stu_time+"')) AND "+ 				       "STU_OTHER_NUMBER IN (SELECT HI_EXAMCODE FROM HISTORICAL_IMAGES WHERE HI_REF_EXAMCODE='"+stu_on+"') "+ 				       "ORDER BY STU_OTHER_NUMBER ASC, STU_DATE DESC, STU_TIME DESC");  	    int count = 1; 	    String code = ""; 	    String stu_code = ""; 	    while (study.next()) { 		stu_code = study.getString("STU_OTHER_NUMBER"); 		if (code.compareTo(stu_code)!=0) { 		    String stu = study.getString("STU_INSTANCE_UID"); 		    System.out.println("Trouve "+stu_code+" - "+stu); 		    AnteriorList.add(stu); 		    code = stu_code; 		} 		count++; 	    }  	} catch(SQLException ex){ 	    System.out.println("Erreur a la demande de la liste d'anterieur: "+ex.toString()); 	}     }      ///////////////////////////////////////////////////////     ///Find images for a study and put them in ImageList     ///is keep is true, doesn't clear the list, simply add to it     public void dbSelectImages(String stu_uid, boolean keep) { 	if (!keep) 	    ImageList.clear(); 	try{ 	    ResultSet study; 	    Statement stmt1 = Database.createStatement();     	    study = stmt1.executeQuery( 				       "SELECT * FROM COMPOSITE_OBJECT_INSTANCE,MEDIA_FILE_SET WHERE "+ 				       "COI_STUDY_INSTANCE_UID = '"+stu_uid+"' AND "+ 				       "COI_STO_MEDIA_FSET_UID = MFS_UID");  	    int count = 0; 	    String COI[]; 	    while (study.next()) { 		COI = new String[4]; 		COI[0] = study.getString("MFS_MOUNT_POINT"); 		COI[1] = study.getString("COI_STUDY_INSTANCE_UID"); 		COI[2] = study.getString("COI_SERIES_INSTANCE_UID"); 		COI[3] = study.getString("COI_SOP_INSTANCE_UID"); 		String remote_filename = COI[0]+"/"+COI[1]+"/"+COI[2]+"/"+COI[3]+".dcm"; 		System.out.println("Must retrieve: "+COI[3]); 		ImageList.add(COI); 		count++; 	    } 	    if (count==0) 		System.out.println("Aucune images");  	} catch(SQLException ex){ 	    System.out.println("Erreur a la demande de la liste d'images: "+ex.toString()); 	}     }      ///////////////////////////////////////////////////////     ///Retrieve images     public void retrieveImages(String COI[], Ftp ftplink) { 	// source FtpFile remote file 	String remote_filename = COI[0]+"/"+COI[1]+"/"+COI[2]+"/"+COI[3]+".dcm"; 	CoFile file = new FtpFile(remote_filename,ftplink); 	// Check if local directory exists and create them if needed 	File testDir = new File(base_path+"/"+COI[1]); 	if (!testDir.exists()) 	    testDir.mkdir(); 	testDir = new File(base_path+"/"+COI[1]+"/"+COI[2]); 	if (!testDir.exists()) 	    testDir.mkdir(); 	// destination LocalFile home-dir/Welcome 	CoFile to = new LocalFile(base_path+"/"+COI[1]+"/"+COI[2],COI[3]+".dcm"); 	// download /Welcome file to home-dir/Welcome 	CoLoad.copy(to,file);     } }