Exemplo n.º 1
0
def simulate_and_compare(varparams,
                         varparamkeys,
                         system,
                         data_arrays,
                         to,
                         light,
                         powers=None,
                         which='pulse',
                         irf_args={'fwhm': 55 * ps},
                         N_coarse=500,
                         roll_value=0,
                         comparison='linear',
                         absolute=True,
                         limits=None,
                         norm=True,
                         roll_criterion='max',
                         maxavgnum=10,
                         condensed_output=True,
                         verbose=False):
    """
    Returns an array or list of arrays of differences between a set of
    simulated data and a set of experimental data, after aligning them. 
    The parameters and output of this functions are eventually to be passed to
    an optimization function such as ``scipy.optimize.least_sqares``.
    
    Parameters
    ----------
    varparams : list
        Rate equation parameters or other simulation parameters that determine
        the output of `system`. It does not need to be the comprehensive list 
        of parameters that define the system, simply the parameters with 
        respect to which the system output is to be optimized.
        varparams must have been obtained as list(dictionary.keys()) of the
        same dictionary that varparamkeys are extracted.
    varparamkeys : dictionary keys
        Names of varied parameters.
    system : object
        A system object to which `params` are passed, which contains a function
        that can output an array of PL signals. The system object needs to have
        been created previously in the code with dummy or guess parameters. It
        is then redefined with different parameters every time the 
        ``simulate_and_compare`` function is called.
    data_list : array or list of 1D arrays
        Array or list of 1D arrays containing experimental data to be compared 
        to the simulation. The output of ``system.PLsig`` must have the same 
        shape as `data_list`.
    to : dictionary
        Dictionary with time parameters. 
    light : object
        Excitation object that determines simulation
    powers : dictionary
        List of powers at which experiment is conducted, in SI units
    which : string, 'pulse' or 'cw'
        whether the varied powers represent the pulsed or CW laser
    irf_args: float, optional
        Arguments for constructing the Instrument Response Function used for convolution. See
        ``convolve_irf`` function. 
    N_coarse : integer
        N_coarse parameter of refined_simulation function.
    roll_value : float, optional
        Value on ``to['array']`` to which maxima of aligned arrays will be 
        shifted to.
    comparison : 'linear' or 'log'
        see ``elementwise_diff`` function. Default is linear.
    absolute : boolean, optional
        see ``elementwise_diff`` function. Default is False.
    limits : list of 2 values, optional
        lower and upper limit on time axis for which fitting is desired.
        Default is None (whole time axis fitted).
    norm : Boolean
        Determines whether each data/simulation transient should be normalized 
        with respect to itself. If false, all simulation and data traces are
        normalized by the simulation and data trace corresponding 
        to the highest power, respectively.
    roll_criterion : string, 'steep' or 'max'
        Determines whether the alignment of the two arrays happens by their 
        maximum or their steepest point. Default is 'max'
    maxavgnum : integer
        If `roll_criterion` is `"max"`, maxavgnum determines the `avgnum` 
        keyword in ``KinetiKit.kit.align_by_max().``
    verbose : boolean
        Whether to print the cost function at the end of each iteration. 
        
    Returns
    -------
    diffs : array or list of 1D arrays
        Array(s) of the differences or relative differences between the passed
        experimental data and simulation array(s).
    al_data_list : array or list of 1D arrays
        Aligned data arrays.
    al_sim_list : array or list of 1D arrays
        Aligned simulation arrays.
    """

    param_dict = kin_kit.dict_from_list(varparams, varparamkeys)
    system.update(**param_dict)
    # print(system.params())
    if light is not None:
        pulse = light.pulse
    dtime = to['array'][::to['subsample']]

    global counter

    if counter % settings['display_counter_every'] == 0:
        if settings['display_counter']:
            print(counter)
    counter += 1

    if system.populations is None:
        pl, converged = sim.lib.simulate_func(system, dtime)
        sim_arrays = sim.lib.convolve_irf(pl, dtime, irf_args)

    else:
        if powers is None:

            transient, converged = sim.lib.refined_simulation(
                system, to, light, N_coarse=N_coarse)
            pl = system.PLsig(transient)
            sim_arrays = sim.lib.convolve_irf(pl, dtime, irf_args)
            #sim_arrays /= max(sim_arrays)
            #data_arrays /= max(data_arrays)

        else:
            for i, power in enumerate(powers):
                if which == 'pulse':
                    light = light.updated_with(pulse={'power': power})
                elif which == 'cw':
                    light = light.updated_with(cw={'power': power})
                else:
                    print('parameter "which" should be "pulse" or "cw".')

                transient, converged = sim.lib.refined_simulation(
                    system, to, light, N_coarse=N_coarse)
                pl_at_this_power = system.PLsig(transient)

                if i == 0:
                    pl = pl_at_this_power
                else:
                    pl = np.vstack((pl, pl_at_this_power))
            sim_arrays = sim.lib.convolve_irf(pl, dtime, irf_args)

    if roll_criterion == 'max':
        al_data_arrays = kin_kit.align_by_max(data_arrays,
                                              dtime,
                                              avgnum=maxavgnum,
                                              value=roll_value)

        al_sim_arrays = kin_kit.align_by_max(sim_arrays,
                                             dtime,
                                             avgnum=maxavgnum,
                                             value=roll_value)

    elif roll_criterion == 'steep':
        al_data_arrays = kin_kit.align_by_steep(data_arrays,
                                                dtime,
                                                avgnum=maxavgnum,
                                                value=roll_value)

        al_sim_arrays = kin_kit.align_by_steep(sim_arrays,
                                               dtime,
                                               avgnum=maxavgnum,
                                               value=roll_value)

    else:
        print('Roll_criterion must be max or steep.')

    sim_arrays = kin_kit.make_2d(sim_arrays)
    data_arrays = kin_kit.make_2d(data_arrays)
    if not norm:
        # divide all traces by maximum value of highest-power trace
        sim_arrays /= max(sim_arrays[np.argmax(powers)])
        data_arrays /= max(data_arrays[np.argmax(powers)])

    if limits is not None:
        al_data_arrays = slice_by_time(al_data_arrays, dtime, limits[0],
                                       limits[1])
        al_sim_arrays = slice_by_time(al_sim_arrays, dtime, limits[0],
                                      limits[1])

    diffs = elementwise_diff(al_data_arrays,
                             al_sim_arrays,
                             norm=norm,
                             comparison=comparison,
                             absolute=absolute)

    #print("diff : %0.3e"%(np.sum(diffs**2)/(to['N']/to['subsample'])))

    if condensed_output:
        if verbose:
            print(np.average(np.sum(diffs**2)))
        return np.sum(diffs**2)
    else:
        if verbose:
            print(np.average(diffs.flatten()))
        return diffs.flatten()
Exemplo n.º 2
0
def MultiPowerViz(system,
                  p1,
                  p2,
                  p3,
                  p4,
                  p5,
                  p6,
                  p7,
                  p8,
                  p9,
                  p10,
                  p11,
                  p12,
                  p13,
                  p14,
                  p15,
                  p16,
                  p17,
                  p18,
                  p19,
                  p20,
                  to=sim.time.linear(),
                  refined=True,
                  N_coarse=500,
                  pulse_power=1,
                  cw_power=0,
                  which=None,
                  irf_args={'fwhm': 55 * ps},
                  data=None,
                  ids=['one', 'two'],
                  power_unit='microWatt',
                  light=sim.lib.Excitation(),
                  align_by='steep',
                  avgnum=5,
                  xmin=0.1,
                  xmax=None,
                  ymin=1e-3,
                  ymax=1.2):
    """
    more functionality to allow for CW and pulsed power variations
    """
    args = p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14,\
        p15, p16, p17, p18, p19, p20,
    param_names = system.params().keys()
    trunc_args = args[:len(list(param_names))]
    params = kin_kit.dict_from_list(trunc_args, param_names)
    system.update(
        **params
    )  # system is updated according to the parameters provided as *args

    #--- Creating Time Array
    dtime = to['array'][::to['subsample']]

    if which is None:
        pulse_power *= units[power_unit]
        cw_power *= units[power_unit]
        light = light.updated_with(pulse={'power': pulse_power},
                                   cw={'power': cw_power})

        if refined:
            transient, converged = sim.lib.refined_simulation(
                system, to, light, N_coarse=N_coarse)
        else:
            transient, converged = sim.lib.simulate_until_steady(
                system, to, light)

        pl = kin_kit.make_2d(system.PLsig(transient))
        sims = sim.lib.convolve_irf(pl, dtime, args=irf_args)

        # Aligns data with sim either by max. or steep
        if align_by == 'steep':
            aligned_sims = kin_kit.align_by_steep(sims,
                                                  dtime,
                                                  value=0.5 * ns,
                                                  avgnum=avgnum)

        elif align_by == 'max':
            aligned_sims = kin_kit.align_by_max(sims,
                                                dtime,
                                                value=0.5 * ns,
                                                avgnum=avgnum)
        else:
            print('\'align_by\' must be \'steep\' or \'max\'')

        aligned_sims = kin_kit.make_2d(aligned_sims)

        fig = None

        data_ended = False
        sims_ended = False
        for i in range(20):
            if data is None:
                pass
            else:
                data = kin_kit.make_2d(data)
                try:
                    d = data[i]
                    fig = art.plot3scales.plot(dtime,
                                               d,
                                               sys_obj=None,
                                               t_dict=None,
                                               annotate=False,
                                               fig=fig,
                                               linewidth=1,
                                               color=color_range[i],
                                               mlabel='data_%s' % (ids[i]),
                                               xmin=xmin,
                                               xmax=xmax,
                                               ymin=ymin,
                                               ymax=ymax)
                except IndexError:
                    data_ended = True
                    pass

                try:
                    aligned_sim = aligned_sims[i]
                    art.plot3scales.plot(dtime,
                                         aligned_sim,
                                         system,
                                         t_dict=to,
                                         ivtype='none',
                                         annotate=True,
                                         fig=fig,
                                         ResetColorCyc=i == 0,
                                         color=color_range[i],
                                         linewidth=8,
                                         opaq=0.4,
                                         mlabel='sim_%s' % (ids[i]),
                                         xmin=xmin,
                                         xmax=xmax,
                                         ymin=ymin,
                                         ymax=ymax)

                except IndexError:
                    sims_ended = True
                    pass

                if sims_ended and data_ended:
                    break
        return

    else:
        fig = None
        data_ended = False
        for i in range(20):
            if data is None:
                pass
            else:
                data = kin_kit.make_2d(data)
                try:
                    d = data[i]
                    fig = art.plot3scales.plot(dtime,
                                               d,
                                               sys_obj=None,
                                               t_dict=None,
                                               annotate=False,
                                               fig=fig,
                                               linewidth=1,
                                               color=color_range[i],
                                               mlabel='data_%s' % (ids[i]),
                                               xmin=xmin,
                                               xmax=xmax,
                                               ymin=ymin,
                                               ymax=ymax)
                except IndexError:
                    data_ended = True
                    pass

                if data_ended:
                    break

        if which == 'pulse':
            var_power = np.array(pulse_power) * units[power_unit]
            set_power = cw_power * units[power_unit]

        if which == 'cw':
            var_power = np.array(cw_power) * units[power_unit]
            set_power = pulse_power * units[power_unit]

        for p, power in enumerate(var_power):
            if which == 'pulse':
                light = light.updated_with(pulse={'power': power},
                                           cw={'power': set_power})
            elif which == 'cw':
                light = light.updated_with(pulse={'power': set_power},
                                           cw={'power': power})
            else:
                print(' "which" should be "cw" or "pulse" ')
            #print('cw_power ', light.cw_power)
            if refined:
                transient, converged = sim.lib.refined_simulation(
                    system, to, light, N_coarse=N_coarse)
            else:
                transient, converged = sim.lib.simulate_until_steady(
                    system, to, light)

            pl = system.PLsig(transient)
            sims = sim.lib.convolve_irf(pl, dtime, args=irf_args)

            # Aligns data with sim either by max. or steep
            if align_by == 'steep':
                aligned_sims = kin_kit.align_by_steep(sims,
                                                      dtime,
                                                      value=0.5 * ns,
                                                      avgnum=avgnum)

            elif align_by == 'max':
                aligned_sims = kin_kit.align_by_max(sims,
                                                    dtime,
                                                    value=0.5 * ns,
                                                    avgnum=avgnum)
            else:
                print('\'align_by\' must be \'steep\' or \'max\'')

            art.plot3scales.plot(dtime,
                                 aligned_sims,
                                 system,
                                 t_dict=to,
                                 ivtype='none',
                                 annotate=True,
                                 fig=fig,
                                 ResetColorCyc=i == 0,
                                 color=color_range[p],
                                 linewidth=8,
                                 opaq=0.4,
                                 mlabel='sim_%s' % (ids[p]),
                                 xmin=xmin,
                                 xmax=xmax,
                                 ymin=ymin,
                                 ymax=ymax)

    return
Exemplo n.º 3
0
def FuncViz(system,
            p1,
            p2,
            p3,
            p4,
            p5,
            p6,
            p7,
            p8,
            p9,
            p10,
            p11,
            p12,
            p13,
            p14,
            p15,
            p16,
            p17,
            p18,
            p19,
            p20,
            to=sim.time.linear(),
            N_coarse=500,
            power=1e-6,
            irf_args={},
            data=None,
            power_list=[1],
            power_unit='microWatt',
            align_by='steep',
            avgnum=5,
            slidepower=False,
            xmin=0.1,
            xmax=None,
            ymin=1e-3,
            ymax=1.2):

    args = p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14,\
        p15, p16, p17, p18, p19, p20,
    param_names = system.params().keys()
    trunc_args = args[:len(list(param_names))]
    params = kin_kit.dict_from_list(trunc_args, param_names)
    system.update(
        **params
    )  # system is updated according to the parameters provided as *args

    #--- Creating Time Array
    dtime = to['array'][::to['subsample']]

    pl = system.PLsig(dtime)

    sims = sim.lib.convolve_irf(pl, dtime, irf_args)

    # Aligns data with sim either by max. or steep
    if align_by == 'steep':
        aligned_sims = kin_kit.align_by_steep(sims,
                                              dtime,
                                              value=0.5 * ns,
                                              avgnum=avgnum)

    elif align_by == 'max':
        aligned_sims = kin_kit.align_by_max(sims,
                                            dtime,
                                            value=0.5 * ns,
                                            avgnum=avgnum)
    else:
        print('\'align_by\' must be \'steep\' or \'max\'')
    aligned_sims = kin_kit.make_2d(aligned_sims)

    fig = None
    data_ended = False
    sims_ended = False
    for i in range(20):
        if data is None:
            pass
        else:
            data = kin_kit.make_2d(data)
            try:
                d = data[i]
                fig = art.plot3scales.plot(dtime,
                                           d,
                                           sys_obj=None,
                                           t_dict=None,
                                           annotate=False,
                                           fig=fig,
                                           linewidth=1,
                                           color=color_range[i],
                                           mlabel='data_%0.3f' %
                                           (power_list[i]),
                                           xmin=xmin,
                                           xmax=xmax,
                                           ymin=ymin,
                                           ymax=ymax)
            except IndexError:
                data_ended = True
                pass

            try:
                aligned_sim = aligned_sims[i]
                art.plot3scales.plot(dtime,
                                     aligned_sim,
                                     system,
                                     t_dict=to,
                                     ivtype='none',
                                     annotate=True,
                                     fig=fig,
                                     ResetColorCyc=i == 0,
                                     color=color_range[i],
                                     linewidth=8,
                                     opaq=0.4,
                                     mlabel='sim_%0.3f' % (power_list[i]),
                                     xmin=xmin,
                                     xmax=xmax,
                                     ymin=ymin,
                                     ymax=ymax)
            except IndexError:
                sims_ended = True
                pass

            if sims_ended and data_ended:
                break

    return
Exemplo n.º 4
0
def MonoViz(system,
            p1,
            p2,
            p3,
            p4,
            p5,
            p6,
            p7,
            p8,
            p9,
            p10,
            p11,
            p12,
            p13,
            p14,
            p15,
            p16,
            p17,
            p18,
            p19,
            p20,
            to=sim.time.linear(),
            N_coarse=500,
            pulse_power=1e-6,
            irf_args={},
            data=None,
            power_unit='microWatt',
            light=sim.lib.Excitation(),
            align_by='steep',
            avgnum=5,
            xmin=0.1,
            xmax=None,
            ymin=1e-3,
            ymax=1.2):

    args = p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14,\
        p15, p16, p17, p18, p19, p20,
    param_names = system.params().keys()
    trunc_args = args[:len(list(param_names))]
    params = kin_kit.dict_from_list(trunc_args, param_names)
    system.update(
        **params
    )  # system is updated according to the parameters provided as *args

    #--- Creating Time Array
    dtime = to['array'][::to['subsample']]

    if isinstance(pulse_power, np.float) or isinstance(pulse_power, np.int):
        power_list = [pulse_power]
        pulse_power *= units[power_unit]
        light = light.updated_with(pulse={'power': pulse_power})
        transient, converged = sim.lib.refined_simulation(system,
                                                          to,
                                                          light,
                                                          N_coarse=N_coarse)
        pl = system.PLsig(transient)

    elif isinstance(pulse_power, list):
        print('list')
        power_list = pulse_power
        for i, power in enumerate(power_list):
            power *= units[power_unit]
            light = light.updated_with(pulse={'power': power})
            transient, converged = sim.lib.refined_simulation(
                system, to, light, N_coarse=N_coarse)
            pl_at_this_power = system.PLsig(transient)

            if i == 0:
                pl = pl_at_this_power
            else:
                pl = np.vstack((pl, pl_at_this_power))

    sims = sim.lib.convolve_irf(pl, dtime, irf_args)
    # Aligns data with sim either by max. or steep
    if align_by == 'steep':
        aligned_sims = kin_kit.align_by_steep(sims,
                                              dtime,
                                              value=0.5 * ns,
                                              avgnum=avgnum)

    elif align_by == 'max':
        aligned_sims = kin_kit.align_by_max(sims,
                                            dtime,
                                            value=0.5 * ns,
                                            avgnum=avgnum)
    else:
        print('\'align_by\' must be \'steep\' or \'max\'')
    aligned_sims = kin_kit.make_2d(aligned_sims)

    fig = None
    data_ended = False
    sims_ended = False
    for i in range(20):
        if data is None:
            pass
        else:
            data = kin_kit.make_2d(data)
            try:
                d = data[i]
                fig = art.plot3scales.plot(dtime,
                                           d,
                                           sys_obj=None,
                                           t_dict=None,
                                           annotate=False,
                                           fig=fig,
                                           linewidth=1,
                                           color=color_range[i],
                                           mlabel='data_%0.3f' %
                                           (power_list[i]),
                                           xmin=xmin,
                                           xmax=xmax,
                                           ymin=ymin,
                                           ymax=ymax)

            except IndexError:
                data_ended = True
                pass

            try:
                aligned_sim = aligned_sims[i]
                art.plot3scales.plot(dtime,
                                     aligned_sim,
                                     system,
                                     t_dict=to,
                                     ivtype='none',
                                     annotate=True,
                                     fig=fig,
                                     ResetColorCyc=i == 0,
                                     color=color_range[i],
                                     linewidth=8,
                                     opaq=0.4,
                                     mlabel='sim_%0.3f' % (power_list[i]),
                                     xmin=xmin,
                                     xmax=xmax,
                                     ymin=ymin,
                                     ymax=ymax)

            except IndexError:
                sims_ended = True
                pass

            if sims_ended and data_ended:
                break

    return