3 Let's write our own python parser to clean up the pdf (after
5 Instructions: run pdftotext like this:
7 $ pdftotext -f 9 -l 81 -raw -nopgbrk 04_06PU.PDF 04_06PU-3.txt
9 then run the python parser like this:
11 $ python ParseDict.py 04_06PU.txt dicomV3.dic
16 PdfTextParser takes as input a text file (produced by pdftotext)
17 and create as output a clean file (ready to be processed) by
19 Warning: PdfTextParser does not expand:
20 - (xxxx,xxxx to xxxx) xxxxxxxxxxxx
22 - (12xx, 3456) comment...
28 self._InputFilename = ''
29 self._OutputFilename = ''
32 self._PreviousBuffers = []
34 def SetInputFileName(self,s):
35 self._InputFilename = s
37 def SetOutputFileName(self,s):
38 self._OutputFilename = s
40 # Function returning if s is a comment for sure
41 def IsAComment(self,s):
43 if s == "Tag Name VR VM":
45 elif s == "PS 3.6-2003":
47 elif s == "PS 3.6-2004":
49 patt = re.compile('^Page [0-9]+$')
54 def IsAStartingLine(self,s):
55 patt = re.compile('^\\([0-9a-fA-Fx]+,[0-9a-fA-F]+\\) (.*)$')
60 def IsAFullLine(self,s):
61 patt = re.compile('^\\([0-9a-fA-Fx]+,[0-9a-fA-F]+\\) (.*) [A-Z][A-Z] [0-9]$')
66 # FIXME this function could we avoided...
67 def IsSuspicious(self,s):
73 def AddOutputLine(self,s):
74 assert not self.IsAComment(s)
75 self._OutLines.append(s + '\n')
78 self._Infile = file(self._InputFilename, 'r')
79 for line in self._Infile.readlines():
80 line = line[:-1] # remove '\n'
81 if not self.IsAComment( line ):
82 if self.IsAStartingLine(line):
83 #print "Previous buffer:",self._PreviousBuffers
84 previousbuffer = ' '.join(self._PreviousBuffers)
85 if self.IsAStartingLine(previousbuffer):
86 if not self.IsSuspicious(previousbuffer):
87 self.AddOutputLine(previousbuffer)
89 # this case should not happen if I were to rewrite the
90 # thing I should be able to clean that
91 #print "Suspicious:", previousbuffer
92 #print "List is:", self._PreviousBuffers
93 s = self._PreviousBuffers[0]
94 if self.IsAFullLine(s):
95 # That means we have a weird line that does not start
96 # as usual (xxxx,xxxx) therefore we tried constructing
97 # a buffer using a the complete previous line...
98 #print "Full line:", s
100 s2 = ' '.join(self._PreviousBuffers[1:])
101 #print "Other Full line:", s2
102 self.AddOutputLine(s2)
104 # we have a suspicioulsy long line, so what that could
105 # happen, let's check:
106 if self.IsAFullLine(previousbuffer):
107 self.AddOutputLine(previousbuffer)
109 # This is the only case where we do not add
110 # previousbuffer to the _OutLines
111 print "Suspicious and Not a full line:", s
114 print "Not a buffer:", previousbuffer
115 # We can clean buffer, since only the case 'suspicious' +
116 # 'Not a full line' has not added buffer to the list
117 self._PreviousBuffers = []
118 # In all cases save the line for potentially growing this line
119 assert not self.IsAComment(line)
120 self._PreviousBuffers.append(line)
122 #print "Not a line",line
123 assert not self.IsAComment(line)
124 self._PreviousBuffers.append(line)
126 #print "Comment:",line
127 previousbuffer = ' '.join(self._PreviousBuffers)
128 if previousbuffer and self.IsAStartingLine(previousbuffer):
129 #print "This line is added:", previousbuffer
130 self.AddOutputLine( previousbuffer )
132 #print "Line is comment:", line
133 print "Buffer is:", previousbuffer
134 # Ok this is a comment we can safely clean the buffer:
135 self._PreviousBuffers = []
139 outfile = file(self._OutputFilename, 'w')
140 outfile.writelines( self._OutLines )
144 # Main function to call for parsing
149 This class is meant to expand line like:
150 - (xxxx,xxxx to xxxx) xxxxxxxxxxxx
152 - (12xx, 3456) comment...
155 class DicomV3Expander:
157 self._InputFilename = ''
158 self._OutputFilename = ''
161 def SetInputFileName(self,s):
162 self._InputFilename = s
164 def SetOutputFileName(self,s):
165 self._OutputFilename = s
167 # Function to turn into lower case a tag:
168 # ex: (ABCD, EF01) -> (abcd, ef01)
169 def LowerCaseTag(self,s):
170 #print "Before:", s[:-1]
171 patt = re.compile('^(\\([0-9a-fA-F]+,[0-9a-fA-F]+\\))(.*)$')
176 return s1.lower() + s2
178 print "Impossible case:", s
181 def AddOutputLine(self,s):
182 if s.__class__ == list:
184 self._OutLines.append(i + '\n')
186 self._OutLines.append(s + '\n')
188 # Expand the line approriaetkly and also add it to the
190 def ExpandLine(self, s):
192 s = s[:-1] # remove \n
194 if self.NeedToExpansion(s, list):
195 self.AddOutputLine(list) # list != []
196 elif self.NeedXXExpansion(s, list):
197 self.AddOutputLine(list) # list != []
199 self.AddOutputLine(self.LowerCaseTag(s))
202 # (0020,3100 to 31FF) Source Image Ids RET
203 def NeedToExpansion(self,s, list):
204 patt = re.compile('^\\(([0-9a-fA-F]+),([0-9a-fA-F]+) to ([0-9a-fA-F]+)\\)(.*)$')
209 el_start = '0x'+m.group(2)
210 el_end = '0x'+m.group(3)
211 for i in range(eval(el_start), eval(el_end)):
213 l = '('+gr+','+el+')'+m.group(4)
219 # (50xx,1200) Number of Patient Related Studies IS 1
220 def NeedXXExpansion(self,s,list):
221 patt = re.compile('^\\(([0-9a-fA-F]+)xx,([0-9a-fA-F]+)\\)(.*)$')
225 gr_start = m.group(1)
227 #el_start = '0x'+m.group(2)
228 #el_end = '0x'+m.group(3)
229 start = '0x'+gr_start+'00'
230 end = '0x'+gr_start+'FF'
231 for i in range(eval(start), eval(end)):
233 l = '('+gr+','+el+')'+m.group(3)
240 outfile = file(self._OutputFilename, 'w')
241 outfile.writelines( self._OutLines )
245 infile = file(self._InputFilename,'r')
246 for line in infile.readlines():
247 # ExpandLine also LowerCase the line
248 self.ExpandLine(line) # l is [1,n] lines
252 if __name__ == "__main__":
253 argc = len(os.sys.argv )
255 print "Sorry, wrong list of args"
256 os.sys.exit(1) #error
258 inputfilename = os.sys.argv[1]
259 outputfilename = os.sys.argv[2]
260 tempfile = "/tmp/mytemp"
262 dp.SetInputFileName( inputfilename )
263 #dp.SetOutputFileName( outputfilename )
264 dp.SetOutputFileName( tempfile )
267 exp = DicomV3Expander()
268 exp.SetInputFileName( tempfile )
269 exp.SetOutputFileName( outputfilename )
273 #print dp.IsAStartingLine( "(0004,1212) File-set Consistency Flag US 1\n" )