예제 #1
0
def test_transition():
    '''Test generic transitions'''

    # labels are skipped in comparisons and hashing
    t1 = Transition(IonType.S, 1, 0)
    t2 = Transition(IonType.S,
                    1,
                    0,
                    label_ion='Yb',
                    label_i='ES',
                    label_f='GS')
    assert t1 == t2
    assert hash(t1) == hash(t2)

    # different states yield different Transitions
    t3 = Transition(IonType.S, 2, 0)
    assert t3 != t1
    assert t3 != t2
    assert hash(t3) != hash(t1)
    assert hash(t3) != hash(t2)

    # different ions yield different Transitions
    t4 = Transition(IonType.A, 1, 0)
    assert t4 != t1
    assert hash(t4) != hash(t1)
예제 #2
0
def test_optim_ok_proc(data_proc): # ok
    data = data_proc[0] + '''optimization:
        processes: [ETU53, {}]
'''.format(data_proc[1])
    with temp_config_filename(data) as filename:
        cte = settings.load(filename)

    ETU53 = EneryTransferProcess([Transition(IonType.A, 5, 6), Transition(IonType.A, 3, 1)],
                                 mult=6, strength=2.5e8, name='ETU53')
    assert cte.optimization['processes'] == [ETU53, data_proc[2]]
예제 #3
0
def test_ET_process():
    '''Test excitation transitions'''

    strength = 1e9
    t1 = Transition(IonType.S, 1, 0)
    t2 = Transition(IonType.S, 0, 1)
    et1 = EneryTransferProcess([t1, t2], mult=6, strength=strength)
    et2 = EneryTransferProcess([t1, t2], mult=8, strength=strength)
    assert et1 != et2

    t3 = Transition(IonType.S, 0, 1, label_ion='Yb')
    et3 = EneryTransferProcess([t1, t3], mult=6, strength=strength)
    assert et1 == et3

    assert et1.strength == strength
    assert et1.strength_avg == strength

    strength_avg = 1e3
    et4 = EneryTransferProcess([t1, t2],
                               mult=8,
                               strength=strength,
                               strength_avg=strength_avg)
    assert et4.strength_avg == strength_avg
예제 #4
0
def setup_cte_sim(setup_cte):
    '''Load the settings for simulations'''

    # test_sim_dyn_2S_2A was created with these settings
    setup_cte['decay']['branching_A'].add(DecayTransition(IonType.A, 3, 2, branching_ratio=0.1))
    setup_cte['energy_transfer'] = {
               'CR50': EneryTransferProcess([Transition(IonType.A, 5, 3),
                                             Transition(IonType.A, 0, 2)],
                                            mult=6, strength=2893199540.0),
               'ETU53': EneryTransferProcess([Transition(IonType.A, 5, 6),
                                              Transition(IonType.A, 3, 1)],
                                             mult=6, strength=254295690.0),
               'BackET': EneryTransferProcess([Transition(IonType.A, 3, 0),
                                               Transition(IonType.S, 0, 1)],
                                              mult=6, strength=4502.20614),
               'EM': EneryTransferProcess([Transition(IonType.S, 1, 0),
                                           Transition(IonType.S, 0, 1)],
                                          mult=6, strength=45022061400.0),
               'ETU1': EneryTransferProcess([Transition(IonType.S, 1, 0),
                                             Transition(IonType.A, 0, 2)],
                                            mult=6, strength=10000.0)
               }

    return Settings.load_from_dict(setup_cte)
예제 #5
0
def test_decay_transition():
    '''Test generic decay or branching transitions'''

    # labels are skipped in comparisons and hashing
    t1 = DecayTransition(IonType.S, 1, 0, branching_ratio=0.4)
    t2 = DecayTransition(IonType.S,
                         1,
                         0,
                         branching_ratio=0.4,
                         label_ion='Yb',
                         label_i='ES',
                         label_f='GS')
    assert t1 == t2
    assert hash(t1) == hash(t2)
    t1_dec = DecayTransition(IonType.S, 1, 0, decay_rate=1e5)
    t2_dec = DecayTransition(IonType.S,
                             1,
                             0,
                             decay_rate=1e5,
                             label_ion='Yb',
                             label_i='ES',
                             label_f='GS')
    assert t1_dec == t2_dec
    assert hash(t1_dec) == hash(t2_dec)

    # different branching_ratios: not equal but same hash
    t3 = DecayTransition(IonType.S, 1, 0, branching_ratio=0.1)
    assert t3 != t1
    assert t3 != t2
    assert hash(t3) == hash(t1)
    assert hash(t3) == hash(t2)

    # compare Transitions with DecayTransitions, ignores values
    t4 = Transition(IonType.S, 1, 0)
    assert t1 == t4
    assert t4 == t1
    assert hash(t1) == hash(t4)
예제 #6
0
def setup_cte():
    '''Load the cte data structure'''

    class Cte(dict):
        __getattr__= dict.__getitem__
        __setattr__= dict.__setitem__
        __delattr__= dict.__delitem__

    cte = Cte({'version': 1,
               'energy_transfer': OrderedDict({
                  'CR50': EneryTransferProcess([Transition(IonType.A, 5, 3),
                                                Transition(IonType.A, 0, 2)],
                                               mult=6, strength=887920884.0, name='CR50'),
                  'ETU53': EneryTransferProcess([Transition(IonType.A, 5, 6),
                                                 Transition(IonType.A, 3, 1)],
                                                mult=6, strength=450220614.0, name='ETU53'),
                  'ETU55': EneryTransferProcess([Transition(IonType.A, 5, 6),
                                                 Transition(IonType.A, 5, 4)],
                                                mult=6, strength=0.0, name='ETU55'),
                  'BackET': EneryTransferProcess([Transition(IonType.A, 3, 0),
                                                  Transition(IonType.S, 0, 1)],
                                                 mult=6, strength=4502.20614, name='BackET'),
                  'EM': EneryTransferProcess([Transition(IonType.S, 1, 0),
                                              Transition(IonType.S, 0, 1)],
                                             mult=6, strength=45022061400.0, name='EM'),
                  'ETU1': EneryTransferProcess([Transition(IonType.S, 1, 0),
                                                Transition(IonType.A, 0, 2)],
                                               mult=6, strength=10000.0, name='ETU1'),
                  'coop1': EneryTransferProcess([Transition(IonType.S, 1, 0),
                                             Transition(IonType.S, 1, 0),
                                             Transition(IonType.A, 0, 5)],
                                            mult=6, strength=1000.0, name='coop1')
              }),
         'decay': {
             'branching_A': {DecayTransition(IonType.A, 2, 1, branching_ratio=0.4),
                             DecayTransition(IonType.A, 3, 1, branching_ratio=0.3),
                             DecayTransition(IonType.A, 4, 3, branching_ratio=0.999),
                             DecayTransition(IonType.A, 5, 1, branching_ratio=0.15),
                             DecayTransition(IonType.A, 5, 2, branching_ratio=0.16),
                             DecayTransition(IonType.A, 5, 3, branching_ratio=0.04),
                             DecayTransition(IonType.A, 5, 4, branching_ratio=0.0),
                             DecayTransition(IonType.A, 6, 1, branching_ratio=0.43)},
             'branching_S': {DecayTransition(IonType.S, 1, 0, branching_ratio=1.0)},
             'decay_A': {DecayTransition(IonType.A, 1, 0, decay_rate=83.33333333333333),
                         DecayTransition(IonType.A, 2, 0, decay_rate=40000.0),
                         DecayTransition(IonType.A, 3, 0, decay_rate=500.0),
                         DecayTransition(IonType.A, 4, 0, decay_rate=500000.0),
                         DecayTransition(IonType.A, 5, 0, decay_rate=1315.7894736842104),
                         DecayTransition(IonType.A, 6, 0, decay_rate=14814.814814814814)},
             'decay_S': {DecayTransition(IonType.S, 1, 0, decay_rate=400.0)}
             },
         'excitations': {
                  'NIR_1470': [Excitation(IonType.A, 5, 6, False, 9/5, 2e-4, 1e7, 1e-8)],
                  'NIR_800': [Excitation(IonType.A, 0, 3, False, 13/9, 0.0044, 1e7, 1e-8),
                              Excitation(IonType.A, 2, 5, False, 11/9, 0.002, 1e7, 1e-8)],
                  'NIR_980': [Excitation(IonType.S, 0, 1, False, 4/3, 0.0044, 1e7, 1e-8)],
                  'Vis_473': [Excitation(IonType.A, 0, 5, True, 13/9, 0.00093, 1e6, 1e-8)]},
         'ions': {'activators': 113, 'sensitizers': 0, 'total': 113},
         'lattice': {'A_conc': 0.3,
                     'N_uc': 20,
                     'S_conc': 0.3,
                     'a': 5.9738,
                     'alpha': 90.0,
                     'b': 5.9738,
                     'beta': 90.0,
                     'c': 3.5297,
                     'gamma': 120.0,
                     'd_max': 100.0,
                     'd_max_coop': 25.0,
                     'name': 'bNaYF4',
                     'sites_occ': [1.0, 0.5],
                     'sites_pos': [(0.0, 0.0, 0.0), (0.6666666666666666, 0.3333333333333333, 0.5)],
                     'spacegroup': 'P-6'},
         'no_console': False,
         'no_plot': False,
         'concentration_dependence': {'concentrations': [(0.0, 0.1), (0.0, 0.3), (0.0, 0.5), (0.0, 1.0)],
                                      'N_uc_list': [65, 40, 35, 25]},
         'power_dependence': [10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 10000000.0],
         'optimization': {'method': 'SLSQP',
                          'processes': [EneryTransferProcess([Transition(IonType.A, 5, 3), Transition(IonType.A, 0, 2)],
                                                             mult=6, strength=2893199540.0, name='CR50'),
                                        DecayTransition(IonType.A, 3, 1, branching_ratio=0.3)],
                          'options': {'tol': 1e-3,
                                      'N_points': 30,
                                      'min_factor': 1e-2,
                                      'max_factor': 2},
                          'excitations': ['Vis_473', 'NIR_980']
                          },
         'simulation_params': {'N_steps': 1000,
                               'N_steps_pulse': 2,
                               'atol': 1e-15,
                               'rtol': 0.001},
         'states': {'activator_ion_label': 'Tm',
                    'activator_states': 7,
                    'activator_states_labels': ['3H6', '3F4', '3H5', '3H4', '3F3', '1G4', '1D2'],
                    'sensitizer_ion_label': 'Yb',
                    'sensitizer_states': 2,
                    'sensitizer_states_labels': ['GS', 'ES'],
                    'energy_states': 791}
         }
         )
    cte['config_file'] = '''
version: 1

lattice:
    name: bNaYF4
    N_uc: 20
    S_conc: 0.3 # concentration
    A_conc: 0.3
    # unit cell
    a: 5.9738 # distances in Angstrom
    b: 5.9738
    c: 3.5297
    alpha: 90 # angles in degree
    beta: 90
    gamma: 120
    spacegroup: P-6 # the number is also ok for the spacegroup
    # info about sites
    sites_pos: [[0, 0, 0], [2/3, 1/3, 1/2]]
    sites_occ: [1, 1/2]

    # optional
    # maximum distance of interaction for normal ET and for cooperative
    # if not present, both default to infinite
    d_max: 100.0
    # it's strongly advised to keep this number low,
    # the number of coop interactions is very large (~num_atoms^3)
    d_max_coop: 25.0

states:
# all fields here are mandatory,
# leave empty if necessary (i.e.: just "sensitizer_ion_label" on a line), but don't delete them
    sensitizer_ion_label: Yb
    sensitizer_states_labels: [GS, ES]
    activator_ion_label: Tm
    activator_states_labels: [3H6, 3F4, 3H5, 3H4, 3F3, 1G4, 1D2]

excitations:
# the excitation label can be any text
# at this point, only one active excitation is suported
# the t_pulse value is only mandatory for the dynamics, it's ignored in the steady state
    Vis_473:
        active: True
        power_dens: 1e6 # power density W/cm^2
        t_pulse: 1e-8 # pulse width, seconds
        process: Tm(3H6) -> Tm(1G4) # both ion labels are required
        degeneracy: 13/9 # initial_state_g/final_state_g
        pump_rate: 9.3e-4 # cm2/J
    NIR_1470:
        active: False
        power_dens: 1e7 # power density W/cm^2
        t_pulse: 1e-8 # pulse width, seconds
        process: Tm(1G4) -> Tm(1D2) # both ion labels are required
        degeneracy: 9/5 # initial_state_g/final_state_g
        pump_rate: 2e-4 # cm2/J
    NIR_980:
        active: False
        power_dens: 1e7 # power density W/cm^2
        t_pulse: 1e-8 # pulse width, seconds
        process: Yb(GS)->Yb(ES)
        degeneracy: 4/3
        pump_rate: 4.4e-3 # cm2/J
    NIR_800: # ESA: list of processes, degeneracies and pump rates
        active: False
        power_dens: 1e7 # power density W/cm^2
        t_pulse: 1e-8 # pulse width, seconds
        process: [Tm(3H6)->Tm(3H4), Tm(3H5)->Tm(1G4)]
        degeneracy: [13/9, 11/9]
        pump_rate: [4.4e-3, 2e-3] # cm2/J

sensitizer_decay:
# lifetimes in s
    ES: 2.5e-3

activator_decay:
# lifetimes in s
    3F4: 12e-3
    3H5: 25e-6
    3H4: 2e-3
    3F3: 2e-6
    1G4: 760e-6
    1D2: 67.5e-6

activator_branching_ratios:
    # 3H5 and 3H4 to 3F4
    3H5->3F4: 0.4
    3H4->3F4: 0.3
    # 3F3 to 3H4
    3F3->3H4: 0.999
    # 1G4 to 3F4, 3H5, 3H4 and 3F3
    1G4->3F4: 0.15
    1G4->3H5: 0.16
    1G4->3H4: 0.04
    1G4->3F3: 0.00
    # 1D2 to 3F4
    1D2->3F4: 0.43

energy_transfer:
    CR50:
        process: Tm(1G4) + Tm(3H6) -> Tm(3H4) + Tm(3H5)
        multipolarity: 6
        strength: 8.87920884e+08
    ETU53:
        process:  Tm(1G4) + Tm(3H4) -> Tm(1D2) + Tm(3F4)
        multipolarity: 6
        strength: 4.50220614e+08
    ETU55:
        process:  Tm(1G4) + Tm(1G4) -> Tm(1D2) + Tm(3F3)
        multipolarity: 6
        strength: 0 # 4.50220614e+7
    ETU1:
        process:  Yb(ES) + Tm(3H6) -> Yb(GS) + Tm(3H5)
        multipolarity: 6
        strength: 1e4
    BackET:
        process:  Tm(3H4) + Yb(GS) -> Tm(3H6) + Yb(ES)
        multipolarity: 6
        strength: 4502.20614
    EM:
        process:  Yb(ES) + Yb(GS) -> Yb(GS) + Yb(ES)
        multipolarity: 6
        strength: 4.50220614e+10
    coop1:
        process:  Yb(ES) + Yb(ES) + Tm(3H6) -> Yb(GS) + Yb(GS) + Tm(1G4)
        multipolarity: 6
        strength: 1000

optimization:
    processes: [CR50, 3H4->3F4]
    method: SLSQP
    options:
        tol: 1e-3
        N_points: 30
        min_factor: 1e-2
        max_factor: 2
    excitations: [Vis_473, NIR_980]

simulation_params: # default values for certain parameters in the ODE solver
    rtol: 1e-3 # relative tolerance
    atol: 1e-15 # absolute tolerance
    N_steps_pulse: 2 # number of steps for the pulse (only for dynamics)
    N_steps: 1000 # number of steps for relaxation (also for steady state)

power_dependence: [1e1, 1e7, 7]

concentration_dependence:
    concentrations: [[0], [0.1, 0.3, 0.5, 1.0]]
    N_uc_list: [65, 40, 35, 25]

'''
    cte['no_console'] = False
    cte['no_plot'] = False
    return cte
예제 #7
0
@author: Pedro
"""
import pytest
import numpy as np
import warnings

from lmfit import Parameters

import simetuc.optimize as optimize
import simetuc.simulations as simulations
from simetuc.util import IonType, DecayTransition, EneryTransferProcess, Transition
from simetuc.util import temp_bin_filename, temp_config_filename


B_43 = DecayTransition(IonType.A, 3, 1, branching_ratio=0.3)
CR50 = EneryTransferProcess([Transition(IonType.A, 5, 3), Transition(IonType.A, 0, 2)],
                            mult=6, strength=2893199540.0, name='CR50')
def idfn_param(param):
    '''Returns the name of the test according to the parameters'''
    return 'method={}'.format(param)
def idfn_avg(param):
    '''Returns the name of the test according to the parameters'''
    return 'avg={}'.format(param)
def idfn_proc(param):
    '''Returns the name of the test according to the parameters'''
    return 'num={}'.format(len(param))
@pytest.mark.parametrize('method', ['COBYLA', 'L-BFGS-B', 'TNC',
                                    'SLSQP', 'brute', 'leastsq'],
                                    ids=idfn_param)
@pytest.mark.parametrize('function', ['optimize_dynamics', 'optimize_concentrations'])
@pytest.mark.parametrize('average', [True, False], ids=idfn_avg)
예제 #8
0
            settings.load(filename)
    assert excinfo.match(r"Wrong labels in optimization: processes")
    assert excinfo.type == settings.LabelError

def test_optim_wrong_B_proc_label():
    '''Wrong branching ration optimization process'''
    data = data_ET_ok + '''optimization:
        processes: [3H145->3F4]
'''
    with pytest.raises(settings.LabelError) as excinfo: # wrong ET process label
        with temp_config_filename(data) as filename:
            settings.load(filename)
    assert excinfo.match(r"Wrong labels in optimization: processes")
    assert excinfo.type == settings.LabelError

@pytest.mark.parametrize('data_proc', [(data_ET_ok, '3H5->3F4',  Transition(IonType.A, 2, 1)),
                                       (data_ET_ok_full_S, '3ES->1ES',  Transition(IonType.S, 3, 1))])
def test_optim_ok_proc(data_proc): # ok
    data = data_proc[0] + '''optimization:
        processes: [ETU53, {}]
'''.format(data_proc[1])
    with temp_config_filename(data) as filename:
        cte = settings.load(filename)

    ETU53 = EneryTransferProcess([Transition(IonType.A, 5, 6), Transition(IonType.A, 3, 1)],
                                 mult=6, strength=2.5e8, name='ETU53')
    assert cte.optimization['processes'] == [ETU53, data_proc[2]]

def test_optim_method(): # ok
    data = data_ET_ok + '''optimization:
        method: COBYLA'''
예제 #9
0
def _parse_ET(parsed_settings: Settings) -> Dict:
    '''Parse the energy transfer processes'''
    dict_states = parsed_settings.states
    sensitizer_ion_label = dict_states['sensitizer_ion_label']
    activator_ion_label = dict_states['activator_ion_label']
    list_ion_label = [sensitizer_ion_label, activator_ion_label]

    sensitizer_labels = dict_states['sensitizer_states_labels']
    activator_labels = dict_states['activator_states_labels']
    tuple_state_labels = (sensitizer_labels, activator_labels)

    # ET PROCESSES.
    ET_dict = {}  # type: Dict
    for num, (name, et_subdict) in enumerate(
            parsed_settings['energy_transfer'].items()):

        process = et_subdict['process']
        mult = et_subdict['multipolarity']
        strength = et_subdict['strength']
        strength_avg = et_subdict.get('strength_avg', None)

        # get the ions and states labels involved
        list_init_final = _get_ion_and_state_labels(process)
        list_ions_num = [
            _get_ion_index(list_ion_label, ion)
            for ion, label in list_init_final
        ]
        list_indices = [
            _get_state_index(tuple_state_labels[ion_num],
                             label,
                             section='ET process',
                             process=process,
                             num=num)
            for ion_num, (ion_label,
                          label) in zip(list_ions_num, list_init_final)
        ]

        # list with all information about this ET process
        # tuples with ion and states labels and numbers
        list_ion_states = [(ion_label, state_label, ion_num, state_num)
                           for (ion_label, state_label), ion_num, state_num in
                           zip(list_init_final, list_ions_num, list_indices)]
        # fold the list of ion, state labels in two
        # so that each tuple has two tuples with the states belonging to the same transition
        folded_lst = list(
            zip(list_ion_states[:len(list_ion_states) // 2],
                list_ion_states[len(list_ion_states) // 2:]))

        # store the data
        trans_lst = [
            Transition(IonType(tuple_i[2]),
                       tuple_i[3],
                       tuple_f[3],
                       label_ion=tuple_i[0],
                       label_i=tuple_i[1],
                       label_f=tuple_f[1]) for tuple_i, tuple_f in folded_lst
        ]
        #            print(trans_lst)
        ET_dict[name] = EneryTransferProcess(trans_lst,
                                             mult=mult,
                                             strength=strength,
                                             strength_avg=strength_avg,
                                             name=name)

    return ET_dict