preorder2tuple maps a preorder number to a node definition.
       ottID2preorder maps every OTT ID in taxonomy.tsv to a preorder #
        'ottID2preorder'
        'ottID2preorder'
        'preorder2ottID'
        'ottID2uniq'
        'uniq2ottID'
        'name2ottID'
        'ottID2names'
        'ottID2ranks'
        'ottID2parentOttId'
        'preorder2tuple'

def _create_pickle_files(self, out_dir=None):  # pylint: disable=R0914,R0915
        """
       preorder2tuple maps a preorder number to a node definition.
       ottID2preorder maps every OTT ID in taxonomy.tsv to a preorder #
        'ottID2preorder'
        'ottID2preorder'
        'preorder2ottID'
        'ottID2uniq'
        'uniq2ottID'
        'name2ottID'
        'ottID2names'
        'ottID2ranks'
        'ottID2parentOttId'
        'preorder2tuple'
        """
        if out_dir is None:
            out_dir = self.ott_dir
        taxonomy_file = self.taxonomy_filepath
        if not os.path.isfile(taxonomy_file):
            raise ValueError('Expecting to find "{}" based on ott_dir of "{}"'.format(taxonomy_file, self.ott_dir))
        num_lines = 0
        _LOG.debug('Reading "{f}"...'.format(f=taxonomy_file))
        id2par = {}  # UID to parent UID
        id2name = {}  # UID to 'name' field
        id2rank = {}  # UID to 'rank' field
        id2uniq = {}  # UID to 'uniqname' field
        uniq2id = {}  # uniqname to UID
        id2flag = {}  # UID to a key in flag_set_id2flag_set
        id2source = {}  # UID to {rank: ... silva: ..., ncbi: ... gbif:..., irmng : , f}
        # where the value for f is
        flag_set_id2flag_set = {}
        flag_set2flag_set_id = {}
        sources = set()
        flag_set = set()
        f_set_id = 0
        source = {}
        root_ott_id = None
        with codecs.open(taxonomy_file, 'r', encoding='utf-8') as tax_fo:
            it = iter(tax_fo)
            first_line = next(it)
            assert first_line == 'uid\t|\tparent_uid\t|\tname\t|\trank\t|\tsourceinfo\t|\tuniqname\t|\tflags\t|\t\n'
            # now parse the rest of the taxonomy file
            for rown in it:
                ls = rown.split('\t|\t')
                uid, par, name = ls[:3]
                rank,sourceinfo, uniqname, flags = ls[3:7]
                skip = False
                for p in self.skip_prefixes:
                    if uniqname.startswith(p):
                        skip = True
                        break
                if skip:
                    continue
                uid = int(uid)
                if par == '':
                    # parse the root node (name = life; no parent)
                    par = NONE_PAR
                    root_ott_id = uid
                    assert name == 'life'
                    self._root_name = name
                else:
                    # this is not the root node
                    par = int(par)
                    if par not in id2par:
                        raise ValueError('parent {} not found in OTT parsing'.format(par))
                assert ls[7] == '\n'
                assert uid not in id2par
                id2par[uid] = par
                id2name[uid] = name
                if rank:
                    id2rank[uid] = rank
                if uniqname:
                    id2uniq[uid] = uniqname
                    if uniqname in uniq2id:
                        _LOG.error('uniqname "{u}" used for OTT ID "{f:d}" and "{n:d}"'.format(
                            u=uniqname,
                            f=uniq2id[uniqname],
                            n=uid))
                    uniq2id[uniqname] = uid
                if sourceinfo:
                    s_list = sourceinfo.split(',')
                    for x in s_list:
                        src, sid = x.split(':')
                        try:
                            sid = int(sid)
                        except:
                            pass
                        sources.add(src)
                        source[src] = sid
                if flags:
                    f_list = flags.split(',')
                    if len(f_list) > 1:
                        f_list.sort()
                    f_set = frozenset(f_list)
                    for x in f_list:
                        flag_set.add(x)
                    fsi = flag_set2flag_set_id.get(f_set)
                    if fsi is None:
                        fsi = f_set_id
                        f_set_id += 1
                        flag_set_id2flag_set[fsi] = f_set
                        flag_set2flag_set_id[f_set] = fsi
                    id2flag[uid] = fsi
                if source:
                    id2source[uid] = source
                    source = {}

                num_lines += 1
                if num_lines % 100000 == 0:
                    _LOG.debug('read {n:d} lines...'.format(n=num_lines))
        _LOG.debug('read taxonomy file. total of {n:d} lines.'.format(n=num_lines))
        _write_pickle(out_dir, 'ottID2parentOttId', id2par)
        synonyms_file = self.synonyms_filepath
        _LOG.debug('Reading "{f}"...'.format(f=synonyms_file))
        if not os.path.isfile(synonyms_file):
            raise ValueError('Expecting to find "{}" based on ott_dir of "{}"'.format(synonyms_file, self.ott_dir))
        num_lines = 0
        with codecs.open(synonyms_file, 'r', encoding='utf-8') as syn_fo:
            it = iter(syn_fo)
            first_line = next(it)
            # modified to allow for final 'source column'
            assert first_line.startswith('name\t|\tuid\t|\ttype\t|\tuniqname')
            for rown in it:
                ls = rown.split('\t|\t')
                name, ott_id = ls[0], ls[1]
                ott_id = int(ott_id)
                if ott_id in id2name:
                    n = id2name[ott_id]
                    if isinstance(n, list):
                        n.append(name)
                    else:
                        id2name[ott_id] = [n, name]
                else:
                    _f = u'synonym "{n}" maps to an ott_id ({u}) that was not in the taxonomy!'
                    _m = _f.format(n=name, u=ott_id)
                    _LOG.debug(_m)
                num_lines += 1
                if num_lines % 100000 == 0:
                    _LOG.debug('read {n:d} lines...'.format(n=num_lines))
        _LOG.debug('read synonyms file. total of {n:d} lines.'.format(n=num_lines))
        _LOG.debug('normalizing id2name dict. {s:d} entries'.format(s=len(id2name)))
        _swap = {}
        for k, v in id2name.items():
            if isinstance(v, list):
                v = tuple(v)
            _swap[k] = v
        id2name = _swap
        _LOG.debug('inverting id2name dict. {s:d} entries'.format(s=len(id2name)))
        name2id = {}
        for ott_id, v in id2name.items():
            if not isinstance(v, tuple):
                v = [v]
            for el in v:
                prev = name2id.get(el)
                if prev is None:
                    name2id[el] = ott_id
                elif isinstance(prev, list):
                    prev.append(ott_id)
                else:
                    name2id[el] = [prev, ott_id]
        _LOG.debug('normalizing name2id dict. {s:d} entries'.format(s=len(name2id)))
        _swap = {}
        for k, v in name2id.items():
            if isinstance(v, list):
                v = tuple(v)
            _swap[k] = v
        name2id = _swap
        homonym2id = {}
        nonhomonym2id = {}
        for name, ott_ids in name2id.items():
            if isinstance(ott_ids, tuple) and len(ott_ids) > 1:
                homonym2id[name] = ott_ids
            else:
                nonhomonym2id[name] = ott_ids
        _LOG.debug('Making heavy tree')
        tt = make_tree_from_taxonomy(id2par)
        _LOG.debug('preorder numbering nodes')
        root = tt[root_ott_id]
        root.number_tree(0)
        _LOG.debug('creating ott_id <--> preorder maps')
        ott_id2preorder = {}
        preorder2ott_id = {}
        for ott_id, node in tt.items():
            ott_id2preorder[ott_id] = node.preorder_number
            preorder2ott_id[node.preorder_number] = ott_id
        ott_id2preorder['root_ott_id'] = root_ott_id
        ott_id2preorder['root'] = root.preorder_number
        preorder2ott_id['root'] = root_ott_id
        preorder2ott_id['root_preorder'] = root.preorder_number
        self._root_ott_id = root_ott_id
        self._write_root_properties(out_dir, self._root_name, self._root_ott_id)
        _write_pickle(out_dir, 'ottID2preorder', ott_id2preorder)
        _write_pickle(out_dir, 'preorder2ottID', preorder2ott_id)
        _write_pickle(out_dir, 'ottID2uniq', id2uniq)
        _write_pickle(out_dir, 'uniq2ottID', uniq2id)
        _write_pickle(out_dir, 'name2ottID', name2id)
        _write_pickle(out_dir, 'homonym2ottID', homonym2id)
        _write_pickle(out_dir, 'nonhomonym2ottID', nonhomonym2id)
        _write_pickle(out_dir, 'ottID2names', id2name)
        _write_pickle(out_dir, 'ottID2sources', id2source)
        _write_pickle(out_dir, 'ottID2ranks', id2rank)
        _write_pickle(out_dir, 'ottID2flags', id2flag)
        _write_pickle(out_dir, 'flagSetID2FlagSet', flag_set_id2flag_set)
        _write_pickle(out_dir, 'taxonomicSources', sources)
        forward_table = self._parse_forwarding_files()
        _write_pickle(out_dir, 'forwardingTable', forward_table)
        _LOG.debug('creating tree representation with preorder # to tuples')
        preorder2tuples = {}
        root.par = _TransitionalNode()  # fake parent of root
        root.par.preorder_number = None
        root.fill_preorder2tuples(None, preorder2tuples)
        preorder2tuples['root'] = root.preorder_number
        _write_pickle(out_dir, 'preorder2tuple', preorder2tuples)