示例#1
0
    def get_dark_frame(self):
        '''
        takes however many dark files that are specified in the pipe.yml and computes the counts/pixel/sec for the sum
        of all the dark obs. This creates a stitched together long dark obs from all of the smaller obs given. This
        is useful for legacy data where there may not be a specified dark observation but parts of observations where
        the filter wheel was closed.

        If self.use_wavecal is True then a dark is not subtracted off since this just  takes into account total counts
        and not energy information

        :return: expected dark counts for each pixel over a flat observation
        '''
        if not self.dark_h5_file_names:
            dark_frame = np.zeros_like(self.spectralCubes[0][:, :, 0])
        else:
            self.dark_start = [self.cfg.flatcal.dark_data['start_times']]
            self.dark_int = [self.cfg.flatcal.dark_data['int_times']]
            self.dark_h5_file_names = [
                os.path.join(self.h5_directory,
                             str(t) + '.h5') for t in self.dark_start
            ]
            frames = np.zeros((140, 146, len(self.dark_start)))
            getLogger(__name__).info('Loading dark frames for Laser flat')

            for i, file in enumerate(self.dark_h5_file_names):
                obs = Photontable(file)
                frame = obs.getPixelCountImage(
                    integrationTime=self.dark_int[i])['image']
                frames[:, :, i] = frame
            total_counts = np.sum(frames, axis=2)
            total_int_time = float(np.sum(self.dark_int))
            counts_per_sec = total_counts / total_int_time
            dark_frame = counts_per_sec
        return dark_frame
示例#2
0
 def __init__(self):
     self.endtime = -1
     self.begintime = 0
     self.tick_duration = 1e-6
     self.ticks_per_sec = int(1.0 / self.tick_duration)
     self.nRow = 140
     self.nCol = 146
     self.h5file = 'test'
     self.obs = Photontable(self.h5file)
示例#3
0
    def __init__(self, configuration=None, h5_file_names=None, solution_name='solution.npz', interpolation=None,
                 use_satellite_spots=True, obj_pos=None):

        self.interpolation = interpolation
        self.use_satellite_spots = use_satellite_spots
        self.obj_pos = obj_pos

        self.flux_spectra = None
        self.flux_effTime = None
        self.wvl_bin_edges = None
        self.std_spectrum = None
        self.std_wvls = None
        self.std_flux = None
        self.rebin_std_wvls = None
        self.rebin_std_flux = None
        self.obs = None
        self.wvl_bin_widths = None
        self.curve = None
        self.image = None
        self.bb_flux = None
        self.bb_wvls = None
        self.conv_wvls = None
        self.conv_flux = None
        self.data = None
        self.rebin_plot_data = None
        self.wvl_bin_centers = None
        self.flux_spectrum = None
        self.cube = None
        self.aperture_centers = None
        self.aperture_radii = None
        self.errors=None
        self.contrast = None

        if h5_file_names:
            self.obs = [Photontable(f) for f in h5_file_names]
        if configuration:
            self.cfg = Configuration(configuration) if not isinstance(configuration, Configuration) else configuration
            self.obj_pos = self.cfg.obj_pos
            self.solution_name = solution_name
            self.use_satellite_spots = self.cfg.use_satellite_spots
            self.interpolation = self.cfg.interpolation
            self.obs = [Photontable(f) for f in self.cfg.h5_file_names]
            self.wvl_bin_widths = self.cfg.wvl_bin_widths
            self.wvl_bin_edges = self.cfg.wvl_bin_edges
            self.data = self.cfg.data
            self.wvl_bin_centers = self.cfg.wvl_bin_centers
            self.contrast = np.zeros_like(self.wvl_bin_centers)
            self.aperture_centers = np.zeros((len(self.wvl_bin_centers), 2))
            self.aperture_radii = np.zeros_like(self.wvl_bin_centers)
            self.platescale = self.data.wcscal.platescale
            self.solution = ResponseCurve(configuration=self.cfg, curve=self.curve, wvl_bin_widths=self.wvl_bin_widths,
                                          wvl_bin_centers= self.wvl_bin_centers, cube=self.cube,
                                          solution_name=self.solution_name, errors=self.errors)
示例#4
0
def fetchimg(ob, kwargs):
    of = Photontable(ob.h5)
    if kwargs['nwvl'] > 1:
        im = of.getSpectralCube(hdu=True, **kwargs)
    else:
        kwargs.pop('wvlN', None)
        im = of.getPixelCountImage(hdu=True, **kwargs)
    del of

    #TODO move to photontable and fetch it from an import
    im.headerh['PIXELA'] = 10.0**2
    return im
示例#5
0
 def make_spectralcube(self):
     '''
     called from loadFlatSpectra
     :return:
     list of counts per second cubes, list of all of the integration times used to make the count per second cubes,
     bag pixel mask
     '''
     wavelengths = self.wavelengths
     nWavs = len(self.wavelengths)
     ntimes = self.cfg.flatcal.nchunks
     if np.any(
             self.intTime * self.cfg.flatcal.nchunks > self.exposure_times):
         ntimes = int((self.exposure_times / self.intTime).max())
         getLogger(__name__).info(
             'Number of chunks * chunk time is longer than the laser exposure. Using full'
             'length of exposure ({} chunks)'.format(ntimes))
     cps_cube_list = np.zeros([ntimes, self.xpix, self.ypix, nWavs])
     mask = np.zeros([self.xpix, self.ypix, nWavs])
     int_times = np.zeros([self.xpix, self.ypix, nWavs])
     if self.use_wavecal:
         delta_list = wavelengths / self.r_list
     for iwvl, wvl in enumerate(wavelengths):
         obs = Photontable(self.h5_file_names[iwvl])
         # mask out hot pixels before finding the mean
         if not obs.info['isBadPixMasked'] and not self.use_wavecal:
             getLogger(__name__).info(
                 'Hot pixel masking laser h5 file for flatcal')
             badpix.mask_hot_pixels(self.h5_file_names[iwvl])
         bad_mask = obs.flagMask(pixelflags.PROBLEM_FLAGS)
         mask[:, :, iwvl] = bad_mask
         if self.use_wavecal:
             counts = obs.getTemporalCube(
                 integrationTime=self.intTime * self.cfg.flatcal.nchunks,
                 timeslice=self.intTime,
                 startw=wvl - (delta_list[iwvl] / 2.),
                 stopw=wvl + (delta_list[iwvl] / 2.))
         else:
             counts = obs.getTemporalCube(
                 integrationTime=self.cfg.flatcal.chunk_time *
                 self.cfg.flatcal.nchunks,
                 timeslice=self.intTime)
         getLogger(__name__).info('Loaded {}nm spectral cube'.format(wvl))
         cps_cube = counts[
             'cube'] / self.intTime  # TODO move this division outside of the loop
         cps_cube = np.moveaxis(cps_cube, 2, 0)
         int_times[:, :, iwvl] = self.intTime
         cps_cube_list[:, :, :, iwvl] = cps_cube
     return cps_cube_list, int_times, mask
示例#6
0
    def handle_existing(self):
        """ Handles existing h5 files, deleting them if appropriate"""
        if os.path.exists(self.cfg.h5file):

            if self.force:
                getLogger(__name__).info('Remaking {} forced'.format(
                    self.cfg.h5file))
                done = False
            else:
                try:
                    done = Photontable(
                        self.cfg.h5file).duration >= self.cfg.inttime
                    if not done:
                        getLogger(__name__).info(
                            ('{} does not contain full duration, '
                             'will remove and rebuild').format(
                                 self.cfg.h5file))
                except:
                    done = False
                    getLogger(__name__).info(
                        ('{} presumed corrupt,'
                         ' will remove and rebuild').format(self.cfg.h5file),
                        exc_info=True)
            if not done:
                try:
                    os.remove(self.cfg.h5file)
                    getLogger(__name__).info('Deleted {}'.format(
                        self.cfg.h5file))
                except FileNotFoundError:
                    pass
            else:
                getLogger(__name__).info(
                    'H5 {} already built. Remake not requested. Done.'.format(
                        self.cfg.h5file))
                self.done = True
示例#7
0
def getPixelPhotonList(filename, xCoord, yCoord, **kwargs):
    """
    Gets the list of photon arrival times from a H5 file
    
    INPUTS:
        filename - Name of H5 data file
        xCoord - 
        yCoord - 
        **kwargs - keywords for Obsfile getpixelphotonlist()
    OUTPUTS:
        ts - timestamps in us of photon arrival times
    """
    obs = Photontable(filename)
    photonList = obs.getPixelPhotonList(xCoord, yCoord, **kwargs)
    times = photonList['Time']
    print("#photons: " + str(len(times)))
    del obs  #make sure to close files nicely
    return times
示例#8
0
    def plot_counts_on_array(self, obsFile, timeStep=10):
        obs = Photontable(obsFile)
        photons = obs.photonTable.read()

        hist = np.bincount((photons['Time'] / timeStep).astype(int))
        timestamps = np.linspace(0, photons['Time'].max(), len(hist))

        plt.plot(timestamps, hist, linewidth=0.3)
        plt.xlabel('Time (microseconds)')
        plt.ylabel('Counts on Array')
        plt.title(f"Array Count Time Stream ({obsFile})")
示例#9
0
    def determine_mean_photperRID(self):
        ret = {}
        # return {d:1 for d in self.datasets}

        for d in self.datasets:
            if d in self.count_images:
                cnt_img = self.count_images[d]
            else:
                res = list(self.query_iter((SHORTT_QUERY), dataset=d))
                i = np.array([r.queryt for r in res]).argmin()
                fast_file = res[i].file
                print('This might take a while: {:.0f} s'.format(
                    res[i].queryt))
                of = Photontable(fast_file)
                cnt_img = of.getPixelCountImage(firstSec=30,
                                                integrationTime=5)['image']
                cnt_img *= of.info['expTime'] / 5
                del of
                self.count_images[d] = cnt_img
            ret[d] = cnt_img.sum() / (cnt_img > 0).sum()
        return ret
示例#10
0
    def loadData(self):
        getLogger(__name__).info('Loading calibration data from {}'.format(
            self.h5file))
        self.obs = Photontable(self.h5file)
        if not self.obs.wavelength_calibrated:
            raise RuntimeError('Photon data is not wavelength calibrated.')
        self.beamImage = self.obs.beamImage
        self.wvlFlags = pixelflags.beammap_flagmap_to_h5_flagmap(
            self.obs.beamFlagImage)
        self.xpix = self.obs.nXPix
        self.ypix = self.obs.nYPix

        self.energies = [(c.h * c.c) / (i * 10**(-9) * c.e)
                         for i in self.wavelengths]
        middle = int(len(self.wavelengths) / 2.0)
        self.energyBinWidth = self.energies[middle] / (5.0 *
                                                       self.r_list[middle])

        self.wvlBinEdges = Photontable.makeWvlBins(self.energyBinWidth,
                                                   self.wvlStart, self.wvlStop)
        self.wavelengths = self.wvlBinEdges[:-1] + np.diff(self.wvlBinEdges)
        self.wavelengths = self.wavelengths.flatten()
        self.sol = False
示例#11
0
        time.time())

    args = parser.parse_args()

    flattner = WhiteCalibrator(args.cfgfile,
                               cal_file_name='calsol_{}.h5'.format(timestamp))

    if not os.path.isfile(flattner.cfg.h5file):
        raise RuntimeError('Not up to date')
        b2h_config = bin2hdf.Bin2HdfConfig(datadir=flattner.cfg.paths.data,
                                           beamfile=flattner.cfg.beammap.file,
                                           outdir=flattner.paths.out,
                                           starttime=flattner.cfg.start_time,
                                           inttime=flattner.cfg.expTime,
                                           x=flattner.cfg.beammap.ncols,
                                           y=flattner.cfg.beammap.ncols)
        bin2hdf.makehdf(b2h_config, maxprocs=1)
        getLogger(__name__).info('Made h5 file at {}.h5'.format(
            flattner.cfg.start_time))

    obsfile = Photontable(flattner.h5file, mode='write')
    if not obsfile.wavelength_calibrated:
        obsfile.applyWaveCal(wavecal.load_solution(flattner.cfg.wavesol))
        getLogger(__name__).info('Applied Wavecal {} to {}.h5'.format(
            flattner.cfg.wavesol, flattner.h5file))

    if args.h5only:
        exit()

    flattner.makeCalibration()
示例#12
0
def mask_hot_pixels(file,
                    method='hpm_flux_threshold',
                    step=30,
                    startt=0,
                    stopt=None,
                    ncpu=1,
                    **methodkw):
    """
    This routine is the main code entry point of the bad pixel masking code.
    Takes an obs. file as input and writes a 'bad pixel table' to that h5 file where each entry is an indicator of
    whether the pixel was good, dead, hot, or cold.  Defaults should be somewhat reasonable for a typical on-sky image.
    HPCut method is interchangeable with any of the methods listed here.

    The HOT and DEAD masks are combined into a single BAD mask at the end

    Required Input:
    :param obsfile:           user passes an obsfile instance here
    :param startt         Scalar Integer.  Timestamp at which to begin bad pixel masking, default = 0
    :param stopt           Scalar Integer.  Timestamp at which to finish bad pixel masking, default = -1
                                               (run to the end of the file)
    :param step          Scalar Integer.  Number of seconds to do the bad pixel masking over (should be an integer
                                               number of steps through the obsfile), default = 30
    :param hpcutmethod        String.          Method to use to detect hot pixels.  Options are:
                                               hpm_median_movingbox
                                               hpm_flux_threshold
                                               hpm_laplacian
                                               hpm_cps_cut

    Other Input:
    Appropriate args and kwargs that go into the chosen hpcut function

    :return:
    Applies relevant pixelflags - see pixelflags.py
    """
    obs = Photontable(file)
    if obs.info['isBadPixMasked']:
        getLogger(__name__).info('{} is already bad pixel calibrated'.format(
            obs.fileName))
        return

    if stopt is None:
        stopt = obs.getFromHeader('expTime')
    assert startt < stopt
    if step > stopt - startt:
        getLogger(__name__).warning((
            'Hot pixel step time longer than exposure time by {:.0f} s, using full '
            'exposure').format(abs(stopt - startt - step)))
        step = stopt - startt

    step_starts = np.arange(
        startt, stopt, step,
        dtype=int)  # Start time for each step (in seconds).
    step_ends = step_starts + int(step)  # End time for each step
    step_ends[step_ends > stopt] = int(
        stopt
    )  # Clip any time steps that run over the end of the requested time range.

    # Initialise stack of masks, one for each time step
    hot_masks = np.zeros([obs.nXPix, obs.nYPix, step_starts.size], dtype=bool)
    cold_masks = np.zeros([obs.nXPix, obs.nYPix, step_starts.size], dtype=bool)
    func = globals()[method]

    # Generate a stack of bad pixel mask, one for each time step
    for i, each_time in enumerate(step_starts):
        getLogger(__name__).info('Processing time slice: {} - {} s'.format(
            each_time, each_time + step))
        raw_image_dict = obs.getPixelCountImage(
            firstSec=each_time,
            integrationTime=step,
            applyWeight=True,
            applyTPFWeight=True,
            scaleByEffInt=method == 'hpm_cps_cut')
        bad_pixel_solution = func(raw_image_dict['image'], **methodkw)
        hot_masks[:, :, i] = bad_pixel_solution['hot_mask']
        cold_masks[:, :, i] = bad_pixel_solution['cold_mask']
    unstable_mask = np.zeros((obs.nXPix, obs.nYPix), dtype=bool)
    for x in range(obs.nXPix):
        for y in range(obs.nYPix):
            vals = np.zeros(len(hot_masks[x, y, :]), dtype=bool)
            for i, mask in enumerate(hot_masks[x, y, :]):
                vals[i] = mask
            if not all(vals) or all(vals):
                unstable_mask[x, y] = False
            else:
                unstable_mask[x, y] = True

    # Combine the bad pixel masks into a master mask
    obs.enablewrite()
    obs.applyBadPixelMask(np.all(hot_masks, axis=-1),
                          np.all(cold_masks, axis=-1), unstable_mask)
    obs.disablewrite()
示例#13
0
    9459, 9460, 9461, 9462, 9463, 9464, 9465, 9466, 9467, 9468, 9469, 9470,
    9471, 9472, 9473, 9474, 9475, 9476, 9477, 9478, 9479, 9480, 9481, 9482,
    9483, 9484, 9485, 9486, 9487, 9488, 9489, 9490, 9491, 9492, 9493, 9494,
    9495, 9496, 9497, 9498, 9499, 9500, 9501, 9502, 9503, 9504, 9505
])

print('Warning: Only run this script once per file')
print(fns)
tmp = ''
while tmp not in ['Y', 'N']:
    tmp = input('Are you sure you want to run this script? (Y/N)')
    tmp = tmp.upper()
if tmp == 'Y':
    for fn in fns:
        print('Adjusting flags in: ' + fn)
        obs = Photontable(fn, mode='w')
        resIDs = obs.beamImage[:, :]
        flags = obs.beamFlagImage[:, :]

        resID_noBeammap = resIDs[np.where(np.bitwise_and(flags, 1) > 0)]
        resID_beammap = resIDs[np.where(np.bitwise_and(flags, 1) == 0)]
        print('ResIDs with a DAC Tone that failed the beammap:')
        print(resID_withTone[np.where(np.isin(resID_withTone,
                                              resID_noBeammap))])
        print(
            'ResIDs without a DAC Tone that passed the beammaped (should be none):'
        )
        print(resID_beammap[np.where(
            np.isin(resID_beammap, resID_withTone, invert=True))])

        resID_wvlCal = resIDs[np.where(np.bitwise_and(flags, 2) == 0)]
示例#14
0
class WhiteCalibrator(FlatCalibrator):
    """
    Opens flat file using parameters from the param file, sets wavelength binning parameters, and calculates flat
    weights for flat file.  Writes these weights to a h5 file and plots weights both by pixel
    and in wavelength-sliced images.
    """
    def __init__(self, config=None, cal_file_name='flatsol_{start}.h5'):
        """
        Reads in the param file and opens appropriate flat file.  Sets wavelength binning parameters.
        """
        super().__init__(config)
        self.startTime = self.cfg.start_time
        self.expTime = self.cfg.exposure_time
        self.h5file = self.cfg.get(
            'h5file',
            os.path.join(self.cfg.paths.out,
                         str(self.startTime) + '.h5'))
        self.flatCalFileName = self.cfg.get(
            'flatname',
            os.path.join(self.cfg.paths.database,
                         cal_file_name.format(start=self.startTime)))

    def loadData(self):
        getLogger(__name__).info('Loading calibration data from {}'.format(
            self.h5file))
        self.obs = Photontable(self.h5file)
        if not self.obs.wavelength_calibrated:
            raise RuntimeError('Photon data is not wavelength calibrated.')
        self.beamImage = self.obs.beamImage
        self.wvlFlags = pixelflags.beammap_flagmap_to_h5_flagmap(
            self.obs.beamFlagImage)
        self.xpix = self.obs.nXPix
        self.ypix = self.obs.nYPix

        self.energies = [(c.h * c.c) / (i * 10**(-9) * c.e)
                         for i in self.wavelengths]
        middle = int(len(self.wavelengths) / 2.0)
        self.energyBinWidth = self.energies[middle] / (5.0 *
                                                       self.r_list[middle])

        self.wvlBinEdges = Photontable.makeWvlBins(self.energyBinWidth,
                                                   self.wvlStart, self.wvlStop)
        self.wavelengths = self.wvlBinEdges[:-1] + np.diff(self.wvlBinEdges)
        self.wavelengths = self.wavelengths.flatten()
        self.sol = False

    def loadFlatSpectra(self):
        """
        Reads the flat data into a spectral cube whose dimensions are determined
        by the number of x and y pixels and the number of wavelength bins.
        Each element will be the spectral cube for a time chunk
        Find factors to correct nonlinearity due to deadtime in firmware

        To be used for whitelight flat data
        """

        self.spectralCubes = []
        self.cubeEffIntTimes = []
        for firstSec in range(0, self.expTime,
                              self.intTime):  # for each time chunk
            cubeDict = self.obs.getSpectralCube(firstSec=firstSec,
                                                integrationTime=self.intTime,
                                                applyWeight=False,
                                                applyTPFWeight=False,
                                                wvlBinEdges=self.wvlBinEdges)
            cube = cubeDict['cube'] / cubeDict['effIntTime'][:, :, None]
            # TODO:  remove when we have deadtime removal code in pipeline
            cube /= (1 - cube.sum(axis=2) * self.deadtime)[:, :, None]
            bad = np.isnan(
                cube
            )  # TODO need to update masks to note why these 0s appeared
            cube[bad] = 0

            self.spectralCubes.append(cube)
            self.cubeEffIntTimes.append(cubeDict['effIntTime'])
            msg = 'Loaded Flat Spectra for seconds {} to {}'.format(
                int(firstSec),
                int(firstSec) + int(self.intTime))
            getLogger(__name__).info(msg)

        self.spectralCubes = np.array(self.spectralCubes[0])
        # Haven't had a chance to check if the following lines break - find me if you come across this before me - Sarah
        self.cubeEffIntTimes = np.array(self.cubeEffIntTimes)
        self.countCubes = self.cubeEffIntTimes * self.spectralCubes
示例#15
0
class Cosmic:
    def __init__(self):
        self.endtime = -1
        self.begintime = 0
        self.tick_duration = 1e-6
        self.ticks_per_sec = int(1.0 / self.tick_duration)
        self.nRow = 140
        self.nCol = 146
        self.h5file = 'test'
        self.obs = Photontable(self.h5file)

    def findCosmics(self,
                    stride=10,
                    threshold=100,
                    population_max=2000,
                    nsigma=5,
                    pps_stride=10000):
        """
        Find cosmics ray suspects.  Histogram the number of photons
        recorded at each timeStamp.  When the number of photons in a
        group of stride timeStamps is greater than threshold in second
        iSec, add (iSec,timeStamp) to cosmicTimeLists.  Also keep
        track of the histogram of the number of photons per stride
        timeStamps.
        return a dictionary of 'populationHg', 'cosmicTimeLists',
        'binContents', 'timeHgValues', 'interval', 'frameSum', and 'pps'

        populationHg is a histogram of the number of photons in each time bin.
        This is a poisson distribution with a long tail due to cosmic events

        cosmicTimeLists is a numpy array  of all the sequences that are
        suspects for cosmic rays
        binContents corresponds to cosmicTimeLists.  For each time in
        cosmicTimeLists, binContents is the number of photons detected
        at that time.

        timeHgValues is a histogram of the number of photons in each time
        interval

        frameSum is a two dimensional  numpy array of the number of photons
        detected by each pixel
        interval is the interval of data to be masked out
        pps is photons per second, calculated every ppsStride bins.
        """

        ###self.logger.info("findCosmics: begin stride=%d threshold=%d populationMax=%d nSigma=%d writeCosmicMask=%s")

        exptime = self.endtime - self.begintime
        nbins = int(np.round(self.ticks_per_sec * exptime + 1))
        bins = np.arange(0, nbins, 1)
        timehist_values, framesum = self.get_timehist_and_framesum(
            self.begintime, self.endtime)
        remainder = len(timehist_values) % pps_stride
        if remainder > 0:
            temp = timehist_values[:-remainder]
        else:
            temp = timehist_values
        pps_time = (pps_stride * self.tick_duration)
        pps = np.sum(temp.reshape(-1, pps_stride), axis=1) / pps_time
        cr_pop = Cosmic.population_from_timehist_values(
            timehist_values, population_max, stride, threshold)

        # now build up all of the intervals in seconds

        i = interval()
        icount = 0
        seconds_per_tick = self.tick_duration
        for cosmic_time in cr_pop['cosmic_time_list']:

            t0 = self.begintime + cosmic_time * seconds_per_tick
            dt = stride * seconds_per_tick
            t1 = t0 + dt
            left = max(self.begintime, t0 - nsigma * dt)
            right = min(self.endtime, t1 + 2 * nsigma * dt)
            i = i | interval[left, right]
            icount += 1

        times_masked = Cosmic.count_masked_bins(i)
        ppm_masked = 1000000 * times_masked / (self.endtime - self.begintime)

        return_val = {}
        return_val['timehist_values'] = timehist_values
        return_val['population_hist'] = cr_pop['population_hist']
        return_val['cosmic_timelist'] = cr_pop['cosmic_timelist']
        return_val['bin_contents'] = cr_pop['bin_contents']
        return_val['framesum'] = framesum
        return_val['interval'] = i
        return_val['ppm_masked'] = ppm_masked
        return_val['pps'] = pps
        return_val['pps_time'] = pps_time

        return return_val

    def get_timehist_and_framesum(self, begintime, endtime):
        integrationtime = endtime - begintime
        nbins = int(np.round(self.ticks_per_sec * integrationtime + 1))
        timehist_values = np.zeros(nbins, dtype=np.int64)
        framesum = np.zeros((self.nRow, self.nCol))
        for iRow in range(self.nRow):
            for iCol in range(self.nCol):
                gtpl = self.obs.getPixelPhotonList(
                    iRow,
                    iCol,
                    firstSec=begintime,
                    integrationtime=integrationtime)
                timestamps = gtpl['timestamps']
                if timestamps.size > 0:
                    timestamps = (timestamps - begintime) * self.ticks_per_sec
                    ts32 = np.round(timestamps).astype(np.uint32)
                    ts_binner.ts_binner32(ts32, timehist_values)
                    framesum[iRow, iCol] += ts32.size

        return timehist_values, framesum

    @staticmethod
    def count_masked_bins(mask_interval):
        return_val = 0
        for x in mask_interval:
            return_val += x[1] - x[0]
        return return_val

    @staticmethod
    def population_from_timehist_values(timehist_values, population_max,
                                        stride, threshold):
        """
        Rebin the timehist_values histogram by combining stride bins.  If
        stride > 1, then bin a second time after shifting by stride/2
        Create population_hist, a histogram of the number of photons in
        the large bins.  Also, create (and then sort) a list
        cosmic_timelist of the start of bins (in original time units)
        of overpopulated bins that have more than threshold number of
        photons.
        return a dictionary containing population_hist and cosmic_timelist
        """
        pop_range = (-0.5, population_max - 0.5)
        if stride == 1:
            population_hist = np.histogram(timehist_values,
                                           population_max,
                                           range=pop_range)
            cosmic_timelist = np.where(timehist_values > threshold)[0]
            bin_contents = np.extract(timehist_values > threshold,
                                      timehist_values)
        else:
            # rebin the timehist_values before counting the populations
            length = timehist_values.size
            remainder = length % stride
            if remainder == 0:
                end = length
            else:
                end = -remainder

            timehist_values_trimmed = timehist_values[0:end]

            timehist_values_rebinned_0 = np.reshape(
                timehist_values_trimmed, [length / stride, stride]).sum(axis=1)
            population_hist_0 = np.histogram(timehist_values_rebinned_0,
                                             population_max,
                                             range=pop_range)
            cosmic_timelist_0 = stride * np.where(
                timehist_values_rebinned_0 > threshold)[0]
            bin_contents_0 = np.extract(timehist_values_rebinned_0 > threshold,
                                        timehist_values_rebinned_0)

            timehist_values_rebinned_1 = np.reshape(
                timehist_values_trimmed[stride / 2:-stride / 2],
                [(length - stride) / stride, stride]).sum(axis=1)
            population_hist_1 = np.histogram(timehist_values_rebinned_1,
                                             population_max,
                                             range=pop_range)
            cosmic_timelist_1 = (stride / 2) + stride * np.where(
                timehist_values_rebinned_1 > threshold)[0]
            bin_contents_1 = np.extract(timehist_values_rebinned_1 > threshold,
                                        timehist_values_rebinned_1)

            population_hist = (population_hist_0[0] + population_hist_1[0],
                               population_hist_0[1])
            cosmic_timelist = np.concatenate(
                (cosmic_timelist_0, cosmic_timelist_1))
            bin_contents = np.concatenate((bin_contents_0, bin_contents_1))
            args = np.argsort(cosmic_timelist)
            cosmic_timelist = cosmic_timelist[args]
            bin_contents = bin_contents[args]
            cosmic_timelist.sort()

        return_val = {}
        return_val['population_hist'] = population_hist
        return_val['cosmic_timelist'] = cosmic_timelist
        return_val['bin_contents'] = bin_contents
        return return_val
        planet_photons = np.array(planet_photons).T.astype(np.float32)
        planet_photons = np.insert(planet_photons,
                                   obj=1,
                                   values=cam.phase_cal(ap.wvl_range[0]),
                                   axis=0)
        planet_photons[0] = (planet_photons[0] + abs_step) * sp.sample_time
        photons = np.concatenate((star_photons, planet_photons), axis=1)

        # cam.save_photontable(photonlist=photons, index=None, populate_subsidiaries=False)
        stem = cam.arange_into_stem(photons.T,
                                    (cam.array_size[1], cam.array_size[0]))
        stem = list(map(list, zip(*stem)))
        stem = cam.remove_close(stem)
        photons = cam.ungroup(stem)
        photons = photons[[0, 1, 3, 2]]
        # grid(cam.rebin_list(photons), show=False)
        cam.populate_photontable(photons=photons, finalise=False)
    cam.populate_photontable(photons=[], finalise=True)
    grid(cam.rebin_list(photons), show=False)

    # to look at the photontable
    obs = Photontable(iop.photonlist)
    print(obs.photonTable)

    # to plot an image of all the photons on the array
    image = obs.getPixelCountImage(integrationTime=None)['image']
    quick2D(image, show=False, title='Const planet photons')

    plt.show(block=True)
示例#17
0
    def getTotalCountsAndDuration(self, obsFilePath):
        counts = np.zeros((len(self.resIDs), len(BF_LASER_WAVELENGTHS)))
        cosmicCounts = np.zeros((len(self.resIDs), len(BF_LASER_WAVELENGTHS)))
        durations = np.zeros((len(self.resIDs), len(BF_LASER_WAVELENGTHS)))

        thresh = 4

        if thresh is not None:
            print(
                f"Using a threshold of {thresh} counts per bin to identify cosmic ray events in {obsFilePath}"
            )

        obs = Photontable(obsFilePath)
        cosmicPeaks, cosmicCutout = self.findCosmicRayTimeStamps(
            obs.photonTable.read(), threshold=thresh)
        s1 = time.time()
        for count1, j in enumerate(self.resIDs):
            if (count1 % 40) == 0:
                print(
                    f"{count1 / len(self.resIDs) * 100:.2f}% done with obsFile {obsFilePath}"
                )

            if obs.duration >= 60:
                duration = 60
            else:
                duration = obs.duration

            timeRemoved = len(cosmicCutout) / 1e6

            for count2, _ in enumerate(BF_LASER_WAVELENGTHS):
                photonList = obs.getPixelPhotonList(
                    resid=j,
                    wvlStart=self.wlLimits[0][count2],
                    wvlStop=self.wlLimits[1][count2],
                    integrationTime=60)

                cosmicCount = [
                    np.any(np.in1d(cosmicCutout, k))
                    for k in photonList['Time']
                ]
                photonsToRemove = np.sum(cosmicCount)

                counts[count1][count2] = len(photonList)
                durations[count1][count2] = (duration - timeRemoved)
                cosmicCounts[count1][count2] = photonsToRemove

        temp = np.concatenate((self.resIDs[:, None], counts, cosmicCounts,
                               durations[:, 0][:, None]),
                              axis=1)
        data = np.core.records.fromarrays(
            temp.transpose(),
            names=
            'ResID, bin1, bin2, bin3, bin4, bin5, bin1cosmics, bin2cosmics, bin3cosmics, bin4cosmics, bin5cosmics, duration',
            formats='i4, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8')

        e1 = time.time()
        print(
            f"--- It took {int(e1 - s1)} seconds to generate counts from Photontable {obsFilePath} ---"
        )
        obs.file.close()
        return data
示例#18
0
def test_settings(cfg,
                  settings,
                  queries,
                  do_build=True,
                  do_query=True,
                  cleanup=True,
                  recovery=''):

    if recovery:
        try:
            with open(recovery, 'rb') as f:
                results = pickle.load(f)
        except IOError:
            results = {}

    builders = []
    h5s = ['{}_{}.h5'.format(cfg.h5file[:-3], setting_id(s)) for s in settings]

    for s, h5 in zip(settings, h5s):
        builder = bin2hdf.HDFBuilder(copy.copy(cfg))
        builder.cfg.user_h5file = h5
        builder.kwargs = s
        builders.append(builder)

    needed = {b.cfg.h5file: False for b in builders}

    for b in builders:
        if b.cfg.h5file not in results:
            needed[b.cfg.h5file] = do_build
        elif do_query:
            for q in queries:
                if str(q) not in results[b.cfg.h5file]:
                    needed[b.cfg.h5file] = do_build
                    break

    for b in builders:
        if not (needed[b.cfg.h5file] and not os.path.exists(b.cfg.h5file)):
            continue
        tic = time.time()
        b.run()
        toc = time.time()
        results[b.cfg.h5file] = dict(creation=toc - tic)
        of = Photontable(b.cfg.h5file)
        results[b.cfg.h5file].update(
            dict(size=os.stat(b.cfg.h5file).st_size / 1024**2,
                 nphotons=len(of.photonTable),
                 file_nfo=str(of),
                 table_nfo=repr(of.photonTable)))
        del of
        if recovery:
            with open(recovery, 'wb') as f:
                pickle.dump(results, f)

    if not do_query:
        queries = []

    for q in queries:
        for b in builders:
            key = b.cfg.h5file
            if key not in results or not os.path.exists(b.cfg.h5file):
                getLogger(__name__).info(
                    f'No result record/file for {b.cfg.h5file}')
                continue
            if str(q) in results[key]:
                continue
            of = Photontable(b.cfg.h5file)
            tic = time.time()
            result = of.query(**q)
            toc = time.time()
            del of
            results[key][str(q)] = {'time': toc - tic, 'nphotons': len(result)}
            if recovery:
                with open(recovery, 'wb') as f:
                    pickle.dump(results, f)

    if cleanup:
        for f in h5s:
            os.remove(f)

    return results
示例#19
0
def tsectest(f):
    of = Photontable(f)
    # p=LineProfiler(of.photonTable._where)
    # p.enable()
    of.query(startt=0, intt=30)
示例#20
0
def get_transforms(ditherfile,
                   datadir,
                   wvl_start=None,
                   wvl_stop=None,
                   fwhm_guess=3.0,
                   fit_power=1,
                   CONEX_ERROR=0.0001,
                   plot=False):
    dither = MKIDDitheredObservation(os.path.basename(ditherfile), ditherfile,
                                     None, None)
    obs_files = [
        os.path.join(datadir, '{}.h5'.format(o.start)) for o in dither.obs
    ]

    box_size = fwhm_guess * 10

    debug_images = []
    pixel_positions = []
    source_est = []

    for file in obs_files:
        obs = Photontable(file)
        data = obs.getPixelCountImage(applyWeight=False,
                                      exclude_flags=pixelflags.PROBLEM_FLAGS,
                                      wvlStart=wvl_start,
                                      wvlStop=wvl_stop)['image']
        data = np.transpose(data)
        debug_images.append(data)
        mean, median, std = stats.sigma_clipped_stats(data,
                                                      sigma=3.0,
                                                      mask_value=0)
        mask = np.zeros_like(data, dtype=bool)
        mask[data == 0] = True

        sources = DAOStarFinder(fwhm=fwhm_guess,
                                threshold=5. * std)(data - median, mask=mask)
        source = sources[sources['flux'].argmax()]
        source_est.append((source['xcentroid'], source['ycentroid']))

        position = centroids.centroid_sources(data,
                                              source['xcentroid'],
                                              source['ycentroid'],
                                              box_size=int(box_size),
                                              centroid_func=centroid_2dg,
                                              mask=mask)
        pixel_positions.append((position[0][0], position[1][0]))

    pixel_positions = np.array(pixel_positions)
    conex_positions = np.array(dither.pos)

    xform_con2pix = tf.estimate_transform('polynomial',
                                          conex_positions,
                                          pixel_positions,
                                          order=fit_power)
    xform_pix2con = tf.estimate_transform('polynomial',
                                          pixel_positions,
                                          conex_positions,
                                          order=fit_power)

    if plot:
        axis = int(round(np.sqrt(len(obs_files)), 0))
        fig, axs = plt.subplots(axis, axis, figsize=(20, 15))
        i = 0
        j = 0
        for index, image in enumerate(debug_images[:-1]):
            axs[i, j].imshow(image,
                             origin='lower',
                             interpolation='nearest',
                             cmap='viridis')
            axs[i, j].add_patch(
                Rectangle(
                    (source_est[index][0] -
                     (box_size / 2), source_est[index][1] - (box_size / 2)),
                    box_size,
                    box_size,
                    linewidth=1,
                    edgecolor='r',
                    fill=None))
            marker = '+'
            ms, mew = 30, 2.
            axs[i, j].plot(source_est[index][0],
                           source_est[index][1],
                           color='red',
                           marker=marker,
                           ms=ms,
                           mew=mew)
            axs[i, j].plot(pixel_positions[index][0],
                           pixel_positions[index][1],
                           color='blue',
                           marker=marker,
                           ms=ms,
                           mew=mew)
            axs[i, j].set_title(
                'Red + = Estimate, Blue + = Centroid for Dither Pos %i' %
                index)
            if (index + 1) % axis == 0 and (index + 1) != len(obs_files):
                i += 1
                j = 0
            elif index != len(obs_files) - 1:
                j += 1
        plt.show()

        _plotresiduals(xform_con2pix, conex_positions, pixel_positions)

    return xform_con2pix, xform_pix2con