def __init__(self,drift_object,times_to_combine_str,save_plots=True):
        """
            Creates a drift_diagnositc object to load wavecal soln data into memory. Set's up outpath
        """
        self.drift = drift_object
        self.times_to_combine = [[strpdate2num("%Y%m%d-%H%M%S")(tstamp1),strpdate2num("%Y%m%d-%H%M%S")(tstamp2)] for [tstamp1,tstamp2] in times_to_combine_str]

        
        self.drift.mastercalFNs, self.params = getCalFileNames(self.drift.params,'mastercal_','_drift')
        self.save_plots=save_plots

        intermDir=self.params['intermDir']
        outdir=self.params['outdir']
        if intermDir is None or intermDir is '':
            intermDir = os.getenv('MKID_PROC_PATH', default="/Scratch")
        if outdir is None or outdir is '':
            outdir = '/waveCalSolnFiles'
        self.outpath=intermDir+outdir+os.sep+self.drift.driftFNs[0].run+os.sep+'master_cals'
        try:
            os.mkdir(self.outpath)
            os.mkdir(self.outpath+'/drift_study')
            if self.save_plots:
                os.mkdir(self.outpath+'/figs')
        except:
            pass
    def populate_drift_fluctuations(self):
        """
        Finds the fluctuations in each pixel for each mastercal time period

        The following needs to be run before:
            self.populate_peak_data()
            self.populate_master_peak_data()
            self.populate_master_times_data()
        """
        if hasattr(self, 'drift_fluct'):
            return
        if not hasattr(self, 'masterFNs'):
            self.masterFNs,p = getCalFileNames(self.params,'mastercal_','_drift.h5')
        if len(self.masterFNs)==0:
            print "No master cal files found!"
            return

        self.avg_drift_fluct = np.zeros((self.beammap.shape[0],self.beammap.shape[1],len(self.masterFNs)))
        self.drift_fluct = np.zeros((self.beammap.shape[0],self.beammap.shape[1],len(self.driftFNs)))
        for i in range(len(self.masterFNs)):
        #for i in [3]:
            indices_of_wavecals = (np.where((np.asarray(self.timeArray) >= self.master_start_time[i]) * (np.asarray(self.timeArray) <= self.master_end_time[i])))[0]

            flucts = [self.blue_xOffset[:,:,j] - self.master_blue[:,:,i] for j in indices_of_wavecals]
            for j in range(len(flucts)):
                flucts[j][np.where(self.master_blue[:,:,i] != 0)] = flucts[j][np.where(self.master_blue[:,:,i] != 0)]/self.master_blue[:,:,i][np.where(self.master_blue[:,:,i] != 0)]
                flucts[j][np.where(self.master_blue[:,:,i] == 0)] = 1.0
                
            for k in range(len(indices_of_wavecals)):
                self.drift_fluct[:,:,indices_of_wavecals[k]]=flucts[k]

            self.avg_drift_fluct[:,:,i] = np.asarray(np.ma.average(np.abs(flucts),axis=0,weights=np.abs(flucts)<1.0))
    def populate_master_times_data(self):
        if not hasattr(self, 'masterFNs'):
            self.masterFNs,p = getCalFileNames(self.params,'mastercal_','_drift.h5')
        if len(self.masterFNs)==0:
            print "No master cal files found!"
            return

        print "Collecting master wvlcal start and end times for "+str(self.driftFNs[0].run)+'...'
        self.master_start_time = np.zeros(len(self.masterFNs))
        self.master_end_time = np.zeros(len(self.masterFNs))
        for i in range(len(self.masterFNs)):
            try:
                driftFile=tables.openFile(self.masterFNs[i].mastercalDriftInfo(),mode='r')
                drift_times = driftFile.root.params_drift.drifttimes.cols.wavecal[:]
                drift_num_times = [strpdate2num("%Y%m%d-%H%M%S")(fname.split('_')[1].split('.')[0]) for fname in drift_times]
                #print drift_times
                self.master_start_time[i] = np.amin(drift_num_times)
                self.master_end_time[i] = np.amax(drift_num_times)
                driftFile.close()
            except:
                
                print '\tUnable to open: '+self.masterFNs[i].mastercalDriftInfo()

        #print self.master_start_time
        #print self.master_end_time
        print "\tDone."
    def populate_master_peak_data(self):
        if hasattr(self, 'master_blue'):
            return
        if not hasattr(self, 'masterFNs'):
            self.masterFNs,p = getCalFileNames(self.params,'mastercal_','_drift.h5')
        if len(self.masterFNs)==0:
            print "No master cal files found!"
            return

        print "Collecting master peak data for "+str(self.driftFNs[0].run)+'...'
        self.master_blue = np.zeros((self.beammap.shape[0],self.beammap.shape[1],len(self.masterFNs)))
        self.master_red = np.zeros((self.beammap.shape[0],self.beammap.shape[1],len(self.masterFNs)))
        self.master_IR = np.zeros((self.beammap.shape[0],self.beammap.shape[1],len(self.masterFNs)))
        for i in range(len(self.masterFNs)):
            try:
                driftFile=tables.openFile(self.masterFNs[i].mastercalDriftInfo(),mode='r')
                drift_row = driftFile.root.params_drift.driftparams.cols.pixelrow[:]    
                drift_col = driftFile.root.params_drift.driftparams.cols.pixelcol[:]    
                drift_params = driftFile.root.params_drift.driftparams.cols.avglaserphase[:]
                for p in range(len(drift_row)):
                    self.master_blue[drift_row[p],drift_col[p],i]=(drift_params[p])[0]
                    self.master_red[drift_row[p],drift_col[p],i]=(drift_params[p])[1]
                    self.master_IR[drift_row[p],drift_col[p],i]=(drift_params[p])[2]
                driftFile.close()
            except:
                print '\tUnable to open: '+self.masterFNs[i].mastercalDriftInfo()
                #raise
        print "\tDone."
    def populate_master_cal_data(self):
        if hasattr(self, 'master_parab_const'):
            return
        if not hasattr(self, 'masterFNs'):
            self.masterFNs,p = getCalFileNames(self.params,'mastercal_','_drift.h5')
        if len(self.masterFNs)==0:
            print "No master cal files found!"
            return

        print "Collecting Master Cal Data for "+str(self.driftFNs[0].run)+'...'
        self.master_parab_const=-1.0*np.ones((self.beammap.shape[0],self.beammap.shape[1],len(self.masterFNs)))
        self.master_parab_lin=-1.0*np.ones((self.beammap.shape[0],self.beammap.shape[1],len(self.masterFNs)))
        self.master_parab_quad=-1.0*np.ones((self.beammap.shape[0],self.beammap.shape[1],len(self.masterFNs)))

        for i in range(len(self.masterFNs)):
            try:
                calFile=tables.openFile(self.masterFNs[i].mastercalSoln(),mode='r')
                cal_row = calFile.root.wavecal.calsoln.cols.pixelrow[:]    
                cal_col = calFile.root.wavecal.calsoln.cols.pixelcol[:]    
                cal_params = calFile.root.wavecal.calsoln.cols.polyfit[:]
                for p in range(len(cal_row)):
                    self.master_parab_const[cal_row[p],cal_col[p],i]=(cal_params[p])[0]
                    self.master_parab_lin[cal_row[p],cal_col[p],i]=(cal_params[p])[1]
                    self.master_parab_quad[cal_row[p],cal_col[p],i]=(cal_params[p])[2]
                calFile.close()
            except:
                print '\tUnable to open: '+self.masterFNs[i].mastercalSoln()
                #raise
        print "\tDone."
    def populate_master_sig_range_data(self):
        if hasattr(self, 'master_sigma'):
            return
        if not hasattr(self, 'masterFNs'):
            self.masterFNs,p = getCalFileNames(self.params,'mastercal_','_drift.h5')
        if len(self.masterFNs)==0:
            print "No master cal files found!"
            return

        print "Collecting Master Sigma and Range Data for "+str(self.driftFNs[0].run)+'...'
        self.master_sigma=np.zeros((self.beammap.shape[0],self.beammap.shape[1],len(self.masterFNs)))
        self.master_range_min=np.zeros((self.beammap.shape[0],self.beammap.shape[1],len(self.masterFNs)))
        self.master_range_max=np.zeros((self.beammap.shape[0],self.beammap.shape[1],len(self.masterFNs)))

        for i in range(len(self.masterFNs)):
            try:
                calFile=tables.openFile(self.masterFNs[i].mastercalSoln(),mode='r')
                cal_row = calFile.root.wavecal.calsoln.cols.pixelrow[:]    
                cal_col = calFile.root.wavecal.calsoln.cols.pixelcol[:]    
                cal_range = calFile.root.wavecal.calsoln.cols.solnrange[:]
                cal_sigma = calFile.root.wavecal.calsoln.cols.sigma[:]
                for p in range(len(cal_row)):
                    self.master_range_min[cal_row[p],cal_col[p],i]=(cal_range[p])[0]
                    self.master_range_max[cal_row[p],cal_col[p],i]=(cal_range[p])[1]
                    self.master_sigma[cal_row[p],cal_col[p],i]=cal_sigma[p]
                calFile.close()
            except:
                print '\tUnable to open: '+self.masterFNs[i].mastercalSoln()
                #raise
        print "\tDone."
            # close the file, flush all remaining buffers
            driftCalFile.close()

        print '\tDone'




if __name__ == "__main__":
    try:
        paramFile = sys.argv[1]
    except IndexError:
        paramFile=os.getenv('PYTHONPATH',default=os.path.expanduser('~')+'/ARCONS-pipeline').split(':')[0]+'/params/waveCal.dict'
        #paramFile = '/home/abwalter/ARCONS-pipeline/params/waveCal.dict'
        print "Loading parameters from: "+paramFile
    calFNs, params = getCalFileNames(paramFile,'calsol_','_drift.h5',getAll=True)   #Automatically grabs all cal files
    drift_object = drift_object(calFNs,params)
    drift_object.populate_peak_data()


    #PAL2012
    #times_to_combine_str = [['20121206-030039', '20121206-034635'],         # Dec 5
    #                        ['20121206-044321', '20121206-115709'],         # Dec 5, realigned laser and retuned array
    #                        ['20121207-023127', '20121207-062840'],         # Dec 6
    #                        ['20121207-064749', '20121207-132325'],         # Dec 6, retuned
    #                        ['20121208-024054', '20121208-031248'],         # Dec 7, optimal filters from day 1, 2
    #                        ['20121208-031719', '20121208-063741'],         # Dec 7, template FIR filters
    #                        ['20121208-070505', '20121208-133818'],         # Dec 7, retuned
    #                        ['20121209-021609', '20121209-060704'],         # Dec 8
    #                        ['20121209-062404', '20121209-131132'],         # Dec 8, retuned
    #                        ['20121211-020441', '20121211-072632'],         # Dec 10
        
        for r in np.unique(self.roach_arr):
            hist_r, bin_edges = np.histogram(tempdrift[np.where(self.roach_arr==r)],bins=100,range=(-.2,.2))
            plt.plot(bins,hist_r,linestyle='steps-',label='roach '+str(int(r)))
        plt.legend()
        
        plt.show()


if __name__ == '__main__':
    try:
        paramFile = sys.argv[1]
    except IndexError:
        paramFile=os.getenv('PYTHONPATH',default=os.path.expanduser('~')+'/ARCONS-pipeline').split(':')[0]+'/params/waveCal.dict'
        print "Loading parameters from: "+paramFile
    driftFNs, params = getCalFileNames(paramFile,'calsol_','_drift.h5',getAll=True)
    
    try:
        drift = drift_object(driftFNs,params)
        #drift.populate_peak_data()
        #drift.plot_laser_xOffset(save=False)
        ##drift_ana.plot_fluct_map()
        #drift.plot_numSols_map(save=False)

        drift.populate_peak_data()
        drift.populate_master_peak_data()
        drift.populate_master_times_data()
        drift.populate_drift_fluctuations()
        #drift.plot_fluct_map(save=False)
        #drift.hist_fluct(save=False)
        drift.hist_wvlcal_fluct()