Beispiel #1
0
# ----------------------------------------------------------------------------
# Convert input file

trs = Transcription(name=trs_input.GetName()+"-IPA")

for n in args.n.split(','):
    print(" -> Tier {:s}:".format(n))
    tier = trs_input.Find(n, case_sensitive=False)
    if tier is not None:
        new_tier = mapping.map_tier(tier)
        new_tier.SetName(n+"-IPA")
        new_tier.metadata = tier.metadata
        trs.Append(new_tier)
    else:
        print(" [IGNORED] Wrong tier name.")

# Set the other members
trs.metadata = trs_input.metadata

# ----------------------------------------------------------------------------
# Write converted tiers

if trs.GetSize() == 0:
    print("No tier converted. No file created.")
    sys.exit(1)

infile, inext = os.path.splitext(args.i)
filename = infile + "-ipa" + inext
aio.write(filename, trs)
print("File {:s} created.".format(filename))
Beispiel #2
0
class TrsList(wx.Panel):
    """
    :author:       Brigitte Bigi
    :organization: Laboratoire Parole et Langage, Aix-en-Provence, France
    :contact:      [email protected]
    :license:      GPL, v3
    :copyright:    Copyright (C) 2011-2018  Brigitte Bigi
    :summary:      Show data about transcriptions, in a panel including a list of tiers.

    """
    def __init__(self, parent, filename, trs=None, multiple=False):
        wx.Panel.__init__(self, parent, -1, size=wx.DefaultSize)

        # initialize the GUI
        self._prefs = Preferences()
        self._filename = filename
        self._dirty = False  # the transcription was changed
        self._selected = False  # the transcription is selected
        self._protected = [
        ]  # list of the tiers that are protected (can't be modified)

        if len(filename) == 0:
            self._filename = "Empty"

        boxtitle = self._create_title()
        self.tier_list = self._create_list(multiple)

        # load the Transcription
        if trs is None and len(filename) != 0:
            self.LoadFile(filename)
        else:
            self._transcription = trs
        # add Transcription information in the list
        for i in range(self._transcription.GetSize()):
            self.SetTierProperties(i)
        self._checksize()

        # events
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnListItemSelected,
                  self.tier_list)
        self.Bind(wx.EVT_LIST_COL_CLICK, self.OnListItemSelected,
                  self.tier_list)

        # layout
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(boxtitle, 0, wx.EXPAND | wx.ALL, border=4)
        sizer.Add(self.tier_list, 1, wx.EXPAND | wx.ALL, border=4)

        self.SetFont(self._prefs.GetValue('M_FONT'))
        self.SetForegroundColour(self._prefs.GetValue('M_FG_COLOUR'))
        self.SetBackgroundColour(self._prefs.GetValue('M_BG_COLOUR'))
        self._boxtitle.SetForegroundColour(FG_FILE_COLOUR)

        self.SetSizerAndFit(sizer)
        self.SetAutoLayout(True)
        self.Layout()

    # ----------------------------------------------------------------------

    def _create_title(self):
        """ Create the title of the panel. """

        _sizer = wx.BoxSizer(wx.HORIZONTAL)

        self._static_tx = wx.TextCtrl(self,
                                      -1,
                                      "File: ",
                                      style=wx.TE_READONLY | wx.NO_BORDER)
        self._boxtitle = wx.TextCtrl(self,
                                     -1,
                                     self._filename,
                                     style=wx.TE_READONLY | wx.NO_BORDER)

        _sizer.Add(self._static_tx, 0, wx.RIGHT, border=2)
        _sizer.Add(self._boxtitle, 1, wx.EXPAND)

        return _sizer

    # ----------------------------------------------------------------------

    def _create_list(self, multiple=False):
        """ Create the list to show information of a each tier of a transcription. """

        if multiple:
            tier_list = CheckListCtrl(self,
                                      -1,
                                      style=wx.LC_REPORT | wx.BORDER_NONE)
        else:
            tier_list = CheckListCtrl(self,
                                      -1,
                                      style=wx.LC_REPORT | wx.BORDER_NONE
                                      | wx.LC_SINGLE_SEL)

        # Add all columns
        col_names = [
            " Nb ", " Name    ", " Begin   ", " End     ", " Type    ",
            " Size    "
        ]
        for i, n in enumerate(col_names):
            tier_list.InsertColumn(i, n)

        # Fix column width
        for i in range(len(col_names)):
            tier_list.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER)
        # Enlarge column with tier name
        tier_list.SetColumnWidth(1, 140)

        return tier_list

    # -------------------------------------------------------------------------

    def SetTierProperties(self, tier_idx):
        """ Display tier properties. """

        try:
            tier = self._transcription[tier_idx]

            if tier.IsPoint() is True:
                tier_type = "Point"
            elif tier.IsInterval():
                tier_type = "Interval"
            elif tier.IsDisjoint():
                tier_type = "Disjoint"
            else:
                tier_type = "Unknown"

            if tier.IsEmpty() is True:
                begin = " ... "
                end = " ... "
            else:
                begin = str(tier.GetBeginValue())
                end = str(tier.GetEndValue())

            self.tier_list.InsertStringItem(tier_idx,
                                            "Tier %d" % (tier_idx + 1))
            self.tier_list.SetStringItem(tier_idx, 1, tier.GetName())
            self.tier_list.SetStringItem(tier_idx, 2, begin)
            self.tier_list.SetStringItem(tier_idx, 3, end)
            self.tier_list.SetStringItem(tier_idx, 4, tier_type)
            self.tier_list.SetStringItem(tier_idx, 5, str(tier.GetSize()))

        except Exception as e:
            self.tier_list.InsertStringItem(1, "Error: " + str(e))

    # ----------------------------------------------------------------------
    # Callbacks...
    # ----------------------------------------------------------------------

    def OnListItemSelected(self, event):
        """ An item of this panel was clicked. Inform the parent. """

        evt = PanelSelectedEvent(panel=self)
        evt.SetEventObject(self)
        wx.PostEvent(self.GetParent(), evt)

    # ----------------------------------------------------------------------
    # GUI
    # ----------------------------------------------------------------------

    def SetPreferences(self, prefs):
        """ Set new preferences. """

        self._prefs = prefs
        self.SetBackgroundColour(self._prefs.GetValue("M_BG_COLOUR"))
        self.SetForegroundColour(self._prefs.GetValue("M_FG_COLOUR"))
        self.SetFont(self._prefs.GetValue("M_FONT"))

    # -------------------------------------------------------------------------

    def SetFont(self, font):
        """ Set a new font. """

        wx.Window.SetFont(self, font)

        self.tier_list.SetFont(font)
        for i in range(self._transcription.GetSize()):
            self.tier_list.SetItemFont(i, font)
        self._static_tx.SetFont(font)
        self._boxtitle.SetFont(font)
        self.Layout()  # bigger/smaller font can impact on the layout

    # -------------------------------------------------------------------------

    def SetBackgroundColour(self, color):
        """ Set background. """

        wx.Window.SetBackgroundColour(self, color)

        self.tier_list.SetBackgroundColour(color)
        for i in range(self._transcription.GetSize()):
            self.tier_list.SetItemBackgroundColour(i, color)
        self._static_tx.SetBackgroundColour(color)
        self._boxtitle.SetBackgroundColour(color)
        self.Refresh()

    # -------------------------------------------------------------------------

    def SetForegroundColour(self, color):
        """ Set foreground and items text color. """

        wx.Window.SetForegroundColour(self, color)

        self.tier_list.SetForegroundColour(color)
        for i in range(self._transcription.GetSize()):
            self.tier_list.SetItemTextColour(i, color)
        self._static_tx.SetForegroundColour(color)
        self.Refresh()

    # ----------------------------------------------------------------------
    # Functions...
    # ----------------------------------------------------------------------

    def Protect(self):
        """
        Fix the current list of tiers as protected: they won't be changed.
        """
        self._protected = []
        for i, t in enumerate(self._transcription):
            self._protected.append(t)
            self.tier_list.SetItemTextColour(i, wx.Colour(140, 10, 10))

    # -------------------------------------------------------------------------

    def Unprotect(self):
        """
        Erase the list of protected tiers.
        """
        self._protected = []

    # ----------------------------------------------------------------------

    def IsSelected(self, tiername, case_sensitive=False):
        """
        Return True if the tier is selected.
        """
        i = self._transcription.GetIndex(tiername, case_sensitive)
        if i != -1:
            return self.tier_list.IsSelected(i)
        return False

    # ----------------------------------------------------------------------

    def Select(self, tiername, case_sensitive=False):
        """
        Select tiers which name is exactly matching.
        """
        i = self._transcription.GetIndex(tiername, case_sensitive)
        if i != -1:
            self.tier_list.Select(i, on=True)
            return True
        return False

    # ----------------------------------------------------------------------

    def Deselect(self):
        #for i in range(self.tier_list.GetItemCount()):
        #    self.tier_list.Select(i, on=0)
        self.tier_list.DeSelectAll()

    # ----------------------------------------------------------------------

    def Rename(self):
        """ Rename the selected tier. Dialog with the user to get the new name. """

        if self._transcription.GetSize() == 0:
            return

        # Get the selected tier in the list
        sellist = self.tier_list.GetFirstSelected()
        # Nothing selected
        if sellist == -1:
            return
        # Too many selected items
        if self.tier_list.GetSelectedItemCount() > 1:
            ShowInformation(self,
                            self._prefs,
                            'Only one tier has to be checked to be renamed...',
                            style=wx.ICON_INFORMATION)
            return

        tier = self._transcription[sellist]
        if tier in self._protected:
            ShowInformation(self,
                            self._prefs,
                            "Attempt to rename a protected tier: forbidden!",
                            style=wx.ICON_INFORMATION)
            return

        # Ask the user to enter a new name
        dlg = wx.TextEntryDialog(self, 'Indicate the new tier name',
                                 'Data Roamer', 'Rename a tier.')
        dlg.SetValue(self._transcription[sellist].GetName())
        if dlg.ShowModal() == wx.ID_OK:
            # Update tier name of the transcription
            tier.SetName(dlg.GetValue())
            # Update tier name of the list
            self.tier_list.SetStringItem(sellist, 1, dlg.GetValue())
            self._dirty = True
            self._boxtitle.SetForegroundColour(FG_FILE_DIRTY_COLOUR)
            self.Refresh()
        dlg.Destroy()

    # ----------------------------------------------------------------------

    def Cut(self):
        """ Cut the selected tier. Return the clipboard. """

        if self._transcription.GetSize() == 0:
            return

        # Get the selected tier in the list
        sellist = self.tier_list.GetFirstSelected()
        # No tier selected
        if sellist == -1:
            return
        # Too many selected items
        if self.tier_list.GetSelectedItemCount() > 1:
            ShowInformation(self,
                            self._prefs,
                            'One tier must be checked.',
                            style=wx.ICON_INFORMATION)
            return

        # Copy the tier to the clipboard
        tier = self._transcription[sellist]
        if tier in self._protected:
            ShowInformation(self,
                            self._prefs,
                            "Attempt to cut a protected tier: forbidden!",
                            style=wx.ICON_INFORMATION)
            return

        clipboard = tier.Copy()
        # Delete tier of the transcription
        self._transcription.Remove(sellist)
        # Delete tier of the list
        self.tier_list.DeleteItem(sellist)

        # Update tier numbers of next items in the list.
        for i in range(sellist, self.tier_list.GetItemCount()):
            self.tier_list.SetStringItem(i, 0, "Tier " + str(i + 1))

        self.Deselect()
        self._checksize()
        self._dirty = True
        self._boxtitle.SetForegroundColour(FG_FILE_DIRTY_COLOUR)
        self.Refresh()

        return clipboard

    # ----------------------------------------------------------------------

    def Copy(self):
        """ Return the selected tier. """

        if self._transcription.GetSize() == 0:
            return

        # Get the selected tier in the list
        sellist = self.tier_list.GetFirstSelected()
        if sellist == -1:
            return
        # Too many selected items
        if self.tier_list.GetSelectedItemCount() > 1:
            ShowInformation(self,
                            self._prefs,
                            "One tier must be checked",
                            style=wx.ICON_INFORMATION)
            return

        # Copy the tier to the clipboard
        tier = self._transcription[sellist]

        return tier.Copy()

    # ----------------------------------------------------------------------

    def Paste(self, clipboard):
        """ Paste the clipboard tier to the current page. """

        # Get the clipboard tier
        if clipboard is None:
            return

        # Append clipboard to the transcription
        tier = clipboard  #.Copy()

        self.Append(tier)

        # The tier comes from another Transcription... must update infos.
        if not (tier.GetTranscription() is self._transcription):
            # parent transcription
            tier.SetTranscription(self._transcription)
            # And if CtrlVocab...
            # TODO

        self._checksize()

    # ----------------------------------------------------------------------

    def Delete(self):
        """ Delete the selected tier.
            Dialog with the user to confirm. """

        if self._transcription.GetSize() == 0:
            return 0

        # Get the selected tier in the list of this page
        sellist = self.tier_list.GetFirstSelected()
        if sellist == -1:
            return 0

        # Get Indexes of tiers to remove
        indexes = []
        while sellist != -1:
            indexes.append(sellist)
            sellist = self.tier_list.GetNextSelected(sellist)

        # Ask the user to confirm before deleting
        delete = 0
        message = 'Are you sure you want to definitively delete:\n' \
                  '%d tiers in %s?' % (len(indexes), self._filename)
        dlg = ShowYesNoQuestion(self, self._prefs, message)
        if dlg == wx.ID_YES:
            for sellist in reversed(sorted(indexes)):

                item = self.tier_list.GetItem(sellist)

                tier = self._transcription[sellist]
                if tier in self._protected:
                    pass
                else:

                    # Delete tier of the transcription
                    self._transcription.Remove(sellist)
                    # Delete tier of the list
                    self.tier_list.DeleteItem(sellist)
                    delete = delete + 1
                    # Update tier numbers of next items in the list.
                    for i in range(sellist, self.tier_list.GetItemCount()):
                        self.tier_list.SetStringItem(i, 0, str(i + 1))

        self._dirty = True
        self._boxtitle.SetForegroundColour(FG_FILE_DIRTY_COLOUR)
        self.Refresh

        self._checksize()
        return delete

    # ----------------------------------------------------------------------

    def Duplicate(self):
        """ Duplicate the selected tier. """

        if self._transcription.GetSize() == 0:
            return

        # Get the selected tier index in the list
        sellist = self.tier_list.GetFirstSelected()
        if sellist == -1:
            return
        # Too many selected items
        if self.tier_list.GetSelectedItemCount() > 1:
            ShowInformation(self,
                            self._prefs,
                            "One tier must be checked",
                            style=wx.ICON_INFORMATION)
            return

        tier = self._transcription[sellist]
        self.Append(tier.Copy())

    # ----------------------------------------------------------------------

    def MoveUp(self):
        """ Move up the selected tier (except for the first one). """

        if self._transcription.GetSize() == 0:
            return

        # Get the selected tier in the list
        sellist = self.tier_list.GetFirstSelected()
        if sellist == -1:
            return
        # Too many selected items
        if self.tier_list.GetSelectedItemCount() > 1:
            ShowInformation(self,
                            self._prefs,
                            "One tier must be checked",
                            style=wx.ICON_INFORMATION)
            return

        #
        tier = self._transcription[sellist]
        if tier in self._protected:
            ShowInformation(self,
                            self._prefs,
                            "Attempt to move a protected tier: forbidden!",
                            style=wx.ICON_INFORMATION)
            return

        #Impossible to move up the first tier.
        if sellist == 0:
            return

        # Pop selected tier from transcription.
        try:
            self._transcription._hierarchy.remove_tier(
                self._transcription[sellist]
            )  # waiting a better way to work with hierarchy...
        except Exception:
            pass
        self._transcription.Pop(sellist)

        # Delete old tier of the list
        self.tier_list.DeleteItem(sellist)

        # Add tier to the transcription
        tierindex = self._transcription.Add(tier, sellist - 1)
        # Add tier to the list
        self.SetTierProperties(tierindex)
        # Update tier number
        self.tier_list.SetStringItem(sellist, 0, str(sellist + 1))

        # Let the item selected
        self.tier_list.Select(sellist - 1, on=True)
        self._dirty = True
        self._boxtitle.SetForegroundColour(FG_FILE_DIRTY_COLOUR)
        self.Refresh()

    # ----------------------------------------------------------------------

    def MoveDown(self):
        """ Move down the selected tier (except for the last one). """

        if self._transcription.GetSize() == 0:
            return

        # Get the selected tier in the list
        sellist = self.tier_list.GetFirstSelected()
        if sellist == -1:
            return

        # Too many selected items
        if self.tier_list.GetSelectedItemCount() > 1:
            ShowInformation(self,
                            self._prefs,
                            "One tier must be checked",
                            style=wx.ICON_INFORMATION)
            return

        #
        tier = self._transcription[sellist]
        if tier in self._protected:
            ShowInformation(self,
                            self._prefs,
                            "Attempting to move a protected tier: forbidden!",
                            style=wx.ICON_INFORMATION)
            return

        # Impossible to move down the last tier.
        if (sellist + 1) == self.tier_list.GetItemCount():
            return

        # Pop selected tier from transcription.
        try:
            self._transcription._hierarchy.remove_tier(
                self._transcription[sellist]
            )  # waiting a better way to work with hierarchy...
        except Exception:
            pass
        self._transcription.Pop(sellist)

        # Delete old tier of the list
        self.tier_list.DeleteItem(sellist)

        # Add tier to the transcription
        if (sellist + 1) >= self.tier_list.GetItemCount():
            tierindex = self._transcription.Add(tier)
        else:
            tierindex = self._transcription.Add(tier, sellist + 1)
        # Add tier to the list
        self.SetTierProperties(tierindex)
        # Update tier number
        self.tier_list.SetStringItem(sellist, 0, "Tier " + str(sellist + 1))
        self.tier_list.SetStringItem(sellist + 1, 0,
                                     "Tier " + str(tierindex + 1))

        # Let the item selected
        self.tier_list.Select(sellist + 1, on=True)
        self._dirty = True
        self._boxtitle.SetForegroundColour(FG_FILE_DIRTY_COLOUR)
        self.Refresh()

    # ----------------------------------------------------------------------

    def Radius(self):
        """ Fix a new radius value to all TimePoint instances of the selected tier. """

        if self._transcription.GetSize() == 0:
            return

        # Get the selected tier in the list
        sellist = self.tier_list.GetFirstSelected()
        if sellist == -1:
            return

        #
        tier = self._transcription[sellist]
        if tier in self._protected:
            ShowInformation(self,
                            self._prefs,
                            "Attempt to modify a protected tier: forbidden!",
                            style=wx.ICON_INFORMATION)
            return

        # Open a dialog to ask the new radius value
        radius = tier.GetBegin().GetRadius()
        dlg = RadiusChooser(self, self._prefs, radius)
        if dlg.ShowModal() == wx.ID_OK:
            # Get the value
            r = dlg.GetValue()
            try:
                r = float(r)
                if r > 1.0:
                    raise ValueError('Radius must range 0-1.')
            except:
                logging.info('Radius cancelled (can not be applied: %f).' % r)
                return

            # Set the value
            while sellist != -1:
                tier.SetRadius(r)
                logging.debug('Radius fixed to %f' % r)
                sellist = self.tier_list.GetNextSelected(sellist)

        dlg.Destroy()

    # ----------------------------------------------------------------------

    def Preview(self):
        """ Open a grid frame with the selected tier content. """

        if self._transcription.GetSize() == 0:
            return

        # Get the selected tier in the list
        sellist = self.tier_list.GetFirstSelected()
        if sellist == -1:
            return

        # Too many selected items
        if self.tier_list.GetSelectedItemCount() > 1:
            ShowInformation(self,
                            self._prefs,
                            "One tier only must be checked",
                            style=wx.ICON_INFORMATION)
            return

        tier = self._transcription[sellist]

        dlg = PreviewTierDialog(self, self._prefs, tiers=[tier])
        dlg.Show()

    # ----------------------------------------------------------------------

    def Append(self, newtier):
        """
        Append a tier in the transcription and in the list.

        """
        # Append tier to the transcription
        tierindex = self._transcription.Append(newtier)

        # Append tier to the list
        self.SetTierProperties(tierindex)

        # Display information
        self._dirty = True
        self._boxtitle.SetForegroundColour(FG_FILE_DIRTY_COLOUR)
        self.Refresh()

    # ----------------------------------------------------------------------

    def LoadFile(self, filename):
        """
        Load a file in memory and show it.

        @param filename is an annotated file.

        """
        self._filename = filename
        if os.path.exists(filename) is False:
            self._transcription = Transcription("Empty")
            return
        try:
            self._transcription = sppas.src.annotationdata.aio.read(filename)
            self._dirty = False
            self._boxtitle.SetForegroundColour(FG_FILE_COLOUR)
            self.Refresh()
        except Exception as e:
            logging.info('Error loading file %s: %s' % (filename, str(e)))
            self._transcription = Transcription("IO-Error")
            #raise

    # ----------------------------------------------------------------------

    def Save(self):
        """ Save the current page content. """

        if self._dirty is False:
            return

        try:
            sppas.src.annotationdata.aio.write(self._filename,
                                               self._transcription)
            self._dirty = False
            self._boxtitle.SetForegroundColour(FG_FILE_COLOUR)
            self.Refresh()
        except Exception as e:
            # give information
            ShowInformation(self,
                            self._prefs,
                            'File not saved: %s' % str(e),
                            style=wx.ICON_ERROR)

    # ----------------------------------------------------------------------

    def SaveAs(self, filename):
        """
        Save the current page content with another file name.
        Keep everything un-changed in self.
        """
        try:
            sppas.src.annotationdata.aio.write(filename, self._transcription)
        except Exception as e:
            # give information
            ShowInformation(self,
                            self._prefs,
                            'File not saved: %s' % str(e),
                            style=wx.ICON_ERROR)

    # ----------------------------------------------------------------------

    def GetTranscription(self):
        """ Return the Transcription. """

        return self._transcription

    # ----------------------------------------------------------------------

    def GetTranscriptionName(self):
        """ Return the name of the transcription. """

        return self._transcription.GetName()

    # ----------------------------------------------------------------------
    # Private
    # ----------------------------------------------------------------------

    def _checksize(self):
        """
        Check the transcription size. Append an "empty line" if
        transcription is empty. Remove this empty line if transcription
        is not empty. Return True if something has changed.

        """
        # Append an "empty" line in the ListCtrl
        if self._transcription.GetSize() == 0 and self.tier_list.GetItemCount(
        ) == 0:
            self.tier_list.InsertStringItem(0, " ... ")
            if self._transcription.GetName() == "IO-Error":
                self.tier_list.SetStringItem(
                    0, 1, " Error while reading this file ")
            else:
                self.tier_list.SetStringItem(0, 1, " Empty file: no tiers ")
            for i in range(2, 5):
                self.tier_list.SetStringItem(0, i, " ")
            return True

        # Remove the "empty" line of the ListCtrl
        if self._transcription.GetSize() < self.tier_list.GetItemCount():
            self.tier_list.DeleteItem(self.tier_list.GetItemCount() - 1)
            return True

        return False
Beispiel #3
0
class IPUsTrs(object):
    """
    :author:       Brigitte Bigi
    :organization: Laboratoire Parole et Langage, Aix-en-Provence, France
    :contact:      [email protected]
    :license:      GPL, v3
    :copyright:    Copyright (C) 2011-2017  Brigitte Bigi
    :summary:      An IPUs segmentation from an already annotated data file.

    """
    def __init__(self, trs):
        """ Creates a new IPUsTrs instance.

        :param trs: (Transcription) Input transcription from which it's
        possible to extract IPUs.
        Expected tiers are:
            - first tier: the IPUs content [required]
            - second tier: the IPUs file names [optional]

        """
        super(IPUsTrs, self).__init__()
        
        self._trsinput = Transcription()
        self._units = list()  # List of the content of the units (if any)
        self._names = list()  # List of file names for IPUs (if any)
        self.set_transcription(trs)

    # ------------------------------------------------------------------

    def get_units(self):
        """ Return the list of the IPUs contents. """
        
        return self._units

    # ------------------------------------------------------------------

    def get_names(self):
        """ Return the list of file names for IPUs. """

        return self._names

    # ------------------------------------------------------------------
    # Manage Transcription
    # ------------------------------------------------------------------

    def set_transcription(self, trs):
        """ Set a new Transcription.

        :param trs: (Transcription) Input transcription from which it's
        possible to extract IPUs.

        """
        if trs is not None:
            self._trsinput = trs
        else:
            self._trsinput = Transcription()

    # ------------------------------------------------------------------
    # Units search
    # ------------------------------------------------------------------

    def extract_bounds(self):
        """ Return bound values.

        Bound values are boolean to know if we expect a silence at start
        or end of the given transcription. It is relevant only if the
        transcription was created from a non-aligned file.

        """
        # False means that I DON'T know if there is a silence:
        # It does not mean that there IS NOT a silence.
        # However, True means that there is a silence, for sure!
        bound_start = False
        bound_end = False

        if len(self._trsinput) > 0:

            # Check tier
            tier = self._trsinput[0]
            if tier.GetSize() == 0:
                raise IOError('Got no utterances.')

            # Fix bounds
            if tier[0].GetLabel().IsSilence() is True:
                bound_start = True
            if tier[-1].GetLabel().IsSilence() is True and tier.GetSize() > 1:
                bound_end = True

        return bound_start, bound_end

    # ------------------------------------------------------------------

    def extract(self):
        """ Extract units and (if any) extract tracks and silences.

        :returns: tracks and silences, with time as seconds.

        """
        self._units = list()
        self._names = list()

        if self._trsinput.GetSize() == 0:
            return [], []

        trstier = self._trsinput[0]
        nametier = None
        if self._trsinput.GetSize() == 2:
            nametier = self._trsinput[1]

        tracks = []
        silences = []
        if trstier.GetSize() == 0:
            raise IOError('Got no utterances.')

        if trstier[0].GetLocation().GetValue().IsTimeInterval():
            (tracks, silences) = self.extract_aligned(trstier, nametier)
        else:
            self.extract_units()

        return tracks, silences

    # ------------------------------------------------------------------

    def extract_units(self):
        """ Extract IPUs content from a non-aligned transcription file.

        """
        self._units = []
        self._names = []

        tier = self._trsinput[0]
        if tier.GetSize() == 0:
            raise IOError('Got no utterances.')

        i = 0
        for ann in tier:
            if ann.GetLabel().IsSilence() is False:
                self._units.append(ann.GetLabel().GetValue())
                self._names.append("track_%.06d" % (i+1))
                i += 1

    # ------------------------------------------------------------------

    def extract_aligned(self, trstier, nametier):
        """ Extract from a time-aligned transcription file.

        :returns: a tuple with tracks and silences lists

        """
        trstracks = []
        silences = []
        self._units = list()
        self._names = list()

        i = 0
        last = trstier.GetSize()
        while i < last:
            # Set the current annotation values
            ann = trstier[i]

            # Save information
            if ann.GetLabel().IsSilence():
                start = ann.GetLocation().GetBegin().GetMidpoint()
                end = ann.GetLocation().GetEnd().GetMidpoint()
                # Verify next annotations (concatenate all silences between 2 tracks)
                if (i + 1) < last:
                    nextann = trstier[i + 1]
                    while (i + 1) < last and nextann.GetLabel().IsSilence():
                        end = nextann.GetLocation().GetEnd().GetMidpoint()
                        i += 1
                        if (i + 1) < last:
                            nextann = trstier[i + 1]
                silences.append([start, end])
            else:
                start = ann.GetLocation().GetBegin().GetMidpoint()
                end = ann.GetLocation().GetEnd().GetMidpoint()
                trstracks.append([start, end])
                self._units.append(ann.GetLabel().GetValue())

                if nametier is not None:
                    aname = nametier.Find(ann.GetLocation().GetBegin().GetMidpoint(),
                                          ann.GetLocation().GetEnd().GetMidpoint(), True)
                    if len(aname) == 0:
                        trstracks.pop()
                        self._units.pop()
                    else:
                        sf = sppasFileUtils(aname[0].GetLabel().GetValue())
                        # We have to take care in case of duplicated names
                        filename = sf.clear_whitespace()
                        if len(filename) == 0:
                            filename = "unnamed_track"
                        new_name = filename
                        idx = 2
                        while new_name in self._names:
                            new_name = u"%s_%.06d" % (filename, idx)
                            idx += 1
                        self._names.append(new_name)

            # Continue
            i += 1

        return trstracks, silences