Ignore:
Timestamp:
Apr 13, 2021 1:15:13 PM (2 years ago)
Author:
toby
Message:

CIF multiblock export: set temperature in Phase

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/exports/G2export_CIF.py

    r4879 r4883  
    582582                  G2mth.ValEsd(cellmass/Z,-0.09,True))
    583583
    584 
    585584class ExportCIF(G2IO.ExportBaseclass):
    586585    '''Base class for CIF exports
     
    604603                             'Unicode not valid for CIF')
    605604            return True
     605
     606    def _CellSelectNeeded(self,phasenam):
     607        '''Determines if selection is needed for a T value in a multiblock CIF
     608
     609        :returns: True if the choice of T is ambiguous and a human should
     610          be asked.
     611        '''
     612        phasedict = self.Phases[phasenam] # pointer to current phase info
     613        Tlist = {}  # histname & T values used for cell w/o Hstrain
     614        DijTlist = {} # hId & T values used for cell w/Hstrain
     615        # scan over histograms used in this phase to determine the best
     616        # data collection T value
     617        for h in phasedict['Histograms']:
     618            if not phasedict['Histograms'][h]['Use']: continue
     619            T = self.Histograms[h]['Sample Parameters']['Temperature']
     620            if np.any(abs(np.array(phasedict['Histograms'][h]['HStrain'][0])) > 1e-8):
     621                DijTlist[h] = T
     622            else:
     623                Tlist[h] = T
     624        if len(Tlist) > 0:
     625            T = sum(Tlist.values())/len(Tlist)
     626            if max(Tlist.values()) - T > 1:
     627                return True # temperatures span more than 1 degree, user needs to pick one
     628            return False
     629        elif len(DijTlist) == 1:
     630            return False
     631        elif len(DijTlist) > 1:
     632                # each histogram has different cell lengths, user needs to pick one
     633            return True
     634       
     635    def _CellSelectHist(self,phasenam):
     636        '''Select T value for a phase in a multiblock CIF
     637
     638        :returns: T,h_ranId where T is a temperature (float) or '?' and
     639          h_ranId is the random Id (ranId) for a histogram in the
     640          current phase. This is stored in OverallParms['Controls']['CellHistSelection']
     641        '''
     642        phasedict = self.Phases[phasenam] # pointer to current phase info
     643        Tlist = {}  # histname & T values used for cell w/o Hstrain
     644        DijTlist = {} # hId & T values used for cell w/Hstrain
     645        # scan over histograms used in this phase to determine the best
     646        # data collection T value
     647        for h in phasedict['Histograms']:
     648            if not phasedict['Histograms'][h]['Use']: continue
     649            T = self.Histograms[h]['Sample Parameters']['Temperature']
     650            if np.any(abs(np.array(phasedict['Histograms'][h]['HStrain'][0])) > 1e-8):
     651                DijTlist[h] = T
     652            else:
     653                Tlist[h] = T
     654        if len(Tlist) > 0:
     655            T = sum(Tlist.values())/len(Tlist)
     656            if max(Tlist.values()) - T > 1:
     657                # temperatures span more than 1 degree, user needs to pick one
     658                choices = ["{} (unweighted average)".format(T)]
     659                Ti = [T]
     660                for h in Tlist:
     661                    choices += ["{} (hist {})".format(Tlist[h],h)]
     662                    Ti += [Tlist[h]]                           
     663                msg = 'The cell parameters for phase {} are from\nhistograms with different temperatures.\n\nSelect a T value below'.format(phasenam)
     664                dlg = wx.SingleChoiceDialog(self.G2frame,msg,'Select T',choices)
     665                if dlg.ShowModal() == wx.ID_OK:
     666                    T = Ti[dlg.GetSelection()]
     667                else:
     668                    T = '?'
     669                dlg.Destroy()
     670            return (T,None)
     671        elif len(DijTlist) == 1:
     672            h = list(DijTlist.keys())[0]
     673            h_ranId = self.Histograms[h]['ranId']
     674            return (DijTlist[h],h_ranId)
     675        elif len(DijTlist) > 1:
     676            # each histogram has different cell lengths, user needs to pick one
     677            choices = []
     678            hi = []
     679            for h in DijTlist:
     680                choices += ["{} (hist {})".format(DijTlist[h],h)]
     681                hi += [h]
     682            msg = 'There are {} sets of cell parameters for phase {}\n due to refined Hstrain values.\n\nSelect the histogram to use with the phase form list below'.format(len(DijTlist),phasenam)
     683            dlg = wx.SingleChoiceDialog(self.G2frame,msg,'Select cell',choices)
     684            if dlg.ShowModal() == wx.ID_OK:
     685                h = hi[dlg.GetSelection()]
     686                h_ranId = self.Histograms[h]['ranId']
     687                T = DijTlist[h]
     688            else:
     689                T = '?'
     690                h_ranId = None
     691            dlg.Destroy()
     692            return (T,h_ranId)
     693        else:
     694            print('Unexpected option in _CellSelectHist for',phasenam)
     695            return ('?',None)
    606696
    607697    def _Exporter(self,event=None,phaseOnly=None,histOnly=None,IncludeOnlyHist=None):
     
    11381228                    WriteCIFitem(self.fp, line)
    11391229
    1140         def WritePhaseInfo(phasenam):
     1230        def WritePhaseInfo(phasenam,quick=True,oneblock=True):
    11411231            'Write out the phase information for the selected phase'
    11421232            WriteCIFitem(self.fp, '\n# phase info for '+str(phasenam) + ' follows')
     
    11441234            WriteCIFitem(self.fp, '_pd_phase_name', phasenam)
    11451235            cellList,cellSig = self.GetCell(phasenam)
     1236            if quick:  # leave temperature as unknown
     1237                WriteCIFitem(self.fp,"_cell_measurement_temperature","?")
     1238            elif oneblock:
     1239                pass # temperature should be written when the histogram saved later
     1240            else: # get T set in _SelectPhaseT_CellSelectHist and possibly get new cell params
     1241                T,hRanId = self.CellHistSelection.get(phasedict['ranId'],
     1242                                                          ('?',None))
     1243                try:
     1244                    T = G2mth.ValEsd(T,-1.0)
     1245                except:
     1246                    pass
     1247                WriteCIFitem(self.fp,"_cell_measurement_temperature",T)
     1248                for h in phasedict['Histograms']:
     1249                    if self.Histograms[h]['ranId'] == hRanId:
     1250                        pId = phasedict['pId']
     1251                        hId = self.Histograms[h]['hId']
     1252                        cellList,cellSig = G2strIO.getCellSU(pId,hId,
     1253                                        phasedict['General']['SGData'],
     1254                                        self.parmDict,
     1255                                        self.OverallParms['Covariance'])
     1256                        break
     1257                else:
     1258                    T = '?'
     1259
    11461260            defsigL = 3*[-0.00001] + 3*[-0.001] + [-0.01] # significance to use when no sigma
    11471261            names = ['length_a','length_b','length_c',
     
    17171831                phasedict['General']['DisAglCtls'] = dlg.GetData()
    17181832            dlg.Destroy()
    1719 
     1833           
     1834        def SetCellT(event):
     1835            '''Set the temperature value by selection of a histogram
     1836            '''
     1837            but = event.GetEventObject()
     1838            phasenam = but.phase
     1839            rId =  self.Phases[phasenam]['ranId']
     1840            self.CellHistSelection[rId] = self._CellSelectHist(phasenam)
     1841           
    17201842        def EditCIFDefaults():
    17211843            '''Fills the CIF Defaults window with controls for editing various CIF export
     
    17641886                    but.Bind(wx.EVT_BUTTON,SelectDisAglFlags)     # phase bond/angle ranges
    17651887                    cbox.Add(but,0,wx.ALIGN_LEFT,0)
     1888                if self._CellSelectNeeded(phasenam):
     1889                    but = wx.Button(cpnl, wx.ID_ANY,'Select cell temperature')
     1890                    cbox.Add(but,0,wx.ALIGN_LEFT,0)
     1891                    cbox.Add((-1,2))
     1892                    but.phase = phasenam  # set a pointer to current phase info
     1893                    but.Bind(wx.EVT_BUTTON,SetCellT)
    17661894                cbox.Add((-1,2))
    17671895            for i in sorted(self.powderDict.keys()):
     
    19992127                s += '.'
    20002128        self.CIFname = s
     2129       
     2130        self.InitExport(event)
     2131        # load all of the tree into a set of dicts
     2132        self.loadTree()
    20012133        # load saved CIF author name
    2002         try:
    2003             self.author = self.OverallParms['Controls'].get("Author",'?').strip()
    2004         except KeyError:
    2005             pass
     2134        self.author = self.OverallParms['Controls'].get("Author",'?').strip()
     2135        # initialize dict for Selection of Hist for unit cell reporting
     2136        self.OverallParms['Controls']['CellHistSelection'] = self.OverallParms[
     2137            'Controls'].get('CellHistSelection',{})
     2138        self.CellHistSelection = self.OverallParms['Controls']['CellHistSelection']
    20062139        #=================================================================
    20072140        # write quick CIFs
     
    20332166            #phasenam = self.Phases.keys()[0]
    20342167            WriteCIFitem(self.fp, 'data_'+self.CIFname)
    2035             #print 'phasenam',phasenam
    2036             #phaseblk = self.Phases[phasenam] # pointer to current phase info
    2037             #instnam = instnam.replace(' ','')
    2038             #WriteCIFitem(self.fp, '_pd_block_id',
    2039             #             str(self.CIFdate) + "|" + str(self.CIFname) + "|" +
    2040             #             str(self.shortauthorname) + "|" + instnam + '|' + histname)
    2041             #WriteAudit()
    2042             #writeCIFtemplate(self.OverallParms['Controls'],'publ') # overall (publication) template
    2043             #WriteOverall()
    2044             #writeCIFtemplate(self.Phases[phasenam]['General'],'phase',phasenam) # write phase template
    2045             # report the phase info
    2046             #WritePhaseInfo(phasenam,hist)
    2047             # preferred orientation
    2048             #SH = FormatSH(phasenam)
    2049             #MD = FormatHAPpo(phasenam)
    2050             #if SH and MD:
    2051             #    WriteCIFitem(self.fp, '_pd_proc_ls_pref_orient_corr', SH + '\n' + MD)
    2052             #elif SH or MD:
    2053             #    WriteCIFitem(self.fp, '_pd_proc_ls_pref_orient_corr', SH + MD)
    2054             #else:
    2055             #    WriteCIFitem(self.fp, '_pd_proc_ls_pref_orient_corr', 'none')
    2056             # report profile, since one-block: include both histogram and phase info
    2057             #WriteCIFitem(self.fp, '_pd_proc_ls_profile_function',
    2058             #    FormatInstProfile(histblk["Instrument Parameters"],histblk['hId'])
    2059             #        +'\n'+FormatPhaseProfile(phasenam))
    20602168            if hist.startswith("PWDR"):
    20612169                WritePowderData(hist)
    20622170            elif hist.startswith("HKLF"):
    20632171                WriteSingleXtalData(hist)
    2064             #writeCIFtemplate(histblk,'powder',histblk['InstrName']) # write powder template
    2065             #self.CloseFile()
    20662172            return
    2067         #elif IncludeOnlyHist is not None: # truncate histogram list to only selected (for sequential export)
    2068         #    self.Histograms = {IncludeOnlyHist:self.Histograms[IncludeOnlyHist]}
    2069 
    20702173        #===============================================================================
    20712174        # the export process for a full CIF starts here
    20722175        #===============================================================================
    2073         self.InitExport(event)
    2074         # load all of the tree into a set of dicts
    2075         self.loadTree()
    20762176        # create a dict with refined values and their uncertainties
    20772177        self.loadParmDict()
     
    21492249                    return
    21502250                dlg.Destroy()
    2151             # scan over histograms used in this phase for
    2152             #pId = self.Phases[phasenam]['pId']
    2153             #for h in phasedict['Histograms']:
    2154             #    if not phasedict['Histograms'][h]['Use']: continue
    2155             #    hId = self.Histograms[h]['hId']
    2156             #    T = self.Histograms[h]['Sample Parameters']['Temperature']
    2157                
     2251                   
    21582252        # check if temperature values & pressure are defaulted
    21592253        default = 0
     
    21952289        if not self.author:
    21962290            self.author = self.OverallParms['Controls'].get("Author",'?').strip()
    2197             self.shortauthorname = self.author.replace(',','').replace(' ','')[:20]
    21982291        if not self.author:
    21992292            if not EditAuthor(): return
    22002293        self.ValidateAscii([('Author name',self.author),]) # check for ASCII strings where needed, warn on problems
     2294        self.shortauthorname = self.author.replace(',','').replace(' ','')[:20]
    22012295        self.cifdefs = wx.Dialog(
    22022296            self.G2frame,
     
    22462340            writeCIFtemplate(self.Phases[phasenam]['General'],'phase',phasenam) # write phase template
    22472341            # report the phase info
    2248             WritePhaseInfo(phasenam)
     2342            WritePhaseInfo(phasenam,False)
    22492343            if hist.startswith("PWDR"):  # this is invoked for single-block CIFs
    22502344                # preferred orientation
     
    22712365        else:
    22722366            #=== multiblock: multiple phases and/or histograms ====================
     2367            for phasenam in sorted(self.Phases.keys()):
     2368                rId = phasedict['ranId']
     2369                if rId in self.CellHistSelection: continue
     2370                self.CellHistSelection[rId] = self._CellSelectHist(phasenam)
    22732371            nsteps = 1 + len(self.Phases) + len(self.powderDict) + len(self.xtalDict)
    22742372            dlg = wx.ProgressDialog('CIF progress','starting',nsteps,parent=self.G2frame)
    2275 #                Size = dlg.GetSize()
    2276 #                Size = (int(Size[0]*3),Size[1]) # increase size along x
    2277 #                dlg.SetSize(Size)
    22782373            dlg.CenterOnParent()
    22792374
     
    23442439                # report the phase
    23452440                writeCIFtemplate(self.Phases[phasenam]['General'],'phase',phasenam) # write phase template
    2346                 WritePhaseInfo(phasenam)
     2441                WritePhaseInfo(phasenam,False,False)
    23472442                # preferred orientation
    23482443                if self.ifPWDR:
Note: See TracChangeset for help on using the changeset viewer.