Ejemplo n.º 1
0
temperatures = 10**np.linspace(5.7, 7.1, num=nt + 1)
logtemps = np.linspace(5.7, 7.1, num=nt + 1)
tresp = read_csv('tresp.csv').to_numpy()
# print(tresp_logt.keys())
# data=np.ones([nx,ny,nf])
# edata=np.ones([nx,ny,nf])/10
# dem_norm=np.ones([nx,ny,nt])
data = np.array([3.4, 13.8, 184, 338, 219.55, 12.22])
edata = np.array([0.2, 0.43, 7.83, 12.9, 5.80, 0.23])
dem_norm = np.array([
    0.082588151, 0.18005607, 0.30832890, 0.47582966, 0.66201794, 0.83059740,
    0.93994260, 0.95951378, 0.88358527, 0.73393929, 0.54981130, 0.37136465,
    0.22609001, 0.11025056
])

correction_table = get_correction_table()
wavenum = ['94', '131', '171', '193', '211', '335']
channels = []
for i in np.arange(len(wavenum)):
    channels.append(float(wavenum[i]) * u.angstrom)

time_calibration = time.Time('2014-01-01T00:00:00', scale='utc')

time_test = time.Time('2014-01-01T00:00:00', scale='utc')

# deg_calibration = {}
deg_calibration = np.zeros([len(channels)])
# deg = {}
deg = np.zeros([len(channels)])

for i, c in enumerate(channels):
Ejemplo n.º 2
0
 def __init__(self, do_deconv=False, do_degrad=True):
     self.do_deconv = do_deconv
     self.do_degrad = do_degrad
     if self.do_degrad :
         self.correction_table = get_correction_table()
Ejemplo n.º 3
0
def create_iron18(dir_094=None,
                  dir_171=None,
                  dir_211=None,
                  outdir=None,
                  tr_degradation_corr=[True, '2018-09-09T12:00:00'],
                  needing_prepped=False):
    """Takes the 94, 171, 211 channels from SDO/AIA to create an iron18 emission proxy (Del Zanna 2013).
    
    Parameters
    ----------
    dir_*** : str
            The string of the directory with the 94A (dir_094), 171A (dir_171), and 211A (dir_211) files.
            Default: None
            
    outdir : str
            Directory for the output iron18 files.
            Default: None

    tr_degradation_corr : list [bool, str]
            Do you want the iron18 to be created where 94, 171, 211  have been corrected for the instrument degredation?
            Also provide a time for the data-set of the form "YYYY-MM-DDTHH:mm:ss".
            (This should always really be True with the right time.)
            Default: [True, '2018-09-09T12:00:00']

    needing_prepped : bool
            Is the AIA data in dir_*** needing prepped?
            Default: False
            
    Returns
    -------
    Filenames of the iron 18 files.
    """

    files_094_list = list(os.listdir(dir_094))
    files_094 = []
    files_094 = [f for f in files_094_list if f.endswith('.fits')]
    files_094.sort()

    files_171_list = list(os.listdir(dir_171))
    files_171 = []
    files_171 = [f for f in files_171_list if f.endswith('.fits')]
    files_171.sort()

    files_211_list = list(os.listdir(dir_211))
    files_211 = []
    files_211 = [f for f in files_211_list if f.endswith('.fits')]
    files_211.sort()

    degs = [1, 1, 1]
    if tr_degradation_corr[0] is True:
        import warnings
        warnings.simplefilter('ignore')
        from aiapy.calibrate import degradation
        from aiapy.calibrate.util import get_correction_table, CALIBRATION_VERSION
        import astropy.units as u
        from astropy import time

        correction_table = get_correction_table()
        time_obs = time.Time(tr_degradation_corr[1], scale='utc')
        channels = [94, 171, 211] * u.angstrom
        for i in range(3):
            deg = degradation(channels[i],
                              time_obs,
                              correction_table=correction_table)
            degs[i] = deg.value

    co_094 = []
    co_171 = []
    co_211 = []

    output = []

    for fn094 in files_094:
        if needing_prepped:
            time_094 = data_handling.getTimeFromFormat(
                fn094[-39:-20], custom_fmt='%Y_%m_%dt%H_%M_%S')
        else:
            time_094 = data_handling.getTimeFromFormat(
                fn094[3:18]
            )  #datetime.datetime.strptime(fn094[3:18], '%Y%m%d_%H%M%S')

        for fn171 in files_171:
            if needing_prepped:
                time_171 = data_handling.getTimeFromFormat(
                    fn171[-39:-20], custom_fmt='%Y_%m_%dt%H_%M_%S')
            else:
                time_171 = data_handling.getTimeFromFormat(
                    fn171[3:18]
                )  #datetime.datetime.strptime(fn171[3:18], '%Y%m%d_%H%M%S')

            if time_094 <= time_171 < time_094 + timedelta(seconds=12):

                for fn211 in files_211:
                    if needing_prepped:
                        time_211 = data_handling.getTimeFromFormat(
                            fn211[-39:-20], custom_fmt='%Y_%m_%dt%H_%M_%S')
                    else:
                        time_211 = data_handling.getTimeFromFormat(
                            fn211[3:18]
                        )  #datetime.datetime.strptime(fn211[3:18], '%Y%m%d_%H%M%S')

                    if time_094 <= time_211 < time_094 + timedelta(seconds=12):
                        co_094.append(fn094)
                        co_171.append(fn171)
                        co_211.append(fn211)
                        break
                break
    files_094 = co_094
    files_171 = co_171
    files_211 = co_211

    d = 1
    d_total = len(files_094)
    for f094, f171, f211 in zip(files_094, files_171, files_211):
        aia_map_094 = sunpy.map.Map(dir_094 + f094)

        if needing_prepped:
            aia_map_094 = prep(aia_map_094)

        data_094 = aia_map_094.data / aia_map_094.meta['exptime']
        data_094[data_094 < 0] = 0

        aia_map_171 = sunpy.map.Map(dir_171 + f171)

        if needing_prepped:
            aia_map_171 = prep(aia_map_171)

        data_171 = aia_map_171.data / aia_map_171.meta['exptime']
        data_171[data_171 < 0] = 0

        aia_map_211 = sunpy.map.Map(dir_211 + f211)

        if needing_prepped:
            aia_map_211 = prep(aia_map_211)

        data_211 = aia_map_211.data / aia_map_211.meta['exptime']
        data_211[data_211 < 0] = 0

        Iron_18 = data_094 / degs[0] - data_211 / (
            120 * degs[2]) - data_171 / (450 * degs[1])
        Iron_18[Iron_18 < 0] = 0
        aia_map_Fe18 = sunpy.map.Map(Iron_18, aia_map_094.meta)

        del aia_map_094
        del aia_map_171
        del aia_map_211

        file = fits.open(dir_094 + f094)
        hdr = file[0].header
        file.close()

        primary_hdu = fits.PrimaryHDU(data=Iron_18, header=hdr)

        hdul = fits.HDUList([primary_hdu])

        if needing_prepped:
            f094 = "AIA" + f094[-39:-35] + f094[-34:-32] + f094[
                -31:-29] + "_" + f094[-28:-26] + f094[-25:-23] + f094[
                    -22:-20] + "_0094.fits"

        hdul.writeto(outdir + f094[:18] + '_FeXVIII.fits', overwrite=True)
        #names the file as 'AIAYYYYMMDD_HHmmss_FeXVIII.fits'

        #change header info
        fits.setval(outdir + f094[:18] + '_FeXVIII.fits',
                    'pixlunit',
                    value='DN/s')
        fits.setval(outdir + f094[:18] + '_FeXVIII.fits', 'exptime', value=1)
        #add in info that this is iron 18 apart from just the filename
        fits.setval(outdir + f094[:18] + '_FeXVIII.fits',
                    'iron_channel',
                    value='iron18')
        fits.setval(outdir + f094[:18] + '_FeXVIII.fits',
                    'file094',
                    value=f094)
        fits.setval(outdir + f094[:18] + '_FeXVIII.fits',
                    'file171',
                    value=f171)
        fits.setval(outdir + f094[:18] + '_FeXVIII.fits',
                    'file211',
                    value=f211)

        if tr_degradation_corr[0] is True:
            fits.setval(outdir + f094[:18] + '_FeXVIII.fits',
                        'temp_resp_info',
                        value='atLaunch')
            deg_94_str, deg_171_str, deg_211_str, cal_ver_str = str(
                degs[0]), str(degs[1]), str(degs[2]), str(CALIBRATION_VERSION)
            fits.setval(outdir + f094[:18] + '_FeXVIII.fits',
                        'cal_ver',
                        value=cal_ver_str)
            fits.setval(outdir + f094[:18] + '_FeXVIII.fits',
                        'deg_94',
                        value=deg_94_str)
            fits.setval(outdir + f094[:18] + '_FeXVIII.fits',
                        'deg_171',
                        value=deg_171_str)
            fits.setval(outdir + f094[:18] + '_FeXVIII.fits',
                        'deg_211',
                        value=deg_211_str)

        output.append(f094[:18] + '_FeXVIII.fits')

        print(
            f'\r[function: {sys._getframe().f_code.co_name}] Saved {d} submap(s) of {d_total}.        ',
            end='')
        d += 1
    return output
Ejemplo n.º 4
0
def batch_dem_jp2(t_start,
                  cadence,
                  nobs,
                  fits_dir,
                  jp2_dir,
                  get_fits=0,
                  serr_per=10,
                  min_snr=2,
                  fe_min=2,
                  use_fe=False,
                  sat_lvl=1.5e4,
                  mk_jp2=False,
                  plot_out=False,
                  plot_loci=False,
                  mk_fits=False,
                  xp=370,
                  yp=750):
    """
    batch script for loading (or downloading) synoptic data from jsoc, setting up the AIA degradation and temperature response etc.
    running demregpy to produce 2-d DEM maps. Finally the code has optional very basic plotting routines and an optional call to
    dem2jp2 to make jpeg2000 greyscale, bytescaled 8 bit images for hv. 


    """
    version_number = 1.2
    contact_email = '*****@*****.**'
    location = 'University of Glasgow A+A'
    #we only want optically thin coronal wavelengths
    wavenum = ['94', '131', '171', '193', '211', '335']
    t_start = Time(t_start)
    print(t_start)
    for obs in np.arange(nobs):
        t_obs = (t_start + TimeDelta(obs * cadence, format='sec'))
        print(t_obs)
        t_obs.precision = 0
        #convert our string into a datetime object
        # t=dateutil.parser.parse(TimeString(t_obs))
        t = t_obs.to_datetime()

        #deconstruct the datetime object into a synoptica data filename
        file_str = [('AIA' + str(t.year).zfill(4) + str(t.month).zfill(2) +
                     str(t.day).zfill(2) + '_' + str(t.hour).zfill(2) +
                     str(t.minute).zfill(2) + '_' +
                     "{}".format(wave.zfill(4)) + '.fits')
                    for j, wave in enumerate(wavenum)]
        dir_str = str(t.year).zfill(4) + '/' + str(
            t.month).zfill(2) + '/' + str(t.day).zfill(2) + '/'
        syn_url = 'http://jsoc.stanford.edu/data/aia/synoptic/'
        nf = len(file_str)

        cklist = []

        for file in file_str:
            cklist.append(os.path.isfile(fits_dir + dir_str + file))
        if not os.path.isdir(fits_dir + dir_str):
            os.makedirs(fits_dir + dir_str)
        if not all(cklist):
            # not all the files exist.
            print('Downloading synoptic data')
            url = [(syn_url + dir_str + 'H' + str(t.hour).zfill(2) + '00' +
                    '/' + file_str[jj]) for jj, c in enumerate(file_str)]
            for jj, c in enumerate(file_str):
                # h = httplib2.Http()
                # open the webpage
                # resp = h.request(url[jj], 'HEAD')
                request = requests.get(url[jj])
                if request.status_code < 400:
                    # webpage exists so download
                    wget.download(url[jj], fits_dir + dir_str)
            cklist = []
            for file in file_str:
                # check for files again
                cklist.append(os.path.isfile(fits_dir + dir_str + file))
            if not all(cklist):
                #skipping this observation
                print('\n Missing synoptioc data for ' + str(t) +
                      '...Skipping to next...')

                continue

        #find the files in their directory
        fits_files = [
            fits_dir + dir_str + file_str[j] for j in np.arange(len(file_str))
        ]
        #load the fits with sunpy
        aia = Map(fits_files)
        if aia[0].meta['percentd'] < 95.0:
            #check if the percentage data > 95 otherwise skip next observation
            print('\n PERCENTAGE GOOD DATA BELOW THRESHOLD = ' +
                  str(aia[0].meta['percentd']) + ' at ' + str(t) +
                  '\n...Skipping to next...')
            dem = Dem()
            continue
        if aia[2].meta['datamax'] < 1e3:
            #check if the data is there, sometimes synoptic outputs maps of noise only if the observation not taken, we just threshold aia 171 at 1k DN
            print(
                '\n Image looks like noise, possibly broken synoptic maps? Datamax = '
                + str(aia[2].meta['datamax']) + ' at ' + str(t) +
                '\n...Skipping to next...')
            dem = Dem()
            continue
        correction_table = get_correction_table()
        # correction_table=get_correction_table('aia_V8_20171210_050627_response_table.txt')  #for use as a hardcoded response file
        cal_ver = 10
        #correct the images for degradation
        aia = [
            correct_degradation(m,
                                correction_table=correction_table,
                                calibration_version=cal_ver) for m in aia
        ]
        # aia = [update_pointing(m) for m in aia]

        channels = [aia[i].wavelength for i in range(nf)]

        nt = 32
        t_space = 0.05
        t_min = 5.6
        logtemps = np.linspace(t_min, t_min + t_space * nt, num=nt + 1)
        temperatures = 10**logtemps
        logt_bin = np.zeros(nt)
        for i in np.arange(nt):
            logt_bin[i] = (logtemps[i] + logtemps[i + 1]) / 2

        tren = io.readsav('aia_trespv9_en.dat')
        tresp_logt = tren.logt
        tresp_calibrated = np.zeros([tresp_logt.shape[0], nf + 1])
        tresp_calibrated[:, :-1] = tren.tr.T

        #initialise structure
        dem = Dem()
        dem.bitpix = 8
        nx = aia[0].meta['naxis1']
        ny = aia[0].meta['naxis2']
        dem.naxis1 = nx
        dem.naxis2 = ny
        dem.crota2 = 0
        dem.crval1 = aia[0].meta['crval1']
        dem.crval2 = aia[0].meta['crval2']
        dem.crpix1 = 512.5
        dem.crpix2 = 512.5
        dem.cdelt1 = aia[0].meta['cdelt1'] * 4.0
        dem.cdelt2 = aia[0].meta['cdelt2'] * 4.0
        dem.cunit1 = aia[0].meta['cunit1']
        dem.cunit2 = aia[0].meta['cunit2']
        dem.dsun_obs = aia[0].meta['dsun_obs']
        dem.crlt_obs = aia[0].meta['crlt_obs']
        dem.crln_obs = aia[0].meta['crln_obs']
        dem.hglt_obs = B0(t_obs).value
        dem.hgln_obs = 0
        dem.temperatures = temperatures
        dem.minTemp = logtemps[0]
        dem.maxTemp = logtemps[-1]
        dem.t_obs = t_obs
        dem.filt_use = 6
        dem.rsun_ref = 6.957E+08
        dem.rsun_obs = angular_radius(t_obs).value
        dem.hv_zero = np.log10(dem.dem_min)
        dem.hv_scale = (np.log10(dem.dem_max) - np.log10(dem.dem_min)) / 255
        dem.contact = contact_email
        dem.produced = 'Produced at ' + location + ' on: ' + datetime.today(
        ).strftime('%Y-%m-%d')
        dem.dem_ver = version_number

        dem1 = Dem()
        dem1.bitpix = 8
        dem1.naxis1 = nx
        dem1.naxis2 = ny
        dem1.crota2 = aia[0].meta['crota2']
        dem1.crval1 = aia[0].meta['crval1']
        dem1.crval2 = aia[0].meta['crval2']
        dem1.crpix1 = 512.5
        dem1.crpix2 = 512.5
        dem1.cdelt1 = aia[0].meta['cdelt1'] * 4.0
        dem1.cdelt2 = aia[0].meta['cdelt2'] * 4.0
        dem1.cunit1 = aia[0].meta['cunit1']
        dem1.cunit2 = aia[0].meta['cunit2']
        dem1.dsun_obs = aia[0].meta['dsun_obs']
        dem1.crlt_obs = aia[0].meta['crlt_obs']
        dem1.crln_obs = aia[0].meta['crln_obs']
        dem1.hglt_obs = B0(t_obs).value
        dem1.hgln_obs = 0
        dem1.minTemp = logtemps[0]
        dem1.maxTemp = logtemps[-1]
        dem1.filt_use = 7
        dem1.rsun_ref = 6.957E+08
        dem1.rsun_obs = np.rad2deg(np.arctan2(dem1.rsun_ref,
                                              dem1.dsun_obs)) * 3600
        dem1.hv_zero = np.log10(dem1.dem_min)
        dem1.hv_scale = (np.log10(dem1.dem_max) - np.log10(dem1.dem_min)) / 255
        dem1.contact = contact_email
        dem1.produced = 'Produced at ' + location + ' on: ' + datetime.today(
        ).strftime('%Y-%m-%d')
        dem1.dem_ver = version_number

        data = np.zeros([nx, ny, nf + 1])

        #errors in dn/px
        npix = 4096.**2 / (nx * ny)
        edata = np.zeros([nx, ny, nf + 1])
        gains = np.array([18.3, 17.6, 17.7, 18.3, 18.3, 17.6])
        dn2ph = gains * [94, 131, 171, 193, 211, 335] / 3397.0
        rdnse = 1.15 * np.sqrt(npix) / npix
        drknse = 0.17
        qntnse = 0.288819 * np.sqrt(npix) / npix
        for f in range(nf):
            #convert from our list to an array of data
            data[:, :, f] = aia[f].data
            data[data < 0.0] = 0.0
        for j in np.arange(nf):
            shotnoise = (dn2ph[j] * data[:, :, j])**0.5 / dn2ph[j]
            esys = serr_per / 100.0 * data[:, :, j]
            etemp = np.sqrt(rdnse**2. + drknse**2. + qntnse**2. + shotnoise**2)
            edata[:, :, j] = np.sqrt(esys**2 + etemp**2)

        for f in range(nf):
            #convert to values per second
            data[:, :, f] = data[:, :, f] / aia[f].exposure_time.to(u.s).value
            edata[:, :,
                  f] = edata[:, :, f] / aia[f].exposure_time.to(u.s).value

        #calculate the hot component of aia 94
        a94_fe18 = np.zeros([nx, ny])
        a94_warm = np.zeros([nx, ny])
        a94_fe18[:, :] = data[:, :,
                              0] - data[:, :, 4] / 120.0 - data[:, :,
                                                                2] / 450.0
        a94_warm = data[:, :, 0] - a94_fe18[:, :]

        #threshold of fe_min for the hot component

        a94_fe18[a94_fe18 <= 0] = 0.0001
        a94_warm[a94_warm <= 0] = 0.0001
        data[:, :, 6] = a94_fe18

        #now we need fe18 temp response in a94
        trfe = (tresp_calibrated[:, 0] - tresp_calibrated[:, 4] / 120.0 -
                tresp_calibrated[:, 2] / 450.0)
        trfe[tresp_logt <= 6.4] = 1e-38
        #remove low peak

        tresp_calibrated[:, 6] = trfe + 1e-3 * tresp_calibrated[:, 0]
        #errors on fe18 are a little arbitary, percentage error and a flat of 2...
        edata[:, :, 6] = serr_per / 100 * data[:, :, 6] + 2.0
        plt.rcParams.update({'font.size': 10})
        # dem,edem,elogt,chisq,dn_reg=dn2dem_pos(data[x1:x2,y1:y2,:filt_use],edata[x1:x2,y1:y2,:filt_use],tresp_calibrated[:,:filt_use],tresp_logt,temperatures,dem_norm0=dem_norm0[x1:x2,y1:y2,:],max_iter=10)
        x1 = 0
        x2 = nx
        y1 = 0
        y2 = ny
        filt_use = 6
        norm_mean = 6.35
        norm_std = 0.35
        dem_norm0 = np.zeros([nx, ny, nt])
        dem_norm = gaussian(logt_bin, norm_mean, norm_std)
        dem_norm0[:, :, :] = dem_norm[:]
        dem1.data, dem1.edem, dem1.elogt, dem1.chisq, dem1.dn_reg = dn2dem_pos(
            data[x1:x2, y1:y2, :filt_use],
            edata[x1:x2, y1:y2, :filt_use],
            tresp_calibrated[:, :filt_use],
            tresp_logt,
            dem.temperatures,
            max_iter=15,
            dem_norm0=dem_norm0)

        if plot_out == True:
            aia_col = ['#c2c3c0', '#g0r0r0']
            fig = plt.figure(figsize=(8, 7))
            for j in range(int(nt / 2)):
                fig = plt.subplot(4, 4, j + 1)

                em_loci = data[xp, yp, :] / tresp_calibrated
                plt.errorbar(logt_bin,
                             dem1.data[xp, yp + j * 5, :],
                             color='c',
                             xerr=dem1.elogt[xp, yp + j * 5, :],
                             yerr=dem1.edem[xp, yp + j * 5, :],
                             fmt='or',
                             ecolor='gray',
                             elinewidth=3,
                             capsize=0)
                for i in range(7):
                    em_loci[:-1, i] = em_loci[:-1, i] / (10**tresp_logt[1:] -
                                                         10**tresp_logt[:-1])
                if plot_loci == True:
                    plt.plot(tresp_logt[:-1], em_loci[:-1, :6])
                ax = plt.gca()
                plt.ylim([1e19, 1e23])
                plt.xlim([5.7, 7.3])
                plt.xlabel('$\mathrm{\log_{10}T\;[K]}$')
                plt.ylabel('$\mathrm{DEM\;[cm^{-5}\;K^{-1}]}$')
                plt.yscale('log')
                ax.label_outer()
            plt.gcf().suptitle("6 Filter", fontsize=14)
            plt.gcf().tight_layout(pad=2.0)

            fig = plt.figure(figsize=(8, 7))
            for j in range(int(nt / 2)):
                fig = plt.subplot(4, 4, j + 1)
                plt.imshow(np.log10(dem1.data[:, :, 2 * j] + 1),
                           'inferno',
                           vmin=19,
                           vmax=24,
                           origin='lower')
                ax = plt.gca()
                ax.set_title('%.1f' % (t_min + 2 * j * 0.05))
            plt.gcf().suptitle("dem1", fontsize=14)

        if use_fe == True:
            filt_use = 7

        dem_norm0 = np.zeros([nx, ny, nt])
        mxdem = np.max(dem1.data)
        for ii in np.arange(nx):
            for jj in np.arange(ny):
                dem_norm0[ii,
                          jj, :] = (np.convolve(dem1.data[ii, jj, 1:-1],
                                                np.ones(5) / 5))[1:-1] / mxdem
        dem_norm0[dem_norm0 <= 1e-8] = 1e-8

        if plot_out == True:
            aia_col = ['#c2c3c0', '#g0r0r0']
            fig = plt.figure(figsize=(8, 7))
            for j in range(int(nt / 2)):
                fig = plt.subplot(4, 4, j + 1)

                em_loci = data[xp, yp, :] / tresp_calibrated
                plt.errorbar(logt_bin,
                             dem_norm0[xp, yp + j * 5, :] * mxdem,
                             color='c',
                             xerr=dem1.elogt[xp, yp + j * 5, :],
                             yerr=dem1.edem[xp, yp + j * 5, :],
                             fmt='or',
                             ecolor='gray',
                             elinewidth=3,
                             capsize=0)
                for i in range(7):
                    em_loci[:-1, i] = em_loci[:-1, i] / (10**tresp_logt[1:] -
                                                         10**tresp_logt[:-1])
                if plot_loci == True:
                    plt.plot(tresp_logt[:-1], em_loci[:-1, :6])
                ax = plt.gca()
                plt.ylim([1e19, 1e23])
                plt.xlim([5.7, 7.3])
                plt.xlabel('$\mathrm{\log_{10}T\;[K]}$')
                plt.ylabel('$\mathrm{DEM\;[cm^{-5}\;K^{-1}]}$')
                plt.yscale('log')
                ax.label_outer()
            plt.gcf().suptitle("DEM NORM", fontsize=14)
            plt.gcf().tight_layout(pad=2.0)

        if use_fe == True:
            data[a94_fe18 < fe_min, :] = 0
        dem.data, dem.edem, dem.elogt, dem.chisq, dem.dn_reg = dn2dem_pos(
            data[x1:x2, y1:y2, :filt_use],
            edata[x1:x2, y1:y2, :filt_use],
            tresp_calibrated[:, :filt_use],
            tresp_logt,
            temperatures,
            dem_norm0=dem_norm0[x1:x2, y1:y2, :],
            max_iter=15)
        if use_fe == True:
            dem.data[a94_fe18 < fe_min, :] = dem1.data[a94_fe18 < fe_min, :]
        dem.data[dem.data <= 0] = 1

        if plot_out == True:
            aia_col = ['#c2c3c0', '#g0r0r0']
            fig = plt.figure(figsize=(8, 7))
            for j in range(int(np.floor(nt / 2))):
                fig = plt.subplot(4, 4, j + 1)

                em_loci = data[xp, yp, :] / tresp_calibrated
                plt.errorbar(logt_bin,
                             dem.data[xp, yp + j * 5, :],
                             color='c',
                             xerr=dem.elogt[xp, yp + j * 5, :],
                             yerr=dem.edem[xp, yp + j * 5, :],
                             fmt='or',
                             ecolor='gray',
                             elinewidth=3,
                             capsize=0)
                for i in range(7):
                    em_loci[:-1, i] = em_loci[:-1, i] / (10**tresp_logt[1:] -
                                                         10**tresp_logt[:-1])
                if plot_loci == True:
                    plt.plot(tresp_logt[:-1], em_loci[:-1, :6])
                ax = plt.gca()
                plt.ylim([1e19, 1e23])
                plt.xlim([5.7, 7.3])
                plt.xlabel('$\mathrm{\log_{10}T\;[K]}$')
                plt.ylabel('$\mathrm{DEM\;[cm^{-5}\;K^{-1}]}$')
                plt.yscale('log')
                ax.label_outer()
            plt.gcf().suptitle("7", fontsize=14)
            plt.gcf().tight_layout(pad=2.0)

            fig = plt.figure(figsize=(8, 7))
            for j in range(int(nt / 2)):
                fig = plt.subplot(4, 4, j + 1)
                plt.imshow(np.log10(dem.data[:, :, j * 2] + 1),
                           'inferno',
                           vmin=19,
                           vmax=24,
                           origin='lower')
                ax = plt.gca()
                ax.set_title('%.1f' % (t_min + j * 2 * 0.05))
            plt.gcf().suptitle("7", fontsize=14)
            plt.gcf().tight_layout(pad=2.0)

        if plot_out == True:
            aia_col = ['#c2c3c0', '#g0r0r0']
            fig = plt.figure(figsize=(8, 7))
            for j in range(int(np.floor(nt / 2))):
                fig = plt.subplot(4, 4, j + 1)

                em_loci = data[xp, yp, :] / tresp_calibrated
                plt.errorbar(logt_bin,
                             dem.data[xp, yp + j * 5, :],
                             color='c',
                             xerr=dem.elogt[xp, yp + j * 5, :],
                             yerr=dem.edem[xp, yp + j * 5, :],
                             fmt='or',
                             ecolor='gray',
                             elinewidth=3,
                             capsize=0)
                for i in range(7):
                    em_loci[:-1, i] = em_loci[:-1, i] / (10**tresp_logt[1:] -
                                                         10**tresp_logt[:-1])
                if plot_loci == True:
                    plt.plot(tresp_logt[:-1], em_loci[:-1, :6])
                ax = plt.gca()
                plt.ylim([1e19, 1e23])
                plt.xlim([5.7, 7.3])
                plt.xlabel('$\mathrm{\log_{10}T\;[K]}$')
                plt.ylabel('$\mathrm{DEM\;[cm^{-5}\;K^{-1}]}$')
                plt.yscale('log')
                ax.label_outer()
            plt.gcf().suptitle("Combo", fontsize=14)
            plt.gcf().tight_layout(pad=2.0)

            fig = plt.figure(figsize=(8, 7))
            for j in range(int(nt / 2)):
                fig = plt.subplot(4, 4, j + 1)
                plt.imshow(np.log10(dem.data[:, :, j * 2] + 1),
                           'inferno',
                           vmin=19,
                           vmax=24,
                           origin='lower')
                ax = plt.gca()
                ax.set_title('%.1f' % (t_min + j * 2 * 0.05))
            plt.gcf().suptitle("Combo", fontsize=14)
            plt.gcf().tight_layout(pad=2.0)
            aia[0].peek()
            plt.show()
        dem.nimg = int(np.floor(nt / 4))
        if mk_jp2 == True:
            if not os.path.isdir(jp2_dir + dir_str):
                os.makedirs(jp2_dir + dir_str)
            for i in range(dem.nimg):
                img_data = (dem.data[:, :, i * 2] + dem.data[:, :, i * 2 + 1] +
                            dem.data[:, :, i * 2 + 2] +
                            dem.data[:, :, i * 2 + 3]) / 4
                jp2_fname = (str(t.year).zfill(4) + '_' +
                             str(t.month).zfill(2) + '_' +
                             str(t.day).zfill(2) + '__' +
                             str(t.hour).zfill(2) + '_' +
                             str(t.minute).zfill(2) + '_' +
                             str(t.second).zfill(2) + '_00' +
                             '__DEM_REGINV_T_' + '%.2f_%.2f' %
                             (logtemps[i * 4], logtemps[i * 4 + 4]))
                tmin = logtemps[i * 4]
                tmax = logtemps[(i + 1) * 4]
                print('writing ' + jp2_fname + ' img ' + str(i + 1) + ' of ' +
                      str(dem.nimg))
                dem2jp2(img_data,
                        dem,
                        jp2_dir + dir_str + jp2_fname,
                        i,
                        tmin,
                        tmax,
                        mk_fits=mk_fits)
    return dem