예제 #1
0
class AResAlpha(object):
    """

    His results for alpha ratio

    """
    def __init__(self,
                 Info={},
                 thissym='Not Set',
                 thiscol='Not Set',
                 thisshift=0.0,
                 name='',
                 LLname='',
                 Auto=True):

        ## A infront of variable is for Ahmed file convention

        ## Initialising plotting parameters
        self.thisshift = thisshift
        self.thiscol = thiscol
        self.thissym = thissym

        # Opboot { it } bs
        self.alphaAvg = ODNested()
        self.alphaStd = ODNested()

        ## kappa up down (in integer form)
        if 'kud' in list(Info.keys()): self.kud = 'kud' + str(Info['kud'])
        else: self.kud = ''

        ## kappa strange (in integer form)
        if 'ks' in list(Info.keys()): self.ks = 'ks' + str(Info['ks'])
        else: self.ks = ''

        ## Current obersvables are TopCharge and Weinberg
        if 'Observable' in list(Info.keys()): self.Observ = Info['Observable']
        else: self.Observ = 'TopCharge'  ## default to TopCharge

        self.latparams = mp.LatticeParameters(Info=Info)
        self.latparams.LoadPickle()

        if self.Observ == 'TopCharge':
            self.thisconv = chitcoeff(self.latparams.nt, self.latparams.nxyz,
                                      self.latparams.latspace, 'QQ')
        else:
            self.thisconv = chitcoeff(self.latparams.nt, self.latparams.nxyz,
                                      self.latparams.latspace, 'WW')

        ## Ahmed only gave me a single flow time result, this will be changed when he gives me all flow times.
        if 'flowtime' in list(Info.keys()): self.flowtime = Info['flowtime']
        else: self.flowtime = 't_f6.00'  ## default to read all flow times

        self.kappafolder = 'Kud0' + self.kud.replace(
            'kud', '') + 'Ks0' + self.ks.replace('ks', '')
        self.AObserv = self.Observ.lower().replace('weinberg', 'weinopp')
        self.Akud = self.kud.replace('kud', 'K')[:-2]
        self.Aflowtime = self.flowtime.replace('t_f', '').replace('.', '')
        self.Auto = Auto

        self.SetCustomName(name, LLname)
        thisdir = outputdir + '/AhmedResults/'
        if self.Auto:
            self.readdir = thisdir + 'ratio_' + self.AObserv + '_' + self.Akud + '_at_flow_time_' + self.Aflowtime + '/'
        else:
            self.readdir = thisdir + 'ratio_boot_' + self.AObserv + '_' + self.Akud + '_at_flow_time_' + self.Aflowtime + '/'
        self.thisfile = 'Tauint_at_flow_time_' + self.Aflowtime + 'time_value_dvalue.txt'

    def ReadAlpha(self):
        print('reading ', self.readdir + self.thisfile)
        with open(self.readdir + self.thisfile, 'r') as f:
            ## first line has info
            f.readline()
            for line in f:
                fmtline = line.split()
                self.alphaAvg['t' + str(fmtline[0])] = np.float(fmtline[1])
                self.alphaStd['t' + str(fmtline[0])] = np.float(fmtline[2])

    def PlotAlpha(self,
                  xlims=defxlimAlpha,
                  thiscol='PreDefine',
                  thissym='PreDefine',
                  thisshift='PreDefine'):
        if thisshift != 'PreDefine':
            xlen = np.abs(xlims[1] - xlims[0])
            self.thisshift = thisshift * xlen
        if thissym != 'PreDefine': self.thissym = thissym
        if thiscol != 'PreDefine': self.thiscol = thiscol
        xvals, yvals, yerr = [], [], []
        for (it, iy), iyerr in zip(iter(self.alphaAvg.items()),
                                   iter(self.alphaStd.values())):
            itplot = untstr(it)
            if xlims[0] - 1 < itplot < xlims[1] + 1:
                xvals.append(itplot)
                yvals.append(iy / self.thisconv)
                yerr.append(iyerr / self.thisconv)
        if len(list(self.alphaAvg.keys())) == 0:
            raise EnvironmentError(
                'Please read in Ahmend results before plotting with self.ReadAlpha()'
            )
        if self.thiscol == 'Not Set' or self.thissym == 'Not Set':
            raise EnvironmentError(
                'plotting color or symbol not set, please initialise class or set when plotting'
            )
        # pl.errorbar(np.array(xvals)+self.thisshift,yvals,yerr,label=self.LegLab,fmt=self.thissym,color=self.thiscol)

    def SetCustomName(self, string='', stringLL=''):
        if string == '':
            self.name = self.filename = '_'.join(
                [self.kappafolder, self.Observ])
        else:
            self.filename = self.name = string
        if stringLL == '':
            if self.Auto:
                self.LegLab = '$' + '\ '.join([
                    self.latparams.GetPionMassLab(), self.Observ, 'Ahmed'
                ]) + '$ Auto'  ## customise this how you like
            else:
                self.LegLab = '$' + '\ '.join([
                    self.latparams.GetPionMassLab(), self.Observ, 'Ahmed'
                ]) + '$'  ## customise this how you like
        else:
            self.LegLab = stringLL
예제 #2
0
class AResChi2(object):
    """

    His results for <Q^{2}> or <W^{2}> (WITHOUT COEFFICIENT)

    """
    def __init__(self,
                 Info={},
                 thissym='Not Set',
                 thiscol='Not Set',
                 thisshift=0.0,
                 name='',
                 LLname=''):

        ## A infront of variable is for Ahmed file convention

        ## Initialising plotting parameters
        self.thisshift = thisshift
        self.thiscol = thiscol
        self.thissym = thissym

        # Opboot { it } bs
        self.Chi2Avg = ODNested()
        self.Chi2Std = ODNested()

        ## kappa up down (in integer form)
        if 'kud' in list(Info.keys()): self.kud = 'kud' + str(Info['kud'])
        else: self.kud = ''

        ## kappa strange (in integer form)
        if 'ks' in list(Info.keys()): self.ks = 'ks' + str(Info['ks'])
        else: self.ks = ''

        ## Current obersvables are TopCharge and Weinberg
        if 'Observable' in list(Info.keys()): self.Observ = Info['Observable']
        else: self.Observ = 'TopCharge'  ## default to TopCharge

        self.latparams = mp.LatticeParameters(Info=Info)
        self.latparams.LoadPickle()

        if 'TopCharge' in self.Observ:
            self.thisconv = chitcoeff(self.latparams.nt, self.latparams.nxyz,
                                      self.latparams.latspace, 'QQ')
        else:
            self.thisconv = chitcoeff(self.latparams.nt, self.latparams.nxyz,
                                      self.latparams.latspace, 'WW')

        # ## this is used display only these flowtimes, Still reads and writes all
        # if 'tflowlist' in Info.keys(): self.tflowlist = Info['tflowlist']
        # else: self.tflowlist = defxlimOp ## default to read all flow times

        # listout = []
        # for ict,itflow in enumerate(self.tflowlist):
        #     if 't_f' not in str(itflow):
        #         listout.append(tflowstr(itflow))
        #     else:
        #         listout.append(itflow)
        # self.tflowfloat = [untflowstr(itflow) for itflow in listout]
        # self.tflowlist = np.array(listout)

        self.kappafolder = 'Kud0' + self.kud.replace(
            'kud', '') + 'Ks0' + self.ks.replace('ks', '')
        if 'topcharge' in self.Observ.lower().replace('weinberg', 'weinopp'):
            self.AObserv = 'topcharge'
        elif 'weinopp' in self.Observ.lower().replace('weinberg', 'weinopp'):
            self.AObserv = 'weinopp'
        self.Akud = self.kud.replace('kud', '')[:-2]

        self.SetCustomName(name, LLname)
        thisdir = outputdir + '/AhmedResults/'
        self.readdir = thisdir + self.AObserv + self.Akud + '/'
        self.thisfile = self.AObserv + self.Akud + '.txt'

    def ReadChi2(self):
        print('reading ', self.readdir + self.thisfile)
        with open(self.readdir + self.thisfile, 'r') as f:
            ## first line has info
            f.readline()
            for line in f:
                fmtline = line.split()
                tflowkey = tflowstr(float(fmtline[0]) / 100)
                self.Chi2Avg[tflowkey] = np.float(fmtline[1])
                self.Chi2Std[tflowkey] = np.float(fmtline[2])

    def CorrectAhmed(self, iy, iyerr):
        if 'TopCharge' in self.Observ or 'Q' in self.Observ:
            return iy**(1 / 4.), iy**(-3 / 4.) * iyerr / 4.
        else:
            return iy**(1 / 8.), iy**(-7 / 8.) * iyerr / 8.

    # def CorrectAhmed(self,iy,iyerr):
    #     return iy,iyerr

    def PlotChi2(self,
                 xlims='data',
                 thiscol='PreDefine',
                 thissym='PreDefine',
                 thisshift='PreDefine'):
        if len(list(self.Chi2Avg.keys())) == 0:
            raise EnvironmentError(
                'Please read in Ahmend results before plotting with self.ReadChi2()'
            )
        if isinstance(xlims, str) and xlims == 'data':
            xlims = list(self.Chi2Avg.keys())
        if (not isinstance(xlims[0], str)) or 't_f' not in xlims[0]:
            xlims = list(map(tflowstr, xlims))
        if thisshift != 'PreDefine':
            xlen = np.abs(xlims[1] - xlims[0])
            self.thisshift = thisshift * xlen
        if thissym != 'PreDefine': self.thissym = thissym
        if thiscol != 'PreDefine': self.thiscol = thiscol
        if self.thiscol == 'Not Set' or self.thissym == 'Not Set':
            raise EnvironmentError(
                'plotting color or symbol not set, please initialise class or set when plotting'
            )
        xvals, yvals, yerr = [], [], []
        for (it, iy), iyerr in zip(iter(self.Chi2Avg.items()),
                                   iter(self.Chi2Std.values())):
            itplot = TflowToPhys(np.array([untflowstr(it)]),
                                 self.latparams.latspace)[0]
            if it in xlims:
                iycorr, iyerrcorr = self.CorrectAhmed(iy, iyerr)
                xvals.append(itplot)
                yvals.append(iycorr * self.thisconv)
                yerr.append(iyerrcorr * self.thisconv)
        # pl.errorbar(np.array(xvals)+self.thisshift,yvals,yerr,label=self.LegLab,fmt=self.thissym,color=self.thiscol)

    def SetCustomName(self, string='', stringLL=''):
        if string == '':
            self.name = self.filename = '_'.join(
                [self.kappafolder, self.Observ])
        else:
            self.filename = self.name = string
        if stringLL == '':
            self.LegLab = '$' + '\ '.join([
                self.latparams.GetPionMassLab(), self.Observ, 'Ahmed'
            ]) + '$'  ## customise this how you like
        else:
            self.LegLab = stringLL
예제 #3
0
class FormFact(object):
    """

    This class should produce all form factor combinations for a particular from factor type
    (e.g. vector, pseudo-vector, tensor etc...)

    """
    def Construct_FormFact_File(this_file):
        return Construct_File_Object(this_file, FormFact)

    def __init__(self,
                 currtype,
                 q2list,
                 pp2list=[0],
                 Info=defInfo,
                 tflowlist=[],
                 name=''):

        if currtype not in CurrTypes:
            raise IOError(
                currtype +
                ' not recognised as a current type in FormFactors.py')
        self.currtype = currtype
        self.doflow = ('Top' in self.currtype) or ('Wein' in self.currtype)
        self.fffun = FFFitFuns[currtype]
        self.currOp = CurrOpps[currtype]
        self.currOpNP = CurrOppsNoProj[currtype]
        self.currOpNPFSig = CurrOppsNoProjSigBack[currtype]
        self.npar = NoFFPars[currtype]
        self.ffpars = FFParams[currtype]
        self.kappafolder = ''

        self.ppparams = mp.LatticeParameters(mom2list=pp2list, Info=Info)
        self.ppparams.LoadPickle()
        self.qparams = mp.LatticeParameters(mom2list=q2list, Info=Info)
        self.qparams.LoadPickle()
        self.nt = self.qparams.nt
        self.nxyz = self.qparams.nxyz
        self.dim_label = 'RC' + str(self.nxyz) + 'x' + str(self.nt)
        self.dim_ll = str(self.nxyz) + r'^{3}\times ' + str(self.nt)

        tracespin = CorrSpinTrace()
        self.FFFun = tracespin[self.currtype]
        self.tflowlist = tflowlist
        # if not isinstance(mass,basestring):
        #     self.SetMass(mass)
        # else:
        #     self.mass = 'Not Set'
        # if not isinstance(alpha,basestring):
        #     self.SetAlpha(alpha,tflowlist)
        # else:
        #     self.alpha = 'Not Set'
        self.mass = 'Not Set'
        self.alpha = 'Not Set'
        self.SetCustomName(name)

        # ## self.paramDict { icurrOp , ipkey , iqkey , imass (, tflow ) , ipar } bs
        # ## (, tflow) if cp odd form factor with flow times
        # self.paramDict = 'Not Set'

        if self.doflow:
            self.param_Col_Names = [
                'current_operator', 'sink_momentum', 'current_momentum',
                'mass_and_alpha', 'flow_time', 'form_factor'
            ]
            self.paramRed_Col_Names = [
                'current_operator', 'sink_momentum', 'current_momentum',
                'mass_and_alpha', 'flow_time', 'form_factor'
            ]
        else:
            self.param_Col_Names = [
                'current_operator', 'sink_momentum', 'current_momentum',
                'mass', 'form_factor'
            ]
            self.paramRed_Col_Names = [
                'current_operator', 'sink_momentum', 'current_momentum',
                'mass', 'form_factor'
            ]
        self.param_Stats = pa.DataFrame()
        '''
        columns = FF FFAvg FFStd
        rows are param_Col_Names
        '''

        self.paramRed_Stats = pa.DataFrame()
        '''
        columns = FF FFAvg FFStd
        rows are param_Col_Names
        '''

    def AppendName(self):
        this_str = self.name
        if isinstance(self.mass, (dict, OrderedDict)):
            this_str += '_' + list(self.mass.keys())[0]
        if isinstance(self.alpha, (dict, OrderedDict)):
            this_str += '_' + list(self.alpha.keys())[0] + '_' + list(
                list(self.alpha.values())[0].keys())[0]
        self.SetCustomName(string=this_str)

    def SetCustomName(self, string=''):
        if string == '':
            # if len(self.tflowlist) > 0:
            #     if self.tflowlist[0] == 'none':
            #         self.name = '_'.join([  self.currtype,'q'+''.join(map(str,self.qparams.mom2list)),
            #                                 'pp'+''.join(map(str,self.ppparams.mom2list))])
            #     else:
            #         self.name = '_'.join([  self.currtype,'q'+''.join(map(str,self.qparams.mom2list)),
            #                                 'pp'+''.join(map(str,self.ppparams.mom2list)),self.tflowlist[0]])
            # else:
            self.name = '_'.join([
                self.currtype, 'q' + ''.join(map(str, self.qparams.mom2list)),
                'pp' + ''.join(map(str, self.ppparams.mom2list))
            ])
        else:
            self.name = string

        self.FFcoeffDir = outputdir + '/' + self.dim_label + self.kappafolder + 'FFcoeffs/'
        mkdir_p(self.FFcoeffDir + '/Pickle/')
        mkdir_p(self.FFcoeffDir + '/Excel/')
        self.HumanFile = self.FFcoeffDir + self.name + '.xml'
        self.ExcelFile = self.FFcoeffDir + '/Excel/' + self.name + '.xlsx'
        self.PickleFile = self.FFcoeffDir + '/Pickle/' + self.name + '.py3p'

    def GetRedFFParms(self):
        if len(self.param_Stats) == 0:
            self.GetFFParams()
        vall, keyl = [], []
        vall_nd, qsqrdlist = [], []
        Avgl, Stdl = [], []
        keycombl, coeffl = [], []
        for ikey, iFF in self.param_Stats['FF'].groupby(
                self.paramRed_Col_Names[:-1]):
            if isinstance(ikey, str):
                this_key = list(iFF.index[0])
                iq = this_key[2]
            else:
                this_key = ikey
                iq = ikey[2]
            thisqsqrd = self.qparams.Getpsqrdform(iq, pre='q')
            checkbool = True
            FFvals = iFF.values
            FFvalsAvg = np.array([hold_val.Avg for hold_val in FFvals])
            for ic, iffavg in enumerate(FFvalsAvg):
                if abs(iffavg) > myeps:
                    break
                elif ic == len(FFvalsAvg) - 1:
                    print('Warning, form factor is all zero for:')
                    print(ikey)
            for ics, (pref_ff,
                      prev_qsqrd) in enumerate(zip(vall_nd, qsqrdlist)):
                prev_ffAvg = np.array([hold_val.Avg for hold_val in pref_ff])
                comp_rat = prev_ffAvg[ic] / FFvalsAvg[ic]
                rat_list = []
                for denomen, numer in zip(FFvalsAvg, prev_ffAvg):
                    if denomen == 0:
                        if numer != 0:
                            rat_list.append(False)
                    else:
                        rat_list.append(numer / denomen)
                if all(rat_list == comp_rat) and prev_qsqrd == thisqsqrd:
                    checkbool = False
                    keycombl[ics].append(this_key)
                    coeffl[ics].append(comp_rat)
                    break
            if checkbool:
                keycombl.append([this_key])
                coeffl.append([1.0])
                vall += list(FFvals)
                vall_nd.append(list(FFvals))
                qsqrdlist.append(thisqsqrd)
                Avgl += [ival.Avg for ival in FFvals]
                Stdl += [ival.Std for ival in FFvals]
                keyl += list(iFF.keys())
        if len(keyl) > 0:
            indicies = pa.MultiIndex.from_tuples(keyl,
                                                 names=self.paramRed_Col_Names)
            self.paramRed_Stats.loc[:, 'FF'] = pa.Series(vall, index=indicies)
            self.paramRed_Stats.loc[:, 'FFAvg'] = pa.Series(Avgl,
                                                            index=indicies)
            self.paramRed_Stats.loc[:, 'FFStd'] = pa.Series(Stdl,
                                                            index=indicies)
            self.combine_keys_forRF = keycombl
            self.coeffs_forRF = coeffl
        else:
            print('Warning, error with reducing form factor list')
            print(self.param_Stats['FF'])

    ## imass is input parameter since we can use bootstrapped values
    ## wrapped by MassFFParams()
    def GetFFParms(self):
        # if thismass != 'PreDef': self.SetMass(thismass)
        # if thisalpha != 'PreDef' and self.doflow: self.SetAlpha(thisalpha,thistflowlist)

        if self.mass == 'Not Set':
            raise IOError(
                'mass not set, either pass into MassFFParams() or use SetMass()'
            )
        if self.alpha == 'Not Set':
            self.alpha = {}
            for itflow in self.tflowlist:
                if itflow == 'none': continue
                self.alpha[itflow] = {'Test': alpha_guess}
        plist, pAvg, pStd = [], [], []
        ilist = []
        if self.doflow and len(self.tflowlist) == 0:
            raise IOError('no tflowlist present with flowed operators')
        looplist = [
            self.currOp, self.ppparams.momformlist, self.qparams.momformlist
        ]
        thistimer = Timer(linklist=looplist, name='FF ' + self.name)
        for icurrOp in self.currOp:
            for ip in self.ppparams.momformlist:
                for iq in self.qparams.momformlist:
                    ipvec, iqvec = list(self.ppparams.TOpvec(
                        ip, actual=True)), list(
                            self.qparams.TOpvec(iq, actual=True))
                    ipkey, iqkey = self.ppparams.TOpform(
                        ip, 'pp'), self.qparams.TOpform(iq, 'q')
                    hold, rcheck, ccheck = self.FFFun(
                        icurrOp, iqvec, ipvec,
                        list(self.mass.values())[0].Avg)
                    if ccheck == True and rcheck == True:
                        print(hold)
                        raise ArithmeticError(
                            'Operator ' + ' '.join(icurrOp +
                                                   ('pp' + ip, 'q' + iq)) +
                            ' has both real and imaginary components, check Form Factor coeff construction'
                        )
                    elif ccheck == True:
                        Opout = icurrOp + ('cmplx', )
                    else:
                        Opout = icurrOp
                    for imass, bootmass in self.mass.items():
                        if self.doflow:
                            for itflow in self.tflowlist:
                                for ialpha, bootalpha in self.alpha[
                                        itflow].items():
                                    holdlist = [[] for i in self.ffpars]
                                    # print bootmass.Avg,iqvec,ipvec,icurrOp
                                    # print rcheck, ccheck
                                    # print hold
                                    thisalpha = [bootalpha] * len(
                                        bootmass.bootvals)
                                    if isinstance(bootalpha, BootStrap):
                                        thisalpha = bootalpha.bootvals
                                    for bmass, balpha in zip(
                                            bootmass.bootvals, thisalpha):
                                        hold, rdump, cdump = self.FFFun(
                                            icurrOp,
                                            iqvec,
                                            ipvec,
                                            bmass,
                                            alpha=balpha)
                                        if rcheck:
                                            for icpar, ipar in enumerate(
                                                    self.ffpars):
                                                holdlist[icpar].append(
                                                    hold[icpar].real)
                                        if ccheck:
                                            for icpar, ipar in enumerate(
                                                    self.ffpars):
                                                holdlist[icpar].append(
                                                    hold[icpar].imag)
                                    for icpar, ipar in enumerate(self.ffpars):
                                        if len(holdlist[icpar]
                                               ) != bootmass.nboot:
                                            continue
                                        ilist.append(
                                            ('_'.join(Opout), ipkey, iqkey,
                                             '_'.join([imass,
                                                       ialpha]), itflow, ipar))
                                        this_param = BootStrap(
                                            bootmass.nboot,
                                            name=ipar,
                                            bootvals=holdlist[icpar])
                                        plist.append(this_param)
                                        pAvg.append(this_param.Avg)
                                        pStd.append(this_param.Std)
                        else:
                            holdlist = [[] for i in self.ffpars]
                            for bmass in bootmass.bootvals:
                                hold, rdump, cdump = self.FFFun(
                                    icurrOp,
                                    iqvec,
                                    ipvec,
                                    bmass,
                                    alpha=self.alpha)
                                if rcheck:
                                    for icpar, ipar in enumerate(self.ffpars):
                                        holdlist[icpar].append(
                                            hold[icpar].real)
                                if ccheck:
                                    for icpar, ipar in enumerate(self.ffpars):
                                        holdlist[icpar].append(
                                            hold[icpar].imag)
                            for icpar, ipar in enumerate(self.ffpars):
                                if len(holdlist[icpar]) != bootmass.nboot:
                                    continue
                                ilist.append(('_'.join(Opout), ipkey, iqkey,
                                              imass, ipar))
                                this_param = BootStrap(
                                    bootmass.nboot,
                                    name=ipar,
                                    bootvals=holdlist[icpar])
                                plist.append(this_param)
                                pAvg.append(this_param.Avg)
                                pStd.append(this_param.Std)
                    thistimer.Lap()
        if len(ilist) > 0:
            indicies = pa.MultiIndex.from_tuples(ilist,
                                                 names=self.param_Col_Names)
            self.param_Stats.loc[:, 'FF'] = pa.Series(plist, index=indicies)
            self.param_Stats.loc[:, 'FFAvg'] = pa.Series(pAvg, index=indicies)
            self.param_Stats.loc[:, 'FFStd'] = pa.Series(pStd, index=indicies)

    ## self.mass ends up as BootStrap class
    def SetMass(self, mass):
        self.mass = ODNested()
        if isinstance(mass, TwoPointCorr):
            if 'boot' not in mass.C2_Fit_Stats:
                raise IOError(
                    'C2_Fit_Stats in TwoPointCorr not calculated, please run Fit() on TwoPointCorr instance'
                )
            for (istate, ip), fitdata in mass.C2_Fit_Stats['boot'].items():
                if ip != 'p000': continue
                ifitr, this_data = fitdata.GetMaxFitr()
                self.mass['C2_' + '_'.join([istate, ifitr])] = this_data.iloc[
                    0].fit_data['Params']['Energy']
        elif isinstance(mass, Fitting):
            if 'Energy' not in list(mass.fit_data['Params'].keys()):
                print(list(mass.fit_data['Params'].keys()))
                raise IOError('Fitting class instance has no parameter Energy')
            self.mass['C2_' + mass.name] = mass.fit_data['Params']['Energy']
        elif isinstance(mass, BootStrap):
            self.mass['C2_' + mass.name] = mass
        elif mass == 'Not Set':
            self.mass = 'Not Set'
        else:
            raise IOError(
                'mass input type not recognisied (see FormFactors.py, SetMass())'
            )

    def GetFuns(self):
        if not hasattr(self, 'FFFun'):
            self.FFFun, self.fffun = ReadFuns(self.FFFun_name, self.fffun_name)

    def RemoveFuns(self):
        if hasattr(self, 'FFFun') and hasattr(self.FFFun, '__name__'):
            self.FFFun_name = self.FFFun.__name__
            self.fffun_name = self.fffun.__name__
            WriteFuns(self.FFFun, self.fffun)
            del self.FFFun
            del self.fffun

    ## self.Alpha ends up as BootStrap class
    def SetAlpha(self, alpha, tflowlist):
        self.alpha = ODNested()
        self.tflowlist = tflowlist
        if isinstance(alpha, NNQFullCorr):
            # if self.kappafolder not in  ['',alpha.kappafolder+'/']:
            #     raise IOError('kappa folders used in FormFact (from FormFactors.py) have changed, check alpha and mass used.')
            # self.kappafolder = alpha.kappafolder + '/'
            # self.SetCustomName(string=self.name)
            if 'boot' not in alpha.NNQFull_Fit_Stats:
                raise IOError(
                    'No fits have been performed on the AlphaFull object passed to Form Factors'
                )
            for itflow in tflowlist:
                if ('p000',
                        itflow) not in alpha.NNQFull_Fit_Stats['boot'].index:
                    print(alpha.NNQFull_Fit_Stats['boot'])
                    raise IOError(
                        'No zero momentum found in NNQFull_Fit_Stats in TwoPointCorr, try running Fit()'
                    )
                ifitr, this_data = alpha.NNQFull_Fit_Stats.at[(
                    'p000', itflow), 'boot'].GetMaxFitr()
                ifitr = ifitr.replace('fittwor', 'tsumfitr')
                self.alpha[itflow][
                    'alpha_' +
                    ifitr] = this_data.iloc[0].fit_data['Params'].iloc[0]
            return
        elif isinstance(alpha, NNQCorr):
            # if self.kappafolder not in  ['',alpha.kappafolder+'/']:
            #     raise IOError('kappa folders used in FormFact (from FormFactors.py) have changed, check alpha and mass used.')
            # self.kappafolder = alpha.kappafolder + '/'
            # self.SetCustomName(string=self.name)
            if 'boot' not in alpha.NNQ_Fit_Stats:
                raise IOError(
                    'No fits have been performed on the Alpha object passed to Form Factors'
                )
            for itflow in tflowlist:
                if ('p000', itflow) not in alpha.NNQ_Fit_Stats['boot'].index:
                    print(alpha.NNQ_Fit_Stats['boot'])
                    raise IOError(
                        'No zero momentum found in NNQ_Fit_Stats in TwoPointCorr, try running Fit()'
                    )
                ifitr, this_data = alpha.NNQ_Fit_Stats.at[('p000', itflow),
                                                          'boot'].GetMaxFitr()
                self.alpha[itflow][
                    'alpha_' +
                    ifitr] = this_data.iloc[0].fit_data['Params'].iloc[0]
            return
        try:
            firstflow = list(alpha.keys())[0]
            if isinstance(alpha[firstflow], Fitting):
                for itflow in tflowlist:
                    if itflow not in list(alpha.keys()):
                        raise IOError(
                            'No tflow found in alpha.keys(), alpha can be dictionary with tflows'
                        )
                    if 'Energy' not in list(alpha.fit_data['Params'].keys()):
                        print(list(alpha[itflow].fit_data['Params'].keys()))
                        raise IOError(
                            'Fitting class instance has no parameter Energy')
                    self.alpha[itflow][
                        'alpha_' +
                        alpha.name] = alpha.fit_data['Params'].iloc[0]
            elif isinstance(alpha[firstflow], BootStrap):
                for itflow in tflowlist:
                    if itflow not in list(alpha.keys()):
                        raise IOError(
                            'No tflow found in alpha.keys(), alpha can be dictionary with tflows'
                        )
                    self.alpha[itflow]['alpha_' + alpha.name] = alpha
        except Exception as err:
            if alpha == 'No Alpha' or alpha == 'PreDef':
                self.alpha = 'Not Set'
            elif self.alpha != 'Not Set':
                print(type(alpha))
                if isinstance(alpha, str):
                    print(alpha)
                raise IOError(
                    'alpha input type not recognisied (see FormFactors.py, SetAlpha())'
                )

    def __getitem__(self, ikey):
        return self.param_Stats['FF'][ikey]

    ## if data is instance of FormFact (e.g. data = FormFact(...)
    ## for iOp,ipkey,iqkey,imass,ipar,data in data.items():
    ##    etc.....
    def items(self):
        return list(self.param_Stats['FF'].items())

    def iteritems(self):
        return iter(self.param_Stats['FF'].items())

    def iteritemsRed(self):
        return iter(self.paramRed_Stats['FF'].items())

    def itemsMass(self):
        ## self.paramDict { icurrOp , ipkey , iqkey , imass } bs
        output = []
        for icurrOp, currdata in self.paramDict.items():
            for ipkey, pdata in currdata.items():
                for iqkey, qdata in pdata.items():
                    output.append((icurrOp, ipkey, iqkey, qdata))
        return output

    def itemsParList(self):
        ## self.paramDict { icurrOp , ipkey , iqkey , imass } bs
        output = []
        if self.doflow:
            this_levels = ('current_operator', 'sink_momentum',
                           'current_momentum', 'mass_and_alpha', 'flow_time')
            for (icurrOp, ipkey, iqkey, imass,
                 itflow), flow_data in self.param_Stats['FF'].groupby(
                     level=this_levels):
                this_fdata = flow_data[icurrOp, ipkey, iqkey, imass, itflow]
                output.append((icurrOp, ipkey, iqkey, imass, itflow,
                               list(this_fdata.keys()), this_fdata.values))
        else:
            this_levels = ('current_operator', 'sink_momentum',
                           'current_momentum', 'mass')
            for (icurrOp, ipkey, iqkey,
                 imass), flow_data in self.param_Stats['FF'].groupby(
                     level=this_levels):
                this_fdata = flow_data[icurrOp, ipkey, iqkey, imass]
                output.append((icurrOp, ipkey, iqkey, imass,
                               list(this_fdata.keys()), this_fdata.values))
        return output

    def itemsParListRed(self):
        ## self.paramDict { icurrOp , ipkey , iqkey , imass } bs
        output = []
        if self.doflow:
            this_levels = ('current_operator', 'sink_momentum',
                           'current_momentum', 'mass_and_alpha', 'flow_time')
            for (icurrOp, ipkey, iqkey, imass,
                 itflow), flow_data in self.paramRed_Stats['FF'].groupby(
                     level=this_levels):
                this_fdata = flow_data[icurrOp, ipkey, iqkey, imass, itflow]
                output.append((icurrOp, ipkey, iqkey, imass, itflow,
                               list(this_fdata.keys()), this_fdata.values))
        else:
            this_levels = ('current_operator', 'sink_momentum',
                           'current_momentum', 'mass')
            for (icurrOp, ipkey, iqkey,
                 imass), flow_data in self.paramRed_Stats['FF'].groupby(
                     level=this_levels):
                this_fdata = flow_data[icurrOp, ipkey, iqkey, imass]
                output.append((icurrOp, ipkey, iqkey, imass,
                               list(this_fdata.keys()), this_fdata.values))
        return output

    def itemsAvgStd(self):
        outlist = []
        for ivals in self.param_Stats.itertuples():
            outlist.append((ivals[0], ivals[2], ivals[3]))
        return outlist

    def values(self):
        ## self.paramDict { icurrOp , ipkey , iqkey , imass , ipar } bs
        return self.param_Stats['FF'].values

    def valuesAvgStd(self):
        ## self.paramDict { icurrOp , ipkey , iqkey , imass , ipar } bs
        outlist = []
        for ivals in self.param_Stats.itertuples():
            outlist.append((ivals[2], ivals[3]))
        return outlist

    def keys(self):
        return list(self.param_Stats.keys())

    def keysOpMoms(self):
        ## self.paramDict { icurrOp , ipkey , iqkey , imass , ipar } bs
        output = []
        for (icurrOp, ipkey, iqkey), idata in self.param_Stats['FF'].groupby(
                level=('current_operator', 'sink_momentum',
                       'current_momentum')):
            output.append((icurrOp.split('_'), ipkey, iqkey))
        return output

    def keysOpMomsRed(self):
        ## self.paramDict { icurrOp , ipkey , iqkey , imass , ipar } bs
        output = []
        for (icurrOp, ipkey,
             iqkey), idata in self.paramRed_Stats['FF'].groupby(
                 level=('current_operator', 'sink_momentum',
                        'current_momentum')):
            output.append((icurrOp.split('_'), ipkey, iqkey))
        return output

    def Write(self):
        def FixDictArray(thislist, ikey):
            outDict = OrderedDict()
            for ic, ilist in enumerate(thislist):
                outDict[ikey + str(ic + 1)] = ilist
            return outDict

        self.outDict = ODNested()
        self.outDict['Type'] = self.currtype
        self.outDict['FFparams'] = FixDictArray(self.ffpars, 'FF')
        self.outDict['tflowlist'] = FixDictArray(self.tflowlist, 'flow')
        ## TODO, output more information about momenta if you would like
        self.outDict['nt'] = self.nt
        self.outDict['nxyz'] = self.nxyz
        self.outDict['q2max'] = self.qparams.mom2max
        self.outDict['q2min'] = self.qparams.mom2min
        self.outDict['pp2max'] = self.ppparams.mom2max
        self.outDict['pp2min'] = self.ppparams.mom2min
        excel_params = pa.Series(deepcopy(self.outDict))
        firstkey = list(self.mass.keys())[0]
        excel_params['massAvg_' + firstkey] = list(self.mass.values())[0].Avg
        excel_params['massStd_' + firstkey] = list(self.mass.values())[0].Std
        for icFF, iFF in excel_params['FFparams'].items():
            excel_params[icFF] = iFF
        for ictflow, itflow in excel_params['tflowlist'].items():
            excel_params[ictflow] = itflow
        del excel_params['FFparams']
        del excel_params['tflowlist']

        if self.doflow:
            for itflow in self.tflowlist:
                firstdata = list(self.alpha[itflow].values())[0]
                if isinstance(firstdata, BootStrap):
                    excel_params['AlphaAvg_' + firstkey + '_' +
                                 itflow] = firstdata.Avg
                else:
                    excel_params['AlphaAvg_' + firstkey + '_' +
                                 itflow] = firstdata
            for itflow in self.tflowlist:
                firstdata = list(self.alpha[itflow].values())[0]
                if isinstance(firstdata, BootStrap):
                    excel_params['AlphaStd_' + firstkey + '_' +
                                 itflow] = firstdata.Std

        for ikey, massdata in self.mass.items():
            if isinstance(massdata, BootStrap):
                self.outDict['mass'][ikey] = AvgStdToFormat(
                    massdata.Avg, massdata.Std)
            else:
                self.outDict['mass'][ikey] = massdata
        if self.doflow:
            for itflow, alphatflow in self.alpha.items():
                firstalpha = list(alphatflow.values())[0]
                alpha_key = list(alphatflow.keys())[0]
                if isinstance(firstalpha, BootStrap):
                    self.outDict['alpha'][alpha_key][itflow] = AvgStdToFormat(
                        firstalpha.Avg, firstalpha.Std)
                else:
                    self.outDict['alpha'][alpha_key][itflow] = firstalpha
        if self.doflow:
            for (gammakey, ipp, iq, imass, itflow,
                 ipar), paramdata in self.items():
                thisqsqrd = self.qparams.Getpsqrdform(iq, pre='q')
                ## TODO, this is incorrectly order with respect to qsqrd, need to write function to fix this somewhere
                ## also, you can play around with the ordering of keys to get the formating you like !!
                # self.outDict[imass][ipp][itflow][self.qparams.Getpsqrdform(iq,pre='q')]['Coeff_of_'+ipar]['_'.join([gammakey,iq])] = AvgStdToFormat(paramdata.Avg,paramdata.Std)
                try:
                    self.outDict['Equations'][imass][ipp][itflow][thisqsqrd][
                        '_'.join([gammakey, iq])] += ' (' + AvgStdToFormat(
                            paramdata.Avg, paramdata.Std, dec=5,
                            numlen=8) + ') ' + ipar + ' +'
                except Exception as err:
                    self.outDict['Equations'][imass][ipp][itflow][thisqsqrd][
                        '_'.join([gammakey, iq])] = ' (' + AvgStdToFormat(
                            paramdata.Avg, paramdata.Std, dec=5,
                            numlen=8) + ') ' + ipar + ' +'
                if ipar == self.ffpars[-1]:
                    self.outDict['Equations'][imass][ipp][itflow][thisqsqrd][
                        '_'.join([gammakey, iq])] = self.outDict['Equations'][
                            imass][ipp][itflow][thisqsqrd]['_'.join(
                                [gammakey, iq])][:-1]
        else:
            for (gammakey, ipp, iq, imass, ipar), paramdata in self.items():
                thisqsqrd = self.qparams.Getpsqrdform(iq, pre='q')
                ## TODO, this is incorrectly order with respect to qsqrd, need to write function to fix this somewhere
                ## also, you can play around with the ordering of keys to get the formating you like !!
                try:
                    self.outDict['Equations'][imass][ipp][thisqsqrd]['_'.join(
                        [gammakey, iq])] += ' (' + AvgStdToFormat(
                            paramdata.Avg, paramdata.Std, dec=5,
                            numlen=8) + ') ' + ipar + ' +'
                except Exception as err:
                    self.outDict['Equations'][imass][ipp][thisqsqrd]['_'.join(
                        [gammakey, iq])] = ' (' + AvgStdToFormat(
                            paramdata.Avg, paramdata.Std, dec=5,
                            numlen=8) + ') ' + ipar + ' +'
                if ipar == self.ffpars[-1]:
                    self.outDict['Equations'][imass][ipp][thisqsqrd]['_'.join([
                        gammakey, iq
                    ])] = self.outDict['Equations'][imass][ipp][thisqsqrd][
                        '_'.join([gammakey, iq])][:-1]

        if self.doflow:
            for (gammakey, ipp, iq, imass, itflow,
                 ipar), paramdata in self.iteritemsRed():
                thisqsqrd = self.qparams.Getpsqrdform(iq, pre='q')
                ## TODO, this is incorrectly order with respect to qsqrd, need to write function to fix this somewhere
                ## also, you can play around with the ordering of keys to get the formating you like !!
                # self.outDict[imass][ipp][itflow][self.qparams.Getpsqrdform(iq,pre='q')]['Coeff_of_'+ipar]['_'.join([gammakey,iq])] = AvgStdToFormat(paramdata.Avg,paramdata.Std)
                try:
                    self.outDict['Equations_Reduced'][imass][ipp][itflow][
                        thisqsqrd]['_'.join(
                            [gammakey, iq])] += ' (' + AvgStdToFormat(
                                paramdata.Avg, paramdata.Std, dec=5,
                                numlen=8) + ') ' + ipar + ' +'
                except Exception as err:
                    self.outDict['Equations_Reduced'][imass][ipp][itflow][
                        thisqsqrd]['_'.join(
                            [gammakey, iq])] = ' (' + AvgStdToFormat(
                                paramdata.Avg, paramdata.Std, dec=5,
                                numlen=8) + ') ' + ipar + ' +'
                if ipar == self.ffpars[-1]:
                    self.outDict['Equations_Reduced'][imass][ipp][itflow][
                        thisqsqrd]['_'.join([
                            gammakey, iq
                        ])] = self.outDict['Equations_Reduced'][imass][ipp][
                            itflow][thisqsqrd]['_'.join([gammakey, iq])][:-1]
        else:
            for (gammakey, ipp, iq, imass,
                 ipar), paramdata in self.iteritemsRed():
                thisqsqrd = self.qparams.Getpsqrdform(iq, pre='q')
                ## TODO, this is incorrectly order with respect to qsqrd, need to write function to fix this somewhere
                ## also, you can play around with the ordering of keys to get the formating you like !!
                try:
                    self.outDict['Equations_Reduced'][imass][ipp][thisqsqrd][
                        '_'.join([gammakey, iq])] += ' (' + AvgStdToFormat(
                            paramdata.Avg, paramdata.Std, dec=5,
                            numlen=8) + ') ' + ipar + ' +'
                except Exception as err:
                    self.outDict['Equations_Reduced'][imass][ipp][thisqsqrd][
                        '_'.join([gammakey, iq])] = ' (' + AvgStdToFormat(
                            paramdata.Avg, paramdata.Std, dec=5,
                            numlen=8) + ') ' + ipar + ' +'
                if ipar == self.ffpars[-1]:
                    self.outDict['Equations_Reduced'][imass][ipp][thisqsqrd][
                        '_'.join([gammakey,
                                  iq])] = self.outDict['Equations_Reduced'][
                                      imass][ipp][thisqsqrd]['_'.join(
                                          [gammakey, iq])][:-1]

        ## Write human readable file with data
        WriteXml(self.HumanFile, {'Results': self.outDict})

        WriteExcel(self.ExcelFile, {'FF_results': deepcopy(self.param_Stats)},
                   params=excel_params)

        ## pickles rest of data for reading
        self.RemoveFuns()
        WritePickle(self.PickleFile, self.__dict__)
        self.GetFuns()

    def LoadKappaDir(self, mass, alpha='None'):
        if isinstance(mass, TwoPointCorr):
            if self.kappafolder.replace('/', '') not in ['', mass.kappafolder]:
                raise IOError(
                    'kappa folders used in FormFact (from FormFactors.py) have changed, check alpha and mass used.'
                )
            self.kappafolder = mass.kappafolder + '/'
        if isinstance(alpha, NNQFullCorr) or isinstance(alpha, NNQCorr):
            if self.kappafolder.replace('/',
                                        '') not in ['', alpha.NN.kappafolder]:
                raise IOError(
                    'kappa folders used in FormFact (from FormFactors.py) have changed, check alpha and mass used.'
                )
            self.kappafolder = alpha.NN.kappafolder + '/'
        self.SetCustomName(string=self.name)

    def LoadPickle(self,
                   thismass,
                   thisalpha='No Alpha',
                   thistflowlist=[],
                   DefWipe=False):
        # if self.doflow and thisalpha == 'No Alpha':
        #     raise EnvironmentError('alpha is needed for FormFact when using FO form factor.')
        self.LoadKappaDir(thismass, alpha=thisalpha)
        self.SetMass(thismass)
        self.SetAlpha(thisalpha, thistflowlist)
        self.AppendName()

        # print 'loading ', self.PickleFile, 'with DefWipe ' , DefWipe
        if os.path.isfile(self.PickleFile) and not DefWipe:
            # print 'Loading Pickle for ' , self.name

            thispickle = ReadPickleWrap(self.PickleFile)
            # print thistflowlist, thispickle['tflowlist'],self.doflow
            if len(thistflowlist
                   ) == 0 or thistflowlist == thispickle['tflowlist'] or (
                       not self.doflow):
                self.__dict__.update(thispickle)
                self.Write()
            else:
                if os.path.isfile(self.PickleFile + '.bak'):
                    print('using backupfile for ' + self.name)
                    self.PickleFile = self.PickleFile + '.bak'
                    self.HumanFile = self.HumanFile + '.bak'
                    self.ExcelFile = self.ExcelFile.replace(
                        '.xlsx', '.bak.xlsx')
                    self.LoadPickle(thismass,
                                    thisalpha=thisalpha,
                                    thistflowlist=thistflowlist,
                                    DefWipe=DefWipe)
                    return
                self.GetFFParms()
                self.GetRedFFParms()
                self.Write()
        else:
            self.GetFFParms()
            self.GetRedFFParms()
            self.Write()