Exemple #1
0
    def __init__(self, ionStr,  temperature, abundance=0, abundanceName=0, em=0, verbose=0):
        nameDict = util.convertName(ionStr)
        self.Z = nameDict['Z']
        self.Ion = nameDict['Ion']
        self.IonStr = ionStr
        self.Dielectronic = 0
        self.Defaults = chdata.Defaults
        self.AbundanceName = self.Defaults['abundfile']
        self.IoneqName = self.Defaults['ioneqfile']
        #
        #  ip in eV, reading Ip of next lower level, needed for freeBound

        if self.Ion == 1:
            if verbose:
                print(' for %s this is the neutral ions an does not produce a continuum'%(ionStr))
            return 
        #  the Ip is only relevant to the free-free methods
#        self.Ip = ip[self.Z-1, self.Ion-1]
        self.Ipr = ip[self.Z-1, self.Ion-2]
        #
        if type(temperature) == float and temperature > 0.:
            self.Temperature = np.asarray(temperature,'float64')
        elif type(temperature) == list or type(temperature) == tuple or type(temperature) == np.ndarray:
            temperature = np.asarray(temperature, 'float64')
            self.Temperature = temperature
        #
        if abundance:
            self.Abundance = abundance
        elif abundanceName:
            if abundanceName in sorted(chdata.Abundance.keys()):
                self.AbundanceName = abundanceName
                self.Abundance = chdata.Abundance[self.AbundanceName]['abundance'][self.Z-1]
            else:
                abundChoices = sorted(chdata.Abundance.keys())
#                for one in wvl[topLines]:
#                    wvlChoices.append('%12.3f'%(one))
                abundChoice = chgui.gui.selectorDialog(abundChoices,label='Select Abundance name')
                abundChoice_idx = abundChoice.selectedIndex
                self.AbundanceName = abundChoices[abundChoice_idx[0]]
                abundanceName = self.AbundanceName
                print(' Abundance chosen:  %s '%(self.AbundanceName))
                self.Abundance = chdata.Abundance[self.AbundanceName]['abundance'][self.Z-1]
        else:
            self.AbundanceName = self.Defaults['abundfile']
            self.Abundance = chdata.Abundance[self.AbundanceName]['abundance'][self.Z-1]
        #
        self.ioneqOne()
        #
        if type(em) == int and em == 0:
            em = np.ones_like(self.Temperature, 'float64')
            self.Em = em
        elif type(em) == float and em > 0.:
            em = np.ones_like(self.Temperature, 'float64')*em        
            self.Em = em
        elif type(em) == list or type(em) == tuple or type(em) == np.ndarray:
            em = np.asarray(em, 'float64')
            self.Em = em
Exemple #2
0
    def __init__(self, ionStr,  temperature=None,  density=None):
        nameDict = util.convertName(ionStr)
        self.Z = nameDict['Z']
        self.Ion = nameDict['Ion']
        self.IonStr = ionStr
        self.Dielectronic = 0
        self.Defaults = chdata.Defaults
        self.AbundanceName = self.Defaults['abundfile']
        self.IoneqName = self.Defaults['ioneqfile']
        #
        #  ip in eV, reading Ip of next lower level, needed for freeBound

        if self.Ion > 1:
            self.Ip=ip[self.Z-1, self.Ion-2]
        else:
            print ' in continuum, trying to use the neutral ion'
            return
        #
        if type(temperature) != types.NoneType:
            self.Temperature = np.array(temperature,'float64')
        #
        if type(density) != types.NoneType:
            self.Density = np.asarray(density,'float64')
Exemple #3
0
 def ionGate(self,
             elementList=0,
             ionList=0,
             minAbund=0,
             doContinuum=1,
             doWvlTest=1,
             verbose=0):
     '''
     creates a list of ions for free-free, free-bound, and line intensity calculations
     if doing the radiative losses, accept all wavelength -> doWvlTest=0
     '''
     #
     masterlist = chdata.MasterList
     abundAll = self.AbundAll
     #
     nonzed = abundAll > 0.
     minAbundAll = abundAll[nonzed].min()
     if minAbund:
         if minAbund < minAbundAll:
             minAbund = minAbundAll
     ionInfo = chio.masterListInfo()
     #
     if hasattr(self, 'Wavelength'):
         wvlRange = [self.Wavelength.min(), self.Wavelength.max()]
     elif hasattr(self, 'WvlRange'):
         wvlRange = self.WvlRange
     else:
         print(' need a wavelength range in ionGate ')
     #
     temperature = self.Temperature
     #
     # use the ionList but make sure the ions are in the database
     self.Todo = {}
     #
     if minAbund:
         if doContinuum:
             for iz in range(1, 31):
                 abundance = chdata.Abundance[
                     self.AbundanceName]['abundance'][iz - 1]
                 if abundance >= minAbund:
                     if verbose:
                         print(' %5i %5s abundance = %10.2e ' %
                               (iz, const.El[iz - 1], abundance))
                     #
                     for ionstage in range(1, iz + 2):
                         ionS = util.zion2name(iz, ionstage)
                         masterListTest = ionS in masterlist
                         masterListInfoTest = ionS in sorted(ionInfo.keys())
                         if masterListTest or masterListInfoTest:
                             if doWvlTest:
                                 wvlTestMin = wvlRange[0] <= ionInfo[ionS][
                                     'wmax']
                                 wvlTestMax = wvlRange[1] >= ionInfo[ionS][
                                     'wmin']
                             else:
                                 wvlTestMin = 1
                                 wvlTestMax = 1
                             ioneqTest = (temperature.max() >=
                                          ionInfo[ionS]['tmin']) and (
                                              temperature.min() <=
                                              ionInfo[ionS]['tmax'])
                         # construct similar test for the dielectronic files
                         ionstageTest = ionstage > 1
                         if ionstageTest and ioneqTest and doContinuum:
                             # ionS is the target ion, cannot be the neutral for the continuum
                             if verbose:
                                 print(
                                     ' setting up continuum calculation for %s  '
                                     % (ionS))
                             if ionS in sorted(self.Todo.keys()):
                                 self.Todo[ionS] += '_ff_fb'
                             else:
                                 self.Todo[ionS] = 'ff_fb'
                             if verbose:
                                 print(' for ion %s do : %s' %
                                       (ionS, self.Todo[ionS]))
     #
     if elementList:
         for i, one in enumerate(elementList):
             elementList[i] = one.lower()
         for one in masterlist:
             stuff = util.convertName(one)
             bare = stuff['Z'] == stuff['Ion']
             if stuff['Element'] in elementList:
                 self.Todo[one] = 'line'
                 if doContinuum and not stuff['Dielectronic']:
                     self.Todo[one] += '_ff'
                     if not bare:
                         self.Todo[one] += '_fb'
     if ionList:
         for one in ionList:
             stuff = util.convertName(one)
             bare = stuff['Z'] == stuff['Ion']
             if masterlist.count(one):
                 self.Todo[one] = 'line'
                 if doContinuum and not stuff['Dielectronic']:
                     self.Todo[one] += '_ff'
                     if not bare:
                         self.Todo[one] += '_fb'
             else:
                 if verbose:
                     pstring = ' %s not in CHIANTI database' % (one)
                     print(pstring)
     #
     #
     #
     if minAbund:
         for iz in range(1, 31):
             abundance = chdata.Abundance[self.AbundanceName]['abundance'][
                 iz - 1]
             if abundance >= minAbund:
                 if verbose:
                     print(' %5i %5s abundance = %10.2e ' %
                           (iz, const.El[iz - 1], abundance))
                 #
                 for ionstage in range(1, iz + 2):
                     ionS = util.zion2name(iz, ionstage)
                     masterListTest = ionS in masterlist
                     masterListInfoTest = ionS in sorted(ionInfo.keys())
                     if masterListTest or masterListInfoTest:
                         if masterListTest or masterListInfoTest:
                             if doWvlTest:
                                 wvlTestMin = wvlRange[0] <= ionInfo[ionS][
                                     'wmax']
                                 wvlTestMax = wvlRange[1] >= ionInfo[ionS][
                                     'wmin']
                             else:
                                 wvlTestMin = 1
                                 wvlTestMax = 1
                         ioneqTest = (
                             temperature.max() >= ionInfo[ionS]['tmin']
                         ) and (temperature.min() <= ionInfo[ionS]['tmax'])
                     # construct similar test for the dielectronic files
                     ionSd = util.zion2name(iz, ionstage, dielectronic=1)
                     masterListTestD = ionSd in masterlist
                     masterListInfoTestD = ionSd in sorted(ionInfo.keys())
                     if masterListTestD or masterListInfoTestD:
                         if doWvlTest:
                             wvlTestMinD = wvlRange[0] <= ionInfo[ionSd][
                                 'wmax']
                             wvlTestMaxD = wvlRange[1] >= ionInfo[ionSd][
                                 'wmin']
                         else:
                             wvlTestMinD = 1
                             wvlTestMaxD = 1
                         ioneqTestD = (
                             temperature.max() >= ionInfo[ionSd]['tmin']
                         ) and (temperature.min() <= ionInfo[ionSd]['tmax'])
                         #
                     if masterListTest and wvlTestMin and wvlTestMax and ioneqTest:
                         #if verbose:
                         #print(' setting up spectrum calculation for  %s'%(ionS))
                         if ionS in sorted(self.Todo.keys()):
                             self.Todo[ionS] += '_line'
                         else:
                             self.Todo[ionS] = 'line'
                     # get dielectronic lines
                         if verbose:
                             print(' for ion %s do : %s' %
                                   (ionS, self.Todo[ionS]))
                     if masterListTestD and wvlTestMinD and wvlTestMaxD and ioneqTestD:
                         #if verbose:
                         #print(' setting up  spectrum calculation for  %s '%(ionSd))
                         if ionSd in sorted(self.Todo.keys()):
                             self.Todo[ionSd] += '_line'
                         else:
                             self.Todo[ionSd] = 'line'
                         if verbose:
                             print(' for ion %s do : %s' %
                                   (ionSd, self.Todo[ionSd]))
     return
Exemple #4
0
    def __init__(self, temperature, eDensity, wavelength, filter=(chfilters.gaussianR, 1000.), label=0, elementList = 0, ionList = 0, minAbund=0, keepIons=0, abundanceName=0,  doContinuum=1, allLines = 1, em =0,  proc=3, verbose = 0,  timeout=0.1):
        #
        t1 = datetime.now()
        # creates Intensity dict from first ion calculated
        setupIntensity = 0
        #
        #masterlist = chdata.MasterList
        # use the ionList but make sure the ions are in the database
        #if elementList:
            #for i,  one in enumerate(elementList):
                #elementList[i] = one.lower()
            #alist = []
            #for one in masterlist:
                #stuff = util.convertName(one)
                #if stuff['Element'] in  elementList:
                    #alist.append(one)
            #masterlist = alist
        #elif ionList:
            #alist=[]
            #for one in ionList:
                #if masterlist.count(one):
                    #alist.append(one)
                #else:
                    #if verbose:
                        #pstring = ' %s not in CHIANTI database'%(one)
                        #print(pstring)
            #masterlist = alist
        self.Defaults = defaults
        #
        masterlist = chdata.MasterList
        self.Defaults = defaults
        self.Temperature = np.asarray(temperature, 'float64')
        nTemp = self.Temperature.size
        self.EDensity = np.asarray(eDensity, 'float64')
        nDen = self.EDensity.size
        nTempDen = max([nTemp, nDen])
        self.NTempDen = nTempDen
        #
        if type(em) == int and em == 0:
            em = np.ones(self.NTempDen, 'float64')
        elif type(em) == float and em > 0.:
            em = np.ones(self.NTempDen, 'float64')*em        
        elif type(em) == list or type(em) == tuple:
            em = np.asarray(em, 'float64')
        self.Em = em
        #
        #
        if self.Em.any() > 0.:
            ylabel = r'erg cm$^{-2}$ s$^{-1}$ sr$^{-1} \AA^{-1}$ $'
        else:
            ylabel = r'erg cm$^{-2}$ s$^{-1}$ sr$^{-1} \AA^{-1}$ ($\int\,$ N$_e\,$N$_H\,$d${\it l}$)$^{-1}$'
        #
        xlabel = 'Wavelength ('+self.Defaults['wavelength'] +')'
        #
        #
        self.AllLines = allLines
        #
        if not abundanceName:
            self.AbundanceName = self.Defaults['abundfile']
        else:
            if abundanceName in chdata.Abundance:
                self.AbundanceName = abundanceName
            else:
                abundChoices = list(chdata.Abundance.keys())
#                for one in wvl[topLines]:
#                    wvlChoices.append('%12.3f'%(one))
                abundChoice = chgui.gui.selectorDialog(abundChoices,label='Select Abundance name')
                abundChoice_idx = abundChoice.selectedIndex
                self.AbundanceName = abundChoices[abundChoice_idx[0]]
                abundanceName = self.AbundanceName
                print(' Abundance chosen:  %s '%(self.AbundanceName))
        #
        abundAll = chdata.Abundance[self.AbundanceName]['abundance']
        self.AbundAll = abundAll
        #
#        nonzed = abundAll > 0.
#        minAbundAll = abundAll[nonzed].min()
#        # if minAbund is even set
#        if minAbund:
#            if minAbund < minAbundAll:
#                minAbund = minAbundAll
        #ionInfo = chio.masterListInfo()
        wavelength = np.asarray(wavelength)
        nWvl = wavelength.size
        self.Wavelength = wavelength
#        wvlRange = [wavelength.min(), wavelength.max()]
        #
        proc = min([proc, mp.cpu_count()])
        #
        freeFree = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        freeBound = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        twoPhoton = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        lineSpectrum = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        #
        #  free-free multiprocessing setup
        ffWorkerQ = mp.Queue()
        ffDoneQ = mp.Queue()
        #
        #  free-bound multiprocessing setup
        #
        fbWorkerQ = mp.Queue()
        fbDoneQ = mp.Queue()
        #
        #  ion multiprocessing setup
        ionWorkerQ = mp.Queue()
        ionDoneQ = mp.Queue()
        #
        self.IonsCalculated = []
        if keepIons:
            self.IonInstances = {}
        self.Finished = []
        #
        
#        self.Todo = []
        self.ionGate(elementList = elementList, ionList = ionList, minAbund=minAbund, doContinuum=doContinuum, verbose = verbose)
        #
        for akey in sorted(self.Todo.keys()):
            zStuff = util.convertName(akey)
            Z = zStuff['Z']
            abundance = chdata.Abundance[self.AbundanceName]['abundance'][Z - 1]
            if verbose:
                print(' %5i %5s abundance = %10.2e '%(Z, const.El[Z-1],  abundance))
            if verbose:
                print(' doing ion %s for the following processes %s'%(akey, self.Todo[akey]))
            if 'ff' in self.Todo[akey]:
#                if verbose:
#                    print(' doing ff')
                ffWorkerQ.put((akey, temperature, wavelength, abundance, em))
#                allInpt.append([akey, 'ff', temperature, wavelength, abundance])
            if 'fb' in self.Todo[akey]:
#                if verbose:
#                    print(' doing fb')
                fbWorkerQ.put((akey, temperature, wavelength, abundance, em))
#                allInpt.append([akey, 'fb', temperature, wavelength, abundance])
            if 'line' in self.Todo[akey]:
#                if verbose:
#                    print(' doing line')
                ionWorkerQ.put((akey, temperature, eDensity, wavelength, filter, allLines, abundance, em, doContinuum))
#                allInpt.append([akey, 'line', temperature, eDensity, wavelength, filter, allLines, abundance, em, doContinuum])


        #
        ffWorkerQSize = ffWorkerQ.qsize()
        fbWorkerQSize = fbWorkerQ.qsize()
        ionWorkerQSize = ionWorkerQ.qsize()
        if doContinuum:
            ffProcesses = []
            for i in range(proc):
                p = mp.Process(target=mputil.doFfQ, args=(ffWorkerQ, ffDoneQ))
                p.start()
                ffProcesses.append(p)
    #       timeout is not necessary
            for p in ffProcesses:
                if p.is_alive():
                    p.join(timeout=timeout)
#            for i in range(proc):
#                ffProcesses.append('STOP')
            #
            for iff in range(ffWorkerQSize):
                thisFreeFree = ffDoneQ.get()
#                freeFree += thisFreeFree['rate']
#                if nTempDen ==1:
#                    freeFree += thisFreeFree['rate']*em[0]
#                else:
#                    for iTempDen in range(nTempDen):
#                        freeFree[iTempDen] += thisFreeFree['rate'][iTempDen]*em[iTempDen]
                freeFree += thisFreeFree['rate']
            for p in ffProcesses:
                if not isinstance(p, str):
                    p.terminate()
        #
            fbProcesses = []
            for i in range(proc):
                p = mp.Process(target=mputil.doFbQ, args=(fbWorkerQ, fbDoneQ))
                p.start()
                fbProcesses.append(p)
    #       timeout is not necessary
            for p in fbProcesses:
                if p.is_alive():
                    p.join(timeout=timeout)
#            for i in range(proc):
#                fbProcesses.append('STOP')
            #
            for ifb in range(fbWorkerQSize):
                thisFreeBound = fbDoneQ.get()
                if 'rate' in sorted(thisFreeBound.keys()):
#                    freeBound += thisFreeBound['rate']
#                    if nTempDen ==1:
#                        freeBound += thisFreeBound['rate']*em[0]
#                    else:
#                        for iTempDen in range(nTempDen):
#                            freeBound[iTempDen] += thisFreeBound['rate'][iTempDen]*em[iTempDen]
                    freeBound += thisFreeBound['rate']
            for p in fbProcesses:
                if not isinstance(p, str):
                    p.terminate()
        #
        ionProcesses = []
        if ionWorkerQSize < proc:
            proc = ionWorkerQSize
        for i in range(proc):
            p = mp.Process(target=mputil.doIonQ, args=(ionWorkerQ, ionDoneQ))
            p.start()
            ionProcesses.append(p)
#            ionWorkerQ.put('STOP')
#       timeout is not necessary
        for p in ionProcesses:
#            print' process is alive:  ', p.is_alive()
            if p.is_alive():
#                p.join()
                p.join(timeout=timeout)
#        for i in range(proc):
#            ionProcesses.append('STOP')
        #
        for ijk in range(ionWorkerQSize):
            out = ionDoneQ.get()
            ions = out[0]
            if verbose:
                print(' collecting calculation for %s'%(ions))
            thisIon = out[1]
#            thisSpectrum = thisIon.Spectrum
            thisIntensity = thisIon.Intensity
            if not 'errorMessage' in sorted(thisIntensity.keys()):
                self.Finished.append(ions)
                if keepIons:
                    self.IonInstances[ions] = copy.deepcopy(thisIon)
                if setupIntensity:
                    for akey in sorted(self.Intensity.keys()):
                        self.Intensity[akey] = np.hstack((copy.copy(self.Intensity[akey]), thisIntensity[akey]))
                else:
                    setupIntensity = 1
                    self.Intensity  = thisIntensity
                #
                if not 'errorMessage' in sorted(thisIon.Spectrum.keys()):
                    lineSpectrum += thisIon.Spectrum['intensity']
#                if nTempDen == 1:
#                    lineSpectrum += thisSpectrum['intensity']
#                else:
#                    for iTempDen in range(nTempDen):
#                        lineSpectrum[iTempDen] += thisSpectrum['intensity'][iTempDen]
               # check for two-photon emission
                if len(out) == 3:
                    tp = out[2]
                    twoPhoton += tp['rate']
#                    if nTempDen == 1:
#                        twoPhoton += tp['rate']*em[0]
#                    else:
#                        for iTempDen in range(nTempDen):
#                            twoPhoton[iTempDen] += tp['rate'][iTempDen]*em[iTempDen]
            else:
                if 'errorMessage' in sorted(thisIntensity.keys()):
                    print(thisIntensity['errorMessage'])
        #
        for p in ionProcesses:
            if not isinstance(p, str):
                p.terminate()
        #
        #
        #
        self.FreeFree = {'wavelength':wavelength, 'intensity':freeFree.squeeze()}
        self.FreeBound = {'wavelength':wavelength, 'intensity':freeBound.squeeze()}
        self.LineSpectrum = {'wavelength':wavelength, 'intensity':lineSpectrum.squeeze()}
        self.TwoPhoton = {'wavelength':wavelength, 'intensity':twoPhoton.squeeze()}
        #
        total = freeFree + freeBound + lineSpectrum + twoPhoton
        #
        t2 = datetime.now()
        dt=t2-t1
        print(' elapsed seconds = %12.3f'%(dt.seconds))
        #
        if nTempDen == 1:
            integrated = total
        else:
            integrated = total.sum(axis=0)
        #
        if type(label) == type(''):
            if hasattr(self, 'Spectrum'):
                self.Spectrum[label] = {'wavelength':wavelength, 'intensity':total.squeeze(), 'filter':filter[0].__name__,   'width':filter[1], 'integrated':integrated, 'ions':self.IonsCalculated, 'em':em,
                'ions':self.IonsCalculated, 'Abundance':self.AbundanceName, 'xlabel':xlabel, 'ylabel':ylabel}
            else:
                self.Spectrum = {label:{'wavelength':wavelength, 'intensity':total.squeeze(), 'filter':filter[0].__name__,   'width':filter[1], 'integrated':integrated, 'ions':self.IonsCalculated, 'em':em,
                'ions':self.IonsCalculated, 'Abundance':self.AbundanceName, 'xlabel':xlabel, 'ylabel':ylabel}}
        else:
            self.Spectrum ={'wavelength':wavelength, 'intensity':total.squeeze(), 'filter':filter[0].__name__,   'width':filter[1], 'integrated':integrated, 'ions':self.IonsCalculated,
            'em':em, 'Abundance':self.AbundanceName, 'xlabel':xlabel, 'ylabel':ylabel}
Exemple #5
0
    def __init__(self,
                 temperature,
                 eDensity,
                 wavelength,
                 filter=(chfilters.gaussianR, 1000.),
                 label=0,
                 elementList=0,
                 ionList=0,
                 minAbund=0,
                 keepIons=0,
                 abundanceName=0,
                 doContinuum=1,
                 allLines=1,
                 em=0,
                 proc=3,
                 verbose=0,
                 timeout=0.1):
        #
        t1 = datetime.now()
        # creates Intensity dict from first ion calculated
        setupIntensity = 0
        #
        #masterlist = chdata.MasterList
        # use the ionList but make sure the ions are in the database
        #if elementList:
        #for i,  one in enumerate(elementList):
        #elementList[i] = one.lower()
        #alist = []
        #for one in masterlist:
        #stuff = util.convertName(one)
        #if stuff['Element'] in  elementList:
        #alist.append(one)
        #masterlist = alist
        #elif ionList:
        #alist=[]
        #for one in ionList:
        #if masterlist.count(one):
        #alist.append(one)
        #else:
        #if verbose:
        #pstring = ' %s not in CHIANTI database'%(one)
        #print(pstring)
        #masterlist = alist
        self.Defaults = defaults
        #
        masterlist = chdata.MasterList
        self.Defaults = defaults
        self.Temperature = np.asarray(temperature, 'float64')
        nTemp = self.Temperature.size
        self.EDensity = np.asarray(eDensity, 'float64')
        nDen = self.EDensity.size
        nTempDen = max([nTemp, nDen])
        self.NTempDen = nTempDen
        #
        if type(em) == int and em == 0:
            em = np.ones(self.NTempDen, 'float64')
        elif type(em) == float and em > 0.:
            em = np.ones(self.NTempDen, 'float64') * em
        elif type(em) == list or type(em) == tuple:
            em = np.asarray(em, 'float64')
        self.Em = em
        #
        #
        if self.Em.any() > 0.:
            ylabel = r'erg cm$^{-2}$ s$^{-1}$ sr$^{-1} \AA^{-1}$ $'
        else:
            ylabel = r'erg cm$^{-2}$ s$^{-1}$ sr$^{-1} \AA^{-1}$ ($\int\,$ N$_e\,$N$_H\,$d${\it l}$)$^{-1}$'
        #
        xlabel = 'Wavelength (' + self.Defaults['wavelength'] + ')'
        #
        #
        self.AllLines = allLines
        #
        if not abundanceName:
            self.AbundanceName = self.Defaults['abundfile']
        else:
            if abundanceName in chdata.Abundance:
                self.AbundanceName = abundanceName
            else:
                abundChoices = list(chdata.Abundance.keys())
                #                for one in wvl[topLines]:
                #                    wvlChoices.append('%12.3f'%(one))
                abundChoice = chgui.gui.selectorDialog(
                    abundChoices, label='Select Abundance name')
                abundChoice_idx = abundChoice.selectedIndex
                self.AbundanceName = abundChoices[abundChoice_idx[0]]
                abundanceName = self.AbundanceName
                print(' Abundance chosen:  %s ' % (self.AbundanceName))
        #
        abundAll = chdata.Abundance[self.AbundanceName]['abundance']
        self.AbundAll = abundAll
        #
        #        nonzed = abundAll > 0.
        #        minAbundAll = abundAll[nonzed].min()
        #        # if minAbund is even set
        #        if minAbund:
        #            if minAbund < minAbundAll:
        #                minAbund = minAbundAll
        #ionInfo = chio.masterListInfo()
        wavelength = np.asarray(wavelength)
        nWvl = wavelength.size
        self.Wavelength = wavelength
        #        wvlRange = [wavelength.min(), wavelength.max()]
        #
        proc = min([proc, mp.cpu_count()])
        #
        freeFree = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        freeBound = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        twoPhoton = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        lineSpectrum = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        #
        #  free-free multiprocessing setup
        ffWorkerQ = mp.Queue()
        ffDoneQ = mp.Queue()
        #
        #  free-bound multiprocessing setup
        #
        fbWorkerQ = mp.Queue()
        fbDoneQ = mp.Queue()
        #
        #  ion multiprocessing setup
        ionWorkerQ = mp.Queue()
        ionDoneQ = mp.Queue()
        #
        self.IonsCalculated = []
        if keepIons:
            self.IonInstances = {}
        self.Finished = []
        #

        #        self.Todo = []
        self.ionGate(elementList=elementList,
                     ionList=ionList,
                     minAbund=minAbund,
                     doContinuum=doContinuum,
                     verbose=verbose)
        #
        for akey in sorted(self.Todo.keys()):
            zStuff = util.convertName(akey)
            Z = zStuff['Z']
            abundance = chdata.Abundance[self.AbundanceName]['abundance'][Z -
                                                                          1]
            if verbose:
                print(' %5i %5s abundance = %10.2e ' %
                      (Z, const.El[Z - 1], abundance))
            if verbose:
                print(' doing ion %s for the following processes %s' %
                      (akey, self.Todo[akey]))
            if 'ff' in self.Todo[akey]:
                #                if verbose:
                #                    print(' doing ff')
                ffWorkerQ.put((akey, temperature, wavelength, abundance, em))
#                allInpt.append([akey, 'ff', temperature, wavelength, abundance])
            if 'fb' in self.Todo[akey]:
                #                if verbose:
                #                    print(' doing fb')
                fbWorkerQ.put((akey, temperature, wavelength, abundance, em))
#                allInpt.append([akey, 'fb', temperature, wavelength, abundance])
            if 'line' in self.Todo[akey]:
                #                if verbose:
                #                    print(' doing line')
                ionWorkerQ.put((akey, temperature, eDensity, wavelength,
                                filter, allLines, abundance, em, doContinuum))
#                allInpt.append([akey, 'line', temperature, eDensity, wavelength, filter, allLines, abundance, em, doContinuum])

#
        ffWorkerQSize = ffWorkerQ.qsize()
        fbWorkerQSize = fbWorkerQ.qsize()
        ionWorkerQSize = ionWorkerQ.qsize()
        if doContinuum:
            ffProcesses = []
            for i in range(proc):
                p = mp.Process(target=mputil.doFfQ, args=(ffWorkerQ, ffDoneQ))
                p.start()
                ffProcesses.append(p)
    #       timeout is not necessary
            for p in ffProcesses:
                if p.is_alive():
                    p.join(timeout=timeout)
#            for i in range(proc):
#                ffProcesses.append('STOP')
#
            for iff in range(ffWorkerQSize):
                thisFreeFree = ffDoneQ.get()
                #                freeFree += thisFreeFree['rate']
                #                if nTempDen ==1:
                #                    freeFree += thisFreeFree['rate']*em[0]
                #                else:
                #                    for iTempDen in range(nTempDen):
                #                        freeFree[iTempDen] += thisFreeFree['rate'][iTempDen]*em[iTempDen]
                freeFree += thisFreeFree['rate']
            for p in ffProcesses:
                if not isinstance(p, str):
                    p.terminate()
        #
            fbProcesses = []
            for i in range(proc):
                p = mp.Process(target=mputil.doFbQ, args=(fbWorkerQ, fbDoneQ))
                p.start()
                fbProcesses.append(p)
    #       timeout is not necessary
            for p in fbProcesses:
                if p.is_alive():
                    p.join(timeout=timeout)
#            for i in range(proc):
#                fbProcesses.append('STOP')
#
            for ifb in range(fbWorkerQSize):
                thisFreeBound = fbDoneQ.get()
                if 'rate' in sorted(thisFreeBound.keys()):
                    #                    freeBound += thisFreeBound['rate']
                    #                    if nTempDen ==1:
                    #                        freeBound += thisFreeBound['rate']*em[0]
                    #                    else:
                    #                        for iTempDen in range(nTempDen):
                    #                            freeBound[iTempDen] += thisFreeBound['rate'][iTempDen]*em[iTempDen]
                    freeBound += thisFreeBound['rate']
            for p in fbProcesses:
                if not isinstance(p, str):
                    p.terminate()
        #
        ionProcesses = []
        if ionWorkerQSize < proc:
            proc = ionWorkerQSize
        for i in range(proc):
            p = mp.Process(target=mputil.doIonQ, args=(ionWorkerQ, ionDoneQ))
            p.start()
            ionProcesses.append(p)
#            ionWorkerQ.put('STOP')
#       timeout is not necessary
        for p in ionProcesses:
            #            print' process is alive:  ', p.is_alive()
            if p.is_alive():
                #                p.join()
                p.join(timeout=timeout)
#        for i in range(proc):
#            ionProcesses.append('STOP')
#
        for ijk in range(ionWorkerQSize):
            out = ionDoneQ.get()
            ions = out[0]
            if verbose:
                print(' collecting calculation for %s' % (ions))
            thisIon = out[1]
            #            thisSpectrum = thisIon.Spectrum
            thisIntensity = thisIon.Intensity
            if not 'errorMessage' in sorted(thisIntensity.keys()):
                self.Finished.append(ions)
                if keepIons:
                    self.IonInstances[ions] = copy.deepcopy(thisIon)
                if setupIntensity:
                    for akey in sorted(self.Intensity.keys()):
                        self.Intensity[akey] = np.hstack(
                            (copy.copy(self.Intensity[akey]),
                             thisIntensity[akey]))
                else:
                    setupIntensity = 1
                    self.Intensity = thisIntensity
                #
                if not 'errorMessage' in sorted(thisIon.Spectrum.keys()):
                    lineSpectrum += thisIon.Spectrum['intensity']
#                if nTempDen == 1:
#                    lineSpectrum += thisSpectrum['intensity']
#                else:
#                    for iTempDen in range(nTempDen):
#                        lineSpectrum[iTempDen] += thisSpectrum['intensity'][iTempDen]
# check for two-photon emission
                if len(out) == 3:
                    tp = out[2]
                    twoPhoton += tp['rate']
#                    if nTempDen == 1:
#                        twoPhoton += tp['rate']*em[0]
#                    else:
#                        for iTempDen in range(nTempDen):
#                            twoPhoton[iTempDen] += tp['rate'][iTempDen]*em[iTempDen]
            else:
                if 'errorMessage' in sorted(thisIntensity.keys()):
                    print(thisIntensity['errorMessage'])
        #
        for p in ionProcesses:
            if not isinstance(p, str):
                p.terminate()
        #
        #
        #
        self.FreeFree = {
            'wavelength': wavelength,
            'intensity': freeFree.squeeze()
        }
        self.FreeBound = {
            'wavelength': wavelength,
            'intensity': freeBound.squeeze()
        }
        self.LineSpectrum = {
            'wavelength': wavelength,
            'intensity': lineSpectrum.squeeze()
        }
        self.TwoPhoton = {
            'wavelength': wavelength,
            'intensity': twoPhoton.squeeze()
        }
        #
        total = freeFree + freeBound + lineSpectrum + twoPhoton
        #
        t2 = datetime.now()
        dt = t2 - t1
        print(' elapsed seconds = %12.3f' % (dt.seconds))
        #
        if nTempDen == 1:
            integrated = total
        else:
            integrated = total.sum(axis=0)
        #
        if type(label) == type(''):
            if hasattr(self, 'Spectrum'):
                self.Spectrum[label] = {
                    'wavelength': wavelength,
                    'intensity': total.squeeze(),
                    'filter': filter[0].__name__,
                    'width': filter[1],
                    'integrated': integrated,
                    'ions': self.IonsCalculated,
                    'em': em,
                    'ions': self.IonsCalculated,
                    'Abundance': self.AbundanceName,
                    'xlabel': xlabel,
                    'ylabel': ylabel
                }
            else:
                self.Spectrum = {
                    label: {
                        'wavelength': wavelength,
                        'intensity': total.squeeze(),
                        'filter': filter[0].__name__,
                        'width': filter[1],
                        'integrated': integrated,
                        'ions': self.IonsCalculated,
                        'em': em,
                        'ions': self.IonsCalculated,
                        'Abundance': self.AbundanceName,
                        'xlabel': xlabel,
                        'ylabel': ylabel
                    }
                }
        else:
            self.Spectrum = {
                'wavelength': wavelength,
                'intensity': total.squeeze(),
                'filter': filter[0].__name__,
                'width': filter[1],
                'integrated': integrated,
                'ions': self.IonsCalculated,
                'em': em,
                'Abundance': self.AbundanceName,
                'xlabel': xlabel,
                'ylabel': ylabel
            }
Exemple #6
0
    def __init__(self, temperature, density, wavelength, filter=(chfilters.gaussianR, 1000.), elementList = 0, ionList = 0, minAbund=0, doContinuum=1, em = None,  verbose=0, allLines=1):
        t1 = datetime.now()
        masterlist = chdata.MasterList
        # use the ionList but make sure the ions are in the database
        if elementList:
            for i,  one in enumerate(elementList):
                elementList[i] = one.lower()
            alist = []
            for one in masterlist:
                stuff = util.convertName(one)
                if stuff['Element'] in  elementList:
                    alist.append(one)
            masterlist = alist
        elif ionList:
            alist=[]
            for one in ionList:
                if masterlist.count(one):
                    alist.append(one)
                else:
                    if verbose:
                        pstring = ' %s not in CHIANTI database'%(one)
                        print('')
            masterlist = alist
        self.Defaults=defaults
        self.Temperature = np.asarray(temperature, 'float64')
        nTemp = self.Temperature.size
        self.Density = np.asarray(density, 'float64')
        nDen = self.Density.size
        nTempDen = max([nTemp, nDen])
        if type(em) != types.NoneType:
            if type(em) == types.FloatType:
                if nTempDen > 1:
                    em = np.ones_like(self.Temperature)*em
                    nEm = nTempDen
                else:
                    nEm = 1
            else:
                em = np.asarray(em, 'float64')
                nEm = em.size
                if nEm != nTempDen:
                    print ' the emission measure array must be the same size as the temperature/density array'
                    return
        self.AbundanceName = defaults['abundfile']
        self.AbundanceAll = chdata.AbundanceAll
        abundAll = self.AbundanceAll['abundance']
        nonzed = abundAll > 0.
        minAbundAll = abundAll[nonzed].min()
        if minAbund < minAbundAll:
            minAbund = minAbundAll
        self.minAbund = minAbund
        ionInfo = util.masterListInfo()
        wavelength = np.asarray(wavelength)
        nWvl = wavelength.size
        self.Wavelength = wavelength
        wvlRange = [wavelength.min(), wavelength.max()]
        #
        freeFree = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        freeBound = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        twoPhoton = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        lineSpectrum = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        #
        ionsCalculated = []
        #
        for iz in range(31):
            abundance = self.AbundanceAll['abundance'][iz-1]
            if abundance >= minAbund:
                print ' %5i %5s abundance = %10.2e '%(iz, const.El[iz-1],  abundance)
                #
                for ionstage in range(1, iz+2):
                    ionS = util.zion2name(iz, ionstage)
#                   print ' ionS = ', ionS
                    masterListTest = ionS in masterlist
                    masterListInfoTest = ionS in ionInfo.keys()
                    if masterListTest or masterListInfoTest:
                        wvlTestMin = self.Wavelength.min() <= ionInfo[ionS]['wmax']
                        wvlTestMax = self.Wavelength.max() >= ionInfo[ionS]['wmin']
                        ioneqTest = (self.Temperature.max() >= ionInfo[ionS]['tmin']) and (self.Temperature.min() <= ionInfo[ionS]['tmax'])
                    # construct similar test for the dielectronic files
                    ionSd = util.zion2name(iz, ionstage, dielectronic=1)
                    masterListTestD = ionSd in masterlist
                    masterListInfoTestD = ionSd in ionInfo.keys()
                    if masterListTestD or masterListInfoTestD:
                        wvlTestMinD = self.Wavelength.min() <= ionInfo[ionSd]['wmax']
                        wvlTestMaxD = self.Wavelength.max() >= ionInfo[ionSd]['wmin']
                        ioneqTestD = (self.Temperature.max() >= ionInfo[ionSd]['tmin']) and (self.Temperature.min() <=ionInfo[ionSd]['tmax'])
                    ionstageTest = ionstage > 1
                    if ionstageTest and ioneqTest and doContinuum:
                        # ionS is the target ion, cannot be the neutral for the continuum
                        print ' calculating continuum for :  ',  ionS
                        cont = chianti.core.continuum(ionS, temperature)
                        cont.freeFree(wavelength)
    #                   print dir(thisIon)
    #                   print ' wvl = ', thisIon.FreeFree['wvl']
                        if nTempDen ==1:
                            freeFree += cont.FreeFree['rate']
                        else:
                            for iTempDen in range(nTempDen):
                                freeFree[iTempDen] += cont.FreeFree['rate'][iTempDen]
                    #
                        cont.freeBound(wavelength)
                        if 'errorMessage' not in cont.FreeBound.keys():
                            #  an fblvl file exists for this ions
                            if nTempDen == 1:
                                freeBound += cont.FreeBound['rate']
                            else:
                                for iTempDen in range(nTempDen):
                                    freeBound[iTempDen] += cont.FreeBound['rate'][iTempDen]
                    if masterListTest and wvlTestMin and wvlTestMax and ioneqTest:
                        print ' calculating spectrum for  :  ', ionS
                        thisIon = chianti.core.ion(ionS, temperature, density)
                        ionsCalculated.append(ionS)
#                       print ' dir = ', dir(thisIon)
#                        thisIon.emiss(wvlRange = wvlRange, allLines=allLines)
                        thisIon.intensity(wvlRange = wvlRange, allLines=allLines)
                        # check that there are lines in this wavelength range
                        if 'errorMessage' not in  thisIon.Intensity.keys():
                            thisIon.spectrum(wavelength, filter=filter)
#                           intensity = thisIon.Intensity['intensity']
                            if nTempDen == 1:
                                lineSpectrum += thisIon.Spectrum['intensity']
                            else:
                                for iTempDen in range(nTempDen):
                                    lineSpectrum[iTempDen] += thisIon.Spectrum['intensity'][iTempDen]
                        # get 2 photon emission for H and He sequences
                        if (iz - ionstage) in [0, 1]:
                            thisIon.twoPhoton(wavelength)
                            twoPhoton += thisIon.TwoPhoton['rate']
                    # get dielectronic lines
                    if masterListTestD and wvlTestMinD and wvlTestMaxD and ioneqTestD:
                        print ' calculating spectrum for  :  ', ionSd
                        thisIon = chianti.core.ion(ionSd, temperature, density)
                        ionsCalculated.append(ionSd)
#                       print ' dir = ', dir(thisIon)
#                       have to do all lines for the dielectronic satellites
#                        thisIon.emiss(allLines=1)
                        thisIon.intensity(wvlRange = wvlRange, allLines=allLines)
                        # check that there are lines in this wavelength range - probably not redundant
                        if 'errorMessage' not in  thisIon.Intensity.keys():
                            thisIon.spectrum(wavelength, filter=filter)
                            if nTempDen == 1:
                                lineSpectrum += thisIon.Spectrum['intensity']
                            else:
                                for iTempDen in range(nTempDen):
                                    lineSpectrum[iTempDen] += thisIon.Spectrum['intensity'][iTempDen]
        self.FreeFree = {'wavelength':wavelength, 'intensity':freeFree.squeeze()}
        self.FreeBound = {'wavelength':wavelength, 'intensity':freeBound.squeeze()}
        self.LineSpectrum = {'wavelength':wavelength, 'intensity':lineSpectrum.squeeze()}
        self.TwoPhoton = {'wavelength':wavelength, 'intensity':twoPhoton.squeeze()}
        #
        total = freeFree + freeBound + lineSpectrum + twoPhoton
        t2 = datetime.now()
        dt=t2-t1
        print ' elapsed seconds = ', dt.seconds
        if type(em) != types.NoneType:
            if nEm == 1:
                integrated = total*em
            else:
                integrated = np.zeros_like(wavelength)
                for iTempDen in range(nTempDen):
                    integrated += total[iTempDen]*em[iTempDen]
            self.Spectrum ={'wavelength':wavelength, 'intensity':total.squeeze(), 'filter':filter[0].__name__,   'width':filter[1], 'integrated':integrated, 'em':em, 'ions':ionsCalculated}
        else:
            self.Spectrum ={'wavelength':wavelength, 'intensity':total.squeeze(), 'filter':filter[0].__name__,   'width':filter[1], 'ions':ionsCalculated}
Exemple #7
0
    def __init__(self, temperature, eDensity, wavelength, filter=(chfilters.gaussianR, 1000.), label=0, elementList = 0, ionList = 0, minAbund=0, doContinuum=1, em=0, keepIons=0,  abundanceName=0, verbose=0, allLines=1):
        #
        t1 = datetime.now()
        # creates Intensity dict from first ion calculated
        setupIntensity = 0
        #
        masterlist = chdata.MasterList
        # use the ionList but make sure the ions are in the database
        #if elementList:
            #for i,  one in enumerate(elementList):
                #elementList[i] = one.lower()
            #alist = []
            #for one in masterlist:
                #stuff = util.convertName(one)
                #if stuff['Element'] in  elementList:
                    #alist.append(one)
            #masterlist = alist
        #elif ionList:
            #alist=[]
            #for one in ionList:
                #if masterlist.count(one):
                    #alist.append(one)
                #else:
                    #if verbose:
                        #pstring = ' %s not in CHIANTI database'%(one)
                        #print(pstring)
            #masterlist = alist
        self.Defaults=defaults
        self.Temperature = np.asarray(temperature, 'float64')
        nTemp = self.Temperature.size
        self.EDensity = np.asarray(eDensity, 'float64')
        nDen = self.EDensity.size
        self.NTempDen = max([nTemp, nDen])
        nTempDen = self.NTempDen
        self.Wavelength = wavelength
        #
        if type(em) == int and em == 0:
            em = np.ones(self.NTempDen, 'float64')
        elif type(em) == float and em > 0.:
            em = np.ones(self.NTempDen, 'float64')*em
        elif type(em) == list or type(em) == tuple:
            em = np.asarray(em, 'float64')
        self.Em = em
        #
        if self.Em.any() > 0.:
            ylabel = r'erg cm$^{-2}$ s$^{-1}$ sr$^{-1} \AA^{-1}$ $'
        else:
            ylabel = r'erg cm$^{-2}$ s$^{-1}$ sr$^{-1} \AA^{-1}$ ($\int\,$ N$_e\,$N$_H\,$d${\it l}$)$^{-1}$'
        #
        xlabel = 'Wavelength ('+self.Defaults['wavelength'] +')'
        #
        #self.AbundanceName = defaults['abundfile']
        #self.AbundanceAll = chdata.AbundanceAll
        #
        if abundanceName:
            if abundanceName in list(chdata.Abundance.keys()):
                self.AbundanceName = abundanceName
            else:
                abundChoices = list(chdata.Abundance.keys())
#                for one in wvl[topLines]:
#                    wvlChoices.append('%12.3f'%(one))
                abundChoice = chGui.gui.selectorDialog(abundChoices,label='Select Abundance name')
                abundChoice_idx = abundChoice.selectedIndex
                self.AbundanceName = abundChoices[abundChoice_idx[0]]
                abundanceName = self.AbundanceName
                print((' Abundance chosen:  %s '%(self.AbundanceName)))
        else:
            self.AbundanceName = self.Defaults['abundfile']
        #
        abundAll = chdata.Abundance[self.AbundanceName]['abundance']
        # needed by ionGate
        self.AbundAll = abundAll
        #
        nonzed = abundAll > 0.
        minAbundAll = abundAll[nonzed].min()
        # if minAbund is even set
        if minAbund:
            if minAbund < minAbundAll:
                minAbund = minAbundAll
        else:
            minAbund = minAbundAll
        self.MinAbund = minAbund
#        ionInfo = chio.masterListInfo()
        wavelength = np.asarray(wavelength)
        nWvl = wavelength.size
        self.Wavelength = wavelength
        wvlRange = [wavelength.min(), wavelength.max()]
        #
        freeFree = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        freeBound = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        twoPhoton = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        lineSpectrum = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        #
        self.IonsCalculated = []
        if keepIons:
            self.IonInstances = {}
        self.Finished = []
        #
        self.ionGate(elementList = elementList, ionList = ionList, minAbund=minAbund, doContinuum=doContinuum, verbose = verbose)
        #
        for akey in sorted(self.Todo.keys()):
            zStuff = util.convertName(akey)
            Z = zStuff['Z']
            ionstage = zStuff['Ion']
            dielectronic = zStuff['Dielectronic']
            abundance = chdata.Abundance[self.AbundanceName]['abundance'][Z - 1]
            if verbose:
                print(' %5i %5s abundance = %10.2e '%(Z, const.El[Z-1],  abundance))
            if verbose:
                print(' doing ion %s for the following processes %s'%(akey, self.Todo[akey]))
            if 'ff' in self.Todo[akey]:
                if verbose:
                    print(' calculating ff continuum for :  %s'%(akey))
                FF = chianti.core.continuum(akey, temperature, abundanceName=self.AbundanceName, em=em)
                FF.freeFree(wavelength)
#                if nTempDen == 1:
#                    freeFree += cont.FreeFree['rate']*em[0]
#                else:
#                    for iTempDen in range(nTempDen):
#                        freeFree[iTempDen] += cont.FreeFree['rate'][iTempDen]*em[iTempDen]
                freeFree += FF.FreeFree['rate']
            if 'fb' in self.Todo[akey]:
                if verbose:
                    print(' calculating fb continuum for :  %s'%(akey))
                try:
                    FB = chianti.core.continuum(akey, temperature, abundanceName=self.AbundanceName, em=em)
                    FB.freeBound(wavelength)
                    if 'errorMessage' not in list(cont.FreeBound.keys()):
                        #  an fblvl file exists for this ions
                        freeBound += FB.FreeBound['rate']
                except:
                    cont = chianti.core.continuum(akey, temperature, abundanceName=self.AbundanceName)
                    cont.freeBound(wavelength)
#                if 'errorMessage' not in list(cont.FreeBound.keys()):
#                    #  an fblvl file exists for this ions
#                    if nTempDen == 1:
#                        freeBound += cont.FreeBound['rate']*em[0]
#                    else:
#                        for iTempDen in range(nTempDen):
#                            freeBound[iTempDen] += cont.FreeBound['rate'][iTempDen]*em[iTempDen]
#                        freeBound += cont.FreeBound['rate']
            if 'line' in self.Todo[akey]:
                if verbose:
                    print(' calculating spectrum for  :  %s'%(akey))
                thisIon = chianti.core.ion(akey, temperature, eDensity, abundanceName=self.AbundanceName)
                thisIon.intensity(wvlRange=wvlRange, allLines=allLines, em=em)
                self.IonsCalculated.append(akey)
                if 'errorMessage' not in  list(thisIon.Intensity.keys()):
                    self.Finished.append(akey)
                    thisIon.spectrum(wavelength, filter=filter, allLines=allLines, em=em)
                    if keepIons:
                        self.IonInstances[akey] = copy.deepcopy(thisIon)
                    if setupIntensity:
                        for bkey in self.Intensity:
                            self.Intensity[bkey] = np.hstack((copy.copy(self.Intensity[bkey]), thisIon.Intensity[bkey]))
                    else:
                        setupIntensity = 1
                        self.Intensity  = thisIon.Intensity
                    lineSpectrum += thisIon.Spectrum['intensity']
#                            if nTempDen == 1:
#                                lineSpectrum += thisIon.Spectrum['intensity']
#                            else:
#                                for iTempDen in range(nTempDen):
#                                    lineSpectrum[iTempDen] += thisIon.Spectrum['intensity'][iTempDen]
                else:
                    if verbose:
                        print(thisIon.Intensity['errorMessage'])
                # get 2 photon emission for H and He sequences
                if (Z - ionstage) in [0, 1] and not dielectronic:
                    thisIon.twoPhoton(wavelength)
                    twoPhoton += thisIon.TwoPhoton['rate']

        self.FreeFree = {'wavelength':wavelength, 'intensity':freeFree.squeeze()}
        self.FreeBound = {'wavelength':wavelength, 'intensity':freeBound.squeeze()}
        self.LineSpectrum = {'wavelength':wavelength, 'intensity':lineSpectrum.squeeze()}
        self.TwoPhoton = {'wavelength':wavelength, 'intensity':twoPhoton.squeeze()}
        #
        #
        total = freeFree + freeBound + lineSpectrum + twoPhoton
        self.Total = total
        t2 = datetime.now()
        dt=t2-t1
        print(' elapsed seconds = %12.3f'%(dt.seconds))
        if nTempDen == 1:
            integrated = total
        else:
            integrated = total.sum(axis=0)
        #
        if type(label) == type(''):
            if hasattr(self, 'Spectrum'):
                self.Spectrum[label] = {'wavelength':wavelength, 'intensity':total.squeeze(), 'filter':filter[0].__name__,   'width':filter[1], 'integrated':integrated, 'em':em, 'ions':self.IonsCalculated,
                'Abundance':self.AbundanceName, 'xlabel':xlabel, 'ylabel':ylabel}
            else:
                self.Spectrum = {label:{'wavelength':wavelength, 'intensity':total.squeeze(), 'filter':filter[0].__name__,   'width':filter[1], 'integrated':integrated, 'em':em, 'ions':self.IonsCalculated,
                'Abundance':self.AbundanceName, 'xlabel':xlabel, 'ylabel':ylabel}}
        else:
            self.Spectrum ={'wavelength':wavelength, 'intensity':total.squeeze(), 'filter':filter[0].__name__,   'width':filter[1], 'integrated':integrated,  'ions':self.IonsCalculated,
            'Abundance':self.AbundanceName, 'xlabel':xlabel, 'ylabel':ylabel}
Exemple #8
0
 def ionGate(self, elementList = 0, ionList = 0, minAbund=0, doContinuum=1, doWvlTest=1, verbose=0):
     '''
     creates a list of ions for free-free, free-bound, and line intensity calculations
     if doing the radiative losses, accept all wavelength -> doWvlTest=0
     '''
     #
     masterlist = chdata.MasterList
     abundAll = self.AbundAll
     #
     nonzed = abundAll > 0.
     minAbundAll = abundAll[nonzed].min()
     if minAbund:
         if minAbund < minAbundAll:
             minAbund = minAbundAll
     ionInfo = chio.masterListInfo()
     #
     if hasattr(self, 'Wavelength'):
         wvlRange = [self.Wavelength.min(), self.Wavelength.max()]
     elif hasattr(self, 'WvlRange'):
         wvlRange = self.WvlRange
     else:
         print(' need a wavelength range in ionGate ')
     #
     temperature = self.Temperature
     #
     # use the ionList but make sure the ions are in the database
     self.Todo = {}
     #
     if minAbund:
         if doContinuum:
             for iz in range(1, 31):
                 abundance = chdata.Abundance[self.AbundanceName]['abundance'][iz-1]
                 if abundance >= minAbund:
                     if verbose:
                         print(' %5i %5s abundance = %10.2e '%(iz, const.El[iz-1],  abundance))
                     #
                     for ionstage in range(1, iz+2):
                         ionS = util.zion2name(iz, ionstage)
                         masterListTest = ionS in masterlist
                         masterListInfoTest = ionS in sorted(ionInfo.keys())
                         if masterListTest or masterListInfoTest:
                             if doWvlTest:
                                 wvlTestMin = wvlRange[0] <= ionInfo[ionS]['wmax']
                                 wvlTestMax = wvlRange[1] >= ionInfo[ionS]['wmin']
                             else:
                                 wvlTestMin = 1
                                 wvlTestMax = 1
                             ioneqTest = (temperature.max() >= ionInfo[ionS]['tmin']) and (temperature.min() <= ionInfo[ionS]['tmax'])
                         # construct similar test for the dielectronic files
                         ionstageTest = ionstage > 1
                         if ionstageTest and ioneqTest and doContinuum:
                             # ionS is the target ion, cannot be the neutral for the continuum
                             if verbose:
                                 print(' setting up continuum calculation for %s  '%(ionS))
                             if ionS in sorted(self.Todo.keys()):
                                 self.Todo[ionS] += '_ff_fb'
                             else:
                                 self.Todo[ionS] = 'ff_fb'
                             if verbose:
                                 print(' for ion %s do : %s'%(ionS, self.Todo[ionS]))
     #
     if elementList:
         for i,  one in enumerate(elementList):
             elementList[i] = one.lower()
         for one in masterlist:
             stuff = util.convertName(one)
             bare = stuff['Z'] == stuff['Ion']
             if stuff['Element'] in  elementList:
                 self.Todo[one] = 'line'
                 if doContinuum and not stuff['Dielectronic']:
                     self.Todo[one]+= '_ff'
                     if not bare:
                         self.Todo[one] += '_fb'
     if ionList: 
         for one in ionList:
             stuff = util.convertName(one)
             bare = stuff['Z'] == stuff['Ion']
             if masterlist.count(one):
                 self.Todo[one] = 'line'
                 if doContinuum and not stuff['Dielectronic']:
                     self.Todo[one]+= '_ff'
                     if not bare:
                         self.Todo[one] += '_fb'
             else:
                 if verbose:
                     pstring = ' %s not in CHIANTI database'%(one)
                     print(pstring)
     #
     #
     #
     if minAbund:
         for iz in range(1, 31):
             abundance = chdata.Abundance[self.AbundanceName]['abundance'][iz-1]
             if abundance >= minAbund:
                 if verbose:
                     print(' %5i %5s abundance = %10.2e '%(iz, const.El[iz-1],  abundance))
                 #
                 for ionstage in range(1, iz+2):
                     ionS = util.zion2name(iz, ionstage)
                     masterListTest = ionS in masterlist
                     masterListInfoTest = ionS in sorted(ionInfo.keys())
                     if masterListTest or masterListInfoTest:
                         if masterListTest or masterListInfoTest:
                             if doWvlTest:
                                 wvlTestMin = wvlRange[0] <= ionInfo[ionS]['wmax']
                                 wvlTestMax = wvlRange[1] >= ionInfo[ionS]['wmin']
                             else:
                                 wvlTestMin = 1
                                 wvlTestMax = 1
                         ioneqTest = (temperature.max() >= ionInfo[ionS]['tmin']) and (temperature.min() <= ionInfo[ionS]['tmax'])
                     # construct similar test for the dielectronic files
                     ionSd = util.zion2name(iz, ionstage, dielectronic=1)
                     masterListTestD = ionSd in masterlist
                     masterListInfoTestD = ionSd in sorted(ionInfo.keys())
                     if masterListTestD or masterListInfoTestD:
                         if doWvlTest:
                             wvlTestMinD = wvlRange[0] <= ionInfo[ionSd]['wmax']
                             wvlTestMaxD = wvlRange[1] >= ionInfo[ionSd]['wmin']
                         else:
                             wvlTestMinD = 1
                             wvlTestMaxD = 1
                         ioneqTestD = (temperature.max() >= ionInfo[ionSd]['tmin']) and (temperature.min() <=ionInfo[ionSd]['tmax'])
                         #
                     if masterListTest and wvlTestMin and wvlTestMax and ioneqTest:
                         #if verbose:
                             #print(' setting up spectrum calculation for  %s'%(ionS))
                         if ionS in sorted(self.Todo.keys()):
                             self.Todo[ionS] += '_line'
                         else:
                             self.Todo[ionS] = 'line'
                     # get dielectronic lines
                         if verbose:
                             print(' for ion %s do : %s'%(ionS, self.Todo[ionS]))
                     if masterListTestD and wvlTestMinD and wvlTestMaxD and ioneqTestD:
                         #if verbose:
                             #print(' setting up  spectrum calculation for  %s '%(ionSd))
                         if ionSd in sorted(self.Todo.keys()):
                             self.Todo[ionSd] += '_line'
                         else:
                             self.Todo[ionSd] = 'line'
                         if verbose:
                             print(' for ion %s do : %s'%(ionSd, self.Todo[ionSd]))
     return
Exemple #9
0
    def __init__(self, temperature, eDensity, wvlRange, elementList=0, ionList=0, minAbund=0, keepIons=0, em=0, abundanceName=0, verbose=0, allLines=1):
        #
        t1 = datetime.now()
        # creates Intensity dict from first ion calculated
        setupIntensity = 0
        #
        self.Defaults=defaults
        temperature = np.asarray(temperature, 'float64')
        self.Temperature = temperature
        eDensity = np.asarray(eDensity, 'float64')
        self.EDensity = eDensity

        #
        self.EDensity = np.asarray(eDensity,'float64')
        self.NEDens = self.EDensity.size
        ndens = self.EDensity.size
        ntemp = self.Temperature.size
        tst1 = ndens == ntemp
        tst1a = ndens != ntemp
        tst2 = ntemp > 1
        tst3 = ndens > 1
        tst4 = ndens > 1 and ntemp > 1
        if tst1 and ntemp == 1:
            self.NTempDen = 1
        elif tst1a and (tst2 or tst3) and not tst4:
            self.NTempDen = ntemp*ndens
            if ntemp == self.NTempDen and ndens != self.NTempDen:
                self.EDensity = np.ones_like(self.Temperature)*self.EDensity
            elif ndens == self.NTempDen and ntemp != self.NTempDen:
                self.Temperature = np.ones_like(self.EDensity)*self.Temperature
        elif tst1 and tst4:
            self.NTempDen = ntemp
        #
        if type(em) == int and em == 0:
            em = np.ones(self.NTempDen, 'float64')
        elif type(em) == float and em > 0.:
            em = np.ones(self.NTempDen, 'float64')*em        
        elif type(em) == list or type(em) == tuple:
            em = np.asarray(em, 'float64')
        self.Em = em
        #
        #if em != 0:
            #if type(em) == type(float):
                #if nTempDen > 1:
                    #em = np.ones_like(self.Temperature)*em
                    #nEm = nTempDen
                #else:
                    #nEm = 1
            #else:
                #em = np.asarray(em, 'float64')
                #nEm = em.size
                #if nEm != nTempDen:
                    #print(' the emission measure array must be the same size as the temperature/density array')
                    #return
        #else:
            #nEm = 0
        #self.NEm = nEm
        #self.AbundanceName = defaults['abundfile']
        #self.AbundanceAll = chdata.AbundanceAll
        #
        if abundanceName:
            if abundanceName in list(chdata.Abundance.keys()):
                self.AbundanceName = abundanceName
            else:
                abundChoices = list(chdata.Abundance.keys())
#                for one in wvl[topLines]:
#                    wvlChoices.append('%12.3f'%(one))
                abundChoice = chGui.gui.selectorDialog(abundChoices,label='Select Abundance name')
                abundChoice_idx = abundChoice.selectedIndex
                self.AbundanceName = abundChoices[abundChoice_idx[0]]
                abundanceName = self.AbundanceName
                print((' Abundance chosen:  %s '%(self.AbundanceName)))
        else:
            self.AbundanceName = self.Defaults['abundfile']
        #
        abundAll = chdata.Abundance[self.AbundanceName]['abundance']
        # needed by ionGate
        self.AbundAll = abundAll
        #
#        nonzed = abundAll > 0.
#        minAbundAll = abundAll[nonzed].min()
#        # if minAbund is even set
#        if minAbund:
#            if minAbund < minAbundAll:
#                minAbund = minAbundAll
#        self.minAbund = minAbund
        ionInfo = chio.masterListInfo()
        #        #
#        self.Intensity = {'ionS':[], 'lvl1':[], 'lvl2':[], 'wvl':np.ndarray, 'pretty1':np.ndarray, 'pretty2':np.ndarray, 'intensity':np.zeros((nTempDen, 0),'float64'), 'obs':np.ndarray }
        self.IonsCalculated = []
        if keepIons:
            self.IonInstances = {}
        self.Finished = []
        #
        # also needed by ionGate
        self.WvlRange = np.asarray(wvlRange, 'float64')
        #
        self.ionGate(elementList = elementList, ionList = ionList, minAbund=minAbund, doContinuum=0, verbose = verbose)
        #
        for ionS in sorted(self.Todo.keys()):
            nameStuff = util.convertName(ionS)
            Z = nameStuff['Z']
            
            if verbose:
                print(' calculating %s'%(ionS))
            thisIon = chianti.core.ion(ionS, temperature, eDensity, abundance=abundAll[Z-1])
            thisIon.intensity(wvlRange=wvlRange, allLines = allLines,  em=em)
            self.IonsCalculated.append(ionS)
            #
            if 'errorMessage' not in  list(thisIon.Intensity.keys()):
                self.Finished.append(ionS)
#                            thisIon.spectrum(wavelength, filter=filter)
                if keepIons:
                    self.IonInstances[ionS] = copy.deepcopy(thisIon)
                if setupIntensity:
                    for akey in self.Intensity:
                        self.Intensity[akey] = np.hstack((copy.copy(self.Intensity[akey]), thisIon.Intensity[akey]))
                else:
                    setupIntensity = 1
#                                print(' creating Intensity dict from ion %s'%(ionS))
                    self.Intensity  = thisIon.Intensity
            else:
                if verbose:
                    print(thisIon.Intensity['errorMessage'])
        #
        #
        t2 = datetime.now()
        dt=t2-t1
        print(' elapsed seconds = %12.3f'%(dt.seconds))
        return
Exemple #10
0
    def __init__(self, temperature, eDensity, wavelength, filter=(chfilters.gaussianR, 1000.), label=0, elementList = 0, ionList = 0, minAbund=0, keepIons=0, doContinuum=0, allLines = 1, em=0, abundanceName=0, verbose=0,  timeout=0.1):
        #
        t1 = datetime.now()
        #
        rcAll = Client()
#        all_engines = rcAll[:]
        lbvAll = rcAll.load_balanced_view()
        #
        #
        # creates Intensity dict from first ion calculated
        #
        setupIntensity = 0
        #
        masterlist = chdata.MasterList
        self.Defaults = defaults
        #
        self.Temperature = np.asarray(temperature,'float64')
        self.EDensity = np.asarray(eDensity,'float64')
        self.NEDens = self.EDensity.size
        ndens = self.EDensity.size
        ntemp = self.Temperature.size
        tst1 = ndens == ntemp
        tst1a = ndens != ntemp
        tst2 = ntemp > 1
        tst3 = ndens > 1
        tst4 = ndens > 1 and ntemp > 1
        if tst1 and ntemp == 1:
            self.NTempDen = 1
        elif tst1a and (tst2 or tst3) and not tst4:
            self.NTempDen = ntemp*ndens
            if ntemp == self.NTempDen and ndens != self.NTempDen:
                self.EDensity = np.ones_like(self.Temperature)*self.EDensity
            elif ndens == self.NTempDen and ntemp != self.NTempDen:
                self.Temperature = np.ones_like(self.EDensity)*self.Temperature
        elif tst1 and tst4:
            self.NTempDen = ntemp
            #
        #
        if type(em) == int and em == 0:
            em = np.ones(self.NTempDen, 'float64')
        elif type(em) == float and em > 0.:
            em = np.ones(self.NTempDen, 'float64')*em        
        elif type(em) == list or type(em) == tuple:
            em = np.asarray(em, 'float64')
        self.Em = em
        #
        #
        if self.Em.any() > 0.:
            ylabel = r'erg cm$^{-2}$ s$^{-1}$ sr$^{-1} \AA^{-1}$ $'
        else:
            ylabel = r'erg cm$^{-2}$ s$^{-1}$ sr$^{-1} \AA^{-1}$ ($\int\,$ N$_e\,$N$_H\,$d${\it l}$)$^{-1}$'
        #
        xlabel = 'Wavelength ('+self.Defaults['wavelength'] +')'
        #
        self.AllLines = allLines
        #
        if not abundanceName:
            self.AbundanceName = self.Defaults['abundfile']
        else:
            if abundanceName in chdata.Abundance:
                self.AbundanceName = abundanceName
            else:
                abundChoices = list(chdata.Abundance.keys())
#                for one in wvl[topLines]:
#                    wvlChoices.append('%12.3f'%(one))
                abundChoice = chgui.gui.selectorDialog(abundChoices,label='Select Abundance name')
                abundChoice_idx = abundChoice.selectedIndex
                self.AbundanceName = abundChoices[abundChoice_idx[0]]
                abundanceName = self.AbundanceName
                print(' Abundance chosen:  %s '%(self.AbundanceName))
        #
        #
        abundAll = chdata.Abundance[self.AbundanceName]['abundance']
        self.AbundAll = abundAll
        self.MinAbund = minAbund
        #
#        nonzed = abundAll > 0.
#        minAbundAll = abundAll[nonzed].min()
#        # if minAbund is even set
#        if minAbund:
#            if minAbund < minAbundAll:
#                minAbund = minAbundAll
        #ionInfo = chio.masterListInfo()
        wavelength = np.asarray(wavelength)
        nWvl = wavelength.size
        self.Wavelength = wavelength
#        wvlRange = [wavelength.min(), wavelength.max()]
        #
        #
        freeFree = np.zeros((self.NTempDen, nWvl), 'float64').squeeze()
        freeBound = np.zeros((self.NTempDen, nWvl), 'float64').squeeze()
        twoPhoton = np.zeros((self.NTempDen, nWvl), 'float64').squeeze()
        lineSpectrum = np.zeros((self.NTempDen, nWvl), 'float64').squeeze()
        #
         #
        allInpt = []
        #
        if keepIons:
            self.IonInstances = {}
            self.FbInstances = {}
            self.FfInstances = {}
        #
        # ionGate creates the self.Todo list
        #
        self.ionGate(elementList = elementList, ionList = ionList, minAbund=minAbund, doContinuum=doContinuum, verbose = verbose)
        #
        for akey in sorted(self.Todo.keys()):
            zStuff = util.convertName(akey)
            Z = zStuff['Z']
            abundance = chdata.Abundance[self.AbundanceName]['abundance'][Z - 1]
            if verbose:
                print(' %5i %5s abundance = %10.2e '%(Z, const.El[Z-1],  abundance))
            if verbose:
                print(' doing ion %s for the following processes %s'%(akey, self.Todo[akey]))
            if 'ff' in self.Todo[akey]:
#                if verbose:
#                    print(' doing ff')
                allInpt.append([akey, 'ff', temperature, wavelength, abundance, em])
            if 'fb' in self.Todo[akey]:
#                if verbose:
#                    print(' doing fb')
                allInpt.append([akey, 'fb', temperature, wavelength, abundance, em])
            if 'line' in self.Todo[akey]:
#                if verbose:
#                    print(' doing line')
                allInpt.append([akey, 'line', temperature, eDensity, wavelength, filter, allLines, abundance, em, doContinuum])
        #
        for anInpt in allInpt:
            lbvAll.apply(doAll, anInpt)
        lbvAll.wait()
        lbvAll.get_result()
        if verbose:
            print(' got all ff, fb, line results')
        ionsCalculated = []
        #
        for ijk in range(len(list(lbvAll.results.values()))):
            out = list(lbvAll.results.values())[ijk]
            if type(out) != list:
                print(' a problem has occured - this can be caused by')
                print('running Python3 and not using ipcluster3')
                return
            ionS = out[0]
            if verbose:
                print(' collecting calculation for %s'%(ionS))
            ionsCalculated.append(ionS)
            calcType = out[1]
            if verbose:
                print(' processing %s results'%(calcType))
            #
            if calcType == 'ff':
                thisFf = out[2]
                if 'errorMessage' not in sorted(thisFf.keys()):
                    if keepIons:
                        self.FfInstances[ionS] = thisFf
#                    if nTempDen == 1:
#                        freeFree += thisFf['rate']*em[0]
#                    else:
#                        for iTempDen in range(nTempDen):
#                            freeFree[iTempDen] += thisFf['rate'][iTempDen]*em[iTempDen]
                    freeFree += thisFf['rate']
                elif type(thisFf) == str:
                    print(' error in FfCont %s'%(thisFf))
                else:
                    print(thisFf['errorMessage'])
            #
#            if calcType == 'ff':
#                thisFf = out[2]
#                if hasattr(thisFf, 'FreeFree'):
#                    if 'errorMessage' not in sorted(thisFf.FreeFree.keys()):
#                        if keepIons:
#                            self.FfInstances[ionS] = thisFf
#    #                    if nTempDen == 1:
#    #                        freeFree += thisFf['rate']*em[0]
#    #                    else:
#    #                        for iTempDen in range(nTempDen):
#    #                            freeFree[iTempDen] += thisFf['rate'][iTempDen]*em[iTempDen]
#                        freeFree += thisFf.FreeFree['rate']
#                    elif type(thisFf) == str:
#                        print(' error in FfCont %s'%(thisFf))
#                    else:
#                        print(thisFf['errorMessage'])
            #
            elif calcType == 'fb':
                thisFb = out[2]
                if verbose:
                    print(' fb ion = %s'%(ionS))
                if hasattr(thisFb, 'FreeBound'):
                    if 'errorMessage' not in sorted(thisFb.FreeBound.keys()):
                        if keepIons:
                            self.FbInstances[ionS] = thisFb
                        #                        if nTempDen == 1:
#                            freeBound += thisFbCont.FreeBound['rate']*em[0]
#                        else:
#                            for iTempDen in range(nTempDen):
#                                freeBound[iTempDen] += thisFbCont.FreeBound['rate'][iTempDen]*em[iTempDen]
                        freeBound += thisFb.FreeBound['rate']
                    else:
                        print(thisFb.FreeBound['errorMessage'])
            #
            elif calcType == 'line':
                thisIon = out[2]
                if not 'errorMessage' in sorted(thisIon.Intensity.keys()):
                    if keepIons:
                        self.IonInstances[ionS] = thisIon
                    thisIntensity = thisIon.Intensity
    ##                self.IonInstances.append(copy.deepcopy(thisIon))
                    if setupIntensity:
                        for akey in sorted(self.Intensity.keys()):
                            self.Intensity[akey] = np.hstack((self.Intensity[akey], thisIntensity[akey]))
                    else:
                        setupIntensity = 1
                        self.Intensity  = thisIntensity
                    #
                    lineSpectrum += thisIon.Spectrum['intensity']
    #                if nTempDen == 1:
    #                    lineSpectrum += thisSpectrum['intensity']
    #                else:
    #                    for iTempDen in range(nTempDen):
    #                        lineSpectrum[iTempDen] += thisSpectrum['intensity'][iTempDen]
                   # check for two-photon emission
                    if len(out) == 4:
                        tp = out[3]
                        if self.NTempDen == 1:
                            twoPhoton += tp['rate']
                        else:
                            for iTempDen in range(self.NTempDen):
                                twoPhoton[iTempDen] += tp['rate'][iTempDen]
                else:
                    if 'errorMessage' in sorted(thisIon.Intensity.keys()):
                        print(thisIon.Intensity['errorMessage'])
        #
        #
        self.IonsCalculated = ionsCalculated
        #
        #
        self.FreeFree = {'wavelength':wavelength, 'intensity':freeFree.squeeze()}
        self.FreeBound = {'wavelength':wavelength, 'intensity':freeBound.squeeze()}
        self.LineSpectrum = {'wavelength':wavelength, 'intensity':lineSpectrum.squeeze()}
        self.TwoPhoton = {'wavelength':wavelength, 'intensity':twoPhoton.squeeze()}
        #
        total = freeFree + freeBound + lineSpectrum + twoPhoton
        #
        t2 = datetime.now()
        dt=t2-t1
        print(' elapsed seconds = %12.3e'%(dt.seconds))
        rcAll.purge_results('all')
        #
        if self.NTempDen == 1:
            integrated = total
        else:
            integrated = total.sum(axis=0)
        #
        if type(label) == type(''):
            if hasattr(self, 'Spectrum'):
                print(' hasattr = true')
                self.Spectrum[label] = {'wavelength':wavelength, 'intensity':total.squeeze(), 'filter':filter[0].__name__,   'width':filter[1], 'integrated':integrated, 'em':em,  'Abundance':self.AbundanceName, 
                                            'xlabel':xlabel, 'ylabel':ylabel}
            else:
                self.Spectrum = {label:{'wavelength':wavelength, 'intensity':total.squeeze(), 'filter':filter[0].__name__,   'width':filter[1], 'integrated':integrated, 'em':em, 'Abundance':self.AbundanceName, 
                                'xlabel':xlabel, 'ylabel':ylabel}}
        else:
            self.Spectrum = {'wavelength':wavelength, 'intensity':total.squeeze(), 'filter':filter[0].__name__,   'width':filter[1], 'integrated':integrated, 'em':em, 'Abundance':self.AbundanceName, 
                                'xlabel':xlabel, 'ylabel':ylabel}
Exemple #11
0
    def __init__(self,
                 temperature,
                 eDensity,
                 wavelength,
                 filter=(chfilters.gaussianR, 1000.),
                 label=0,
                 elementList=0,
                 ionList=0,
                 minAbund=0,
                 keepIons=0,
                 doContinuum=0,
                 allLines=1,
                 em=0,
                 abundanceName=0,
                 verbose=0,
                 timeout=0.1):
        #
        t1 = datetime.now()
        #
        rcAll = Client()
        #        all_engines = rcAll[:]
        lbvAll = rcAll.load_balanced_view()
        #
        #
        # creates Intensity dict from first ion calculated
        #
        setupIntensity = 0
        #
        masterlist = chdata.MasterList
        self.Defaults = defaults
        #
        self.Temperature = np.asarray(temperature, 'float64')
        self.EDensity = np.asarray(eDensity, 'float64')
        self.NEDens = self.EDensity.size
        ndens = self.EDensity.size
        ntemp = self.Temperature.size
        tst1 = ndens == ntemp
        tst1a = ndens != ntemp
        tst2 = ntemp > 1
        tst3 = ndens > 1
        tst4 = ndens > 1 and ntemp > 1
        if tst1 and ntemp == 1:
            self.NTempDen = 1
        elif tst1a and (tst2 or tst3) and not tst4:
            self.NTempDen = ntemp * ndens
            if ntemp == self.NTempDen and ndens != self.NTempDen:
                self.EDensity = np.ones_like(self.Temperature) * self.EDensity
            elif ndens == self.NTempDen and ntemp != self.NTempDen:
                self.Temperature = np.ones_like(
                    self.EDensity) * self.Temperature
        elif tst1 and tst4:
            self.NTempDen = ntemp
            #
        #
        if type(em) == int and em == 0:
            em = np.ones(self.NTempDen, 'float64')
        elif type(em) == float and em > 0.:
            em = np.ones(self.NTempDen, 'float64') * em
        elif type(em) == list or type(em) == tuple:
            em = np.asarray(em, 'float64')
        self.Em = em
        #
        #
        if self.Em.any() > 0.:
            ylabel = r'erg cm$^{-2}$ s$^{-1}$ sr$^{-1} \AA^{-1}$ $'
        else:
            ylabel = r'erg cm$^{-2}$ s$^{-1}$ sr$^{-1} \AA^{-1}$ ($\int\,$ N$_e\,$N$_H\,$d${\it l}$)$^{-1}$'
        #
        xlabel = 'Wavelength (' + self.Defaults['wavelength'] + ')'
        #
        self.AllLines = allLines
        #
        if not abundanceName:
            self.AbundanceName = self.Defaults['abundfile']
        else:
            if abundanceName in chdata.Abundance:
                self.AbundanceName = abundanceName
            else:
                abundChoices = list(chdata.Abundance.keys())
                #                for one in wvl[topLines]:
                #                    wvlChoices.append('%12.3f'%(one))
                abundChoice = chgui.gui.selectorDialog(
                    abundChoices, label='Select Abundance name')
                abundChoice_idx = abundChoice.selectedIndex
                self.AbundanceName = abundChoices[abundChoice_idx[0]]
                abundanceName = self.AbundanceName
                print(' Abundance chosen:  %s ' % (self.AbundanceName))
        #
        #
        abundAll = chdata.Abundance[self.AbundanceName]['abundance']
        self.AbundAll = abundAll
        self.MinAbund = minAbund
        #
        #        nonzed = abundAll > 0.
        #        minAbundAll = abundAll[nonzed].min()
        #        # if minAbund is even set
        #        if minAbund:
        #            if minAbund < minAbundAll:
        #                minAbund = minAbundAll
        #ionInfo = chio.masterListInfo()
        wavelength = np.asarray(wavelength)
        nWvl = wavelength.size
        self.Wavelength = wavelength
        #        wvlRange = [wavelength.min(), wavelength.max()]
        #
        #
        freeFree = np.zeros((self.NTempDen, nWvl), 'float64').squeeze()
        freeBound = np.zeros((self.NTempDen, nWvl), 'float64').squeeze()
        twoPhoton = np.zeros((self.NTempDen, nWvl), 'float64').squeeze()
        lineSpectrum = np.zeros((self.NTempDen, nWvl), 'float64').squeeze()
        #
        #
        allInpt = []
        #
        if keepIons:
            self.IonInstances = {}
            self.FbInstances = {}
            self.FfInstances = {}
        #
        # ionGate creates the self.Todo list
        #
        self.ionGate(elementList=elementList,
                     ionList=ionList,
                     minAbund=minAbund,
                     doContinuum=doContinuum,
                     verbose=verbose)
        #
        for akey in sorted(self.Todo.keys()):
            zStuff = util.convertName(akey)
            Z = zStuff['Z']
            abundance = chdata.Abundance[self.AbundanceName]['abundance'][Z -
                                                                          1]
            if verbose:
                print(' %5i %5s abundance = %10.2e ' %
                      (Z, const.El[Z - 1], abundance))
            if verbose:
                print(' doing ion %s for the following processes %s' %
                      (akey, self.Todo[akey]))
            if 'ff' in self.Todo[akey]:
                #                if verbose:
                #                    print(' doing ff')
                allInpt.append(
                    [akey, 'ff', temperature, wavelength, abundance, em])
            if 'fb' in self.Todo[akey]:
                #                if verbose:
                #                    print(' doing fb')
                allInpt.append(
                    [akey, 'fb', temperature, wavelength, abundance, em])
            if 'line' in self.Todo[akey]:
                #                if verbose:
                #                    print(' doing line')
                allInpt.append([
                    akey, 'line', temperature, eDensity, wavelength, filter,
                    allLines, abundance, em, doContinuum
                ])
        #
        for anInpt in allInpt:
            lbvAll.apply(doAll, anInpt)
        lbvAll.wait()
        lbvAll.get_result()
        if verbose:
            print(' got all ff, fb, line results')
        ionsCalculated = []
        #
        for ijk in range(len(list(lbvAll.results.values()))):
            out = list(lbvAll.results.values())[ijk]
            if type(out) != list:
                print(' a problem has occured - this can be caused by')
                print('running Python3 and not using ipcluster3')
                return
            ionS = out[0]
            if verbose:
                print(' collecting calculation for %s' % (ionS))
            ionsCalculated.append(ionS)
            calcType = out[1]
            if verbose:
                print(' processing %s results' % (calcType))
            #
            if calcType == 'ff':
                thisFf = out[2]
                if 'errorMessage' not in sorted(thisFf.keys()):
                    if keepIons:
                        self.FfInstances[ionS] = thisFf
#                    if nTempDen == 1:
#                        freeFree += thisFf['rate']*em[0]
#                    else:
#                        for iTempDen in range(nTempDen):
#                            freeFree[iTempDen] += thisFf['rate'][iTempDen]*em[iTempDen]
                    freeFree += thisFf['rate']
                elif type(thisFf) == str:
                    print(' error in FfCont %s' % (thisFf))
                else:
                    print(thisFf['errorMessage'])
            #
#            if calcType == 'ff':
#                thisFf = out[2]
#                if hasattr(thisFf, 'FreeFree'):
#                    if 'errorMessage' not in sorted(thisFf.FreeFree.keys()):
#                        if keepIons:
#                            self.FfInstances[ionS] = thisFf
#    #                    if nTempDen == 1:
#    #                        freeFree += thisFf['rate']*em[0]
#    #                    else:
#    #                        for iTempDen in range(nTempDen):
#    #                            freeFree[iTempDen] += thisFf['rate'][iTempDen]*em[iTempDen]
#                        freeFree += thisFf.FreeFree['rate']
#                    elif type(thisFf) == str:
#                        print(' error in FfCont %s'%(thisFf))
#                    else:
#                        print(thisFf['errorMessage'])
#
            elif calcType == 'fb':
                thisFb = out[2]
                if verbose:
                    print(' fb ion = %s' % (ionS))
                if hasattr(thisFb, 'FreeBound'):
                    if 'errorMessage' not in sorted(thisFb.FreeBound.keys()):
                        if keepIons:
                            self.FbInstances[ionS] = thisFb
                        #                        if nTempDen == 1:


#                            freeBound += thisFbCont.FreeBound['rate']*em[0]
#                        else:
#                            for iTempDen in range(nTempDen):
#                                freeBound[iTempDen] += thisFbCont.FreeBound['rate'][iTempDen]*em[iTempDen]
                        freeBound += thisFb.FreeBound['rate']
                    else:
                        print(thisFb.FreeBound['errorMessage'])
            #
            elif calcType == 'line':
                thisIon = out[2]
                if not 'errorMessage' in sorted(thisIon.Intensity.keys()):
                    if keepIons:
                        self.IonInstances[ionS] = thisIon
                    thisIntensity = thisIon.Intensity
                    ##                self.IonInstances.append(copy.deepcopy(thisIon))
                    if setupIntensity:
                        for akey in sorted(self.Intensity.keys()):
                            self.Intensity[akey] = np.hstack(
                                (self.Intensity[akey], thisIntensity[akey]))
                    else:
                        setupIntensity = 1
                        self.Intensity = thisIntensity
                    #
                    lineSpectrum += thisIon.Spectrum['intensity']
                    #                if nTempDen == 1:
                    #                    lineSpectrum += thisSpectrum['intensity']
                    #                else:
                    #                    for iTempDen in range(nTempDen):
                    #                        lineSpectrum[iTempDen] += thisSpectrum['intensity'][iTempDen]
                    # check for two-photon emission
                    if len(out) == 4:
                        tp = out[3]
                        if self.NTempDen == 1:
                            twoPhoton += tp['rate']
                        else:
                            for iTempDen in range(self.NTempDen):
                                twoPhoton[iTempDen] += tp['rate'][iTempDen]
                else:
                    if 'errorMessage' in sorted(thisIon.Intensity.keys()):
                        print(thisIon.Intensity['errorMessage'])
        #
        #
        self.IonsCalculated = ionsCalculated
        #
        #
        self.FreeFree = {
            'wavelength': wavelength,
            'intensity': freeFree.squeeze()
        }
        self.FreeBound = {
            'wavelength': wavelength,
            'intensity': freeBound.squeeze()
        }
        self.LineSpectrum = {
            'wavelength': wavelength,
            'intensity': lineSpectrum.squeeze()
        }
        self.TwoPhoton = {
            'wavelength': wavelength,
            'intensity': twoPhoton.squeeze()
        }
        #
        total = freeFree + freeBound + lineSpectrum + twoPhoton
        #
        t2 = datetime.now()
        dt = t2 - t1
        print(' elapsed seconds = %12.3e' % (dt.seconds))
        rcAll.purge_results('all')
        #
        if self.NTempDen == 1:
            integrated = total
        else:
            integrated = total.sum(axis=0)
        #
        if type(label) == type(''):
            if hasattr(self, 'Spectrum'):
                print(' hasattr = true')
                self.Spectrum[label] = {
                    'wavelength': wavelength,
                    'intensity': total.squeeze(),
                    'filter': filter[0].__name__,
                    'width': filter[1],
                    'integrated': integrated,
                    'em': em,
                    'Abundance': self.AbundanceName,
                    'xlabel': xlabel,
                    'ylabel': ylabel
                }
            else:
                self.Spectrum = {
                    label: {
                        'wavelength': wavelength,
                        'intensity': total.squeeze(),
                        'filter': filter[0].__name__,
                        'width': filter[1],
                        'integrated': integrated,
                        'em': em,
                        'Abundance': self.AbundanceName,
                        'xlabel': xlabel,
                        'ylabel': ylabel
                    }
                }
        else:
            self.Spectrum = {
                'wavelength': wavelength,
                'intensity': total.squeeze(),
                'filter': filter[0].__name__,
                'width': filter[1],
                'integrated': integrated,
                'em': em,
                'Abundance': self.AbundanceName,
                'xlabel': xlabel,
                'ylabel': ylabel
            }
Exemple #12
0
    def __init__(self, temperature, density, wavelength, filter=(chfilters.gaussianR, 1000.), elementList = 0, ionList = 0, minAbund=0., doContinuum=1, allLines = 1, em = None,  proc=3,  verbose = 0,  timeout=0.1):
        t1 = datetime.now()
        masterlist = chdata.MasterList
        # use the ionList but make sure the ions are in the database
        if elementList:
            for i,  one in enumerate(elementList):
                elementList[i] = one.lower()
            alist = []
            for one in masterlist:
                stuff = util.convertName(one)
                if stuff['Element'] in  elementList:
                    alist.append(one)
            masterlist = alist
        elif ionList:
            alist=[]
            for one in ionList:
                if masterlist.count(one):
                    alist.append(one)
                else:
                    if verbose:
                        pstring = ' %s not in CHIANTI database'%(one)
                        print('')
            masterlist = alist
        self.Defaults = defaults
        self.Temperature = np.asarray(temperature, 'float64')
        nTemp = self.Temperature.size
        self.Density = np.asarray(density, 'float64')
        nDen = self.Density.size
        nTempDen = max([nTemp, nDen])
        if type(em) != types.NoneType:
            if isinstance(em, float):
                if nTempDen > 1:
                    em = np.ones_like(self.Temperature)*em
                    nEm = nTempDen
                else:
                    nEm = 1
            else:
                em = np.asarray(em, 'float64')
                nEm = em.size
                if nEm != nTempDen:
                    print ' the emission measure array must be the same size as the temperature/density array'
                    return
            self.Em = em
        self.AllLines = allLines
        self.AbundanceName = self.Defaults['abundfile']
#        self.AbundanceAll = util.abundanceRead(abundancename = self.AbundanceName)
        self.AbundanceAll = chdata.AbundanceAll
        abundAll = self.AbundanceAll['abundance']
        nonzed = abundAll > 0.
        minAbundAll = abundAll[nonzed].min()
        if minAbund < minAbundAll:
            minAbund = minAbundAll
        ionInfo = util.masterListInfo()
        wavelength = np.asarray(wavelength)
        nWvl = wavelength.size
        self.Wavelength = wavelength
        wvlRange = [wavelength.min(), wavelength.max()]
        #
        proc = min([proc, mp.cpu_count()])
        #
        freeFree = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        freeBound = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        twoPhoton = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        lineSpectrum = np.zeros((nTempDen, nWvl), 'float64').squeeze()
        #
        #  free-free multiprocessing setup
        ffWorkerQ = mp.Queue()
        ffDoneQ = mp.Queue()
        #
        #  free-bound multiprocessing setup
        #
        fbWorkerQ = mp.Queue()
        fbDoneQ = mp.Queue()
        #
        #  ion multiprocessing setup
        ionWorkerQ = mp.Queue()
        ionDoneQ = mp.Queue()
        #
        ionsCalculated = []
        #
        self.Todo = []
        for iz in range(31):
            abundance = self.AbundanceAll['abundance'][iz-1]
            if abundance >= minAbund:
                if verbose:
                    print ' %5i %5s abundance = %10.2e '%(iz, const.El[iz-1],  abundance)
                #
                for ionstage in range(1, iz+2):
                    ionS = util.zion2name(iz, ionstage)
                    masterListTest = ionS in masterlist
                    masterListInfoTest = ionS in ionInfo.keys()
                    if masterListTest or masterListInfoTest:
                        wvlTestMin = self.Wavelength.min() <= ionInfo[ionS]['wmax']
                        wvlTestMax = self.Wavelength.max() >= ionInfo[ionS]['wmin']
                        ioneqTest = (self.Temperature.max() >= ionInfo[ionS]['tmin']) and (self.Temperature.min() <= ionInfo[ionS]['tmax'])
                    # construct similar test for the dielectronic files
                    ionSd = util.zion2name(iz, ionstage, dielectronic=1)
                    masterListTestD = ionSd in masterlist
                    masterListInfoTestD = ionSd in ionInfo.keys()
                    if masterListTestD or masterListInfoTestD:
                        wvlTestMinD = self.Wavelength.min() <= ionInfo[ionSd]['wmax']
                        wvlTestMaxD = self.Wavelength.max() >= ionInfo[ionSd]['wmin']
                        ioneqTestD = (self.Temperature.max() >= ionInfo[ionSd]['tmin']) and (self.Temperature.min() <=ionInfo[ionSd]['tmax'])
                    ionstageTest = ionstage > 1
                    if ionstageTest and ioneqTest and doContinuum:
                        # ionS is the target ion, cannot be the neutral for the continuum
                        if verbose:
                            print ' setting up continuum calculation for :  ',  ionS
                        ffWorkerQ.put((ionS, temperature, wavelength))
                        fbWorkerQ.put((ionS, temperature, wavelength))
#                        fbInputs.append([ionS, temperature, wavelength])
                        #
                    if masterListTest and wvlTestMin and wvlTestMax and ioneqTest:
                        if verbose:
                            print ' setting up spectrum calculation for  :  ', ionS
                        ionWorkerQ.put((ionS, temperature, density, wavelength, filter, allLines))
                        self.Todo.append(ionS)
                        ionsCalculated.append(ionS)
                    # get dielectronic lines
                    if masterListTestD and wvlTestMinD and wvlTestMaxD and ioneqTestD:
                        if verbose:
                            print ' setting up  spectrum calculation for  :  ', ionSd
#                        dielWorkerQ.put((ionSd, temperature, density, wavelength, filter))
                        # set allLines fo dielectronic
                        ionWorkerQ.put((ionSd, temperature, density, wavelength, filter, 1))
                        self.Todo.append(ionSd)
                        ionsCalculated.append(ionS)
        #
        ffWorkerQSize = ffWorkerQ.qsize()
        fbWorkerQSize = fbWorkerQ.qsize()
        ionWorkerQSize = ionWorkerQ.qsize()
        if doContinuum:
            ffProcesses = []
            for i in range(proc):
                p = mp.Process(target=mputil.doFfQ, args=(ffWorkerQ, ffDoneQ))
                p.start()
                ffProcesses.append(p)
    #       timeout is not necessary
            for p in ffProcesses:
                if p.is_alive():
                    p.join(timeout=timeout)
#            for i in range(proc):
#                ffProcesses.append('STOP')
            #
            for iff in range(ffWorkerQSize):
                thisFreeFree =ffDoneQ.get()
                if nTempDen ==1:
                    freeFree += thisFreeFree['rate']
                else:
                    for iTempDen in range(nTempDen):
                        freeFree[iTempDen] += thisFreeFree['rate'][iTempDen]
            for p in ffProcesses:
                if not isinstance(p, str):
                    p.terminate()
        #
            fbProcesses = []
            for i in range(proc):
                p = mp.Process(target=mputil.doFbQ, args=(fbWorkerQ, fbDoneQ))
                p.start()
                fbProcesses.append(p)
    #       timeout is not necessary
            for p in fbProcesses:
                if p.is_alive():
                    p.join(timeout=timeout)
#            for i in range(proc):
#                fbProcesses.append('STOP')
            #
            for ifb in range(fbWorkerQSize):
                thisFreeBound = fbDoneQ.get()
                if thisFreeBound.has_key('rate'):
                    if nTempDen ==1:
                        freeBound += thisFreeBound['rate']
                    else:
                        for iTempDen in range(nTempDen):
                            freeBound[iTempDen] += thisFreeBound['rate'][iTempDen]
            for p in fbProcesses:
                if not isinstance(p, str):
                    p.terminate()
        #
        ionProcesses = []
        if ionWorkerQSize < proc:
            nproc = ionWorkerQSize
        for i in range(proc):
            p = mp.Process(target=mputil.doIonQ, args=(ionWorkerQ, ionDoneQ))
            p.start()
            ionProcesses.append(p)
#            ionWorkerQ.put('STOP')
#       timeout is not necessary
        for p in ionProcesses:
#            print' process is alive:  ', p.is_alive()
            if p.is_alive():
#                p.join()
                p.join(timeout=timeout)
#        for i in range(proc):
#            ionProcesses.append('STOP')
        self.Finished = []
        #
        for ijk in range(ionWorkerQSize):
            out = ionDoneQ.get()
            ions = out[0]
            self.Finished.append(ions)
            aspectrum = out[1]
            try:
                if nTempDen == 1:
                    lineSpectrum += aspectrum['intensity']
                else:
                    for iTempDen in range(nTempDen):
                        lineSpectrum[iTempDen] += aspectrum['intensity'][iTempDen]
               # check for two-photon emission
                if len(out) == 3:
                    tp = out[2]
                    if nTempDen == 1:
                        twoPhoton += tp['rate']
                    else:
                        for iTempDen in range(nTempDen):
                            twoPhoton[iTempDen] += tp['rate'][iTempDen]
            except:
                print '  error in ion pool'
        #
        for p in ionProcesses:
            if not isinstance(p, str):
                p.terminate()
        #
        #
        #
        self.FreeFree = {'wavelength':wavelength, 'intensity':freeFree.squeeze()}
        self.FreeBound = {'wavelength':wavelength, 'intensity':freeBound.squeeze()}
        self.LineSpectrum = {'wavelength':wavelength, 'intensity':lineSpectrum.squeeze()}
        self.TwoPhoton = {'wavelength':wavelength, 'intensity':twoPhoton.squeeze()}
        #
        total = freeFree + freeBound + lineSpectrum + twoPhoton
        t2 = datetime.now()
        dt=t2-t1
        if verbose:
            print ' elapsed seconds = ', dt.seconds
        if type(em) != types.NoneType:
            if nEm == 1:
                integrated = total*em
            else:
                integrated = np.zeros_like(wavelength)
                for iTempDen in range(nTempDen):
                    integrated += total[iTempDen]*em[iTempDen]
            self.Spectrum ={'temperature':temperature, 'density':density, 'wavelength':wavelength, 'intensity':total.squeeze(), 'filter':filter[0].__name__,   'width':filter[1], 'integrated':integrated, 'em':em, 'minAbund':minAbund, 'masterlist':masterlist, 'ions':ionsCalculated}
        else:
            self.Spectrum ={'temperature':temperature, 'density':density, 'wavelength':wavelength, 'intensity':total.squeeze(), 'filter':filter[0].__name__,   'width':filter[1], 'minAbund':minAbund, 'masterlist':masterlist, 'ions':ionsCalculated}
Exemple #13
0
    def __init__(self,
                 temperature,
                 eDensity,
                 elementList=0,
                 ionList=0,
                 minAbund=0,
                 doContinuum=1,
                 abundanceName=0,
                 verbose=0,
                 allLines=1,
                 keepIons=0):
        t1 = datetime.now()
        masterlist = chdata.MasterList
        # use the ionList but make sure the ions are in the database
        if ionList:
            alist = []
            for one in ionList:
                if masterlist.count(one):
                    alist.append(one)
                else:
                    if verbose:
                        pstring = ' %s not in CHIANTI database' % (one)
                        print(pstring)
            masterlist = alist
        self.Defaults = defaults
        self.Temperature = np.asarray(temperature, 'float64')
        nTemp = self.Temperature.size
        self.EDensity = np.asarray(eDensity, 'float64')
        nDen = self.EDensity.size
        nTempDen = max([nTemp, nDen])

        if not abundanceName:
            self.AbundanceName = self.Defaults['abundfile']
        else:
            if abundanceName in sorted(chdata.Abundance.keys()):
                self.AbundanceName = abundanceName
            else:
                abundChoices = sorted(chdata.Abundance.keys())
                #                for one in wvl[topLines]:
                #                    wvlChoices.append('%12.3f'%(one))
                abundChoice = chgui.gui.selectorDialog(
                    abundChoices, label='Select Abundance name')
                abundChoice_idx = abundChoice.selectedIndex
                self.AbundanceName = abundChoices[abundChoice_idx[0]]
                abund = self.AbundanceName
                print(' Abundance chosen:  %s ' % (self.AbundanceName))
        #
        abundAll = chdata.Abundance[self.AbundanceName]['abundance']
        # needed by ionGate
        self.AbundAll = abundAll
        #
        nonzed = abundAll > 0.
        minAbundAll = abundAll[nonzed].min()
        # if minAbund is even set
        if minAbund:
            if minAbund < minAbundAll:
                minAbund = minAbundAll
#        ionInfo = util.masterListInfo()
#
        freeFreeLoss = np.zeros((nTempDen), 'float64').squeeze()
        freeBoundLoss = np.zeros((nTempDen), 'float64').squeeze()
        twoPhotonLoss = np.zeros((nTempDen), 'float64').squeeze()
        boundBoundLoss = np.zeros((nTempDen), 'float64').squeeze()
        twoPhotonLoss = np.zeros((nTempDen), 'float64').squeeze()
        #
        self.IonsCalculated = []
        if keepIons:
            self.IonInstances = {}
        self.Finished = []
        #
        self.WvlRange = [0., 1.e+30]
        #
        self.ionGate(elementList=elementList,
                     ionList=ionList,
                     minAbund=minAbund,
                     doContinuum=doContinuum,
                     doWvlTest=0,
                     verbose=verbose)
        #
        #
        for akey in sorted(self.Todo.keys()):
            zStuff = util.convertName(akey)
            Z = zStuff['Z']
            ionstage = zStuff['Ion']
            dielectronic = zStuff['Dielectronic']
            abundance = chdata.Abundance[self.AbundanceName]['abundance'][Z -
                                                                          1]
            if verbose:
                print(' %5i %5s abundance = %10.2e ' %
                      (Z, const.El[Z - 1], abundance))
            if verbose:
                print(' doing ion %s for the following processes %s' %
                      (akey, self.Todo[akey]))
            if ionstage != 1:
                if verbose:
                    print(' calculating ff continuum for :  %s' % (akey))
                if 'ff' in self.Todo[akey]:
                    # need to skip the neutral
                    cont = chianti.core.continuum(
                        akey, temperature, abundanceName=self.AbundanceName)
                    cont.freeFreeLoss()
                    freeFreeLoss += cont.FreeFreeLoss['rate']
    #                if nTempDen == 1:
    #                    freeFree += cont.FreeFreeLoss['rate']
    #                else:
    #                    for iTempDen in range(nTempDen):
    #                        freeFree[iTempDen] += cont.FreeFree['rate'][iTempDen]*em[iTempDen]
    #                freeFree += cont.FreeFree['rate']
                if 'fb' in self.Todo[akey]:
                    if verbose:
                        print(' calculating fb continuum for :  %s' % (akey))
    #                try:
    # does cont already exist - i.e did we create it for ff
                    if hasattr(cont, 'FreeFreeLoss'):
                        cont.freeBoundLoss()
                    else:
                        cont = chianti.core.continuum(
                            akey,
                            temperature,
                            abundanceName=self.AbundanceName)
                        cont.freeBoundLoss()
                    if 'errorMessage' not in list(cont.FreeBoundLoss.keys()):
                        #  an fblvl file exists for this ions
                        freeBoundLoss += cont.FreeBoundLoss['rate']
#                except:
#                    cont = chianti.core.continuum(akey, temperature, abundanceName=self.AbundanceName)
#                    cont.freeBoundLoss()
#                if 'errorMessage' not in list(cont.FreeBound.keys()):
#                    #  an fblvl file exists for this ions
#                    freeBoundLoss += cont.FreeBoundLoss['rate']
#                    if nTempDen == 1:
#                        freeBoundLoss += cont.FreeBoundLoss['rate']
#                    else:
#                        for iTempDen in range(nTempDen):
#                            freeBound[iTempDen] += cont.FreeBound['rate'][iTempDen]*em[iTempDen]
#                        freeBound += cont.FreeBound['rate']
            if 'line' in self.Todo[akey]:
                if verbose:
                    print(' calculating spectrum for  :  %s' % (akey))
                thisIon = chianti.core.ion(akey,
                                           temperature,
                                           eDensity,
                                           abundanceName=self.AbundanceName)
                thisIon.intensity(allLines=allLines)
                self.IonsCalculated.append(akey)
                if 'errorMessage' not in list(thisIon.Intensity.keys()):
                    self.Finished.append(akey)
                    thisIon.boundBoundLoss()
                    #                    self.IonInstances[akey] = copy.deepcopy(thisIon)
                    #                    if setupIntensity:
                    #                        for bkey in self.Intensity:
                    #                            self.Intensity[bkey] = np.hstack((copy.copy(self.Intensity[bkey]), thisIon.Intensity[bkey]))
                    #                    else:
                    #                        setupIntensity = 1
                    #                        self.Intensity  = thisIon.Intensity
                    boundBoundLoss += thisIon.BoundBoundLoss['rate']
#                            if nTempDen == 1:
#                                lineSpectrum += thisIon.Spectrum['intensity']
#                            else:
#                                for iTempDen in range(nTempDen):
#                                    lineSpectrum[iTempDen] += thisIon.Spectrum['intensity'][iTempDen]
                else:
                    if verbose:
                        print(thisIon.Intensity['errorMessage'])
                # get 2 photon emission for H and He sequences
                if (Z - ionstage) in [0, 1] and not dielectronic:
                    thisIon.twoPhotonLoss()
                    twoPhotonLoss += thisIon.TwoPhotonLoss['rate']

#        for iz in range(31):
#            abundance = chdata.Abundance['abundance'][iz-1]
#            if abundance >= minAbund:
#                print(' %5i %5s abundance = %10.2e '%(iz, const.El[iz-1],  abundance))
#                #
#                for ionstage in range(1, iz+2):
#                    ionS = util.zion2name(iz, ionstage)
##                   print ' ionS = ', ionS
#                    masterListTest = ionS in masterlist
#                    masterListInfoTest = ionS in sorted(ionInfo.keys())
#                    if masterListTest or masterListInfoTest:
#                        ioneqTest = (self.Temperature.max() >= ionInfo[ionS]['tmin']) and (self.Temperature.min() <= ionInfo[ionS]['tmax'])
#                    # construct similar test for the dielectronic files
#                    ionSd = util.zion2name(iz, ionstage, dielectronic=1)
#                    masterListTestD = ionSd in masterlist
#                    masterListInfoTestD = ionSd in sorted(ionInfo.keys())
#                    if masterListTestD or masterListInfoTestD:
#                        ioneqTestD = (self.Temperature.max() >= ionInfo[ionSd]['tmin']) and (self.Temperature.min() <=ionInfo[ionSd]['tmax'])
#                    ionstageTest = ionstage > 1
#                    if ionstageTest and ioneqTest and doContinuum:
#                        # ionS is the target ion, cannot be the neutral for the continuum
#                        print(' calculating continuum for %s'%(ionS))
#                        cont = chianti.core.continuum(ionS, temperature, abund=abund)
#                        cont.freeFreeLoss()
#    #                   print dir(thisIon)
#    #                   print ' wvl = ', thisIon.FreeFree['wvl']
##                        if nTempDen ==1:
#                        freeFreeLoss += cont.FreeFreeLoss['rate']
##                        else:
##                            for iTempDen in range(nTempDen):
##                                freeFreeLoss[iTempDen] += cont.FreeFreeLoss['rate'][iTempDen]
#                    #
#                        cont.freeBoundLoss()
#                        if 'errorMessage' not in sorted(cont.FreeBoundLoss.keys()):
#                            #  an fblvl file exists for this ions
##                            if nTempDen == 1:
#                            freeBoundLoss += cont.FreeBoundLoss['rate']
##                            else:
##                                freeBound[iTempDen] += cont.FreeBound['rate'][iTempDen]
#                    if masterListTest and ioneqTest:
#                        print(' calculating spectrum for  %s  '%(ionS))
#                        thisIon = chianti.core.ion(ionS, temperature, density, abund=abund)
##                       print ' dir = ', dir(thisIon)
##                        thisIon.emiss(wvlRange = wvlRange, allLines=allLines)
#                        thisIon.boundBoundLoss( allLines=allLines)
#                        # check that there are lines in this wavelength range
#                        if 'errorMessage' not in  sorted(thisIon.BoundBoundLoss.keys()):
#                            thisIon.boundBoundLoss()
##                           intensity = thisIon.Intensity['intensity']
##                            if nTempDen == 1:
#                            boundBoundLoss += thisIon.BoundBoundLoss['rate']
##                            else:
##                                for iTempDen in range(nTempDen):
##                                    lineSpectrum[iTempDen] += thisIon.Spectrum['intensity'][iTempDen]
#                        # get 2 photon emission for H and He sequences
#                        if (iz - ionstage) in [0, 1]:
#                            thisIon.twoPhotonLoss()
#                            twoPhotonLoss += thisIon.TwoPhotonLoss['rate']
#                    # get dielectronic lines
#                    if masterListTestD and ioneqTestD:
#                        print(' calculating spectrum for  %s '%(ionSd))
#                        thisIon = chianti.core.ion(ionSd, temperature, density, abund=abund)
##                       print ' dir = ', dir(thisIon)
##                       have to do all lines for the dielectronic satellites
##                        thisIon.emiss(allLines=1)
#                        thisIon.intensity(allLines=allLines)
#                        # check that there are lines in this wavelength range - probably not redundant
#                        if 'errorMessage' not in  sorted(thisIon.Intensity.keys()):
#                            thisIon.boundBoundLoss()
##                            if nTempDen == 1:
#                            boundBoundLoss += thisIon.BoundBoundLoss['rate']
##                            else:
##                                for iTempDen in range(nTempDen):
##                                    lineSpectrum[iTempDen] += thisIon.Spectrum['intensity'][iTempDen]
        self.FreeFreeLoss = freeFreeLoss
        self.FreeBoundLoss = freeBoundLoss
        self.BoundBoundLoss = boundBoundLoss
        self.TwoPhotonLoss = twoPhotonLoss
        #
        total = freeFreeLoss + freeBoundLoss + boundBoundLoss + twoPhotonLoss
        t2 = datetime.now()
        dt = t2 - t1
        print(' elapsed seconds = %10.2e' % (dt.seconds))
        self.RadLoss = {
            'rate': total,
            'temperature': self.Temperature,
            'density': self.EDensity,
            'minAbund': minAbund,
            'abundance': self.AbundanceName
        }