def main():

    objectName = "hz21"
    fileNum=0
    energyBinWidth = 0.1
    #make bins for 3000 to 13000
    wvlStart = 3000
    wvlStop = 13000
    wvlBinEdges = ObsFile.makeWvlBins(energyBinWidth,wvlStart,wvlStop)
    nWvlBins = len(wvlBinEdges)-1
    binWidths = np.empty(nWvlBins)
    print "Showing bin widths for %i bins"%(nWvlBins)
    for i in xrange(nWvlBins):
        binWidths[i] = wvlBinEdges[i+1]-wvlBinEdges[i]
    print binWidths

    nVirtPixX=250
    nVirtPixY=250
    cube = np.zeros((nVirtPixX,nVirtPixY,nWvlBins),dtype=float)

    for n in xrange(nWvlBins):
        print "Making image for wvls %i to %i"%(wvlBinEdges[n], wvlBinEdges[n+1])
        virtualImage, imageStack, medImage = makeImageStack(fileNames='photons_*.h5', dir=os.getenv('MKID_PROC_PATH', default="/Scratch")+'/photonLists/20131209',
                   detImage=False, saveFileName='stackedImage.pkl', wvlMin=wvlBinEdges[n],
                   wvlMax=wvlBinEdges[n+1], doWeighted=True, medCombine=False, vPlateScale=0.2,
                   nPixRA=nVirtPixX,nPixDec=nVirtPixY)
        print virtualImage
        print virtualImage.image
        print np.shape(virtualImage.image)
        cube[:,:,n] = virtualImage.image
    
    #calculate midpoints of wvl bins for plotting
    wvls = np.empty((nWvlBins),dtype=float)
    for n in xrange(nWvlBins):
        binsize=wvlBinEdges[n+1]-wvlBinEdges[n]
        wvls[n] = (wvlBinEdges[n]+(binsize/2.0))

    print "wvls ",wvls
    #reshape cube for makeMovie
    movieCube = np.zeros((nWvlBins,np.shape(cube)[0],np.shape(cube)[1]),dtype=float)
    for i in xrange(nWvlBins):
        movieCube[i,:,:] = cube[:,:,i]
        #show individual frames as they are made to debug
        #plt.matshow(movieCube[i],vmin = 0, vmax = 100)
        #plt.show()
    print "movieCube shape ", np.shape(movieCube)
    print "wvls shape ", np.shape(wvls)

    #print cube
    #print "--------------------------"
    #print movieCube

    np.savez('%s_raw_%s.npz'%(objectName,fileNum),stack=movieCube,wvls=wvls)
    utils.makeMovie(movieCube,frameTitles=wvls,cbar=True,outName='%s_pl_raw_%s.gif'%(objectName,fileNum), normMin=0, normMax=1000)

    '''
def cleanSpectrum(x,y,objectName, wvlBinEdges):
        #locations and widths of absorption features in Angstroms
        #features = [3890,3970,4099,4340,4860,6564,6883,7619]
        #widths = [50,50,50,50,50,50,50,50]
        #for i in xrange(len(features)):
        #    #check for absorption feature in std spectrum
        #    ind = np.where((x<(features[i]+15)) & (x>(features[i]-15)))[0]
        #    if len(ind)!=0:
        #        ind = ind[len(ind)/2]
        #    #if feature is found (flux is higher on both sides of the specified wavelength where the feature should be)
        #    if y[ind]<y[ind+1] and y[ind]<y[ind-1]:
        #        #cut out width[i] around feature[i]
        #        inds = np.where((x >= features[i]+widths[i]) | (x <= features[i]-widths[i]))
        #        x = x[inds]
        #        y = y[inds]

        #fit a tail to the end of the spectrum to interpolate out to desired wavelength in angstroms
        fraction = 2.1/3
        newx = np.arange(int(x[fraction*len(x)]),20000)

        slopeguess = (np.log(y[-1])-np.log(y[fraction*len(x)]))/(x[-1]-x[fraction*len(x)])
        print "Guess at exponential slope is %f"%(slopeguess)
        guess_a, guess_b, guess_c = float(y[fraction*len(x)]), x[fraction*len(x)], slopeguess
        guess = [guess_a, guess_b, guess_c]

        fitx = x[fraction*len(x):]
        fity = y[fraction*len(x):]

        exp_decay = lambda fx, A, x0, t: A * np.exp((fx-x0) * t)

        params, cov = curve_fit(exp_decay, fitx, fity, p0=guess, maxfev=2000)
        A, x0, t= params
        print "A = %s\nx0 = %s\nt = %s\n"%(A, x0, t)
        best_fit = lambda fx: A * np.exp((fx-x0)*t)

        calcx = np.array(newx,dtype=float)
        newy = best_fit(calcx)

        #func = interpolate.splrep(x[fration*len(x):],y[fraction*len(x):],s=smooth)
        #newx = np.arange(int(x[fraction*len(x)]),self.wvlBinEdges[-1])
        #newy = interpolate.splev(newx,func)

        wl = np.concatenate((x,newx[newx>max(x)]))
        flux = np.concatenate((y,newy[newx>max(x)]))

        #new method, rebin data to grid of wavelengths generated from a grid of evenly spaced energy bins
        #R=7.0 at 4500
        #R=E/dE -> dE = R/E
        dE = 0.3936 #eV
        start = 1000 #Angs
        stop = 25000 #Angs
        enBins = ObsFile.makeWvlBins(dE,start,stop)
        rebinned = rebin(wl,flux,enBins)
        re_wl = rebinned[:,0]
        re_flux = rebinned[:,1]
        #plt.plot(re_wl,re_flux,color='r')
        
        re_wl = re_wl[np.isnan(re_flux)==False]
        re_flux = re_flux[np.isnan(re_flux)==False]

        start1 = wvlBinEdges[0]
        stop1 = wvlBinEdges[-1]
        #regrid downsampled data 

        new_wl = np.arange(start1,stop1)

        #print re_wl
        #print re_flux
        #print new_wl

        #weight=1.0/(re_flux)**(2/1.00)
        print len(re_flux)
        weight = np.ones(len(re_flux))
        #decrease weights near peak
        ind = np.where(re_flux == max(re_flux))[0]
        weight[ind] = 0.3
        for p in [1,2,3]:
            if p==1:
                wt = 0.3
            elif p==2:
                wt = 0.6
            elif p==3:
                wt = 0.7
            try:
                weight[ind+p] = wt
            except IndexError:
                 pass
            try:
                 if ind-p >= 0:
                     weight[ind-p] = wt
            except IndexError:
                pass
        #change weights to set how tightly fit must match data points
        #weight[-4:] = 1.0
        weight = [0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7]
        #print len(weight)
        #weight = re_flux/min(re_flux)
        #weight = 1.0/weight
        #weight = weight/max(weight)
        print weight
        f = interpolate.splrep(re_wl,re_flux,w=weight,k=3,s=max(re_flux)**200)
        new_flux = interpolate.splev(new_wl,f,der=0)
        return new_wl, new_flux
NumFrames = 31
#nFiles = 13 #j0926
#nFiles=25 #crab
nFiles = 1 #try with only 1 file
curves = np.zeros((nFiles,NumFrames),dtype=float)

for k in xrange(nFiles):
    #FileName = '/home/srmeeker/scratch/standards/crabNight2_fit_%s.npz'%(fileNum)
    FileName = '/home/srmeeker/scratch/standards/crabNight1_fit_%s.npz'%(fileNum)
    print FileName
    t = np.load(FileName)

    energyBinWidth = 0.1
    wvlStart = 3000
    wvlStop = 13000
    wvlBinEdges = ObsFile.makeWvlBins(energyBinWidth,wvlStart,wvlStop)
    nWvlBins = len(wvlBinEdges)-1
    binWidths = np.empty(nWvlBins)
    for i in xrange(nWvlBins):
        binWidths[i] = wvlBinEdges[i+1]-wvlBinEdges[i]
    #print binWidths
    params = t['params']
    wvls = t['wvls']
    amps = params[:,1]
    widths = params[:,4]
    xpos = params[:,2]
    ypos = params[:,3]

    #print len(wvls)
    #print len(binWidths)
def main():

    obsSequence1="""
    035332
    035834
    040336
    040838
    041341
    041843
    042346
    042848
    043351
    043853
    044355
    044857
    045359
    045902
    """

    obsSequence2="""
    050404
    050907
    051409
    051912
    052414
    052917
    053419
    053922
    """

    obsSequence3="""
    054926
    055428
    """


    pulseLabel = 1 #1 for interpulse, 2 for main pulse
    verbose = True
    run = 'PAL2012'
    path = '/Scratch/dataProcessing/crabData2/'
    nIdxToCheck = 81
    nBins = 250
    outFilePath = path+'indPulseProfiles_3sigma_P{}_KS.h5'.format(pulseLabel)
    wvlBinEdges = ObsFile.makeWvlBins(wvlStart=4000,wvlStop=11000)
    wvlBinWidths = np.diff(wvlBinEdges)
    nWvlBins = len(wvlBinWidths)
    peakIdx=167#the index of the phaseBin at the main pulse peak

    obsSequences = [obsSequence1,obsSequence2,obsSequence3]
    #obsSequences = [obsSequence1]
    wvlCals = ['063518','063518','063518']
    flatCals = ['20121211','20121211','20121211']
    fluxCalDates = ['20121206','20121206','20121206']
    fluxCals = ['20121207-072055','20121207-072055','20121207-072055']

    obsUtcDates = ['20121212','20121212','20121212']


    obsFileNames = []
    obsFileNameTimestamps = []
    wvlFileNames = []
    flatFileNames = []
    fluxFileNames = []
    timeMaskFileNames = []
    plFileNames = []
    skyFileNames = []

    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]
        plFileNames.append([FileName(run=run,date=sunsetDate,tstamp=ts).crabList() for ts in obsSequence])
        skyFileNames.append([FileName(run=run,date=sunsetDate,tstamp=ts).crabSkyList() for ts in obsSequence])

    np.set_printoptions(precision=11,threshold=np.nan)


    labels=np.array('iBTOA   pulseNumber BTOA    Noise_Offset    Noise_RMS   Max  Mean Index    TestMax  TestMean TestIndex'.split())

    table = np.loadtxt(path+'giantPulseList_P{}_3sigma_indices.txt'.format(pulseLabel),skiprows=1,usecols=range(len(labels)))
    peakDetectionMask = table[:,np.argmax('Max'==labels)]!=0
    table = table[peakDetectionMask]#cut out test_P2 (false) detections

    dimMask = np.ones(len(table))
    #dimMask[13292:22401]=0
    dimMask = dimMask==1

    radioStrength = table[:,5]
    allGiantPulseNumbers = table[:,1]
    if pulseLabel == 2:
        radioStrengthCutoff = 0.175
    elif pulseLabel == 1:
        radioStrengthCutoff = 0.01

    radioCutoffMask = radioStrength >= radioStrengthCutoff
    strongMask = np.logical_and(radioCutoffMask,dimMask)
    table = table[strongMask]

    giantDict = dict()
    for iLabel,label in enumerate(labels):
        giantDict[label] = table[:,np.argmax(label==labels)]

    noiseStrengthLabel = 'TestMax'


    #count number of detections in the test range and the P2 peak range
    nNoiseDetections = np.sum(giantDict[noiseStrengthLabel]!=0)
    print nNoiseDetections,'noise detections'
    nPeakDetections = np.sum(giantDict['Max']!=0)
    print nPeakDetections,'peak detections'
    
    giantPulseNumbers = giantDict['pulseNumber']
    radioMax = giantDict['Max']
    radioMean = giantDict['Mean']
    radioDetectedIndices = giantDict['Index']

    nGRP = len(giantPulseNumbers)
    if verbose:
        print 'Number of GRPs',nGRP
    counts = np.zeros((nGRP,nIdxToCheck))
    skyCounts = np.zeros((nGRP,nIdxToCheck))

    idxOffsets = np.array(np.linspace(-(nIdxToCheck//2),nIdxToCheck//2,nIdxToCheck),dtype=np.int)
    nIdxOffsets = len(idxOffsets)

    histStart = 0.
    histEnd = 1.
    pulsarPeriod = 33e-3 #s, approximately
    indProfiles = np.zeros((nGRP,nIdxOffsets,nBins))
    skyIndProfiles = np.zeros((nGRP,nIdxOffsets,nBins))
    fullSpectra = np.zeros((nIdxOffsets,nWvlBins),dtype=np.double)
    skyFullSpectra = np.zeros((nIdxOffsets,nWvlBins),dtype=np.double)
    peakSpectra = np.zeros((nIdxOffsets,nWvlBins),dtype=np.double)
    skyPeakSpectra = np.zeros((nIdxOffsets,nWvlBins),dtype=np.double)
    plList = [PhotList(fn) for seq in plFileNames for fn in seq]
    skyList = [PhotList(fn) for seq in skyFileNames for fn in seq]
    plMins = []
    plMaxs = []
    for iPL,pl in enumerate(plList):
        minPulseNumber = pl.photTable.cols.pulseNumber[pl.photTable.colindexes['pulseNumber'][0]]
        maxPulseNumber = pl.photTable.cols.pulseNumber[pl.photTable.colindexes['pulseNumber'][-1]]
        print pl.fileName,minPulseNumber,maxPulseNumber
        plMins.append(minPulseNumber)
        plMaxs.append(maxPulseNumber)

    plMins = np.array(plMins)
    plMaxs = np.array(plMaxs)
        
    pulseNumberTable = np.array([gpn+idxOffsets for gpn in giantPulseNumbers])
    giantPulseNumberMask = np.zeros(np.shape(pulseNumberTable))
    validWvlCutoff = 11000 #angstroms
    if verbose:
        print 'filling giant pulse number mask'
    for iGiantPN,giantPN in enumerate(allGiantPulseNumbers):
        if verbose and iGiantPN % 500 == 0:
            print 'mask',iGiantPN,'of',len(allGiantPulseNumbers)
        giantMatches = (pulseNumberTable == giantPN)
        giantPulseNumberMask = np.logical_or(giantPulseNumberMask,giantMatches)

    outFile = tables.openFile(outFilePath,mode='w')

    nLivePixels = []
    for iPL,pl in enumerate(plList):
        pixels = np.unique(pl.photTable.cols.xyPix[:])
        print pixels
        nPixels = len(pixels)
        nLivePixels.append(nPixels)

    nLivePixels = np.array(nLivePixels)
    nSkyLivePixels = []
    for iPL,pl in enumerate(skyList):
        pixels = np.unique(pl.photTable.cols.xyPix[:])
        print pixels
        nPixels = len(pixels)
        nSkyLivePixels.append(nPixels)
    nSkyLivePixels = np.array(nSkyLivePixels)

    pulseNumberList = np.unique(pulseNumberTable.ravel())       
    nPulseNumbers = len(pulseNumberList)                        
    pulseNumberListMask = np.ones(nPulseNumbers)                

    floatAtom = tables.Float64Atom()
    uint8Atom = tables.UInt8Atom()

    nExpectedRows=1e7
    #phaseArrays = [outFile.createEArray(outFile.root,'phases{:03d}'.format(iIdxOffset),floatAtom,(0,),title='phases at pulse number {} w.r.t. GRP'.format(idxOffset),expectedrows=nExpectedRows) for iIdxOffset,idxOffset in enumerate(idxOffsets)]
    #skyPhaseArrays = [outFile.createEArray(outFile.root,'skyPhases{:03d}'.format(iIdxOffset),floatAtom,(0,),title='phases at pulse number {} w.r.t. GRP in sky'.format(idxOffset),expectedrows=nExpectedRows) for iIdxOffset,idxOffset in enumerate(idxOffsets)]
    #wavelengthArrays = [outFile.createEArray(outFile.root,'wavelengths{:03d}'.format(iIdxOffset),floatAtom,(0,),title='wavelengths at pulse number {} w.r.t. GRP'.format(idxOffset),expectedrows=nExpectedRows) for iIdxOffset,idxOffset in enumerate(idxOffsets)]
    #skyWavelengthArrays = [outFile.createEArray(outFile.root,'skyWavelengths{:03d}'.format(iIdxOffset),floatAtom,(0,),title='wavelengths at pulse number {} w.r.t. GRP in sky'.format(idxOffset),expectedrows=nExpectedRows) for iIdxOffset,idxOffset in enumerate(idxOffsets)]
    grpPeakWavelengthArrays = outFile.createVLArray(outFile.root,'grpWavelengths',floatAtom,'photon wavelength list for GRPs at main peak',tables.Filters(complevel=1))
    nongrpPeakWavelengthArrays = outFile.createVLArray(outFile.root,'nongrpWavelengths',floatAtom,'photon wavelength list for nonGRPs at main peak',tables.Filters(complevel=1))

    for iGiantPN,giantPN in enumerate(giantPulseNumbers):
        if verbose and iGiantPN % 100 == 0:
            print iGiantPN
        
        iPL = np.searchsorted(plMaxs,giantPN)

        if iPL >= len(plMins):
            if verbose:
                print iGiantPN,'GRP not found in optical'
            continue
        if plMins[iPL] > giantPN:
            if verbose:
                print iGiantPN,'GRP not found in optical'

            continue

        if plMins[iPL] >= giantPN+idxOffsets[0] or plMaxs[iPL] <= giantPN+idxOffsets[-1]:
            if verbose:
                print iGiantPN,'optical pulses surrounding GRP not found'
            continue

        pl = plList[iPL]
        skyPL = skyList[iPL]
        #grab all photons in the pulseNumber range covered by all idxOffsets for this GRP
        pulseSelectionIndices = pl.photTable.getWhereList('({} <= pulseNumber) & (pulseNumber <= {})'.format(giantPN+idxOffsets[0],giantPN+idxOffsets[-1]))
        skyPulseSelectionIndices = skyPL.photTable.getWhereList('({} <= pulseNumber) & (pulseNumber <= {})'.format(giantPN+idxOffsets[0],giantPN+idxOffsets[-1]))
        photonsInPulseSelection = pl.photTable.readCoordinates(pulseSelectionIndices)
        skyPhotonsInPulseSelection = skyPL.photTable.readCoordinates(skyPulseSelectionIndices)

        nPulsesInSelection = len(np.unique(photonsInPulseSelection['pulseNumber']))
        nSkyPulsesInSelection = len(np.unique(skyPhotonsInPulseSelection['pulseNumber']))
        if  nPulsesInSelection < nIdxOffsets or nSkyPulsesInSelection < nIdxOffsets:
            if verbose:
                print 'only ',nPulsesInSelection,' pulses for ',iGiantPN,giantPN
            continue
        startIdx = 0
        
        nPixels = 1.*nLivePixels[iPL]
        nSkyPixels = 1.*nSkyLivePixels[iPL]
        nongrpPeakWvls = np.array([])
        for iIdxOffset,idxOffset in enumerate(idxOffsets):
            pulseNumber = giantPN+idxOffset
            if giantPulseNumberMask[iGiantPN,iIdxOffset] == False or idxOffset==0:
                photons = photonsInPulseSelection[photonsInPulseSelection['pulseNumber']==pulseNumber]
                skyPhotons = skyPhotonsInPulseSelection[skyPhotonsInPulseSelection['pulseNumber']==pulseNumber]
                phases = photons['phase']
                wavelengths = photons['wavelength']
                skyPhases = skyPhotons['phase']
                skyWavelengths = skyPhotons['wavelength']
                count = 1.*len(photons)/nPixels
                skyCount = 1.*len(skyPhotons)/nSkyPixels
                counts[iGiantPN,iIdxOffset] = count
                skyCounts[iGiantPN,iIdxOffset] = skyCount

                profile,phaseBinEdges = np.histogram(phases,bins=nBins,range=(histStart,histEnd))
                skyProfile,phaseBinEdges = np.histogram(skyPhases,bins=nBins,range=(histStart,histEnd))
                
                indProfiles[iGiantPN,iIdxOffset] = profile/nPixels
                skyIndProfiles[iGiantPN,iIdxOffset] = skyProfile/nSkyPixels

                spectrum,_ = np.histogram(wavelengths,bins=wvlBinEdges)
                spectrum = 1.0*spectrum/(nPixels*wvlBinWidths)#convert to counts per pixel per angstrom
                fullSpectra[iIdxOffset] += spectrum

                skySpectrum,_ = np.histogram(skyWavelengths,bins=wvlBinEdges)
                skySpectrum = 1.0*skySpectrum/(nSkyPixels*wvlBinWidths)#convert to counts per pixel per angstrom
                skyFullSpectra[iIdxOffset] += skySpectrum

                phasesBinned = np.digitize(phases,phaseBinEdges)-1
                peakPhaseMask = np.logical_or(phasesBinned==(peakIdx-1),phasesBinned==peakIdx)
                peakPhaseMask = np.logical_or(peakPhaseMask,phasesBinned==(peakIdx+1))
                peakWvls = wavelengths[peakPhaseMask]
                if idxOffset == 0:
                    grpPeakWavelengthArrays.append(peakWvls)
                else:
                    nongrpPeakWvls = np.append(nongrpPeakWvls,peakWvls)

                peakSpectrum,_ = np.histogram(peakWvls,bins=wvlBinEdges)
                peakSpectrum = 1.0*peakSpectrum/(nPixels*wvlBinWidths)#convert to counts per pixel per angstrom
                peakSpectra[iIdxOffset] += peakSpectrum

                skyPhasesBinned = np.digitize(skyPhases,phaseBinEdges)-1
                skyPeakPhaseMask = np.logical_or(skyPhasesBinned==(peakIdx-1),skyPhasesBinned==peakIdx)
                skyPeakPhaseMask = np.logical_or(skyPeakPhaseMask,skyPhasesBinned==(peakIdx+1))
                skyPeakWvls = skyWavelengths[skyPeakPhaseMask]
                skyPeakSpectrum,_ = np.histogram(skyPeakWvls,bins=wvlBinEdges)
                skyPeakSpectrum = 1.0*skyPeakSpectrum/(nSkyPixels*wvlBinWidths)#convert to counts per pixel per angstrom
                skyPeakSpectra[iIdxOffset] += skyPeakSpectrum
#                phaseArrays[iIdxOffset].append(phases)
#                skyPhaseArrays[iIdxOffset].append(skyPhases)
#                wavelengthArrays[iIdxOffset].append(photons['wavelength'])
#                skyWavelengthArrays[iIdxOffset].append(skyPhotons['wavelength'])
        nongrpPeakWavelengthArrays.append(nongrpPeakWvls)


    if verbose:
        print 'done searching'
    outFile.createArray(outFile.root,'counts',counts)
    outFile.createArray(outFile.root,'skyCounts',skyCounts)
    outFile.createArray(outFile.root,'idxOffsets',idxOffsets)
    outFile.createArray(outFile.root,'radioMax',radioMax)
    outFile.createArray(outFile.root,'radioMean',radioMean)
    outFile.createArray(outFile.root,'indProfiles',indProfiles)
    outFile.createArray(outFile.root,'skyIndProfiles',skyIndProfiles)
    outFile.createArray(outFile.root,'phaseBinEdges',phaseBinEdges)
    outFile.createArray(outFile.root,'giantPulseNumbers',giantPulseNumbers)
    outFile.createArray(outFile.root,'giantPulseNumberMask',giantPulseNumberMask)
    outFile.createArray(outFile.root,'pulseNumberTable',pulseNumberTable)
    outFile.createArray(outFile.root,'radioIndices',radioDetectedIndices)
    outFile.createArray(outFile.root,'nPixels',nLivePixels)
    outFile.createArray(outFile.root,'nSkyPixels',nSkyLivePixels)
    outFile.createArray(outFile.root,'fullSpectra',fullSpectra)
    outFile.createArray(outFile.root,'skyFullSpectra',skyFullSpectra)
    outFile.createArray(outFile.root,'peakSpectra',peakSpectra)
    outFile.createArray(outFile.root,'skyPeakSpectra',skyPeakSpectra)
    outFile.createArray(outFile.root,'wvlBinEdges',wvlBinEdges)

    outFile.flush()
    outFile.close()
    if verbose:
        print 'done saving'
    def __init__(self,paramFile):
        """
        opens flat file,sets wavelength binnning parameters, and calculates flat factors for the file
        """
        self.params = readDict()
        self.params.read_from_file(paramFile)

        run = self.params['run']
        sunsetDate = self.params['sunsetDate']
        flatTstamp = self.params['flatTstamp']
        wvlSunsetDate = self.params['wvlSunsetDate']
        wvlTimestamp = self.params['wvlTimestamp']
        obsSequence = self.params['obsSequence']
        needTimeAdjust = self.params['needTimeAdjust']
        self.deadtime = self.params['deadtime'] #from firmware pulse detection
        self.intTime = self.params['intTime']
        self.timeSpacingCut = self.params['timeSpacingCut']
        self.nSigmaClip = self.params['nSigmaClip']
        self.nNearest = self.params['nNearest']

        obsFNs = [FileName(run=run,date=sunsetDate,tstamp=obsTstamp) for obsTstamp in obsSequence]
        self.obsFileNames = [fn.obs() for fn in obsFNs]
        self.obsList = [ObsFile(obsFileName) for obsFileName in self.obsFileNames]
        timeMaskFileNames = [fn.timeMask() for fn in obsFNs]
        timeAdjustFileName = FileName(run=run).timeAdjustments()

        print len(self.obsFileNames), 'flat files to co-add'
        self.flatCalFileName = FileName(run=run,date=sunsetDate,tstamp=flatTstamp).illumSoln()
        if wvlSunsetDate != '':
            wvlCalFileName = FileName(run=run,date=wvlSunsetDate,tstamp=wvlTimestamp).calSoln()
        for iObs,obs in enumerate(self.obsList):
            if wvlSunsetDate != '':
                obs.loadWvlCalFile(wvlCalFileName)
            else:
                obs.loadBestWvlCalFile()
            if needTimeAdjust:
                obs.loadTimeAdjustmentFile(timeAdjustFileName)
            timeMaskFileName = timeMaskFileNames[iObs]
            print timeMaskFileName
            #Temporary step, remove old hotpix file
            #if os.path.exists(timeMaskFileName):
            #    os.remove(timeMaskFileName)
            if not os.path.exists(timeMaskFileName):
                print 'Running hotpix for ',obs
                hp.findHotPixels(self.obsFileNames[iObs],timeMaskFileName,fwhm=np.inf,useLocalStdDev=True)
                print "Flux file pixel mask saved to %s"%(timeMaskFileName)
            obs.loadHotPixCalFile(timeMaskFileName)
        self.wvlFlags = self.obsList[0].wvlFlagTable

        self.nRow = self.obsList[0].nRow
        self.nCol = self.obsList[0].nCol
        print 'files opened'
        #self.wvlBinWidth = params['wvlBinWidth'] #angstroms
        self.energyBinWidth = self.params['energyBinWidth'] #eV
        self.wvlStart = self.params['wvlStart'] #angstroms
        self.wvlStop = self.params['wvlStop'] #angstroms
        self.wvlBinEdges = ObsFile.makeWvlBins(self.energyBinWidth,self.wvlStart,self.wvlStop)
        self.intTime = self.params['intTime']
        self.countRateCutoff = self.params['countRateCutoff']
        self.fractionOfChunksToTrim = self.params['fractionOfChunksToTrim']
        #wvlBinEdges includes both lower and upper limits, so number of bins is 1 less than number of edges
        self.nWvlBins = len(self.wvlBinEdges)-1
def cleanSpectrum(x,y,objectName, wvlBinEdges):
        #locations and widths of absorption features in Angstroms
        #features = [3890,3970,4099,4340,4860,6564,6883,7619]
        #widths = [50,50,50,50,50,50,50,50]
        #for i in xrange(len(features)):
        #    #check for absorption feature in std spectrum
        #    ind = np.where((x<(features[i]+15)) & (x>(features[i]-15)))[0]
        #    if len(ind)!=0:
        #        ind = ind[len(ind)/2]
        #    #if feature is found (flux is higher on both sides of the specified wavelength where the feature should be)
        #    if y[ind]<y[ind+1] and y[ind]<y[ind-1]:
        #        #cut out width[i] around feature[i]
        #        inds = np.where((x >= features[i]+widths[i]) | (x <= features[i]-widths[i]))
        #        x = x[inds]
        #        y = y[inds]

        #fit a tail to the end of the spectrum to interpolate out to desired wavelength in angstroms
        fraction = 0 #4.0/5.0
        newx = np.arange(int(x[fraction*len(x)]),20000)

        #slopeguess = (np.log(y[-1])-np.log(y[fraction*len(x)]))/(x[-1]-x[fraction*len(x)])
        #print "Guess at exponential slope is %f"%(slopeguess)
        #guess_a, guess_b, guess_c = float(y[fraction*len(x)]), x[fraction*len(x)], slopeguess
        #guess = [guess_a, guess_b, guess_c]

        fitx = x[fraction*len(x)::]
        fity = y[fraction*len(x)::]

        #exp_decay = lambda fx, A, x0, t: A * np.exp((fx-x0) * t)

        #params, cov = curve_fit(exp_decay, fitx, fity, p0=guess, maxfev=2000)
        #A, x0, t= params
        #print "A = %s\nx0 = %s\nt = %s\n"%(A, x0, t)
        #best_fit = lambda fx: A * np.exp((fx-x0)*t)

        #calcx = np.array(newx,dtype=float)
        #newy = best_fit(calcx)

        #normalizing
        norm = fity.max()
        fity/=norm

        guess_a, guess_b = 1/(2*h*c**2/1e-9), 5600 #Constant, Temp
        guess = [guess_a, guess_b]

        blackbody = lambda fx, N, T: N * 2*h*c**2 / (fx)**5 * (exp(h*c/(k*T*(fx))) - 1)**-1 # Planck Law
        #blackbody = lambda fx, N, T: N*2*c*k*T/(fx)**4 #Rayleigh Jeans tail
        #blackbody = lambda fx, N, T: N*2*h*c**2/(fx**5) * exp(-h*c/(k*T*fx)) #Wein Approx

        params, cov = curve_fit(blackbody, fitx*1.0e-8, fity, p0=guess, maxfev=2000)
        N, T= params
        print "N = %s\nT = %s\n"%(N, T)
        best_fit = lambda fx: N * 2*h*c**2 / (fx)**5 * (exp(h*c/(k*T*(fx))) - 1)**-1 #Planck Law
        #best_fit = lambda fx: N*2*c*k*T/(fx)**4 # Rayleigh Jeans Tail
        #best_fit = lambda fx: N*2*h*c**2/(fx**5) * exp(-h*c/(k*T*fx)) #Wein Approx

        calcx = np.array(newx,dtype=float)
        bbfit = best_fit(calcx*1.0E-8)

        calcx = np.array(newx,dtype=float)
        newy = best_fit(calcx*1.0E-8)

        fity*=norm
        newy*=norm

        plt.plot(calcx[3.0*len(fitx)/4.0::],newy[3.0*len(fitx)/4.0::]*1E15,linestyle='--',linewidth=2, color="black",alpha=0.5) #plot fit

        #func = interpolate.splrep(x[fration*len(x):],y[fraction*len(x):],s=smooth)
        #newx = np.arange(int(x[fraction*len(x)]),self.wvlBinEdges[-1])
        #newy = interpolate.splev(newx,func)

        wl = np.concatenate((x,newx[newx>max(x)]))
        flux = np.concatenate((y,newy[newx>max(x)]))

        #new method, rebin data to grid of wavelengths generated from a grid of evenly spaced energy bins
        #R=7.0 at 4500
        #R=E/dE -> dE = R/E
        dE = 0.3936 #eV
        start = 1000 #Angs
        stop = 25000 #Angs
        enBins = ObsFile.makeWvlBins(dE,start,stop)
        rebinned = rebin(wl,flux,enBins)
        re_wl = rebinned[:,0]
        re_flux = rebinned[:,1]
        plt.plot(re_wl,re_flux*1E15,linestyle="o", marker="o",markersize=6) #plot rebinned spectrum with exp tail
        
        re_wl = re_wl[np.isnan(re_flux)==False]
        re_flux = re_flux[np.isnan(re_flux)==False]

        start1 = wvlBinEdges[0]
        stop1 = wvlBinEdges[-1]
        #regrid downsampled data 

        new_wl = np.arange(start1,stop1)

        #print re_wl
        #print re_flux
        #print new_wl

        #weight=1.0/(re_flux)**(2/1.00)
        print len(re_flux)
        weight = np.ones(len(re_flux))
        #decrease weights near peak
        ind = np.where(re_flux == max(re_flux))[0]
        weight[ind] = 0.3
        for p in [1,2,3]:
            if p==1:
                wt = 0.3
            elif p==2:
                wt = 0.6
            elif p==3:
                wt = 0.7
            try:
                weight[ind+p] = wt
            except IndexError:
                 pass
            try:
                 if ind-p >= 0:
                     weight[ind-p] = wt
            except IndexError:
                pass
        #change weights to set how tightly fit must match data points
        #weight[-4:] = 1.0
        weight = 0.7*np.ones((len(re_wl)),dtype=float)
        #weight = [0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7]
        #print len(weight)
        #weight = re_flux/min(re_flux)
        #weight = 1.0/weight
        #weight = weight/max(weight)
        print weight
        f = interpolate.splrep(re_wl,re_flux,w=weight,k=2,s=0)#max(re_flux)**300)
        new_flux = interpolate.splev(new_wl,f,der=0)
        return new_wl, new_flux
Exemplo n.º 7
0
a = std.load(objectName)
stdWvls = np.array(a[:, 0], dtype=float)  # wavelengths in angstroms
stdFlux = np.array(a[:, 1], dtype=float)  # flux in counts/s/cm^2/Angs
stdFlux *= h * c * 1e10 / stdWvls  # flux in J/s/cm^2/Angs or W/cm^2/Angs


# cut spectrum arrays to our wavelength region
stdFlux = stdFlux[(stdWvls > 3000) & (stdWvls < 13000)]
stdWvls = stdWvls[(stdWvls > 3000) & (stdWvls < 13000)]


plt.plot(stdWvls[(stdWvls > 3158) & (stdWvls < 11089)], stdFlux[(stdWvls > 3158) & (stdWvls < 11089)])
total = integrate.simps(stdFlux[(stdWvls > 3158) & (stdWvls < 11089)], x=stdWvls[(stdWvls > 3158) & (stdWvls < 11089)])
print "Original total flux = ", total
# rebin test
dE = 0.3936  # eV
start = 3000  # Angs
stop = 13000  # Angs
for n in xrange(10):
    n = float(n) + 1.0
    enBins = ObsFile.makeWvlBins(dE / n, start, stop)
    rebinned = rebin(stdWvls, stdFlux, enBins)
    re_wl = rebinned[:, 0]
    re_flux = rebinned[:, 1]
    print re_wl[0]
    print re_wl[-1]
    plt.plot(re_wl[(re_wl > 3158) & (re_wl < 11089)], re_flux[(re_wl > 3158) & (re_wl < 11089)])
    total = integrate.simps(re_flux[(re_wl > 3158) & (re_wl < 11089)], x=re_wl[(re_wl > 3158) & (re_wl < 11089)])
    print "Total flux for dE = ", dE / n, "eV is ", total, "W/cm^2"
plt.show()
        obsSequence = obsSequences[iSeq]
        sunsetDate = sunsetDates[iSeq]
        plPaths.append([FileName(run=run,date=sunsetDate,tstamp=ts).photonList() for ts in obsSequence])

    obsTimestamps = np.concatenate(obsSequences)
    plPaths = [path for pathList in plPaths for path in pathList]

    nPhaseBins = 1500 #bin it finely, we can rebin later
    wvlStart = 3000 #angstrom
    wvlEnd = 13000 #angstrom
    wvlRange = (wvlStart,wvlEnd)
    centroidRaStr='03:37:43.826'
    centroidDecStr='14:15:14.828'


    wvlBinEdges = ObsFile.makeWvlBins(.01)
#    #open up the first photon list and extract the wavelength bin edges used to make the flatcal and fluxcal
#    pl0 = PhotList(plPaths[0])
#    wvlBinEdges = np.array(pl0.file.root.flatcal.wavelengthBins.read())
#    del pl0
    print wvlBinEdges


#    apertureData = np.loadtxt('smoothApertList.txt',dtype={'names':('obsTimestamp','oldApert','apertureRadius'),'formats':('S80','f8','f8')},delimiter='\t')
#    apertureRadiusDict = {eachItem['obsTimestamp']:eachItem['apertureRadius'] for eachItem in apertureData}
#    apertureList = [apertureRadiusDict[timestamp] for timestamp in obsTimestamps]
    

    foldPlBins = functools.partial(foldPl,nPhaseBins=nPhaseBins,wvlBinEdges=wvlBinEdges,wvlRange=wvlRange,centroidRaStr=centroidRaStr,centroidDecStr=centroidDecStr)
    def foldPlOneArg(foldArg):
        plPath,apertureRadius = foldArg