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():
def write(self,index=None): if not self.loaded: raise Error("Cannot write unloaded symbol {}.".format(repr(self.name))) if self.data_type == GamsDataType.Set: self._fixup_set_value() if index is not None: self._index = index if self.index == 0: # universal set gdxcc.gdxUELRegisterRawStart(self.file.H) gdxcc.gdxUELRegisterRaw(self.file.H,self.name) gdxcc.gdxUELRegisterDone(self.file.H) return # write the data userinfo = 0 if self.variable_type is not None: userinfo = self.variable_type.value elif self.equation_type is not None: userinfo = self.equation_type.value if not gdxcc.gdxDataWriteStrStart(self.file.H, self.name, self.description, self.num_dims, self.data_type.value, userinfo): raise GdxError(self.file.H,"Could not start writing data for symbol {}".format(repr(self.name))) # set domain information if self.num_dims > 0: if self.index: if not gdxcc.gdxSymbolSetDomainX(self.file.H,self.index,self.dims): raise GdxError(self.file.H,"Could not set domain information for {}. Domains are {}".format(repr(self.name),repr(self.dims))) else: logger.info("Not writing domain information because symbol index is unknown.") values = gdxcc.doubleArray(gdxcc.GMS_VAL_MAX) # make sure index is clean -- needed for merging in convert_np_to_gdx_svs self.dataframe = self.dataframe.reset_index(drop=True) for row in convert_np_to_gdx_svs(self.dataframe,self.num_dims,self.file).itertuples(index=False,name=None): dims = [str(x) for x in row[:self.num_dims]] vals = row[self.num_dims:] for col_name, col_ind in self.value_cols: values[col_ind] = float(0.0) try: if isinstance(vals[col_ind],Number): values[col_ind] = float(vals[col_ind]) except: raise Error("Unable to set element {} from {}.".format(col_ind,vals)) gdxcc.gdxDataWriteStr(self.file.H,dims,values) gdxcc.gdxDataWriteDone(self.file.H) return
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)
def _insert_symbols(gdxHandle, sets, parameters): """ Function that writes all sets and parameters to the gdxHandle :param sets: dictionary with all the sets :param parameters: dictionary with all the parameters """ # It is essential to write the sets first, otherwise h might be written in the wrong order for s in sets: gdxSymbolType = gdxcc.GMS_DT_SET dims = 1 gdxcc.gdxDataWriteStrStart(gdxHandle, s, "", dims, gdxSymbolType, 0) gdxValues = gdxcc.doubleArray(5) gdxValues[ gdxcc. GMS_VAL_LEVEL] = 0.0 # 0.0 == Y (explanatory text of set in gdx) Nrows = len(sets[s]) for row in range(Nrows): gdxKeys = [str(ss) for ss in shrink_to_64([sets[s][row]]) ] # Reduce the size if bigger than 64 characters try: success = gdxcc.gdxDataWriteStr(gdxHandle, gdxKeys, gdxValues) except: success = False if not success: logging.error('Key ' + gdxKeys[0] + ' of set ' + s + ' could not be written') gdxcc.gdxDataWriteDone(gdxHandle) # Check array sizes for parameters: for p in parameters: variable = parameters[p] # Check that the required fields are present: dims = len(variable['sets']) shape = variable['val'].shape Nrows = variable['val'].shape[0] gdxSymbolType = gdxcc.GMS_DT_PAR gdxcc.gdxDataWriteStrStart(gdxHandle, p, "", dims, gdxSymbolType, 0) gdxValues = gdxcc.doubleArray(5) gdxValues[ gdxcc. GMS_VAL_LEVEL] = 0.0 # 0.0 == Y (explanatory text of set in gdx) if len(shape) != dims: logging.error('Variable ' + p + ': The \'val\' data matrix has ' + str(len(shape)) + ' dimensions and should have ' + str(dims)) sys.exit(1) for i in range(dims): if shape[i] != len(sets[variable['sets'][i]]): logging.error('Variable ' + p + ': The \'val\' data matrix has ' + str(shape[i]) + ' elements for dimention ' + str(variable['sets'][i]) + ' while there are ' + str(len(variable['sets'])) + ' set values') sys.exit(1) for index, value in np.ndenumerate(variable['val']): # Write line by line if value is non null if value != 0 and not pd.isnull(value): gdxKeys = [] # All the set values for this line for i in range(dims): key = sets[variable['sets'][i]][index[ i]] # Get the string value of the set by using the indice in the val matrix gdxKeys.append(str(key)) gdxKeys = shrink_to_64( gdxKeys) # Reduce the size if bigger than 64 characters gdxValues[gdxcc.GMS_VAL_LEVEL] = float(value) try: success = gdxcc.gdxDataWriteStr(gdxHandle, gdxKeys, gdxValues) except: logging.error("Didn't work") success = False if not success: logging.error('Key ' + gdxKeys[0] + ' of parameter ' + p + ' could not be written') gdxcc.gdxDataWriteDone(gdxHandle) logging.debug('Parameter ' + p + ' successfully written') logging.debug('Set ' + s + ' successfully written')
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)
if success_gdxcc and success_path: print('\n \nTRY TO GENERATE GDX FILE') try: gdxHandle = gdxcc.new_gdxHandle_tp() gdxcc.gdxCreateD(gdxHandle, gamspath, gdxcc.GMS_SSSIZE) gdxcc.gdxOpenWrite(gdxHandle, 'test.gdx', "") # 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')
def _write_symbol(self, symname: str, symbol: _GAMSSymbol): """Write a Pandas series to a GAMS Set symbol Args: symbol: GAMS symbol object Raises: RuntimeError """ # Get number of dimensions dim = symbol.dimension try: recs = len(symbol) except TypeError: recs = 1 set_has_text = False # TODO # Begin writing to a symbol ret = gdxcc.gdxDataWriteStrStart( self._h, symname, symbol.expl_text, dim, GMS_DTYPES[symbol._type], GMS_USERINFO_SET_PARAMETER, ) if not ret: raise RuntimeError( gdxcc.gdxErrorStr(self._h, gdxcc.gdxGetLastError(self._h))[1]) # Define domain if symbol.domain is not None: domain = [(d if d is not None else '*') for d in symbol.domain] else: domain = dim * ['*'] ret = gdxcc.gdxSymbolSetDomainX(self._h, self._find_symbol(symname), domain) if not ret: raise RuntimeError( "Unable to set domain for symbol '{}'".format(symname)) # Init value array value_arr = gdxcc.doubleArray(gdxcc.GMS_VAL_MAX) if dim == 0: # It’s a scalar value_arr[GMS_VAL_LEVEL] = float(symbol) gdxcc.gdxDataWriteStr(self._h, list(), value_arr) elif isinstance(symbol, GAMSSet): for key in symbol: # For sets, register the associated text in the string table and # store index number as the value if set_has_text: pass # TODO # assoc_text = copy(values[i]) # ret, value_arr[GMS_VAL_LEVEL] = gdxAddSetText(self._h, # str(assoc_text)) # if not ret: # warn("Unable to register string '{}' " # "to string table".format(assoc_text)) else: value_arr[GMS_VAL_LEVEL] = 0 gdxcc.gdxDataWriteStr(self._h, list(key), value_arr) elif isinstance(symbol, GAMSParameter): for key, value in symbol: value_arr[GMS_VAL_LEVEL] = value gdxcc.gdxDataWriteStr(self._h, list(key), value_arr) gdxcc.gdxDataWriteDone(self._h)