@@ -52,36 +52,33 @@ def __init__(self,filename):
5252 self .fi = fileinfo ()
5353 self .fileHandle = open (filename , 'rb' );
5454 self .fileHandle .seek (5 ) # we find the FPS at position 05
55- fFPSByte = self .fileHandle .read (4 )
56- self .fps = struct .unpack ('>f' , fFPSByte )[0 ]
57-
58-
5955 self .fileHandle .seek (10 ) # we find the image size at position 10
6056 fSizeByte = self .fileHandle .read (4 )
6157 self .fi .size = int .from_bytes (fSizeByte , byteorder = 'big' , signed = True )
62- self .fi .nImages = 1000
63-
64- self .fi .width = 576
65- if ((self .fi .size / (2 * self .fi .width ))% 2 != 0 ):
66- self .fi .width = 512
67- self .fi .height = int (self .fi .size / (2 * self .fi .width ))
68- else :
69- self .fi .height = int (self .fi .size / (2 * self .fi .width ))
70-
7158 self .filestats = stat (self .fileName )
59+ self .fi .nImages = 1000
7260 self .fi .nImages = int ((self .filestats .st_size - self .fi .offset ) / (self .fi .size + self .fi .gapBetweenImages ))
73-
7461 self .numberOfFrames = self .fi .nImages
75-
62+
63+ meta = self .getMostRelevantMetaInfo ()
64+ self .fi .width = int (meta .get ('width' , 0 ))
65+ self .fi .height = int (meta .get ('height' , 0 ))
66+ self .fps = float (meta .get ('framerate' , 0 ))
67+
7668 self .geometry_imsize = [self .fi .height , self .fi .width ]
7769 self .imsize = [self .fi .height , self .fi .width ]
7870 self .geometry_tilesize = [(self .fi .height , self .fi .width )]
7971 self .geometry_rows = [1 ]
8072 self .geometry_columns = [1 ]
8173 self .levels = [1 ]
8274 self .channels = 1
83- self .mpp_x = 250 / 576 # approximate number for gastroflex, 250 ym field of view, 576 px
84- self .mpp_y = 250 / 576
75+
76+ self .fovx = float (meta .get ('fovx' , 250 ))
77+ self .fovy = float (meta .get ('fovy' , 250 ))
78+ print (f"fovx: { self .fovx } , fovy: { self .fovy } " )
79+ self .mpp_x = self .fovx / self .fi .width # approximate number for gastroflex, 250 ym field of view, 576 px
80+ self .mpp_y = self .fovy / self .fi .height
81+
8582
8683 # generate circular mask for this file
8784 self .circMask = circularMask (self .fi .width ,self .fi .height , self .fi .width - 2 ).mask
@@ -91,6 +88,52 @@ def __init__(self,filename):
9188 openslide .PROPERTY_NAME_MPP_Y : self .mpp_y ,
9289 openslide .PROPERTY_NAME_OBJECTIVE_POWER :20 ,
9390 openslide .PROPERTY_NAME_VENDOR : 'MKT' }
91+
92+
93+ def getMetaInfo (self ):
94+ # the meta information at the MKT file always starts with "00616C6C 6F776564 5F656761 696E5F65 6F666673 65745F70 61697273 3D" or allowed_egain_eoffset_pairs= in the hex code
95+ # we need to read the whole file to find the meta information
96+ with open (self .fileName , 'rb' ) as f :
97+ fileContent = f .read ()
98+ # find start position with fileContent.find(b'allowed_egain_eoffset_pairs=') that searches for the byte sequence
99+ metaStart = fileContent .rfind (b'allowed_egain_eoffset_pairs=' )
100+ metaEnd = fileContent .find (b'<CEND' , metaStart )
101+ metaInfo = fileContent [metaStart :metaEnd ].decode ('utf-8' )
102+ return metaInfo
103+
104+
105+ def getMostRelevantMetaInfo (self ):
106+ metaInfo = self .getMetaInfo ()
107+ relevantInfo = {}
108+
109+ for line in metaInfo .split ('\n ' ):
110+ if "=" not in line :
111+ continue
112+ key , value = line .split ('=' )
113+ if key == 'framerate' :
114+ value_str = value .strip ()
115+ try :
116+ framerate = float (value_str )
117+ except ValueError :
118+ print (f"Warning: invalid framerate value in metadata: { value_str !r} " )
119+ continue
120+ if framerate <= 0 :
121+ print (f"Warning: non-positive framerate value in metadata: { framerate } " )
122+ continue
123+ relevantInfo ['framerate' ] = value_str
124+ relevantInfo ['duration_seconds' ] = self .fi .nImages / framerate
125+ elif key == 'width' :
126+ relevantInfo ['width' ] = value
127+ elif key == 'height' :
128+ relevantInfo ['height' ] = value
129+ elif key == 'fovx' :
130+ relevantInfo ['fovx' ] = value
131+ elif key == 'fovy' :
132+ relevantInfo ['fovy' ] = value
133+ elif key == 'patient_id' :
134+ relevantInfo ['patient_id' ] = value
135+
136+ return relevantInfo
94137
95138 def _2_init__ (self , filename ):
96139
@@ -137,7 +180,25 @@ def _2_init__(self, filename):
137180
138181 self .circMask = circularMask (self .fi .width ,self .fi .height , self .fi .width - 2 ).mask
139182
183+ @property
184+ def meta_data (self ) -> dict :
185+ # Cache metadata to avoid repeated file I/O and parsing.
186+ if not hasattr (self , "_meta_data_cache" ):
187+ self ._meta_data_cache = self .getMostRelevantMetaInfo ()
188+ return self ._meta_data_cache
140189
190+ @property
191+ def meta_data_dict (self ) -> dict :
192+ meta_data_dict = {
193+ 'width' : 'Image width (pixels)' ,
194+ 'height' : 'Image height (pixels)' ,
195+ 'framerate' : 'Frame rate (fps)' ,
196+ 'duration_seconds' : 'Duration (seconds)' ,
197+ 'patient_id' : 'Patient ID' ,
198+ 'fovx' : 'Field of view x (micrometers)' ,
199+ 'fovy' : 'Field of view y (micrometers)'
200+ }
201+ return meta_data_dict
141202
142203 @property
143204 def seriesInstanceUID (self ) -> str :
0 commit comments