text:
import os

import lmfit
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from ImagingReso._utilities import ev_to_s
from cycler import cycler
from lmfit import Model
from lmfit.models import LinearModel
from scipy.interpolate import interp1d

import ResoFit._utilities as fit_util
from ResoFit.model import cole_windsor
from ResoFit.model import cole_windsor_jparc
from ResoFit.model import ikeda_carpenter
from ResoFit.model import ikeda_carpenter_jparc
from ResoFit.model import loglog_linear
from ResoFit.model import pseudo_voigt

# import ImagingReso._utilities as reso_util

__file_path = os.path.abspath(os.path.dirname(__file__))
_rel_path_to_proton = 'data/_data_for_tutorial/proton_pulse/waveform_20170901.txt'
proton_path = os.path.join(__file_path, _rel_path_to_proton)

t_min_us = 5e-2
t_max_us = 183.7
t_step_us = 0.01
t_nbr = round((t_max_us - t_min_us) / t_step_us) + 1

mcnp_plot_lim_dict = {'x_min': 0,
                      'x_max': 5,
                      'y_min': -0.05,
                      'y_max': 1.05}
plot_x_range = mcnp_plot_lim_dict['x_max'] - mcnp_plot_lim_dict['x_min']
default_cycler = cycler('color',
                        ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f',
                         '#bcbd22', '#17becf'])
# fmt_list = ['o--', 'v--', 's--', 'p--', 'D--', 'h--', '^--', '<--', '>--', 'o--']
marker_list = ['o', 'v', 's', '^', 'D', 'h', '<', '>', 'x', 'p']

class NeutronPulse(object):

    def __init__(self, path, model_index=1):
        """
        Load total neutron pulse shape from .dat file

        :param path: path to the '.dat' file
        :type path: str
        """
        self.shape_total_df = _load_neutron_total_shape(path)
        self.shape_dict_mcnp = None
        self.shape_df_mcnp = None
        self.shape_df_mcnp_norm = None
        self.shape_df_interp = None
        self.shape_tof_df_interp = None
        self.shape_tof_df_dir = None

        self.result_shape_fit = None
        self.param_df_dir = None
        self.param_df = None
        self.linear_df = None
        self.linear_df_dir = None
        self.model_param_names = None
        self.e_min = None
        self.e_max = None
        self.t_us_mcnp = None
        self.t_us_conv_proton = np.linspace(t_min_us, t_max_us, t_nbr).round(3)
        self.result_neutron_folder = None
        self._energy_list = None
        self._energy_list_dropped = None

        self.model_map = {1: 'ikeda_carpenter',
                          2: 'cole_windsor',
                          3: 'pseudo_voigt',
                          4: 'ikeda_carpenter_jparc',
                          5: 'cole_windsor_jparc',
                          }
        self.model_index = None
        self.model_used = None
        self.model = None
        self.__set_model(model_index)

        if self.result_neutron_folder is None:
            self.result_neutron_folder = self._check_and_make_subdir('result', 'neutron_pulse', self.model_used)

        self.proton_pulse = ProtonPulse(path=proton_path)

    def load_shape_each(self, path, save_each=False):
        """
        Load each eV neutron pulse shape from .dat file

        :param save_each:
        :type save_each:
        :param path: path to the '.dat' file
        :type path: str
        """
        self.shape_dict_mcnp = _load_neutron_each_shape(path, export=save_each)
        self.shape_df_mcnp, self.shape_df_mcnp_norm = _shape_dict_to_dfs(self.shape_dict_mcnp,
                                                                         t_max=t_max_us)
        self._energy_list = list(self.shape_df_mcnp.set_index('t_us').columns)
        self.t_us_mcnp = np.array(self.shape_df_mcnp['t_us']).round(5)

    def _form_energy_list_dropped(self, e_min, e_max):
        assert self._energy_list is not None
        _energy_list_dropped = []
        for _each_e in self._energy_list:
            if e_min <= _each_e <= e_max:
                _energy_list_dropped.append(_each_e)
        _energy_list_dropped.sort()
        self._energy_list_dropped = _energy_list_dropped
        return _energy_list_dropped

    def plot_shape_total(self, x1_type='energy', x2_type='lambda', source_to_detector_m=None):
        """
        Plot the total beam shape obtained from MCNPX simulation

        :param x1_type:
        :type x1_type:
        :param x2_type:
        :type x2_type:
        :param source_to_detector_m:
        :type source_to_detector_m:
        :return: plot
        :rtype: matplotlib
        """
        x_type_list = ['energy', 'lambda', 'time', 'none']
        if x1_type not in x_type_list:
            raise ValueError("Please specify the x-axis type using one from '{}'.".format(x_type_list))
        if x2_type not in x_type_list:
            raise ValueError("Please specify the x-axis type using one from '{}'.".format(x_type_list))
        if x1_type == 'time' or x2_type == 'time':
            if source_to_detector_m is None:
                raise ValueError("Please specify the source-to-detector distance in m.")
        if x1_type == x2_type:
            x2_type = 'none'

        fig, ax1 = plt.subplots()
        if x1_type == 'energy':
            ax1.loglog(self.shape_total_df['E_eV'], self.shape_total_df['f(E)'], 'b.')
            ax1.set_xlabel('Energy (eV)', color='b')
        elif x1_type == 'lambda':
            ax1.loglog(self.shape_total_df['l_angstrom'], self.shape_total_df['f(l)'], 'b.')
            ax1.set_xlabel(u"Wavelength (\u212B)", color='b')
            ax1.invert_xaxis()
        elif x1_type == 'time':
            ax1.loglog(ev_to_s(array=self.shape_total_df['E_eV'],
                               offset_us=0,
                               source_to_detector_m=source_to_detector_m) * 1e6,
                       self.shape_total_df['f(l)'], 'b.')
            ax1.set_xlabel(u"Time-of-flight (\u03BCs)", color='b')
            ax1.invert_xaxis()
        ax1.set_ylabel('Flux (n/sterad/pulse)')
        ax1.tick_params('x', colors='b', which='both')
        ax1.grid(axis='x', which='both', color='b', alpha=0.3)
        ax1.grid(axis='y', which='major', alpha=0.3)
        if x2_type != 'none':
            ax2 = ax1.twiny()
            if x2_type == 'energy':
                ax2.loglog(self.shape_total_df['E_eV'], self.shape_total_df['f(E)'], 'rx')
                ax2.set_xlabel('Energy (eV)', color='r')
            elif x2_type == 'lambda':
                ax2.loglog(self.shape_total_df['l_angstrom'], self.shape_total_df['f(l)'], 'rx')
                ax2.set_xlabel(u"Wavelength (\u212B)", color='r')
                ax2.invert_xaxis()
            elif x2_type == 'time':
                ax2.loglog(ev_to_s(array=self.shape_total_df['E_eV'],
                                   offset_us=0,
                                   source_to_detector_m=source_to_detector_m) * 1e6,
                           self.shape_total_df['f(l)'], 'rx')
                ax2.set_xlabel(u"Time-of-flight (\u03BCs)", color='r')
                ax2.invert_xaxis()
            ax2.grid(axis='x', which='both', color='r', alpha=0.3)
            ax2.tick_params('x', colors='r', which='both')
        # ax1.set_title('Neutron total flux', y=1.08, loc='left')
        return fig

    def plot_shape_mcnp(self, e_min, e_max, logy=False, norm=False, marker='o', ax_mpl=None, plt_arrow=True):
        """
        Plot each eV beam shape obtained from MCNPX simulation

        :param e_min:
        :type e_min:
        :param e_max:
        :type e_max:
        :param logy:
        :type logy:
        :param norm:
        :type norm:
        :param marker:
        :type marker:
        :param ax_mpl:
        :type ax_mpl:
        :param plt_arrow:
        :type plt_arrow:
        :return:
        :rtype:
        """
        assert self.shape_dict_mcnp is not None
        if norm:
            _shape_df = self.shape_df_mcnp_norm
            _y_label = 'Ratio out of max flux of each energy'
        else:
            _shape_df = self.shape_df_mcnp
            _y_label = 'Flux (n/sterad/pulse)'

        # Only the energy provided by MCNPX simulation will be filtered
        _energy_list_dropped = self._form_energy_list_dropped(e_min=e_min, e_max=e_max)
        if ax_mpl is None:
            fig, ax_mpl = plt.subplots()
        ax_mpl.set_prop_cycle(default_cycler)
        for each in _energy_list_dropped:
            if logy:
                ax_mpl.semilogy(_shape_df['t_us'],
                                _shape_df[each],
                                linestyle='-',
                                marker=marker,
                                # fmt=marker,
                                label=str(each) + ' eV (MCNPX)')
            else:
                ax_mpl.plot(_shape_df['t_us'],
                            _shape_df[each],
                            linestyle='-',
                            marker=marker,
                            # fmt=marker,
                            label=str(each) + ' eV (MCNPX)')
        ax_mpl.set_ylabel(_y_label)
        ax_mpl.set_xlabel(u'Time (\u03BCs)')
        ax_mpl.grid()
        if len(_energy_list_dropped) <= 7:
            ax_mpl.legend()
        else:
            if plt_arrow:
                _plot_ev_arrow_as_legend(ax=ax_mpl, ev_list=_energy_list_dropped)
        ax_mpl.set_title('Energy dependent neutron pulse shape (MCNPX)')
        ax_mpl.set_xlim(left=mcnp_plot_lim_dict['x_min'], right=mcnp_plot_lim_dict['x_max'])
        return ax_mpl

    def plot_shape_interp(self, e_ev, source_to_detector_m, conv_proton, proton_params={},
                          t_interp=None, logy=False, norm=False, for_sum=False,
                          marker='o', ax_mpl=None, plt_arrow=True):
        """
        Plot each eV beam shape obtained from the fitting approach

        :param e_ev:
        :type e_ev:
        :param source_to_detector_m:
        :type source_to_detector_m:
        :param conv_proton:
        :type conv_proton:
        :param proton_params:
        :type proton_params:
        :param t_interp:
        :type t_interp:
        :param logy:
        :type logy:
        :param norm:
        :type norm:
        :param for_sum:
        :type for_sum:
        :param marker:
        :type marker:
        :param ax_mpl:
        :type ax_mpl:
        :param plt_arrow:
        :type plt_arrow:
        :return:
        :rtype:
        """
        if t_interp is None:
            t_interp = self.t_us_mcnp
        self._make_shape(e_ev=e_ev, t_interp=t_interp, norm=norm, for_sum=for_sum,
                         source_to_detector_m=source_to_detector_m, print_tof=False,
                         conv_proton=conv_proton, proton_params=proton_params)
        _shape_df_interp = self.shape_df_interp

        _y_label = 'Flux (n/sterad/pulse)'
        if norm:
            _y_label = 'Ratio out of max flux of each energy'
        _for_sum_s = ''
        if for_sum:
            _for_sum_s = ' for_sum'
        _norm_s = ''
        if norm:
            _norm_s = ' norm'
        _conv_proton_s = ''
        if conv_proton:
            _conv_proton_s = ' proton'
        _proton_param_s = ''
        for _param in proton_params.keys():
            _proton_param_s = _proton_param_s + '_' + _param + '_' + str(proton_params[_param])
        _details_s = _norm_s + _conv_proton_s + _proton_param_s + _for_sum_s
        _title_s = 'Energy dependent neutron pulse shape (interp.{})'.format(_details_s)

        _energy_interp_list = list(_shape_df_interp.set_index('t_us').columns)
        _energy_interp_list.sort()
        if ax_mpl is None:
            fig, ax_mpl = plt.subplots()
        ax_mpl.set_prop_cycle(default_cycler)
        for each in _energy_interp_list:
            if logy:
                ax_mpl.semilogy(_shape_df_interp['t_us'],
                                _shape_df_interp[each],
                                linestyle='--',
                                marker=marker,
                                # fmt=fmt,
                                mfc='none',
                                label=str(each) + ' eV (interp.)')
            else:
                ax_mpl.plot(_shape_df_interp['t_us'],
                            _shape_df_interp[each],
                            linestyle='--',
                            marker=marker,
                            # fmt=fmt,
                            mfc='none',
                            label=str(each) + ' eV (interp.)')
        ax_mpl.set_ylabel(_y_label)
        ax_mpl.set_xlabel(u'Time (\u03BCs)')
        ax_mpl.grid()
        if len(_energy_interp_list) <= 7:
            ax_mpl.legend()
        else:
            if plt_arrow:
                _plot_ev_arrow_as_legend(ax=ax_mpl, ev_list=_energy_interp_list)

        ax_mpl.set_title(_title_s)
        return ax_mpl

    def plot_shape_each_compare(self, e_min, e_max, source_to_detector_m, conv_proton, proton_params={},
                                t_interp=None, logy=False, norm=False, for_sum=False):
        """
        Plot each eV beam shape obtained from MCNPX simulation and current fitting approach to compare

        :param e_min:
        :type e_min:
        :param e_max:
        :type e_max:
        :param source_to_detector_m:
        :type source_to_detector_m:
        :param conv_proton:
        :type conv_proton:
        :param proton_params:
        :type proton_params:
        :param t_interp:
        :type t_interp:
        :param logy:
        :type logy:
        :param norm:
        :type norm:
        :param for_sum:
        :type for_sum:
        :return:
        :rtype:
        """
        if t_interp is None:
            t_interp = self.t_us_mcnp
        _energy_list_dropped = self._form_energy_list_dropped(e_min=e_min, e_max=e_max)
        ax_mcnp = self.plot_shape_mcnp(e_min=e_min, e_max=e_max, norm=norm, logy=logy, plt_arrow=False)
        ax = self.plot_shape_interp(e_ev=_energy_list_dropped,
                                    source_to_detector_m=source_to_detector_m,
                                    conv_proton=conv_proton, proton_params=proton_params,
                                    t_interp=t_interp, logy=logy, norm=norm, for_sum=for_sum, ax_mpl=ax_mcnp)
        ax.set_title('Energy dependent neutron pulse shape MCNPX vs. interp.')
        if len(_energy_list_dropped) <= 7:
            ax.legend()
        ax.grid()

        return ax

    def plot_tof_shape_interp(self, e_ev, source_to_detector_m, conv_proton, proton_params={},
                              t_interp=None, for_sum=False, logy=False, norm=False, marker='o', ax_mpl=None,
                              plt_arrow=True):
        """
        Plot each eV beam shape obtained from the fitting approach

        :param e_ev:
        :type e_ev:
        :param source_to_detector_m:
        :type source_to_detector_m:
        :param conv_proton:
        :type conv_proton:
        :param proton_params:
        :type proton_params:
        :param t_interp:
        :type t_interp:
        :param for_sum:
        :type for_sum:
        :param logy:
        :type logy:
        :param norm:
        :type norm:
        :param marker:
        :type marker:
        :param ax_mpl:
        :type ax_mpl:
        :param plt_arrow:
        :type plt_arrow:
        :return:
        :rtype:
        """
        if isinstance(e_ev, int) or isinstance(e_ev, float):
            e_ev = [e_ev]
        e_ev.sort()
        if t_interp is None:
            t_interp = self.t_us_mcnp
        self._make_shape(e_ev=e_ev, t_interp=t_interp, for_sum=for_sum, norm=norm,
                         source_to_detector_m=source_to_detector_m, print_tof=False,
                         conv_proton=conv_proton, proton_params=proton_params)
        _shape_tof_df_interp = self.shape_tof_df_interp
        _y_label = 'Flux (n/sterad/pulse)'

        if norm:
            _y_label = 'Ratio out of max flux of each energy'
        _x_tag = 'tof_us'
        _for_sum_s = ''
        if for_sum:
            _for_sum_s = ' for_sum'
        _norm_s = ''
        if norm:
            _norm_s = ' norm'
        _conv_proton_s = ''
        if conv_proton:
            _conv_proton_s = ' proton'
        _proton_param_s = ''
        for _param in proton_params.keys():
            _proton_param_s = _proton_param_s + '_' + _param + '_' + str(proton_params[_param])
        _details_s = _norm_s + _conv_proton_s + _proton_param_s + _for_sum_s
        _title_s = 'Energy dependent neutron pulse shape (interp.{})'.format(_details_s)

        if ax_mpl is None:
            fig, ax_mpl = plt.subplots()
        ax_mpl.set_prop_cycle(default_cycler)
        for each_e in e_ev:
            if not for_sum:
                _x_tag = str(each_e) + '_tof_us'
            if logy:
                ax_mpl.semilogy(_shape_tof_df_interp[_x_tag],
                                _shape_tof_df_interp[str(each_e)],
                                linestyle='--',
                                marker=marker,
                                mfc='none',
                                label=str(each_e) + ' eV (interp.{})'.format(_proton_param_s))
            else:
                ax_mpl.plot(_shape_tof_df_interp[_x_tag],
                            _shape_tof_df_interp[str(each_e)],
                            linestyle='--',
                            marker=marker,
                            mfc='none',
                            label=str(each_e) + ' eV (interp.{})'.format(_proton_param_s))
        if len(e_ev) <= 7:
            ax_mpl.legend()
        else:
            if plt_arrow:
                _plot_ev_arrow_as_legend(ax=ax_mpl, ev_list=e_ev)
        ax_mpl.set_ylabel(_y_label)
        ax_mpl.set_xlabel(u'Time (\u03BCs)')
        ax_mpl.grid()
        ax_mpl.set_title(_title_s)
        return ax_mpl

    def plot_proton_conv(self, e_ev, source_to_detector_m, conv_proton, sigma_list, tof=True,
                         t_interp=None, for_sum=False, logy=False, norm=False, plt_arrow=True):
        _list_of_dicts = _break_proton_param_list_to_dict(proton_param_list=sigma_list, proton_param_name='sigma')
        fig, ax1 = plt.subplots()
        for i, _e_param_dict in enumerate(_list_of_dicts):
            if tof:
                ax1 = self.plot_tof_shape_interp(e_ev=e_ev, source_to_detector_m=source_to_detector_m,
                                                 conv_proton=conv_proton, proton_params=_e_param_dict,
                                                 t_interp=t_interp, for_sum=for_sum, logy=logy, norm=norm, ax_mpl=ax1,
                                                 plt_arrow=plt_arrow, marker=marker_list[i])
            else:
                ax1 = self.plot_shape_interp(e_ev=e_ev, source_to_detector_m=source_to_detector_m,
                                             conv_proton=conv_proton, proton_params=_e_param_dict,
                                             t_interp=t_interp, for_sum=for_sum, logy=logy, norm=norm, ax_mpl=ax1,
                                             plt_arrow=plt_arrow, marker=marker_list[i])
        _for_sum_s = ''
        if for_sum:
            _for_sum_s = ' for_sum'
        _title_s = 'Energy dependent neutron pulse shape (interp.{}) with proton convolved'.format(_for_sum_s)
        ax1.set_title(_title_s)

        return ax1

    def make_shape(self, e_ev, source_to_detector_m, conv_proton, proton_params={},
                   t_interp=None, for_sum=False, norm=False, overwrite_csv=False):
        assert self.linear_df is not None
        assert self.model is not None
        if isinstance(e_ev, int) or isinstance(e_ev, float):
            e_ev = [e_ev]
        e_ev.sort()
        if t_interp is None:
            t_interp = self.t_us_mcnp
            # t_interp = self.t_us
        if isinstance(t_interp, int) or isinstance(t_interp, float):
            raise ValueError("'t_interp' must be a list or array.")
        t_interp.sort()

        # construct the str for the file name
        _distance_s = '_' + str(source_to_detector_m) + 'm'
        _for_sum_s = ''
        if for_sum:
            _for_sum_s = '_for_sum'
        _norm_s = ''
        if norm:
            _norm_s = '_norm'
        _conv_proton_s = ''
        if conv_proton:
            _conv_proton_s = '_proton'
        _proton_param_s = ''
        for _param in proton_params.keys():
            _proton_param_s = _proton_param_s + '_' + _param + '_' + str(proton_params[_param])

        _e_min = e_ev[0]
        _e_max = e_ev[-1]
        _e_nbr = len(e_ev) - 1
        _e_step = (_e_max - _e_min) / _e_nbr

        _e_str = '_eV_' + str(_e_min) + '_' + str(_e_max) + '_' + str(_e_step)

        _t_min = t_min_us
        _t_max = t_max_us
        _t_step = t_step_us

        _t_str = '_us_' + str(_t_min) + '_' + str(_t_max) + '_' + str(_t_step)

        assert self.model_used is not None
        _model_s = '_' + self.model_used + '.csv'

        _filename = 'TOF_shape' + _e_str + _t_str + _norm_s + _conv_proton_s + _proton_param_s \
                    + _for_sum_s + _distance_s + _model_s
        _shape_tof_df_dir = os.path.join(self.result_neutron_folder, _filename)
        self.shape_tof_df_dir = _shape_tof_df_dir

        # File exists
        if os.path.isfile(_shape_tof_df_dir):
            print("\u2705 '{}' exists...".format(_shape_tof_df_dir))
            if overwrite_csv:
                # Override==True, perform making shape and overwrite the .csv file
                print("File overwriting...")
                print("New beam shape generation starts...")
                # Making starts
                self._make_shape(e_ev=e_ev, t_interp=t_interp, for_sum=for_sum, norm=norm,
                                 source_to_detector_m=source_to_detector_m,
                                 save_dir=_shape_tof_df_dir,
                                 print_tof=True,
                                 conv_proton=conv_proton,
                                 proton_params=proton_params,
                                 )
                print("File overwritten.")
            else:
                # Override==False, read the .csv file
                self.shape_tof_df_interp = pd.read_csv(_shape_tof_df_dir)
                print("TOF neutron beam shape file loaded.")
                self.proton_pulse.make_new_shape(proton_params=proton_params)  # Making sure proton shape params updated

        # File not exists, perform fitting
        else:
            print("\u274C No previous TOF neutron beam shape file named '{}' detected.".format(_shape_tof_df_dir))
            print("Beam shape generation starts...")
            # Making starts
            self._make_shape(e_ev=e_ev, t_interp=t_interp, for_sum=for_sum, norm=norm,
                             source_to_detector_m=source_to_detector_m,
                             save_dir=_shape_tof_df_dir,
                             print_tof=True,
                             conv_proton=conv_proton,
                             proton_params=proton_params,
                             )

    def _make_shape(self, e_ev, t_interp, for_sum, norm, source_to_detector_m, print_tof,
                    conv_proton, proton_params={}, save_dir=None):
        assert self.linear_df is not None
        assert self.model is not None
        if isinstance(e_ev, int) or isinstance(e_ev, float):
            e_ev = [e_ev]
        e_ev.sort()
        if t_interp is not None:
            t_interp.sort()
        else:
            t_interp = self.t_us_mcnp
        if isinstance(t_interp, int) or isinstance(t_interp, float):
            raise ValueError("'t_interp' must be a list or array.")
        # _t_shift = 0
        # if conv_proton:
        #     _t_shift = self.proton_pulse._t_shift
        #     # t used to shift convolution from 'full' to 'same'

        _param_df_interp = self._interpolate_param(e_ev=e_ev).set_index('E_eV')
        _shape_df_interp = pd.DataFrame()
        _shape_df_interp['t_us'] = t_interp
        # _shape_df_interp['t_us'] = t_interp - _t_shift
        _shape_tof_df_interp = pd.DataFrame()
        _tof_us_dict = {}
        _tof_total_us_array = []

        self.proton_pulse.make_new_shape(proton_params=proton_params)  # Making sure proton shape params updated

        if print_tof:
            print('For {} (m)'.format(source_to_detector_m))

        for _each_e in e_ev:
            _t_us, _array = self._make_single_shape(e_ev=_each_e,
                                                    t_us=t_interp,
                                                    param_df=_param_df_interp,
                                                    conv_proton=conv_proton,
                                                    )
            if not norm:
                _array = _array * _param_df_interp['f_max'][_each_e]
            _array[_array < 0] = 0
            _array = _array.round(5)
            _shape_df_interp[_each_e] = _array
            _tof_diff_us = ev_to_s(offset_us=0, source_to_detector_m=source_to_detector_m, array=_each_e) * 1e6
            if print_tof:
                print('{} (eV) neutron spent {} (us)'.format(_each_e, _tof_diff_us))
            _tof_us_dict[_each_e] = _tof_diff_us
            _current_tof_us = t_interp + _tof_diff_us

            _tof_total_us_array = np.append(_tof_total_us_array, _current_tof_us)

            if not for_sum:
                # _shape_tof_df_interp[str(_each_e) + '_tof_us'] = _current_tof_us - _t_shift
                _shape_tof_df_interp[str(_each_e) + '_tof_us'] = _t_us + _tof_diff_us
                _shape_tof_df_interp[str(_each_e)] = _array

        self.shape_df_interp = _shape_df_interp
        self.tof_us_dict = _tof_us_dict

        _tof_total_us_array.sort()  # list of all time that exist in all energy

        if for_sum:
            # _shape_tof_df_interp['tof_us'] = _tof_total_us_array - _t_shift
            if print_tof is True:
                print('Making shape for:')
            for _each_e in e_ev:
                __tof_diff_us = _tof_us_dict[_each_e]
                _current_t_without_tof = _tof_total_us_array - __tof_diff_us
                if print_tof is True:
                    print('{} (eV) neutron ...'.format(_each_e))
                _t_us, _array = self._make_single_shape(e_ev=_each_e,
                                                        t_us=_current_t_without_tof,
                                                        param_df=_param_df_interp,
                                                        conv_proton=conv_proton,
                                                        )
                if not norm:
                    _array = _array * _param_df_interp['f_max'][_each_e]
                _array[_array < 0] = 0
                _array = _array.round(5)
                _shape_tof_df_interp['tof_us'] = _t_us + __tof_diff_us
                _shape_tof_df_interp[str(_each_e)] = _array

        self.shape_tof_df_interp = _shape_tof_df_interp

        # Save shape_tof_df_interp as .csv
        if save_dir is not None:
            self.shape_tof_df_interp.to_csv(save_dir, index=False)
            print("TOF neutron beam shape file has been saved at '{}'".format(save_dir))

    def _make_single_shape(self, e_ev, t_us, param_df, conv_proton):
        # if not isinstance(e_ev, int) or isinstance(e_ev, float):
        #     raise ValueError("'e_ev' must be a number for single shape generation.")
        if isinstance(t_us, int) or isinstance(t_us, float):
            raise ValueError("'t_us' must be a list or array for shape interpolation.")
        # if e_ev < 1 or e_ev > 500:
        #     raise ValueError()
        t_us = np.array(t_us)
        _my_model = self.model
        for _each_param in self.model_param_names:
            _my_model.set_param_hint(_each_param, value=param_df[_each_param][e_ev])
        _params = _my_model.make_params()

        _t_shift = 0
        if not conv_proton:
            _array = _my_model.eval(_params, t=t_us)  # lmfit.model.eval() returns np.ndarray
        else:
            _t_shift = self.proton_pulse._t_shift
            # t used to shift convolution from 'full' to 'same'
            _array_for_conv_proton = _my_model.eval(_params, t=self.t_us_conv_proton)
            _proton_x = np.array(self.proton_pulse.new_shape_df['t_ns'] / 1e3 + self.t_us_conv_proton[-1])
            _proton_y = np.array(self.proton_pulse.new_shape_df['intensity'])
            _conv_y = np.convolve(_array_for_conv_proton, _proton_y, mode='full')
            _conv_x = np.append(self.t_us_conv_proton, _proton_x[1:])
            _array_function = interp1d(x=_conv_x, y=_conv_y, kind='cubic', bounds_error=False, fill_value=0)
            _array = _array_function(t_us)
            # print(t_us)
            # print(len(t_us))

        assert len(t_us) == len(_array)
        return t_us - _t_shift, _array

    def _interpolate_param(self, e_ev):

        _linear_df = self.linear_df.set_index('param_name')
        _param_df_interp = pd.DataFrame()
        _param_df_interp['E_eV'] = e_ev

        for each_param in _linear_df.index:
            _param_df_interp[each_param] = loglog_linear(x=e_ev,
                                                         slope=_linear_df['slope'][each_param],
                                                         intercept=_linear_df['intercept'][each_param])
        return _param_df_interp

    def plot_params_vs_e(self, loglog=True):
        assert self.param_df is not None
        self.param_df.set_index('E_eV').plot(loglog=loglog, style='.')
        plt.xlabel('Energy (eV)')
        plt.ylabel('Fitted parameter value')

    def fit_params(self, show_init=True, check_each=False, save_fig=False, overwrite_csv=False, loglog_fit=True):
        if self.param_df is None:
            raise ValueError("'NeutronPulse._fit_shape_proton()' must be applied before 'NeutronPulse.fit_params'")

        _e_min = str(self.e_min) + 'eV_'
        _e_max = str(self.e_max) + 'eV_'
        _model_s = self.model_used + '.csv'
        _filename = 'Loglog_linear_within_' + _e_min + _e_max + _model_s
        self.linear_df_dir = os.path.join(self.result_neutron_folder, _filename)

        # File exists
        if os.path.isfile(self.linear_df_dir):
            print("\u2705 '{}' exists...".format(self.linear_df_dir))
            if overwrite_csv:
                # Override==True, perform fitting and overwrite the .csv file
                print("File overwriting...")
                print("New fitting starts...")
                # Fitting starts
                self._fit_params(show_init=show_init,
                                 check_each=check_each,
                                 save_fig=save_fig,
                                 loglog_fit=loglog_fit)
                print("File overwritten.")
            else:
                # Override==False, read the .csv file
                self.linear_df = pd.read_csv(self.linear_df_dir)
                print("Parameters linear fitted file loaded.")

        # File not exists, perform fitting
        else:
            print("\u274C No previous fitting file detected.\nNew fitting starts...")
            # Fitting starts
            self._fit_params(show_init=show_init,
                             check_each=check_each,
                             save_fig=save_fig,
                             loglog_fit=loglog_fit)

    def _fit_params(self, show_init, check_each, save_fig, loglog_fit):

        _param_df = self.param_df
        e_log = np.log10(_param_df['E_eV'])
        param_name_list = list(_param_df.columns.drop('E_eV'))
        linear_dict = {}
        for each_param in param_name_list:
            linear_dict[each_param] = self.__fit_params(y=_param_df[each_param],
                                                        x=_param_df['E_eV'],
                                                        x_log=e_log,
                                                        name=each_param,
                                                        check_each=check_each,
                                                        show_init=show_init,
                                                        save_fig=save_fig,
                                                        loglog_fit=loglog_fit
                                                        )
        # self.linear_dict = linear_dict
        self.linear_df = self._form_linear_df(linear_dict=linear_dict, save=True)

    def _form_linear_df(self, linear_dict, save=False):
        _key_list = list(linear_dict.keys())
        linear_param_list = list(linear_dict[_key_list[0]].keys())

        _dict = {}
        for each_param in linear_param_list:
            _dict[each_param] = []
        for _key in _key_list:
            for each_param in linear_param_list:
                _dict[each_param].append(linear_dict[_key][each_param])
        _df = pd.DataFrame()
        for each_param in linear_param_list:
            _df[each_param] = _dict[each_param]
        _df.insert(0, 'param_name', _key_list)

        if save is True:
            assert self.result_neutron_folder is not None
            assert self.linear_df_dir is not None
            _df.to_csv(path_or_buf=self.linear_df_dir, index=False)
            print("Parameters linear fitting file has been saved at '{}'".format(self.linear_df_dir))

        return _df

    def __fit_params(self, y, x, x_log, name, show_init, check_each, save_fig, loglog_fit):

        # Guess to make param
        y_log = np.log10(y)
        _temp_guess_model = LinearModel()
        params = _temp_guess_model.guess(y_log, x_log)

        # Load actual loglog linear model
        my_param_model = Model(loglog_linear)
        assert my_param_model.independent_vars == ['x']
        assert my_param_model.param_names == ['slope', 'intercept']

        # Fit the model (NOTE: lmfit leastsq gives different results!!!???)
        if loglog_fit:
            # fit in loglog space
            out = _temp_guess_model.fit(y_log, params, x=x_log)
            _x_label = 'Log E (eV)'
            _y_label = 'Log value (arb. unit)'
        else:
            # fit in real space
            out = my_param_model.fit(y, params, x=x)
            _y_label = 'Parameter value (arb. unit)'
            _x_label = 'E (eV)'

        if check_each:
            # assert self.result_shape_fit is not None
            if name == 'f_max':
                if loglog_fit:
                    _y_label = 'Log flux (neutrons/s/cm2)'
                else:
                    _y_label = 'Flux (neutrons/s/cm2)'

            if show_init is True:
                out.plot(xlabel=_x_label, ylabel=_y_label)
            else:
                out.plot(xlabel=_x_label, ylabel=_y_label, initfmt='None')

            plt.title(name, fontsize=12)
            if loglog_fit is False:
                plt.yscale('log')
                plt.xscale('log')
                plt.xlim(left=self.e_min * 0.8, right=self.e_max * 1.2)
                plt.ylim(bottom=np.amin(y) * 0.8, top=np.amax(y) * 1.2)

            if save_fig:
                # Check and make dir to save
                assert self.result_neutron_folder is not None
                assert self.model_used is not None
                _model_s = self.model_used + '_' + name + '.png'
                _filename = 'Neutron_pulse_param_fit_' + _model_s
                _dir_to_save = os.path.join(self.result_neutron_folder, _filename)
                plt.savefig(_dir_to_save, dpi=300, transparent=False)
                plt.close()
            else:
                plt.show()
        elif save_fig:
            raise ValueError("'check_each' has to be 'True' in order to save figure")

        return out.best_values

    def __set_model(self, model_index):
        if model_index == 1:
            my_model = Model(ikeda_carpenter)
        elif model_index == 2:
            my_model = Model(cole_windsor)
        elif model_index == 3:
            my_model = Model(pseudo_voigt)
        elif model_index == 4:
            my_model = Model(ikeda_carpenter_jparc)
        elif model_index == 5:
            my_model = Model(cole_windsor_jparc)
        else:
            raise ValueError("Model index not exists, please refer to: '{}' ".format(self.model_map))

        self.model = my_model
        self.model_index = model_index
        self.model_used = self.model_map[model_index]
        self.model_param_names = my_model.param_names

    def fit_shape(self, e_min, e_max,
                  drop=False, norm=True,
                  show_init=True, check_each=False, save_fig=False, overwrite_csv=False):
        # [1: 'ikeda_carpenter', 2: 'cole_windsor', 3: 'pseudo_voigt']
        self.e_min = e_min
        self.e_max = e_max
        self._form_energy_list_dropped(e_min=e_min, e_max=e_max)
        # File name of fitted_param_df.csv
        assert self.model_used is not None
        _e_min = str(self.e_min) + 'eV_'
        _e_max = str(self.e_max) + 'eV_'
        _model_s = self.model_used + '.csv'
        _filename = 'Neutron_fitted_params_' + _e_min + _e_max + _model_s
        self.param_df_dir = os.path.join(self.result_neutron_folder, _filename)

        # File exists
        if os.path.isfile(self.param_df_dir):
            print("\u2705 '{}' exists...".format(self.param_df_dir))
            if overwrite_csv:
                # Override==True, perform fitting and overwrite the .csv file
                print("File overwriting...")
                print("New fitting starts...")
                # Fitting starts
                self._fit_shape_params(drop=drop, norm=norm, show_init=show_init, check_each=check_each,
                                       save_fig=save_fig)
                print("File overwritten.")
            else:
                # Override==False, read the .csv file
                self.param_df = pd.read_csv(self.param_df_dir)
                print("Fitted parameters file loaded.")

        # File not exists, perform fitting
        else:
            print("\u274C No previous fitting file detected.\nNew fitting starts...")
            # Fitting starts
            self._fit_shape_params(drop=drop, norm=norm, show_init=show_init, check_each=check_each, save_fig=save_fig)

    def _fit_shape_params(self, drop, norm, show_init, check_each, save_fig):
        # Fitting starts
        param_dict_fitted = {}
        for each_e in self.shape_dict_mcnp.keys():
            if self.e_min <= each_e <= self.e_max:
                print("Fitting [{} eV] ...".format(each_e))
                param_dict_fitted[each_e] = {}
                # If drop is True, only flux value above 0 will be used
                if drop:
                    _data_used = 'data'
                else:
                    _data_used = 'data_raw'
                if norm:
                    _flux_used = 'f_norm'
                else:
                    _flux_used = 'f'
                f = self.shape_dict_mcnp[each_e][_data_used][_flux_used]
                t = self.shape_dict_mcnp[each_e][_data_used]['t_us']
                param_dict_fitted[each_e]['fitted_params'] = self.__fit_shape_params(f=f,
                                                                                t=t,
                                                                                e=each_e,
                                                                                model_index=self.model_index,
                                                                                check_each=check_each,
                                                                                show_init=show_init,
                                                                                save_fig=save_fig)
        # Organize fitted parameters into pd.DataFrame
        self.param_df = self._form_params_df(param_dict=param_dict_fitted, save=True)

    def _form_params_df(self, param_dict, save=False):
        e_list_fitted = list(param_dict.keys())
        if self.model_param_names is None:
            param_list_fitted = list(param_dict[e_list_fitted[0]]['fitted_params'].keys())
        else:
            param_list_fitted = self.model_param_names

        _dict = {}
        for each_param in param_list_fitted:
            _dict[each_param] = []
        f_max_list = []
        for each_e in e_list_fitted:
            f_max_list.append(self.shape_dict_mcnp[each_e]['f_max'])
            for each_param in param_list_fitted:
                _dict[each_param].append(param_dict[each_e]['fitted_params'][each_param])
        _df = pd.DataFrame()
        _df['E_eV'] = e_list_fitted
        for each_param in param_list_fitted:
            _df[each_param] = _dict[each_param]
        _df['f_max'] = f_max_list

        # print("------------------------------------------------------------------------------------------")
        # print("NOTE: 'f_max' in the params_df is NOT a fitted parameter, it is the maximum in each shape.")
        # print("------------------------------------------------------------------------------------------")
        # print("                                    Fitted Parameter                                      ")
        # print("------------------------------------------------------------------------------------------")
        # print(_df)

        if save is True:
            assert self.result_neutron_folder is not None
            assert self.param_df_dir is not None
            _df.to_csv(path_or_buf=self.param_df_dir, index=False)
            print("Parameters fitting file ({}) has been saved at '{}'".format(self.model_used, self.param_df_dir))

        return _df

    def __fit_shape_params(self, f, t, e, model_index, show_init, check_each, save_fig):
        _model_map = self.model_map
        verbose = False

        if model_index != self.model_index:
            self.__set_model(model_index)
        my_model = self.model
        # ikeda_carpenter
        if model_index == 1:
            assert my_model.param_names == ['alpha', 'beta', 'fraction', 't0', 'norm_factor']
            assert my_model.independent_vars == ['t']

            # Set params hints
            if self.result_shape_fit is None:
                my_model.set_param_hint('alpha', value=0.699, min=0, max=20)
                my_model.set_param_hint('beta', value=0.0215, min=0, max=20)
                my_model.set_param_hint('fraction', value=0.383, min=0, max=1)
                my_model.set_param_hint('t0', value=0.0889, min=0, max=20)
                my_model.set_param_hint('norm_factor', value=1, min=0)

                # Make params
                params = my_model.make_params(verbose=verbose)
            else:
                _best_pre_values = self.result_shape_fit.best_values
                my_model.set_param_hint('alpha', value=_best_pre_values['alpha'], min=0, max=20)
                my_model.set_param_hint('beta', value=_best_pre_values['beta'], min=0, max=20)
                my_model.set_param_hint('fraction', value=_best_pre_values['fraction'], min=0, max=1)
                my_model.set_param_hint('t0', value=_best_pre_values['t0'], min=0, max=20)
                my_model.set_param_hint('norm_factor', value=_best_pre_values['norm_factor'], min=0)

                # Make params
                params = my_model.make_params(verbose=verbose)

            # Fit the model
            self.result_shape_fit = my_model.fit(f, params, t=t)

        # ikeda_carpenter_jparc
        elif model_index == 4:
            assert my_model.param_names == ['alpha', 'beta', 'fraction', 't0', 'norm_factor']
            assert my_model.independent_vars == ['t']

            # Set params hints
            if self.result_shape_fit is None:
                my_model.set_param_hint('alpha', value=0.699, min=0, max=20)
                my_model.set_param_hint('beta', value=0.0215, min=0, max=20)
                my_model.set_param_hint('fraction', value=0.383, min=0, max=1)
                my_model.set_param_hint('t0', value=0.0889, min=0, max=20)
                my_model.set_param_hint('norm_factor', value=1, min=0)

                # Make params
                params = my_model.make_params(verbose=verbose)
            else:
                _best_pre_values = self.result_shape_fit.best_values
                my_model.set_param_hint('alpha', value=_best_pre_values['alpha'], min=0, max=20)
                my_model.set_param_hint('beta', value=_best_pre_values['beta'], min=0, max=20)
                my_model.set_param_hint('fraction', value=_best_pre_values['fraction'], min=0, max=1)
                my_model.set_param_hint('t0', value=_best_pre_values['t0'], min=0, max=20)
                my_model.set_param_hint('norm_factor', value=_best_pre_values['norm_factor'], min=0)

                # Make params
                params = my_model.make_params(verbose=verbose)

            # Fit the model
            self.result_shape_fit = my_model.fit(f, params, t=t)

        # cole_windsor
        elif model_index == 2:
            assert my_model.param_names == ['sig1', 'sig2', 'gamma', 'fraction', 't0', 'norm_factor']
            assert my_model.independent_vars == ['t']

            # Set params hints
            if self.result_shape_fit is None:
                my_model.set_param_hint('sig1', value=0.06917, min=0, max=20)
                my_model.set_param_hint('sig2', value=0.2041, min=0, max=20)
                my_model.set_param_hint('gamma', value=6.291, min=0, max=20)
                my_model.set_param_hint('fraction', value=0.1308, min=0, max=1)
                my_model.set_param_hint('t0', value=0.3176, min=0, max=20)
                my_model.set_param_hint('norm_factor', value=0.9951, min=0)

                # Make params
                params = my_model.make_params(verbose=verbose)
            else:
                _best_pre_values = self.result_shape_fit.best_values
                my_model.set_param_hint('sig1', value=_best_pre_values['sig1'], min=0, max=20)
                my_model.set_param_hint('sig2', value=_best_pre_values['sig2'], min=0, max=20)
                my_model.set_param_hint('gamma', value=_best_pre_values['gamma'], min=0, max=20)
                my_model.set_param_hint('fraction', value=_best_pre_values['fraction'], min=0, max=1)
                my_model.set_param_hint('t0', value=_best_pre_values['t0'], min=0, max=20)
                my_model.set_param_hint('norm_factor', value=_best_pre_values['norm_factor'], min=0)

                # Make params
                params = my_model.make_params(verbose=verbose)

            # Fit the model
            self.result_shape_fit = my_model.fit(f, params, t=t)

        # cole_windsor_jparc
        elif model_index == 5:
            assert my_model.param_names == ['sig1', 'sig2', 'gam1', 'gam2', 'fraction', 't0', 'norm_factor']
            assert my_model.independent_vars == ['t']

            # Set params hints
            if self.result_shape_fit is None:
                my_model.set_param_hint('sig1', value=0.06917, min=0, max=20)
                my_model.set_param_hint('sig2', value=0.2041, min=0, max=20)
                my_model.set_param_hint('gam1', value=6.291, min=0, max=20)
                my_model.set_param_hint('gam2', value=1.285, min=0, max=20)
                my_model.set_param_hint('fraction', value=0.1308, min=0, max=1)
                my_model.set_param_hint('t0', value=0.3176, min=0, max=20)
                my_model.set_param_hint('norm_factor', value=0.9951, min=0)

                # Make params
                params = my_model.make_params(verbose=verbose)
            else:
                _best_pre_values = self.result_shape_fit.best_values
                my_model.set_param_hint('sig1', value=_best_pre_values['sig1'], min=0, max=20)
                my_model.set_param_hint('sig2', value=_best_pre_values['sig2'], min=0, max=20)
                my_model.set_param_hint('gam1', value=_best_pre_values['gam1'], min=0, max=20)
                my_model.set_param_hint('gam2', value=_best_pre_values['gam2'], min=0, max=20)
                my_model.set_param_hint('fraction', value=_best_pre_values['fraction'], min=0, max=1)
                my_model.set_param_hint('t0', value=_best_pre_values['t0'], min=0, max=20)
                my_model.set_param_hint('norm_factor', value=_best_pre_values['norm_factor'], min=0)

                # Make params
                params = my_model.make_params(verbose=verbose)

            # Fit the model
            self.result_shape_fit = my_model.fit(f, params, t=t)

        else:
            raise ValueError("Model index not exists, please refer to: '{}' ".format(_model_map))

        # Check or visually inspect the fitting result of each energy
        if check_each:
            assert self.result_shape_fit is not None
            _y_label = 'Normalized neutron flux (arb. unit)'
            _x_label = 'Time (\u03BCs)'
            _e_text = str(e) + ' eV'
            if show_init is True:
                self.result_shape_fit.plot(xlabel=_x_label, ylabel=_y_label)
            else:
                self.result_shape_fit.plot(xlabel=_x_label, ylabel=_y_label, initfmt='None')
            plt.title(_e_text, fontsize=12)

            # set x_max for plot
            if e < 1:
                _plt_xmax = 40
            elif 1 <= e < 5:
                _plt_xmax = 20
            elif 5 <= e < 15:
                _plt_xmax = 10
            elif 15 <= e < 30:
                _plt_xmax = 6
            elif 30 <= e < 50:
                _plt_xmax = 4
            elif 50 <= e < 500:
                _plt_xmax = 2.5
            else:
                _plt_xmax = 1.5

            # Show fitted params in figure
            _param_text = ''
            for _each in self.model_param_names:
                _param_text = _param_text + _each + ': ' + str(self.result_shape_fit.best_values[_each]) + '\n'
            param_text = _param_text[:-2]  # get rid of '\n' at the end
            plt.text(x=0.5 * _plt_xmax, y=0.4, s=param_text, fontsize=10,
                     bbox={'facecolor': 'None', 'alpha': 0.5, 'pad': 2}
                     )

            # Apply plot limit
            plt.xlim(xmin=0, xmax=_plt_xmax)

            if save_fig:
                # Check and make dir to save
                assert self.result_neutron_folder is not None
                _model_s = _model_map[model_index] + '.png'
                _filename = 'Neutron_pulse_fit_' + str(e) + '_eV_' + _model_s
                _dir_to_save = os.path.join(self.result_neutron_folder, _filename)
                plt.savefig(_dir_to_save, dpi=300, transparent=False)
                plt.close()
            else:
                plt.show()
        elif save_fig:
            raise ValueError("'check_each' has to be 'True' in order to save figure")

        return self.result_shape_fit.best_values

    def _export_total(self, filename=None):
        assert self.shape_total_df is not None

        if filename is None:
            self.shape_total_df.to_clipboard(excel=True)
        else:
            self.shape_total_df.to_csv(filename, index=False)

    def _export_each_to_csv(self):
        for index, each_energy in enumerate(self.shape_dict_mcnp.keys()):
            df = self.shape_dict_mcnp[each_energy]
            file_name = 'energy_' + str(index + 1) + '.csv'
            df.to_csv(file_name, index=False)
            print("Neutron pulse shape of 'E = {} eV' has exported to './{}'".format(each_energy, file_name))

    @staticmethod
    def _check_and_make_subdir(*args):
        # Check and make dir to save
        _file_path = os.path.abspath(os.path.dirname(__file__))
        for arg in args:
            _created_path = fit_util.check_and_make_dir(_file_path, arg)
            _file_path = _created_path
        return _file_path

class ProtonPulse(object):

    def __init__(self, path):
        """"""
        self._shape_df = _load_proton_pulse(path)
        self._shape_df_fit = None
        self.params = None
        self.new_params = None
        self.new_shape_df = None
        self.model = None
        self._t_shift = None
        self.result = self._fit_shape_proton(print_params=True)

    def __get_t_shift(self):
        self._t_shift = round(self.new_shape_df['t_ns'].median() / 10) / 100

    def _fit_shape_proton(self, print_params=False):
        t_ns = self._shape_df['t_ns']
        intensity = self._shape_df['intensity']
        _model = lmfit.models.GaussianModel()
        _proton_params = _model.guess(data=intensity, x=t_ns)
        result = _model.fit(data=intensity, x=t_ns, params=_proton_params)
        self.model = _model
        self.params = result.params
        sig_fit_s = str(round(self.params.valuesdict()['sigma'], 2))
        # if self._shape_df_fit is None:
        self._shape_df_fit = pd.DataFrame()
        self._shape_df_fit['t_ns'] = self._shape_df['t_ns']
        _new_array = self.model.eval(params=result.params, x=self._shape_df['t_ns'])
        self._shape_df_fit['Fit (\u03C3={})'.format(sig_fit_s)] = _new_array.round(5)

        _new_shape_df = pd.DataFrame()
        _new_shape_df['t_ns'] = self._shape_df_fit['t_ns']
        _new_shape_df['intensity'] = _new_array.round(5)
        self.new_shape_df = _new_shape_df
        self.__get_t_shift()

        if print_params:
            print("Fitted params for raw proton pulse shape:")
            result.params.pretty_print()
        return result

    def make_new_shape(self, proton_params={}, print_params=False):
        _check_proton_params_dict_keys(proton_params)
        assert self.model is not None
        _params_guess = self.model.guess(data=self._shape_df['intensity'], x=self._shape_df['t_ns'])
        result = self.model.fit(data=self._shape_df['intensity'], x=self._shape_df['t_ns'], params=_params_guess)
        _new_params = result.params
        for each_par in proton_params.keys():
            _new_params.add(each_par, proton_params[each_par])
        if print_params:
            print("Fitted params for simulated proton pulse shape:")
            _new_params.pretty_print()
        sig_fit_s = str(round(_new_params.valuesdict()['sigma'], 2))
        _new_shape_df = pd.DataFrame()
        _new_shape_df['t_ns'] = self._shape_df['t_ns']
        _new_array = self.model.eval(params=_new_params, x=self._shape_df['t_ns'])
        _new_shape_df['intensity'] = _new_array.round(5)
        self._shape_df_fit['Fit (\u03C3={})'.format(sig_fit_s)] = _new_array.round(5)
        self.new_params = _new_params
        self.new_shape_df = _new_shape_df
        self.__get_t_shift()
        return _new_shape_df

    def plot(self):
        fig, ax = plt.subplots()
        # sig1 = str(round(self.params.valuesdict()['sigma'], 2))
        ax.plot(self._shape_df['t_ns'], self._shape_df['intensity'], label='Raw')
        # ax.plot(_x, self._shape_df_fit['intensity'], 'b:', label='Fit (\u03C3={})'.format(sig1))
        if self._shape_df_fit is not None:
            # sig2 = str(round(self.new_params.valuesdict()['sigma'], 2))
            # ax.plot(_x, self.new_shape_df['intensity'], 'r--', label='Fit (\u03C3={})'.format(sig2))
            ax = self._shape_df_fit.set_index('t_ns').plot(ax=ax)
        ax.set_title('Proton pulse raw vs. fitting')
        ax.set_xlabel('Time (ns)')
        ax.set_ylabel('Intensity (a.u.)')
        ax.legend()
        ax.grid()
        return ax

def _check_proton_params_dict_keys(proton_params):
    _key_list = ['sigma', 'center', 'amplitude']
    for each_par in proton_params.keys():
        if each_par not in _key_list:
            raise ValueError("'{}' is not a valid param name, accepted keys are: '{}'.".format(each_par, _key_list))

def _break_proton_param_list_to_dict(proton_param_list, proton_param_name):
    _list_of_dicts = []
    for _each in proton_param_list:
        _list_of_dicts.append({proton_param_name: _each})
    return _list_of_dicts

# Functions to load files #
def _load_neutron_total_shape(path):
    p = np.genfromtxt(path)
    pp = p.T
    df1 = pd.DataFrame()
    for i, col in enumerate(pp):
        df1[i] = col
    col_name_1 = ['E_eV', 'l_angstrom', 'b(E)', 'bs(E)', 'b(l)', 'bs(l)']
    df1.columns = col_name_1
    df1['f(E)'] = df1['b(E)'] * df1['E_eV']
    df1['s(E)'] = df1['bs(E)'] * df1['E_eV']
    df1['f(l)'] = df1['b(l)'] * df1['l_angstrom']
    df1['s(l)'] = df1['bs(l)'] * df1['l_angstrom']

    return df1

def _load_neutron_each_shape(path, export=False):
    q = np.genfromtxt(path)
    qq = q.T
    df2 = pd.DataFrame()
    for i, col in enumerate(qq):
        df2[i] = col

    energy_list = list(set(list(df2[1])))
    energy_list.sort()

    shape_dict = {}
    for index, each_energy in enumerate(energy_list):
        data_dict = {}
        t_us = []
        e_ev = []
        b = []
        bs = []
        f = []
        s = []
        df = pd.DataFrame()
        for each_line in q:
            if each_energy == each_line[1]:
                t_us.append(each_line[0])
                e_ev.append(each_line[1])
                b.append(each_line[2])
                f.append(each_line[2] * each_line[1])  # brightness * E
                bs.append(each_line[3])
                s.append(each_line[3] * each_line[1])  # brightness s * E
        f_max = np.amax(f)
        df['t_us'] = t_us
        df['b'] = b
        df['bs'] = bs
        df['f'] = f
        df['s'] = s
        df['f_norm'] = f / f_max
        df['s_norm'] = s / f_max
        df['E_eV'] = e_ev
        data_dict['data_raw'] = df
        df_dropped = df.drop(df[df.f_norm <= 0].index)
        df_dropped.reset_index(drop=True, inplace=True)
        data_dict['data'] = df_dropped
        data_dict['f_max'] = f_max
        shape_dict[each_energy] = data_dict

        # Export to .csv
        if export is True:
            file_name = 'energy_' + str(index + 1) + '.csv'
            df.to_csv(file_name, index=False)

    return shape_dict

def _shape_dict_to_dfs(shape_dict, t_max=None):
    _first_key = list(shape_dict.keys())[0]
    _t_us = shape_dict[_first_key]['data_raw']['t_us']
    _shape_df = pd.DataFrame()
    _shape_df_norm = pd.DataFrame()
    _shape_df['t_us'] = _t_us
    _shape_df_norm['t_us'] = _t_us
    for each_key in shape_dict.keys():
        _shape_df[each_key] = shape_dict[each_key]['data_raw']['f']
        _shape_df_norm[each_key] = shape_dict[each_key]['data_raw']['f_norm']
    # _shape_df = _shape_df.drop(_shape_df[_shape_df.t_us < t_min_us].index)
    # _shape_df.reset_index(drop=True, inplace=True)
    # _shape_df = _shape_df.drop(_shape_df[_shape_df.t_us < t_min_us].index)
    # _shape_df.reset_index(drop=True, inplace=True)
    # , t_min_us, t_max_us
    if t_max is not None:
        _shape_df = _shape_df[_shape_df.t_us <= t_max]
        _shape_df_norm = _shape_df_norm[_shape_df_norm.t_us <= t_max]
    return _shape_df, _shape_df_norm

def _load_proton_pulse(path=proton_path):
    _df = pd.read_csv(path, sep=' ', skiprows=1, header=None)
    _df.columns = ['t_ns', 'intensity']
    df = _df.round(5)
    df[df < 0] = 0
    return df

def _plot_ev_arrow_as_legend(ax, ev_list):
    bbox_props = dict(boxstyle="round,pad=0.1", fc="w", ec="k", lw=0.5, alpha=0.4)
    ax.annotate(str(ev_list[-1]) + ' eV',
                xy=(.65, .65), xycoords='figure fraction',
                xytext=(.21, .83), textcoords='figure fraction',
                arrowprops=dict(arrowstyle="fancy",
                                # linestyle="dashed",
                                color="k",
                                patchB=None,
                                shrinkB=0,
                                connectionstyle="arc3",
                                alpha=0.55
                                ),
                bbox=bbox_props
                )
    ax.annotate(str(ev_list[0]) + ' eV',
                xy=(.63, .62), xycoords='figure fraction',
                bbox=bbox_props
                )
    return ax


text:
Hyundai NEXO awarded five-star Green NCAP rating
NEXO, Hyundai's second-generation fuel cell electric vehicle, has been awarded the maximum possible rating by Green NCAP
Green NCAP is an independent organisation that rates cars based on energy efficiency and emissions
NEXO is the third Hyundai model to receive a maximum five-star rating, following IONIQ Electric in 2019 and KONA Electric in 2020
Hyundai's NEXO has received a maximum five-star rating from Green NCAP, the independent organisation that ranks vehicles based on their energy efficiency and emissions.
The rating was based on three indices, each of which contained several metrics: clean air, energy efficiency and greenhouse gases. As a fuel cell electric vehicle, powered by hydrogen and producing distilled water as its only emission, NEXO naturally scored full points on both the Clean Air and Greenhouse Gas index. Its excellent rating for energy efficiency was a further testament to the quality of the product, proving that fuel cell mobility is a mature technology and a viable transportation solution.
In its report, Green NCAP wrote: "[With Hyundai NEXO] there are no tailpipe emissions other than water. As a result, the NEXO scores full points for both the Clean Air and Greenhouse Gas indexes. Energy efficiency is also very high and the NEXO emerges with an average index just high enough to earn the car a maximum five-star rating."
We're proud to announce that NEXO is the latest Hyundai model to have been awarded a five-star Green NCAP rating, joining the ranks of IONIQ and KONA Electric. This is further proof that we are achieving our goal of making high-quality, eco-friendly mobility solutions available to all. Our flagship fuel cell electric vehicle has been recognised not just for being an environmentally-friendly zero-emission vehicle, but also a strong product with very high energy efficiency.
Andreas-Christoph Hofmann Vice President Marketing and Product at Hyundai Motor Europe
Hyundai's NEXO is a fuel cell electric vehicle and the technological flagship of Hyundai's growing eco-vehicle fleet. It combines the practicality of an SUV crossover with advanced electrified technology, comprehensive driver assistance functions and innovative design features.
NEXO is the third Hyundai model to receive a maximum five-star rating. In 2019, Green NCAP also awarded the five-star rating to the battery-electric version of Hyundai IONIQ. Meanwhile, in 2020 the organisation also awarded the Hyundai KONA Electric the maximum score.
See the full report: https://www.greenncap.com/assessments/hyundai-nexo-2021-0069/
About Green NCAP
Green NCAP is an independent initiative which aims to promote the development of cars which are clean, energy efficient and not harmful to the environment. The organisation uses a broad range of tests that go above and beyond legislative testing and, through consumer information, rewards manufacturers whose vehicles go beyond the minimum requirements.
Hyundai Motor to join as main exhibitor at HyBayern Hydrogen Days
Hyundai Motor is attending HyBayern Hydrogen Days to share its expertise on and vision for hydrogen energy.
Hyundai Mobis invests $1.1 billion for 2 new hydrogen fuel cell system plants in Korea
Hyundai Mobis will build two new fuel cell plants in Korea to accelerate the hydrogen economy and to secure broader global market dominance.

redpajama_set_name: RedPajamaCommonCrawl


text:
Bruised Movie Synopsis & Plot
Jackie Justice (Halle Berry) is a mixed martial arts fighter who leaves the sport in disgrace. Down on her luck and simmering with rage and regret years after her fight, she's coaxed into a brutal underground fight by her manager and boyfriend Desi (Adan Canto) and grabs the attention of a fight league promoter (Shamier Anderson) who promises Jackie a life back in the octagon. But the road to redemption becomes unexpectedly personal when Manny (Danny Boyd, Jr.) — the son she gave up as an infant — shows up at her doorstep. BRUISED marks the directorial debut of Academy Award winner Halle Berry and also stars Adriane Lenox, Sheila Atim, Valentina Shevchenko, and Stephen McKinley Henderson in a triumphant story of a fighter who reclaims her power, in and out of the ring, when everyone has counted her out
Read our Bruised movie review »


text:
Posts tagged 'portal 2'
January 17, 2012 by Brian
Last January, I wan't looking forward to much on the Xbox. In fact, there were just two games: Mass Effect 3 and Batman: Akham City. Unfortunately Mass Effect 3 was delayed, but Akham City more than made up for that. The game had everything I loved about the first Batman game but added improvements, and even though I've finished the game, I still pop it into my console occasionally to beat on some thugs.
Outside of Arkham City, my Xbox didn't get much playtime, which I guess is why it decided to red-ring on me in December. I had hoped by waiting through the first few manufacturing runs and getting an Elite, that I had dogged all of the overheating problems with Microsoft's console. I was wrong. The repair process was relatively painless: go online and submit a repair request, print out a label, box and ship it out. I just wish it hadn't cost me $99.
The PC had a few more titles I was excited about: Minecraft, Portal 2, Warhammer 40k: Dawn of War 2 – Retribution (could the title be any longer?), and Warhammer 40k: Space Marine. Well okay, Minecraft was a bit of a cheat since it was pretty much already released. Portal 2 was as good as I hoped it would be, and I got to have some extra fun by playing through the co-op version with MMOGamerChick. DoW Retribution I've barely touched. I really really loved the original Dawn of War games, but the shift in focus from base building to boss battles has soured me a bit on the franchise. Space Marine made up for my disappointment in Retribution though, the game was over the top gory fun. Some people may try to tell you that using a chainsword on an Ork get's old, but they're lying to you.
Unlike with Xbox, this last year also had two big surprises for me on the PC platform. First there was the colossal disappointment of Deus Ex: Human Revolution. This was a game I was not anticipating in the slightest, but ended up buying because of the wave of good press and excitement from friends. Unfortunately, I only put five hours into it before running headlong into a boss battle geared for the exact opposite type of character that I was playing. I realize I'm in the minority opinion on this game, but I still strongly believe that you don't build a game around choice and then take it away during the central moments of the game.
The second big surprise happened in exactly the same way, but with opposite results. Elder Scrolls 5: Skyrim was another game that I wasn't anticipating at all. Like DXHR, I hadn't played any of the earlier games in the series, and even though the screenshots looked good and I thought I might like it, I was wary of letting myself get sucked along with the ground again. In the end, I did end up going ahead and getting it, and I'm so glad I did. Skyrim has been a Minecraft-like experience for me (which is ironic given the legal battle between the companies). Just like I got sucked completely into Minecraft last year and played nothing else for months, my gaming time was wholly subsumed by Skyrim. Today, I've put 117 hours into just one single-player game. One hundred and seventeen hours. That is incredible, considering a good single-player game usually lasts me no more than 40 (like Red Dead Redemption or Arkham City). But even more incredible is that after more than a hundred hours, I'm not even halfway through the main story line.
PC was much more exciting this year than I thought it would be. I'm not sure that 2012 will be though, but I'll save that for later.
Trion had the perfect situation this year. From January to November, they had the only new major MMO title. I think they capitalized in it very well too. They've been continually releasing new content and making tuning changes. Honestly if anything, I think Trion's proved it's possible to have too much of a good thing. They've been updating the game so much, that when I came back after a month away, it felt like I'd been gone for six months or more.
BioWare ended up releasing much later in the year than I expected. This ended up being a good thing both because they had more time to get things right, but also because they managed to get through the hype backlash I was expecting before release (or even beta). There's not too much more I can say about TOR as far as 2011 goes beyond I got in at launch, had no problems, have seen no queues, and am immensely enjoying the Jedi Knight story line.
Champions has been a fun game to hop into of f and on over the year, especially the few times I've gotten to play with Scott. The game had a successful F2P launch and has released some good story content with their first Comic Series and a third Adventure Pack. While I haven't had that original love of the game rekindle, I'm sure I'll continue to login anytime I get an urge to play superheroes.
Last year, I was feeling pretty down on LotRO. The F2P conversion caused an explosion of gold store buttons in the interface that just got under my skin. My disinterest continued for most of the year, including well into the development cycle for Rise of Isengard. It wasn't until I saw a developer diary with some video about the making of Orthanc for the game, that I had any interest in returning to Middle-Earth.
Once I got back in the game, I was motivated enough to finish Volume 2 of the Epic Quests, get caught up on Volume 3 in Enedwaith, and charge on towards Isengard. I didn't make it to level cap before Skyrim started dominating my playtime, but I was really happy with the new work Turbine has done on the game and I've finally trained myself to not see the store buttons.
And lastly, we come to the MMO that I've had both the most and least fun with during 2011.
The game started out very well. We had an anniversary event, an excellent renovation of Earth Spacedock, and then a third Featured Episode Series, Cloaked Intentions. The Series 3 was the best one so far and featured great missions, fun voice work, and the music from Amok Time.
Unfortunately, that was the high point of the year. We did get the Foundry followed by a good revamp of ground combat in Season Four, but we also got Atari selling Cryptic, Dan Stahl leaving the Executive Producer role, Free-to-Pay announced, and no new story missions.
Whether it was Dan leaving, the change in ownership from Atari to Perfect World, or the announced F2P transition, the high level of communication and transparency that I loved in 2010 has vanished. The last Engineering Report was released in August, with no word about if or when it's coming back. The last Ask Cryptic was in September. Granted, the temporary Executive Producer Stephen D'Angelo did write a lot of blogs during the F2P development, but I found them pretty thin on details.
Overall, it's been a disappointing year for me in STO. I guess I have to have at least one MMO to be down on at the end of every year.
Tags: arkham city, batman, champions, dawnofwar2, lotro, mass effect 3, minecraft, mmo, pc, portal 2, rift, star trek, sto, swtor, warhammer 40k, xbox 360, year end
Category: Rambles | 1 Comment
Partners in Science
June 6, 2011 by Brian
When Portal 2's co-op mode was originally announced, I didn't expect to actually play it. But when I mentioned the game a few weeks ago, MMOGC pointed out the amazing deal Amazon was running and we ended up planning to do the co-op portion.
The co-op game took us about five or six hours to finish, across three nights. I ended up as Blue (naturally) and GC played Orange. Organized as five courses, with eight puzzles in each, there's nearly as much humor and story in the co-op mode as there is in the single-player game. Check out GC's review here.
I thought having a co-op review for a co-op game would be fun, and GC agreed to do a little question an answer with me (this section is on GC's blog as well)…
BlueKae: I had expected the co-op game to be fun, but it turned out to be a lot more fun than I realized. Challenging in different ways than the single player, and somehow easier too. What surprised you about playing co-op?
MMOGamerChick: From the start, I knew co-op was going to be about playing together, but what I didn't expect to see was how often we were put into situations where we had to work together…but separately. Initially, I think I was picturing something akin to a two-player platformer, where you and your partner would go everywhere together, do everything together. There were some puzzles like that, but I'd say most of them involved each person doing very different things, sometimes in different parts of the room. It made things more interesting, in my opinion. It's still very much about the teamwork because our chances of success still depended on both people accomplishing their respective tasks, but that meant trust was also very important — especially when we couldn't see what the other person was doing and had to rely on coordination and communication.
Okay, my turn to ask a question. What did you find was most challenging about co-op?
BK: Remembering that I was playing with someone. I mean we were chatting the whole time so I knew you were there and all, but after playing through on single player I was so used to running into a new puzzle and starting to throw portals around that it was an adjustment to remember I was playing with someone. I know there were a few times when I wiped a portal of yours out with one of mine because I wasn't thinking.
I very much agree with your surprise about how the co-op worked. I assumed that our portals would link up instead of being separate. It was definitely more about communicating, coordinating, and trust. The spike maze comes to mind. 🙂
The best part was having a second person to help figure out how to solve the puzzles. I wasn't tempted to go look at Youtube once. If/when there's a Portal 3 are you looking forward more to single player or more co-op?
MMOGC: Both. I mean, obviously the co-op is a huge draw, but single player has its moments. And both portions were filled with humorous moments, GLaDOS doing her thing. That's what made the whole game, I think. It would be difficult for me to say which I prefer or look forward to more.
And I totally agree with you about remembering that I was playing with someone. Though with regards to wiping out each other's portals, I just like to think of it more as both of us being on the same page. Great minds think alike and all that!
BK: True! I think the single player had a bit more personality, maybe that's because it stretched across two games. Did it seem to you like the single player was more about how to solve a puzzle and the co-op was more about actually doing the solution?
MMOGC: Oh yeah, definitely. I approached single-player and co-op very differently. In co-op (and I think you might have noticed this too), the first thing both of us did with a new puzzle was run in there and start exploring, playing with whatever buttons or stuff we found. I found myself "working backwards" in co-op more than I did in single-player. First find the exit, then "do" the solution.
BK: I wasn't quite that organized about it. Mostly I was just trying to make sure that when we picked a solution that it was using all of the different parts in the puzzle.
MMOGC: Let me ask you another thing. Were you stressed at any point? 'Cause I know I was. I kept thinking, "Oh crap oh crap oh crap, I'm going to let Blue Kae down and he's going to think I'm an idiot." I'm not the best when it comes to coordination and reflexes. There were several times that I botched a jump or a portal and I just felt terrible.
BK: A couple of times, definitely. I worried about getting you killed on a couple of puzzles where there was timing involved. But most of the time it was so easy to run back in, that I didn't worry much. I can't remember getting frustrated at all though.
MMOGC: Well, it was definitely much more enjoyable to play with a friend.
BK: I totally agree. The frustrating parts for me in the single player game were figuring out what to do next. Having someone to talk with and point out things I missed made the game much much more fun.
MMOGC: I totally carried you. Haha, just kidding.
BK: There were definitely puzzles that you just got right off that I didn't and vice versa. There was only one puzzle, I remember, that stumped us both for a bit.
MMOGC: That part really was cool. I saw where my own weaknesses were, and was grateful when you figured stuff out that I couldn't. I was really happy that we were able to figure everything out between us without going to outside help.
BK: Yeah, I ended up hitting Youtube twice for puzzles in the singleplayer game when it stopped being fun.
MMOGC: And fun is what it's all about.
Tags: portal 2
The Humor Makes the Game
May 24, 2011 by Brian
No spoilers, I promise.
Portal came out as part of the Orange Box back in October 2007, nearly a year before I started this blog. I originally bought the Orange Box for the Half-Life 2, but I got so much more enjoyment from Portal than either that or Team Fortress 2. That's especially surprising because I don't like puzzle games or platformers. I'm not a fan of the Mario or Sonic games. I quit the first God of War (and the series) when I got to a wall of blades jumping puzzle.
The game was concise and fun. It had challenges but always prepared me in advance to solve them. These bits made for a very good game.
The humor made the game great.
So, four years later (roughly) Valve has released Portal 2. I've been looking forward to the game and yet avoiding nearly all of the marketing. Since it came out right as I was focused on Rift, I figured I'd wait until I was ready to play it then buy and download it (I'm trying to keep my mountain of unplayed games shorter than Everest). I was excited to play Portal 2 but wasn't feeling and urgency to play.
Amazon forced my hand though by offering the PC version for $30. Even better, I apparently had $15 off promo for a game too which I found out when I checked out, so I ended up getting Portal 2 for $15. That's a steal.
I feel bad though. I bought a physical disc and had it shipped to me, yet all I used was the license key. I literally opened the box and typed the key into Stream then started the download. The disc never left the box.
While not giving away anything whatsoever of the plot, let me just say that right from the first second of the game the humor is back and it's amaaaaaazing! I had a great time making my way through the environments and enjoying the humor and personality in the game. It's able to build on the history of the first game so there's no ramp like in the first game where you don't actually know there's a story for the first half of the game (assuming I remember the pacing rightly).
As far as the pure mechanics of the game, puzzles are less about reflexes and more about understanding your environment. That can lead to some minor frustrations, but if I could figure it out then anyone could.
All in all, I think Portal 2 is an excellent sequel. I'm looking forward to trying the co-op when GC is ready.
And then I'll go to bed…
I finished Portal 2 on Friday night. Well actually it was Saturday morning:
11:30 pm – I think I'll play a little Portal 2 before I go to bed.
12:30 am – I think I'll solve another one or two puzzles before I go to bed.
2 am – What time is it? Oh… One more puzzle then I'll go to bed.
3:30 am – What the- ok, I really need to go to bed so I'm not a zombie at my son's swimming lesson. I'll just finish this puzzle and then go to bed.
5 am – That was a good game. It's going to be a rough morning.
Looking Forward to 2011 – Console/PC
I debated just tacking this onto the end of my 2011 MMOs post, since it could be condensed down to:
Mass Effect 3! Mass Effect 3! Minecraft! Minecraft!
But that feels a bit lazy and January is way too early for me to give into laziness, that's what March is for.
There's only two games I'm excited to play on the Xbox 360 this coming year:
Do I really need to explain why? Fine.
Bioware has shown marked improvement in the game-play from 1 to 2, I can only imagine 3 with be even better. Honestly, I'm not sure how though, the mining mini-game was really the only part that was below excellent.
The story, characters, and dialogue have been consistently good through out the first two games, despite my concerns based on the way Mass Effect 2 was marketed. It will be shocking if they somehow manage to drop the ball for the finale.
It's the rare superhero game that really recreate the experience of being an iconic hero from the comics. Besides Batman: Arkham Asylum only Spider-man 2 and Incredible Hulk: Ultimate Destruction come to mind. I'm very interested to see if Rocksteady Studios can pull off a sequel. Will they be able to improve on the combat and the detective mode issues without losing the magic from the first game?
I'm sure I missed one or two, but this was all I had in my wish-lists on Steam and Amazon.
Obviously there's going to be a lot happening with Minecraft this year. Notch's company, Mojang, is up and running, he's got developers and an artist helping out now, and he's got big plans. While I'm excited to see Notch does this year with all the resources at his disposal, to be totally honest, I've already gotten more than my $14 worth.
I hate puzzle games and platformers, yes even Mario Bros. I loved Portal though. The game did an excellent job of training you on how to solve the puzzles in the game and the difficulty curve always managed to challenge me without causing my to break my keyboard. I've been on a complete media blackout regarding this game, all I know is that it's scheduled for 2011 and I want it.
Warhammer 40K: Dawn of War 2 – Retribution & Warhammer 40k: Space Marine
An expansion for DoW2 and a 40k shooter are both due out this year. I loved the single player game for DoW2 but it took a while before I really started to like the multi-player mode, mostly I just missed the base building. Still, I'm very excited to get to play my favorite race from DoW1, the Imperial Guard.
The shooter, Space Marine, looks interesting and given Relic and THQ's track record with DoW 1 and 2, I'm definitely going to give it a shot. I'm assuming I'll get the PC version, but there is an Xbox 360 version scheduled as well.
Tags: arkham city, batman, dawnofwar2, mass effect 3, minecraft, pc, portal 2, space marine, status, xbox 360, year end


text:
Aldric Doran Chamblee (born November 17, 1968) is a former American football linebacker. He played for the Tampa Bay Buccaneers from 1991 to 1992.

References

1968 births
Living people
American football linebackers
Virginia Tech Hokies football players
Tampa Bay Buccaneers players

redpajama_set_name: RedPajamaWikipedia


- By Meghan Labot - The world of tea is full of rich experiences for every sense. Much like wine, the visual language of tea has exploded in recent. . .
June 1, 2018 FOR IMMEDIATE RELEASE: Firsd Tea North America, Announces Global Tea Championship Medalists - World Tea Expo Booth #528 - Win. . .
June 1, 2018 FOR IMMEDIATE RELEASE: Firsd Tea North America, Announces Launch of Tea Program for Coffee, Retail, and Foodservice - World Tea. . .
Product Description: Firsd Tea's CBD tea is a blend of green tea, herbal ingredients, natural flavorings, and CBD. Cannabidiol (CBD) is a hemp-. . .
- Come see what World Tea Expo has to offer! - Firsd Tea @ World Tea Expo Booth # 528 Las Vegas Convention Center June 12-14 - We'll be. . .
In our ongoing series on tea retail at coffee shops, the series has covered: - Daily Tea Consumption Trends Drivers of US Tea Consu. . .
Changing demographics and other market trends are showing a continued rise in demand for premium teas. Some of these trends and indicators have been c. . .
The data about tea sales in coffee shops tends to get confusing. Recent NCA reports might have you believe tea is declining. - However, a more thoro. . .
Product Description: Sapphire Blue employs the unique properties of the blue butterfly pea flower to create a naturally deep blue tea. Ginger a. . .
Product Description: Amethyst Butterfly tea dazzles the senses with a vibrant purple cup and a rich spectrum of floral character. The bright amet. . .


Franklin has had one goal since the first day of football practice in August. That goal moved one step closer to being accomplished in Reisterstown on Friday night, when the Indians defeated Huntingtown, 21-10, to advance to the state Class 3A title game.
Completing the goal will be a little more daunting.
The Indians (11-2) used a crisp running game and a stingy defense to defeat the Hurricanes (10-3) from Charles County. In doing so, they advance to the Class 3A State Championship on Thursday at Navy-Marine Corp Stadium in Annapolis.
Elijah Solomon led Franklin with 20 carries for 80 yards and a touchdown.
It took the Indians' offense a while to get going before it scored all 21 of Franklin's points in the second quarter.
After the Hurricanes took a 3-0 lead on Hunter Bray's 36-yard field goal with 6:41 left in the first quarter, the Franklin offense went to work early in the second quarter. Taking over at their own 24, the Indians used a 36-yard run by Solomon on the first play to get the offense in gear. Seven plays later, receiver Corey Crawford scored on a jet sweep from 10 yards to give the Indians a 7-3 lead just 2:33 into the second quarter.
Franklin added to the lead on its next possession. The Indians defense tightened, forcing a Hurricanes punt from deep in their own territory. Franklin took over at the Huntingtown 38 and needed only four plays to score. The drive was capped by a direct snap to receiver Daniel Yarborough. The sophomore ran down the left sideline and scored from 29 yards to give the Indians a 14-3 lead with 4:57 left in the half.
The Indians scored again just before the half. The biggest play in that drive was a 50-yard pass from Franklin quarterback Vernon Brown to senior Joshua Wilson. Wilson tipped the ball at the Huntingtown 25, before finally catching it and being tackled at the 8-yard line. Solomon did the rest, scoring from 5 yards two plays later to give the Indians at 21-3 lead with 29.1 seconds left in the half.
Huntingtown took advantage of a bad punt in Franklin territory to engineer its only touchdown drive. The Hurricanes took over at the Franklin 12, and needed two plays to before Matteo Degennaro caught a 6-yard pass from Bray to cut the margin to 21-10 with 2:28 left in the third quarter.
The Franklin defense pitched a shutout from that point.
The Indians will face Frederick County's Linganore, a winner over Chesapeake of Anne Arundel, in the other semifinal. The Lancers are the defending state champions.


Finished my Rally Car but struggling to get it running right. its a European Strategy (ABARO) 1995 EECV ECU (EXIT).
Automatic Trans ECU but I'm running a manual, lowered the coolant temp, has no Cats now, and also need more Ignition advance.
I have Dongle version Binary Editor with Mongoose Licence, with a limited, encrypted Def file, does Transmission and Fans, but sadly I've bought a fake Mongoose lead that don't work.
Also I have EEC Editor with a pretty comprehensive Def, which doesn't encrypt my bins but that won't flash the ECU, only J3 Chips.
I have Moates Burn2 and J3 reader/ flasher card.
I have Innovate AFR W/B for checking fuelling.
I have a proper Ford FDS 2000 Dealer machine, which will re flash EECV's but I can't get round it's programming, I don't know enough about computer software to do that.
I would like to find someone to help write a new disc for it, by modifying what's on the existing one and including my own .bin file so it will flash my own files, and I can simply add new ones on to the disc then when I want to reflash.
I think this might be the easiest and cheapest solution for me at this time.
Perhaps just take a look at a FDS Disc first The disc contains all the European Cal Files, an operating system, and in all different languages.
Also have Ford FDS but yet to find anyone who can modify it's Operating Program so I can flash my own .bins with it.
Yes it's on a CD, I'll download WINISO now.
Is it sort of like uploading pictures to Photobucket ?
I've done the ISO bit, I'll pm ya in a min.
Right, I've condensed it down from 550MB to 31.2MB, as a load of the files are country specific, and we are only concerned with the read me, OS and GB Folders, the other country ones just contain the same cal files as the GB one but relevant to the language selected.


Pro Car Key Replacement Services For Buckeye, AZ - Low Rates!
Losing your car, truck or motorcycle keys can certainly throw off your plans thoroughly. Without your keys you have no way of getting around town. Nevertheless, we can easily handle your car key duplication and replacement needs rather quickly and professionally around Buckeye Arizona.
Remember that car dealerships have a tendency to ask for considerably more then key companies for backup keys and your car key programming. Most key companies cost you significantly less in comparison to the car dealer considering that the hidden knowledge they don't really want you to find out is generating duplicate keys is much less expensive than producing a new car key. With us you will always pay the lowest price tag offered and even benefit from the best auto key product on the market.
Keys are growing far more hi-tech every day. Many cars and trucks are beginning to work with laser cut keys.
When these guys tell you they'll be there within the hour, they aren't lying! I called them for a replacement Cadillac key and they were there within 50 minutes! I was so impressed by their on pointness and price that I saved them into my contacts!


text:
Home Editor Pick Evergreen's Organic Farm Stand Relocates, Re-opens in Compliance with Safety Protocols
Stop Evergreen's farm stand every Thursday from 3:00 p.m. to 6:00 p.m. for a selection of plant starts and fresh produce. Come early for the best selection or pre-order your favorites by enrolling in the farm's email list. Photo courtesy: The Evergreen State College
Evergreen's Organic Farm Stand Relocates, Re-opens in Compliance with Safety Protocols
Alison Bailey
The organic farm at The Evergreen State College has been preparing students to own and operate small-scale organic farms since 1992. Kirsop Farm, Calliope Farm, Little Big Farm, Skipping Stone Farm, Helsing Junction Farms are all part of a family of farms across western Washington touched in some way by a graduate of Evergreen's Practice of Organic Farming program. The associated farm stand allows students to learn first-hand what it's like to market and sell commercially-grown produce to the public.
Beth Leimbach has worked on the organic farm at The Evergreen State College since 2015, when she started as the farm's assistant manager. "Students leave this program with the knowledge and skill to start their own farm, work on other farms, or work in agriculture education or policy advocacy," she says. "Even if they don't go down that path, they come away with an appreciation for sustainable farming on a local level." Beth became the farm manager in January 2020. Photo courtesy: The Evergreen State College
"We have a great success rate at getting people on their own farms and starting their own businesses," says faculty member David Muehleisen. Evergreen's Practice of Organic Farming program is a direct contributor to our region's most sustainable food supply at this critical time.
"Students come to Evergreen for this program specifically," explains Beth Leimbach, the farm's manager. The program runs for three quarters every spring, summer and fall. David leads the students through academic coursework on soil science, botany and entomology. He also teaches small business planning, lean management strategies and practical tasks like how to get a permit for a value-added product. "The small organic farm is inherently entrepreneurial," adds Beth.
This includes the operation of a farm stand. "It's important that the organic farm at Evergreen be modeling and teaching students how farms are doing business today," Beth says. Small farms across the country are pivoting to adapt their operations to new social distancing and hygiene protocols, and the organic farm at Evergreen is no exception.
Evergreen's farm stand is now located near the outbuildings of the farm rather than in the middle of campus, allowing easier access for the greater community. Beth and her colleagues built a hand washing station, procured bags to comply with single-use rules and have started looking in to digital platforms that will allow you to preorder and prepay for the items you want, allowing for a quick pick up.
While the program hasn't moved ahead with the digital platforms yet, the students prepare a weekly email distribution to let patrons of the farm stand know what's available for purchase. As a patron, you can reserve the items you'd like to purchase via email and pick up your pre-bagged orders on Thursday from 3:00 p.m. to 6:00 p.m. during the farm stand's operating hours. Plant starts are self-serve from designated racks, but all other produce is handled and bagged by the students running the stand. They are currently set up to take cash and check; a reliable means of paying by credit card is in the works.
The friendly farmers at the Evergreen farm stand will happily bag up your produce when you visit. Just point to what you'd like and you'll be on your way with fresh goodies in no time! Photo courtesy: The Evergreen State College
As of late May, the farm stand is offering more plant starts than produce. In normal times, the cohort of 23 students would have spent at least two days a week working on the farm throughout April and May. This year, Beth, her assistant manager, and two farm aides who qualified as essential food production workers right away because of their status as employees under a work-study program, have worked hard to keep farm operations on track.
The students have been in Zoom classes with David at least two hours a day, five days a week, since spring quarter started in early April. "I've front-loaded the book work so that as soon as we can get back into the field, we can maximize our time there," says David. Although there is plenty of book work to be done, the emphasis of this program is to emulate the experience of running a small organic farm as a business.
Students are cleared to return to work the farm in the third week of May. Beth has been working with the college's deans and Evergreen's Environmental Health and Safety Committee to ensure compliance with Governor Inslee's Phase 1 Higher Education & Critical Infrastructure Workforce Training Restart Plan. Students will work in small groups during two shifts wearing face coverings and gloves. Between morning and afternoon shifts, a two-hour break will allow Beth and the farm aides to sanitize equipment and high traffic areas.
Stop by Evergreen's farm stand every Thursday from 3:00 p.m. to 6:00 p.m. for a selection of plant starts and fresh produce. Come early for the best selection or pre-order your favorites by enrolling in the farm's email list. Photo courtesy: The Evergreen State College
Despite this season's setbacks, David and Beth both express confidence in the students' ability to work hard and get the farm back on schedule. The situation has given the students an opportunity to problem solve and think creatively about how their work gets done in the broader context of a global disaster. "Everything we do with the students here needs to emulate what it's like to run a farm, and this situation is no different," says Beth.
You can support the organic farm at Evergreen by visiting the farm stand on Thursdays from 3:00 p.m. to 6:00 p.m. Sign up for the email list by sending a message to OrganicFarm@evergreen.edu.
Previous articleInslee Announces Religious and Faith-Based Services Guidance
Next articleInslee Announces State's Long Term Care Testing Plan and Farmworker Protections
Blue Heron Bakery in West Olympia Goes Co-Op in a Unique Way and Invites You to Join
Architectural Drawings of Olympia Brewing Company Lobby 1961 Remodel Donated to Schmidt House


Following the preceeding two years the aim for this 3rd international symposium on the "Societal Impact of Pain" (SIP 2012) was to show the progress in implementing the "SIP - Road Map for Action" on both EU and Member State level. The Road Map was the key outcome of the second SIP symposium in the EU Parliament/ Brussels in 2011 and outlines seven main policy dimensions on how EU institutions and Member State governments can address the the societal impact of pain in order to improve the management of chronic pain in Europe.
Amongst other, impressive examples of local SIP platforms, the development of pain registries or progress in pain research and education were presented.
On the following subpages you will find the complete SIP 2012 programme, presentations & videos, as well as impressions and further symposium materials.


At the top of every docket, we provide a host of functions and features that allow you to search, display, print and download the docket any which way you want.
Using the search bar shown above, you can search the docket by keyword, document range, or date range. After entering your desired parameters, just click the blue magnifying glass (or hit enter on your keyboard) to execute your search & display only those docket entries that match your criteria.


Erika, You symbolize greatness through struggles and just giving!
Let's stay in touch and we are proud of you.
Cannot speak highly enough about Erika - she is one in a Million!
I love Erika. She so pretty and sing good.


You need to log in before you can use the adoption features of the site.
Occasionally users need to transfer ownership of their listings to other users. This is a handy utility for sending and receiving adoption requests and a way to help make the transition go smoothly for the new listing owner.


Most pastors have their 2005 soul winning plans developed. But if you are having a 'planners block' why not talk to your conference ministerial director. He can share ideas and resources with you. In addition Dan Serns & Ramon Canals will be available to give personal help at many of the January pastors' meetings. Check with your ministerial director or administration for available times.