mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Adding some samples to verify new heuristics
This commit is contained in:
		
							
								
								
									
										344
									
								
								samples/Mathematica/HeyexImport.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										344
									
								
								samples/Mathematica/HeyexImport.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,344 @@ | |||||||
|  | (* Mathematica Package *) | ||||||
|  | (* Created with IntelliJ IDEA and the Mathematica Language plugin *) | ||||||
|  |  | ||||||
|  | (* :Title: Importer for the RAW data-format of the Heidelberg Eye Explorer (known as HEYEX) *) | ||||||
|  |  | ||||||
|  | (* :Context: HeyexImport` *) | ||||||
|  |  | ||||||
|  | (* :Author: Patrick Scheibe pscheibe@trm.uni-leipzig.de *) | ||||||
|  |  | ||||||
|  | (* :Package Version: 1.0 *) | ||||||
|  |  | ||||||
|  | (* :Mathematica Version: 8.0 *) | ||||||
|  |  | ||||||
|  | (* :Copyright: Patrick Scheibe, 2013-2015 *) | ||||||
|  |  | ||||||
|  | (* :Discussion: This package registers a new importer which can load the RAW data-format exported by a | ||||||
|  |                 Heidelberg Spectralis OCT. The import-functionality can access different information contained | ||||||
|  |                 in a file: | ||||||
|  |                 1. The file header which contains meta data like when the patient was scanned etc | ||||||
|  |                 2. The scanned volume data | ||||||
|  |                 3. Images which represent slices of the scanned volume | ||||||
|  |                 4. The Scanning laser ophthalmoscopy (SLO) image which is taken with every scanned patient | ||||||
|  |                 5. The segmentation data for different retina layers provided by the software | ||||||
|  |  | ||||||
|  | *) | ||||||
|  |  | ||||||
|  | (* :Keywords: Import, Heyex, OCT, Spectralis, Heidelberg Engineering *) | ||||||
|  |  | ||||||
|  | BeginPackage[ "HeyexImport`" ] | ||||||
|  |  | ||||||
|  | HeyexEyePosition::usage = "HeyexEyePosition[file] tries to extract which eye was scanned, left or right."; | ||||||
|  |  | ||||||
|  | HeyexImport::wrongHdr = "Error importing OCT data. Broken/Wrong file?"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Begin[ "`Private`" ]; | ||||||
|  |  | ||||||
|  | (* | ||||||
|  |     Registration of all import possibilities for the Heidelberg OCT. | ||||||
|  | *) | ||||||
|  |  | ||||||
|  | ImportExport`RegisterImport[ | ||||||
|  |   "Heyex" , | ||||||
|  |   { | ||||||
|  |     "FileHeader" :> importHeader, | ||||||
|  |     { "Data" , n_Integer} :> (importData[n][##]&), | ||||||
|  |     "Data" :> importData, | ||||||
|  |     { "Images" , n_Integer} :> (importImages[n][##]&), | ||||||
|  |     "Images" :> importImages, | ||||||
|  |     "SLOImage" :> importSLOImage, | ||||||
|  |     "SegmentationData" :> importSegmentation, | ||||||
|  |     { "SegmentationData" , n_Integer} :> (importSegmentation[n][##]&), | ||||||
|  |     "DataSize" :> importDataSize, | ||||||
|  |     importData | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   { | ||||||
|  |     "Image3D" :> (Image3D["Data" /. #1]&) | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   "AvailableElements" -> {"FileHeader", "Data", "DataSize", "Images", "SLOImage", "SegmentationData", "Image3D"} | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | If[Quiet[Check[TrueQ[Compile[{}, 0, CompilationTarget -> "C"][] == 0], False]], | ||||||
|  |   $compileTarget = CompilationTarget -> "C", | ||||||
|  |   $compileTarget = CompilationTarget -> "MVM" | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | (* | ||||||
|  |     Helper function which reads data from a stream. This is | ||||||
|  |     only a unification so I can map the read function over a | ||||||
|  |     list. | ||||||
|  | *) | ||||||
|  | read[{id_String, type_String}, str_] := | ||||||
|  | id -> BinaryRead[str, type]; | ||||||
|  | read[{type_String, n_Integer}, str_] := BinaryReadList[str, type, n]; | ||||||
|  | read[{id_String, {type_String, n_Integer}}, str_] := id -> BinaryReadList[str, type, n]; | ||||||
|  | (* | ||||||
|  |     Note that when reading bytes explicitly I convert them to | ||||||
|  |     a string and remove any zeroes at the end. | ||||||
|  | *) | ||||||
|  | read[{id_String, { "Byte" , n_Integer}}, str_] := | ||||||
|  | id -> StringJoin[ | ||||||
|  |     FromCharacterCode /@ (Rest[ | ||||||
|  |       NestList[BinaryRead[str, "Byte" ] &, Null, | ||||||
|  |         n]] /. {chars___Integer, Longest[0 ...]} :> {chars})]; | ||||||
|  |  | ||||||
|  | (* | ||||||
|  |     The layout of a file exported with "Raw Export" | ||||||
|  |  | ||||||
|  |     ***************** | ||||||
|  |     *   File Header * | ||||||
|  |     ***************** | ||||||
|  |     *   SLO Image   * | ||||||
|  |     ***************** | ||||||
|  |     *   B-Scan #0   * | ||||||
|  |     ***************** | ||||||
|  |     *   .....       * | ||||||
|  |     ***************** | ||||||
|  |     *   B-Scan #n-1 * | ||||||
|  |     ***************** | ||||||
|  | *) | ||||||
|  |  | ||||||
|  | With[{i = "Integer32", f = "Real32", d = "Real64", b = "Byte"}, | ||||||
|  |  | ||||||
|  |   $fileHeaderInfo = Transpose[{ | ||||||
|  |     { | ||||||
|  |       "Version" , "SizeX" , "NumBScans" , "SizeZ" , "ScaleX" , "Distance" , | ||||||
|  |       "ScaleZ" , "SizeXSlo" , "SizeYSlo" , "ScaleXSlo" , "ScaleYSlo" , | ||||||
|  |       "FieldSizeSlo" , "ScanFocus" , "ScanPosition" , "ExamTime" , | ||||||
|  |       "ScanPattern" , "BScanHdrSize" , "ID" , "ReferenceID" , "PID" , | ||||||
|  |       "PatientID" , "Padding" , "DOB" , "VID" , "VisitID" , "VisitDate" , | ||||||
|  |       "Spare" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       {b, 12}, i, i, i, d, d, d, i, i, d, d, i, d, {b, 4}, {i, 2}, i, i, | ||||||
|  |       {b, 16}, {b, 16}, i, {b, 21}, {b, 3}, d, i, {b, 24}, d, {b, 1840} | ||||||
|  |     } | ||||||
|  |   }]; | ||||||
|  |  | ||||||
|  |   $bScanHeaderInfo = Transpose[{ | ||||||
|  |     { | ||||||
|  |       "Version" , "BScanHdrSize" , "StartX" , "StartY" , "EndX" , "EndY" , | ||||||
|  |       "NumSeg" , "OffSeg" , "Quality" , "Spare" | ||||||
|  |     }, | ||||||
|  |     {{b, 12}, i, d, d, d, d, i, i, f, {b, 196}} | ||||||
|  |   }]; | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | isHeyexRawFormat[{"Version" -> version_String, "SizeX" -> _Integer, "NumBScans" -> _Integer, _Rule..}] /; StringMatchQ[version, "HSF-OCT" ~~__] := True ; | ||||||
|  | isHeyexRawFormat[___] := False; | ||||||
|  |  | ||||||
|  | readFileHeader[str_InputStream] := With[{hdr = Quiet[read[#, str]] & /@ $fileHeaderInfo}, | ||||||
|  |   hdr /; TrueQ[isHeyexRawFormat[hdr]] | ||||||
|  | ]; | ||||||
|  | readFileHeader[___] := (Message[HeyexImport::wrongHdr]; Throw[$Failed]); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | (*  Reads the camera image of the retina. Note that you must have the | ||||||
|  |     information from the fileheader and you must be at the right position | ||||||
|  |     of the file stream for this.*) | ||||||
|  | readSLOImage[str_InputStream, fileHdr : {(_String -> _) ..}] := | ||||||
|  |   Image[Partition[ | ||||||
|  |     BinaryReadList[str, "Byte" , "SizeXSlo" * "SizeYSlo" /. fileHdr], | ||||||
|  |     "SizeXSlo" /. fileHdr], "Byte" ]; | ||||||
|  |  | ||||||
|  | skipSLOImage[str_InputStream, fileHdr : {(_String -> _) ..}] := | ||||||
|  |   Skip[str, "Byte" , "SizeXSlo" * "SizeYSlo" /. fileHdr]; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | (*  One single BScan consists itself again of a header and a data part *) | ||||||
|  | readBScanHeader[str_InputStream, fileHdr : {(_String -> _) ..}] := | ||||||
|  |   Module[{i = "Integer32", f = "Real32", d = "Real64", b = "Byte", | ||||||
|  |     bScanHdr}, | ||||||
|  |     bScanHdr = read[#, str] & /@ Transpose[{ | ||||||
|  |       { "Version" , "BScanHdrSize" , "StartX" , "StartY" , "EndX" , "EndY" , | ||||||
|  |         "NumSeg" , "OffSeg" , "Quality" , "Spare" }, | ||||||
|  |       {{b, 12}, i, d, d, d, d, i, i, f, {b, 196}}} | ||||||
|  |     ]; | ||||||
|  |     AppendTo[bScanHdr, | ||||||
|  |       read[{ "SegArray" , { "Real32" , | ||||||
|  |         "NumSeg" * "SizeX" /. bScanHdr /. fileHdr}}, str] | ||||||
|  |     ]; | ||||||
|  |     (* | ||||||
|  |       This is horrible slow, therefore I just skip the fillbytes | ||||||
|  |     | ||||||
|  |       AppendTo[bScanHdr, | ||||||
|  |        read[{"Fillbytes", {"Byte", | ||||||
|  |           "BScanHdrSize" - 256 - "NumSeg"*"SizeX"*4 /. bScanHdr /. | ||||||
|  |            fileHdr}}, str] | ||||||
|  |        ] | ||||||
|  |    *) | ||||||
|  |     Skip[str, "Byte" , "BScanHdrSize" - 256 - "NumSeg" * "SizeX" * 4 /. bScanHdr /. fileHdr]; | ||||||
|  |     AppendTo[bScanHdr, "FillBytes" -> None] | ||||||
|  |   ] | ||||||
|  |  | ||||||
|  | skipBScanHeader[str_InputStream, fileHdr : {(_String -> _) ..}] := | ||||||
|  |   Skip[str, "Byte" , "BScanHdrSize" /. fileHdr]; | ||||||
|  |  | ||||||
|  | readBScanData[str_InputStream, fileHdr : {(_String -> _) ..}] := | ||||||
|  |   Module[{}, | ||||||
|  |     Developer`ToPackedArray[ | ||||||
|  |       Partition[read[{ "Real32" , "SizeX" * "SizeZ" /. fileHdr}, str], | ||||||
|  |         "SizeX" /. fileHdr]] | ||||||
|  |   ]; | ||||||
|  |  | ||||||
|  | skipBScanData[str_InputStream, fileHdr : {(_String -> _) ..}] := | ||||||
|  |   Skip[str, "Byte" , "SizeX" * "SizeZ" * 4 /. fileHdr]; | ||||||
|  |  | ||||||
|  | skipBScanBlocks[str_InputStream, fileHdr : {(_String -> _) ..}, n_Integer] := | ||||||
|  |   Skip[str, "Byte" , n * ("BScanHdrSize" + "SizeX" * "SizeZ" * 4) /. fileHdr]; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | importHeader[filename_String, ___] := Module[ | ||||||
|  |   {str, header}, | ||||||
|  |   str = OpenRead[filename, BinaryFormat -> True]; | ||||||
|  |   header = readFileHeader[str]; | ||||||
|  |   Close[str]; | ||||||
|  |   "FileHeader" -> header | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | (* Imports the dimension of the scanned volume. *) | ||||||
|  | importDataSize[filename_String, r___] := Module[{header = importHeader[filename]}, | ||||||
|  |   "DataSize" -> ({"NumBScans", "SizeZ", "SizeXSlo"} /. ("FileHeader" /. header)) | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | importSLOImage[filename_String, ___] := Module[ | ||||||
|  |   {str, header, slo}, | ||||||
|  |   str = OpenRead[filename, BinaryFormat -> True]; | ||||||
|  |   header = readFileHeader[str]; | ||||||
|  |   slo = readSLOImage[str, header]; | ||||||
|  |   Close[str]; | ||||||
|  |   "SLOImage" -> slo | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | importData[filename_String, ___] := Module[ | ||||||
|  |   {str, header, nx, n, data}, | ||||||
|  |   str = OpenRead[filename, BinaryFormat -> True]; | ||||||
|  |   header = readFileHeader[str]; | ||||||
|  |   {nx, n} = { "SizeX" , "SizeX" * "SizeZ"} /. header; | ||||||
|  |   skipSLOImage[str, header]; | ||||||
|  |   data = Table[ | ||||||
|  |     skipBScanHeader[str, header]; | ||||||
|  |     Partition[read[{ "Real32" , n}, str], nx], | ||||||
|  |     {"NumBScans" /. header} | ||||||
|  |   ]; | ||||||
|  |   Close[str]; | ||||||
|  |   "Data" -> Developer`ToPackedArray[data] | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | importData[num_Integer][filename_String, ___] := Module[ | ||||||
|  |   {str, header, nx, n, data}, | ||||||
|  |   str = OpenRead[filename, BinaryFormat -> True]; | ||||||
|  |   header = readFileHeader[str]; | ||||||
|  |   {nx, n} = { "SizeX" , "SizeX" * "SizeZ"} /. header; | ||||||
|  |   skipSLOImage[str, header]; | ||||||
|  |   skipBScanBlocks[str, header, Max[Min["NumBScans" /. header, num - 1], 0] ]; | ||||||
|  |   skipBScanHeader[str, header]; | ||||||
|  |   data = Partition[read[{ "Real32" , n}, str], nx]; | ||||||
|  |   Close[str]; | ||||||
|  |   {"Data" -> {num -> Developer`ToPackedArray[data]}} | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | (* | ||||||
|  |     As suggested in the Heidelberg OCT Manual the importer will adjust | ||||||
|  |     the graylevels when importing images. Since this is very time-consuming | ||||||
|  |     for the whole scanned volume, I use an optimized version of this function. | ||||||
|  | *) | ||||||
|  | With[{$compileTarget = $compileTarget}, $adjustGraylevelFunc := ($adjustGraylevelFunc = Compile[{{values, _Real, 2}}, | ||||||
|  |   Map[Floor[255.0 * Min[Max[0.0, #], 1.0]^(0.25) + 0.5] &, values, {2}], | ||||||
|  |   RuntimeAttributes -> {Listable}, | ||||||
|  |   Parallelization -> True, | ||||||
|  |   RuntimeOptions -> "Speed", | ||||||
|  |   $compileTarget | ||||||
|  | ])]; | ||||||
|  |  | ||||||
|  | importImages[filename_String, ___] := Module[ | ||||||
|  |   {data}, | ||||||
|  |   data = "Data" /. importData[filename]; | ||||||
|  |   "Images" -> (Image[#, "Byte" ]& /@ $adjustGraylevelFunc[data]) | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | importImages[imageNumber_Integer][filename_String, ___] := Module[ | ||||||
|  |   {data}, | ||||||
|  |   data = {imageNumber /. ("Data" /. importData[imageNumber][filename])}; | ||||||
|  |   {"Images" -> {imageNumber -> (Image[#, "Byte" ]& @@ $adjustGraylevelFunc[data])}} | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | importSegmentation[filename_String, ___] := Module[ | ||||||
|  |   {str, header, data}, | ||||||
|  |   str = OpenRead[filename, BinaryFormat -> True]; | ||||||
|  |   header = readFileHeader[str]; | ||||||
|  |   skipSLOImage[str, header]; | ||||||
|  |   data = Table[ | ||||||
|  |     Module[{bScanHeader, t}, | ||||||
|  |       {t, bScanHeader} = Timing@readBScanHeader[str, header]; | ||||||
|  |       skipBScanData[str, header]; | ||||||
|  |       bScanHeader | ||||||
|  |     ], {"NumBScans" /. header} | ||||||
|  |   ]; | ||||||
|  |   Close[str]; | ||||||
|  |   (* | ||||||
|  |       The BScanHeaderData contain the segmentation vectors as a single list | ||||||
|  |       of numbers. Before returning the result, I check how many segmentations | ||||||
|  |       there are inside the BScan an I transform the segmentation value list | ||||||
|  |       into separate vectors and call them "ILM", "RPE" and "NFL" like described | ||||||
|  |       in the manual | ||||||
|  |       *) | ||||||
|  |   "SegmentationData" -> Function[{bhdr}, | ||||||
|  |     Block[{numVecs = "NumSeg" /. bhdr, vecNames, nx = "SizeX" /. header}, | ||||||
|  |       If[numVecs > 0, | ||||||
|  |         vecNames = Take[{ "ILM" , "RPE" , "NFL" }, numVecs]; | ||||||
|  |         bhdr /. ("SegArray" -> vec_) :> Sequence @@ (Rule @@@ Transpose[{vecNames, Partition[vec, nx]} ]), | ||||||
|  |         bhdr | ||||||
|  |       ] | ||||||
|  |     ]] /@ data | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | importSegmentation[num_Integer][filename_String, ___] := Module[ | ||||||
|  |   {str, header, bhdr}, | ||||||
|  |   str = OpenRead[filename, BinaryFormat -> True]; | ||||||
|  |   header = readFileHeader[str]; | ||||||
|  |   skipSLOImage[str, header]; | ||||||
|  |   skipBScanBlocks[str, header, Max[Min["NumBScans" /. header, num - 1], 0] ]; | ||||||
|  |   bhdr = readBScanHeader[str, header]; | ||||||
|  |   Close[str]; | ||||||
|  |   (* See doc above *) | ||||||
|  |   {"SegmentationData" -> {num -> Block[ | ||||||
|  |     {numVecs = "NumSeg" /. bhdr, vecNames, nx = "SizeX" /. header}, | ||||||
|  |     If[ numVecs > 0, | ||||||
|  |       vecNames = Take[{ "ILM" , "RPE" , "NFL" }, numVecs]; | ||||||
|  |       bhdr /. ("SegArray" -> vec_) :> Sequence @@ (Rule @@@ Transpose[{vecNames, Partition[vec, nx]} ]), | ||||||
|  |       bhdr | ||||||
|  |     ] | ||||||
|  |   ] | ||||||
|  |   }} | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | (* Extracts which eye was scanned. This is stored in the header of the file *) | ||||||
|  | (* OD stands for oculus dexter which is latin for "right eye" and OS stands | ||||||
|  |    for oculus sinister which is latin for "left eye" *) | ||||||
|  | HeyexEyePosition[file_String /; FileExistsQ[file]] := Module[{position}, | ||||||
|  |   Check[ | ||||||
|  |     position = "ScanPosition" /. Import[file, { "Heyex" , "FileHeader" }]; | ||||||
|  |     Switch[ | ||||||
|  |       position, | ||||||
|  |       "OD" , | ||||||
|  |       Right, | ||||||
|  |       "OS" , | ||||||
|  |       Left, | ||||||
|  |       _, | ||||||
|  |       $Failed | ||||||
|  |     ], | ||||||
|  |     $Failed | ||||||
|  |   ] | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | End[] | ||||||
|  |  | ||||||
|  | EndPackage[] | ||||||
							
								
								
									
										46
									
								
								samples/Mercury/switch_detection_bug.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								samples/Mercury/switch_detection_bug.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | % This is a regression test for a bug in switch detection | ||||||
|  | % where it was preferring incomplete switches to complete | ||||||
|  | % one-case switches, and hence inferring the wrong determinism. | ||||||
|  |  | ||||||
|  | %------------------------------------------------------------------------------% | ||||||
|  |  | ||||||
|  | :- module switch_detection_bug. | ||||||
|  |  | ||||||
|  | :- interface. | ||||||
|  |  | ||||||
|  | :- type note ---> note(rank, modifier, octave). | ||||||
|  |  | ||||||
|  | :- type rank ---> c ; d ; e ; f ; g ; a ; b . | ||||||
|  |  | ||||||
|  | :- type modifier ---> natural ; sharp ; flat . | ||||||
|  |  | ||||||
|  | :- type octave == int. | ||||||
|  |  | ||||||
|  | :- type qualifier ---> maj ; min . | ||||||
|  |  | ||||||
|  | :- pred next_topnote(note, qualifier, note). | ||||||
|  | :- mode next_topnote(in, in, out) is multi. | ||||||
|  |  | ||||||
|  | %------------------------------------------------------------------------------% | ||||||
|  |  | ||||||
|  | :- implementation. | ||||||
|  |  | ||||||
|  | next_topnote(note(c, _, Oct), _, note(d, natural, Oct)). | ||||||
|  | next_topnote(note(d, _, Oct), _, note(c, natural, Oct)). | ||||||
|  | next_topnote(note(d, _, Oct), maj, note(e, natural, Oct)). | ||||||
|  | next_topnote(note(d, _, Oct), min, note(e, flat, Oct)). | ||||||
|  | next_topnote(note(e, _, Oct), _, note(d, natural, Oct)). | ||||||
|  | next_topnote(note(e, _, Oct), _, note(f, natural, Oct)). | ||||||
|  | next_topnote(note(f, _, Oct), maj, note(e, natural, Oct)). | ||||||
|  | next_topnote(note(f, _, Oct), min, note(e, flat, Oct)). | ||||||
|  | next_topnote(note(g, _, Oct), _, note(f, natural, Oct)). | ||||||
|  | next_topnote(note(g, _, Oct), min, note(a, flat, Oct)). | ||||||
|  | next_topnote(note(g, _, Oct), maj, note(a, natural, Oct)). | ||||||
|  | next_topnote(note(a, _, Oct), _, note(g, natural, Oct)). | ||||||
|  | next_topnote(note(a, _, Oct), min, note(b, flat, Oct)). | ||||||
|  | next_topnote(note(a, _, Oct), maj, note(b, natural, Oct)). | ||||||
|  | next_topnote(note(b, _, Oct), maj, note(a, natural, Oct)). | ||||||
|  | next_topnote(note(b, _, Oct), min, note(a, flat, Oct)). | ||||||
|  |  | ||||||
|  | %------------------------------------------------------------------------------% | ||||||
|  |  | ||||||
		Reference in New Issue
	
	Block a user