Пример #1
0
def setup_cte_full_S(setup_cte):
    copy_cte = copy.deepcopy(setup_cte)
    copy_cte.states['sensitizer_states_labels'] = ['GS', '1ES', '2ES', '3ES']
    copy_cte.states['sensitizer_states'] = 4
    copy_cte.decay['branching_S'] = [DecayTransition(IonType.S, 1, 0, 1.0),
                                        DecayTransition(IonType.S, 2, 1, 0.5),
                                        DecayTransition(IonType.S, 3, 1, 0.01)]
    copy_cte.optimization['processes'] = ['CR50', DecayTransition(IonType.S, 2, 1, 0.5)]

    return copy_cte
Пример #2
0
def _parse_branching_ratios(
    parsed_settings: Settings
) -> Tuple[Set[DecayTransition], Set[DecayTransition]]:
    '''Parse the branching ratios'''
    dict_states = parsed_settings.states
    sensitizer_labels = dict_states['sensitizer_states_labels']
    sensitizer_ion_label = dict_states['sensitizer_ion_label']
    activator_labels = dict_states['activator_states_labels']
    activator_ion_label = dict_states['activator_ion_label']

    branch_ratios_S = parsed_settings.get('sensitizer_branching_ratios', None)
    branch_ratios_A = parsed_settings.get('activator_branching_ratios', None)
    if branch_ratios_S:
        states_val = [
            (*_get_branching_ratio_indices(process, sensitizer_labels), value)
            for process, value in branch_ratios_S.items()
        ]
        branch_trans_S = {
            DecayTransition(IonType.S,
                            state_i,
                            state_f,
                            branching_ratio=val,
                            label_ion=sensitizer_ion_label,
                            label_i=sensitizer_labels[state_i],
                            label_f=sensitizer_labels[state_f])
            for state_i, state_f, val in states_val if state_f != 0
        }
    else:
        branch_trans_S = set()
    if branch_ratios_A:
        states_val = [
            (*_get_branching_ratio_indices(process, activator_labels), value)
            for process, value in branch_ratios_A.items()
        ]
        branch_trans_A = {
            DecayTransition(IonType.A,
                            state_i,
                            state_f,
                            branching_ratio=val,
                            label_ion=activator_ion_label,
                            label_i=activator_labels[state_i],
                            label_f=activator_labels[state_f])
            for state_i, state_f, val in states_val if state_f != 0
        }
    else:
        branch_trans_A = set()

    return (branch_trans_S, branch_trans_A)
Пример #3
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)
Пример #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 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
Пример #6
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'])
Пример #7
0
def test_sim_power_dep_ESA():
    '''Make sure the simulated solution for a simple problem is equal to the theoretical one.'''
    test_filename = os.path.join(test_folder_path, 'data_0S_1A.hdf5')

    cte = {
        'version': 1,
        'decay': {
            'decay_A': {
                DecayTransition(IonType.A, 1, 0, decay_rate=1e3),
                DecayTransition(IonType.A, 2, 0, decay_rate=1e6)
            },
            'decay_S': {DecayTransition(IonType.S, 1, 0, decay_rate=1e1)},
            'branching_S': {},
            'branching_A': {}
        },
        'excitations': {
            'ESA': [
                Excitation(IonType.A, 0, 1, True, 0, 1e-3, 1e6, t_pulse=None),
                Excitation(IonType.A, 1, 2, True, 0, 1e-3, 1e6, t_pulse=None)
            ]
        },
        'energy_transfer': {},
        'lattice': {
            'A_conc': 0.3,
            'N_uc': 20,
            'S_conc': 0.0,
            'a': 5.9738,
            'alpha': 90.0,
            'b': 5.9738,
            'beta': 90.0,
            'c': 3.5297,
            'gamma': 120.0,
            'name': 'bNaYF4',
            'sites_occ': [1.0, 0.5],
            'sites_pos': [(0.0, 0.0, 0.0), (2 / 3, 1 / 3, 0.5)],
            'spacegroup': 'P-6'
        },
        'no_console': False,
        'no_plot': False,
        'simulation_params': {
            'N_steps': 1000,
            'N_steps_pulse': 100,
            'atol': 1e-15,
            'rtol': 0.001
        },
        'states': {
            'activator_ion_label': 'Tm',
            'activator_states': 3,
            'activator_states_labels': ['GS', 'ES1', 'ES2'],
            'energy_states': 3,
            'sensitizer_ion_label': 'Yb',
            'sensitizer_states': 2,
            'sensitizer_states_labels': ['GS', 'ES']
        }
    }
    simple_cte = Settings.load_from_dict(cte)

    power_dens_list = np.logspace(1, 6, 6)

    sim = simulations.Simulations(simple_cte, full_path=test_filename)

    solution = sim.simulate_power_dependence(power_dens_list, average=True)

    # check that the ES1 and ES2 populations are close to the theoretical values
    for sol in solution:
        GS = sol.steady_state_populations[2]
        ES1 = sol.steady_state_populations[3]
        ES2 = sol.steady_state_populations[4]
        P = sol.power_dens * sol.cte.excitations['ESA'][0].pump_rate
        k1 = 1e3
        k2 = 1e6
        theo_ES1 = GS * P / (k1 + P)
        theo_ES2 = GS * P**2 / ((k1 + P) * k2)
        #        print('ES1: {}, theo_ES1: {}'.format(ES1, theo_ES1))
        #        print('ES2: {}, theo_ES2: {}'.format(ES2, theo_ES2))
        assert np.allclose(theo_ES1, ES1, rtol=1e-4)
        assert np.allclose(theo_ES2, ES2, rtol=1e-4)
Пример #8
0
def _parse_decay_rates(
        dict_states: Dict,
        parsed_settings: Dict) -> Dict[str, Set[DecayTransition]]:
    '''Parse the decay rates and return two lists with the state index and decay rate'''
    sensitizer_labels = dict_states['sensitizer_states_labels']
    sensitizer_ion_label = dict_states['sensitizer_ion_label']
    activator_labels = dict_states['activator_states_labels']
    activator_ion_label = dict_states['activator_ion_label']

    # the number of user-supplied lifetimes must be the same as
    # the number of energy states (minus the GS)
    if parsed_settings['sensitizer_decay'] is None or\
            len(parsed_settings['sensitizer_decay']) != len(sensitizer_labels)-1:
        msg = 'All sensitizer states must have a decay rate.'
        raise SettingsValueError(msg)
    if parsed_settings['activator_decay'] is None or\
            len(parsed_settings['activator_decay']) != len(activator_labels)-1:
        msg = 'All activator states must have a decay rate.'
        raise SettingsValueError(msg)

    parsed_S_decay = parsed_settings['sensitizer_decay']
    parsed_A_decay = parsed_settings['activator_decay']
    try:
        # list of tuples of state and decay rate
        decay_S_state = [(_get_state_index(sensitizer_labels,
                                           key,
                                           section='decay rate',
                                           process=key,
                                           num=num), 1 / tau, key)
                         for num, (key,
                                   tau) in enumerate(parsed_S_decay.items())]
        decay_S = {
            DecayTransition(IonType.S,
                            state_i,
                            0,
                            decay_rate=val,
                            label_ion=sensitizer_ion_label,
                            label_i=label,
                            label_f=sensitizer_labels[0])
            for state_i, val, label in decay_S_state
        }

        decay_A_state = [(_get_state_index(activator_labels,
                                           key,
                                           section='decay rate',
                                           process=key,
                                           num=num), 1 / tau, key)
                         for num, (key,
                                   tau) in enumerate(parsed_A_decay.items())]
        decay_A = {
            DecayTransition(IonType.A,
                            state_i,
                            0,
                            decay_rate=val,
                            label_ion=activator_ion_label,
                            label_i=label,
                            label_f=activator_labels[0])
            for state_i, val, label in decay_A_state
        }
    except LabelError:
        raise

    parsed_dict = {}
    parsed_dict['decay_S'] = decay_S
    parsed_dict['decay_A'] = decay_A

    return parsed_dict