示例#1
0
 def test_evaluate_multiplemodels_singleitem(self):
     """Can we evaluate value-type objective for multiple models"""
     yamldata = """objectives:
         - item:
             models: [A, B, C]
             ref: [2.0, 2., 3.]
             options:
                 # normalise: True
                 subweights: [2, 1, 1.5]
     """
     # set model data
     database = Database()
     db1 = {'item': 1.0}
     db2 = {'item': 1.0}
     db3 = {'item': 1.0}
     database.update('A', db1)
     _db = database.get('A')
     self.assertDictEqual(_db, db1)
     database.update('B', db2)
     database.update('C', db3)
     # declaration of objective
     spec = yaml.load(yamldata)['objectives'][0]
     objv = oo.get_objective(spec)
     # evaluate
     self.assertAlmostEqual(1.4142135623730951, objv(database))
示例#2
0
 def test_evaluate_bands(self):
     """Can we evaluate value-type objective of type bands (2D array)"""
     yamldata = """objectives:
         - bands: 
             models: A
             ref: 
                 file: ./reference_data/fakebands.dat
                 loader_args: {unpack: False}
                 process:
                     rm_columns: 1
             eval: [RMS, relerr]
     """
     # set model data
     database = Database()
     database.update('A')
     db1 = database.get('A')
     # declaration of objective
     spec = yaml.load(yamldata)['objectives'][0]
     objv = oo.get_objective(spec)
     self.assertAlmostEqual(1., np.sum(objv.subweights))
     #logger.debug(objv.ref_data)
     #logger.debug(objv.subweights)
     db1['bands'] = objv.ref_data * 1.1
     cost = np.sqrt(np.sum(objv.subweights*relerr(objv.ref_data, db1['bands'])**2))
     #logger.debug(cost)
     # evaluate
     self.assertAlmostEqual(cost, objv(database))
示例#3
0
 def test_objtype_values_single_model_single_data(self):
     """Can we create value-type objective for a single model"""
     yamldata = """objectives:
         - band_gap:
             doc: Band gap, Si
             models: Si/bs
             ref: 1.12
             weight: 3.0
     """
     dat = 1.2
     ow  = 1.
     spec = yaml.load(yamldata)['objectives'][0]
     que = 'band_gap'
     ref = 1.12
     www = 3.0
     mnm = 'Si/bs'
     # set data base
     database = Database()
     database.update('Si/bs')
     modeldb = database.get('Si/bs')
     # check declaration
     objv = oo.get_objective(spec)
     self.assertEqual(objv.objtype, 'values')
     self.assertEqual(objv.model_names, mnm)
     self.assertEqual(objv.model_weights, ow)
     self.assertEqual(objv.weight, www)
     self.assertEqual(objv.ref_data, ref)
     self.assertEqual(objv.subweights, ow)
     self.assertEqual(objv.query_key, que)
     # check __call__()
     modeldb['band_gap'] = dat
     mdat, rdat, weights = objv.get(database)
     self.assertEqual(mdat, dat)
     self.assertEqual(rdat, ref)
     self.assertEqual(weights, ow)
示例#4
0
 def test_objtype_keyvaluepairs(self):
     """Can we create objective from given key-value pairs"""
     yamldata = """objectives:
         - meff:
             doc: Effective masses, Si
             models: Si/bs
             ref: 
                 file: ./reference_data/meff-Si.dat
                 loader_args: 
                     dtype:
                     # NOTABENE: yaml cannot read in tuples, so we must
                     #           use the dictionary formulation of dtype
                         names: ['keys', 'values']
                         formats: ['S15', 'float']
             options:
                 normalise: false
                 subweights: 
                     # consider only a couple of entries from available data
                     dflt: 0.
                     me_GX_0: 2.
                     mh_GX_0: 1.
             weight: 1.5
     """
     spec = yaml.load(yamldata)['objectives'][0]
     que = 'meff'
     # NOTABENE: order here must coincide with order in ref:file
     ref = np.array([('me_GX_0', 0.916), ('mh_GX_0', -0.276)],
                    dtype=[('keys', 'S15'), ('values', 'float')])
     ref = ref['values']
     subw = np.array([2., 1.])
     doc = spec[que]['doc']
     oww = spec[que]['weight']
     mnm = spec[que]['models']
     # check declaration
     objv = oo.get_objective(spec)
     logger.debug(objv)
     self.assertEqual(objv.doc, doc)
     self.assertEqual(objv.weight, oww)
     self.assertEqual(objv.model_names, mnm)
     self.assertEqual(objv.model_weights, 1.)
     nptest.assert_array_equal(objv.ref_data, ref, verbose=True)
     nptest.assert_array_equal(objv.subweights, subw, verbose=True)
     self.assertEqual(objv.query_key, ['me_GX_0', 'mh_GX_0'])
     self.assertEqual(objv.objtype, 'keyval_pairs')
     # set data base: 
     # could be done either before or after declaration
     database = Database()
     dat = [0.9, -0.5, 1.2]
     database.update('Si/bs', {'me_GX_0': dat[0], 'mh_GX_0': dat[1],
                                  'me_GL_2':dat[2]})
     # check __call__()
     mdat, rdat, weights = objv.get(database)
     #logger.debug(mdat)
     #logger.debug(rdat)
     #logger.debug(weights)
     # NOTABENE: order depends on the order in the reference file!!!
     nptest.assert_array_equal(mdat, np.asarray(dat[0:2]), verbose=True)
     nptest.assert_array_equal(rdat, ref, verbose=True)
     nptest.assert_array_equal(weights, subw, verbose=True)
示例#5
0
 def test_objtype_values_single_model_array_data(self):
     """Can we create 1d-array-values-type objective for a single model"""
     yamldata = """objectives:
         - Etot(Vol):
             doc: 'Energy-Volume dependnce of Wurtziteac structure'
             models: GaN-W-ac 
             ref: [-20.236, -21.099, -21.829, -22.45, -22.967,
                 -23.387, -23.719, -23.974, 
                 -24.158, -24.278, -24.304, -24.348, -24.309,
                 -24.228, -24.11 , -23.952, 
                 -23.769, -23.559, -23.328, -23.076, -22.809]
             options:
                 subweights: [1,1,1,1,1, 2,2,2, 3,3,3,3,3, 2,2,2, 1,1,1,1,1]
     """
     data = [-20.24,-21.1,-21.83,-22.45,-22.97,
         -23.4,-23.72,-23.97,
         -24.2,-24.3,-24.3,-24.35,-24.31, 
         -24.23,-24.11,-23.9,
         -23.77,-23.56,-23.3,-23.1,-22.8]
     logger.info(data)
     que = 'Etot(Vol)'
     ref = [-20.236, -21.099, -21.829, -22.45,-22.967,
                 -23.387, -23.719, -23.974,
                 -24.158, -24.278, -24.304,  -24.348, -24.309, 
                 -24.228, -24.11,  -23.952,
                 -23.769, -23.559, -23.328,  -23.076, -22.809]
     sbw = [1,1,1,1,1, 2,2,2, 3,3,3,3,3, 2,2,2, 1,1,1,1,1]
     sbw = np.asarray(sbw)/np.sum(sbw) # normalise
     model = 'GaN-W-ac'
     # set data base
     database = Database()
     database.update(model)
     modeldb = database.get(model)
     # check declaration
     spec = yaml.load(yamldata)['objectives'][0]
     logger.info(spec)
     objv = oo.get_objective(spec)
     self.assertEqual(objv.model_names, model)
     self.assertEqual(objv.model_weights, 1.)
     self.assertEqual(objv.weight, 1)
     nptest.assert_array_equal(objv.ref_data, ref, verbose=True)
     nptest.assert_array_equal(objv.subweights, sbw, verbose=True)
     self.assertEqual(objv.query_key, que)
     self.assertEqual(objv.objtype, 'values')
     # check __call__()
     modeldb[que] = data
     mdata, rdata, weights = objv.get(database)
     nptest.assert_array_equal(mdata, data, verbose=True)
     nptest.assert_array_equal(rdata, ref, verbose=True)
     nptest.assert_array_equal(weights, sbw, verbose=True)
示例#6
0
 def test_evaluate_singleitem(self):
     """Can we evaluate value-type objective for a single model"""
     yamldata = """objectives:
         - item:
             models: A
             ref: 1.0
     """
     # set data base
     database = Database()
     database.update('A')
     db = database.get('A')
     # declaration of objective
     spec = yaml.load(yamldata)['objectives'][0]
     objv = oo.get_objective(spec)
     # evaluate
     db['item'] = 1.2
     self.assertAlmostEqual(0.2, objv(database))
示例#7
0
 def test_database(self):
     """Can we update model DB"""
     database = Database()
     self.assertTrue(database is not None)
     #
     database.update('m1', {'i1': 42})
     self.assertDictEqual(database.all(), {'m1': {'i1': 42}})
     #
     database.update('m1', {'i1': 33})
     self.assertDictEqual(database.all(), {'m1': {'i1': 33}})
     #
     database.update('m2', {'i1': 10})
     self.assertDictEqual(database.all(), {'m1': {'i1': 33},
                                           'm2': {'i1': 10}})
     #
     database.update('m2', {'i2': 20})
     self.assertDictEqual(database.all(), {'m1': {'i1': 33},
                                           'm2': {'i1': 10,
                                                  'i2': 20}})
     update(database, 'm1', {'i2': 25})
     self.assertDictEqual(database.all(), {'m1': {'i1': 33,
                                                  'i2': 25},
                                           'm2': {'i1': 10,
                                                  'i2': 20}})
     database.update({'m2': {'i3': 40}})
     self.assertDictEqual(database.all(), {'m1': {'i1': 33,
                                                  'i2': 25},
                                           'm2': {'i3': 40}})
     #
     mdb = database.get('m2')
     self.assertDictEqual(mdb, {'i3': 40})
     self.assertEqual(database.get_item('m1', 'i2'), 25)
     #
     # check query initialised without database
     query = Query('m2', 'i1')
     self.assertEqual(query(database, atleast_1d=False), None)
     query = Query('m2', 'i3')
     self.assertEqual(query(database, atleast_1d=False), 40)
     #
     # check query initialised with database within database.query method
     self.assertEqual(database.query('m1', 'i1', atleast_1d=False), 33)
     nptest.assert_array_equal(database.query('m1', 'i1'), [33])
     #
     database.clear()
     self.assertDictEqual(database.all(), {})
示例#8
0
 def test_objtype_weightedsum(self):
     """Can we create objective from pairs of value-weight"""
     yamldata = """objectives:
         - Etot:
             doc: "heat of formation, SiO2"
             models: 
                 - [SiO2-quartz/scc, 1.]
                 - [Si/scc, -0.5] 
                 - [O2/scc, -1]
             ref: 1.8 
             weight: 1.2
     """
     spec = yaml.load(yamldata)['objectives'][0]
     que = 'Etot'
     ref = spec[que]['ref']
     doc = spec[que]['doc']
     oww = spec[que]['weight']
     mnm = [m[0] for m in spec[que]['models']]
     mww = np.asarray([m[1] for m in spec[que]['models']])
     subw = 1.
     # set data base: 
     # could be done either before or after declaration
     database = Database()
     # check declaration
     objv = oo.get_objective(spec)
     self.assertEqual(objv.doc, doc)
     self.assertEqual(objv.weight, oww)
     self.assertEqual(objv.model_names, mnm)
     nptest.assert_array_equal(objv.model_weights, mww, verbose=True)
     self.assertEqual(objv.ref_data, ref)
     self.assertEqual(objv.subweights, subw)
     self.assertEqual(objv.query_key, 'Etot')
     self.assertEqual(objv.objtype, 'weighted_sum')
     dat = [20, 12, 16]
     database.update('SiO2-quartz/scc', {'Etot': dat[0]})
     database.update('Si/scc', {'Etot': dat[1]})
     database.update('O2/scc', {'Etot': dat[2]})
     # check __call__()
     mdat, rdat, weights = objv.get(database)
     nptest.assert_array_equal(mdat, np.dot(np.asarray(dat), np.asarray(mww)), verbose=True)
     nptest.assert_array_equal(rdat, ref, verbose=True)
     nptest.assert_array_equal(weights, subw, verbose=True)
示例#9
0
    def test_objtype_bands(self):
        """Can we create objective from spec for bands?"""
        yamldata = """objectives:
            - bands: 
                doc: Valence Band, Si
                models: Si/bs
                ref: 
                    file: ./reference_data/fakebands.dat 
                    loader_args: {unpack: True}
                    process:       # eliminate unused columns, like k-pt enumeration
                        # indexes and ranges below refer to file, not array, 
                        # i.e. independent of 'unpack' loader argument
                        rm_columns: 1                # filter k-point enumeration, and bands, potentially
                        # rm_rows   : [[18,36], [1,4]] # filter k-points if needed for some reason
                        # scale     : 1                # for unit conversion, e.g. Hartree to eV, if needed
                options:
                    use_ref: [[2, 4]]                # fortran-style index-bounds of bands to use
                    use_model: [[1, 3]]              # model has lesser number of bands
                    # Alignment works after data has been masked by use_* clause, and therefore
                    # the indexes below do not correspond to original but masked array
                    align_ref: [3, max]              # fortran-style index of band and k-point,
                    align_model: [3, max]            # or a function (e.g. min, max) instead of k-point
                    normalise: false
                    subweights: 
                        # NOTABENE:
                        # --------------------------------------------------
                        # Energy values are with respect to the ALIGNEMENT.
                        # If we want to have the reference  band index as zero,
                        # we would have to do tricks with the range specification 
                        # behind the curtain, to allow both positive and negative 
                        # band indexes, e.g. [-3, 0], INCLUSIVE of either boundary.
                        # Currently this is not done, so only standard Fortran
                        # range spec is supported. Therefore, band 1 is always
                        # the lowest lying, and e.g. band 4 is the third above it.
                        # --------------------------------------------------
                        dflt: 1
                        values: # [[range], subweight] for E-k points in the given range of energy
                        # notabene: the range below is with respect to the alignment value
                            - [[-0.2, 0.], 3.5]
                        bands: # [[range], subweight] of bands indexes; fortran-style
                            - [[2, 3], 1.5]   # two valence bands below the top VB
                            - [4 , 3.0]       # emphasize the reference band
                        # not supported yet     ipoint:
                weight: 1.0
            """
        spec = yaml.load(yamldata)['objectives'][0]
        que  = 'bands'
        doc  = spec[que]['doc']
        model  = 'Si/bs'
        mww = [1]
        oww  = 1
        ref  = np.loadtxt('reference_data/fakebands.dat', unpack=True)
        ref  = ref[2:5] # remove 1st col of file(k-pt enum.), consider first 3 bands from 2nd
        shift = -0.4 # this is the top of the VB (cf: fakebands.dat)
        ref -= shift
        shape = ref.shape
        # we have use_model => only a subset of bands is needed
        subset_ind = np.array([0,1,2])
        # subweights
        subw  = np.ones(shape)
        subw[1:2] = 1.5
        subw[2] = 3.0
        # subweights on value are the last one to be applied
        subw[ref > -0.2] = 3.5
        subw = subw/np.sum(subw)
        database = Database()
#        # check declaration
        objv = oo.get_objective(spec)
        self.assertEqual(objv.doc, doc)
        self.assertEqual(objv.query_key, que)
        self.assertEqual(objv.weight, oww)
        self.assertEqual(objv.model_names, model)
        nptest.assert_array_equal(objv.model_weights, mww)
        nptest.assert_array_equal(objv.ref_data, ref, verbose=True)
        nptest.assert_array_equal(objv.subset_ind, subset_ind, verbose=True)
        nptest.assert_array_equal(objv.subweights, subw, verbose=True)
        # check the __call__()
        data = np.loadtxt("reference_data/fakebands-2.dat", unpack=True)
        database.update('Si/bs', {'bands': data[1:]})
        mdat, rdat, weights = objv.get(database)
        nptest.assert_array_almost_equal(mdat, ref, decimal=2, verbose=True)
        nptest.assert_array_equal(rdat, ref, verbose=True)
        nptest.assert_array_equal(weights, subw, verbose=True)
示例#10
0
 def test_objtype_values_multiple_models(self):
     """Can we create a value-type objective from several models"""
     yamldata = """objectives:
         - Etot:
             doc: Energy vs volume, Si
             models: [Si/scc-1, Si/scc, Si/scc+1,]
             ref: [23., 10, 15.]
             options:
                 normalise: false
                 subweights: [1., 3., 1.,]
     """
     spec = yaml.load(yamldata)['objectives'][0]
     que = 'Etot'
     ref = [23., 10, 15.]
     mnm = ['Si/scc-1', 'Si/scc', 'Si/scc+1',]
     subw = [1., 3., 1.]
     # check declaration
     objv = oo.get_objective(spec)
     self.assertEqual(objv.model_names, mnm)
     self.assertEqual(objv.weight, 1)
     nptest.assert_array_equal(objv.model_weights, [1]*3, verbose=True)
     nptest.assert_array_equal(objv.ref_data, ref, verbose=True)
     nptest.assert_array_equal(objv.subweights, subw, verbose=True)
     self.assertEqual(objv.query_key, que)
     # set data base: 
     # could be done either before or after declaration
     database = Database()
     database.update('Si/scc-1')
     database.update('Si/scc')
     database.update('Si/scc+1')
     dat = [20, 12, 16]
     database.update('Si/scc-1', {'Etot': dat[0]})
     database.update('Si/scc', {'Etot': dat[1]})
     database.update('Si/scc+1', {'Etot': dat[2]})
     # check __call__()
     mdat, rdat, weights = objv.get(database)
     nptest.assert_array_equal(mdat, dat, verbose=True)
     nptest.assert_array_equal(rdat, ref, verbose=True)
     nptest.assert_array_equal(weights, subw, verbose=True)