Ejemplo n.º 1
0
    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
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
    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)