001/** 002 * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/ 003 * 004 * This file is part of Dicoogle/dicoogle. 005 * 006 * Dicoogle/dicoogle is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Dicoogle/dicoogle is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Dicoogle. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package pt.ua.dicoogle.server.queryretrieve; 020 021import java.text.Format; 022import java.text.SimpleDateFormat; 023import java.util.Date; 024import java.util.HashMap; 025 026import pt.ua.dicoogle.core.exceptions.CFindNotSupportedException; 027 028import java.util.Iterator; 029import java.util.Set; 030 031import org.dcm4che2.data.DicomElement; 032import org.dcm4che2.data.DicomObject; 033import org.dcm4che2.data.Tag; 034 035import pt.ua.dicoogle.core.ServerSettings; 036import pt.ua.dicoogle.sdk.utils.TagValue; 037import pt.ua.dicoogle.sdk.utils.TagsStruct; 038 039/** 040 * 041 * [SOP Class name] - [SOP Class UID] 042 * Patient Root Q/R Find - 1.2.840.10008.5.1.4.1.2.1.1 043 * Study Root Q/R Find - 1.2.840.10008.5.1.4.1.2.2.1 044 * NOT SUPPORTED: @depracated 045 * Patient-Study Root Q/R Find (Retired) - 1.2.840.10008.5.1.4.1.2.3.1 046 * 047 * 048 * 049 * @author Luís A. Bastião Silva <bastiao@ua.pt> 050 */ 051public class CFindBuilder 052{ 053 054 private boolean patientRoot = false ; 055 private boolean studyRoot = false ; 056 057 private String query = ""; 058 059 060 public CFindBuilder(DicomObject key, DicomObject rsp) throws CFindNotSupportedException 061 { 062 063 //if (!setRoot(rsp)) 064 // throw new CFindNotSupportedException() ; 065 066 067 /** 068 * Sample output 069 (0008,0005) CS #10 [ISO_IR 100] Specific Character Set 070 (0008,0020) DA #18 [20090531-20090531] Study Date 071 (0008,0030) TM #22 [000000.000-120000.000] Study Time 072 (0008,0050) SH #0 [] Accession Number 073 (0008,0052) CS #6 [STUDY] Query/Retrieve Level 074 (0008,0061) CS #2 [XA] Modalities in Study 075 (0008,1030) LO #0 [] Study Description 076 (0010,0010) PN #0 [] Patient's Name 077 (0010,0020) LO #0 [] Patient ID 078 (0010,0030) DA #0 [] Patient's Birth Date 079 (0020,000D) UI #0 [] Study Instance UID 080 (0020,0010) SH #0 [] Study ID 081 (0020,1208) IS #0 [] Number of Study Related Instances 082 */ 083 084 /** Search by required fields 085 086 * 087 * 088 */ 089 090 // Get Affected SOP Classs UID 091 DicomElement elem = rsp.get(Integer.parseInt("00000002", 16)); 092 String affectedSOP = new String(elem.getBytes()); 093 094 TagsStruct tagstruct = TagsStruct.getInstance(); 095 096 //TagsStruct.getInstance().toStringNew(); 097 boolean all=false ; 098 String append = "" ; 099 query=""; 100 System.out.println(tagstruct.getDIMFields().size()); 101 Iterator<TagValue> it = tagstruct.getDIMFields().iterator(); 102 while(it.hasNext()) 103 { 104 /** Verify if this tags exists 105 */ 106 TagValue tag = it.next(); 107 int k = tag.getTagNumber() ; 108 DicomElement e = key.get(k); 109 //DebugManager.getInstance().debug("get key::"+ k ); 110 if (e!=null) 111 { 112 String value = new String(e.getBytes()); 113 //DebugManager.getInstance().debug("Value getted in CFIND RP:<"+t.get(k).getAlias() + "> "+ value +"."); 114 if (value.equals("")) 115 { 116 continue ; 117 118 } 119 else 120 { 121 value=value.trim(); 122 boolean modified = false ; 123 // TODO :: Study Date need to be rewritted 124 // and others weird tags like // should be mapped to lucene! 125 if (k == Tag.ModalitiesInStudy) 126 { 127 String [] modality = value.split("\\\\"); 128 int i = 0 ; 129 String modalityQuery = ""; 130 for (String mod : modality ) 131 { 132 133 //DebugManager.getInstance().debug(mod); 134 135 if (modified) 136 { 137 // There is already exist a modality 138 modalityQuery += " OR "; 139 } 140 141 i++ ; 142 modified = true ; 143 modalityQuery += "Modality" + ":" + mod; 144 } 145 if (!modalityQuery.equals("")) 146 { 147 System.err.println(modalityQuery); 148 query = query + append + " (" + modalityQuery + ")" ; 149 } 150 151 } 152 153 else if(k == Tag.StudyDate) 154 { 155 System.out.println("Value :@" +value+"."); 156 157 String [] date = value.split("-"); 158 int i = 0 ; 159 if (date.length==1) 160 { 161 162 if (!value.contains("-")) 163 { 164 query = query + append +tag.getAlias() + ":[" + date[0] + " TO " + 165 date[0] + "]" ; 166 } 167 else 168 { 169 170 String s; 171 Format formatter; 172 Date date2 = new Date(); 173 174 // 01/09/02 175 formatter = new SimpleDateFormat("YYYYMMdd"); 176 s = formatter.format(date2); 177 178 query = query + append +tag.getAlias() + ":[" + date[0] + " TO " + 179 s + "]" ; 180 } 181 182 183 //query = query +append + t.get(k).getAlias() + ":[" + date[0] + " TO " + 184 // date[0] + "]" ; 185 } 186 else if(date.length==2) 187 { 188 query = query + append + tag.getAlias() + ":[" + date[0] + " TO " + 189 date[1] + "]" ; 190 } 191 modified = true ; 192 } 193 194 195 else if(k == Tag.StudyTime) 196 { 197 String [] date = value.split("-"); 198 int i = 0 ; 199 if (date.length==1) 200 { 201 query = query + append +tag.getAlias() + ":[" + date[0] + " TO " + 202 date[0] + "]" ; 203 /*if (!value.contains("-")) 204 { 205 query = query + append +t.get(k).getAlias() + ":[" + date[0] + " TO " + 206 date[0] + "]" ; 207 } 208 else 209 { 210 211 String s; 212 Format formatter; 213 Date date2 = new Date(); 214 215 // 01/09/02 216 formatter = new SimpleDateFormat("YYYYMMdd"); 217 s = formatter.format(date2); 218 219 query = query + append +t.get(k).getAlias() + ":[" + date[0] + " TO " + 220 s + "]" ; 221 }*/ 222 } 223 else if(date.length==2) 224 { 225 query = query + append + tag.getAlias() + ":[" + date[0] + " TO " + 226 date[1] + "]" ; 227 } 228 modified = true ; 229 } 230 231 232 233 else 234 { 235 modified = true ; 236 query += append + tag.getAlias() + ":" + value; 237 } 238 239 if (modified && it.hasNext()) 240 { 241 append = " AND "; 242 } 243 244 } 245 246 } 247 } 248 249 if (query.equals("")) 250 query="*:*"; 251 //DebugManager.getInstance().debug(">> Query String DICOM: "+ query); 252 253 254 } 255 256 public String getQueryString() 257 { 258 return this.query; 259 } 260 261 private synchronized boolean setRoot(DicomObject rsp) 262 { 263 /** 264 * Verify if it is inside of: 265 * Affected SOP Class UID (0000,0002) 266 * Checked in C-FIND RQ in DICOM 267 * It is one of three ([P|S|PS] Root ) 268 */ 269 270 DicomElement elem = rsp.get(Integer.parseInt("00000002", 16)); 271 String affectedSOP = new String(elem.getBytes()); 272 273 274 275 //DebugManager.getInstance().debug(">" + affectedSOP); 276 //DebugManager.getInstance().debug(">> "+ServerSettings.getInstance().getSOPClass()); 277 278 279 280 boolean found = false; 281 282 for (String i : ServerSettings.getInstance().getSOPClass().split("\\|")) 283 { 284 //DebugManager.getInstance().debug("It have in settings:>: " + i); 285 286 if (affectedSOP.equals(i)) 287 { 288 /** 289 1.2.840.10008.5.1.4.1.2.1.1 (Patient) 290 1.2.840.10008.5.1.4.1.2.2.1 (Study) 291 */ 292 //DebugManager.getInstance().debug(">>> Affected SOPs in "); 293 if (affectedSOP.equals("1.2.840.10008.5.1.4.1.2.1.1")) 294 { 295 this.patientRoot = true ; 296 found = true ; 297 } 298 else if (affectedSOP.equals("1.2.840.10008.5.1.4.1.2.2.1")) 299 { 300 this.studyRoot = true ; 301 found = true ; 302 } 303 break ; 304 } 305 } 306 307 return found ; 308 309 } 310 311 312 313 /** 314 * @return the patientRoot 315 */ 316 public boolean isPatientRoot() 317 { 318 return patientRoot; 319 } 320 321 /** 322 * @param patientRoot the patientRoot to set 323 */ 324 public void setPatientRoot(boolean patientRoot) 325 { 326 this.patientRoot = patientRoot; 327 } 328 329 /** 330 * @return the studyRoot 331 */ 332 public boolean isStudyRoot() 333 { 334 return studyRoot; 335 } 336 337 /** 338 * @param studyRoot the studyRoot to set 339 */ 340 public void setStudyRoot(boolean studyRoot) 341 { 342 this.studyRoot = studyRoot; 343 } 344 345 /** 346 * @return the query 347 */ 348 public String getQuery() 349 { 350 return query; 351 } 352 353 /** 354 * @param query the query to set 355 */ 356 public void setQuery(String query) 357 { 358 this.query = query; 359 } 360 361 362 public static boolean isPatientRoot(DicomObject rsp) 363 { 364 DicomElement elem = rsp.get(Integer.parseInt("00000002", 16)); 365 String affectedSOP = new String(elem.getBytes()); 366 367 if (affectedSOP.equals("1.2.840.10008.5.1.4.1.2.2.1")) 368 { 369 return true; 370 } 371 return false; 372 } 373 374 public static boolean isStudyRoot(DicomObject rsp) 375 { 376 DicomElement elem = rsp.get(Integer.parseInt("00000002", 16)); 377 String affectedSOP = new String(elem.getBytes()); 378 if (affectedSOP.equals("1.2.840.10008.5.1.4.1.2.1.1")) 379 { 380 return true; 381 } 382 return false; 383 } 384 385 386}