def gui(self): self.gui_reset() nFrames = SliderLabel(0) nFrames.setRange(0, 10000) self.items.append({ 'name': 'nFrames', 'string': 'Movie Duration (frames)', 'object': nFrames }) super().gui()
def gui(self): self.gui_reset() nFrames = SliderLabel(0) nFrames.setRange(0, 10000) puffAmplitude = SliderLabel(2) puffAmplitude.setRange(0, 10) nPuffs = SliderLabel(0) nPuffs.setRange(1, 100) pointsFile = FileSelector('*.txt') mx = SliderLabel(0) mx.setRange(1, 10000) my = SliderLabel(0) my.setRange(1, 10000) noisefree = CheckBox() self.items.append({ 'name': 'nFrames', 'string': 'Movie Duration (frames)', 'object': nFrames }) self.items.append({ 'name': 'puffAmplitude', 'string': 'Amplitude of puffs (multiples of SNR)', 'object': puffAmplitude }) self.items.append({ 'name': 'nPuffs', 'string': 'number of puffs', 'object': nPuffs }) self.items.append({ 'name': 'pointsFile', 'string': 'Location to save points', 'object': pointsFile }) self.items.append({ 'name': 'mx', 'string': 'Movie Width', 'object': mx }) self.items.append({ 'name': 'my', 'string': 'Movie Height', 'object': my }) self.items.append({ 'name': 'noisefree', 'string': 'Noise Free', 'object': noisefree }) super().gui()
def gui(self): self.gui_reset() nFrames=SliderLabel(0) nFrames.setRange(0,10000) nFrames.setValue(1000) puffAmplitude=SliderLabel(2) puffAmplitude.setRange(0,10) puffAmplitude.setValue(5) nPuffs=SliderLabel(0) nPuffs.setRange(1,100) nPuffs.setValue(10) pointsFile=FileSelector('*.txt') self.items.append({'name':'nFrames','string':'Movie Duration (frames)','object':nFrames}) self.items.append({'name':'puffAmplitude','string':'Amplitude of puffs (multiples of SNR)','object':puffAmplitude}) self.items.append({'name':'nPuffs','string':'number of puffs','object': nPuffs}) self.items.append({'name':'pointsFile','string':'Location to save points','object': pointsFile}) super().gui()
class Simulate_mepp(BaseProcess_noPriorWindow): """ Simulate MEPP events in a noisy time trace Trace generated by linear summation of randomly occuring unitary events hF(t) (MEPPs) see Segal et al. Biophys J, 1985 h = time independent amplitude factor F(t) = nondimensional function of time hF(t) = h(exp(-t/dT) - exp(-t/dR)) dT = decay time constant rT = rise time constant time of MEPP addition drawn from exponential distribution (np.random.exponential()) amplitude of MEPP drawn from normal distribution (np.random.normal()) duration of MEPP drawn from normal distribution (np.random.normal()) """ def __init__(self): if g.settings[ 'mepp_simulator'] is None or 'decayTime' not in g.settings[ 'mepp_simulator']: s = dict() s['traceLength'] = 10000 s['meppAmplitude'] = 5 s['meppDuration'] = 1 s['startTime'] = 0 s['meanExp'] = 1000.0 s['baseline'] = 0.0 s['noiseSigma'] = 0.1 s['riseTime'] = 1.0 #s['riseTime_sigma'] = 0.01 s['decayTime'] = 10.0 #s['decayTime_sigma'] = 0.1 g.settings['mepp_simulator'] = s super().__init__() self.data = np.array([]) def gui(self): s = g.settings['mepp_simulator'] self.gui_reset() self.meppWindow = PlotWindow('Single MEPP (No noise)') self.traceWindow = PlotWindow('Time Trace') self.meppWindow.hide() self.traceWindow.hide() self.traceLength = SliderLabel(0) self.traceLength.setRange(0, 1000000) self.traceLength.setValue(s['traceLength']) self.startTime = SliderLabel(0) self.startTime.setRange(0, s['traceLength']) self.startTime.setValue(s['startTime']) self.meppDuration_slider = pg.SpinBox(int=True, step=1) self.meppDuration_slider.setValue(s['meppDuration']) self.meppDuration_sigma_slider = pg.SpinBox(int=True, step=1) self.meppDuration_sigma_slider.setValue(1) self.baseline_slider = pg.SpinBox(int=False, step=.01) self.baseline_slider.setValue(s['baseline']) self.noiseSigma_slider = pg.SpinBox(int=False, step=.01) self.noiseSigma_slider.setValue(s['noiseSigma']) self.meppAmplitude_slider = pg.SpinBox(int=False, step=.01) self.meppAmplitude_slider.setValue(s['meppAmplitude']) self.meppAmplitude_sigma_slider = pg.SpinBox(int=False, step=.01) self.meppAmplitude_sigma_slider.setValue(1.0) self.meppRiseTime_slider = pg.SpinBox(int=False, step=.01) self.meppRiseTime_slider.setValue(s['riseTime']) #self.meppRiseTime_sigma_slider = pg.SpinBox(int=False, step=.01) #self.meppRiseTime_sigma_slider.setValue(0.01) self.meppDecayTime_slider = pg.SpinBox(int=False, step=.01) self.meppDecayTime_slider.setValue(s['decayTime']) #self.meppDecayTime_sigma_slider = pg.SpinBox(int=False, step=.01) #self.meppDecayTime_sigma_slider.setValue(0.1) self.randommeppsAdded = False self.meanExp_slider = pg.SpinBox(int=False, step=.01) self.meanExp_slider.setValue(1000.0) self.plotHistoTimes = CheckBox() self.plotHistoTimes.setValue(False) self.exportTimes_button = QPushButton('Export times') self.exportTimes_button.pressed.connect(self.exportTimes) self.randommeppButton = QPushButton('Generate Trace') self.randommeppButton.pressed.connect(self.addRandommepps) self.plotmeppButton = QPushButton('Plot single MEPP') self.plotmeppButton.pressed.connect(self.plotSingleMEPP) self.items.append({ 'name': 'traceLength', 'string': 'Recording length', 'object': self.traceLength }) self.items.append({ 'name': 'startTime', 'string': 'Start time', 'object': self.startTime }) self.items.append({ 'name': 'meppDuration', 'string': 'MEPP duration (mean)', 'object': self.meppDuration_slider }) self.items.append({ 'name': 'meppDuration_sigma', 'string': 'MEPP duration (standard deviation)', 'object': self.meppDuration_sigma_slider }) self.items.append({ 'name': 'riseTime', 'string': 'MEPP rise time constant', 'object': self.meppRiseTime_slider }) #self.items.append({'name': 'riseTime_sigma','string':'MEPP rise time constant (standard deviation)','object':self.meppRiseTime_sigma_slider}) self.items.append({ 'name': 'decayTime', 'string': 'MEPP decay time constant', 'object': self.meppDecayTime_slider }) #self.items.append({'name': 'decayTime_sigma','string':'MEPP decay time constant (standard deviation)','object':self.meppDecayTime_sigma_slider}) self.items.append({ 'name': 'meppAmplitude', 'string': 'MEPP Amplitude (mean)', 'object': self.meppAmplitude_slider }) self.items.append({ 'name': 'meppAmplitude_sigma', 'string': 'MEPP Amplitude (standard deviation)', 'object': self.meppAmplitude_sigma_slider }) self.items.append({ 'name': 'meanExp', 'string': 'Mean of exponential distibution', 'object': self.meanExp_slider }) self.items.append({ 'name': 'baseline', 'string': 'Baseline', 'object': self.baseline_slider }) self.items.append({ 'name': 'noiseSigma', 'string': 'Noise Sigma', 'object': self.noiseSigma_slider }) self.items.append({ 'name': 'histoTimes', 'string': 'Plot histogram of mepp start times:', 'object': self.plotHistoTimes }) self.items.append({ 'name': 'random_mepp_Button', 'string': 'Click to add randomly distibuted mepps', 'object': self.randommeppButton }) self.items.append({ 'name': 'listTimes', 'string': 'Export list of mepp start times', 'object': self.exportTimes_button }) self.items.append({ 'name': 'plotMEPP', 'string': 'Plot single MEPP (without noise)', 'object': self.plotmeppButton }) super().gui() def __call__(self, keepSourceWindow=False): g.settings['mepp_simulator']['traceLength'] = self.getValue( 'traceLength') g.settings['mepp_simulator']['meppAmplitude'] = self.getValue( 'meppAmplitude') g.settings['mepp_simulator']['meppDuration'] = self.getValue( 'meppDuration') g.settings['mepp_simulator']['startTime'] = self.getValue('startTime') g.settings['mepp_simulator']['meanExp'] = self.getValue('meanExp') g.settings['mepp_simulator']['baseline'] = self.getValue('baseline') g.settings['mepp_simulator']['noiseSigma'] = self.getValue( 'noiseSigma') g.settings['mepp_simulator']['riseTime'] = self.getValue('riseTime') g.settings['mepp_simulator']['decayTime'] = self.getValue('decayTime') return def addMEPP(self, time, amplitude, duration, dT=10, rT=1): #using Segal et al. Biophys J, 1985 MINIATURE ENDPLATE POTENTIAL FREQUENCY AND AMPLITUDE DETERMINED BY AN EXTENSION OF CAMPBELL'S THEOREM #dT = decay time #rT = rise time ampList = [] for t in range(0, duration): ampList.append(amplitude * (math.exp(-t / dT) - math.exp(-t / rT))) #square event test #self.data[time:time+duration] = self.data[time:time+duration] + amplitude #add MEPP to trace self.data[time:time + duration] = self.data[time:time + duration] + np.array(ampList) def plotSingleMEPP(self): amp = self.getValue('meppAmplitude') duration = self.getValue('meppDuration') dT = self.getValue('decayTime') rT = self.getValue('riseTime') self.plotMEPP(amp, duration, dT=dT, rT=rT) def plotMEPP(self, amplitude, duration, dT=10, rT=1): ampList = [] for t in range(0, duration): ampList.append(amplitude * (math.exp(-t / dT) - math.exp(-t / rT))) #plot matplot #plt.figure(3) #plt.plot(range(0,duration),ampList) #plt.show() #plot pg self.meppWindow.update(ampList, [0, len(ampList)], [0, self.getValue('meppAmplitude')]) self.meppWindow.show() def addRandommepps(self): self.data = np.array([]) #generate noisy time trace n = int(self.getValue('traceLength')) self.data = np.random.normal(self.getValue('baseline'), self.getValue('noiseSigma'), n) #add MEPPS to trace mean = self.getValue('meanExp') meppsAdded = 0 meppsOutsideOfRange = 0 self.timesAdded = [] amp = self.getValue('meppAmplitude') duration = self.getValue('meppDuration') dT = self.getValue('decayTime') rT = self.getValue('riseTime') # add first mepp try: time = int((np.random.exponential(scale=mean, size=1) + self.getValue('startTime'))) #draw random amplitude randAmp = int( np.random.normal(amp, self.getValue('meppAmplitude_sigma'), 1)) #draw random duration randDuration = int( np.random.normal(duration, self.getValue('meppDuration_sigma'), 1)) # add MEPP self.addMEPP(time, randAmp, randDuration, dT=dT, rT=rT) #record time self.timesAdded.append(time) meppsAdded += 1 except BaseException as e: #print(e) #meppsOutsideOfRange += 1 #print('{} MEPPs added, {} MEPPs out of time range'.format(meppsAdded,meppsOutsideOfRange)) #print('1st MEPP outside of time range, aborting') pass # add mepp after each time selection untill end of stack # casting the exponential continous value as an int to select frame while time < self.getValue('traceLength') - self.getValue( 'meppDuration'): try: time = int((time + np.random.exponential(scale=mean, size=1))) #draw random amplitude randAmp = int( np.random.normal(amp, self.getValue('meppAmplitude_sigma'), 1)) #draw random duration randDuration = int( np.random.normal(duration, self.getValue('meppDuration_sigma'), 1)) # add MEPP self.addMEPP(time, randAmp, randDuration, dT=dT, rT=rT) #record time self.timesAdded.append(time) meppsAdded += 1 except BaseException as e: #print(e) meppsOutsideOfRange += 1 #print number of MEPPS added to console #print('{} MEPPs added, {} MEPPs out of time range'.format(meppsAdded,meppsOutsideOfRange)) if self.plotHistoTimes.isChecked(): plt.figure(1) plt.hist(self.timesAdded) plt.xlabel('Time MEPP added') plt.ylabel('Number of MEPPs added') plt.show() self.randommeppsAdded = True #print data to console #print(self.data) #plot data matplotlib #plt.figure(0) #plt.plot(self.data) #plt.show() #plot data pg self.traceWindow.update(self.data, [0, len(self.data)], [ self.getValue('baseline') - (3 * self.getValue('noiseSigma')), self.getValue('meppAmplitude') + (3 * self.getValue('meppAmplitude_sigma')) ]) self.traceWindow.show() return def exportTimes(self): if self.randommeppsAdded == False: g.alert('Add MEPPs first') return #set export path savePath, _ = QFileDialog.getSaveFileName(None, "Save file", "", "Text Files (*.csv)") #write file try: # opening the csv file in 'w+' mode file = open(savePath, 'w+', newline='') # writing the data into the file with file: write = csv.writer(file) write.writerows(map(lambda x: [x], self.timesAdded)) print('List of times saved to: {}'.format(savePath)) except BaseException as e: print(e) print('Export of times failed, printing times to console') print(self.timesAdded)
class Simulate_Puff(BaseProcess_noPriorWindow): """ Add a simulated puff to an image stack """ def __init__(self): super().__init__() self.currentWin = None self.currentROI = None self.data = None def get_init_settings_dict(self): s = dict() s['nFrames'] = 100 s['puffAmplitude'] = 5 s['x'] = 128 s['y'] = 128 s['startFrame'] = 100 s['sigma'] = 20 s['useROI'] = False s['meanExp'] = 5.0 s['nPuffs'] = 0 s['nSites'] = 10 s['meanDuration'] = 10 return s def gui(self): self.gui_reset() self.nFrames = pg.SpinBox(int=False, step=.01) #self.nFrames.setRange(0,10000) self.startFrame = SliderLabel(0) self.startFrame.setRange(0, 10000) self.puffAmplitude = pg.SpinBox(int=False, step=.01) self.puffAmplitude.setValue(1.0) self.sigma = SliderLabel(0) self.sigma.setRange(1, 1000) self.x = SliderLabel(0) self.x.setRange(1, 10000) self.y = SliderLabel(0) self.y.setRange(1, 10000) self.useROI = CheckBox() self.useFrame = CheckBox() self.active_window = WindowSelector() self.previewButton = QPushButton('Preview Puff') self.previewButton.pressed.connect(self.previewPuff) self.puffButton = QPushButton('Add Puff') self.puffButton.pressed.connect(self.addPuff) self.randomPuffsAdded = False self.nSites = 10 columnNames = ['time of puff', 'duration', 'site'] self.timesAdded = pd.DataFrame(columns=columnNames) self.siteNumber = int(0) self.nPuffs_slider = SliderLabel(0) self.nPuffs_slider.setRange(1, 1000) self.meanExp_slider = pg.SpinBox(int=False, step=.01) self.meanExp_slider.setValue(5.0) self.randomDuration = CheckBox() self.randomDuration.setValue(False) self.durationMean = 10.0 self.durationMean_box = pg.SpinBox(int=False, step=.01) self.durationMean_box.setRange(0, 10000) self.durationMean_box.setValue(self.durationMean) self.plotHistoTimes = CheckBox() self.plotHistoTimes.setValue(False) self.addPuffsSequentially = CheckBox() self.addPuffsSequentially.setValue(False) self.exportTimes_button = QPushButton('Export times') self.exportTimes_button.pressed.connect(self.exportTimes) self.randomPuffButton = QPushButton('Add Puffs to site') self.randomPuffButton.pressed.connect(self.addRandomPuffs) self.multipleRandomPuffButton = QPushButton('Add Puffs inside ROI') self.multipleRandomPuffButton.pressed.connect( self.addMultipleRandomPuffs) self.nSites_box = QSpinBox() self.nSites_box.setRange(0, 10000) self.nSites_box.setValue(self.nSites) self.items.append({ 'name': 'active_window', 'string': 'Select Window', 'object': self.active_window }) self.items.append({ 'name': 'nFrames', 'string': 'Duration (frames)', 'object': self.nFrames }) self.items.append({ 'name': 'randomDuration', 'string': 'Use exponentially distributed random duration', 'object': self.randomDuration }) self.items.append({ 'name': 'meanDuration', 'string': 'Mean duration', 'object': self.durationMean_box }) self.items.append({ 'name': 'startFrame', 'string': 'Start Frame', 'object': self.startFrame }) #self.items.append({'name': 'useCurrentFrame', 'string': 'Use Current Frame For Start', 'object': self.useFrame}) self.items.append({ 'name': 'puffAmplitude', 'string': 'Amplitude', 'object': self.puffAmplitude }) self.items.append({'name': 'x', 'string': 'x', 'object': self.x}) self.items.append({'name': 'y', 'string': 'y', 'object': self.y}) #self.items.append({'name': 'useROI', 'string': 'Use ROI for position', 'object': self.useROI}) self.items.append({ 'name': 'sigma', 'string': 'sigma', 'object': self.sigma }) self.items.append({ 'name': 'preview_Button', 'string': 'Click to preview Puff', 'object': self.previewButton }) self.items.append({ 'name': 'puff_Button', 'string': 'Click to add Puff', 'object': self.puffButton }) self.items.append({ 'name': 'blank', 'string': '---------- RANDOM PUFFS ---------------------------', 'object': None }) #self.items.append({'name': 'nPuffs', 'string': 'Number of puffs to add', 'object': self.nPuffs_slider}) self.items.append({ 'name': 'meanExp', 'string': 'Mean of exponential distibution of puff start times', 'object': self.meanExp_slider }) self.items.append({ 'name': 'puffsSequential', 'string': 'Wait until puff ends before adding next puff:', 'object': self.addPuffsSequentially }) self.items.append({ 'name': 'histoTimes', 'string': 'Plot histogram of puff start times:', 'object': self.plotHistoTimes }) self.items.append({ 'name': 'random_puff_Button', 'string': 'Click to add randomly distibuted puffs at one site', 'object': self.randomPuffButton }) self.items.append({ 'name': 'multipleRandom_puff_Button', 'string': 'Click to add randomly distibuted puffs at multiple sites', 'object': self.multipleRandomPuffButton }) self.items.append({ 'name': 'nSites', 'string': 'Number of Sites to add', 'object': self.nSites_box }) self.items.append({ 'name': 'blank', 'string': '---------- Export Puffs ---------------------------', 'object': None }) self.items.append({ 'name': 'listTimes', 'string': 'Export list of puff start times', 'object': self.exportTimes_button }) super().gui() def __call__(self): pass return def update(self): self.currentWin = self.getValue('active_window') #get image data self.data = np.array(deepcopy(self.currentWin.image)) self.dt, self.dy, self.dx = self.data.shape self.x.setRange(1, self.dx - 1) self.y.setRange(1, self.dy - 1) self.x.setValue(int((self.dx - 1) / 2)) self.y.setValue(int((self.dy - 1) / 2)) self.nFrames.setRange(0, self.dt) self.startFrame.setRange(0, self.dt - 1) self.sigma.setRange(1, int(self.dx / 7)) def addPuff(self, time=False, singleSite=True, x=None, y=None, duration=False): '''add synthetic blip to image stack''' #select window self.currentWin = self.getValue('active_window') if self.currentWin == None: g.alert('First select window') return #generate blip sigma = self.getValue('sigma') amp = self.getValue('puffAmplitude') if self.randomDuration.isChecked(): #get random duration if duration == False: duration = float( np.random.exponential(scale=self.getValue('meanDuration'), size=1)[0]) else: duration = self.getValue('nFrames') #scale puff amplitude to account for durations <1 frame if duration < 1: amp = amp * duration duration = ceil(duration) else: #round duration to nearest integer number of frames duration = ceil(duration) blip = generateBlip(sigma=sigma, amplitude=amp, duration=duration) blip_time, blip_x_size, blip_y_size = blip.shape x_size = int(blip_x_size / 2) y_size = int(blip_y_size / 2) #add blip to stack if time == False: t = self.getValue('startFrame') else: t = time if singleSite: x = self.getValue('x') y = self.getValue('y') tt = np.arange(t, t + duration, dtype=np.int) xx = np.arange(x - x_size - 1, x + x_size, dtype=np.int) yy = np.arange(y - y_size - 1, y + y_size, dtype=np.int) if time == False: try: self.data[np.ix_(tt, xx, yy)] = self.data[np.ix_(tt, xx, yy)] + blip except: g.alert( 'Error - Puff might be too large, too long or too close to edge' ) else: self.data[np.ix_(tt, xx, yy)] = self.data[np.ix_(tt, xx, yy)] + blip frame = self.currentWin.currentIndex self.currentWin.imageview.setImage(self.data) self.currentWin.image = self.data self.currentWin.setIndex(frame) print( 'Puff added at time: {}, x: {}, y: {} with duration: {}, sigma: {}, amplitude:{}' .format(t, x, y, duration, sigma, amp)) return def addRandomPuffs(self, singleSite=True, x=None, y=None): if self.getValue('active_window') == None: g.alert('First select window') return mean = self.getValue('meanExp') #nPuffs = self.getValue('nPuffs') puffsAdded = 0 puffsOutsideOfRange = 0 # add first puff try: if self.randomDuration.isChecked(): startTime = int( np.random.exponential(scale=mean, size=1) + self.getValue('startFrame')) duration = float( np.random.exponential(scale=self.getValue('meanDuration'), size=1)[0]) self.addPuff(time=startTime, singleSite=singleSite, x=x, y=y, duration=duration) else: startTime = int( np.random.exponential(scale=mean, size=1) + self.getValue('startFrame')) duration = self.getValue('nFrames') self.addPuff(time=startTime, singleSite=singleSite, x=x, y=y) if self.getValue('puffsSequential'): endTime = startTime + duration else: endTime = startTime except Exception as e: print(e) puffsOutsideOfRange += 1 print('{} puffs added, {} puffs out of range'.format( puffsAdded, puffsOutsideOfRange)) print('1st puff outside of range, aborting') return # add puff after each time selection untill end of stack # rounding the exponential continous value to an int to select frame while startTime < self.dt - self.getValue('nFrames'): try: startTime = int(endTime + np.random.exponential(scale=mean, size=1)) #if random duration if self.randomDuration.isChecked(): #print('original time: ', startTime) duration = np.random.exponential( scale=self.getValue('meanDuration'), size=1) startTime = startTime + ceil(duration) #print('time: ', startTime) #print('duration: ', duration) #add puff at time self.addPuff(time=startTime, singleSite=singleSite, x=x, y=y, duration=duration) #if sequental, add puff duration to time if self.getValue('puffsSequential'): endTime = startTime + duration else: endTime = startTime #else use duration from GUI else: startTime = startTime + self.getValue('nFrames') duration = self.getValue('nFrames') #add puff at time self.addPuff(time=startTime, singleSite=singleSite, x=x, y=y) #if sequental, add puff duration to time if self.getValue('puffsSequential'): endTime = startTime + duration else: endTime = startTime #update puff time log self.timesAdded = self.timesAdded.append( { 'time of puff': startTime, 'duration': duration, 'site': int(self.siteNumber) }, ignore_index=True) puffsAdded += 1 except: puffsOutsideOfRange += 1 print('{} puffs added, {} puffs out of range'.format( puffsAdded, puffsOutsideOfRange)) if self.plotHistoTimes.isChecked(): plt.hist(self.timesAdded) plt.xlabel('Time puff added (frames)') plt.ylabel('Number of puffs added') plt.show() self.randomPuffsAdded = True if singleSite: self.siteNumber += 1 return def addMultipleRandomPuffs(self): nSites = self.getValue('nSites') if self.currentWin == None: g.alert('First select window') return #select current ROI self.currentROI = self.currentWin.currentROI if self.currentWin.currentROI == None: g.alert('First draw an ROI') return bounds = self.currentROI.parentBounds() topLeft_x = bounds.topLeft().x() topLeft_y = bounds.topLeft().y() bottomRight_x = bounds.bottomRight().x() bottomRight_y = bounds.bottomRight().y() print('adding puffs to {} sites from {},{} to {},{}'.format( nSites, topLeft_x, topLeft_y, bottomRight_x, bottomRight_y)) sites = self.getRandomSites(topLeft_x, bottomRight_x, topLeft_y, bottomRight_y, nSites) for site in sites: print("Puff site: ", self.siteNumber) self.addRandomPuffs(singleSite=False, x=site[0], y=site[1]) self.siteNumber += 1 print('Finished adding sites') return def getRandomSites(self, xStart, xEnd, yStart, yEnd, qty, radius=0): import random rangeX = (xStart, xEnd) rangeY = (yStart, yEnd) deltas = set() for x in range(-radius, radius + 1): for y in range(-radius, radius + 1): if x * x + y * y <= radius * radius: deltas.add((x, y)) randPoints = [] excluded = set() i = 0 while i < qty: x = random.randrange(*rangeX) y = random.randrange(*rangeY) if (x, y) in excluded: continue randPoints.append((x, y)) i += 1 excluded.update((x + dx, y + dy) for (dx, dy) in deltas) return randPoints def exportTimes(self): if self.getValue('active_window') == None: g.alert('First select window') return if self.randomPuffsAdded == False: g.alert('Add puffs first') return #set export path savePath, _ = QFileDialog.getSaveFileName(None, "Save file", "", "Text Files (*.csv)") #write file self.timesAdded.to_csv(savePath) print('List of times saved to: {}'.format(savePath)) # #write file # try: # # opening the csv file in 'w+' mode # file = open(savePath, 'w+', newline ='') # # writing the data into the file # with file: # write = csv.writer(file) # write.writerows(map(lambda x: [x], self.timesAdded)) # print('List of times saved to: {}'.format(savePath)) # except BaseException as e: # print(e) # print('Export of times failed, printing times to console') # print(self.timesAdded) def previewPuff(self): '''preview blip to be added''' sigma = self.getValue('sigma') amp = self.getValue('puffAmplitude') if self.randomDuration.isChecked(): #get random duration duration = np.random.exponential( scale=self.getValue('meanDuration'), size=1) #scale puff amplitude to account for durations <1 frame or spread across 2 frames spread = ceil(duration) if spread < 2: amp = amp * (duration / spread) #round duration to nearest integer number of frames duration = ceil(duration) else: duration = self.getValue('nFrames') blip = generateBlip(sigma=sigma, amplitude=amp, duration=duration) Window(blip) return def generateBlip(sigma=1, amplitude=1, duration=1): sigma = int(sigma) width = sigma * 8 + 1 xorigin = sigma * 4 yorigin = sigma * 4 x = np.arange(width) y = np.arange(width) x = x[:, None] y = y[None, :] gaussian = amplitude * (np.exp(-(x - xorigin)**2 / (2. * sigma**2)) * np.exp(-(y - yorigin)**2 / (2. * sigma**2))) blip = np.repeat(gaussian[None, :, :], repeats=duration, axis=0) return blip
def gui(self): self.gui_reset() nFrames=SliderLabel(0) nFrames.setRange(0,10000) self.items.append({'name':'nFrames','string':'Movie Duration (frames)','object':nFrames}) super().gui()
class Drift_Correction(BaseProcess): '''Draw rectangular ROIs around tracer locations to track movement over time. Locate the center coordinates and correct the image for drift ''' def __init__(self): super().__init__() findButton = QPushButton("Find Centers") findButton.pressed.connect(self.find_centers) self.slider = SliderLabel() self.slider.setRange(0, 10) self.slider.valueChanged.connect(self.plotCenters) self.items.append({ 'name': 'findButton', 'string': 'Locate centroids', 'object': findButton }) self.items.append({ 'name': 'smoothness', 'string': 'Drift Smoothness', 'object': self.slider }) # Enable antialiasing for prettier plots pg.setConfigOptions(antialias=True) self.scatter = pg.ScatterPlotItem() self.p1 = pg.PlotWidget(title="X Shift") self.p2 = pg.PlotWidget(title="Y Shift") def gui(self): super().gui() self.ui.layout.insertWidget(0, self.p1) self.ui.layout.insertWidget(1, self.p2) self.ui.resize(1000, 600) def plotCenters(self): self.p1.clear() self.p2.clear() for r in self.rois: centers = np.copy(r['centers']) #self.p1.plot(y=centers[:, 0] / np.average(centers[:, 0]), pen=r['roi'].pen) #self.p2.plot(y=centers[:, 1] / np.average(centers[:, 1]), pen=r['roi'].pen) self.p1.plot(y=gf(centers[:, 0], self.slider.value()), pen=r['roi'].pen) self.p2.plot(y=gf(centers[:, 1], self.slider.value()), pen=r['roi'].pen) def __call__(self, keepSourceWindow=False): xx, yy = [], [] for i in range(len(self.p1.plotItem.items)): xx.append(self.p1.plotItem.items[i].getData()[1]) yy.append(self.p2.plotItem.items[i].getData()[1]) diffs = np.mean([xx, yy], 1).T diffs = -1 * diffs + diffs[0] im = np.copy(g.m.currentWindow.image) for i, sh in enumerate(diffs): g.m.statusBar().showMessage("shifting frame %d of %d" % (i, len(diffs))) im[i] = shift(im[i], sh) QApplication.instance().processEvents() return Window(im) def find_centers(self): win = g.m.currentWindow im = win.image mx, my = win.imageDimensions() self.rois = [] g.centers = [] for roi in g.m.currentWindow.rois: mask = roi.mask mask = mask[(mask[:, 0] >= 0) * (mask[:, 0] < mx) * (mask[:, 1] >= 0) * (mask[:, 1] < my)] xx = mask[:, 0] yy = mask[:, 1] centers = [] for frame in im: gframe = gf(frame, 1) x0, y0 = np.unravel_index(gframe.argmax(), gframe.shape) #centers.append([x0, y0]) #vals = fitGaussian(frame, (x0, y0, 1, 3)) #x1, y1, a, b = vals[0] centers.append([x0, y0]) self.rois.append({'roi': roi, 'centers': centers}) self.plotCenters()
class Volume_Viewer(QWidget): closeSignal=Signal() def show_wo_focus(self): self.show() self.window.activateWindow() # for Windows self.window.raise_() # for MacOS def __init__(self,window=None,parent=None): super(Volume_Viewer,self).__init__(parent) ## Create window with ImageView widget g.m.volume_viewer=self window.lostFocusSignal.connect(self.hide) window.gainedFocusSignal.connect(self.show_wo_focus) self.window=window self.setWindowTitle('Light Sheet Volume View Controller') self.setWindowIcon(QIcon('images/favicon.png')) self.setGeometry(QRect(422, 35, 222, 86)) self.layout = QVBoxLayout() self.vol_shape=window.volume.shape mv,mz,mx,my=window.volume.shape self.currentAxisOrder=[0,1,2,3] self.current_v_Index=0 self.current_z_Index=0 self.current_x_Index=0 self.current_y_Index=0 self.formlayout=QFormLayout() self.formlayout.setLabelAlignment(Qt.AlignRight) self.xzy_position_label=QLabel('Z position') self.zSlider=SliderLabel(0) self.zSlider.setRange(0,mz-1) self.zSlider.label.valueChanged.connect(self.zSlider_updated) self.zSlider.slider.mouseReleaseEvent=self.zSlider_release_event self.sideViewOn=CheckBox() self.sideViewOn.setChecked(False) self.sideViewOn.stateChanged.connect(self.sideViewOnClicked) self.sideViewSide = QComboBox(self) self.sideViewSide.addItem("X") self.sideViewSide.addItem("Y") self.MaxProjButton = QPushButton('Max Intenstiy Projection') self.MaxProjButton.pressed.connect(self.make_maxintensity) self.exportVolButton = QPushButton('Export Volume') self.exportVolButton.pressed.connect(self.export_volume) self.formlayout.addRow(self.xzy_position_label,self.zSlider) self.formlayout.addRow('Side View On',self.sideViewOn) self.formlayout.addRow('Side View Side',self.sideViewSide) self.formlayout.addRow('', self.MaxProjButton) self.formlayout.addRow('', self.exportVolButton) self.layout.addWidget(self.zSlider) self.layout.addLayout(self.formlayout) self.setLayout(self.layout) self.setGeometry(QRect(381, 43, 416, 110)) self.show() def closeEvent(self, event): event.accept() # let the window close def zSlider_updated(self,z_val): self.current_v_Index=self.window.currentIndex vol=self.window.volume testimage=np.squeeze(vol[self.current_v_Index,z_val,:,:]) viewRect = self.window.imageview.view.targetRect() self.window.imageview.setImage(testimage,autoLevels=False) self.window.imageview.view.setRange(viewRect, padding = 0) self.window.image = testimage def zSlider_release_event(self,ev): vol=self.window.volume if self.currentAxisOrder[1]==1: # 'z' self.current_z_Index=self.zSlider.value() image=np.squeeze(vol[:,self.current_z_Index,:,:]) elif self.currentAxisOrder[1]==2: # 'x' self.current_x_Index=self.zSlider.value() image=np.squeeze(vol[:,self.current_x_Index,:,:]) elif self.currentAxisOrder[1]==3: # 'y' self.current_y_Index=self.zSlider.value() image=np.squeeze(vol[:,self.current_y_Index,:,:]) viewRect = self.window.imageview.view.viewRect() self.window.imageview.setImage(image,autoLevels=False) self.window.imageview.view.setRange(viewRect, padding=0) self.window.image = image self.window.imageview.setCurrentIndex(self.current_v_Index) self.window.activateWindow() # for Windows self.window.raise_() # for MacOS QSlider.mouseReleaseEvent(self.zSlider.slider, ev) def sideViewOnClicked(self, checked): self.current_v_Index=self.window.currentIndex vol=self.window.volume if checked==2: #checked=True assert self.currentAxisOrder==[0,1,2,3] side = self.sideViewSide.currentText() if side=='X': vol=vol.swapaxes(1,2) self.currentAxisOrder=[0,2,1,3] vol=vol.swapaxes(2,3) self.currentAxisOrder=[0,2,3,1] elif side=='Y': vol=vol.swapaxes(1,3) self.currentAxisOrder=[0,3,2,1] else: #checked=False if self.currentAxisOrder == [0,3,2,1]: vol=vol.swapaxes(1,3) self.currentAxisOrder=[0,1,2,3] elif self.currentAxisOrder == [0,2,3,1]: vol=vol.swapaxes(2,3) vol=vol.swapaxes(1,2) self.currentAxisOrder=[0,1,2,3] if self.currentAxisOrder[1]==1: # 'z' idx=self.current_z_Index self.xzy_position_label.setText('Z position') self.zSlider.setRange(0,self.vol_shape[1]-1) elif self.currentAxisOrder[1]==2: # 'x' idx=self.current_x_Index self.xzy_position_label.setText('X position') self.zSlider.setRange(0,self.vol_shape[2]-1) elif self.currentAxisOrder[1]==3: # 'y' idx=self.current_y_Index self.xzy_position_label.setText('Y position') self.zSlider.setRange(0,self.vol_shape[3]-1) image=np.squeeze(vol[:,idx,:,:]) self.window.imageview.setImage(image,autoLevels=False) self.window.volume=vol self.window.imageview.setCurrentIndex(self.current_v_Index) self.zSlider.setValue(idx) def make_maxintensity(self): vol=self.window.volume new_vol=np.max(vol,1) if self.currentAxisOrder[1]==1: # 'z' name='Max Z projection' elif self.currentAxisOrder[1]==2: # 'x' name = 'Max X projection' elif self.currentAxisOrder[1]==3: # 'y' name = 'Max Y projection' Window(new_vol, name=name) def export_volume(self): vol=self.window.volume export_path = QFileDialog.getExistingDirectory(g.m, "Select a parent folder to save into.", expanduser("~"), QFileDialog.ShowDirsOnly) export_path = os.path.join(export_path, 'light_sheet_vols') i=0 while os.path.isdir(export_path+str(i)): i+=1 export_path=export_path+str(i) os.mkdir(export_path) for v in np.arange(len(vol)): A=vol[v] filename=os.path.join(export_path,str(v)+'.tiff') if len(A.shape)==3: A=np.transpose(A,(0,2,1)) # This keeps the x and the y the same as in FIJI elif len(A.shape)==2: A=np.transpose(A,(1,0)) tifffile.imsave(filename, A)
class Drift_Correction(BaseProcess): '''Draw rectangular ROIs around tracer locations to track movement over time. Locate the center coordinates and correct the image for drift ''' def __init__(self): super().__init__() findButton = QPushButton("Find Centers") findButton.pressed.connect(self.find_centers) self.slider = SliderLabel() self.slider.setRange(0, 10) self.slider.valueChanged.connect(self.plotCenters) self.items.append({'name':'findButton','string':'Locate centroids','object':findButton}) self.items.append({'name':'smoothness', 'string': 'Drift Smoothness', 'object':self.slider}) # Enable antialiasing for prettier plots pg.setConfigOptions(antialias=True) self.scatter = pg.ScatterPlotItem() self.p1 = pg.PlotWidget(title="X Shift") self.p2 = pg.PlotWidget(title="Y Shift") def gui(self): super().gui() self.ui.layout.insertWidget(0, self.p1) self.ui.layout.insertWidget(1, self.p2) self.ui.resize(1000, 600) def plotCenters(self): self.p1.clear() self.p2.clear() for r in self.rois: centers = np.copy(r['centers']) #self.p1.plot(y=centers[:, 0] / np.average(centers[:, 0]), pen=r['roi'].pen) #self.p2.plot(y=centers[:, 1] / np.average(centers[:, 1]), pen=r['roi'].pen) self.p1.plot(y=gf(centers[:, 0], self.slider.value()), pen=r['roi'].pen) self.p2.plot(y=gf(centers[:, 1], self.slider.value()), pen=r['roi'].pen) def __call__(self, keepSourceWindow=False): xx, yy = [], [] for i in range(len(self.p1.plotItem.items)): xx.append(self.p1.plotItem.items[i].getData()[1]) yy.append(self.p2.plotItem.items[i].getData()[1]) diffs = np.mean([xx, yy], 1).T diffs = -1 * diffs + diffs[0] im = np.copy(g.m.currentWindow.image) for i, sh in enumerate(diffs): g.m.statusBar().showMessage("shifting frame %d of %d" % (i, len(diffs))) im[i] = shift(im[i], sh) QApplication.instance().processEvents() return Window(im) def find_centers(self): win = g.m.currentWindow im = win.image mx,my=win.imageDimensions() self.rois = [] g.centers = [] for roi in g.m.currentWindow.rois: mask = roi.mask mask=mask[(mask[:,0]>=0)*(mask[:,0]<mx)*(mask[:,1]>=0)*(mask[:,1]<my)] xx=mask[:,0]; yy=mask[:,1] centers = [] for frame in im: gframe = gf(frame, 1) x0, y0 = np.unravel_index(gframe.argmax(), gframe.shape) #centers.append([x0, y0]) #vals = fitGaussian(frame, (x0, y0, 1, 3)) #x1, y1, a, b = vals[0] centers.append([x0, y0]) self.rois.append({'roi': roi, 'centers': centers}) self.plotCenters()