Esempio n. 1
0
 def planet_J2000_geo_to_topo(self, gra, gdec, dist, radi, dut1, longitude, latitude, height):
     jd_utc = self.calc_jd_utc()
     date = jd_utc - 2400000.5 + dut1 / (24. * 3600.)
     jd = jd_utc - 2400000.5 + (self.tai_utc + 32.184) / (24. * 3600.) # reference => http://www.cv.nrao.edu/~rfisher/Ephemerides/times.html
     
     # Spherical to x,y,z 
     v = slalib.sla_dcs2c(gra, gdec)
     for i in range (3):
         v[i] *= dist
     
     # Precession to date. 
     rmat = slalib.sla_prec(2000.0, slalib.sla_epj(jd))
     vgp = slalib.sla_dmxv(rmat, v)
     
     # Geocenter to observer (date). 
     stl = slalib.sla_gmst(date) + longitude
     vgo = slalib.sla_pvobs(latitude, height, stl)
     
     # Observer to planet (date). 
     for i in range (3):
         v[i] = vgp[i] - vgo[i]
     
     disttmp = dist
     dist = math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2])
     radi *= disttmp / dist
     
     # Precession to J2000 
     rmat = slalib.sla_prec(slalib.sla_epj(jd), 2000.)
     vgp = slalib.sla_dmxv(rmat, v)
     
     # To RA,Dec. 
     ret = slalib.sla_dcc2s(vgp)
     tra = slalib.sla_dranrm(ret[0])
     tdec = ret[1]
     return [dist, radi, tra, tdec]
Esempio n. 2
0
 def calc_planet_coordJ2000(self, ntarg):
     err_code = i = nctr = 3
     c = 2.99792e8
     k_to_au = 6.68459e-9
     
     jd_utc = self.calc_jd_utc()
     jd = jd_utc + (self.tai_utc + 32.184) / (24. * 3600.)  # Convert UTC to Dynamical Time
     if ntarg != 10:
         if ntarg == 11: #for Sun
             n_ntarg = 10
         else:
             n_ntarg = ntarg
         position = self.jpl[0, n_ntarg].compute(jd) # compute planet Barycenter
         position -= self.jpl[0, 3].compute(jd) # compute Earth Barycenter
         position -= self.jpl[3, 399].compute(jd) # compute Earth position
         dist = math.sqrt(position[0] ** 2 + position[1] ** 2 + position[2] ** 2) # [km]
         
         position_1 = self.jpl[0, 3].compute(jd) #Earth position at jd
         position_2 = self.jpl[0, n_ntarg].compute(jd - (dist / c) / (24. * 3600.)) # Target position when the light left
         position = position_2 - position_1
         position -= self.jpl[3, 399].compute(jd)
         dist = math.sqrt(position[0] ** 2 + position[1] ** 2 + position[2] ** 2)
     else: #for Moon
         position = self.jpl[3, 301].compute(jd)
         dist = math.sqrt(position[0] ** 2 + position[1] ** 2 + position[2] ** 2) # [km]
         
         position = self.jpl[3,301].compute(jd - (dist / c) / (24 * 3600.0))
         dist = math.sqrt(position[0] ** 2 + position[1] ** 2 + position[2] ** 2)
     ret = slalib.sla_dcc2s(position)
     ra = ret[0] # radian
     dec = ret[1] # radian
     ra = slalib.sla_dranrm(ra)
     radi = math.asin(self.eqrau[ntarg] / dist)
     dist = dist*k_to_au
     return [ra, dec, dist, radi]
Esempio n. 3
0
def radec_to_azza(ra, dec, MJD, fctr=350.0, atm=1010.0, temp=283.0, humid=0.5, scope='GBT'):
    """
    redec_to_azza(ra, dec, MJD):
        Return AZ and ZA (in deg) from RA and DEC (J2000 in deg) at MJD.  Keyword params
           are fctr=350.0, atm=1010.0, temp=283.0, humid=0.5, scope='GBT'.
    """
    scope, x, lon, lat, hgt = s.sla_obs(0, scope)
    microns = 3e8/(fctr*1e6)*1e6
    app_rarad, app_decrad = s.sla_map(ra*DEGTORAD,dec*DEGTORAD,0.0,0.0,0.0,0.0,2000.0,MJD)
    az, za, hob, rob, dob  = s.sla_aop(app_rarad,app_decrad,MJD,
                                       0.0,-lon,lat,hgt,0.0,0.0,temp,atm,humid,microns,0.0065)
    az = s.sla_dranrm(az)
    return az*RADTODEG, za*RADTODEG
Esempio n. 4
0
    def calc_planet_coordJ2000(self, ntarg):
        err_code = i = nctr = 3
        c = 2.99792e8
        k_to_au = 6.68459e-9

        jd_utc = self.calc_jd_utc()
        jd = jd_utc + (self.tai_utc + 32.184) / (
            24. * 3600.)  # Convert UTC to Dynamical Time
        if ntarg != 10:
            if ntarg == 11:  #for Sun
                n_ntarg = 10
            else:
                n_ntarg = ntarg
            position = self.jpl[0, n_ntarg].compute(
                jd)  # compute planet Barycenter
            position -= self.jpl[0, 3].compute(jd)  # compute Earth Barycenter
            position -= self.jpl[3, 399].compute(jd)  # compute Earth position
            dist = math.sqrt(position[0]**2 + position[1]**2 +
                             position[2]**2)  # [km]

            position_1 = self.jpl[0, 3].compute(jd)  #Earth position at jd
            position_2 = self.jpl[0, n_ntarg].compute(
                jd - (dist / c) /
                (24. * 3600.))  # Target position when the light left
            position = position_2 - position_1
            position -= self.jpl[3, 399].compute(jd)
            dist = math.sqrt(position[0]**2 + position[1]**2 + position[2]**2)
        else:  #for Moon
            position = self.jpl[3, 301].compute(jd)
            dist = math.sqrt(position[0]**2 + position[1]**2 +
                             position[2]**2)  # [km]

            position = self.jpl[3,
                                301].compute(jd - (dist / c) / (24 * 3600.0))
            dist = math.sqrt(position[0]**2 + position[1]**2 + position[2]**2)
        ret = slalib.sla_dcc2s(position)
        ra = ret[0]  # radian
        dec = ret[1]  # radian
        ra = slalib.sla_dranrm(ra)
        radi = math.asin(self.eqrau[ntarg] / dist)
        dist = dist * k_to_au
        return [ra, dec, dist, radi]
Esempio n. 5
0
def radec_to_azza(ra,
                  dec,
                  MJD,
                  fctr=350.0,
                  atm=1010.0,
                  temp=283.0,
                  humid=0.5,
                  scope='GBT'):
    """
    redec_to_azza(ra, dec, MJD):
        Return AZ and ZA (in deg) from RA and DEC (J2000 in deg) at MJD.  Keyword params
           are fctr=350.0, atm=1010.0, temp=283.0, humid=0.5, scope='GBT'.
    """
    scope, x, lon, lat, hgt = s.sla_obs(0, scope)
    microns = 3e8 / (fctr * 1e6) * 1e6
    app_rarad, app_decrad = s.sla_map(ra * DEGTORAD, dec * DEGTORAD, 0.0, 0.0,
                                      0.0, 0.0, 2000.0, MJD)
    az, za, hob, rob, dob = s.sla_aop(app_rarad, app_decrad, MJD, 0.0, -lon,
                                      lat, hgt, 0.0, 0.0, temp, atm, humid,
                                      microns, 0.0065)
    az = s.sla_dranrm(az)
    return az * RADTODEG, za * RADTODEG
Esempio n. 6
0
    def planet_J2000_geo_to_topo(self, gra, gdec, dist, radi, dut1, longitude,
                                 latitude, height):
        jd_utc = self.calc_jd_utc()
        date = jd_utc - 2400000.5 + dut1 / (24. * 3600.)
        jd = jd_utc - 2400000.5 + (self.tai_utc + 32.184) / (
            24. * 3600.
        )  # reference => http://www.cv.nrao.edu/~rfisher/Ephemerides/times.html

        # Spherical to x,y,z
        v = slalib.sla_dcs2c(gra, gdec)
        for i in range(3):
            v[i] *= dist

        # Precession to date.
        rmat = slalib.sla_prec(2000.0, slalib.sla_epj(jd))
        vgp = slalib.sla_dmxv(rmat, v)

        # Geocenter to observer (date).
        stl = slalib.sla_gmst(date) + longitude
        vgo = slalib.sla_pvobs(latitude, height, stl)

        # Observer to planet (date).
        for i in range(3):
            v[i] = vgp[i] - vgo[i]

        disttmp = dist
        dist = math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2])
        radi *= disttmp / dist

        # Precession to J2000
        rmat = slalib.sla_prec(slalib.sla_epj(jd), 2000.)
        vgp = slalib.sla_dmxv(rmat, v)

        # To RA,Dec.
        ret = slalib.sla_dcc2s(vgp)
        tra = slalib.sla_dranrm(ret[0])
        tdec = ret[1]
        return [dist, radi, tra, tdec]
Esempio n. 7
0
def datetime2st(d, obsvr_long=0.0):
    """Converts the passed datetime object in UTC to a Sidereal Time.
    If the site longitude [obsvr_long] (East +ve; radians) is passed, then
    the returned `stl` will be the Local Apparent Sidereal Time.
    If not passed (or zero), then the Greenwich Apparent Sidereal Time
    will be returned (Greenwich Mean Sidereal Time (GMST) plus the equation
    of the equinoxes.
    `stl`, the sidereal time, is returned in radians, normalized to the
    range 0...2*PI
    """

    # Compute MJD_UTC and MJD_TT
    mjd_utc = datetime2mjd_utc(d)
    mjd_tt = mjd_utc2mjd_tt(mjd_utc)
    # Determine UT1-UTC and hence MJD_UT1
    dut = ut1_minus_utc(mjd_utc)
    mjd_ut1 = mjd_utc + (dut / 86400.0)
    # Greenwich Mean Sidereal Time (GMST), just a function of UT1 ("Earth Rotation Angle")
    gmst = S.sla_gmst(mjd_ut1)
    # Compute Local Apparent Sidereal Time
    stl = gmst + obsvr_long + S.sla_eqeqx(mjd_tt)
    stl = S.sla_dranrm(stl)

    return stl
Esempio n. 8
0
    def handle(self, *args, **options):

        # Suppress incorrect FITSFixedWarnings
        warnings.simplefilter('ignore', FITSFixedWarning)
        self.stdout.write("==== Light curve building %s ====" % (datetime.now().strftime('%Y-%m-%d %H:%M')))

        try:
            start_super_block = SuperBlock.objects.get(tracking_number=options['supblock'])
        except SuperBlock.DoesNotExist:
            self.stdout.write("Cannot find SuperBlock with Tracking Number %d" % options['supblock'])
            exit(-1)
        start_blocks = Block.objects.filter(superblock=start_super_block.id)
        start_block = start_blocks[0]
        if options['single'] is True:
            super_blocks = [start_super_block, ]
        else:
            super_blocks = SuperBlock.objects.filter(body=start_super_block.body, block_start__gte=start_super_block.block_start-timedelta(days=options['timespan']))
        obs_date = None
        if options['date']:
            if isinstance(options['date'], str):
                try:
                    obs_date = datetime.strptime(options['date'], '%Y%m%d')
                except ValueError:
                    raise CommandError(usage)
            else:
                obs_date = options['date']

        # Initialize lists
        times = []
        alltimes = []
        mags = []
        mag_errs = []
        zps = []
        zp_errs = []
        mpc_lines = []
        psv_lines = []
        total_frame_count = 0
        mpc_site = []
        fwhm = []
        air_mass = []
        output_file_list = []

        # build directory path / set permissions
        obj_name = sanitize_object_name(start_super_block.body.current_name())
        datadir = os.path.join(options['datadir'], obj_name)
        out_path = settings.DATA_ROOT
        data_path = ''
        rw_permissions = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH
        if not os.path.exists(datadir) and not settings.USE_S3:
            try:
                os.makedirs(datadir)
                # Set directory permissions correctly for shared directories
                # Sets to (r)ead,(w)rite,e(x)ecute for owner & group, r-x for others
                os.chmod(datadir, stat.S_IRWXU | stat.S_IRWXG | stat.S_IROTH | stat.S_IXOTH)
            except:
                msg = "Error creating output path %s" % datadir
                raise CommandError(msg)
        sb_day = start_super_block.block_start.strftime("%Y%m%d")

        # Turn telescope class into a diameter for theoretical FWHM curve
        tel_classes = start_super_block.get_telclass()
        if len(tel_classes.split(",")) > 1:
            self.stdout.write("Multiple telescope sizes found; theoretical FWHM curve will be wrong")
            tel_class = tel_classes.split(",")[0]
        else:
            tel_class = tel_classes
        try:
            tel_diameter = float(tel_class.replace('m', '.'))
            tel_diameter *= u.m
        except ValueError:
            self.stdout.write("Error determining telescope diameter, assuming 0.4m")
            tel_diameter = 0.4*u.m

        # Set offsets, convert from Arcsec to Radians
        ra_offset = radians(options['ra_offset'] / 3600)
        dec_offset = radians(options['dec_offset'] / 3600)
        for super_block in super_blocks:
            # Create, name, open ALCDEF file.
            if obs_date:
                alcdef_date = options['date']
            else:
                alcdef_date = super_block.block_start.strftime("%Y%m%d")
            base_name = '{}_{}_{}_{}_'.format(obj_name, super_block.get_sites().replace(',', ''), alcdef_date, super_block.tracking_number)
            alcdef_filename = base_name + 'ALCDEF.txt'
            output_file_list.append('{},{}'.format(alcdef_filename, datadir.lstrip(out_path)))
            alcdef_txt = ''
            block_list = Block.objects.filter(superblock=super_block.id)
            if obs_date:
                block_list = block_list.filter(when_observed__lt=obs_date+timedelta(days=2)).filter(when_observed__gt=obs_date)
            self.stdout.write("Analyzing SuperblockBlock# %s for %s" % (super_block.tracking_number, super_block.body.current_name()))
            for block in block_list:
                block_mags = []
                block_mag_errs = []
                block_times = []
                outmag = "NONE"
                self.stdout.write("Analyzing Block# %d" % block.id)

                obs_site = block.site
                # Get all Useful frames from each block
                frames_red = Frame.objects.filter(block=block.id, frametype__in=[Frame.BANZAI_RED_FRAMETYPE]).order_by('filter', 'midpoint')
                frames_ql = Frame.objects.filter(block=block.id, frametype__in=[Frame.BANZAI_QL_FRAMETYPE]).order_by('filter', 'midpoint')
                if len(frames_red) >= len(frames_ql):
                    frames_all_zp = frames_red
                else:
                    frames_all_zp = frames_ql
                frames = frames_all_zp.filter(zeropoint__isnull=False)
                self.stdout.write("Found %d frames (of %d total) for Block# %d with good ZPs" % (frames.count(), frames_all_zp.count(), block.id))
                self.stdout.write("Searching within %.1f arcseconds and +/-%.2f delta magnitudes" % (options['boxwidth'], options['deltamag']))
                total_frame_count += frames.count()
                frame_data = []
                if frames_all_zp.count() != 0:
                    elements = model_to_dict(block.body)
                    filter_list = []

                    for frame in frames_all_zp:
                        # get predicted position and magnitude of target during time of each frame
                        emp_line = compute_ephem(frame.midpoint, elements, frame.sitecode)
                        ra = S.sla_dranrm(emp_line['ra'] + ra_offset)
                        dec = copysign(S.sla_drange(emp_line['dec'] + dec_offset), emp_line['dec'] + dec_offset)
                        mag_estimate = emp_line['mag']
                        (ra_string, dec_string) = radec2strings(ra, dec, ' ')
                        # Find list of frame sources within search region of predicted coordinates
                        sources = search_box(frame, ra, dec, options['boxwidth'])
                        midpoint_string = frame.midpoint.strftime('%Y-%m-%d %H:%M:%S')
                        self.stdout.write("%s %s %s V=%.1f %s (%d) %s" % (midpoint_string, ra_string, dec_string, mag_estimate, frame.sitecode, len(sources), frame.filename))
                        best_source = None
                        # Find source most likely to be target (Could Use Some Work)
                        if len(sources) != 0 and frame.zeropoint is not None:
                            if len(sources) == 1:
                                best_source = sources[0]
                            elif len(sources) > 1:  # If more than 1 source, pick closest within deltamag
                                min_sep = options['boxwidth'] * options['boxwidth']
                                for source in sources:
                                    sep = S.sla_dsep(ra, dec, radians(source.obs_ra), radians(source.obs_dec))
                                    sep = degrees(sep) * 3600.0
                                    src_ra_string, src_dec_string = radec2strings(radians(source.obs_ra), radians(source.obs_dec))
                                    if len(block_mags) > 0:
                                        delta_mag = abs(block_mags[-1] - source.obs_mag)
                                    else:
                                        delta_mag = abs(mag_estimate - source.obs_mag)
                                    self.stdout.write("%s %s %s %s %.1f %.1f-%.1f %.1f" % ( ra_string, dec_string, src_ra_string, src_dec_string, sep, mag_estimate, source.obs_mag, delta_mag))
                                    if sep < min_sep and delta_mag <= options['deltamag']:
                                        min_sep = sep
                                        best_source = source

                            # Save target source and add to output files.
                            if best_source and best_source.obs_mag > 0.0 and abs(mag_estimate - best_source.obs_mag) <= 3 * options['deltamag']:
                                block_times.append(frame.midpoint)
                                mpc_line, psv_line = self.make_source_measurement(block.body, frame, best_source, persist=options['persist'])
                                mpc_lines.append(mpc_line)
                                psv_lines.append(psv_line)
                                block_mags.append(best_source.obs_mag)
                                block_mag_errs.append(best_source.err_obs_mag)
                                filter_list.append(frame.ALCDEF_filter_format())

                        # We append these even if we don't have a matching source or zeropoint
                        # so we can plot conditions for all frames
                        zps.append(frame.zeropoint)
                        zp_errs.append(frame.zeropoint_err)
                        frame_data.append({'ra': ra,
                                           'dec': dec,
                                           'mag': mag_estimate,
                                           'bw': options['boxwidth'],
                                           'dm': options['deltamag'],
                                           'best_source': best_source})
                        alltimes.append(frame.midpoint)
                        fwhm.append(frame.fwhm)
                        azimuth, altitude = moon_alt_az(frame.midpoint, ra, dec, *get_sitepos(frame.sitecode)[1:])
                        zenith_distance = radians(90) - altitude
                        air_mass.append(S.sla_airmas(zenith_distance))
                        obs_site = frame.sitecode
                        catalog = frame.photometric_catalog
                        if catalog == 'GAIA-DR2':
                            outmag = 'GG'
                        elif catalog == 'UCAC4':
                            outmag = 'SR'
                        if obs_site not in mpc_site:
                            mpc_site.append(obs_site)
                    if len(block_times) > 1:
                        filter_set = list(set(filter_list))
                        for filt in filter_set:
                            mag_set = [m for m, f in zip(block_mags, filter_list) if f == filt]
                            time_set = [t for t, f in zip(block_times, filter_list) if f == filt]
                            error_set = [e for e, f in zip(block_mag_errs, filter_list) if f == filt]
                            alcdef_txt += self.output_alcdef(block, obs_site, time_set, mag_set, error_set, filt, outmag)
                    mags += block_mags
                    mag_errs += block_mag_errs
                    times += block_times

                    # Create gif of fits files used for LC extraction
                    data_path = make_data_dir(out_path, model_to_dict(frames_all_zp[0]))
                    frames_list = [os.path.join(data_path, f.filename) for f in frames_all_zp]
                    if not options['nogif']:
                        movie_file = make_gif(frames_list, sort=False, init_fr=100, center=3, out_path=data_path, plot_source=True,
                                              target_data=frame_data, show_reticle=True, progress=True)
                        if "WARNING" not in movie_file:
                            # Add write permissions to movie file
                            try:
                                os.chmod(movie_file, rw_permissions)
                            except PermissionError:
                                pass
                            # Create DataProduct
                            save_dataproduct(obj=block, filepath=movie_file, filetype=DataProduct.FRAME_GIF, force=options['overwrite'])
                            output_file_list.append('{},{}'.format(movie_file, data_path.lstrip(out_path)))
                            self.stdout.write("New gif created: {}".format(movie_file))
                        else:
                            self.stdout.write(movie_file)
            save_dataproduct(obj=super_block, filepath=None, filetype=DataProduct.ALCDEF_TXT, filename=alcdef_filename, content=alcdef_txt, force=options['overwrite'])
            self.stdout.write("Found matches in %d of %d frames" % (len(times), total_frame_count))

        if not settings.USE_S3:

            # Write light curve data out in similar format to Make_lc.csh
            i = 0

            lightcurve_file = open(os.path.join(datadir, base_name + 'lightcurve_data.txt'), 'w')
            mpc_file = open(os.path.join(datadir, base_name + 'mpc_positions.txt'), 'w')
            psv_file = open(os.path.join(datadir, base_name + 'ades_positions.psv'), 'w')
            output_file_list.append('{},{}'.format(os.path.join(datadir, base_name + 'lightcurve_data.txt'), datadir.lstrip(out_path)))
            output_file_list.append('{},{}'.format(os.path.join(datadir, base_name + 'mpc_positions.txt'), datadir.lstrip(out_path)))
            output_file_list.append('{},{}'.format(os.path.join(datadir, base_name + 'ades_positions.psv'), datadir.lstrip(out_path)))

            # Calculate integer part of JD for first frame and use this as a
            # constant in case of wrapover to the next day
            if len(times) > 0 and len(mags) > 0:
                mjd_offset = int(datetime2mjd_utc(times[0]))
                for time in times:
                    time_jd = datetime2mjd_utc(time)
                    time_jd_truncated = time_jd - mjd_offset
                    if i == 0:
                        lightcurve_file.write('#Object: %s\n' % start_super_block.body.current_name())
                        lightcurve_file.write("#MJD-%.1f Mag. Mag. error\n" % mjd_offset)
                    lightcurve_file.write("%7.5lf %6.3lf %5.3lf\n" % (time_jd_truncated, mags[i], mag_errs[i]))
                    i += 1
                lightcurve_file.close()
                try:
                    os.chmod(os.path.join(datadir, base_name + 'lightcurve_data.txt'), rw_permissions)
                except PermissionError:
                    pass

                # Write out MPC1992 80 column file
                for mpc_line in mpc_lines:
                    mpc_file.write(mpc_line + '\n')
                mpc_file.close()
                try:
                    os.chmod(os.path.join(datadir, base_name + 'mpc_positions.txt'), rw_permissions)
                except PermissionError:
                    pass

                # Write out ADES Pipe Separated Value file
                for psv_line in psv_lines:
                    psv_file.write(psv_line + '\n')
                psv_file.close()
                try:
                    os.chmod(os.path.join(datadir, base_name + 'ades_positions.psv'), rw_permissions)
                except PermissionError:
                    pass

                # Create Default Plot Title
                if options['title'] is None:
                    sites = ', '.join(mpc_site)
                    try:
                        # for single dates and short site lists, put everything on single line.
                        if options['timespan'] < 1 and len(sites) <= 13:
                            plot_title = '%s from %s (%s) on %s' % (start_super_block.body.current_name(),
                                                                    start_block.site.upper(), sites, start_super_block.block_end.strftime("%Y-%m-%d"))
                            subtitle = ''
                        # for lc covering multiple nights, reformat title
                        elif options['timespan'] < 1:
                            plot_title = '%s from %s to %s' % (start_block.body.current_name(),
                                                               (start_super_block.block_end - timedelta(
                                                                   days=options['timespan'])).strftime("%Y-%m-%d"),
                                                               start_super_block.block_end.strftime("%Y-%m-%d"))
                            subtitle = 'Sites: ' + sites
                        # for single night LC using many sites, put sites on 2nd line.
                        else:
                            plot_title = '%s from %s on %s' % (start_super_block.body.current_name(),
                                                               start_block.site.upper(),
                                                               start_super_block.block_end.strftime("%Y-%m-%d"))
                            subtitle = 'Sites: ' + sites
                    except TypeError:
                        plot_title = 'LC for %s' % (start_super_block.body.current_name())
                        subtitle = ''
                else:
                    plot_title = options['title']
                    subtitle = ''

                # Make plots
                if not settings.USE_S3:
                    self.plot_timeseries(times, alltimes, mags, mag_errs, zps, zp_errs, fwhm, air_mass, title=plot_title, sub_title=subtitle, datadir=datadir, filename=base_name, diameter=tel_diameter)
                    output_file_list.append('{},{}'.format(os.path.join(datadir, base_name + 'lightcurve_cond.png'), datadir.lstrip(out_path)))
                    output_file_list.append('{},{}'.format(os.path.join(datadir, base_name + 'lightcurve.png'), datadir.lstrip(out_path)))
                    try:
                        os.chmod(os.path.join(datadir, base_name + 'lightcurve_cond.png'), rw_permissions)
                    except PermissionError:
                        pass
                    try:
                        os.chmod(os.path.join(datadir, base_name + 'lightcurve.png'), rw_permissions)
                    except PermissionError:
                        pass
                else:
                    self.stdout.write("No sources matched.")

                if data_path:
                    with open(os.path.join(data_path, base_name + 'lc_file_list.txt'), 'w') as outfut_file_file:
                        outfut_file_file.write('# == Files created by Lightcurve Extraction for {} on {} ==\n'.format(obj_name, sb_day))
                        for output_file in output_file_list:
                            outfut_file_file.write(output_file)
                            outfut_file_file.write('\n')
                    self.stdout.write(f"New lc file list created: {os.path.join(data_path, base_name + 'lc_file_list.txt')}")
                    try:
                        os.chmod(os.path.join(data_path, base_name + 'lc_file_list.txt'), rw_permissions)
                    except PermissionError:
                        pass