예제 #1
0
    def write(self, filename):
        # only write if all symbols loaded
        for symbol in self:
            if not symbol.loaded:
                raise Error(
                    "All symbols must be loaded before this file can be written."
                )

        ret = gdxcc.gdxOpenWrite(self.H, filename, "gdxpds")
        if not ret:
            raise GdxError(
                self.H,
                "Could not open {} for writing. Consider cloning this file (.clone()) before trying to write"
                .format(repr(filename)))
        self._filename = filename

        # set special values
        ret = gdxcc.gdxSetSpecialValues(self.H, self.special_values)
        if ret == 0:
            raise GdxError(self.H, "Unable to set special values")

        # write the universal set
        self.universal_set.write()

        for i, symbol in enumerate(self, start=1):
            try:
                symbol.write(index=i)
            except:
                logger.error("Unable to write {} to {}".format(
                    symbol, filename))
                raise

        gdxcc.gdxClose(self.H)
예제 #2
0
    def read_symbol(self, symbol_name):
        if not (self.lazy_load and self.filename):
            raise RuntimeError(
                """This feature only works if the gdxdict is initialized in 
                               lazy_load mode, and read has already been called."""
            )
        if not symbol_name in self:
            raise RuntimeError(
                "{} is not a symbol in this gdxdict.".format(symbol_name))

        H = gdxx.open(self.gams_dir)
        assert gdxcc.gdxOpenRead(
            H, self.filename)[0], "Couldn't open %s" % filename

        sinfo = self.getinfo(symbol_name)
        set_map = self.set_map
        all_keys = self.all_keys

        self.__read_one_symbol(H, sinfo, all_keys)

        gdxcc.gdxClose(H)
        gdxcc.gdxFree(H)

        guess_domains(self, set_map, all_keys)
        guess_ancestor_domains(self)
        self.set_map = set_map
        self.all_keys = all_keys
예제 #3
0
def write_variables(config, gdx_out, list_vars):
    """
    This function performs the following:
    * Use the gdxcc library to create a gdxHandle instance
    * Check that the gams path is well defined
    * Call the 'insert_symbols' function to write all sets and parameters to gdxHandle

    :param config:          Main config dictionary
    :param gdx_out:         (Relative) path to the gdx file to be written
    :param list_vars:       List with the sets and parameters to be written
    """
    gams_dir = get_gams_path(gams_dir=config['GAMS_folder'].encode())
    if not gams_dir:  # couldn't locate
        logging.critical(
            'GDXCC: Could not find the specified gams directory: ' + gams_dir)
        sys.exit(1)
    gams_dir = force_str(gams_dir)
    config['GAMS_folder'] = gams_dir  # updating the config dictionary
    gdx_out = force_str(gdx_out)

    gdxHandle = gdxcc.new_gdxHandle_tp()
    gdxcc.gdxCreateD(gdxHandle, gams_dir,
                     gdxcc.GMS_SSSIZE)  #it accepts only str type
    gdxcc.gdxOpenWrite(gdxHandle, gdx_out, "")

    [sets, parameters] = list_vars
    _insert_symbols(gdxHandle, sets, parameters)

    gdxcc.gdxClose(gdxHandle)

    logging.info('Data Successfully written to ' + gdx_out)
예제 #4
0
파일: gdxdict.py 프로젝트: NREL/gdx-pandas
        for i in range(records):
            ok, elements, values, afdim = gdxcc.gdxDataReadStr(H)
            if not ok: raise gdxx.GDX_error(H, "Error in gdxDataReadStr")
            if sinfo["dims"] == 0:
                read_symbol(H, self, symbol_name, sinfo["typename"], values)
            else:
                for d in range(sinfo["dims"]-1):
                    key = elements[d]
                    keys[d][key] = True
                    if (len(current_list) < d+2) or (current_list[d+1][0] != key):
                        current_list = current_list[0:d+1]
                        if not key in current_list[d][1]:
                            num_dims_created += 1
                            current_list[d][1][key] = gdxdim(self)
                        current_list = current_list + [(key, current_list[d][1][key])]
                d = sinfo["dims"]-1
                key = elements[d]
                keys[d][key] = True
                read_symbol(H, current_list[d][1], key, sinfo["typename"], values)
        logger.debug("Created {} gdxdims for {} records (ratio = {}). len(current_list) = {}".format(
            num_dims_created, records, float(num_dims_created)/float(records), len(current_list)))

#- Write a GDX file ------------------------------------------------------------

    def write(self, filename, gams_dir=None):
        H = gdxx.open(gams_dir)
        assert gdxcc.gdxOpenWrite(H, filename, "gdxdict.py")[0], "Couldn't open %s" % filename

        # write the universal set
        gdxcc.gdxUELRegisterRawStart(H)
        for key, key_data in self.universal_items():
예제 #5
0
def write_variables(gams_dir, gdx_out, list_vars):
    """
    This function performs the following:
    * Use the gdxcc library to create a gdxHandle instance
    * Check that the gams path is well defined
    * Call the 'insert_symbols' function to write all sets and parameters to gdxHandle

    :param gams_dir:        (Relative) path to the gams directory
    :param gdx_out:         (Relative) path to the gdx file to be written
    :param list_vars:       List with the sets and parameters to be written
    """
    if not os.path.isdir(gams_dir):
        gams_dir = get_gams_path()
    if not os.path.isdir(gams_dir):
        logging.critical(
            'GDXCC: Could not find the specified gams directory: ' + gams_dir)
        sys.exit(1)
    gams_dir = gams_dir.encode()

    gdxHandle = gdxcc.new_gdxHandle_tp()
    gdxcc.gdxCreateD(gdxHandle, gams_dir, gdxcc.GMS_SSSIZE)
    gdxcc.gdxOpenWrite(gdxHandle, gdx_out, "")

    [sets, parameters] = list_vars
    _insert_symbols(gdxHandle, sets, parameters)

    gdxcc.gdxClose(gdxHandle)

    logging.info('Data Successfully written to ' + gdx_out)
예제 #6
0
def get_df(file_name, param_name):
    ws = gams.GamsWorkspace()

    gdxFile = os.path.join(os.getcwd(), file_name)

    gdxHandle = gdxcc.new_gdxHandle_tp()
    rc =  gdxcc.gdxCreate(gdxHandle, gdxcc.GMS_SSSIZE)
    assert rc[0],rc[1]
    assert gdxcc.gdxOpenRead(gdxHandle, gdxFile)[0]
    nrUels = gdxcc.gdxUMUelInfo(gdxHandle)[1]
    uelMap = []

    for i in range(nrUels+1):
        uelMap.append(gdxcc.gdxUMUelGet(gdxHandle, i)[1])
    ret, symNr = gdxcc.gdxFindSymbol(gdxHandle, param_name)
    assert ret, param_name + " parameter not found"
    ret, nrRecs = gdxcc.gdxDataReadRawStart(gdxHandle, symNr)
    assert ret, "Error in gdxDataReadRawStart: " + gdxcc.gdxErrorStr(gdxHandle, gdxcc.gdxGetLastError(gdxHandle))[1]

    ls = []
    for i in range(nrRecs):
        ret = gdxcc.gdxDataReadRaw(gdxHandle)
        sets = [uelMap[x] for x in ret[1]]
        val = ret[2][gdxcc.GMS_VAL_LEVEL]
        if val == 5e300:
            val = 0
        ls.append(sets+[val])

    assert not gdxcc.gdxClose(gdxHandle)
    assert gdxcc.gdxFree(gdxHandle)
    df = pd.DataFrame(ls)
    return df
예제 #7
0
    def write(self, filename, gams_dir=None):
        H = gdxx.open(gams_dir)
        assert gdxcc.gdxOpenWrite(
            H, filename, "gdxdict.py")[0], "Couldn't open %s" % filename

        # write the universal set
        gdxcc.gdxUELRegisterRawStart(H)
        for key, key_data in self.universal_items():
            gdxcc.gdxUELRegisterRaw(H, key_data['name'])
        gdxcc.gdxUELRegisterDone(H)

        for k in self:
            symbol = self[k]
            info = self.getinfo(k)
            if info["dims"] == 0:
                if not gdxcc.gdxDataWriteStrStart(
                        H, k, info["description"], 0,
                        get_type_code(info["typename"]), info["userinfo"]):
                    raise gdxx.GDX_error(H, "couldn't start writing data")
                set_symbol(H, self, k, info["typename"], info["userinfo"],
                           values, [])
                gdxcc.gdxDataWriteDone(H)
            else:
                if not gdxcc.gdxDataWriteStrStart(
                        H, k, info["description"], info["dims"],
                        get_type_code(info["typename"]), info["userinfo"]):
                    raise gdxx.GDX_error(H, "couldn't start writing data")
                domain = []
                for d in info["domain"]:
                    domain.append(d["key"])
                if gdxcc.gdxSymbolSetDomain(H, domain) != 1:
                    raise gdxx.GDX_error(
                        H, "couldn't set domain for symbol %s to %s" %
                        (k, domain))
                write_symbol(H, info["typename"], info["userinfo"], symbol, [])
                gdxcc.gdxDataWriteDone(H)

        gdxcc.gdxClose(H)
        gdxcc.gdxFree(H)
예제 #8
0
파일: gdxdict.py 프로젝트: NREL/gdx-pandas
                continue
                
            logger.debug("Reading {}. ".format(sinfo['name']) + gdxpds.memory_use_str())
            self.__read_one_symbol(H, sinfo, all_keys)
            logger.debug("Read {}. ".format(sinfo['name']) + gdxpds.memory_use_str())

        gdxcc.gdxClose(H)
        gdxcc.gdxFree(H)
        
        logger.debug("Closed the gdx file. " + gdxpds.memory_use_str())

        guess_domains(self, set_map, all_keys)
        guess_ancestor_domains(self)
        
        logger.debug("Finished guessing domains. " + gdxpds.memory_use_str())
        if self.lazy_load:
            self.set_map = set_map
            self.all_keys = all_keys
        
    def read_symbol(self, symbol_name):
        if not (self.lazy_load and self.filename):
            raise RuntimeError("""This feature only works if the gdxdict is initialized in 
                               lazy_load mode, and read has already been called.""")
예제 #9
0
def test_roundtrip_just_special_values(manage_rundir):
    outdir = os.path.join(run_dir,'special_values')
    if not os.path.exists(outdir):
        os.mkdir(outdir)
    # create gdx file containing all special values
    with gdxpds.gdx.GdxFile() as f:
        df = pds.DataFrame([['sv' + str(i+1), f.special_values[i]] for i in range(gdxcc.GMS_SVIDX_MAX-2)],
                           columns=['sv','Value'])
        logger.info("Special values are:\n{}".format(df))

        # save this directly as a GdxSymbol
        filename = os.path.join(outdir,'direct_write_special_values.gdx')
        ret = gdxcc.gdxOpenWrite(f.H,filename,"gdxpds")
        if not ret:
            raise gdxpds.gdx.GdxError(f.H,"Could not open {} for writing. Consider cloning this file (.clone()) before trying to write".format(repr(filename)))
        # set special values
        ret = gdxcc.gdxSetSpecialValues(f.H,f.special_values)
        if ret == 0:
            raise gdxpds.gdx.GdxError(f.H,"Unable to set special values")
        # write the universal set
        f.universal_set.write()
        if not gdxcc.gdxDataWriteStrStart(f.H,
                                          'special_values',
                                          '',
                                          1,
                                          gdxpds.gdx.GamsDataType.Parameter.value,
                                          0):
            raise gdxpds.gdx.GdxError(f.H,"Could not start writing data for symbol special_values")
        # set domain information
        if not gdxcc.gdxSymbolSetDomainX(f.H,1,[df.columns[0]]):
            raise gdxpds.gdx.GdxError(f.H,"Could not set domain information for special_values.")
        values = gdxcc.doubleArray(gdxcc.GMS_VAL_MAX)
        for row in df.itertuples(index=False,name=None):
            dims = [str(x) for x in row[:1]]
            vals = row[1:]
            for col_name, col_ind in gdxpds.gdx.GAMS_VALUE_COLS_MAP[gdxpds.gdx.GamsDataType.Parameter]:
                values[col_ind] = float(vals[col_ind])
            gdxcc.gdxDataWriteStr(f.H,dims,values)
        gdxcc.gdxDataWriteDone(f.H)
        gdxcc.gdxClose(f.H)

    # general test for expected values
    def check_special_values(gdx_file):
        df = gdx_file['special_values'].dataframe
        for i, val in enumerate(df['Value'].values):
            assert gdxpds.gdx.gdx_val_equal(gdx_file.np_to_gdx_svs[i],gdx_file.special_values[i],gdx_file)

    # now roundtrip it gdx-only
    with gdxpds.gdx.GdxFile(lazy_load=False) as f:
        f.read(filename)
        check_special_values(f)
        with f.clone() as g:
            rt_filename = os.path.join(outdir,'roundtripped.gdx')
            g.write(rt_filename)
    with gdxpds.gdx.GdxFile(lazy_load=False) as g:
        g.read(filename)
        check_special_values(g)

    # now roundtrip it through csv
    roundtripped_gdx = roundtrip_one_gdx(filename,'roundtrip_just_special_values')
    with gdxpds.gdx.GdxFile(lazy_load=False) as h:
        h.read(roundtripped_gdx)
        check_special_values(h)
예제 #10
0
    def read(self, filename, gams_dir=None):
        if self.lazy_load:
            self.filename = filename
            self.gams_dir = gams_dir

        H = gdxx.open(gams_dir)
        assert gdxcc.gdxOpenRead(H, filename)[0], "Couldn't open %s" % filename

        logger.debug("Opened the file. " + gdxpds.memory_use_str())

        info = gdxx.file_info(H)
        for k in info:
            if not k in self.file_info:
                self.file_info[k] = info[k]

        logger.debug("Retrieved the file info. " + gdxpds.memory_use_str())

        # read the universal set
        uinfo = gdxx.symbol_info(H, 0)
        for k in uinfo:
            if not k in self.universal_info:
                self.universal_info[k] = uinfo[k]

        logger.debug("Read the universal set. " + gdxpds.memory_use_str())

        ok, records = gdxcc.gdxDataReadStrStart(H, 0)
        for i in range(records):
            ok, elements, values, afdim = gdxcc.gdxDataReadStr(H)
            if not ok: raise gdxx.GDX_error(H, "Error in gdxDataReadStr")
            key = elements[0]
            ret, description, node = gdxcc.gdxGetElemText(
                H, int(values[gdxcc.GMS_VAL_LEVEL]))
            if ret == 0: description = None
            self.add_key(key, description)

        all_keys = {}

        # Read all the 1-D sets
        # Map backwards so we have a map from every set key back to all the sets it's in
        set_map = {}
        for i in range(1, info["symbol_count"] + 1):
            sinfo = gdxx.symbol_info(H, i)
            if sinfo["typename"] == "Set" and sinfo["dims"] == 1:

                self.add_symbol(sinfo)
                symbol_name = sinfo["name"]
                all_keys[symbol_name] = [{}]
                keys = all_keys[symbol_name]
                symbol = self[symbol_name]
                symbol._gdxdim__read_in = True
                ok, records = gdxcc.gdxDataReadStrStart(H, i)
                for i in range(records):
                    ok, elements, values, afdim = gdxcc.gdxDataReadStr(H)
                    if not ok:
                        raise gdxx.GDX_error(H, "Error in gdxDataReadStr")
                    e = elements[0]
                    read_symbol(H, symbol, e, sinfo["typename"], values)
                    if not e in set_map: set_map[e] = {}
                    set_map[e][symbol_name] = True
                    keys[0][e] = True

        # Read all the other symbols
        for i in range(1, info["symbol_count"] + 1):
            sinfo = gdxx.symbol_info(H, i)
            if sinfo["typename"] == "Set" and sinfo["dims"] == 1: continue

            self.add_symbol(sinfo)
            if self.lazy_load and sinfo["dims"] > 0:
                continue

            logger.debug("Reading {}. ".format(sinfo['name']) +
                         gdxpds.memory_use_str())
            self.__read_one_symbol(H, sinfo, all_keys)
            logger.debug("Read {}. ".format(sinfo['name']) +
                         gdxpds.memory_use_str())

        gdxcc.gdxClose(H)
        gdxcc.gdxFree(H)

        logger.debug("Closed the gdx file. " + gdxpds.memory_use_str())

        guess_domains(self, set_map, all_keys)
        guess_ancestor_domains(self)

        logger.debug("Finished guessing domains. " + gdxpds.memory_use_str())
        if self.lazy_load:
            self.set_map = set_map
            self.all_keys = all_keys
예제 #11
0
 def close(self):
     h = self.gdxHandle
     gdxcc.gdxClose(h)
     gdxcc.gdxFree(h)
예제 #12
0
파일: gdxpy.py 프로젝트: jackjackk/gdxpy
 def close(self):
     '''Close Gdx file and free up resources.'''
     h = self.gdx_handle
     gdxcc.gdxClose(h)
     gdxcc.gdxFree(h)
예제 #13
0
파일: gdxdict.py 프로젝트: NREL/gdx-pandas
            
        info["type"] = typecode
        info["typename"] = typename


# -- Read a gdx file -----------------------------------------------------------

    def read(self, filename, gams_dir=None):
        if self.lazy_load:
            self.filename = filename
            self.gams_dir = gams_dir
    
        H = gdxx.open(gams_dir)
        assert gdxcc.gdxOpenRead(H, filename)[0], "Couldn't open %s" % filename
        
        logger.debug("Opened the file. " + gdxpds.memory_use_str())

        info = gdxx.file_info(H)
        for k in info:
            if not k in self.file_info:
                self.file_info[k] = info[k]
                
        logger.debug("Retrieved the file info. " + gdxpds.memory_use_str())

        # read the universal set
        uinfo = gdxx.symbol_info(H, 0)
        for k in uinfo:
            if not k in self.universal_info: 
                self.universal_info[k] = uinfo[k]

        logger.debug("Read the universal set. " + gdxpds.memory_use_str())
                
        ok, records = gdxcc.gdxDataReadStrStart(H, 0)        
        for i in range(records):
            ok, elements, values, afdim = gdxcc.gdxDataReadStr(H)
            if not ok: raise gdxx.GDX_error(H, "Error in gdxDataReadStr")
            key = elements[0]
            ret, description, node = gdxcc.gdxGetElemText(H, int(values[gdxcc.GMS_VAL_LEVEL]))
            if ret == 0: description = None
            self.add_key(key, description)
        
        all_keys = {}

        # Read all the 1-D sets
        # Map backwards so we have a map from every set key back to all the sets it's in
        set_map = {}
        for i in range(1, info["symbol_count"]+1):
            sinfo = gdxx.symbol_info(H, i)
            if sinfo["typename"] == "Set" and sinfo["dims"] == 1:

                self.add_symbol(sinfo)
                symbol_name = sinfo["name"]
                all_keys[symbol_name] = [{}]
                keys = all_keys[symbol_name]
                symbol = self[symbol_name]
                symbol._gdxdim__read_in = True
                ok, records = gdxcc.gdxDataReadStrStart(H, i)
                for i in range(records):
                    ok, elements, values, afdim = gdxcc.gdxDataReadStr(H)
                    if not ok: raise gdxx.GDX_error(H, "Error in gdxDataReadStr")
                    e = elements[0]
                    read_symbol(H, symbol, e, sinfo["typename"], values)
                    if not e in set_map: set_map[e] = {}
                    set_map[e][symbol_name] = True
                    keys[0][e] = True
        
        # Read all the other symbols
        for i in range(1, info["symbol_count"]+1):
            sinfo = gdxx.symbol_info(H, i)
            if sinfo["typename"] == "Set" and sinfo["dims"] == 1: continue

            self.add_symbol(sinfo)
예제 #14
0
파일: gdxdict.py 프로젝트: djhume/py-gdx
    def read(self, filename, gams_dir=None):
        H = gdxx.open(gams_dir)
        assert gdxcc.gdxOpenRead(H, filename)[0], "Couldn't open %s" % filename

        info = gdxx.file_info(H)
        for k in info:
            if not k in self.file_info:
                self.file_info[k] = info[k]

        # read the universal set
        uinfo = gdxx.symbol_info(H, 0)
        for k in uinfo:
            if not k in self.universal_info: 
                self.universal_info[k] = uinfo[k]

        ok, records = gdxcc.gdxDataReadStrStart(H, 0)        
        for i in range(records):
            ok, elements, values, afdim = gdxcc.gdxDataReadStr(H)
            if not ok: raise gdxx.GDX_error(H, "Error in gdxDataReadStr")
            key = elements[0]
            ret, description, node = gdxcc.gdxGetElemText(H, int(values[gdxcc.GMS_VAL_LEVEL]))
            if ret == 0: description = None
            self.add_key(key, description)

        all_keys = {}

        # Read all the 1-D sets
        # Map backwards so we have a map from every set key back to all the sets it's in
        set_map = {}
        for i in range(1, info["symbol_count"]+1):
            sinfo = gdxx.symbol_info(H, i)
            if sinfo["typename"] == "Set" and sinfo["dims"] == 1:

                self.add_symbol(sinfo)
                symbol_name = sinfo["name"]
                all_keys[symbol_name] = [{}]
                keys = all_keys[symbol_name]
                symbol = self[symbol_name]
                ok, records = gdxcc.gdxDataReadStrStart(H, i)
                for i in range(records):
                    ok, elements, values, afdim = gdxcc.gdxDataReadStr(H)
                    if not ok: raise gdxx.GDX_error(H, "Error in gdxDataReadStr")
                    e = elements[0]
                    read_symbol(H, symbol, e, sinfo["typename"], values)
                    if not e in set_map: set_map[e] = {}
                    set_map[e][symbol_name] = True
                    keys[0][e] = True

        # Read all the other symbols
        for i in range(1, info["symbol_count"]+1):

            sinfo = gdxx.symbol_info(H, i)
            if sinfo["typename"] == "Set" and sinfo["dims"] == 1: continue

            self.add_symbol(sinfo)
            symbol_name = sinfo["name"]
            all_keys[symbol_name] = []
            keys = all_keys[symbol_name]
            for d in range(sinfo["dims"]): keys.append({})

            ok, records = gdxcc.gdxDataReadStrStart(H, i)
        
            for i in range(records):
                ok, elements, values, afdim = gdxcc.gdxDataReadStr(H)
                if not ok: raise gdxx.GDX_error(H, "Error in gdxDataReadStr")
                if sinfo["dims"] == 0:
                    read_symbol(H, self, symbol_name, sinfo["typename"], values)
                else:
                    symbol = self[sinfo["name"]]
                    current = symbol
                    for d in range(sinfo["dims"]-1):
                        key = elements[d]
                        keys[d][key] = True
                        if not key in current:
                            current[key] = gdxdim(self)
                        current = current[key]
                    d = sinfo["dims"]-1
                    key = elements[d]
                    keys[d][key] = True
                    read_symbol(H, current, key, sinfo["typename"], values)

        gdxcc.gdxClose(H)
        gdxcc.gdxFree(H)

        guess_domains(self, set_map, all_keys)
        guess_ancestor_domains(self)
예제 #15
0
파일: gdxfile.py 프로젝트: rusty-s/GDX2py
 def close(self):
     gdxcc.gdxClose(self._h)
예제 #16
0
    
        # Write a set:
        dims = 1
        setname = 'set_test'
        keys = ['aa']
        gdxcc.gdxDataWriteStrStart(gdxHandle, setname, "", dims, gdxcc.GMS_DT_SET, 0)
        gdxValues = gdxcc.doubleArray(5)
        gdxValues[gdxcc.GMS_VAL_LEVEL] = 0.0  # 0.0 == Y (explanatory text of set in gdx)
    
        try:
            success = gdxcc.gdxDataWriteStr(gdxHandle, keys, gdxValues)
        except Exception as e:
            success = False
            print('ERROR: the set could not be written to the gdx file. Error msg: ' + str(e))
        gdxcc.gdxDataWriteDone(gdxHandle)
        gdxcc.gdxClose(gdxHandle)
    except Exception as ee:
        print('ERROR: the gdxfile could not be created. Error msg: ' + str(ee))
        success = False
    if success and os.path.isfile('test.gdx'):
        print('GDX successfully written. Cleaning up')
        os.remove('test.gdx')




print('\n \nCHECK PYOMO')
try:
    import pyomo
    print('Pyomo is available')
except Exception as e:
예제 #17
0
    def read(self, filename, gams_dir=None):
        H = gdxx.open(gams_dir)
        assert gdxcc.gdxOpenRead(H, filename)[0], "Couldn't open %s" % filename

        info = gdxx.file_info(H)
        for k in info:
            if not k in self.file_info:
                self.file_info[k] = info[k]

        # read the universal set
        uinfo = gdxx.symbol_info(H, 0)
        for k in uinfo:
            if not k in self.universal_info:
                self.universal_info[k] = uinfo[k]

        ok, records = gdxcc.gdxDataReadStrStart(H, 0)
        for i in range(records):
            ok, elements, values, afdim = gdxcc.gdxDataReadStr(H)
            if not ok: raise gdxx.GDX_error(H, "Error in gdxDataReadStr")
            key = elements[0]
            ret, description, node = gdxcc.gdxGetElemText(
                H, int(values[gdxcc.GMS_VAL_LEVEL]))
            if ret == 0: description = None
            self.add_key(key, description)

        all_keys = {}

        # Read all the 1-D sets
        # Map backwards so we have a map from every set key back to all the sets it's in
        set_map = {}
        for i in range(1, info["symbol_count"] + 1):
            sinfo = gdxx.symbol_info(H, i)
            if sinfo["typename"] == "Set" and sinfo["dims"] == 1:

                self.add_symbol(sinfo)
                symbol_name = sinfo["name"]
                all_keys[symbol_name] = [{}]
                keys = all_keys[symbol_name]
                symbol = self[symbol_name]
                ok, records = gdxcc.gdxDataReadStrStart(H, i)
                for i in range(records):
                    ok, elements, values, afdim = gdxcc.gdxDataReadStr(H)
                    if not ok:
                        raise gdxx.GDX_error(H, "Error in gdxDataReadStr")
                    e = elements[0]
                    read_symbol(H, symbol, e, sinfo["typename"], values)
                    if not e in set_map: set_map[e] = {}
                    set_map[e][symbol_name] = True
                    keys[0][e] = True

        # Read all the other symbols
        for i in range(1, info["symbol_count"] + 1):

            sinfo = gdxx.symbol_info(H, i)
            if sinfo["typename"] == "Set" and sinfo["dims"] == 1: continue

            self.add_symbol(sinfo)
            symbol_name = sinfo["name"]
            all_keys[symbol_name] = []
            keys = all_keys[symbol_name]
            for d in range(sinfo["dims"]):
                keys.append({})

            ok, records = gdxcc.gdxDataReadStrStart(H, i)

            for i in range(records):
                ok, elements, values, afdim = gdxcc.gdxDataReadStr(H)
                if not ok: raise gdxx.GDX_error(H, "Error in gdxDataReadStr")
                if sinfo["dims"] == 0:
                    read_symbol(H, self, symbol_name, sinfo["typename"],
                                values)
                else:
                    symbol = self[sinfo["name"]]
                    current = symbol
                    for d in range(sinfo["dims"] - 1):
                        key = elements[d]
                        keys[d][key] = True
                        if not key in current:
                            current[key] = gdxdim(self)
                        current = current[key]
                    d = sinfo["dims"] - 1
                    key = elements[d]
                    keys[d][key] = True
                    read_symbol(H, current, key, sinfo["typename"], values)

        gdxcc.gdxClose(H)
        gdxcc.gdxFree(H)

        guess_domains(self, set_map, all_keys)
        guess_ancestor_domains(self)