def load(self): if self.loaded: logger.info("Nothing to do. Symbol already loaded.") return if not self.file: raise Error( "Cannot load {} because there is no file pointer".format( repr(self))) if not self.index: raise Error( "Cannot load {} because there is no symbol index".format( repr(self))) if self.data_type == GamsDataType.Parameter and HAVE_GDX2PY: self.dataframe = gdx2py.par2list(self.file.filename, self.name) self._loaded = True return data = [] ret, records = gdxcc.gdxDataReadStrStart(self.file.H, self.index) for i in range(records): ret, elements, values, afdim = gdxcc.gdxDataReadStr(self.file.H) # make sure we pick value columns up correctly data.append( elements + [values[col_ind] for col_name, col_ind in self.value_cols]) if self.data_type == GamsDataType.Set: data[-1][-1] = True # gdxdict called gdxGetElemText here, but I do not currently see value in doing that self.dataframe = data if not self.data_type == GamsDataType.Set: self.dataframe = convert_gdx_to_np_svs(self.dataframe, self.num_dims, self.file) self._loaded = True return
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 def __read_one_symbol(self, H, sinfo, all_keys): 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, sinfo["number"]) symbol = self[symbol_name] if isinstance(symbol, gdxdim): symbol._gdxdim__read_in = True
def dump_GDX_file(H, filename): assert gdxcc.gdxOpenRead(H, filename)[0], "Couldn't open %s" % filename info = gdxx.file_info(H) print "* File Version : %s" % info["version"] print "* Producer : %s" % info["producer"] print "* Symbols : %d" % info["symbol_count"] print "* Unique Elements: %d" % info["element_count"] print "$ontext" for i in range(1, info["symbol_count"] + 1): sinfo = gdxx.symbol_info(H, i) print "%-15s %3d %-12s %s" % (sinfo["name"], sinfo["dims"], sinfo["typename"], sinfo["description"]) print "$offtext\n$onempty onembedded" for i in range(1, info["symbol_count"] + 1): sinfo = gdxx.symbol_info(H, i) name = "%s %s" % (sinfo["full_typename"], sinfo["name"]) dim_string = "" if sinfo["dims"] > 0: dim_string = "(" for j in sinfo["domain"]: if j["index"] > 0: dim_string += "," d = sinfo["domain"][j["index"]] dim_string += d["key"] dim_string += ")" desc = sinfo["description"] sm = '"' if "'" in desc else "'" print "%s%s %s%s%s /" % (name, dim_string, sm, desc, sm) ok, records = gdxcc.gdxDataReadStrStart(H, i) for i in range(records): ok, elements, values, afdim = gdxcc.gdxDataReadStr(H) if not ok: raise GDX_error(H, "Error in gdxDataReadStr") if values[gdxcc.GMS_VAL_LEVEL] == 0: continue dim_string = "" for d in range(sinfo["dims"]): if d > 0: dim_string += "." dim_string += "'%s'" % elements[d] value_string = "" if sinfo["type"] == gdxcc.GMS_DT_PAR or sinfo["type"] == gdxcc.GMS_DT_VAR: value_string = "%g" % values[gdxcc.GMS_VAL_LEVEL] if sinfo["type"] == gdxcc.GMS_DT_SET: ret, description, node = gdxcc.gdxGetElemText(H, int(values[gdxcc.GMS_VAL_LEVEL])) if ret != 0: sm = '"' if "'" in description else "'" value_string = "%s%s%s" % (sm, description, sm) print "%s %s" % (dim_string, value_string) print "/;\n"
def res_1(nrRecs): """ Returns res :param nrRecs: :return: """ res = [] for i in range(nrRecs): ret, elements, values, afdim = gdxDataReadStr(gdxHandle) res.append(elements + [values[0]]) return res
def dump_GDX_file(H, filename): assert gdxcc.gdxOpenRead(H, filename)[0], "Couldn't open %s" % filename info = gdxx.file_info(H) print "* File Version : %s" % info["version"] print "* Producer : %s" % info["producer"] print "* Symbols : %d" % info["symbol_count"] print "* Unique Elements: %d" % info["element_count"] print "$ontext" for i in range(1, info["symbol_count"]+1): sinfo = gdxx.symbol_info(H, i) print "%-15s %3d %-12s %s" % (sinfo["name"], sinfo["dims"], sinfo["typename"], sinfo["description"]) print "$offtext\n$onempty onembedded" for i in range(1, info["symbol_count"]+1): sinfo = gdxx.symbol_info(H, i) name = "%s %s" % (sinfo["full_typename"], sinfo["name"]) dim_string = "" if sinfo["dims"] > 0: dim_string = "(" for j in sinfo["domain"]: if j["index"] > 0: dim_string += "," d = sinfo["domain"][j["index"]] dim_string += d["key"] dim_string += ")" desc = sinfo["description"] sm = '"' if "'" in desc else "'" print "%s%s %s%s%s /" % (name, dim_string, sm, desc, sm) ok, records = gdxcc.gdxDataReadStrStart(H, i) for i in range(records): ok, elements, values, afdim = gdxcc.gdxDataReadStr(H) if not ok: raise GDX_error(H, "Error in gdxDataReadStr") if values[gdxcc.GMS_VAL_LEVEL] == 0: continue dim_string = "" for d in range(sinfo["dims"]): if d > 0: dim_string += "." dim_string += "'%s'" % elements[d] value_string = "" if sinfo["type"] == gdxcc.GMS_DT_PAR or sinfo["type"] == gdxcc.GMS_DT_VAR: value_string = "%g" % values[gdxcc.GMS_VAL_LEVEL] if sinfo["type"] == gdxcc.GMS_DT_SET: ret, description, node = gdxcc.gdxGetElemText(H, int(values[gdxcc.GMS_VAL_LEVEL])) if ret != 0: sm = '"' if "'" in description else "'" value_string = "%s%s%s" % (sm, description, sm) print "%s %s" % (dim_string, value_string) print "/;\n"
def __read_one_symbol(self, H, sinfo, all_keys): 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, sinfo["number"]) symbol = self[symbol_name] if isinstance(symbol, gdxdim): symbol._gdxdim__read_in = True current_list = [(symbol_name, symbol)] num_dims_created = 0 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) if records else 0, len(current_list)))
def gdx_to_list(gams_dir, filename, varname='all', verbose=False): """ This function loads the gdx with the results of the simulation All results are stored in an unordered list :param gams_dir: Gams working directory :param filename: Path to the gdx file to be read :param varname: In case online one variable is needed, specify it name (otherwise specify 'all') :returns: Dictionary with all the collected values (within lists) """ from gdxcc import gdxSymbolInfo, gdxCreateD, gdxOpenRead, GMS_SSSIZE, gdxDataReadDone, new_gdxHandle_tp, \ gdxDataReadStr, gdxFindSymbol, gdxErrorStr, gdxDataReadStrStart, gdxGetLastError out = {} tgdx = tm.time() gdxHandle = new_gdxHandle_tp() gdxCreateD(gdxHandle, gams_dir, GMS_SSSIZE) # make sure the file path is properly formatted: filename = filename.replace('/', os.path.sep).replace( '\\\\', os.path.sep).replace('\\', os.path.sep) filename = str(filename) # removing possible unicode formatting if not os.path.isfile(filename): logging.critical('Gdx file "' + filename + '" does not exist') sys.exit(1) gdxOpenRead(gdxHandle, filename) if varname == 'all': # go through all the symbols one by one and add their data to the dict symNr = 0 SymbolInfo = gdxSymbolInfo(gdxHandle, 0) while SymbolInfo[0] > 0: ret, nrRecs = gdxDataReadStrStart(gdxHandle, symNr) assert ret, "Error in gdx data string" + gdxErrorStr( gdxHandle, gdxGetLastError(gdxHandle))[1] res = [] for i in range(nrRecs): ret, elements, values, afdim = gdxDataReadStr(gdxHandle) res.append(elements + [values[0]]) out[SymbolInfo[1]] = res symNr += 1 SymbolInfo = gdxSymbolInfo(gdxHandle, symNr) else: # find the number of the required symbol: ret, symNr = gdxFindSymbol(gdxHandle, varname) assert ret, "Symbol not found" ret, nrRecs = gdxDataReadStrStart(gdxHandle, symNr) assert ret, "Error in gdx data string" + gdxErrorStr( gdxHandle, gdxGetLastError(gdxHandle))[1] res = [] for i in range(nrRecs): ret, elements, values, afdim = gdxDataReadStr(gdxHandle) res.append(elements + [values[0]]) out[varname] = res gdxDataReadDone(gdxHandle) if verbose: logging.info("Loading gdx file " + filename + " took {}s".format(tm.time() - tgdx)) return out
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
def query(self, name, reshape=RESHAPE_DEFAULT, gamsdir=None, filt=None, idval=None): if __gdxpy_mode__ == GDX_MODE_API: gdxHandle = self.gdxHandle ret, symNr = gdxcc.gdxFindSymbol(gdxHandle, name) assert ret, "Symbol '%s' not found in GDX '%s'" % (name,self.internal_filename) sinfo = self.get_sid_info(symNr) dim = sinfo['dim'] # assert dim>0, "Symbol '%s' is a scalar, not supported" % (name) symType = sinfo['stype'] ret, nrRecs = gdxcc.gdxDataReadStrStart(gdxHandle, symNr) assert ret, "Error in gdxDataReadStrStart: "+gdxcc.gdxErrorStr(gdxHandle,gdxGetLastError(gdxHandle))[1] if idval is None: if symType == gdxcc.GMS_DT_EQU: idval = gdxcc.GMS_VAL_MARGINAL else: idval = gdxcc.GMS_VAL_LEVEL ifilt = None vtable = [] rcounter = 0 rowtype = None if filt != None: if isinstance(filt,list): filt = '^({0})$'.format('|'.join([re.escape(x) for x in filt])) filt_regex = re.compile(filt, re.IGNORECASE) for i in range(nrRecs): vrow = [None]*(dim+1) ret, elements, values, afdim = gdxcc.gdxDataReadStr(gdxHandle) assert ret, "Error in gdxDataReadStr: "+gdxcc.gdxErrorStr(gdxHandle,gdxGetLastError(gdxHandle))[1] if (filt != None): match_filt = False for e in elements: m = filt_regex.match(e) if m != None: match_filt = True break if not match_filt: continue d = -1 for d in range(dim): try: vrow[d] = int(elements[d]) except: vrow[d] = elements[d].lower() vrow[d+1] = values[idval] vtable.append(vrow) rcounter += 1 gdxcc.gdxDataReadDone(gdxHandle) # ifilt = 1 cols = ['s%d' % x for x in range(dim)]+['val',] #print vtable[:5] #print cols df = pd.DataFrame(vtable,columns=cols) #print df #if ifilt != None: # df = df.drop(df.columns[ifilt], axis=1) #print "%d / %d records read from <%s>" % (rcounter, nrRecs, self.internal_filename) elif __gdxpy_mode__ == GDX_MODE_SHELL: cmdline = r'gdxdump.exe {0} symb={1} Format=csv NoHeader'.format(self.internal_filename, name) p = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) # TODO check for return code # p = subprocess.Popen(cmdline +' | tr "[:upper:]" "[:lower:]"', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) strdata = p.communicate()[0] #.replace("'.","',").replace(', \r\n','\r\n').replace(" ",",") sepchar = ',' strdata = strdata.replace('eps','1e-16') csvfile = StringIO.StringIO(strdata) #print strdata[:500] df = pd.read_csv(csvfile,sep=sepchar,quotechar='"',prefix='s',header=None,error_bad_lines=False).dropna() else: raise Exception('Function "get_symbols_list" not available outside GDX API/SHELL mode') #raise e, None, sys.exc_info()[2] #print_traceback(e) #print df.columns.values #print df.columns.values[-1], list(df.columns.values[:-2]), df.columns.values[-2] #print df if symType == gdxcc.GMS_DT_SET: reshape = RESHAPE_SERIES df = dfreshape(df, reshape) if symType == gdxcc.GMS_DT_SET: df = df.index self.data = df return df
def query(self, name, reshape=RESHAPE_DEFAULT, filt=None, idval=None, idxlower=True): ''' Query attribute `idval` from symbol `name`, and return a data structure shaped according to `reshape`. ''' gdx_handle = self.gdx_handle ret, symNr = gdxcc.gdxFindSymbol(gdx_handle, name) assert ret, "Symbol '%s' not found in GDX '%s'" % (name, self.internal_filename) sinfo = self.get_sid_info(symNr) dim = sinfo['dim'] symType = sinfo['stype'] ret, nrRecs = gdxcc.gdxDataReadStrStart(gdx_handle, symNr) assert ret, get_last_error('gdxDataReadStrStart', gdx_handle) if idval is None: if symType == gdxcc.GMS_DT_EQU: idval = gdxcc.GMS_VAL_MARGINAL else: idval = gdxcc.GMS_VAL_LEVEL ifilt = None vtable = [None]*(nrRecs) rcounter = 0 rowtype = None if filt != None: if isinstance(filt,list): filt = '^({0})$'.format('|'.join([re.escape(x) for x in filt])) if isinstance(filt, str): filt_func = re.compile(filt, re.IGNORECASE).match else: filt_func = filt for i in range(nrRecs): vrow = [None]*(dim+1) ret, elements, values, afdim = gdxcc.gdxDataReadStr(gdx_handle) assert ret, get_last_error('gdxDataReadStr', gdx_handle) if (filt != None): match_filt = False for e in elements: m = filt_func(e) if m != None: match_filt = True break if not match_filt: continue d = -1 for d in range(dim): try: vrow[d] = int(elements[d]) except: vrow[d] = elements[d].lower() if idxlower else elements[d] vrow[d+1] = values[idval] vtable[rcounter] = vrow rcounter += 1 gdxcc.gdxDataReadDone(gdx_handle) cols = ['s%d' % x for x in range(dim)]+['val',] df = pd.DataFrame(vtable[:rcounter],columns=cols) logger.debug("%d / %d records read from <%s>" % (rcounter, nrRecs, self.internal_filename)) if symType == gdxcc.GMS_DT_SET: reshape = RESHAPE_SERIES df = dfreshape(df, reshape) if symType == gdxcc.GMS_DT_SET: df = df.index self.data = df return df
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)
def reader(): handle = self.file.H for i in range(records): yield gdxcc.gdxDataReadStr(handle)
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)
def _read_symbol(self, symno: int): """Read a GAMS symbol as a Pandas Series object Args: symno: Symbol number Raises: RuntimeError """ # Get symbol info ret, _sym, dim, symtype = gdxcc.gdxSymbolInfo(self._h, symno) if not ret: warn("Symbol not found!") return None # Get domain of symbol domain = [(d if d != '*' else None) for d in self._get_domain(symno)] if not any(domain): domain = None # Get explanatory text expl_text = self._get_expl_text(symno) # Get length of longest label _label_maxlen = gdxcc.gdxSymbIndxMaxLength(self._h, symno)[0] # Start reading symbol ret, recs = gdxcc.gdxDataReadStrStart(self._h, symno) if not ret: raise Exception( gdxcc.gdxErrorStr(self._h, gdxcc.gdxGetLastError(self._h))[1]) # Initialize keys and values arrays keys = recs * [tuple()] values = recs * [float()] if gdxcc.gdxSetHasText(self._h, symno): assoc_texts = recs * [str()] else: assoc_texts = None # Read GDX data # Code inside the loop is as small as possible for performance, # so the if statements are outside. if symtype == GMS_DT_SET and assoc_texts: for i in range(recs): _ret, key_arr, value_arr, _afdim = gdxcc.gdxDataReadStr( self._h) keys[i] = (key_arr[0] if dim == 1 else tuple(key_arr) ) # Squeze out dimension of 1-dim keys assoc_texts[i] = self._get_set_assoc_text( value_arr[GMS_VAL_LEVEL]) elif symtype == GMS_DT_SET and not assoc_texts: for i in range(recs): _ret, key_arr, _value_arr, _afdim = gdxcc.gdxDataReadStr( self._h) keys[i] = (key_arr[0] if dim == 1 else tuple(key_arr) ) # Squeze out dimension of 1-dim keys elif symtype == GMS_DT_PAR: for i in range(recs): _ret, key_arr, value_arr, _afdim = gdxcc.gdxDataReadStr( self._h) keys[i] = (key_arr[0] if dim == 1 else tuple(key_arr) ) # Squeze out dimension of 1-dim keys val = value_arr[GMS_VAL_LEVEL] values[i] = SPECIAL_VALUES.get(val, val) # Done reading gdxcc.gdxDataReadDone(self._h) # Construct GAMS symbols and return if symtype == GMS_DT_SET: return GAMSSet(keys, domain, expl_text=expl_text, assoc_texts=assoc_texts) elif symtype == GMS_DT_PAR: if dim == 0: return GAMSScalar(values[0], expl_text=expl_text) else: return GAMSParameter(dict(zip(keys, values)), domain=domain, expl_text=expl_text)
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)