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))
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))
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)
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)
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)
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))
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(), {})
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)
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)
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)