Example #1
0
    def determineCoordsFromImage(self, imageFileName):
        configFolder = self.ppl["CONFIG_FOLDER"]
        if configFolder == None:
            configFolder = "$HOME/.pmlib"
        SOLVE_ARGS = "-O --config " + configFolder + "/astrometry.cfg --use-sextractor --sextractor-path sextractor -r -y -p"

        makedirs("temp", exist_ok = True)

        invoke("cp " + imageFileName + " temp/src.fits")

        astFolder = self.ppl["AST_BIN_FOLDER"]
        if astFolder == None:
            astFolder = "/usr/local/astrometry/bin"

        astResult = invoke(astFolder + "/solve-field " + SOLVE_ARGS + " -D temp -N temp/ast.fits temp/src.fits")

        r = astResult.split('\n')
        coords = [0.0, 0.0]
        sCoordsSexa = ["00:00:00", "+00:00:00"]
        for line in r:
            if line.startswith("Field center"):
                if line.find("RA,Dec") > -1:
                    sCoords = self.getPair(line.split('(')[2].split(')')[0])
                    coords = [ float(sCoords[0]), float(sCoords[1]) ]
                    printInfo("Image center: %s %s" % (sCoords[0], sCoords[1]))
                else:
                    sCoordsSexa = self.getPair(line.split('(')[2].split(')')[0])
                    coords = [ hexa2deg(sCoordSexa[0]) * 15.0, hexa2deg(sCoordSexa[1]) ]
                    printInfo("Image center: %s %s" % (sCoordsSexa[0], sCoordsSexa[1]))
            elif line.startswith("Field size"):
                sFieldSize = self.getPair(line.split(':')[1].split('a')[0], 'x')
                printInfo("Image size: %s' x %s'" % (sFieldSize[0], sFieldSize[1]))

        return coords
Example #2
0
    def makeMasterBias(self, biasFolder, color):
        BIAS_PATTERN = "%s/%s*-%s.fits" % (
            biasFolder, self.pplSetup['BIAS_FILE_PREFIX'], color)
        BIASLIST = glob.glob(BIAS_PATTERN)
        BIASLIST.sort()

        masterBiasFile = "%s/%s-%s.fits" % (
            biasFolder, self.pplSetup['MASTER_BIAS_FILE'], color)

        if len(BIASLIST) == 0:
            return 1

        print("%s -> %s" % (BIAS_PATTERN, masterBiasFile))

        # Calibrated images: all the images have the same name but put into a separate directory ($TARGET):
        R_BIASLIST = list(
            map(lambda x: self.TEMPDIR + '/' + basename(x), BIASLIST))

        # The calibration of the individual bias frames, followed by their combination into a single master image:
        invoke("ficalib -i %s %s %s -o %s" %
               (' '.join(BIASLIST), self.COMMON_ARGS,
                self.imSizeArg(BIASLIST[0]), ' '.join(R_BIASLIST)))
        invoke("ficombine %s --mode median -o %s" %
               (' '.join(R_BIASLIST), masterBiasFile))

        # cleanup: remove temp files
        for f in R_BIASLIST:
            os.remove(f)

        return 0
Example #3
0
 def cleanFolder(self, subfolder, filePattern='*'):
     folderPattern = '*' + self.opt['baseFolder'] + '*/' + subfolder
     removePattern = folderPattern + '/' + filePattern
     fs = glob(removePattern)
     if len(fs) > 0:
         printInfo("Cleaning folders: %s" % (folderPattern))
         for f in fs:
             invoke("rm -f %s" % (f))
     else:
         print("No %s files in folders %s" % (filePattern, folderPattern))
Example #4
0
    def makeMasterDark(self, darkFolder, biasFolder, color):

        # Names of the individual files storing the raw bias, dark, flat and object frames:
        DARK_PATTERN = "%s/%s*-%s.fits" % (
            darkFolder, self.pplSetup['DARK_FILE_PREFIX'], color)
        DARKLIST = glob.glob(DARK_PATTERN)
        DARKLIST.sort()

        masterDarkFile = "%s/%s-%s.fits" % (
            darkFolder, self.pplSetup['MASTER_DARK_FILE'], color)
        masterBiasFile = "%s/%s-%s.fits" % (
            biasFolder, self.pplSetup['MASTER_BIAS_FILE'], color)

        if len(DARKLIST) == 0:
            return 1

        print("%s -> %s" % (DARK_PATTERN, masterDarkFile))

        # Calibrated images: all the images have the same name but put into a separate directory ($TARGET):
        R_DARKLIST = list(
            map(lambda x: self.TEMPDIR + '/' + basename(x), DARKLIST))

        # The calibration of the individual bias frames, followed by their combination into a single master image:
        invoke(
            "ficalib -i %s %s %s -o %s --input-master-bias %s" %
            (' '.join(DARKLIST), self.COMMON_ARGS, self.imSizeArg(
                DARKLIST[0]), ' '.join(R_DARKLIST), masterBiasFile))
        invoke("ficombine %s --mode median -o %s" %
               (' '.join(R_DARKLIST), masterDarkFile))

        # Calculate average ccd temperature from .cr2 files, and set it into the master dark
        tsum = 0
        count = 0
        for f in DARKLIST:
            hdr = getFitsHeader(f, 'CCD-TEMP')
            if hdr:
                ccdtemp = int()
                tsum += ccdtemp
                count += 1
        if count > 0:
            AVGTEMP = (tsum + (count / 2)) / count
            print("average dark temperature: %d C" % (AVGTEMP))
            setFitsHeaders(
                masterDarkFile,
                {'CCD-TEMP': ("%d." % (AVGTEMP), "CCD Temperature (Celsius)")})

        # cleanup: remove temp files
        for f in R_DARKLIST:
            os.remove(f)

        return 0
Example #5
0
 def invoked(self, cmd):
     if self.opt['debug']:
         printDebug(cmd)
     result = invoke(cmd)
     if result.startswith('ERROR:'):
         printError(result[len('ERROR: '):])
     elif self.opt['debug']:
         printDebug(result)
     return result
Example #6
0
    def makeMasterFlat(self, flatfolder, biasFolder, darkFolder, color):
        # Names of the individual files storing the raw bias, dark, flat and object frames:
        FLAT_PATTERN = "%s/%s*-%s.fits" % (
            flatfolder, self.pplSetup['FLAT_FILE_PREFIX'], color)
        FLATLIST = glob.glob(FLAT_PATTERN)
        FLATLIST.sort()

        masterFlatFile = "%s/%s-%s.fits" % (
            flatfolder, self.pplSetup['MASTER_FLAT_FILE'], color)
        masterDarkFile = "%s/%s-%s.fits" % (
            darkFolder, self.pplSetup['MASTER_DARK_FILE'], color)
        masterBiasFile = "%s/%s-%s.fits" % (
            biasFolder, self.pplSetup['MASTER_BIAS_FILE'], color)

        if len(FLATLIST) == 0:
            return 1

        print("%s -> %s" % (FLAT_PATTERN, masterFlatFile))

        # Calibrated images: all the images have the same name but put into a separate directory ($TARGET):
        R_FLATLIST = list(
            map(lambda x: self.TEMPDIR + '/' + basename(x), FLATLIST))

        # The calibration of the individual flat frames, followed by their combination into a single master image:
        invoke(
            "ficalib -i %s %s %s --post-scale 20000 -o %s --input-master-bias %s --input-master-dark %s"
            %
            (' '.join(FLATLIST), self.COMMON_ARGS, self.imSizeArg(FLATLIST[0]),
             ' '.join(R_FLATLIST), masterBiasFile, masterDarkFile))
        invoke("ficombine %s --mode median -o %s" %
               (' '.join(R_FLATLIST), masterFlatFile))

        # remove temp files
        for f in R_FLATLIST:
            os.remove(f)

        return 0
Example #7
0
    def raw2fitsFile(self, rawfile, color):
        FITS_NAME = "%s-%s.fits" % (rawfile[:rawfile.rfind('.')], color)
        if self.opt['overwrite'] and exists(FITS_NAME):
            os.remove(FITS_NAME)

        if not exists(FITS_NAME):
            print("%s -> %s" % (rawfile, FITS_NAME))

            # convert raw image to fits
            # TODO: use invoke, parse options with ' or " correctly, or use preparsed options
            os.system(
                "rawtran -c %s -o %s -B 16 -C '-4 -D -t 0' -X '-q 3 -w' %s" %
                (color, FITS_NAME, rawfile))

            # read image temperature from raw file
            exif = invoke("exiftool -s -g %s" % (rawfile))
            IMAGETEMP = None
            for line in exif.split('\n'):
                if line.startswith('CameraTemperature'):
                    IMAGETEMP = line.split(':')[1].strip()
                    break

            if IMAGETEMP:
                # write image temperature to fits file
                setFitsHeaders(
                    FITS_NAME,
                    {'CCD-TEMP': (IMAGETEMP, 'CCD Temperature (Celsius)')})

            # convert observation time from local time to UT
            if self.opt['imageTime'] == 'LT':
                IMAGE_DATE = getFitsHeader(FITS_NAME, 'DATE-OBS')
                IMAGE_DATE_UTC = self.lt2ut(IMAGE_DATE)
                setFitsHeaders(
                    FITS_NAME, {
                        'DATE-OBS':
                        IMAGE_DATE_UTC,
                        'DATE-IMG':
                        (IMAGE_DATE, 'Original image date (in local time)')
                    })

        else:
            print("%s file already exists." % (FITS_NAME))
Example #8
0
    def matchCatalogsByGrmatchPoints(self, refCatFile, pmCatFile, outFile):
        '''
        Match reference catalog with sextractor's .cat file by frame xy points
        '''

        # 1. convert refCat to fits format
        refFitsFile = refCatFile + '.fits'
        table = Table.read(refCatFile, format='ascii')
        if not exists(refFitsFile):
            table.write(refFitsFile)

        # 2. calculate ref objects' frame xy points
        wcsFile = pmCatFile.replace('.cat', '.wcs')
        axyFile = pmCatFile.replace('.cat', '.ref.axy')
        invoke("wcs-rd2xy -w %s -i %s -o %s -R RA_DEG -D DEC_DEG" %
               (wcsFile, refFitsFile, axyFile))  # -f option need argument

        remove(refFitsFile)

        # 3. merge frame xy point to refCat
        tlen = len(table)
        table['X'] = [0.0] * tlen
        table['Y'] = [0.0] * tlen
        table['ID'] = [0] * tlen
        table['ROLE_'] = ['AA'] * tlen

        f = fits.open(axyFile)
        d = f[1].data

        for j in range(tlen):
            x, y = d[j]
            table[j]['X'] = x
            table[j]['Y'] = y

        # 4. match refCat with sextractor's cat by frame xy points
        idFile = pmCatFile + ".idmatch"
        result = invoke(
            "grmatch -r %s -i %s --match-coord --col-ref 4,6 --col-inp 14,15 --output-id %s --col-ref-id 1 --col-inp-id 1"
            % (refCatFile, pmCatFile, idFile))

        # get image size
        astFile = pmCatFile.replace('.cat', '.ast.fits')
        im_x, im_y = self.readFrameSize(astFile)

        idTable = Table.read(idFile, format='ascii')
        pmTable = Table.read(pmCatFile, format='ascii')

        hmgs = self.hmg(pmTable)
        print("Instumental HMG: HMG_ISOCORR = %8.4f, HMG_BEST = %8.4f" %
              (hmgs[0], hmgs[1]))

        for j in range(tlen):

            onFrameStatus = self.determineOnFrameStatus(
                table[j]['X'], table[j]['Y'], im_x, im_y)

            matched = False
            for k in range(len(idTable)):
                if table[j]['AUID'] == idTable[k][0]:
                    table[j]['ID'] = int(idTable[k][1])
                    matched = True
                    break

            pmid = int(table[j]['ID'])
            d = -1.0
            if id != 0:
                pmrow = pmTable[pmid - 1]
                dx = pmrow['XWIN_IMAGE'] - table[j]['X']
                dy = pmrow['YWIN_IMAGE'] - table[j]['Y']
                d = sqrt(dx * dx + dy * dy)

            if onFrameStatus == '' and matched:
                # print('AUID: %s, ID:%d, d:%f, OK, on-frame and mathed' % (table[j]['AUID'], pmid, d))
                if d > 2.0:
                    print('AUID: %s, ID:%d, d:%f, OK, on-frame and mathed' %
                          (table[j]['AUID'], pmid, d))
                    print('   and too large distance')
                    table[j]['ROLE_'] = table[j]['ROLE'] + 'F'
                if table[j]['ROLE'] == 'V' and float(
                        pmrow['MAG_BEST']) > hmgs[1]:
                    if d <= 2.0:
                        print('AUID: %s, ID:%d, OK, on-frame and mathed' %
                              (table[j]['AUID'], pmid))
                    print('   and under limit, mi:%7.3f, hmg:%7.3f' %
                          (float(pmrow['MAG_BEST']), hmgs[1]))
                    table[j]['ROLE_'] = table[j]['ROLE'] + 'F'
                elif d <= 2.0:
                    table[j]['ROLE_'] = table[j]['ROLE']
            elif onFrameStatus == 'B' and matched:
                table[j]['ROLE_'] = table[j]['ROLE'] + 'B'
                print('AUID: %s, ID:%d, d:%f, OK, on-frame-border and mathed' %
                      (table[j]['AUID'], pmid, d))
                if d > 2.0:
                    print('   and too large distance')
                    table[j]['ROLE_'] = table[j]['ROLE'] + 'F'
                if table[j]['ROLE'] == 'VB' and float(
                        pmrow['MAG_BEST']) > hmgs[1]:
                    print('   and under limit, mi:%7.3f, hmg:%7.3f' %
                          (float(pmrow['MAG_BEST']), hmgs[1]))
                    table[j]['ROLE_'] = table[j]['ROLE'] + 'F'
            elif onFrameStatus == 'O' and matched:
                table[j]['ROLE_'] = table[j]['ROLE'] + 'O'
                print(
                    'AUID: %s, ID:%d, d:%f, BAD-MATCH, out-of-frame and mathed'
                    % (table[j]['AUID'], pmid, d))
            elif onFrameStatus == '' and not matched:
                table[j]['ROLE_'] = table[j]['ROLE'] + 'F'
                print('AUID: %s, FAINTER, on-frame and not mathed' %
                      (table[j]['AUID']))
                print('   and under limit, hmg:%7.3f' % (hmgs[1]))
            elif onFrameStatus == 'B' and not matched:
                table[j]['ROLE_'] = table[j]['ROLE'] + 'O'
                print(
                    'AUID: %s, FAINTER-ON-BORDER, on-frame-border and not mathed'
                    % (table[j]['AUID']))
            elif onFrameStatus == 'O' and not matched:
                table[j]['ROLE_'] = table[j]['ROLE'] + 'O'
                print('AUID: %s, OK, out-of-frame and not mathed' %
                      (table[j]['AUID']))

        # save result
        self.dumpResult(table, pmTable, outFile, hmgs)
Example #9
0
    def photometry(self, seqFolder, photFolder, refcatFileName, color):

        # Names of the sequence/combined files:
        SEQLIST = glob(seqFolder + '/' + self.pplSetup['SEQ_FILE_PREFIX'] +
                       '*-' + color + '.fits')
        SEQLIST.sort()
        if len(SEQLIST) == 0:
            SEQLIST = glob(seqFolder + '/Combined-' + color + '.fits')
            if len(SEQLIST) == 0:
                printWarning("No files for photometry in folder %s" %
                             (seqFolder))
                return False

        for f in SEQLIST:

            print("photometry of %s" % (f))

            AST_FILE = photFolder + '/' + basename(f).replace(
                '.fits', '.ast.fits')
            PMCAT_FILE = photFolder + '/' + basename(f).replace(
                '.fits', '.cat')

            printInfo("Make astrometry for %s" % (f))
            if not exists(AST_FILE) or self.opt['overwrite']:
                print("%s/solve-field %s -D %s -N %s %s" %
                      (self.pplSetup['AST_BIN_FOLDER'], self.SOLVE_ARGS,
                       photFolder, AST_FILE, f))
                invoke("%s/solve-field %s -D %s -N %s %s" %
                       (self.pplSetup['AST_BIN_FOLDER'], self.SOLVE_ARGS,
                        photFolder, AST_FILE, f))
                fsolved = PMCAT_FILE.replace('.cat', '.solved')
                if not exists(fsolved):
                    printError("Astrometry of %s failed." % (fsolved))
                    break
            else:
                print("astrometry file %s already exists." % (AST_FILE))

            printInfo("Make photometry for %s" % (f))
            if not exists(PMCAT_FILE) or self.opt['overwrite']:
                invoke(
                    "sextractor %s -c %s -CATALOG_NAME %s -CATALOG_TYPE ASCII_HEAD"
                    % (AST_FILE, self.SEX_CFG, PMCAT_FILE))
            else:
                print("photometry file %s already exists." % (PMCAT_FILE))

            PMCAT_FILE_FLT = PMCAT_FILE + ".cat"
            printInfo("Filtering result catalog to %s" % (PMCAT_FILE_FLT))
            if not exists(PMCAT_FILE_FLT) or self.opt['overwrite']:
                opt = {
                    'ref': refcatFileName,
                    'out': PMCAT_FILE_FLT,
                    'color': color,
                    'files': [PMCAT_FILE],
                }
                matcher = CatalogMatcher(opt)
                matcher.process()

            else:
                print("filtered photometry file %s already exists." %
                      (PMCAT_FILE_FLT))

        return True
Example #10
0
 def removeFolder(self, subfolder):
     folderPattern = '*' + self.opt['baseFolder'] + '*/' + subfolder
     fs = glob(folderPattern)
     printInfo("Removing folders: %s" % (folderPattern))
     for f in fs:
         invoke("rmdir %s" % (f))