From fb8efcf9048417b4f43df4186f45cb188ef3641e Mon Sep 17 00:00:00 2001 From: Kyle Mandli Date: Fri, 15 Jul 2011 18:55:00 -0500 Subject: [PATCH 1/7] Add source related to generation of functionality coverage. Add python script that generates coverage_table.txt from coverage.csv file which is included in the sphinx docs. --- doc/source/coverage.csv | 28 ++++++++++++++++ doc/source/coverage_generator.py | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 doc/source/coverage.csv create mode 100644 doc/source/coverage_generator.py diff --git a/doc/source/coverage.csv b/doc/source/coverage.csv new file mode 100644 index 00000000..a13725da --- /dev/null +++ b/doc/source/coverage.csv @@ -0,0 +1,28 @@ +"Make movie from multiframe image ", immovie +"Play movies, videos, or image sequences ", implay +"Display image ", imshow +"Image Tool ", imtool +"Display multiple image frames as rectangular montage", montage +"Display multiple images in single figure ", subimage +"Display image as texture-mapped surface ", warp + +"Read metadata from header file of Analyze 7.5 data set ",analyze75info +"Read image data from image file of Analyze 7.5 data set ",analyze75read +"Anonymize DICOM file ",dicomanon +"Get or set active DICOM data dictionary ",dicomdict +"Read metadata from DICOM message ",dicominfo +"Find attribute in DICOM data dictionary ",dicomlookup +"Read DICOM image ",dicomread +"Generate DICOM unique identifier ",dicomuid +"Write images as DICOM files ",dicomwrite +"Read high dynamic range (HDR) image ",hdrread +"Write Radiance high dynamic range (HDR) image file ",hdrwrite +"Read metadata from Interfile file ",interfileinfo +"Read images in Interfile format ",interfileread +"Check if file is R-Set ",isrset +"Create high dynamic range image ",makehdr +"Read metadata from National Imagery Transmission Format (NITF) file",nitfinfo +"Read image from NITF file ",nitfread +"Open R-Set file ",openrset +"Create reduced resolution data set from image file ",rsetwrite +"Render high dynamic range image for viewing ",tonemap \ No newline at end of file diff --git a/doc/source/coverage_generator.py b/doc/source/coverage_generator.py new file mode 100644 index 00000000..72d79c69 --- /dev/null +++ b/doc/source/coverage_generator.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python + +import csv + +def table_seperator(cols,lengths,character="-"): + output = "+" + output += '+'.join([character*(length+2) for length in lengths]) + output += "+" + return output + +def table_row(data,lengths,num_columns=None): + if num_columns is None: + num_columns = len(data) + output = "|" + for i in xrange(num_columns): + if len(data)-1 >= i: + entry = data[i] + else: + entry = "" + output += " " + entry + " "*(lengths[i] - len(entry)) + " |" + return output + +csv_path = 'test.csv' +reader = csv.reader(open(csv_path,'r'),delimiter=',',quotechar='"') + +# Find number of columns and column widths, base number of columns is +# determined by the headers +page_title = "Coverage Tables" +print page_title +print "="*len(page_title) +print +table_names = ["Image Display and Exploration","Image File I/O"] +for table in table_names: + num_columns = 3 + data = [["Functionality","Matlab","Scipy"]] + for row in reader: + if len(row) == 0: + break + data.append([entry.expandtabs() for entry in row]) + num_columns = max(num_columns,len(row)) + + column_lengths = [0]*num_columns + for row in data: + for i in xrange(len(row)): + column_lengths[i] = max(column_lengths[i],len(row[i])) + + print table + print "-"*len(table) + print + print table_seperator(num_columns,column_lengths,character="-") + print table_row(data[0],column_lengths,num_columns) + print table_seperator(num_columns,column_lengths,character="=") + for row in data[1:]: + print table_row(row,column_lengths,num_columns) + print table_seperator(num_columns,column_lengths,character='-') + print + print From bb03488872b0fef43812624f07c06a5527eec310 Mon Sep 17 00:00:00 2001 From: Kyle Mandli Date: Fri, 15 Jul 2011 18:56:59 -0500 Subject: [PATCH 2/7] Modify TASKS to include pointer to coverage docs --- TASKS.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TASKS.txt b/TASKS.txt index ee61c652..fe0f7783 100644 --- a/TASKS.txt +++ b/TASKS.txt @@ -16,6 +16,8 @@ Tasks :doc:`gsoc2011` +:doc:`coverage_table` + Infrastructure -------------- - Implement a new backend system so that we may start including From 070e7c9cf32392b9ed88b97e173a3da94e9c86ae Mon Sep 17 00:00:00 2001 From: Kyle Mandli Date: Sat, 16 Jul 2011 10:38:48 -0500 Subject: [PATCH 3/7] Colored missing text in table --- doc/source/_static/default.css_t | 12 ++++++ doc/source/coverage_generator.py | 64 +++++++++++++++++++------------- 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/doc/source/_static/default.css_t b/doc/source/_static/default.css_t index f27fa099..af08871e 100644 --- a/doc/source/_static/default.css_t +++ b/doc/source/_static/default.css_t @@ -271,4 +271,16 @@ th { .field-list { font-size: 80%; +} + +/* Coverage States */ +span.missing{ + color: #FFFFFF; + background-color: #ff5840; + border-color: #A77272; +} +span.covered{ + color: #106600; + background-color: #60f030; + border-color: #4F8530; } \ No newline at end of file diff --git a/doc/source/coverage_generator.py b/doc/source/coverage_generator.py index 72d79c69..b80ba02a 100644 --- a/doc/source/coverage_generator.py +++ b/doc/source/coverage_generator.py @@ -1,7 +1,14 @@ #!/usr/bin/env python +import sys +import os import csv +# Parameters +missing_string = ":missing:`Not Implemented`" +page_title = "Coverage Tables" +table_names = ["Image Display and Exploration","Image File I/O"] + def table_seperator(cols,lengths,character="-"): output = "+" output += '+'.join([character*(length+2) for length in lengths]) @@ -16,42 +23,49 @@ def table_row(data,lengths,num_columns=None): if len(data)-1 >= i: entry = data[i] else: - entry = "" + entry = missing_string output += " " + entry + " "*(lengths[i] - len(entry)) + " |" return output - -csv_path = 'test.csv' -reader = csv.reader(open(csv_path,'r'),delimiter=',',quotechar='"') - -# Find number of columns and column widths, base number of columns is -# determined by the headers -page_title = "Coverage Tables" -print page_title -print "="*len(page_title) -print -table_names = ["Image Display and Exploration","Image File I/O"] -for table in table_names: + +def generate_table(reader,column_titles=["Functionality","Matlab","Scipy"]): + # Find number of columns and column widths, base number of columns is + # determined by the headers num_columns = 3 - data = [["Functionality","Matlab","Scipy"]] + data = [column_titles] for row in reader: if len(row) == 0: break data.append([entry.expandtabs() for entry in row]) num_columns = max(num_columns,len(row)) - column_lengths = [0]*num_columns + column_lengths = [len(missing_string)]*num_columns for row in data: for i in xrange(len(row)): column_lengths[i] = max(column_lengths[i],len(row[i])) - print table - print "-"*len(table) - print - print table_seperator(num_columns,column_lengths,character="-") - print table_row(data[0],column_lengths,num_columns) - print table_seperator(num_columns,column_lengths,character="=") + output = table + "\n" + output += "-"*len(table)+"\n\n" + output += table_seperator(num_columns,column_lengths,character="-") + "\n" + output += table_row(data[0],column_lengths,num_columns) + "\n" + output += table_seperator(num_columns,column_lengths,character="=") + "\n" for row in data[1:]: - print table_row(row,column_lengths,num_columns) - print table_seperator(num_columns,column_lengths,character='-') - print - print + output += table_row(row,column_lengths,num_columns) + "\n" + output += table_seperator(num_columns,column_lengths,character='-') + "\n" + output += "\n\n" + return output + +if __name__ == "__main__": + if len(sys.argv) > 1: + csv_path = os.path.abspath(sys.argv[1]) + else: + csv_path = './coverage.csv' + + reader = csv.reader(open(csv_path,'r'),delimiter=',',quotechar='"') + +print page_title +print "="*len(page_title) +print +print ".. role:: missing" +print +for table in table_names: + print generate_table(reader) From d73416294dbaef7b48e8b42e57b19a2e3ba66238 Mon Sep 17 00:00:00 2001 From: Kyle Mandli Date: Sat, 16 Jul 2011 16:52:09 -0500 Subject: [PATCH 4/7] Add complete matlab image API --- doc/source/coverage.csv | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/doc/source/coverage.csv b/doc/source/coverage.csv index a13725da..02fb548f 100644 --- a/doc/source/coverage.csv +++ b/doc/source/coverage.csv @@ -1,28 +1 @@ -"Make movie from multiframe image ", immovie -"Play movies, videos, or image sequences ", implay -"Display image ", imshow -"Image Tool ", imtool -"Display multiple image frames as rectangular montage", montage -"Display multiple images in single figure ", subimage -"Display image as texture-mapped surface ", warp - -"Read metadata from header file of Analyze 7.5 data set ",analyze75info -"Read image data from image file of Analyze 7.5 data set ",analyze75read -"Anonymize DICOM file ",dicomanon -"Get or set active DICOM data dictionary ",dicomdict -"Read metadata from DICOM message ",dicominfo -"Find attribute in DICOM data dictionary ",dicomlookup -"Read DICOM image ",dicomread -"Generate DICOM unique identifier ",dicomuid -"Write images as DICOM files ",dicomwrite -"Read high dynamic range (HDR) image ",hdrread -"Write Radiance high dynamic range (HDR) image file ",hdrwrite -"Read metadata from Interfile file ",interfileinfo -"Read images in Interfile format ",interfileread -"Check if file is R-Set ",isrset -"Create high dynamic range image ",makehdr -"Read metadata from National Imagery Transmission Format (NITF) file",nitfinfo -"Read image from NITF file ",nitfread -"Open R-Set file ",openrset -"Create reduced resolution data set from image file ",rsetwrite -"Render high dynamic range image for viewing ",tonemap \ No newline at end of file +Image Display and Exploration,Image Display and Exploration,Image File I/O,Image Types and Type Conversions GUI Tools,Modular Interactive Tools,Navigational Tools for Image Scroll Panel,Utilities for Interactive Tools Spatial Transformations and Image Registration,Spatial Transformations,Image Registration, Image Analysis and Statistics,Image Analysis,Texture Analysis,Pixel Values and Statistics Image Arithmetic,,, Image Enhancement and Restoration,Image Enhancement,Image Restoration (Deblurring), Linear Filtering and Transforms,Linear Filtering,Linear 2-D Filter Design,Image Transforms Morphological Operations,Intensity and Binary Images,Binary Images,Structuring Element Creation and Manipulation "ROI-Based, Neighborhood, and Block Processing",ROI-Based Processing,Neighborhood and Block Processing, Colormaps and Color Space,Color Space Conversions,, Utilities,Validation,Array Operations,Performance ,,, Make movie from multiframe image ,immovie ,:done:`immovie`,:partial:`immovie` "Play movies, videos, or image sequences ",implay ,:na:`n/a`, Display image ,imshow ,, Image Tool ,imtool ,, Display multiple image frames as rectangular montage,montage ,, Display multiple images in single figure ,subimage,, Display image as texture-mapped surface ,warp ,, , ,, Read metadata from header file of Analyze 7.5 data set ,analyze75info,, Read image data from image file of Analyze 7.5 data set ,analyze75read,, Anonymize DICOM file ,dicomanon ,, Get or set active DICOM data dictionary ,dicomdict ,, Read metadata from DICOM message ,dicominfo ,, Find attribute in DICOM data dictionary ,dicomlookup ,, Read DICOM image ,dicomread ,, Generate DICOM unique identifier ,dicomuid ,, Write images as DICOM files ,dicomwrite ,, Read high dynamic range (HDR) image ,hdrread ,, Write Radiance high dynamic range (HDR) image file ,hdrwrite ,, Read metadata from Interfile file ,interfileinfo,, Read images in Interfile format ,interfileread,, Check if file is R-Set ,isrset ,, Create high dynamic range image ,makehdr ,, Read metadata from National Imagery Transmission Format (NITF) file,nitfinfo ,, Read image from NITF file ,nitfread ,, Open R-Set file ,openrset ,, Create reduced resolution data set from image file ,rsetwrite ,, Render high dynamic range image for viewing ,tonemap ,, ,,, Convert Bayer pattern encoded image to truecolor image,demosaic,, Convert grayscale or binary image to indexed image,gray2ind,, Convert grayscale image to indexed image using multilevel thresholding,grayslice,, Global image threshold using Otsu's method,graythresh,, "Convert image to binary image, based on threshold",im2bw,, Convert image to double precision,im2double,, Convert image to 16-bit signed integers,im2int16,, Convert image to Java buffered image,im2java2d,, Convert image to single precision,im2single,, Convert image to 16-bit unsigned integers,im2uint16,, Convert image to 8-bit unsigned integers,im2uint8,, Convert indexed image to grayscale image,ind2gray,, Convert indexed image to RGB image,ind2rgb,, Convert label matrix into RGB image,label2rgb,, Convert matrix to grayscale image,mat2gray,, Convert RGB image or colormap to grayscale,rgb2gray,, ,,, Image Information tool,imageinfo,, Adjust Contrast tool,imcontrast,, Display Range tool,imdisplayrange,, Distance tool,imdistline,, Pixel Information tool,impixelinfo,, Pixel Information tool without text label,impixelinfoval,, Pixel Region tool,impixelregion,, Pixel Region tool panel,impixelregionpanel,, ,,, Magnification box for scroll panel,immagbox,, Overview tool for image displayed in scroll panel,imoverview,, Overview tool panel for image displayed in scroll panel,imoverviewpanel,, Scroll panel for interactive image navigation,imscrollpanel,, ,,, Convert axes coordinates to pixel coordinates,axes2pix,, Image data from axes,getimage,, Image model object from image object,getimagemodel,, Information about image attributes,imattributes,, Create draggable ellipse,imellipse,, Create draggable freehand region,imfreehand,, Get handle to current axes containing image,imgca,, Get handle to current figure containing image,imgcf,, Open Image dialog box,imgetfile,, Get all image handles,imhandles,, "Create draggable, resizable line",imline,, Create draggable point,impoint,, "Create draggable, resizable polygon",impoly,, Create draggable rectangle,imrect,, Region-of-interest (ROI) base class,imroi,, Add function handle to callback list,iptaddcallback,, Check validity of handle,iptcheckhandle,, Get Application Programmer Interface (API) for handle,iptgetapi,, Retrieve pointer behavior from HG object,iptGetPointerBehavior,, Directories containing IPT and MATLAB icons,ipticondir,, Create pointer manager in figure,iptPointerManager,, Delete function handle from callback list,iptremovecallback,, Store pointer behavior structure in Handle Graphics object,iptSetPointerBehavior,, Align figure windows,iptwindowalign,, Create rectangularly bounded drag constraint function,makeConstrainToRectFcn,, Adjust display size of image,truesize,, ,,, Create checkerboard image,checkerboard,, Find output bounds for spatial transformation,findbounds,, Flip input and output roles of TFORM structure,fliptform,, Crop image,imcrop,, Image pyramid reduction and expansion,impyramid,, Resize image,imresize,, Rotate image,imrotate,, Apply 2-D spatial transformation to image,imtransform,, Create resampling structure,makeresampler,, Create spatial transformation structure (TFORM),maketform,, Apply spatial transformation to N-D array,tformarray,, Apply forward spatial transformation,tformfwd,, Apply inverse spatial transformation,tforminv,, ,,, Infer spatial transformation from control point pairs,cp2tform,, Tune control-point locations using cross correlation,cpcorr,, Control Point Selection Tool,cpselect,, Convert CPSTRUCT to valid pairs of control points,cpstruct2pairs,, Normalized 2-D cross-correlation,normxcorr2,, ,,, Trace region boundaries in binary image,bwboundaries,, Trace object in binary image,bwtraceboundary,, Find corner points in image,corner,, Create corner metric matrix from image,cornermetric,, Find edges in grayscale image,edge,, Hough transform,hough,, Extract line segments based on Hough transform,houghlines,, Identify peaks in Hough transform,houghpeaks,, Quadtree decomposition,qtdecomp,, Block values in quadtree decomposition,qtgetblk,, Set block values in quadtree decomposition,qtsetblk,, ,,, Entropy of grayscale image,entropy,, Local entropy of grayscale image,entropyfilt,, Create gray-level co-occurrence matrix from image,graycomatrix,, Properties of gray-level co-occurrence matrix,graycoprops,, Local range of image,rangefilt,, Local standard deviation of image,stdfilt,, ,,, 2-D correlation coefficient,corr2,, Create contour plot of image data,imcontour,, Display histogram of image data,imhist,, Pixel color values,impixel,, Pixel-value cross-sections along line segments,improfile,, Average or mean of matrix elements,mean2,, Measure properties of image regions,regionprops,, Standard deviation of matrix elements,std2,, ,,, Absolute difference of two images,imabsdiff,, Add two images or add constant to image,imadd,, Complement image,imcomplement,, Divide one image into another or divide image by constant,imdivide,, Linear combination of images,imlincomb,, Multiply two images or multiply image by constant,immultiply,, Subtract one image from another or subtract constant from image,imsubtract,, ,,, Contrast-limited adaptive histogram equalization (CLAHE),adapthisteq,, Apply decorrelation stretch to multichannel image,decorrstretch,, Enhance contrast using histogram equalization,histeq,, Adjust image intensity values or colormap,imadjust,, Add noise to image,imnoise,, Convert integer values using lookup table,intlut,, 2-D median filtering,medfilt2,, 2-D order-statistic filtering,ordfilt2,, Find limits to contrast stretch image,stretchlim,, 2-D adaptive noise-removal filtering,wiener2,, ,,, Deblur image using blind deconvolution,deconvblind,, Deblur image using Lucy-Richardson method,deconvlucy,, Deblur image using regularized filter,deconvreg,, Deblur image using Wiener filter,deconvwnr,, Taper discontinuities along image edges,edgetaper,, Convert optical transfer function to point-spread function,otf2psf,, Convert point-spread function to optical transfer function,psf2otf,, ,,, 2-D convolution matrix,convmtx2,, Create predefined 2-D filter,fspecial,, N-D filtering of multidimensional images,imfilter,, ,,, 2-D frequency response,freqz2,, 2-D FIR filter using frequency sampling,fsamp2,, 2-D FIR filter using frequency transformation,ftrans2,, 2-D FIR filter using 1-D window method,fwind1,, 2-D FIR filter using 2-D window method,fwind2,, ,,, 2-D discrete cosine transform,dct2,, Discrete cosine transform matrix,dctmtx,, Convert fan-beam projections to parallel-beam,fan2para,, Fan-beam transform,fanbeam,, 2-D inverse discrete cosine transform,idct2,, Inverse fan-beam transform,ifanbeam,, Inverse Radon transform,iradon,, Convert parallel-beam projections to fan-beam,para2fan,, Create head phantom image,phantom,, Radon transform,radon,, ,,, Create connectivity array,conndef,, Bottom-hat filtering,imbothat,, Suppress light structures connected to image border,imclearborder,, Morphologically close image,imclose,, Dilate image,imdilate,, Erode image,imerode,, Extended-maxima transform,imextendedmax,, Extended-minima transform,imextendedmin,, Fill image regions and holes,imfill,, H-maxima transform,imhmax,, H-minima transform,imhmin,, Impose minima,imimposemin,, Morphologically open image,imopen,, Morphological reconstruction,imreconstruct,, Regional maxima,imregionalmax,, Regional minima,imregionalmin,, Top-hat filtering,imtophat,, Watershed transform,watershed,, ,,, Generate convex hull image from binary image,bwconvhull,, Neighborhood operations on binary images using lookup tables,applylut,, Area of objects in binary image,bwarea,, Morphologically open binary image (remove small objects),bwareaopen,, Find connected components in binary image,bwconncomp,, Distance transform of binary image,bwdist,, Euler number of binary image,bweuler,, Binary hit-miss operation,bwhitmiss,, Label connected components in 2-D binary image,bwlabel,, Label connected components in binary image,bwlabeln,, Morphological operations on binary images,bwmorph,, Pack binary image,bwpack,, Find perimeter of objects in binary image,bwperim,, Select objects in binary image,bwselect,, Ultimate erosion,bwulterode,, Unpack binary image,bwunpack,, Top-hat filtering,imtophat,, Create lookup table for use with ``applylut``,makelut,, ,,, Height of structuring element,getheight,, Structuring element neighbor locations and heights,getneighbors,, Structuring element neighborhood,getnhood,, Sequence of decomposed structuring elements,getsequence,, True for flat structuring element,isflat,, Reflect structuring element,reflect,, Create morphological structuring element (``STREL``),strel,, Translate structuring element (``STREL``),translate,, ,,, Convert region of interest (ROI) polygon to region mask,poly2mask,, Select region of interest (ROI) based on color,roicolor,, Fill in specified region of interest (ROI) polygon in grayscale image,roifill,, Filter region of interest (ROI) in image,roifilt2,, Specify polygonal region of interest (ROI),roipoly,, ,,, Determine optimal block size for block processing,bestblk,, Distinct block processing for image,blockproc,, Close ImageAdapter object,close (ImageAdapter),, Rearrange matrix columns into blocks,col2im,, Columnwise neighborhood operations,colfilt,, Rearrange image blocks into columns,im2col,, Interface for image I/O,ImageAdapter,, General sliding-neighborhood operations,nlfilter,, Read region of image,readRegion (ImageAdapter),, Write block of data to region of image,writeRegion (ImageAdapter),, ,,, Apply device-independent color space transformation,applycform,, Search for ICC profiles,iccfind,, Read ICC profile,iccread,, Find system default ICC profile repository,iccroot,, Write ICC color profile to disk file,iccwrite,, True for valid ICC color profile,isicc,, Convert L*a*b* data to double,lab2double,, Convert L*a*b* data to uint16,lab2uint16,, Convert L*a*b* data to uint8,lab2uint8,, Create color transformation structure,makecform,, Convert NTSC values to RGB color space,ntsc2rgb,, Convert RGB color values to NTSC color space,rgb2ntsc,, Convert RGB color values to YCbCr color space,rgb2ycbcr,, XYZ color values of standard illuminants,whitepoint,, Convert XYZ color values to double,xyz2double,, Convert XYZ color values to uint16,xyz2uint16,, Convert YCbCr color values to RGB color space,ycbcr2rgb,, ,,, Default display range of image based on its class,getrangefromclass,, Check validity of connectivity argument,iptcheckconn,, Check validity of array,iptcheckinput,, Check validity of colormap,iptcheckmap,, Check number of input arguments,iptchecknargin,, Check validity of option string,iptcheckstrs,, Convert positive integer to ordinal string,iptnum2ordinal,, ,,, Pad array,padarray,, ,,, Check for presence of Intel Integrated Performance Primitives (Intel IPP) library,ippl,, \ No newline at end of file From 92ce7318900707999e75bc423e961b0578dd2371 Mon Sep 17 00:00:00 2001 From: Kyle Mandli Date: Sat, 16 Jul 2011 16:54:23 -0500 Subject: [PATCH 5/7] Change look and feel of table, add better handling of table columns Add many improvements to table look including support for tags such as missing, partial, done, and not applicable. The tabularcolumns directive does not seem to be affecting the tables width and columns however. --- doc/source/_static/default.css_t | 15 ++- doc/source/coverage_generator.py | 162 +++++++++++++++++++++++-------- 2 files changed, 132 insertions(+), 45 deletions(-) diff --git a/doc/source/_static/default.css_t b/doc/source/_static/default.css_t index af08871e..d6ae53b3 100644 --- a/doc/source/_static/default.css_t +++ b/doc/source/_static/default.css_t @@ -275,12 +275,23 @@ th { /* Coverage States */ span.missing{ - color: #FFFFFF; + color: #000; background-color: #ff5840; border-color: #A77272; + font-weight: bold; } -span.covered{ +span.partial{ + color: #806600; + background-color: #ffc343; + font-weight: bold; +} +span.done{ color: #106600; background-color: #60f030; border-color: #4F8530; + font-weight: bold; +} +span.na{ + color: #A8A8A8; + border-color: #4F8530; } \ No newline at end of file diff --git a/doc/source/coverage_generator.py b/doc/source/coverage_generator.py index b80ba02a..59094daa 100644 --- a/doc/source/coverage_generator.py +++ b/doc/source/coverage_generator.py @@ -4,68 +4,144 @@ import sys import os import csv -# Parameters -missing_string = ":missing:`Not Implemented`" -page_title = "Coverage Tables" -table_names = ["Image Display and Exploration","Image File I/O"] +# Import StringIO module +try: + import cStringIO as StringIO +except ImportError: + import StringIO -def table_seperator(cols,lengths,character="-"): - output = "+" - output += '+'.join([character*(length+2) for length in lengths]) - output += "+" - return output +# Missing item value +MISSING_STRING=":missing:`Not Implemented`" + +def read_table_titles(reader): + r"""Create a dictionary with keys as section names and values as a list of + table names -def table_row(data,lengths,num_columns=None): + return (dict) + """ + section_titles = [] + table_names = {} + try: + for row in reader: + names = [] + # End of names table + if len(row[0]) == 0: + break + # Extract names of the tables + for name in row[1:]: + if len(name) > 0: + names.append(name) + else: + break + section_titles.append(row[0]) + table_names[row[0]] = names + except csv.Error, e: + sys.exit('line %d: %s' % (reader.line_num, e)) + + return section_titles,table_names + +def table_seperator(stream,cols,lengths,character="-"): + stream.write("+") + stream.write('+'.join([character*(length+2) for length in lengths])) + stream.write("+") + +def table_row(stream,data,lengths,num_columns=None): if num_columns is None: num_columns = len(data) - output = "|" + stream.write("|") for i in xrange(num_columns): if len(data)-1 >= i: - entry = data[i] + if len(data[i]) == 0: + entry = MISSING_STRING + else: + entry = data[i] else: - entry = missing_string - output += " " + entry + " "*(lengths[i] - len(entry)) + " |" - return output + entry = MISSING_STRING + stream.write(" " + entry + " "*(lengths[i] - len(entry)) + " |") -def generate_table(reader,column_titles=["Functionality","Matlab","Scipy"]): +def generate_table(reader,stream,table_name, + column_titles=["Functionality","Matlab","Scipy","Scipy"]): # Find number of columns and column widths, base number of columns is # determined by the headers - num_columns = 3 + num_columns = len(column_titles) data = [column_titles] - for row in reader: - if len(row) == 0: - break - data.append([entry.expandtabs() for entry in row]) - num_columns = max(num_columns,len(row)) + try: + for row in reader: + # print row + if len(row[0]) == 0: + break + data.append([entry.expandtabs() for entry in row]) + num_columns = max(num_columns,len(row)) + except csv.Error, e: + sys.exit('line %d: %s' % (reader.line_num, e)) - column_lengths = [len(missing_string)]*num_columns + column_lengths = [len(MISSING_STRING)]*num_columns for row in data: for i in xrange(len(row)): column_lengths[i] = max(column_lengths[i],len(row[i])) - output = table + "\n" - output += "-"*len(table)+"\n\n" - output += table_seperator(num_columns,column_lengths,character="-") + "\n" - output += table_row(data[0],column_lengths,num_columns) + "\n" - output += table_seperator(num_columns,column_lengths,character="=") + "\n" + # Output table header + stream.write(table_name + "\n") + stream.write("~"*len(table_name)+"\n\n") + stream.write(".. tabularcolumns:: |p{40%}|p{20%}|p{20%}|p{20%}|\n\n") + stream.write(".. table::%s\n\n" % table_name) + table_seperator(stream,num_columns,column_lengths,character="-") + stream.write("\n") + table_row(stream,data[0],column_lengths,num_columns) + stream.write("\n") + table_seperator(stream,num_columns,column_lengths,character="=") + stream.write("\n") + + # Output table data for row in data[1:]: - output += table_row(row,column_lengths,num_columns) + "\n" - output += table_seperator(num_columns,column_lengths,character='-') + "\n" - output += "\n\n" - return output + table_row(stream,row,column_lengths,num_columns) + stream.write("\n") + table_seperator(stream,num_columns,column_lengths,character='-') + stream.write("\n") + stream.write("\n\n") + +def generate_page(reader,stream,page_title="Coverage Tables"): + stream.write("%s\n" % page_title) + stream.write("="*len(page_title) + "\n\n") + stream.write(".. role:: missing\n") + stream.write(".. role:: partial\n") + stream.write(".. role:: done\n") + stream.write(".. role:: na\n\n") + stream.write("Color Key\n") + stream.write("---------\n") + stream.write(":done:`Complete` ") + stream.write(":partial:`Partial` ") + stream.write(":missing:`Missing` ") + stream.write(":na:`Not applicable`\n\n") + + sections,table_names = read_table_titles(reader) + for section_name in sections: + stream.write(section_name + "\n") + stream.write("-"*len(section_name) + "\n\n") + for table_name in table_names[section_name]: + generate_table(reader,stream,table_name) if __name__ == "__main__": - if len(sys.argv) > 1: + csv_path = './coverage.csv' + output_path = './coverage_table.txt' + if len(sys.argv) == 2: csv_path = os.path.abspath(sys.argv[1]) - else: - csv_path = './coverage.csv' + if len(sys.argv) == 3: + output_path = os.path.abspath(sys.argv[2]) + + # Figure out dialect and create csv reader + csv_file = open(csv_path,'U') + # dialect = csv.Sniffer().sniff(csv_file.read(1024)) + # csv_file.seek(0) + # reader = csv.reader(csv_file, dialect) + reader = csv.reader(csv_file,) + + output = open(output_path,'w') + generate_page(reader,output) + + csv_file.close() + output.close() + + print "Generated %s from %s." % (output_path,csv_path) - reader = csv.reader(open(csv_path,'r'),delimiter=',',quotechar='"') -print page_title -print "="*len(page_title) -print -print ".. role:: missing" -print -for table in table_names: - print generate_table(reader) From 2303118d0b7e475526286445cc4e6f3ff572c426 Mon Sep 17 00:00:00 2001 From: Kyle Mandli Date: Wed, 20 Jul 2011 10:16:32 -0500 Subject: [PATCH 6/7] Change default css to include coverage bar formatting --- doc/source/_static/default.css_t | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/doc/source/_static/default.css_t b/doc/source/_static/default.css_t index d6ae53b3..cd2bf48f 100644 --- a/doc/source/_static/default.css_t +++ b/doc/source/_static/default.css_t @@ -294,4 +294,30 @@ span.done{ span.na{ color: #A8A8A8; border-color: #4F8530; +} +span.missing-bar{ + color: #000; + background-color: #ff5840; + border-color: #A77272; + font-weight: normal; + font-style: normal; +} +span.partial-bar{ + color: #806600; + background-color: #ffc343; + font-weight: normal; + font-style: normal; +} +span.done-bar{ + color: #106600; + background-color: #60f030; + border-color: #4F8530; + font-weight: normal; + font-style: normal; +} +span.na-bar{ + color: #A8A8A8; + border-color: #4F8530; + font-weight: normal; + font-style: normal; } \ No newline at end of file From 7d79a3f3c696b280df6ad84a89dbc6c978b6c856 Mon Sep 17 00:00:00 2001 From: Kyle Mandli Date: Wed, 20 Jul 2011 10:17:03 -0500 Subject: [PATCH 7/7] Bug fixes and documentation writing --- doc/source/coverage_generator.py | 159 ++++++++++++++++++++++++++----- 1 file changed, 137 insertions(+), 22 deletions(-) diff --git a/doc/source/coverage_generator.py b/doc/source/coverage_generator.py index 59094daa..74e50231 100644 --- a/doc/source/coverage_generator.py +++ b/doc/source/coverage_generator.py @@ -13,6 +13,43 @@ except ImportError: # Missing item value MISSING_STRING=":missing:`Not Implemented`" +def calculate_coverage(reader,blocks=100): + r"""Calculate portions of code that are in one of the coverage categories + + Returns a tuple representing the weighted items as integers. The order is + + (done,partial,missing,not applicable) + """ + # Coverage counters + total_items = 0 + partial_items = 0 + done_items = 0 + na_items = 0 + + # Skip table names + for row in reader: + if len(row[0]) == 0: + break + + # Count items + for row in reader: + if len(row[0]) > 0: + total_items += 1 + if ":done:" in row[2] or ":done:" in row[3]: + done_items += 1 + elif ":partial:" in row[2] or ":partial:" in row[3]: + partial_items += 1 + elif ":na:" in row[2] or ":na:" in row[3]: + na_items += 1 + + weight = float(blocks) / total_items + + return (int(weight*done_items), + int(weight*partial_items), + int(weight*(total_items - (partial_items + done_items + na_items))), + int(weight*na_items)) + + def read_table_titles(reader): r"""Create a dictionary with keys as section names and values as a list of table names @@ -40,12 +77,30 @@ def read_table_titles(reader): return section_titles,table_names -def table_seperator(stream,cols,lengths,character="-"): +def table_seperator(stream,lengths,character="-"): + r"""Write out table row seperator + + :Input: + - *stream* (io/stream) Stream where output is put + - *lengths* (list) A list of the lengths of the columns + - *character* (string) Character to be filled between +, defaults to "-". + + """ stream.write("+") stream.write('+'.join([character*(length+2) for length in lengths])) stream.write("+") def table_row(stream,data,lengths,num_columns=None): + r"""Write out table row data + + :Input: + - *stream* (io/stream) Stream where output is put + - *data* (list) List of strings containing data + - *lengths* (list) A list of the lengths of the columns + - *num_columns* (string) Number of columns, defaults to the length of the + data array + + """ if num_columns is None: num_columns = len(data) stream.write("|") @@ -59,8 +114,25 @@ def table_row(stream,data,lengths,num_columns=None): entry = MISSING_STRING stream.write(" " + entry + " "*(lengths[i] - len(entry)) + " |") -def generate_table(reader,stream,table_name, +def generate_table(reader,stream,table_name=None, column_titles=["Functionality","Matlab","Scipy","Scipy"]): + r"""Generate a reST grid table based on the CSV data in reader + + Reads CSV data from *reader* until an empty line is found and generates a + reST table based on the data into *stream*. A table name can be given for + a section and table label. All rows are read in and checked for maximum + number of columns (defaults to the size of column_titles) and column + widths so that the table can be constructed. If a row contains less than + the maximum number of columns a string is inserted that defaults to the + string *MISSING_STRING* which is a global parameter. + + :Input: + - reader (csv.reader) The CSV reader to read in from + - stream (iostream) Output target + - table_name (string) Optional name of table, defaults to *None* + - column_titles (list) List of column titles + + """ # Find number of columns and column widths, base number of columns is # determined by the headers num_columns = len(column_titles) @@ -82,37 +154,79 @@ def generate_table(reader,stream,table_name, # Output table header stream.write(table_name + "\n") - stream.write("~"*len(table_name)+"\n\n") + if table_name is not None: + stream.write("~"*len(table_name)+"\n\n") stream.write(".. tabularcolumns:: |p{40%}|p{20%}|p{20%}|p{20%}|\n\n") - stream.write(".. table::%s\n\n" % table_name) - table_seperator(stream,num_columns,column_lengths,character="-") + if table_name is not None: + stream.write(".. table::%s\n\n" % table_name) + table_seperator(stream,column_lengths,character="-") stream.write("\n") table_row(stream,data[0],column_lengths,num_columns) stream.write("\n") - table_seperator(stream,num_columns,column_lengths,character="=") + table_seperator(stream,column_lengths,character="=") stream.write("\n") # Output table data for row in data[1:]: table_row(stream,row,column_lengths,num_columns) stream.write("\n") - table_seperator(stream,num_columns,column_lengths,character='-') + table_seperator(stream,column_lengths,character='-') stream.write("\n") stream.write("\n\n") -def generate_page(reader,stream,page_title="Coverage Tables"): +def generate_page(csv_path,stream,page_title="Coverage Tables"): + r"""Generate coverage table page + + Generates all reST for all tables contained in the CSV file at *csv_path* + and output it to *stream*. + + :Input: + - *csv_path* (path) Path to CSV file + - *stream* (iostream) Output stream + - *page_title* (string) Optional page title, defaults to + ``Coverage Tables``. + """ + # Open reader + csv_file = open(csv_path,'U') + + # Sniffer does not seem to work all the time even when an Excel + # spread sheet is being used + # dialect = csv.Sniffer().sniff(csv_file.read(1024)) + # csv_file.seek(0) + # reader = csv.reader(csv_file, dialect) + + reader = csv.reader(csv_file) + item_counts = calculate_coverage(reader,blocks=90) + csv_file.seek(0) + + # Write out header stream.write("%s\n" % page_title) stream.write("="*len(page_title) + "\n\n") stream.write(".. role:: missing\n") stream.write(".. role:: partial\n") stream.write(".. role:: done\n") stream.write(".. role:: na\n\n") + stream.write(".. role:: missing-bar\n") + stream.write(".. role:: partial-bar\n") + stream.write(".. role:: done-bar\n") + stream.write(".. role:: na-bar\n\n") stream.write("Color Key\n") stream.write("---------\n") stream.write(":done:`Complete` ") stream.write(":partial:`Partial` ") stream.write(":missing:`Missing` ") stream.write(":na:`Not applicable`\n\n") + stream.write("Coverage Bar\n") + stream.write("------------\n\n") + if item_counts[0] > 0: + stream.write(":done-bar:`%s` " % ("="*item_counts[0])) + if item_counts[1] > 0: + stream.write(":partial-bar:`%s` " % ("="*item_counts[1])) + if item_counts[2] > 0: + stream.write(":missing-bar:`%s` " % ("="*item_counts[2])) + if item_counts[3] > 0: + stream.write(":na-bar:`%s`" % ("="*item_counts[3])) + stream.write("\n\n") sections,table_names = read_table_titles(reader) for section_name in sections: @@ -120,26 +234,27 @@ def generate_page(reader,stream,page_title="Coverage Tables"): stream.write("-"*len(section_name) + "\n\n") for table_name in table_names[section_name]: generate_table(reader,stream,table_name) + + csv_file.close() if __name__ == "__main__": csv_path = './coverage.csv' output_path = './coverage_table.txt' - if len(sys.argv) == 2: - csv_path = os.path.abspath(sys.argv[1]) - if len(sys.argv) == 3: - output_path = os.path.abspath(sys.argv[2]) - - # Figure out dialect and create csv reader - csv_file = open(csv_path,'U') - # dialect = csv.Sniffer().sniff(csv_file.read(1024)) - # csv_file.seek(0) - # reader = csv.reader(csv_file, dialect) - reader = csv.reader(csv_file,) + if len(sys.argv) > 1: + if sys.argv[1][:5].lower() == "help": + print "Coverage Table Generator: coverage_generator.py" + print " Usage: coverage_generator.py [csv] [output]" + print " csv - Path to csv file, defaults to ./coverage.csv" + print " output - Ouput path, defaults to ./coverage_table.txt" + print "" + sys.exit(0) + if len(sys.argv) == 2: + csv_path = os.path.abspath(sys.argv[1]) + if len(sys.argv) == 3: + output_path = os.path.abspath(sys.argv[2]) output = open(output_path,'w') - generate_page(reader,output) - - csv_file.close() + generate_page(csv_path,output) output.close() print "Generated %s from %s." % (output_path,csv_path)