def centroidObs(obsPath,centroidPath,centroidRa,centroidDec,haOffset,xGuess,yGuess,hotPath,flatPath):
    obs = ObsFile(obsPath)
    print obsPath,obs.getFromHeader('exptime'),obs
    if not os.path.exists(hotPath):
        hp.findHotPixels(obsFile=obs,outputFileName=hotPath)
    obs.loadHotPixCalFile(hotPath,switchOnMask=False)
    obs.loadBestWvlCalFile()
    obs.loadFlatCalFile(flatPath)
    obs.setWvlCutoffs(3000,8000)
    cc.centroidCalc(obs,centroidRa,centroidDec,guessTime=300,integrationTime=30,secondMaxCountsForDisplay=2000,HA_offset=haOffset,xyapprox=[xGuess,yGuess],outputFileName=centroidPath)
    print 'done centroid',centroidPath
    del obs
def centroidObs(obsPath,centroidPath,centroidRa,centroidDec,haOffset,xGuess,yGuess):
    obs = ObsFile(obsPath)
    print obsPath,obs.getFromHeader('exptime'),obs
    obs.loadAllCals()
#    obs.loadBestWvlCalFile()
#    obs.loadFlatCalFile(flatPath)
    obs.setWvlCutoffs(3000,11000)
#    if not os.path.exists(hotPath):
#        hp.findHotPixels(obsFile=obs,outputFileName=hotPath,display=True,fwhm=2.,boxSize=5, nSigmaHot=4.0,)
#    obs.loadHotPixCalFile(hotPath,switchOnMask=True)
    cc.centroidCalc(obs,centroidRa,centroidDec,guessTime=300,integrationTime=30,secondMaxCountsForDisplay=2000,HA_offset=haOffset,xyapprox=[xGuess,yGuess],outputFileName=centroidPath,usePsfFit=True,radiusOfSearch=8)
    print 'done centroid',centroidPath
    del obs
    obsFN = FileName(run=run,date=date,tstamp=tstamp)
    obsPath = obsFN.obs()
     
    flatPath = FileName(run=run,date=date).flatSoln()
    hotPath = obsFN.timeMask()
    centroidPath = obsFN.centroidList()
    
    obs = ObsFile(obsPath)
    if not os.path.exists(hotPath):
        hp.findHotPixels(obsPath,hotPath)
    obs.loadHotPixCalFile(hotPath,switchOnMask=False)
    obs.loadBestWvlCalFile()
    obs.loadFlatCalFile(flatPath)
    obs.setWvlCutoffs(3000,8000)

    
    centroidRa = '03:37:43.826'
    centroidDec = '14:15:14.828'
    haOffset = 150.

    imgDict = obs.getPixelCountImage(integrationTime=60,scaleByEffInt=True)
    plotArray(imgDict['image'])
    

    xGuess = 18 #col
    yGuess = 15 #row
    cc.centroidCalc(obs,centroidRa,centroidDec,guessTime=300,integrationTime=30,secondMaxCountsForDisplay=2000,HA_offset=haOffset,xyapprox=[xGuess,yGuess],outputFileName=centroidPath)

    
def testWritePhotonList(outputFileName=None,firstSec=0,integrationTime=-1,doPixRemap=False):
    '''
    Test run of obsFile.writePhotonList. fileName can be used
    to specify the output file name. If not specified, default
    name/location is used.
    
    Now includes test for pixel remapping....
    '''

    #Details of example obs file to run test on.
#    run = 'PAL2012'
#    date = '20121207'
#    tstamp = '20121208-074649'
#    calTstamp='20121208-070505'
#    fluxTstamp='20121208-133002'

    run = 'PAL2013'
    date = '20131209'
    tstamp = '20131209-115553'
    centroidTstamp = tstamp
    calTstamp='20131209-132225'
    fluxTstamp='ones'
    flatTstamp='20131209'
    if doPixRemap==True:
        pixRemapFileName = FileName(run=run).pixRemap()
    else:
        pixRemapFileName = None
    
    #Load up the obs file
    obsFileName = FileName(run=run, date=date, tstamp=tstamp)
    obsFile = ObsFile(obsFileName.obs())

    obsFile.loadWvlCalFile(FileName(run=run,date=date,tstamp=calTstamp).calSoln())
    obsFile.loadFlatCalFile(FileName(run=run,date=date,tstamp=flatTstamp).flatSoln())
    obsFile.loadFluxCalFile(FileName(run=run,date=date,tstamp=fluxTstamp).fluxSoln())

    HotPixFile = FileName(run=run,date=date,tstamp=tstamp).timeMask()
    if not os.path.exists(HotPixFile): #check if hot pix file already exists
        hp.findHotPixels(obsFileName.obs(),HotPixFile)
        print "Flux file pixel mask saved to %s"%(HotPixFile)
    obsFile.loadHotPixCalFile(HotPixFile)
    print "Hot pixel mask loaded %s"%(HotPixFile)   

    #hz21 location alpha(2000) = 12h 13m 56.42s , delta(2000) = +32d 56' 30.8''
    centroid_RA = '12:13:56.42'
    centroid_DEC = '32:56:30.8'
    CentFile = FileName(run=run,date=date,tstamp=tstamp).centroidList()
    #print "checking centroid file", CentFile
    #if not os.path.exists(CentFile): #check if cent pix file already exists
    cent.centroidCalc(obsFile, centroid_RA, centroid_DEC, outputFileName = CentFile, guessTime=10, integrationTime=10)
    #    print "Flux file centroid cal saved to %s"%(CentFile)
    obsFile.loadCentroidListFile(CentFile)
    print "Centroid File loaded %s"%(CentFile) 

    #Load up associated calibrations

    #obsFile.loadTimeAdjustmentFile(FileName(run=run,date=date,tstamp=tstamp).timeAdjustments())
    #obsFile.loadHotPixCalFile(FileName(run=run,date=date,tstamp=tstamp).timeMask())
    #obsFile.loadCentroidListFile(FileName(run=run,date=date,tstamp=tstamp).centroidList())
    
    #And write out the results....
    obsFile.writePhotonList(outputFileName,firstSec,integrationTime,
                            pixRemapFileName=pixRemapFileName)
    
    #Read the results back in....
    #photFile = photList.PhotFile(outputFilename)
    
    print "Wrote photon list file: ", outputFileName
def main(testRun=False):

    #INPUTS:
    #    - testRun :    If True, run only a single exposure.

    #Try remapping the pixels - set to None to not do this....
    pixRemapFileName = FileName(run='PAL2012').pixRemap()

    obsSequence0="""
    051516
    052018
    052520
    """
    obsSequence1="""
    033323
    033825
    034327
    034830
    035332
    035834
    040336
    040838
    041341
    041843
    042346
    042848
    043351
    043853
    044355
    044857
    045359
    045902
    """

    obsSequence2="""
    050404
    050907
    051409
    051912
    052414
    052917
    053419
    053922
    """
    # 054424 - repointed mid-exposure, leave out for now.    
    

    obsSequence3="""
    054926
    055428
    055930
    060432
    060934
    061436
    061938
    062440
    062942
    """

    run = 'PAL2012'
    obsSequences = [obsSequence0,obsSequence1,obsSequence2,obsSequence3]
    
    #If test run is requested, override and just run one test exposure.
    if testRun is True:
        obsSequences = ['9999999',
                        '''
                        033323
                        ''',
                        '9999999',
                        '9999999']
    
    wvlCals = ['051341','063518','063518','063518']
    flatCals = ['20121211','20121211','20121211','20121211']
    #fluxCalDates = ['20121206','20121206','20121206','20121206']
    #fluxCals = ['20121207-072055','20121207-072055','20121207-072055','20121207-072055']
    fluxCalDates = ['20121211','20121211','20121211','20121211']
    fluxCals = ['absolute_021727','absolute_021727','absolute_021727','absolute_021727']

    #Row coordinate of center of crab pulsar for each obsSequence
    centersRow = [9,30,29,10]
    #Col coordinate of center of crab pulsar for each obsSequence
    centersCol = [13,30,30,14]

    centerRA = '05:34:31.93830'
    centerDec = '+22:00:52.1758'

    obsUtcDate = '20121212'
    obsUtcDates = ['20121206','20121212','20121212','20121212']

    obsFileNames = []
    obsFileNameTimestamps = []
    wvlFileNames = []
    flatFileNames = []
    fluxFileNames = []
    timeMaskFileNames = []
    centroidFileNames = []
    
    for iSeq in range(len(obsSequences)):
        obsSequence = obsSequences[iSeq]
        obsSequence = obsSequence.strip().split()
        obsFileNameTimestamps.append(obsSequence)
        obsUtcDate = obsUtcDates[iSeq]
        sunsetDate = str(int(obsUtcDate)-1)
        obsSequence = [obsUtcDates[iSeq]+'-'+ts for ts in obsSequence]
        obsFileNames.append([FileName(run=run,date=sunsetDate,tstamp=ts).obs() for ts in obsSequence])
        timeMaskFileNames.append([FileName(run=run,date=sunsetDate,tstamp=ts).timeMask() for ts in obsSequence])
        centroidFileNames.append([FileName(run=run,date=sunsetDate,tstamp=ts).centroidList() for ts in obsSequence])

        wvlCalTstamp = obsUtcDate+'-'+wvlCals[iSeq]
        wvlFileNames.append(FileName(run=run,date=sunsetDate,tstamp=wvlCalTstamp).calSoln())
        fluxFileNames.append(FileName(run=run,date=fluxCalDates[iSeq],tstamp=fluxCals[iSeq]).fluxSoln())
        flatFileNames.append(FileName(run=run,date=flatCals[iSeq]).illumSoln()) # *** CURRENTLY USES ILLUMINATION SOLUTION! ***
        centroidFileNames.append(FileName(run=run,date=sunsetDate,tstamp=ts).centroidList())


#     #Make hot pixel masks if needed
#     for iSeq,obsSequence in enumerate(obsSequences):
#         obsSequence = obsSequence.strip().split()
#         print obsSequence
#         for iOb,obs in enumerate(obsSequence):
#             timeMaskFileName = timeMaskFileNames[iSeq][iOb]
#             if os.path.exists(obsFileNames[iSeq][iOb]) and not os.path.exists(timeMaskFileName):
#                 print 'Running hotpix for ',obs
#                 hp.findHotPixels(obsFileNames[iSeq][iOb],timeMaskFileName)
#                 print "Flux file pixel mask saved to %s"%(timeMaskFileName)
#             else:
#                 print 'Skipping hot pixel mask creation for file '+obsFileNames[iSeq][iOb]


    #apertureRadius = 4
    obLists = [[ObsFile(fn)for fn in seq if os.path.exists(fn)] for seq in obsFileNames]
    tstampFormat = '%H:%M:%S'
    #print 'fileName','headerUnix','headerUTC','logUnix','packetReceivedUnixTime'
   
    print '---------Making hot pixel masks/getting centroids-----------' 
    for iSeq,obList in enumerate(obLists):
        for iOb,ob in enumerate(obList):
            timeAdjFileName = FileName(run='PAL2012').timeAdjustments()
            wvlCalFileName = wvlFileNames[iSeq]
            flatCalFileName = flatFileNames[iSeq]
            fluxCalFileName = fluxFileNames[iSeq]
            timeMaskFileName = FileName(obsFile=ob).timeMask() #timeMaskFileNames[iSeq][iOb]
            centroidFileName = FileName(obsFile=ob).centroidList()
            if not os.path.exists(centroidFileName) or not os.path.exists(timeMaskFileName):
                print 'Loading calibration files:'
                print [os.path.basename(x) for x in [timeAdjFileName,wvlCalFileName,flatCalFileName, \
                        fluxCalFileName,timeMaskFileName, centroidFileName]]
                ob.loadTimeAdjustmentFile(timeAdjFileName)
                ob.loadWvlCalFile(wvlCalFileName)
                ob.loadFlatCalFile(flatCalFileName)
                ob.loadFluxCalFile(fluxCalFileName)
                ob.setWvlCutoffs(3000.,12000.) #Keep most of the wavelength range for the purposes of centroiding/hot pixel detection.

                
            if not os.path.exists(timeMaskFileName):
                print 'Running hotpix for ',ob.fileName
                #Run hot pixel detection on *calibrated* file.
                #But don't use flux weighting, as this scales by a large amount, and throws
                #the poisson statistics way too much. (i.e., we really need to use
                #counts *detected* for shot noise statistics, rather than 
                #estimated counts above the atmosphere....)
                hp.findHotPixels(obsFile=ob,outputFileName=timeMaskFileName,
                                 useRawCounts=False,weighted=True,fluxWeighted=False)
                print "Flux file pixel mask saved to %s"%(timeMaskFileName)
            else:
                print 'Skipping hot pixel mask creation for file '+obsFileNames[iSeq][iOb]
            if not os.path.exists(centroidFileName):
                ob.loadHotPixCalFile(timeMaskFileName)
                print 'Running CentroidCalc for ',ob.fileName
                cc.centroidCalc(ob, centerRA, centerDec, outputFileName=centroidFileName,
                                guessTime=300, integrationTime=30, secondMaxCountsForDisplay=500,
                                xyapprox=[centersCol[iSeq],centersRow[iSeq]])
                print "Centroiding calculations saved to %s"%(centroidFileName)
            else:
                print "Centroid file already exists - skipping: "+centroidFileName
def ObjectFinder(frames, data, RA = None, Dec = None, radiusOfSearch=10, usePsfFit=False):
    '''
    This allows the user to determine the exact positioning of a star withing a given frame, given that
    the star exists in two frames. two images pop up, if they contain the same star, click on it in both images,
    and the exact pixel positioning will be determine via centroiding. Some parts are fudged for now.

    Inputs:
        frames - This is an array of images corresponding to the various frames used for the mosaic. note that 
                 the way this is written as of now requires that the first  and last frame include the same star. 
                 I think this is typical so it should not be a problem.

        data - this is an array of dictionaries corresponding to each frame. This is generated from
               getFrameDict() which I have included in the ObsFileSeq class. This is required.

        RA/Dec - these are not used as of now.
    
    Outputs:
        
        all the parameters that are needed for setRm()

    Ben also suggested that a cross-correlating technique may be useful for matching frames with no star in them.
    What do you guys think? I need to look into it more but I believe that this code can be expanded to also do
    cross-correlation. - Neil
    '''

    offsRA = []
    offsDec = []
    iframe = [] 
    meanTime = []  
    
    for i in range(len(data)):
        offsRA.append(data[i]["offsRA"])
        offsDec.append(data[i]["offsDec"])
        iframe.append(data[i]["iframe"])
        meanTime.append(data[i]["meanTime"])

    offsRA = np.array(offsRA)
    offsDec = np.array(offsDec)
    iframe = np.array(iframe)
    meanTime = np.array(meanTime)
    
    dpp = []
    ang = []
    
    for i in range(1, len(frames)):
        images = np.array([frames[i-1], frames[i]])    
        oRA = np.array([offsRA[i-1], offsRA[i]])
        oDec = np.array([offsDec[i-1], offsDec[i]])
        print 'Looking for matching Stars...'

        print 'frame: ', iframe[i-1], 'Offset RA: ', offsRA[i-1], 'Offset Dec: ', offsDec[i-1]
        print 'frame: ', iframe[i], 'Offset RA: ', offsRA[i], 'Offset Dec: ', offsDec[i]         
        
        xyguesses, flagList = getUserObjectGuess(images)

        if flagList[1]==0 and flagList[0]==0:
            print 'match found! - determining centroid positions'
                
            #xycenter1, flag1 
            cenDict1 = cc.centroidImage(images[1], xyguesses[1], radiusOfSearch=radiusOfSearch, doDS9=False, usePsfFit=usePsfFit)
            #xycenter0, flag0 
            cenDict0 = cc.centroidImage(images[0], xyguesses[0], radiusOfSearch=radiusOfSearch, doDS9=False, usePsfFit=usePsfFit)
            print 'Success! Matching stars at: ', cenDict0['xycenter'], cenDict1['xycenter']                
                
            #rc1 = np.array(xycenter1)
            #rc0 = np.array(xycenter0)
            rc1 = np.array(cenDict1['xycenter'])
            rc0 = np.array(cenDict0['xycenter'])
            
            dCol = rc1[0] - rc0[0]
            dRow = rc1[1] - rc0[1]                
            dPix = math.sqrt(((rc1-rc0)**2).sum())

            #center ra,dec of fram calculated from offsets
            dRA = oRA[1]-oRA[0] #arcseconds
            dDec = oDec[1]-oDec[0]
            dDeg = math.sqrt(dRA**2+dDec**2)/3600 #degrees
                
            degPerPix = dDeg/dPix #plate scale
    
            #rotation
            thetaPix = math.atan2(dCol,dRow) #angle from verticle
            thetaSky = math.atan2(dRA, dDec) #angle from north
            theta = thetaPix-thetaSky        #degrees
                
            dpp.append(degPerPix)
            ang.append(theta)
        
        elif flagList[1]==1 or flagList[0]==1:
            print 'no star found' 

    dpp = np.array(dpp)
    #print dpp
    degPerPix = np.mean(dpp)
    #print degPerPix
    ang = np.array(ang)
    print ang
    theta = np.mean(ang)  
    print theta  
     
    ## Pick two frames where the ra,dec offset is zero,
    # usually the beginning and ending frames
    
    print 'Matching stars from the first and last frames'    
    
    images = [frames[0], frames[-1]]

    print 'frame: ', iframe[0], 'Offset RA: ', offsRA[0], 'Offset Dec: ', offsDec[0]
    print 'frame: ', iframe[-1], 'Offset RA: ', offsRA[-1], 'Offset Dec: ', offsDec[-1]  
    
    xyguesses, flagList = getUserObjectGuess(images)
    
    #xycenter1, flag1 
    cenDict1 = cc.centroidImage(images[1], xyguesses[1], radiusOfSearch=radiusOfSearch, doDS9=False, usePsfFit=usePsfFit)
    #xycenter0, flag0 
    cenDict0 = cc.centroidImage(images[0], xyguesses[0], radiusOfSearch=radiusOfSearch, doDS9=False, usePsfFit=usePsfFit)
    
    print 'Success! Matching stars at: ', cenDict0['xycenter'], cenDict1['xycenter']        
    #start here
    rcA = np.array(cenDict0['xycenter'])
    rcB = np.array(cenDict1['xycenter'])
    sct = math.cos(theta)*degPerPix    
    sst = math.sin(theta)*degPerPix
    # This rotation matrix converts from row,col to ra,dec in degrees
    rm = np.array([[sct,-sst],[sst,sct]])
    rdA = rm.dot(rcA)
    rdB = rm.dot(rcB)
    deltaRa = rdB[0]-rdA[0]
    deltaTime = meanTime[-1] - meanTime[0]
    raArcsecPerSec = 3600*deltaRa/deltaTime
    
    return degPerPix, theta, raArcsecPerSec