def _tr_cspad(self, values, obj, evt_key): """Translates CsPad to hummingbird numpy array, quad by quad""" n_quads = obj.quads_shape()[0] for i in range(0, n_quads): add_record(values, 'photonPixelDetectors', '%sQuad%d' % (self._s2c[str(evt_key.src())], i), obj.quads(i).data(), ureg.ADU)
def calculate_epoch_times(evt, time_sec, time_usec): add_record(evt['ID'], 'ID', 'time', time_sec.data + 1.e-6 * time_usec.data) #add_record(evt['ID'], 'ID', 'timeAgo', time.time() - (time_sec.data + 1.e-6*time_usec.data)) # Calculating timeAgo with 606 second offset due to miscalibration of pnCCD server clock #add_record(evt['ID'], 'ID', 'timeAgo', -606. + time.time() - (time_sec.data + 1.e-6*time_usec.data)) add_record(evt['ID'], 'ID', 'timeAgo', 0. + time.time() - (time_sec.data + 1.e-6 * time_usec.data))
def _tr_pnccdFrames(self, values, obj, evt_key): """Translates pnCCD frames to hummingbird numpy array, frame by frame""" n_frames = obj.frame_shape()[0] for i in range(0, n_frames): add_record(values, 'photonPixelDetectors', '%sFrame%d' % (self._s2c[str(evt_key.src())], i), obj.frame(i).data(), ureg.ADU)
def translate_object(self, evt, key): values = {} detid = self._c2id_detectors[key] if detid in PNCCD_IDS: det = self._detectors[detid] obj = self._detectors[detid]['obj'] data_nda = det['data_method'](obj, evt) if data_nda is None: image = None elif len(data_nda.shape) <= 2: image = data_nda elif len(data_nda.shape) == 3: image = numpy.hstack([numpy.vstack([data_nda[0],data_nda[1][::-1,::-1]]), numpy.vstack([data_nda[3],data_nda[2][::-1,::-1]])]) add_record(values, det['type'], det['key'], image, ureg.ADU) elif detid in ACQ_IDS: det = self._detectors[detid] # waveforms are in Volts, times are in Seconds obj = det['obj'] waveforms = obj.waveform(evt) #print("waveforms", waveforms) #times = obj.wftime(evt) for i, wf in enumerate(waveforms): add_record(values, det['type'], det['keys'][i], wf, ureg.V) else: raise RuntimeError('%s not yet supported' % key) return values
def translate(self, evt, key): """Returns a dict of Records that match a given humminbird key""" values = {} if(key in self._c2n): return self.translate_core(evt, key) elif(key == 'parameters'): return self._tr_epics() elif(key == 'analysis'): return {} elif(key == 'stream'): return {} else: # check if the key matches any of the existing keys in the event event_keys = evt.keys() values = {} found = False for event_key in event_keys: if(event_key.key() == key): obj = evt.get(event_key.type(), event_key.src(), event_key.key()) found = True add_record(values, 'native', '%s[%s]' % (self._s2c[str(event_key.src())], key), obj, ureg.ADU) if(found): return values else: print '%s not found in event' % (key)
def _tr_bld_data_ebeam(self, values, obj): """Translates BldDataEBeam to hummingbird photon energy""" photon_energy_ev = -1 if(isinstance(obj, psana.Bld.BldDataEBeamV6)): photon_energy_ev = obj.ebeamPhotonEnergy() else: peak_current = obj.ebeamPkCurrBC2() dl2_energy_gev = 0.001*obj.ebeamL3Energy() # If we don't have direct access to photonEnergy # we need to calculate it if(photon_energy_ev == -1): ltu_wake_loss = 0.0016293*peak_current # Spontaneous radiation loss per segment sr_loss_per_segment = 0.63*dl2_energy_gev # wakeloss in an undulator segment wake_loss_per_segment = 0.0003*peak_current # energy loss per segment energy_loss_per_segment = (sr_loss_per_segment + wake_loss_per_segment) # energy in first active undulator segment [GeV] energy_profile = (dl2_energy_gev - 0.001*ltu_wake_loss - 0.0005*energy_loss_per_segment) # Calculate the resonant photon energy of the first active segment photon_energy_ev = 44.42*energy_profile*energy_profile add_record(values, 'photonEnergies', 'photonEnergy', photon_energy_ev, ureg.eV)
def _tr_bld_data_ebeam(self, values, obj): """Translates BldDataEBeam to hummingbird photon energy""" photon_energy_ev = -1 if (isinstance(obj, psana.Bld.BldDataEBeamV6)): photon_energy_ev = obj.ebeamPhotonEnergy() else: peak_current = obj.ebeamPkCurrBC2() dl2_energy_gev = 0.001 * obj.ebeamL3Energy() # If we don't have direct access to photonEnergy # we need to calculate it if (photon_energy_ev == -1): ltu_wake_loss = 0.0016293 * peak_current # Spontaneous radiation loss per segment sr_loss_per_segment = 0.63 * dl2_energy_gev # wakeloss in an undulator segment wake_loss_per_segment = 0.0003 * peak_current # energy loss per segment energy_loss_per_segment = (sr_loss_per_segment + wake_loss_per_segment) # energy in first active undulator segment [GeV] energy_profile = (dl2_energy_gev - 0.001 * ltu_wake_loss - 0.0005 * energy_loss_per_segment) # Calculate the resonant photon energy of the first active segment photon_energy_ev = 44.42 * energy_profile * energy_profile add_record(values, 'photonEnergies', 'photonEnergy', photon_energy_ev, ureg.eV)
def translate(self, evt, key): """Returns a dict of Records that match a given humminbird key""" values = {} if (key in self._c2n): return self.translate_core(evt, key) elif (key == 'parameters'): return self._tr_epics() elif (key == 'analysis'): return {} elif (key == 'stream'): return {} else: # check if the key matches any of the existing keys in the event event_keys = evt.keys() values = {} found = False for event_key in event_keys: if (event_key.key() == key): obj = evt.get(event_key.type(), event_key.src(), event_key.key()) found = True add_record( values, 'native', '%s[%s]' % (self._s2c[str(event_key.src())], key), obj, ureg.ADU) if (found): return values else: print '%s not found in event' % (key)
def _tr_cspad2x2(self, values, obj): """Translates CsPad2x2 to hummingbird numpy array""" try: add_record(values, 'photonPixelDetectors', 'CsPad2x2S', obj.data(), ureg.ADU) except AttributeError: add_record(values, 'photonPixelDetectors', 'CsPad2x2', obj.data16(), ureg.ADU)
def _tr_camera(self, values, obj): """Translates Camera frame to hummingbird numpy array""" if obj.depth == 16: data = obj.data16() else: data = obj.data8() add_record(values, 'camera', 'opal', data, ureg.ADU)
def _tr_gmd_sqs_pnccd(self, values, obj, evt_key): sase_3_pulse_index = 0 # print("obj.keys()", obj.keys()) sase3 = obj['data.intensitySa3TD'][sase_3_pulse_index] add_record(values, 'GMD', 'SASE3', sase3, ureg.ADU) sase_1_train_length = 176 sase1 = obj['data.intensitySa1TD'][:sase_1_train_length] add_record(values, 'GMD', 'SASE1', sase1, ureg.ADU)
def _tr_bld_data_fee_gas_det_energy(self, values, obj): """Translates gas monitor detector to hummingbird pulse energy""" # convert from mJ to J add_record(values, 'pulseEnergies', 'f_11_ENRC', obj.f_11_ENRC(), ureg.mJ) add_record(values, 'pulseEnergies', 'f_12_ENRC', obj.f_12_ENRC(), ureg.mJ) add_record(values, 'pulseEnergies', 'f_21_ENRC', obj.f_21_ENRC(), ureg.mJ) add_record(values, 'pulseEnergies', 'f_22_ENRC', obj.f_22_ENRC(), ureg.mJ)
def onEvent(evt): # Processing rate [Hz] analysis.event.printProcessingRate() # try: # has_tof = True # evt["DAQ"]["TOF"] # print "We have TOF data!" # except RuntimeError: # has_tof = False # #print "No TOF" has_tof = False detector_type = "photonPixelDetectors" detector_key = "pnCCD" if move_half: detector = evt[detector_type][detector_key] detector = analysis.pixel_detector.moveHalf(evt, detector, horizontal=int(gap_total/pixel_size), outkey='data_half-moved') mask_center_s = analysis.pixel_detector.moveHalf(evt, add_record(evt["analysis"], "analysis", "mask", mask_center), horizontal=int(gap_total/pixel_size), outkey='mask_half-moved').data detector_type = "analysis" detector_key = "data_half-moved" # Do basic hitfinding using lit pixels analysis.hitfinding.countLitPixels(evt, evt[detector_type][detector_key], aduThreshold=aduThreshold, hitscoreThreshold=hitScoreThreshold, mask=mask_center_s) hit = bool(evt["analysis"]["litpixel: isHit"].data) strong_hit=evt["analysis"]["litpixel: hitscore"].data>strong_hit_threshold plotting.line.plotHistory(add_record(evt["analysis"],"analysis","total ADUs", evt[detector_type][detector_key].data.sum()), label='Total ADU', hline=hitScoreThreshold, group='Metric') plotting.line.plotHistory(evt["analysis"]["litpixel: hitscore"], label='Nr. of lit pixels', hline=hitScoreThreshold, group='Metric') analysis.hitfinding.hitrate(evt, hit, history=50) if hit and has_tof: print evt["DAQ"]["TOF"].data print evt["motorPositions"]["InjectorZ"].data plotting.line.plotTrace(evt["DAQ"]["TOF"], label='TOF', history=100, tracelen=20000, name="TOF", group="TOF") plotting.line.plotHistory(evt["motorPositions"]["InjectorZ"], label="InjectorZ (with TOF)", group="TOF") plotting.image.plotImage(evt[detector_type][detector_key], name="pnCCD (Hits with TOF)", group='TOF', mask=mask_center_s) D = {} D['TOF'] = evt['DAQ']['TOF'].data D['pnCCD'] = evt[detector_type][detector_key].data D['InjectorZ'] = evt["motorPositions"]["InjectorZ"].data if do_write: W.write_slice(D)
def find_foci(evt, type,key,type2,key2,minPhase=-500000, maxPhase=500000, steps=101, field_of_view_rad=100, wavelength=1.053, CCD_S_DIST=0.375, PX_SIZE=75e-6): img = evt[type][key].data centroids = evt[type2][key2].data Nfoci = centroids.shape[0] Xrange, Yrange = img.shape Npixel = field_of_view_rad p = numpy.linspace(-Xrange/2, Xrange/2-1, Xrange) q = numpy.linspace(-Yrange/2, Yrange/2-1, Yrange) pp, qq = numpy.meshgrid(p, q) phase_matrix = (2*numpy.pi/wavelength)*numpy.sqrt(1-((PX_SIZE/CCD_S_DIST)**2)*(qq**2 + pp**2)) prop_length = numpy.linspace(minPhase, maxPhase, steps) variance = numpy.zeros([steps, Nfoci]) # shift stuff for performance reasons img_shifted = fftshift(img) phase_matrix_shifted = fftshift(phase_matrix) for idx, phase in enumerate(prop_length): img_propagated = img_shifted * numpy.exp(1.j*phase*phase_matrix_shifted) recon = fftshift(ifft2(img_propagated)) for CC in numpy.arange(Nfoci): centerx, centery = centroids[CC, :] ###print centerx, centery reconcut = numpy.abs(recon[numpy.max([0, centerx-Npixel-1]).astype(int): numpy.min([Xrange-1, centerx+Npixel]).astype(int), numpy.max([0, centery-Npixel-1]).astype(int): numpy.min([Yrange-1, centery+Npixel]).astype(int)]) variance[idx, CC] = reconcut.var() focus_distance = numpy.zeros(Nfoci) CC_size = numpy.zeros(Nfoci) focused_CC = numpy.zeros(4*Npixel**2 * Nfoci).reshape(Nfoci, 2*Npixel, 2*Npixel) for CC in numpy.arange(Nfoci): ind_max = numpy.argmax(variance[:, CC]) tmp = variance[:, CC] # get max which is not at border loc_max_bool = numpy.r_[True, tmp[1:] > tmp[:-1]] & numpy.r_[tmp[:-1] > tmp[1:], True] loc_max_bool[0] = False loc_max_bool[-1] = False ind_max = numpy.argmax(tmp*loc_max_bool) focus_distance[CC] = prop_length[ind_max] img_propagated = img_shifted * numpy.exp(1.j * focus_distance[CC] * phase_matrix_shifted) recon = fftshift(ifft2(img_propagated)) centerx, centery = centroids[CC, :] reconcut = numpy.real(recon[numpy.max([0, centerx-Npixel]).astype(int): numpy.min([Xrange-1, centerx+Npixel]).astype(int), numpy.max([0, centery-Npixel]).astype(int): numpy.min([Yrange-1, centery+Npixel]).astype(int)]) focused_CC[CC, 0:reconcut.shape[0], 0:reconcut.shape[1]] = reconcut CC_size[CC] = numpy.sum(get_CC_size(reconcut)) if len(focused_CC): add_record(evt["analysis"], "analysis", "focused_CC", focused_CC[0]) add_record(evt["analysis"], "analysis", "focus distance", focus_distance) add_record(evt["analysis"], "analysis", "CC_size", CC_size) add_record(evt["analysis"], "analysis", "propagation length", prop_length)
def patterson(evt, type, key, mask=None, threshold=None, diameter_pix=None, crop=None, full_output=False, **params): """TODO: missing docstring .. note:: This feature depends on the python package `libspimage <https://github.com/FilipeMaia/libspimage>`_. """ success, module = utils.io.load_spimage() if not success: print "Skipping analysis.patterson.patterson" return img = evt[type][key].data if mask is None: mask = numpy.ones(shape=img.shape, dtype="bool") else: mask = numpy.array(mask, dtype="bool") if crop is not None: img = module.crop(img, crop) mask = module.crop(mask, crop) out = module.patterson(numpy.float64(img), mask, full_output=full_output, normalize_median=True, **params) v = evt["analysis"] if full_output: P = abs(out[0]) info = out[1] add_record(v, "analysis", "patterson kernel", info["kernel"], unit='') add_record(v, "analysis", "patterson intensities", info["intensities_times_kernel"], unit='') else: P = abs(out) add_record(v, "analysis", "patterson", abs(P), unit='') if threshold is not None: M = P > threshold if diameter_pix is not None: Y,X = numpy.indices(P.shape) X -= P.shape[1]/2 Y -= P.shape[0]/2 Rsq = X**2+Y**2 M *= Rsq > diameter_pix**2 if full_output: add_record(v, "analysis", "patterson multiples", M, unit='') multiple_score = M.sum() add_record(v, "analysis", "multiple score", multiple_score, unit='')
def _tr_photon_detector(self, values, obj, evt_key): """Translates pixel detector into Humminbird ADU array""" img = obj['image.data'] gain = obj['image.gain'] if self._sel_module is not None: img = img[numpy.newaxis] if self._sel_module is not None: gain = gain[numpy.newaxis] # If data is raw, add the gain reference along the 0th dimension if self._data_format == 'Raw': img = numpy.concatenate((img, gain), axis=0) # If data is calibrated there is no need to look at the gain elif self._data_format == 'Calib': pass else: raise NotImplementedError("DataFormat should be 'Calib' or 'Raw''") add_record(values, 'photonPixelDetectors', self._s2c[evt_key], img, ureg.ADU)
def _tr_camera(self, values, obj): """Translates Camera frame to hummingbird numpy array""" #if obj.depth == 16 or obj.depth() == 12: # data = obj.data16() # print data.shape #else: # data = obj.data8() # print data.shape data = obj.data16() # off Axis cam at CXI #if data.shape == (1024,1024): # add_record(values, 'camera', 'offAxis', data, ureg.ADU) # MCP (PNCCD replacement) at AMO (June 2016) if data.shape == (1024,1024): add_record(values, 'camera', 'mcp', data, ureg.ADU) if data.shape == (1752,2336): add_record(values, 'camera', 'onAxis', data, ureg.ADU)
def _tr_camera(self, values, obj): """Translates Camera frame to hummingbird numpy array""" #if obj.depth == 16 or obj.depth() == 12: # data = obj.data16() # print data.shape #else: # data = obj.data8() # print data.shape data = obj.data16() # off Axis cam at CXI #if data.shape == (1024,1024): # add_record(values, 'camera', 'offAxis', data, ureg.ADU) # MCP (PNCCD replacement) at AMO (June 2016) if data.shape == (1024, 1024): add_record(values, 'camera', 'mcp', data, ureg.ADU) if data.shape == (1752, 2336): add_record(values, 'camera', 'onAxis', data, ureg.ADU)
def translate(self, evt, key): """Returns a dict of Records that match a given Humminbird key""" values = {} if('Dummy' not in self.state or 'Data Sources' not in self.state['Dummy']): if(key == 'photonPixelDetectors'): # Translate default CCD as default add_record(values, key, 'CCD', evt['CCD'], ureg.ADU) if(values == {}): raise RuntimeError('%s not found in event' % (key)) return values for ds in self.state['Dummy']['Data Sources']: if self.state['Dummy']['Data Sources'][ds]['type'] == key: # If unit is a string translate into PINT quantity u = self.state['Dummy']['Data Sources'][ds]['unit'] if not isinstance(self.state['Dummy']['Data Sources'][ds]['unit'],ureg.Quantity): u = ureg.parse_expression(u) add_record(values, key, ds, evt[ds], u) if(values == {} and not key == 'analysis'): raise RuntimeError('%s not found in event' % (key)) return values
def translate(self, evt, key): """Returns a dict of Records that match a given Humminbird key""" values = {} if('Dummy' not in self.state or 'Data Sources' not in self.state['Dummy']): if(key == 'photonPixelDetectors'): # Translate default CCD as default add_record(values, key, 'CCD', evt['CCD'], ureg.ADU) if(values == {}): raise RuntimeError('%s not found in event' % (key)) return values for ds in self.state['Dummy']['Data Sources']: if self.state['Dummy']['Data Sources'][ds]['type'] == key: # If unit is a string translate into PINT quantity u = self.state['Dummy']['Data Sources'][ds]['unit'] if not isinstance(self.state['Dummy']['Data Sources'][ds]['unit'],ureg.Unit): u = ureg.parse_units(u) add_record(values, key, ds, evt[ds], u) if(values == {} and not key == 'analysis'): raise RuntimeError('%s not found in event' % (key)) return values
def segment_holographic_hit(evt, type, key): labeled = evt[type][key].data if numpy.unique(labeled).shape[0] == 3: return labeled hitS = ((labeled >0)*1) hitS = ndimage.morphology.binary_dilation(hitS) for i in range(20): hitS = ndimage.morphology.binary_dilation(hitS) hh = gaussian_filter(hitS*4,sigma=15) thresh = 5*numpy.median(hh) hh[hh > thresh] = 1 hh[hh <= thresh] = 0 hitS = hh labeled, nn = ndimage.measurements.label(hitS) centroids = [[0 for a in numpy.arange(2)] for b in numpy.arange(nn)] for CC in numpy.arange(nn): tmp = (labeled == CC+1)*1. centroid = center_of_mass(tmp) #labeled[labeled == CC+1] = 0 if centroid[0] > 30 and centroid[0] < tmp.shape[0]-30 and centroid[1] > 30 and centroid[1] < tmp.shape[1]-30: centroids[CC] = numpy.round(center_of_mass(tmp)).astype(int) labeled[centroid[0]-4:centroid[0]+4,centroid[1]-4:centroid[1]+4] = 10 centroids = numpy.array(centroids, dtype=numpy.int64) add_record(evt["analysis"], "analysis", "labeledHolograms", labeled) add_record(evt["analysis"], "analysis", "centroids", centroids)
def _tr_photon_detector_spb(self, values, obj, evt_key): """Translates pixel detector into Humminbird ADU array""" train_length = numpy.array(obj["image.pulseId"]).shape[-1] cells = self._cell_filter[:train_length] img = obj['image.data'][..., cells] gain = obj['image.gain'][..., cells] if self._sel_module is not None: img = img[numpy.newaxis] assert img.ndim == 4 if self._sel_module is not None: gain = gain[numpy.newaxis] # If data is raw, add the gain reference along the 0th dimension if self._data_format == 'Raw': assert gain.ndim == 4 img = numpy.concatenate((img, gain), axis=0) # If data is calibrated there is no need to look at the gain elif self._data_format == 'Calib': pass else: raise NotImplementedError("DataFormat should be 'Calib' or 'Raw''") add_record(values, 'photonPixelDetectors', self._s2c[evt_key], img, ureg.ADU)
def translate(self, evt, key): """Returns a dict of Records that match a given hummingbird key""" values = {} if (key in self._c2n): return self.translate_core(evt, key) elif (key == 'analysis'): return {} elif (key == 'stream'): return {} else: # check if the key matches any of the existing keys in the event event_keys = evt.keys() values = {} found = False if key in event_keys: obj = evt[key] for subkey in obj.keys(): add_record(values, 'native', '%s[%s]' % (self._s2c[key], subkey), obj[subkey], ureg.ADU) return values else: print('%s not found in event' % (key))
def segment_holographic_hit(evt, type, key): labeled = evt[type][key].data if numpy.unique(labeled).shape[0] == 3: return labeled hitS = ((labeled > 0) * 1) hitS = ndimage.morphology.binary_dilation(hitS) for i in range(20): hitS = ndimage.morphology.binary_dilation(hitS) hh = gaussian_filter(hitS * 4, sigma=15) thresh = 5 * numpy.median(hh) hh[hh > thresh] = 1 hh[hh <= thresh] = 0 hitS = hh labeled, nn = ndimage.measurements.label(hitS) centroids = [[0 for a in numpy.arange(2)] for b in numpy.arange(nn)] for CC in numpy.arange(nn): tmp = (labeled == CC + 1) * 1. centroid = center_of_mass(tmp) #labeled[labeled == CC+1] = 0 if centroid[0] > 30 and centroid[0] < tmp.shape[0] - 30 and centroid[ 1] > 30 and centroid[1] < tmp.shape[1] - 30: centroids[CC] = numpy.round(center_of_mass(tmp)).astype(int) labeled[centroid[0] - 4:centroid[0] + 4, centroid[1] - 4:centroid[1] + 4] = 10 centroids = numpy.array(centroids, dtype=numpy.int64) add_record(evt["analysis"], "analysis", "labeledHolograms", labeled) add_record(evt["analysis"], "analysis", "centroids", centroids)
def refocus_hologram_evt(evt, type, key, gain=30): img = evt[type][key].data.copy() img = img[513 - 256:513 + 256, 584 - 256:584 + 256] image_to_show, centroidsmap, centroids, focal_distance, intensity = refocus_hologram( img, gain=gain) add_record(evt["analysis"], "analysis", "hologram_score", intensity.max()) if evt["analysis"]["hologram_score"]: add_record(evt["analysis"], "analysis", "focused_CC", image_to_show) add_record(evt["analysis"], "analysis", "focus distance", focal_distance[intensity.argmax()] * 5E-7)
def _tr_lusi_ipm_fex(self, values, obj, evt_key): """Translates Ipm relative pulse energy monitor to hummingbird pulse energy""" add_record(values, 'pulseEnergies', 'IpmFex - '+str(evt_key.src()), obj.sum(), ureg.ADU)
print 'creating gaussian and center mask' gMask = gaussian_mask(dimx,dimx,400,700,300) centerMask = euclid(dimx,dimx,numpy.round(dimx/2),numpy.round(dimx/2),150) return mask, gMask, centerMask def double_hit_finder_evt(evt, type, key, mask, weighting_mask, center_mask, threshold_med) img = evt[type][key].data img *= mask img *= weighting_mask recon = fftshift(numpy.abs(fftshift(img))) recon *= center_mask recon = recon[recon>0] med = numpy.median(recon) lit_pix = recon > (med*threshold_med) double_hitscore = lit_pix.sum() add_record(evt["analysis"], "analysis", "hologram score", double_hitscore, unit='cats per doghnuts') def double_hit_finder(pattern, mask, gMask, centerMask, threshold_med, imname=''): hitData = numpy.array(pattern, dtype=numpy.float64) hitData *= numpy.array(mask) hitData *= numpy.array(gMask) holoData = fftshift(numpy.abs(ifft2(hitData))) # if imname == '': # imsave('hit2.png',holoData*centerMask) # else: imsave('%s.png' % imname[:-4],holoData*centerMask) holoData *= centerMask hData = holoData[holoData>0] med = numpy.median(hData) hitS = holoData > (med * threshold_med) # if imname == '': # imsave('hit.png',hitS)
def translate(self, evt, key): """Returns a dict of Records that match a given Humminbird key""" values = {} if key == 'photonPixelDetectors': # Translate pnCCD add_record(values, key, 'pnCCD', evt['pnCCD'], ureg.ADU) elif key == 'motorPositions': val = self.motors.get(self.get_bunch_time()[0]) if val is None: raise RuntimeError('%s not found in event' % key) for motorname, motorpos in val.iteritems(): add_record(values, key, motorname, motorpos, ureg.mm) elif key == 'ID': add_record(values, key, 'DataSetID', self.reader.file_header.dataSetID.rstrip('\0')) # Sometimes BunchID is missing add_record(values, key, 'BunchID', self.reader.frame_headers[-1].external_id) add_record(values, key, 'tv_sec', self.reader.frame_headers[-1].tv_sec, ureg.s) add_record(values, key, 'tv_usec', self.reader.frame_headers[-1].tv_usec, ureg.s) add_record(values, key, 'bunch_sec', self.get_bunch_time()[0], ureg.s) elif key == "DAQ": if self.daq is None: self.daq = read_daq.DAQReader(self.state['FLASH/DAQBaseDir']) if self._current_event_id is not None: tof_trace = self.daq.get_tof(self._current_event_id) if tof_trace is not None: evt["TOF"] = tof_trace #self.keys.add("DAQ") add_record(values, key, "TOF", evt["TOF"], ureg.s) else: raise RuntimeError("{0} not found in event".format(key)) elif key == "FEL": wl = self.get_wavelength(self.get_bunch_time()[1]) if wl is not None: add_record(values, key, "wavelength", wl, ureg.nm) else: raise RuntimeError("%s not found in event" % key) gmd = self.get_gmd(self.get_bunch_time()[1]) if gmd is not None: add_record(values, key, "gmd", gmd, ureg.mJ) else: raise RuntimeError("%s not found in event" % key) elif not key == 'analysis': raise RuntimeError('%s not found in event' % key) return values
def onEvent(evt): # ------------------- # # INITIAL DIAGNOSTICS # # ------------------- # # Time measurement analysis.event.printProcessingRate() # Simple hitfinding (Count Nr. of lit pixels) aduThreshold = 30*16 hitscoreThreshold = 50 hitscoreMax = 500000000 analysis.hitfinding.countLitPixels(evt, back_type, back_key, aduThreshold=aduThreshold, hitscoreThreshold=hitscoreThreshold, hitscoreMax=hitscoreMax, mask=mask_back) analysis.hitfinding.countLitPixels(evt, back_type, back_key, aduThreshold=aduThreshold, hitscoreThreshold=9000, hitscoreMax=hitscoreMax, mask=mask_back,label="Golden ") hit = evt["analysis"]["isHit - " + back_key].data golden_hit = evt["analysis"]["Golden isHit - " + back_key].data # -------------------- # # DETECTOR CORRECTIONS # # -------------------- # back_type_s = back_type back_key_s = back_key front_type_s = front_type front_key_s = front_key mask_back_s = mask_back if do_cmc: # CMC analysis.pixel_detector.cmc_pnccd(evt, back_type_s, back_key_s) #analysis.pixel_detector.cmc_pnccd(evt, front_type_s, front_key_s) back_type_s = "analysis" back_key_s = "cmc_pnccd - " + back_key #front_type_s = "analysis" #front_key_s = "cmc_pnccd - " + front_key # ----- # # WRITE # # ----- # if hit and do_sizing: # Binning analysis.pixel_detector.bin(evt, back_type_s, back_key_s, binning, mask_back_s) #analysis.pixel_detector.bin(evt, front_type_s, front_type_s) #front_key_s = "binned image - " + front_key mask_back_b = evt["analysis"]["binned mask - " + back_key_s].data back_type_b = "analysis" back_key_b = "binned image - " + back_key_s #front_type_s = "analysis" print "HIT (hit score %i > %i)" % (evt["analysis"]["hitscore - " + back_key].data, hitscoreThreshold) # CENTER DETERMINATION analysis.sizing.findCenter(evt, back_type_b, back_key_b, mask=mask_back_b, **centerParams) # RADIAL AVERAGE analysis.pixel_detector.radial(evt, back_type_b, back_key_b, mask=mask_back_b, cx=evt["analysis"]["cx"].data, cy=evt["analysis"]["cy"].data) # FIT SPHERE MODEL analysis.sizing.fitSphereRadial(evt, "analysis", "radial distance - " + back_key_b, "radial average - " + back_key_b, **dict(modelParams, **sizingParams)) # DIFFRACTION PATTERN FROM FIT analysis.sizing.sphereModel(evt, "analysis", "offCenterX", "offCenterY", "diameter", "intensity", (ny_back/binning,nx_back/binning), poisson=False, **modelParams) # RADIAL AVERAGE FIT analysis.pixel_detector.radial(evt, "analysis", "fit", mask=mask_back_b, cx=evt["analysis"]["cx"].data, cy=evt["analysis"]["cy"].data) # ERRORS analysis.sizing.photon_error(evt, back_type_b, back_key_b, "analysis", "fit", 144.) analysis.sizing.absolute_error(evt, back_type_b, back_key_b, "analysis", "fit", "absolute error") # Image of fit msg = "diameter: %.2f nm \nIntensity: %.2f mJ/um2\nError: %.2e" %(evt["analysis"]["diameter"].data, evt["analysis"]["intensity"].data, evt["analysis"]["photon error"].data) # HYBRID PATTERN hybrid = evt["analysis"]["fit"].data.copy() hybrid[:,:520/binning] = evt[back_type_b][back_key_b].data[:,:520/binning] add_record(evt["analysis"], "analysis", "Hybrid pattern", hybrid) error = evt["analysis"]["photon error"].data plotting.image.plotImage(evt["analysis"]["Hybrid pattern"], mask=mask_back_b, name="Hybrid pattern", msg=msg) plotting.line.plotHistory(evt["analysis"]["photon error"], history=1000) plotting.image.plotImage(evt["analysis"]["fit"], log=True, mask=mask_back_b, name="pnCCD: Fit result (radial sphere fit)", msg=msg) # Plot measurement radial average plotting.line.plotTrace(evt["analysis"]["radial average - "+back_key_b], evt["analysis"]["radial distance - "+back_key_b],tracelen=radial_tracelen) # Plot fit radial average plotting.line.plotTrace(evt["analysis"]["radial average - fit"], evt["analysis"]["radial distance - fit"], tracelen=radial_tracelen) diameter_pix = evt["analysis"]["diameter"].data * 1E-9 / res analysis.patterson.patterson(evt, back_type_b, back_key_b, mask_back_b, threshold=4. ,diameter_pix=diameter_pix) plotting.image.plotImage(evt["analysis"]["patterson"], name="Patterson") plotting.line.plotHistory(evt["analysis"]["multiple score"], history=1000)
def _tr_cspad2x2(self, values, obj): """Translates CsPad2x2 to hummingbird numpy array""" add_record(values, 'photonPixelDetectors', 'CsPad2x2', obj.data16(), ureg.ADU)
def patterson(evt, type, key, mask=None, threshold=None, diameter_pix=None, crop=None, full_output=False, xgap_pix=None, ygap_pix=None, frame_pix=None, **params): """TODO: missing docstring .. note:: This feature depends on the python package `libspimage <https://github.com/FilipeMaia/libspimage>`_. """ success, module = utils.io.load_spimage() if not success: print("Skipping analysis.patterson.patterson") return img = evt[type][key].data if mask is None: mask = numpy.ones(shape=img.shape, dtype="bool") else: mask = numpy.array(mask, dtype="bool") if crop is not None: img = module.crop(img, crop) mask = module.crop(mask, crop) out = module.patterson(numpy.float64(img), mask, full_output=full_output, normalize_median=False, **params) v = evt["analysis"] if full_output: P = abs(out[0]) info = out[1] add_record(v, "analysis", "patterson kernel", info["kernel"], unit='') add_record(v, "analysis", "patterson intensities", info["intensities_times_kernel"], unit='') else: P = abs(out) m = numpy.median(P) if not numpy.isclose(m, 0.): P = P / m add_record(v, "analysis", "patterson", P, unit='') if threshold is not None: Minf = ~numpy.isfinite(P) if Minf.sum() > 0: P[Minf] = 0 M = P > threshold if diameter_pix is not None: Y, X = numpy.indices(P.shape) X -= P.shape[1] / 2 Y -= P.shape[0] / 2 Rsq = X**2 + Y**2 M *= Rsq > (diameter_pix / 2)**2 if xgap_pix is not None: cy = M.shape[0] / 2 M[cy - xgap_pix / 2:cy + xgap_pix / 2, :] = False if ygap_pix is not None: cx = M.shape[1] / 2 M[:, cx - ygap_pix / 2:cx + ygap_pix / 2] = False if frame_pix is not None: M[:frame_pix, :] = False M[-frame_pix:, :] = False M[:, :frame_pix] = False M[:, -frame_pix:] = False if full_output: add_record(v, "analysis", "patterson multiples", M, unit='') multiple_score = M.sum() add_record(v, "analysis", "multiple score", multiple_score, unit='')
def _tr_lusi_ipm_fex(self, values, obj, evt_key): """Translates Ipm relative pulse energy monitor to hummingbird pulse energy""" add_record(values, 'pulseEnergies', 'IpmFex - ' + str(evt_key.src()), obj.sum(), ureg.ADU)
def holographic_hitfinder_evt(evt, type, key, maskt, gMask, centerMask, off_x, th=3,radius_smooth=70): t = time.time() img = evt[type][key].data #img = gaussian_filter(img,sigma=3) hitData = numpy.zeros((1024+off_x,1024+off_x)) hitData[:513,:] = img[:513,:] hitData[-514:,:] = img[-514:,:] #mask = numpy.zeros((1024+off_x,1024+off_x)) #mask[:513,:] = mask[:513,:] #mask[-514:,:] = maskt[-514:,:] hitData[hitData > 12000] = 0 hitData[hitData < 30] = 0 # hitData[:512,393] = 0 # hitData[-512:,395] = 0 dd = int(off_x/2) cropsize = 256 pattern = hitData[dd+cropsize:-dd-cropsize,dd+cropsize:-dd-cropsize] mask = maskt[dd+cropsize:-dd-cropsize,dd+cropsize:-dd-cropsize] gMask = gMask[dd+cropsize:-dd-cropsize,dd+cropsize:-dd-cropsize] centerMask = centerMask[dd+cropsize:-dd-cropsize,dd+cropsize:-dd-cropsize] pattern[:512,393] = 0 pattern[-512:,395] = 0 hitData = pattern*mask Ifilter = make_filter( pattern.shape[0],radius_smooth )[0] hitData *= Ifilter #holoData = autocorrelation(hitData,radius_smooth) #holoData *= gMask hitData *= gMask holoData = fftshift(numpy.abs(ifft2(hitData))) holoData *= centerMask hData = holoData[holoData>0] med = numpy.median(hData) if holoData.max() > 0: holoData /= holoData.max() med = numpy.median(holoData) #hitS = 1.*(holoData > 0.05) hitS = 1.*(holoData > med*4) #hitS = crossremove(hitS) hitScore = hitS.sum() if hitScore > 2000: #hitS = 1.*(holoData > 0.15) hitS = 1.*(holoData > med*6) #hitS = crossremove(hitS) #hitScore = hitS.sum() if hitScore > 5000: hitS = binary_erosion(hitS) hitS = binary_erosion(hitS) hitS = binary_erosion(hitS) hitS = binary_erosion(hitS) hitS = binary_dilation(hitS) #hitScore = hitS.sum() #labeled = hitS #labeled, n = ndimage.measurements.label(hitS) #else: #hitS[0][0] = 2 hitS = crossremove(hitS) labeled, n = ndimage.measurements.label(hitS) holoData[labeled == labeled[256][256]] = 0 labeled[labeled == labeled[256][256]] = 0 for i in range(1,n): ss = ((labeled == i)*1.).sum() if ss < 8: labeled[labeled == i] = 0 hitS[labeled == i] = 0. hitScore = ((labeled>0)*1).sum() # print hitScore #print holoData add_record(evt["analysis"], "analysis", "hologramScore", hitScore) add_record(evt["analysis"], "analysis", "holoData", holoData) add_record(evt["analysis"], "analysis", "labeledHolograms", labeled) add_record(evt["analysis"], "analysis", "croppedPattern", pattern*mask)
def make_propagation(evt, type, key_img, key_mask, imnr, minPhase=-120000, maxPhase=120000, steps=50, field_of_view_rad=50, wavelength=2.353, CCD_S_DIST=0.38, PX_SIZE=75e-6,Npixel=50): img = evt[type][key_img].data Xrange, Yrange = img.shape p = numpy.linspace(-Xrange/2, Xrange/2-1, Xrange) q = numpy.linspace(-Yrange/2, Yrange/2-1, Yrange) pp, qq = numpy.meshgrid(p, q) rr = numpy.sqrt(pp**2+qq**2) phase_matrix = (2*numpy.pi/wavelength)*numpy.sqrt(1-((PX_SIZE/CCD_S_DIST)**2)*(qq**2 + pp**2)) img_shifted = fftshift(img) phase_matrix_shifted = fftshift(phase_matrix) r,rg = [],[] steps = 10 rgt = numpy.zeros((steps,Xrange,Yrange)) stepsize = maxPhase/steps from skimage.feature import canny import numpy as np sobt = numpy.zeros_like(img) runname='r0043' for step in range(steps): phase = stepsize*step img_propagated = img_shifted * numpy.exp(1.j*phase*phase_matrix_shifted) img_propagated[:,Yrange/2-3:Yrange/2+3] = img_propagated.mean() recon = fftshift(ifft2(img_propagated)) recon[rr < 30] = recon.mean() cc = canny(abs(recon), sigma=9) cc = binary_dilation(cc) cc = binary_dilation(cc) cc = binary_dilation(cc) cc = binary_fill_holes(cc) cc = binary_erosion(cc) cc = binary_erosion(cc) cc = binary_erosion(cc) cc = binary_erosion(cc) cc = binary_erosion(cc) criterion0 = cc sx = ndimage.sobel(abs(recon), axis=0, mode='constant') sy = ndimage.sobel(abs(recon), axis=1, mode='constant') sob = numpy.hypot(sx, sy) sob[rr < 31] = sob.max() sobt += (sob > 0.1*sob.max())*1. diff = abs(sob-sob.max()) diff /= diff.max() if phase == 0: criterion1 = sob>sob.max()/2 sg = gaussian_filter(sobt,sigma=1) labeled,nnn = ndimage.measurements.label(sg) remove = (labeled == labeled[256][256])*1 remove[246:266,:] = 1 remove[206:306,246:266]= 1 sg[labeled == labeled[256][256]] = 0 sg = sg > 0 sg = binary_erosion(sg) sg = binary_erosion(sg) sg = binary_erosion(sg) sg = binary_erosion(sg) sg = binary_erosion(sg) sg = binary_erosion(sg) sg = binary_erosion(sg) criterion2 = sg FF = 1*(criterion0+criterion1+criterion2)#*abs(1-remove) FF = binary_erosion(FF,numpy.ones((2,2))) FF[remove > 0] = 1 labeled,nnn = ndimage.measurements.label(FF) labeled[labeled == labeled[256][256]] = 0 dance = labeled > 0 dance = binary_dilation(dance) if nnn-1 < 2: return 0 num_holograms = nnn-1 images = [] variance = [] centroids = [] for structure in numpy.unique(labeled): if structure < 1: continue centroids.append( numpy.round(center_of_mass(labeled == structure)).astype(int) ) images.append([]) variance.append([]) cnt = 0 for centerx,centery in centroids: reconcut = numpy.abs(recon[numpy.max([0, centerx-Npixel-1]).astype(int): numpy.min([Xrange-1, centerx+Npixel]).astype(int), numpy.max([0, centery-Npixel-1]).astype(int): numpy.min([Yrange-1, centery+Npixel]).astype(int)]) images[cnt].append(reconcut) variance[cnt].append(reconcut.var()) cnt +=1 #imsave('hitScores/hollows/img_recon_%05d_%06d_3.png'%(imnr,phase),recon,cmap='gray') #rg.append(recon) #print variance focused_CC = [] z_location = [] for i in range(num_holograms): minn = numpy.argmax(numpy.array(variance[i])) #imsave('hitScores/hollows/img_%s_%05d_%06d_%d.png'%(runname,imnr,phase,i), images[i][minn]) focused_CC.append(images[i][numpy.argmin(numpy.array(variance[i]))]) z_location.append(stepsize*minn) if len(focused_CC) > 0: add_record(evt["analysis"], "analysis", "focused_CC", focused_CC[0]) add_record(evt["analysis"], "analysis", "focus distance", z_location)
def onEvent(evt): # Counter global counter counter += 1 # Option to stop after fixed number of frames if args.nr_frames is not None: #print counter, args.nr_frames/ipc.mpi.nr_event_readers() if (counter == args.nr_frames / ipc.mpi.nr_event_readers()): raise StopIteration # Processing rate [Hz] analysis.event.printProcessingRate() # Read FEL parameters try: wavelength_nm = evt['FEL']['wavelength'].data gmd = evt['FEL']['gmd'].data except RuntimeError: wavelength_nm = np.nan gmd = np.nan detector_type = detector_type_raw detector_key = detector_key_raw detector = evt[detector_type][detector_key] if move_half: detector_s = analysis.pixel_detector.moveHalf( evt, detector, horizontal=int(gap_total / pixel_size), outkey='data_half-moved') mask_center_s = analysis.pixel_detector.moveHalf( evt, add_record(evt["analysis"], "analysis", "mask", mask_center), horizontal=int(gap_total / pixel_size), outkey='mask_half-moved').data detector_type = "analysis" detector_key = "data_half-moved" detector = evt[detector_type][detector_key] else: mask_center_s = mask_center # Do basic hitfinding using lit pixels analysis.hitfinding.countLitPixels(evt, detector, aduThreshold=aduThreshold, hitscoreThreshold=hitScoreThreshold, mask=mask_center_s) hit = bool(evt["analysis"]["litpixel: isHit"].data) hitscore = evt['analysis']['litpixel: hitscore'].data global hitscore_cache hitscore_cache[counter % cache_length] = hitscore # Find multiple hits based on patterson function if hit: analysis.patterson.patterson(evt, "analysis", "data_half-moved", mask_center_s, threshold=patterson_threshold, diameter_pix=patterson_diameter, xgap_pix=patterson_xgap_pix, ygap_pix=patterson_ygap_pix, frame_pix=patterson_frame_pix, crop=512, full_output=True, **patterson_params) #print evt['analysis'].keys() multiple_hit = evt["analysis"][ "multiple score"].data > multiScoreThreshold # Write to file if save_anything: if hit and (not args.only_save_multiples or multiple_hit): D = {} D['entry_1'] = {} D['entry_1']['event'] = {} D['entry_1']['motors'] = {} D['entry_1']['FEL'] = {} D['entry_1']['result_1'] = {} if save_pnccd: D['entry_1']['detector_1'] = {} if save_tof: D['entry_1']['detector_2'] = {} # PNCCD if save_pnccd: D['entry_1']['detector_1']['data'] = np.asarray( detector.data, dtype='float16') if ipc.mpi.is_main_event_reader() and len(D_solo) == 0: bitmask = np.array(mask_center_s, dtype='uint16') bitmask[bitmask == 0] = 512 bitmask[bitmask == 1] = 0 D_solo["entry_1"] = {} D_solo["entry_1"]["detector_1"] = {} D_solo["entry_1"]["detector_1"]["mask"] = bitmask # PATTERSON if save_multiple: D['entry_1']['detector_1']['patterson'] = np.asarray( evt['analysis']['patterson'].data, dtype='float16') D['entry_1']['detector_1']['patterson_mask'] = np.asarray( evt['analysis']['patterson multiples'].data, dtype='bool') # TOF if save_tof: # Read ToF traces try: tof = evt["DAQ"]["TOF"] except RuntimeError: logging.warning("Runtime error when reading TOF data.") return except KeyError: logging.warning("Key error when reading TOF data.") return D['entry_1']['detector_2']['data'] = np.asarray( tof.data, dtype='float16') # HIT PARAMETERS D['entry_1']['result_1']['hitscore_litpixel'] = evt['analysis'][ 'litpixel: hitscore'].data D['entry_1']['result_1'][ 'hitscore_litpixel_threshold'] = hitScoreThreshold D['entry_1']['result_1']['multiscore_patterson'] = evt['analysis'][ 'multiple score'].data D['entry_1']['result_1'][ 'multiscore_patterson_threshold'] = multiScoreThreshold try: # FEL PARAMETERS D['entry_1']['FEL']['gmd'] = gmd D['entry_1']['FEL']['wavelength_nm'] = wavelength_nm except KeyError: logging.warning("Cannot find FEL data.") try: # EVENT IDENTIFIERS D['entry_1']['event']['bunch_id'] = evt['ID']['BunchID'].data D['entry_1']['event']['tv_sec'] = evt['ID']['tv_sec'].data D['entry_1']['event']['tv_usec'] = evt['ID']['tv_usec'].data D['entry_1']['event']['dataset_id'] = evt['ID'][ 'DataSetID'].data D['entry_1']['event']['bunch_sec'] = evt['ID'][ 'bunch_sec'].data except KeyError: logging.warning("Cannot find event data.") try: # MOTORS D['entry_1']['motors']['manualy'] = evt['motorPositions'][ 'ManualY'].data D['entry_1']['motors']['injectorx'] = evt['motorPositions'][ 'InjectorX'].data D['entry_1']['motors']['injectory'] = evt['motorPositions'][ 'InjectorZ'].data D['entry_1']['motors']['trigdelay'] = evt['motorPositions'][ 'TrigDelay'].data D['entry_1']['motors']['samplepress'] = evt['motorPositions'][ 'InjectorSamplePressure'].data D['entry_1']['motors']['nozzlepress'] = evt['motorPositions'][ 'InjectorNozzlePressure'].data D['entry_1']['motors']['posdownstream'] = evt[ 'motorPositions']['PosDownstream'].data D['entry_1']['motors']['posupstream'] = evt['motorPositions'][ 'PosUpstream'].data D['entry_1']['motors']['injectorpress'] = evt[ 'motorPositions']['InjectorPressure'].data D['entry_1']['motors']['focusinggas'] = evt['motorPositions'][ 'InjectorFocusingGas'].data except KeyError: logging.warning("Cannot find motor data.") # TODO: FEL W.write_slice(D)
def make_propagation(evt, type, key_img, key_mask, imnr, minPhase=-120000, maxPhase=120000, steps=50, field_of_view_rad=50, wavelength=2.353, CCD_S_DIST=0.38, PX_SIZE=75e-6, Npixel=50): img = evt[type][key_img].data Xrange, Yrange = img.shape p = numpy.linspace(-Xrange / 2, Xrange / 2 - 1, Xrange) q = numpy.linspace(-Yrange / 2, Yrange / 2 - 1, Yrange) pp, qq = numpy.meshgrid(p, q) rr = numpy.sqrt(pp**2 + qq**2) phase_matrix = (2 * numpy.pi / wavelength) * numpy.sqrt(1 - ( (PX_SIZE / CCD_S_DIST)**2) * (qq**2 + pp**2)) img_shifted = fftshift(img) phase_matrix_shifted = fftshift(phase_matrix) r, rg = [], [] steps = 10 rgt = numpy.zeros((steps, Xrange, Yrange)) stepsize = maxPhase / steps from skimage.feature import canny import numpy as np sobt = numpy.zeros_like(img) runname = 'r0043' for step in range(steps): phase = stepsize * step img_propagated = img_shifted * numpy.exp( 1.j * phase * phase_matrix_shifted) img_propagated[:, Yrange / 2 - 3:Yrange / 2 + 3] = img_propagated.mean() recon = fftshift(ifft2(img_propagated)) recon[rr < 30] = recon.mean() cc = canny(abs(recon), sigma=9) cc = binary_dilation(cc) cc = binary_dilation(cc) cc = binary_dilation(cc) cc = binary_fill_holes(cc) cc = binary_erosion(cc) cc = binary_erosion(cc) cc = binary_erosion(cc) cc = binary_erosion(cc) cc = binary_erosion(cc) criterion0 = cc sx = ndimage.sobel(abs(recon), axis=0, mode='constant') sy = ndimage.sobel(abs(recon), axis=1, mode='constant') sob = numpy.hypot(sx, sy) sob[rr < 31] = sob.max() sobt += (sob > 0.1 * sob.max()) * 1. diff = abs(sob - sob.max()) diff /= diff.max() if phase == 0: criterion1 = sob > sob.max() / 2 sg = gaussian_filter(sobt, sigma=1) labeled, nnn = ndimage.measurements.label(sg) remove = (labeled == labeled[256][256]) * 1 remove[246:266, :] = 1 remove[206:306, 246:266] = 1 sg[labeled == labeled[256][256]] = 0 sg = sg > 0 sg = binary_erosion(sg) sg = binary_erosion(sg) sg = binary_erosion(sg) sg = binary_erosion(sg) sg = binary_erosion(sg) sg = binary_erosion(sg) sg = binary_erosion(sg) criterion2 = sg FF = 1 * (criterion0 + criterion1 + criterion2) #*abs(1-remove) FF = binary_erosion(FF, numpy.ones((2, 2))) FF[remove > 0] = 1 labeled, nnn = ndimage.measurements.label(FF) labeled[labeled == labeled[256][256]] = 0 dance = labeled > 0 dance = binary_dilation(dance) if nnn - 1 < 2: return 0 num_holograms = nnn - 1 images = [] variance = [] centroids = [] for structure in numpy.unique(labeled): if structure < 1: continue centroids.append( numpy.round( center_of_mass(labeled == structure)).astype(int)) images.append([]) variance.append([]) cnt = 0 for centerx, centery in centroids: reconcut = numpy.abs( recon[numpy.max([0, centerx - Npixel - 1]).astype(int):numpy. min([Xrange - 1, centerx + Npixel]).astype(int), numpy.max([0, centery - Npixel - 1]).astype(int):numpy. min([Yrange - 1, centery + Npixel]).astype(int)]) images[cnt].append(reconcut) variance[cnt].append(reconcut.var()) cnt += 1 #imsave('hitScores/hollows/img_recon_%05d_%06d_3.png'%(imnr,phase),recon,cmap='gray') #rg.append(recon) #print variance focused_CC = [] z_location = [] for i in range(num_holograms): minn = numpy.argmax(numpy.array(variance[i])) #imsave('hitScores/hollows/img_%s_%05d_%06d_%d.png'%(runname,imnr,phase,i), images[i][minn]) focused_CC.append(images[i][numpy.argmin(numpy.array(variance[i]))]) z_location.append(stepsize * minn) if len(focused_CC) > 0: add_record(evt["analysis"], "analysis", "focused_CC", focused_CC[0]) add_record(evt["analysis"], "analysis", "focus distance", z_location)
def _tr_pnccdFullFrame(self, values, obj, evt_key): """Translates full pnCCD frame to hummingbird numpy array""" add_record(values, 'photonPixelDetectors', '%sfullFrame' % self._s2c[str(evt_key.src())], obj.data(), ureg.ADU)
def onEvent(evt): # Processing rate [Hz] #analysis.event.printProcessingRate() # Calculate time and add to PlotHistory # calculate_epoch_times(evt, evt["ID"]["tv_sec"], evt["ID"]["tv_usec"]) # plotting.line.plotHistory(evt['ID']['timeAgo'], label='Event Time (s)', group='ID') # plotting.line.plotHistory(evt['ID']['tv_sec'], label='Epoch Time (s)', group='ID') detector_type = "photonPixelDetectors" detector_key = "pnCCD" if move_half: detector = evt[detector_type][detector_key] detector = analysis.pixel_detector.moveHalf(evt, detector, horizontal=gap_total / pixel_size, outkey='data_half-moved') mask_center_s = analysis.pixel_detector.moveHalf( evt, add_record(evt["analysis"], "analysis", "mask", mask_center), horizontal=gap_total / pixel_size, outkey='mask_half-moved').data detector_type = "analysis" detector_key = "data_half-moved" # Do basic hitfinding using lit pixels analysis.hitfinding.countLitPixels(evt, evt[detector_type][detector_key], aduThreshold=aduThreshold, hitscoreThreshold=hitScoreThreshold) hit = bool(evt["analysis"]["litpixel: isHit"].data) plotting.line.plotHistory(evt["analysis"]["litpixel: hitscore"], label='Nr. of lit pixels', hline=hitScoreThreshold, group='Metric') analysis.hitfinding.hitrate(evt, hit, history=50) if scanInjector: plotting.histogram.plotNormalizedHistogram( evt["motorPositions"]["InjectorX"], float(1 if hit else 0), hmin=scanXmin, hmax=scanXmax, bins=scanXbins, name="Histogram: InjectorX x Hitrate", group="Scan", buffer_length=1000) plotting.histogram.plotNormalizedHistogram( evt["motorPositions"]["InjectorZ"], float(1 if hit else 0), hmin=scanZmin, hmax=scanZmax, bins=scanZbins, name="Histogram: InjectorZ x Hitrate", group="Scan", buffer_length=1000) plotting.correlation.plotScatter(evt["motorPositions"]["InjectorX"], evt['analysis']['litpixel: hitscore'], name='InjectorX vs Hitscore', xlabel='InjectorX', ylabel='Hit Score', group='Scan') plotting.correlation.plotScatter(evt["motorPositions"]["InjectorZ"], evt['analysis']['litpixel: hitscore'], name='InjectorZ vs Hitscore', xlabel='InjectorZ', ylabel='Hit Score', group='Scan') plotting.line.plotHistory(evt["motorPositions"]["InjectorX"], label="Cluster delay", group="Scan") plotting.line.plotHistory(evt["motorPositions"]["InjectorZ"], label="Nothing", group="Scan") # print("InjectorX = {0}".format(evt["motorPositions"]["InjectorX"].data)) if outputEveryImage: plotting.image.plotImage(evt[detector_type][detector_key], name="pnCCD (All)", group='Images') if ipc.mpi.is_main_worker(): plotting.line.plotHistory(evt["analysis"]["hitrate"], label='Hit rate [%]', group='Metric', history=10000) # plotting.correlation.plotMeanMap(evt['motorPositions']['nozzle_x'], evt['motorPositions']['nozzle_y'], # #evt['analysis']['litpixel: hitscore'].data / 1e5, # evt['analysis']['hitrate'].data, # xmin=0.68, xmax=0.72, ymin=4.20, ymax=4.23, # name='Hitscore mean map vs nozzle_xy', # xlabel='nozzle_x (mm)', # ylabel='nozzle_y (mm)', # group='Metric') if hit: plotting.image.plotImage(evt[detector_type][detector_key], name="pnCCD (Hits)", group='Images', mask=mask_center_s) if do_sizing: # Crop to 1024 x 1024 Nx, Ny = np.shape(evt[detector_type][detector_key].data) diff_y = Ny - 1024 cropped_img = evt[detector_type][detector_key].data[:, diff_y / 2:-(diff_y / 2)] add_record(evt["analysis"], "analysis", "data-cropped", cropped_img) detector_key = "data-cropped" cropped_mask = mask_center_s[:, diff_y / 2:-(diff_y / 2)] add_record(evt["analysis"], "analysis", "mask-cropped", cropped_mask) mask_center_fit_s = evt['analysis']['mask-cropped'].data # Binning analysis.pixel_detector.bin(evt, detector_type, detector_key, binning, mask_center_fit_s) mask_binned = evt["analysis"]["binned mask - " + detector_key].data detector_type_b = "analysis" detector_key_b = "binned image - " + detector_key # CENTER DETERMINATION analysis.sizing.findCenter(evt, detector_type_b, detector_key_b, mask=mask_binned, **centerParams) # RADIAL AVERAGE analysis.pixel_detector.radial(evt, detector_type_b, detector_key_b, mask=mask_binned, cx=evt["analysis"]["cx"].data, cy=evt["analysis"]["cy"].data) # FIT SPHERE MODEL analysis.sizing.fitSphereRadial( evt, "analysis", "radial distance - " + detector_key_b, "radial average - " + detector_key_b, **dict(modelParams, **sizingParams)) # DIFFRACTION PATTERN FROM FIT analysis.sizing.sphereModel(evt, "analysis", "offCenterX", "offCenterY", "diameter", "intensity", (ny / binning, nx / binning), poisson=False, **modelParams) # RADIAL AVERAGE FIT analysis.pixel_detector.radial(evt, "analysis", "fit", mask=mask_binned, cx=evt["analysis"]["cx"].data, cy=evt["analysis"]["cy"].data) # ERRORS #analysis.sizing.photon_error(evt, detector_type_b, detector_key_b, "analysis", "fit", adu_per_photon=144.) #analysis.sizing.absolute_error(evt, detector_type_b, detector_key_b, "analysis", "fit", "absolute error") msg = "diameter: %.2f nm \nIntensity: %.4f mJ/um2\nFit Error: %.2e" % ( evt["analysis"]["diameter"].data, evt["analysis"]["intensity"].data, evt["analysis"]["fit error"].data) # Selection of good fits small_fit_error = evt['analysis'][ 'fit error'].data < fit_error_threshold #small_photon_error = evt['analysis']['photon error'].data < photon_error_threshold correctsized_hit = small_fit_error #and small_photon_error # Select only events in a certain diameter window diameter = evt['analysis']['diameter'].data print diameter plotting.histogram.plotHistogram(evt["analysis"]["diameter"], bins=100, name="Histogram: Particle size", group="Sizing", hmin=20, hmax=100, buffer_length=1000) #correctsized_hit &= ((diameter > diameter_min) & (diameter < diameter_max)) # Plot errors plotting.line.plotHistory(evt["analysis"]["fit error"], history=1000, hline=fit_error_threshold, group='Sizing') #plotting.line.plotHistory(evt["analysis"]["photon error"], history=1000, hline=photon_error_threshold, group='Sizing') #plotting.line.plotHistory(evt["analysis"]["absolute error"], history=1000, group='Sizing') #time.sleep(0.05) if do_showhybrid: # HYBRID PATTERN hybrid = evt["analysis"]["fit"].data.copy() hybrid[:, 512 / binning:] = evt[detector_type_b][ detector_key_b].data[:, 512 / binning:] add_record(evt["analysis"], "analysis", "Hybrid pattern", hybrid) plotting.image.plotImage(evt["analysis"]["Hybrid pattern"], name="Hybrid pattern ", msg=msg, group='Sizing') plotting.image.plotImage(evt["analysis"]["Hybrid pattern"], name="Hybrid pattern / log", vmax=1e4, log=True, msg=msg, group='Sizing') if correctsized_hit: # Plot Correct sized hits plotting.image.plotImage( evt[detector_type][detector_key], group='Sizing', msg=msg, name="pnCCD front (correct hit)") #, mask=mask_front_s) # Plot Intensity plotting.line.plotHistory(evt["analysis"]["intensity"], history=10000, name='Intensity (from sizing)', group='Results') # Plot size (in nm) plotting.line.plotHistory(evt["analysis"]["diameter"], history=10000, name='Size in nm (from sizing)', group='Results') # Normalizing intensity to pulse energy (assuming 1mJ on average) #intensity_normalized = (evt['analysis']['intensity'].data / evt['analysis']['averagePulseEnergy'].data) * 1.0 #add_record(evt['analysis'], 'analysis', 'intensity_normalized', intensity_normalized) # Plot Intensity (normalized) plotting.line.plotHistory( evt['analysis']['intensity'], history=10000, name='Intensity normalized (from sizing)', group='Results')
def _tr_event_codes(self, values, obj): """Translates LCLS event codes into a hummingbird ones""" codes = [] for fifo_event in obj.fifoEvents(): codes.append(fifo_event.eventCode()) add_record(values, 'eventCodes', 'EvrEventCodes', codes)
def find_foci(evt, type, key, type2, key2, minPhase=-500000, maxPhase=500000, steps=101, field_of_view_rad=100, wavelength=1.053, CCD_S_DIST=0.375, PX_SIZE=75e-6): img = evt[type][key].data centroids = evt[type2][key2].data Nfoci = centroids.shape[0] Xrange, Yrange = img.shape Npixel = field_of_view_rad p = numpy.linspace(-Xrange / 2, Xrange / 2 - 1, Xrange) q = numpy.linspace(-Yrange / 2, Yrange / 2 - 1, Yrange) pp, qq = numpy.meshgrid(p, q) phase_matrix = (2 * numpy.pi / wavelength) * numpy.sqrt(1 - ( (PX_SIZE / CCD_S_DIST)**2) * (qq**2 + pp**2)) prop_length = numpy.linspace(minPhase, maxPhase, steps) variance = numpy.zeros([steps, Nfoci]) # shift stuff for performance reasons img_shifted = fftshift(img) phase_matrix_shifted = fftshift(phase_matrix) for idx, phase in enumerate(prop_length): img_propagated = img_shifted * numpy.exp( 1.j * phase * phase_matrix_shifted) recon = fftshift(ifft2(img_propagated)) for CC in numpy.arange(Nfoci): centerx, centery = centroids[CC, :] ###print centerx, centery reconcut = numpy.abs( recon[numpy.max([0, centerx - Npixel - 1]).astype(int):numpy. min([Xrange - 1, centerx + Npixel]).astype(int), numpy.max([0, centery - Npixel - 1]).astype(int):numpy. min([Yrange - 1, centery + Npixel]).astype(int)]) variance[idx, CC] = reconcut.var() focus_distance = numpy.zeros(Nfoci) CC_size = numpy.zeros(Nfoci) focused_CC = numpy.zeros(4 * Npixel**2 * Nfoci).reshape( Nfoci, 2 * Npixel, 2 * Npixel) for CC in numpy.arange(Nfoci): ind_max = numpy.argmax(variance[:, CC]) tmp = variance[:, CC] # get max which is not at border loc_max_bool = numpy.r_[True, tmp[1:] > tmp[:-1]] & numpy.r_[ tmp[:-1] > tmp[1:], True] loc_max_bool[0] = False loc_max_bool[-1] = False ind_max = numpy.argmax(tmp * loc_max_bool) focus_distance[CC] = prop_length[ind_max] img_propagated = img_shifted * numpy.exp( 1.j * focus_distance[CC] * phase_matrix_shifted) recon = fftshift(ifft2(img_propagated)) centerx, centery = centroids[CC, :] reconcut = numpy.real( recon[numpy.max([0, centerx - Npixel]).astype(int):numpy. min([Xrange - 1, centerx + Npixel]).astype(int), numpy.max([0, centery - Npixel]).astype(int):numpy. min([Yrange - 1, centery + Npixel]).astype(int)]) focused_CC[CC, 0:reconcut.shape[0], 0:reconcut.shape[1]] = reconcut CC_size[CC] = numpy.sum(get_CC_size(reconcut)) if len(focused_CC): add_record(evt["analysis"], "analysis", "focused_CC", focused_CC[0]) add_record(evt["analysis"], "analysis", "focus distance", focus_distance) add_record(evt["analysis"], "analysis", "CC_size", CC_size) add_record(evt["analysis"], "analysis", "propagation length", prop_length)
def _tr_bld_data_ebeam(self, values, obj): """Translates BldDataEBeam to hummingbird photon energy and other beam properties""" try: photon_energy_ev = obj.ebeamPhotonEnergy() except AttributeError: peak_current = obj.ebeamPkCurrBC2() dl2_energy_gev = 0.001*obj.ebeamL3Energy() ltu_wake_loss = 0.0016293*peak_current # Spontaneous radiation loss per segment sr_loss_per_segment = 0.63*dl2_energy_gev # wakeloss in an undulator segment wake_loss_per_segment = 0.0003*peak_current # energy loss per segment energy_loss_per_segment = (sr_loss_per_segment + wake_loss_per_segment) # energy in first active undulator segment [GeV] energy_profile = (dl2_energy_gev - 0.001*ltu_wake_loss - 0.0005*energy_loss_per_segment) # Calculate the resonant photon energy of the first active segment photon_energy_ev = 44.42*energy_profile*energy_profile add_record(values, 'photonEnergies', 'photonEnergy', photon_energy_ev, ureg.eV) try: ebeam_ang_x = obj.ebeamLTUAngX() ebeam_ang_y = obj.ebeamLTUAngY() ebeam_pos_x = obj.ebeamLTUPosX() ebeam_pos_y = obj.ebeamLTUPosY() ebeam_charge = obj.ebeamCharge() add_record(values, 'photonEnergies', 'angX', ebeam_ang_x) add_record(values, 'photonEnergies', 'angY', ebeam_ang_y) add_record(values, 'photonEnergies', 'posX', ebeam_pos_x) add_record(values, 'photonEnergies', 'posY', ebeam_pos_y) add_record(values, 'photonEnergies', 'charge', ebeam_charge) except AttributeError: print("Couldn't translate electron beam properties from BldDataEBeam")
def patterson(evt, type, key, mask=None, threshold=None, diameter_pix=None, crop=None, full_output=False, **params): """TODO: missing docstring .. note:: This feature depends on the python package `libspimage <https://github.com/FilipeMaia/libspimage>`_. """ success, module = utils.io.load_spimage() if not success: print "Skipping analysis.patterson.patterson" return img = evt[type][key].data if mask is None: mask = numpy.ones(shape=img.shape, dtype="bool") else: mask = numpy.array(mask, dtype="bool") if crop is not None: img = module.crop(img, crop) mask = module.crop(mask, crop) out = module.patterson(numpy.float64(img), mask, full_output=full_output, normalize_median=True, **params) v = evt["analysis"] if full_output: P = abs(out[0]) info = out[1] add_record(v, "analysis", "patterson kernel", info["kernel"], unit='') add_record(v, "analysis", "patterson intensities", info["intensities_times_kernel"], unit='') else: P = abs(out) add_record(v, "analysis", "patterson", abs(P), unit='') if threshold is not None: M = P > threshold if diameter_pix is not None: Y, X = numpy.indices(P.shape) X -= P.shape[1] / 2 Y -= P.shape[0] / 2 Rsq = X**2 + Y**2 M *= Rsq > diameter_pix**2 if full_output: add_record(v, "analysis", "patterson multiples", M, unit='') multiple_score = M.sum() add_record(v, "analysis", "multiple score", multiple_score, unit='')
def onEvent(evt): # Processing rate [Hz] #analysis.event.printProcessingRate() # Calculate time and add to PlotHistory # calculate_epoch_times(evt, evt["ID"]["tv_sec"], evt["ID"]["tv_usec"]) # plotting.line.plotHistory(evt['ID']['timeAgo'], label='Event Time (s)', group='ID') # plotting.line.plotHistory(evt['ID']['tv_sec'], label='Epoch Time (s)', group='ID') detector_type = "photonPixelDetectors" detector_key = "pnCCD" if move_half: detector = evt[detector_type][detector_key] detector = analysis.pixel_detector.moveHalf(evt, detector, horizontal=int(gap_total / pixel_size), outkey='data_half-moved') mask_center_s = analysis.pixel_detector.moveHalf( evt, add_record(evt["analysis"], "analysis", "mask", mask_center), horizontal=int(gap_total / pixel_size), outkey='mask_half-moved').data detector_type = "analysis" detector_key = "data_half-moved" # Do basic hitfinding using lit pixels analysis.hitfinding.countLitPixels(evt, evt[detector_type][detector_key], aduThreshold=aduThreshold, hitscoreThreshold=hitScoreThreshold, mask=mask_center_s) hit = bool(evt["analysis"]["litpixel: isHit"].data) strong_hit = evt["analysis"][ "litpixel: hitscore"].data > strong_hit_threshold plotting.line.plotHistory(add_record( evt["analysis"], "analysis", "total ADUs", evt[detector_type][detector_key].data.sum()), label='Total ADU', hline=hitScoreThreshold, group='Metric', history=1000) plotting.line.plotHistory(evt["analysis"]["litpixel: hitscore"], label='Nr. of lit pixels', hline=hitScoreThreshold, group='Metric', history=1000) analysis.hitfinding.hitrate(evt, hit, history=50) plotting.line.plotHistory(add_record(evt["analysis"], "analysis", "is_hit", hit), label='Is hit', group='Metric', history=1000) is_strong_hit = evt["analysis"]["total ADUs"].data > 10e6 if hit and is_strong_hit: plotting.image.plotImage(evt[detector_type][detector_key], name="pnCCD (Very Strong)", group='Images', mask=mask_center_s) if scanInjector: plotting.histogram.plotNormalizedHistogram( evt["motorPositions"]["InjectorX"], float(1 if hit else 0), hmin=scanXmin, hmax=scanXmax, bins=scanXbins, name="Histogram: InjectorX x Hitrate", group="Scan injector pos", buffer_length=1000) plotting.histogram.plotNormalizedHistogram( evt["motorPositions"]["InjectorZ"], float(1 if hit else 0), hmin=scanZmin, hmax=scanZmax, bins=scanZbins, name="Histogram: InjectorZ x Hitrate", group="Scan injector pos", buffer_length=1000) plotting.histogram.plotNormalizedHistogram( evt["motorPositions"]["ManualY"], float(1 if hit else 0), hmin=scanYmin, hmax=scanYmax, bins=scanYbins, name="Histogram: ManualY x Hitrate", group="Scan injector pos", buffer_length=1000) plotting.histogram.plotNormalizedHistogram( evt["motorPositions"]["InjectorSamplePressure"], float(1 if hit else 0), hmin=50, hmax=300, bins=50, name="Histogram: InjectorSamplePressure x Hitrate", group="Scan injector pressure", buffer_length=1000) plotting.histogram.plotNormalizedHistogram( evt["motorPositions"]["InjectorNozzlePressure"], float(1 if hit else 0), hmin=50, hmax=300, bins=50, name="Histogram: InjectorNozzlePressure x Hitrate", group="Scan injector pressure", buffer_length=1000) plotting.histogram.plotNormalizedHistogram( evt["motorPositions"]["InjectorFocusingGas"], float(1 if hit else 0), hmin=50, hmax=300, bins=50, name="Histogram: InjectorFocusingGas x Hitrate", group="Scan injector pressure", buffer_length=1000) plotting.histogram.plotNormalizedHistogram( evt["motorPositions"]["InjectorPressure"], float(1 if hit else 0), hmin=50, hmax=300, bins=50, name="Histogram: InjectorPressure x Hitrate", group="Scan", buffer_length=1000) plotting.correlation.plotScatter(evt["motorPositions"]["InjectorX"], evt['analysis']['litpixel: hitscore'], name='InjectorX vs Hitscore', xlabel='InjectorX', ylabel='Hit Score', group='Scan injector pos') plotting.correlation.plotScatter(evt["motorPositions"]["InjectorZ"], evt['analysis']['litpixel: hitscore'], name='InjectorZ vs Hitscore', xlabel='InjectorZ', ylabel='Hit Score', group='Scan injector pos') plotting.correlation.plotScatter(evt["motorPositions"]["ManualY"], evt['analysis']['litpixel: hitscore'], name='ManualY vs Hitscore', xlabel='ManualY', ylabel='Hit Score', group='Scan injector pos') plotting.correlation.plotScatter( evt["motorPositions"]["InjectorSamplePressure"], evt['analysis']['litpixel: hitscore'], name='InjectorSamplePressure vs Hitscore', xlabel='InjectorSamplePressure', ylabel='Hit Score', group='Scan injector pressure') plotting.correlation.plotScatter( evt["motorPositions"]["InjectorNozzlePressure"], evt['analysis']['litpixel: hitscore'], name='InjectorNozzlePressure vs Hitscore', xlabel='InjectorNozzlePressure', ylabel='Hit Score', group='Scan injector pressure') plotting.correlation.plotScatter( evt["motorPositions"]["InjectorFocusingGas"], evt['analysis']['litpixel: hitscore'], name='InjectorFocusingGas vs Hitscore', xlabel='InjectorFocusingGas', ylabel='Hit Score', group='Scan injector presssure') plotting.correlation.plotScatter( evt["motorPositions"]["InjectorPressure"], evt['analysis']['litpixel: hitscore'], name='InjectorPressure vs Hitscore', xlabel='InjectorPressure', ylabel='Hit Score', group='Scan injector pressure') plotting.line.plotHistory(evt["motorPositions"]["InjectorX"], label="InjectorX", group="Scan injector pos") plotting.line.plotHistory(evt["motorPositions"]["InjectorZ"], label="InjectorZ", group="Scan injector pos") if outputEveryImage: plotting.image.plotImage(evt[detector_type][detector_key], name="pnCCD (All)", group='Images', mask=mask_center_s) if ipc.mpi.is_main_worker(): plotting.line.plotHistory(evt["analysis"]["hitrate"], label='Hit rate [%]', group='Metric', history=10000) # plotting.correlation.plotMeanMap(evt['motorPositions']['nozzle_x'], evt['motorPositions']['nozzle_y'], # #evt['analysis']['litpixel: hitscore'].data / 1e5, # evt['analysis']['hitrate'].data, # xmin=0.68, xmax=0.72, ymin=4.20, ymax=4.23, # name='Hitscore mean map vs nozzle_xy', # xlabel='nozzle_x (mm)', # ylabel='nozzle_y (mm)', # group='Metric') if hit: plotting.image.plotImage(evt[detector_type][detector_key], name="pnCCD (log Hits)", group='Images', mask=mask_center_s, log=True) plotting.image.plotImage(evt[detector_type][detector_key], name="pnCCD (Hits)", group='Images', mask=mask_center_s, log=False) if do_sizing: # Crop to 1024 x 1024 Nx, Ny = np.shape(evt[detector_type][detector_key].data) diff_y = Ny - 1024 cropped_img = evt[detector_type][detector_key].data[:, diff_y / 2:-(diff_y / 2)] add_record(evt["analysis"], "analysis", "data-cropped", cropped_img) detector_key = "data-cropped" cropped_mask = mask_center_s[:, diff_y / 2:-(diff_y / 2)] add_record(evt["analysis"], "analysis", "mask-cropped", cropped_mask) mask_center_fit_s = evt['analysis']['mask-cropped'].data # Binning analysis.pixel_detector.bin(evt, detector_type, detector_key, binning, mask_center_fit_s) mask_binned = evt["analysis"]["binned mask - " + detector_key].data detector_type_b = "analysis" detector_key_b = "binned image - " + detector_key # CENTER DETERMINATION analysis.sizing.findCenter(evt, detector_type_b, detector_key_b, mask=mask_binned, **centerParams) # RADIAL AVERAGE analysis.pixel_detector.radial(evt, detector_type_b, detector_key_b, mask=mask_binned, cx=evt["analysis"]["cx"].data, cy=evt["analysis"]["cy"].data) # FIT SPHERE MODEL analysis.sizing.fitSphereRadial( evt, "analysis", "radial distance - " + detector_key_b, "radial average - " + detector_key_b, **dict(modelParams, **sizingParams)) # DIFFRACTION PATTERN FROM FIT analysis.sizing.sphereModel(evt, "analysis", "offCenterX", "offCenterY", "diameter", "intensity", (ny / binning, nx / binning), poisson=False, **modelParams) # RADIAL AVERAGE FIT analysis.pixel_detector.radial(evt, "analysis", "fit", mask=mask_binned, cx=evt["analysis"]["cx"].data, cy=evt["analysis"]["cy"].data) # ERRORS #analysis.sizing.photon_error(evt, detector_type_b, detector_key_b, "analysis", "fit", adu_per_photon=144.) #analysis.sizing.absolute_error(evt, detector_type_b, detector_key_b, "analysis", "fit", "absolute error") msg = "diameter: %.2f nm \nIntensity: %.4f mJ/um2\nFit Error: %.2e" % ( evt["analysis"]["diameter"].data, evt["analysis"]["intensity"].data, evt["analysis"]["fit error"].data) # Selection of good fits small_fit_error = evt['analysis'][ 'fit error'].data < fit_error_threshold #small_photon_error = evt['analysis']['photon error'].data < photon_error_threshold correctsized_hit = small_fit_error #and small_photon_error # Select only events in a certain diameter window diameter = evt['analysis']['diameter'].data #print diameter plotting.histogram.plotHistogram(evt["analysis"]["diameter"], bins=100, name="Histogram: Particle size", group="Sizing", hmin=20, hmax=100, buffer_length=1000) correctsized_hit &= ((diameter > diameter_min) & (diameter < diameter_max)) # Plot errors plotting.line.plotHistory(evt["analysis"]["fit error"], history=1000, hline=fit_error_threshold, group='Sizing') #plotting.line.plotHistory(evt["analysis"]["photon error"], history=1000, hline=photon_error_threshold, group='Sizing') #plotting.line.plotHistory(evt["analysis"]["absolute error"], history=1000, group='Sizing') #time.sleep(0.05) if do_showhybrid: # HYBRID PATTERN hybrid = evt["analysis"]["fit"].data.copy() hybrid[:, 512 / binning:] = evt[detector_type_b][ detector_key_b].data[:, 512 / binning:] add_record(evt["analysis"], "analysis", "Hybrid pattern", hybrid) plotting.image.plotImage(evt["analysis"]["Hybrid pattern"], name="Hybrid pattern ", msg=msg, group='Sizing') plotting.image.plotImage(evt["analysis"]["Hybrid pattern"], name="Hybrid pattern / log", vmax=1e4, log=True, msg=msg, group='Sizing') if correctsized_hit: # Plot Correct sized hits plotting.image.plotImage(evt[detector_type][detector_key], group='Sizing', msg=msg, name="pnCCD front (correct hit)", mask=mask_center_fit_s) if strong_hit: plotting.image.plotImage( evt[detector_type][detector_key], group='Sizing', msg=msg, name="pnCCD front (correct and strong hit)", mask=mask_center_fit_s) # Plot Intensity plotting.line.plotHistory(evt["analysis"]["intensity"], history=10000, name='Intensity (from sizing)', group='Results') # Plot size (in nm) plotting.line.plotHistory(evt["analysis"]["diameter"], history=10000, name='Size in nm (from sizing)', group='Results') # Normalizing intensity to pulse energy (assuming 1mJ on average) #intensity_normalized = (evt['analysis']['intensity'].data / evt['analysis']['averagePulseEnergy'].data) * 1.0 #add_record(evt['analysis'], 'analysis', 'intensity_normalized', intensity_normalized) # Plot Intensity (normalized) plotting.line.plotHistory( evt['analysis']['intensity'], history=10000, name='Intensity normalized (from sizing)', group='Results') # Center position #plotting.correlation.plotMeanMap(evt["analysis"]["cx"], evt["analysis"]["cy"], intensity_normalized, group='Results',name='Wavefront (center vs. intensity)', xmin=-10, xmax=10, xbins=21, ymin=-10, ymax=10, ybins=21, xlabel='Center position in x', ylabel='Center position in y') if hit and do_patterson: analysis.patterson.patterson(evt, detector_type, detector_key, mask_center_s, threshold=patterson_threshold, diameter_pix=patterson_diameter, xgap_pix=patterson_xgap_pix, ygap_pix=patterson_ygap_pix, frame_pix=patterson_frame_pix, crop=512, full_output=True, **patterson_params) plotting.line.plotHistory(evt["analysis"]["multiple score"], history=1000, name='Multiscore', group='Holography', hline=multiScoreThreshold) #print evt["analysis"]["multiple score"].data, multiScoreThreshold multiple_hit = evt["analysis"][ "multiple score"].data > multiScoreThreshold if multiple_hit: plotting.image.plotImage(evt["analysis"]["patterson"], group="Holography", name="Patterson (multiple hits)") plotting.image.plotImage(evt["analysis"]["patterson multiples"], group="Holography", name="Patterson mask (multiple hits)") plotting.image.plotImage(evt[detector_type][detector_key], group="Holography", name="Multiple hits (image)", mask=mask_center_s) analysis.refocus_hologram.refocus_hologram_evt( evt, detector_type, detector_key) if do_hologram and evt["analysis"]["hologram_score"]: plotting.image.plotImage(evt["analysis"]["focused_CC"], group="Holography", name="refocused Hologram (image)") else: plotting.image.plotImage(evt["analysis"]["patterson"], group="Holography", name="Patterson (non-multiple hits)") if not hit and do_patterson: multiple_hit = False if do_patterson: analysis.hitfinding.hitrate(evt, multiple_hit, history=50, outkey='multiple_hitrate') if scanInjector: plotting.histogram.plotNormalizedHistogram( evt["motorPositions"]["InjectorX"], float(1 if multiple_hit else 0), hmin=scanXmin, hmax=scanXmax, bins=scanXbins, name="Histogram: InjectorX x Multiple hitrate", group="Scan injector pos", buffer_length=1000) plotting.histogram.plotNormalizedHistogram( evt["motorPositions"]["InjectorZ"], float(1 if multiple_hit else 0), hmin=scanZmin, hmax=scanZmax, bins=scanZbins, name="Histogram: InjectorZ x Multiple hitrate", group="Scan injector pos", buffer_length=1000) if ipc.mpi.is_main_worker(): plotting.line.plotHistory(evt["analysis"]["multiple_hitrate"], label='Multiple Hit rate [%]', group='Metric', history=10000) non_hitrate = max(1. - (evt["analysis"]["hitrate"].data / 100.), 0.01) multi_hitrate = (evt["analysis"]["multiple_hitrate"].data / 100.) hitrate_corrected_poisson = multi_hitrate / ( 0.25 * np.exp(-2.) * non_hitrate * np.log(non_hitrate)**2) #print "%f/%f/%.4f" %(non_hitrate,multi_hitrate,hitrate_corrected_poisson) e = add_record(evt['analysis'], "analysis", "multiple hitrate (corrected)", hitrate_corrected_poisson) plotting.line.plotHistory( e, label='Multiple hitrate (poisson corrected)', group='Holography', history=10000)