''' This plugin takes a csv as input that defines the structure of the classification GUI The CSV should contain one column per dropdowns choice menu The first line of the CSV contains the label of the category and the following lines the possible choice example Tail, Morphology Straight, Gross Bent, Slim Broken, , ''' #@ File (label="CSV file for category and choice", style="extension:csv") csvpath from java.awt import Panel, Choice, Label, GridLayout from QualiAnnotations import AddDialog, ButtonAction import os, csv, codecs ### Read CSV to get categories and choices csvPath = csvpath.getPath() with open(csvPath, "r") as csvFile: # Check extension (script parameter extension filtering above not functionnal) if csvPath.endswith("csv"): # Guess , or ; separator s = csv.Sniffer() dialect = s.sniff(csvFile.readline()) csvFile.seek(0) # come back to the beginning of the file # Open and parse file csvIterator = csv.reader( codecs.EncodedFile(csvFile, "utf8", "utf_8_sig"), dialect ) # Prevent weird character with utf_8_sig encoding, generated by excel sometime elif csvPath.endswith("tsv"): csvIterator = csv.reader( codecs.EncodedFile(csvFile, "utf8", "utf_8_sig"), delimiter="\t" ) else: raise TypeError("Expected a ,-separated or ;-separated (csv) or tab-separated (tsv) file") headers = csvIterator.next() # read first header line n = len(headers) dropdowns = [ [] for i in range(n)] # [[], [], [], [], []] such that dropdowns[i] contains the list of choices for dropdowns i for row in csvIterator: for i, entry in enumerate(row): # row is a list if entry: dropdowns[i].append(entry) # dropdown[i] is the list of choices # if necessary since all columns might not have the same length # Create horizontal panel for dropdowns panel = Panel( GridLayout(0, n) ) # as many columns (n) as menus, as many rows as necessary (0) # First panel row -> dropdown labels for header in headers: panel.add( Label(header) ) # Second panel row -> dropdown choices for i in range(n): label = headers[i] chooser = Choice() chooser.setName(label) # not display but easier to recover infos dropdown = dropdowns[i] for option in dropdown: chooser.add(option) chooser.setFocusable(False) panel.add(chooser) # Define custom action on button click (in addition to default) def fillTable(Table): '''Called when Add is clicked''' for dropdown in ( panel.getComponents()[n:] ): # n first elements are the labels Table.addValue(dropdown.getName(), dropdown.getSelectedItem() ) # Initialize classification GUI title = "Qualitative Annotations - multi-classes (dropdown)" message = """Select the descriptors corresponding to the current image, then click 'Add' or press one of the '+' key. To annotate ROI, draw a new ROI or select some ROI(s) from the RoiManager before clicking 'Add'/pressing '+'.""" win = AddDialog(title, message, panel, fillTable) # Add button to window win.addButton("Add", ButtonAction(win)) # Add defaults win.addDefaultOptions() win.showDialog()