Esempio n. 1
0
  def get_h5(self,dfile,time) :
      """Retrives 2D image from event.

         @run     run number
         @time    time-stamp
      """

      if dfile == 0 :
         filename = self.dataset_name + '.h5'
      else :
         filename = self.dataset_name + '__' + str(dfile).zfill(4) + '.h5'

      f         = h5py.File(filename,'r')

      # Ascert that time-stamp exist in file
      if time in f.keys():
         self.image  = f[time][self.detector_address]['HistData'].value
      else:
        self.image   = None
        self.img     = None
        return


      # Apply common mode correction

      if self.comm == 1:

         self.image  = pnccd_tbx.common_mode(img     = self.image,
                                             edge    = self.param1,
                                             side    = self.param2,
                                             plot    = self.param4)

      elif self.comm == 2:

         self.image = pnccd_tbx.common_mode_hart(img     = self.image,
                                                 msk     = self.mask,
                                                 max_int = self.param1,
                                                 max_com = self.param2,
                                                 length  = self.param3,
                                                 orient  = self.orient,
                                                 plot    = self.param4)

      # Apply geometry
      self.img  = pnccd_tbx.get_geometry(img    = self.image,
                                         gap    = self.gap,
                                         shift  = self.shift,
                                         orient = self.orient)


      # Check if nQ > smallest dimension/2 then we extend the image with zero values
      if self.nQ > min(self.img.shape[0]/2,self.img.shape[1]/2) :
         self.img   = pnccd_tbx.extend_image(img = self.img)

      # Check if carttesian coord background image exists
      if self.cart :
         self.img = self.img - self.backimg
Esempio n. 2
0
  def get_h5(self,dfile,time) :
      """Retrives 2D image from event.

         @run     run number
         @time    time-stamp
      """

      if dfile == 0 :
         filename = self.dataset_name + '.h5'
      else :
         filename = self.dataset_name + '__' + str(dfile).zfill(4) + '.h5'

      f         = h5py.File(filename,'r')

      # Ascert that time-stamp exist in file
      if time in f.keys():
         self.image  = f[time][self.detector_address]['HistData'].value
      else:
        self.image   = None
        self.img     = None
        return


      # Apply common mode correction

      if self.comm == 1:

         self.image  = pnccd_tbx.common_mode(img     = self.image,
                                             edge    = self.param1,
                                             side    = self.param2,
                                             plot    = self.param4)

      elif self.comm == 2:

         self.image = pnccd_tbx.common_mode_hart(img     = self.image,
                                                 msk     = self.mask,
                                                 max_int = self.param1,
                                                 max_com = self.param2,
                                                 length  = self.param3,
                                                 orient  = self.orient,
                                                 plot    = self.param4)

      # Apply geometry
      self.img  = pnccd_tbx.get_geometry(img    = self.image,
                                         gap    = self.gap,
                                         shift  = self.shift,
                                         orient = self.orient)


      # Check if nQ > smallest dimension/2 then we extend the image with zero values
      if self.nQ > min(self.img.shape[0]/2,self.img.shape[1]/2) :
         self.img   = pnccd_tbx.extend_image(img = self.img)

      # Check if carttesian coord background image exists
      if self.cart :
         self.img = self.img - self.backimg
Esempio n. 3
0
  def get_image(self,evt) :
      """Retrives 2D image from event.

         @run     run number from Psana
         @time    time-stamp from Psana
      """
      self.run_nr         = int(evt.run())

      self.evt            = evt
      self.img            = self.src.image(self.evt)

      # Check if nQ > smallest dimension/2 then we extend the image with zero values
      if self.nQ > min(self.img.shape[0]/2,self.img.shape[1]/2) :
         self.img   = pnccd_tbx.extend_image(img = self.img)

      # Check if carttesian coord background image exists
      if self.cart :
         self.img = self.img - self.backimg

      # CM correction, Make sure that no other CM is already implemented

      self.img            = pnccd_tbx.common_mode(self.img, 150 , 100 , plot = 0)
      self.img            = self.img*self.msk
Esempio n. 4
0
    def get_image(self, evt):
        """Retrives 2D image from event.

         @run     run number from Psana
         @time    time-stamp from Psana
      """
        self.run_nr = int(evt.run())

        self.evt = evt
        self.img = self.src.image(self.evt)

        # Check if nQ > smallest dimension/2 then we extend the image with zero values
        if self.nQ > min(self.img.shape[0] / 2, self.img.shape[1] / 2):
            self.img = pnccd_tbx.extend_image(img=self.img)

        # Check if carttesian coord background image exists
        if self.cart:
            self.img = self.img - self.backimg

        # CM correction, Make sure that no other CM is already implemented

        self.img = pnccd_tbx.common_mode(self.img, 150, 100, plot=0)
        self.img = self.img * self.msk
Esempio n. 5
0
  def __init__(self,
               dataset_name     = None,
               detector_address = None,
               data_type        = 'idx',
               mask_path        = None,
               mask_angles      = None,
               mask_widths      = None,
               backimg_path     = None,
               backmsk_path     = None,
               geom_path        = None,
               det_dist         = None,
               det_pix          = 0.075,
               beam_l           = None,
               mask_thr         = None,
               nQ               = None,
               nPhi             = None,
               dQ               = 1,
               dPhi             = 1,
               cent0            = None,
               r_max            = None,
               dr               = None,
               dx               = None,
               dy               = None,
               r_0              = None,
               q_bound          = None,
               peak             = None,
               dpeak            = None):

    """The fluctuation scattering class stores processing parameters,
       initiates mask and background data and retrieves 2D images
       from events. Processing options of the 2D images include:
       * Transform from cartesian to polar coordinates
       * Beam center refinement
       * Dynamic masking
       * Normalization % SAXS calculation
       * Particle sizing
       * Computation of in-frame 2-point angular auto-correlations using FFTs

    @param dataset_name         Experiment name and run number
    @param detector_address     Adress to back or front detector
    @param data_type            Type of data file format (h5 or xtc in the formats: idx|idx_ffb|smd|smd_ffb|h5)
    @param mask_path            Full path to static image mask
    @param mask_angles          Center of angluar slices (deg) that should be masked out (due to jet streaks etc), [Ang1 Ang2 ...]
    @param mask_widths          Width  of angular slices (deg) that should be masked out (due to jet streaks etc), [delta1 delta2 ...]
    @param backimg_path         Full path to background image
    @param backmsk_path         Full path to background mask
    @param geom_path            Full path to geometry file (for h5 format)
    @param det_dist             Override of detecor distance (in mm)
    @param det_pix              Pixel size (in mm)
    @param beam_l               Override of beam wavelength (in Angstrom)
    @param mask_thr             Threshold for dynamic masking
    @param nQ                   Number of Q-bins to consider   (in pixels)
    @param nPhi                 Number of Phi-bins to consider (in pixels)
    @param dQ                   Stepsize in Q   (in pixels)
    @param dPhi                 Stepsize in Phi (in pixels)
    @param cent0                Initial beam center coordinates [xc,yc]
    @param r_max                Maximum radial value to use for beamcenter refinement (in pixels)
    @param dr                   Stepsize in r (in pixels)
    @param dx                   Gridsize for beam center refinement in x, i.e xc+/-dx (in pixels)
    @param dy                   Gridsize for beam center refinement in y, i.e yc+/-dy (in pixles)
    @param r_0                  Starting value for particle radius refinement [in Ang]
    @param q_bound              Upper and Lower boundaries of q for Particle radius refinement [in Ang^-1]
    @param peak                 Q-values for peak maxima [q_peak1 q_peak2 ...]
    @param dpeak                Delta Q used for peak integration of peak maxima [delta_q1 delta_q2 ...]
    """


    # Initialize parameters and configuration files once

    self.data_type          = data_type
    self.dataset_name       = dataset_name
    self.detector_address   = detector_address


    if (self.data_type == 'idx') or (self.data_type == 'idx_ffb') or (self.data_type == 'smd')  or (self.data_type == 'smd_ffb') or (self.data_type == 'xtc') :


       self.ds       = DataSource(self.dataset_name)
       self.src      = Detector(self.detector_address, self.ds.env())


       if mask_path is None :                   # Create a binary mask of ones, default mask only works for xtc/ffb

          evt               = self.ds.events().next()
          self.mask_address = self.src.mask(evt,calib=True,status=True)
          self.msk          = self.src.image(evt,self.mask_address)
          self.mask         = np.copy(self.msk)

       else:

          self.msk          = np.loadtxt(mask_path)
          self.mask         = np.copy(self.msk)


    if geom_path is not None :
       geom          = np.genfromtxt(geom_path,skiprows=1)
       self.gap      = geom[0]
       self.shift    = geom[1]
       self.orient   = geom[2
]
       self.comm     = geom[3]
       self.param1   = geom[4]
       self.param2   = geom[5]
       self.param3   = geom[6]
       self.param4   = geom[7]

    if (self.data_type == 'h5'):

       if mask_path is None :                      # Create a binary mask of ones

         ## Add default binary mask here ## Default pnCCD dimensions
         dim1      = 1024
         dim2      = 1024
         self.mask = np.ones((dim1,dim2))

       else:

          self.mask = np.loadtxt(mask_path)

       # Apply geometry
       self.msk   = pnccd_tbx.get_geometry(img    = self.mask,
                                          gap    = self.gap,
                                          shift  = self.shift,
                                          orient = self.orient)


    if self.detector_address == 'pnccdFront' :

       evt          = self.ds.events().next()
       gain         = self.src.gain(evt)
       self.gain    = self.src.image(evt,gain)

    self.cart = 0
    self.flat = 0

    if backimg_path is None :
       self.backimg     = None
    else :
       self.backimg     = np.loadtxt(backimg_path).astype(np.float64)

       # Check if background image in cartesian coordinates exists
       if (self.backimg.shape == self.msk.shape):
          self.cart     = 1                             # Remove bg before transform to polar coordinates


    if backmsk_path is None :
       self.backmsk     = None
    else :
       self.backmsk     = np.loadtxt(backmsk_path).astype(np.float64)

    # Check if flat-field image exists
    if (self.backmsk is None) and (self.backimg is not None) and (self.cart==0):
       self.pcflat      = pnccd_tbx.dynamic_flatfield(self.backimg)
       self.flat        = 1


    if det_dist is None :                       # Get detector distance from events
       for run in self.ds.runs():
           self.det_dist = cspad_tbx.env_distance(self.detector_address, run.env(), 577)
    else :
       self.det_dist = det_dist

    self.det_pix = det_pix

    if beam_l is None :                        # Get wavelength from event, note it can change slightly between events. So in the future use average.
       self.beam_l   = cspad_tbx.evt_wavelength(self.ds.events().next())
    else :
       self.beam_l   = beam_l

    if mask_thr is None :                      # No dynamic masking
       self.thr      = None
    else :
       self.thr      = mask_thr

    if nQ is None :                            # Use image dimensions as a guide, leave room for offset beamC
       if self.msk.shape[0] > self.msk.shape[1] :  # nQ determined by smallest dimension
          self.nQ   = int(self.msk.shape[1]/2)-20
       else :
          self.nQ   = int(self.msk.shape[0]/2)-20
    else :
       self.nQ       = nQ


    if (self.nQ % 10):                        # Ascert even number, speeds things up massively for FFT
        self.nQ  = np.floor(self.nQ/10)*10

    if (self.nQ % dQ):                        # Ascert clean divisor
        self.nQ  = np.floor(self.nQ/dQ)*dQ

    if nPhi is None :                         # Estimate based on 2*pi*nQ
       self.nPhi     = np.ceil(2*np.pi*self.nQ)
    else :
       self.nPhi     = nPhi

    if (self.nPhi % 10):                      # Ascert even number, speeds things up massively for FFT
        self.nPhi  = np.ceil(self.nPhi/10)*10

    if (self.nPhi % dPhi):                    # Ascert clean divisor
        self.nPhi  = np.ceil(self.nPhi/dPhi)*dPhi

    self.dQ          = dQ
    self.dPhi        = dPhi

    self.mask_angles        = mask_angles
    self.mask_widths        = mask_widths

    # Compute slices that should be masked in static mask
    if (self.mask_angles is not None) and (self.mask_widths is not None) :
       self.mask_angles        = (self.mask_angles/360) * self.nPhi
       self.mask_widths        = (self.mask_widths/360) * self.nPhi

    # Check if nQ > smallest dimension/2 then we extend the image with zero values
    if self.nQ > min(self.msk.shape[0]/2,self.msk.shape[1]/2) :
       self.msk   = pnccd_tbx.extend_image(img = self.msk)
       self.mask  = np.copy(self.msk)


    if (cent0 is None) or (sum(cent0) == 0):  # Use center of gravity to estimate starting beamC
       self.cent0    = [int(round(self.msk.shape[1]/2)) , int(round(self.msk.shape[0]/2))]
    else :
       self.cent0    = cent0

    self.cent = self.cent0                    # Default center

    if r_max is None :                        # Default, Use half of nQ
       self.r_max    = int(self.nQ*(3/4))
    else :
       self.r_max    = r_max

    if (self.r_max % dr):                     # Ascert clean divisor
        self.r_max  = np.floor(self.r_max/dr)*dr

    self.dr          = dr
    self.dx          = dx
    self.dy          = dy

    if r_0 is None :
       self.radius   = 0
       self.score    = 0

    self.r_0       = r_0

    if q_bound is None or sum(q_bound)==0 :
       self.q_bound    = [None,None]
    else :
       self.q_bound    = [None,self.q_bound]


    # Compute q-spacing
    self.q           = np.arange(0, self.nQ, self.dQ)
    self.q           = self.q*self.det_pix/self.det_dist*4*np.pi/self.beam_l/2

    # Compute Phi (Not accounting for curvature)
    self.phi         = np.linspace(0, 2*np.pi, self.nPhi/self.dPhi,endpoint=False)


    # Compute indices for Peak maxima
    if (peak is not None) and (dpeak is not None) :
       self.peak       = peak
       self.dpeak      = dpeak
       self.ind1       = (self.q >= (self.peak[0] - self.dpeak[0])) & (self.q <= (self.peak[0] + self.dpeak[0]) )
       self.ind2       = (self.q >= (self.peak[1] - self.dpeak[1])) & (self.q <= (self.peak[1] + self.dpeak[1]) )
    else:
       self.peak       = None
       self.dpeak      = None
Esempio n. 6
0
    def __init__(self,
                 dataset_name=None,
                 detector_address=None,
                 data_type='idx',
                 mask_path=None,
                 mask_angles=None,
                 mask_widths=None,
                 backimg_path=None,
                 backmsk_path=None,
                 geom_path=None,
                 det_dist=None,
                 det_pix=0.075,
                 beam_l=None,
                 mask_thr=None,
                 nQ=None,
                 nPhi=None,
                 dQ=1,
                 dPhi=1,
                 cent0=None,
                 r_max=None,
                 dr=None,
                 dx=None,
                 dy=None,
                 r_0=None,
                 q_bound=None,
                 peak=None,
                 dpeak=None):
        """The fluctuation scattering class stores processing parameters,
       initiates mask and background data and retrieves 2D images
       from events. Processing options of the 2D images include:
       * Transform from cartesian to polar coordinates
       * Beam center refinement
       * Dynamic masking
       * Normalization % SAXS calculation
       * Particle sizing
       * Computation of in-frame 2-point angular auto-correlations using FFTs

    @param dataset_name         Experiment name and run number
    @param detector_address     Adress to back or front detector
    @param data_type            Type of data file format (h5 or xtc in the formats: idx|idx_ffb|smd|smd_ffb|h5)
    @param mask_path            Full path to static image mask
    @param mask_angles          Center of angluar slices (deg) that should be masked out (due to jet streaks etc), [Ang1 Ang2 ...]
    @param mask_widths          Width  of angular slices (deg) that should be masked out (due to jet streaks etc), [delta1 delta2 ...]
    @param backimg_path         Full path to background image
    @param backmsk_path         Full path to background mask
    @param geom_path            Full path to geometry file (for h5 format)
    @param det_dist             Override of detecor distance (in mm)
    @param det_pix              Pixel size (in mm)
    @param beam_l               Override of beam wavelength (in Angstrom)
    @param mask_thr             Threshold for dynamic masking
    @param nQ                   Number of Q-bins to consider   (in pixels)
    @param nPhi                 Number of Phi-bins to consider (in pixels)
    @param dQ                   Stepsize in Q   (in pixels)
    @param dPhi                 Stepsize in Phi (in pixels)
    @param cent0                Initial beam center coordinates [xc,yc]
    @param r_max                Maximum radial value to use for beamcenter refinement (in pixels)
    @param dr                   Stepsize in r (in pixels)
    @param dx                   Gridsize for beam center refinement in x, i.e xc+/-dx (in pixels)
    @param dy                   Gridsize for beam center refinement in y, i.e yc+/-dy (in pixles)
    @param r_0                  Starting value for particle radius refinement [in Ang]
    @param q_bound              Upper and Lower boundaries of q for Particle radius refinement [in Ang^-1]
    @param peak                 Q-values for peak maxima [q_peak1 q_peak2 ...]
    @param dpeak                Delta Q used for peak integration of peak maxima [delta_q1 delta_q2 ...]
    """

        # Initialize parameters and configuration files once

        self.data_type = data_type
        self.dataset_name = dataset_name
        self.detector_address = detector_address

        if (self.data_type == 'idx') or (self.data_type == 'idx_ffb') or (
                self.data_type == 'smd') or (self.data_type
                                             == 'smd_ffb') or (self.data_type
                                                               == 'xtc'):

            self.ds = DataSource(self.dataset_name)
            self.src = Detector(self.detector_address, self.ds.env())

            if mask_path is None:  # Create a binary mask of ones, default mask only works for xtc/ffb

                evt = next(self.ds.events())
                self.mask_address = self.src.mask(evt, calib=True, status=True)
                self.msk = self.src.image(evt, self.mask_address)
                self.mask = np.copy(self.msk)

            else:

                self.msk = np.loadtxt(mask_path)
                self.mask = np.copy(self.msk)

        if geom_path is not None:
            geom = np.genfromtxt(geom_path, skiprows=1)
            self.gap = geom[0]
            self.shift = geom[1]
            self.orient = geom[2]
            self.comm = geom[3]
            self.param1 = geom[4]
            self.param2 = geom[5]
            self.param3 = geom[6]
            self.param4 = geom[7]

        if (self.data_type == 'h5'):

            if mask_path is None:  # Create a binary mask of ones

                ## Add default binary mask here ## Default pnCCD dimensions
                dim1 = 1024
                dim2 = 1024
                self.mask = np.ones((dim1, dim2))

            else:

                self.mask = np.loadtxt(mask_path)

            # Apply geometry
            self.msk = pnccd_tbx.get_geometry(img=self.mask,
                                              gap=self.gap,
                                              shift=self.shift,
                                              orient=self.orient)

        if self.detector_address == 'pnccdFront':

            evt = next(self.ds.events())
            gain = self.src.gain(evt)
            self.gain = self.src.image(evt, gain)

        self.cart = 0
        self.flat = 0

        if backimg_path is None:
            self.backimg = None
        else:
            self.backimg = np.loadtxt(backimg_path).astype(np.float64)

            # Check if background image in cartesian coordinates exists
            if (self.backimg.shape == self.msk.shape):
                self.cart = 1  # Remove bg before transform to polar coordinates

        if backmsk_path is None:
            self.backmsk = None
        else:
            self.backmsk = np.loadtxt(backmsk_path).astype(np.float64)

        # Check if flat-field image exists
        if (self.backmsk is None) and (self.backimg is not None) and (self.cart
                                                                      == 0):
            self.pcflat = pnccd_tbx.dynamic_flatfield(self.backimg)
            self.flat = 1

        if det_dist is None:  # Get detector distance from events
            for run in self.ds.runs():
                self.det_dist = cspad_tbx.env_distance(self.detector_address,
                                                       run.env(), 577)
        else:
            self.det_dist = det_dist

        self.det_pix = det_pix

        if beam_l is None:  # Get wavelength from event, note it can change slightly between events. So in the future use average.
            self.beam_l = cspad_tbx.evt_wavelength(next(self.ds.events()))
        else:
            self.beam_l = beam_l

        if mask_thr is None:  # No dynamic masking
            self.thr = None
        else:
            self.thr = mask_thr

        if nQ is None:  # Use image dimensions as a guide, leave room for offset beamC
            if self.msk.shape[0] > self.msk.shape[
                    1]:  # nQ determined by smallest dimension
                self.nQ = int(self.msk.shape[1] / 2) - 20
            else:
                self.nQ = int(self.msk.shape[0] / 2) - 20
        else:
            self.nQ = nQ

        if (self.nQ %
                10):  # Ascert even number, speeds things up massively for FFT
            self.nQ = np.floor(self.nQ / 10) * 10

        if (self.nQ % dQ):  # Ascert clean divisor
            self.nQ = np.floor(self.nQ / dQ) * dQ

        if nPhi is None:  # Estimate based on 2*pi*nQ
            self.nPhi = np.ceil(2 * np.pi * self.nQ)
        else:
            self.nPhi = nPhi

        if (self.nPhi %
                10):  # Ascert even number, speeds things up massively for FFT
            self.nPhi = np.ceil(self.nPhi / 10) * 10

        if (self.nPhi % dPhi):  # Ascert clean divisor
            self.nPhi = np.ceil(self.nPhi / dPhi) * dPhi

        self.dQ = dQ
        self.dPhi = dPhi

        self.mask_angles = mask_angles
        self.mask_widths = mask_widths

        # Compute slices that should be masked in static mask
        if (self.mask_angles is not None) and (self.mask_widths is not None):
            self.mask_angles = (self.mask_angles / 360) * self.nPhi
            self.mask_widths = (self.mask_widths / 360) * self.nPhi

        # Check if nQ > smallest dimension/2 then we extend the image with zero values
        if self.nQ > min(self.msk.shape[0] / 2, self.msk.shape[1] / 2):
            self.msk = pnccd_tbx.extend_image(img=self.msk)
            self.mask = np.copy(self.msk)

        if (cent0 is None) or (
                sum(cent0)
                == 0):  # Use center of gravity to estimate starting beamC
            self.cent0 = [
                int(round(self.msk.shape[1] / 2)),
                int(round(self.msk.shape[0] / 2))
            ]
        else:
            self.cent0 = cent0

        self.cent = self.cent0  # Default center

        if r_max is None:  # Default, Use half of nQ
            self.r_max = int(self.nQ * (3 / 4))
        else:
            self.r_max = r_max

        if (self.r_max % dr):  # Ascert clean divisor
            self.r_max = np.floor(self.r_max / dr) * dr

        self.dr = dr
        self.dx = dx
        self.dy = dy

        if r_0 is None:
            self.radius = 0
            self.score = 0

        self.r_0 = r_0

        if q_bound is None or sum(q_bound) == 0:
            self.q_bound = [None, None]
        else:
            self.q_bound = [None, self.q_bound]

        # Compute q-spacing
        self.q = np.arange(0, self.nQ, self.dQ)
        self.q = self.q * self.det_pix / self.det_dist * 4 * np.pi / self.beam_l / 2

        # Compute Phi (Not accounting for curvature)
        self.phi = np.linspace(0,
                               2 * np.pi,
                               self.nPhi / self.dPhi,
                               endpoint=False)

        # Compute indices for Peak maxima
        if (peak is not None) and (dpeak is not None):
            self.peak = peak
            self.dpeak = dpeak
            self.ind1 = (self.q >= (self.peak[0] - self.dpeak[0])) & (
                self.q <= (self.peak[0] + self.dpeak[0]))
            self.ind2 = (self.q >= (self.peak[1] - self.dpeak[1])) & (
                self.q <= (self.peak[1] + self.dpeak[1]))
        else:
            self.peak = None
            self.dpeak = None