8
8
from pyqtgraph import GraphicsScene
9
9
from scipy .stats import zscore
10
10
from matplotlib import cm
11
- from rastermap .roi import gROI
11
+ from rastermap .roi import gROI , dbROI
12
12
import rastermap .run
13
13
from rastermap import Rastermap
14
+ from sklearn .cluster import DBSCAN
14
15
15
16
def triangle_area (p ):
16
17
area = 0.5 * np .abs (p [0 ,0 ] * p [1 ,1 ] - p [0 ,0 ] * p [2 ,1 ] +
@@ -180,7 +181,7 @@ def __init__(self):
180
181
self .p1 = self .win .addPlot (row = 1 , col = 2 , colspan = 3 ,
181
182
rowspan = 3 , invertY = True , padding = 0 )
182
183
self .p1 .setMouseEnabled (x = False , y = False )
183
- self .img = pg .ImageItem (autoDownsample = False )
184
+ self .img = pg .ImageItem (autoDownsample = True )
184
185
self .p1 .hideAxis ('left' )
185
186
self .p1 .setMenuEnabled (False )
186
187
self .p1 .scene ().contextMenuItem = self .p1
@@ -231,16 +232,31 @@ def __init__(self):
231
232
self .makegrid .clicked .connect (self .make_grid )
232
233
self .makegrid .setStyleSheet (self .styleInactive )
233
234
self .makegrid .setEnabled (False )
234
- self .makegrid .setFixedWidth (100 )
235
+ self .makegrid .setFixedWidth (200 )
235
236
self .l0 .addWidget (self .makegrid , rs + 7 , 0 , 1 , 1 )
236
237
self .gridsize = QtGui .QLineEdit (self )
237
- self .gridsize .setValidator (QtGui .QIntValidator (0 , 500 ))
238
- self .gridsize .setText ("10 " )
238
+ self .gridsize .setValidator (QtGui .QIntValidator (2 , 20 ))
239
+ self .gridsize .setText ("5 " )
239
240
self .gridsize .setFixedWidth (45 )
240
241
self .gridsize .setAlignment (QtCore .Qt .AlignRight )
241
242
self .gridsize .returnPressed .connect (self .make_grid )
242
243
self .l0 .addWidget (self .gridsize , rs + 7 , 1 , 1 , 1 )
243
244
245
+ self .dbbutton = QtGui .QPushButton ("DBSCAN clusters, ms=" )
246
+ self .dbbutton .setFont (QtGui .QFont ("Arial" , 8 , QtGui .QFont .Bold ))
247
+ self .dbbutton .clicked .connect (self .dbscan )
248
+ self .dbbutton .setStyleSheet (self .styleInactive )
249
+ self .dbbutton .setEnabled (False )
250
+ self .dbbutton .setFixedWidth (200 )
251
+ self .l0 .addWidget (self .dbbutton , rs + 8 , 0 , 1 , 1 )
252
+ self .min_samples = QtGui .QLineEdit (self )
253
+ self .min_samples .setValidator (QtGui .QIntValidator (5 , 200 ))
254
+ self .min_samples .setText ("50" )
255
+ self .min_samples .setFixedWidth (45 )
256
+ self .min_samples .setAlignment (QtCore .Qt .AlignRight )
257
+ self .min_samples .returnPressed .connect (self .dbscan )
258
+ self .l0 .addWidget (self .min_samples , rs + 8 , 1 , 1 , 1 )
259
+
244
260
ysm = QtGui .QLabel ("<font color='white'>y-binning</font>" )
245
261
ysm .setFixedWidth (100 )
246
262
self .l0 .addWidget (ysm , rs + 6 , 0 , 1 , 1 )
@@ -295,11 +311,13 @@ def __init__(self):
295
311
# self.load_behavior('C:/Users/carse/github/TX4/beh.npy')
296
312
self .file_iscell = None
297
313
#self.fname = '/media/carsen/DATA2/grive/rastermap/DATA/embedding.npy'
298
- #self.load_proc(self.fname)
314
+ self .fname = 'D:/grive/cshl_suite2p/TX39/embedding.npy'
315
+ self .load_proc (self .fname )
299
316
300
317
self .show ()
301
318
self .win .show ()
302
319
320
+
303
321
def add_imgROI (self ):
304
322
if hasattr (self , 'imgROI' ):
305
323
self .pfull .removeItem (self .imgROI )
@@ -343,23 +361,24 @@ def smooth_activity(self):
343
361
self .sp_smoothed /= 12
344
362
345
363
def plot_activity (self ):
346
- self .smooth_activity ()
347
- nn = self .sp_smoothed .shape [0 ]
348
- nt = self .sp_smoothed .shape [1 ]
349
- self .imgfull .setImage (self .sp_smoothed )
350
- self .imgfull .setLevels ([self .sat [0 ],self .sat [1 ]])
351
- self .img .setImage (self .sp_smoothed )
352
- self .img .setLevels ([self .sat [0 ],self .sat [1 ]])
353
- self .p1 .setXRange (0 , nt , padding = 0 )
354
- self .p1 .setYRange (0 , nn , padding = 0 )
355
- self .p1 .setLimits (xMin = 0 ,xMax = nt ,yMin = 0 ,yMax = nn )
356
- self .pfull .setXRange (0 , nt , padding = 0 )
357
- self .pfull .setYRange (0 , nn , padding = 0 )
358
- self .pfull .setLimits (xMin = - 1 ,xMax = nt + 1 ,yMin = - 1 ,yMax = nn + 1 )
359
- self .imgROI .setPos (- .5 ,- .5 )
360
- self .imgROI .setSize ([nt + .5 ,nn + .5 ])
361
- self .imgROI .maxBounds = QtCore .QRectF (- 1. ,- 1. ,nt + 1 ,nn + 1 )
362
- if 0 :
364
+ if self .embedded :
365
+ self .smooth_activity ()
366
+ nn = self .sp_smoothed .shape [0 ]
367
+ nt = self .sp_smoothed .shape [1 ]
368
+ self .imgfull .setImage (self .sp_smoothed )
369
+ self .imgfull .setLevels ([self .sat [0 ],self .sat [1 ]])
370
+ self .img .setImage (self .sp_smoothed )
371
+ self .img .setLevels ([self .sat [0 ],self .sat [1 ]])
372
+ self .p1 .setXRange (0 , nt , padding = 0 )
373
+ self .p1 .setYRange (0 , nn , padding = 0 )
374
+ self .p1 .setLimits (xMin = 0 ,xMax = nt ,yMin = 0 ,yMax = nn )
375
+ self .pfull .setXRange (0 , nt , padding = 0 )
376
+ self .pfull .setYRange (0 , nn , padding = 0 )
377
+ self .pfull .setLimits (xMin = - 1 ,xMax = nt + 1 ,yMin = - 1 ,yMax = nn + 1 )
378
+ self .imgROI .setPos (- .5 ,- .5 )
379
+ self .imgROI .setSize ([nt + .5 ,nn + .5 ])
380
+ self .imgROI .maxBounds = QtCore .QRectF (- 1. ,- 1. ,nt + 1 ,nn + 1 )
381
+ else :
363
382
nn = self .sp .shape [0 ]
364
383
nt = self .sp .shape [1 ]
365
384
self .imgfull .setImage (self .sp )
@@ -382,8 +401,10 @@ def plot_activity(self):
382
401
def plot_colorbar (self ):
383
402
nneur = self .colormat_plot .shape [0 ]
384
403
self .colorimg .setImage (self .colormat_plot )
385
- N = int (self .smooth .text ())
386
- NN = self .sp_smoothed .shape [0 ]* N
404
+ if self .embedded :
405
+ N = int (self .smooth .text ())
406
+ else :
407
+ N = 1
387
408
self .p3 .setYRange (self .yrange [0 ]* N , self .yrange [- 1 ]* N )
388
409
self .p3 .setXRange (0 ,10 )
389
410
self .p3 .setLimits (yMin = self .yrange [0 ]* N ,yMax = self .yrange [- 1 ]* N ,xMin = 0 ,xMax = 10 )
@@ -415,17 +436,17 @@ def imgROI_range(self):
415
436
yrange = (np .arange (0 ,int (sizey )) + np .floor (posy )).astype (np .int32 )
416
437
xrange = xrange [xrange >= 0 ]
417
438
yrange = yrange [yrange >= 0 ]
418
- # if self.embedded:
419
- xrange = xrange [xrange < self .sp_smoothed .shape [1 ]]
420
- yrange = yrange [yrange < self .sp_smoothed .shape [0 ]]
421
- # else:
422
- # xrange = xrange[xrange<self.sp.shape[1]]
423
- # yrange = yrange[yrange<self.sp.shape[0]]
439
+ if self .embedded :
440
+ xrange = xrange [xrange < self .sp_smoothed .shape [1 ]]
441
+ yrange = yrange [yrange < self .sp_smoothed .shape [0 ]]
442
+ else :
443
+ xrange = xrange [xrange < self .sp .shape [1 ]]
444
+ yrange = yrange [yrange < self .sp .shape [0 ]]
424
445
return xrange ,yrange
425
446
426
447
def imgROI_position (self ):
427
448
xrange ,yrange = self .imgROI_range ()
428
- if 1 :
449
+ if self . embedded :
429
450
self .img .setImage (self .sp_smoothed [np .ix_ (yrange ,xrange )])
430
451
else :
431
452
self .img .setImage (self .sp [np .ix_ (yrange ,xrange )])
@@ -437,7 +458,10 @@ def imgROI_position(self):
437
458
axy = self .p3 .getAxis ('left' )
438
459
axx = self .p1 .getAxis ('bottom' )
439
460
self .plot_colorbar ()
440
- N = int (self .smooth .text ())
461
+ if self .embedded :
462
+ N = int (self .smooth .text ())
463
+ else :
464
+ N = 1
441
465
axy .setTicks ([[(0 ,str (self .yrange [0 ])),(self .yrange [- 1 ]* N ,str (self .yrange [- 1 ]* N ))]])
442
466
axx .setTicks ([[(0.0 ,str (xrange [0 ])),(float (xrange .size ),str (xrange [- 1 ]))]])
443
467
@@ -481,7 +505,9 @@ def ROI_selection(self, loaded=False):
481
505
482
506
self .colormat_plot = self .colormat .copy ()
483
507
self .plot_activity ()
508
+ print ('plotted activity' )
484
509
self .plot_colorbar ()
510
+ print ('plotted colorbar' )
485
511
self .win .show ()
486
512
487
513
def update_selected (self , ineur ):
@@ -501,19 +527,52 @@ def update_selected(self, ineur):
501
527
ineur = self .selected [ineur ]
502
528
self .xp .setData (pos = self .embedding [ineur ,:][np .newaxis ,:])
503
529
530
+ def dbscan (self ):
531
+ ms = int (self .min_samples .text ())
532
+ # remove previous ROIs
533
+ if len (self .ROIs ) > 0 :
534
+ for n in range (len (self .ROIs )):
535
+ self .ROI_delete ()
536
+
537
+ db = DBSCAN (eps = 0.8 , min_samples = ms ).fit (self .embedding )
538
+ ilabels = np .unique (db .labels_ )
539
+ ilabels = ilabels [ilabels >= 0 ]
540
+ print (ilabels )
541
+ #ilabels = ilabels[:1]
542
+ for i in ilabels :
543
+ self .dbROI_add ((db .labels_ == i ).nonzero ()[0 ])
544
+ self .ROI_selection ()
545
+
504
546
def make_grid (self ):
505
547
ng = int (self .gridsize .text ())
506
548
if len (self .ROIs ) > 0 :
507
549
for n in range (len (self .ROIs )):
508
550
self .ROI_delete ()
509
- sz = self .embedding .max () / ng
510
- print (sz )
511
- corners = np .array ([j * sz for j in range (0 ,ng )])
512
- print (corners )
513
- #for j in range(ng):
514
- # for k in range(ng):
515
- # prect = np.array([[corners[j],corners[k]],
516
- # [corners[j],corners[k]],
551
+ sz = (self .embedding .max () - self .embedding .min ()) / ng
552
+ corners = np .linspace (self .embedding .min (), self .embedding .max (), ng + 1 )
553
+ jet = cm .get_cmap ('jet' )
554
+ jet = jet (np .linspace (0 ,1 ,ng ** 2 ))
555
+ jet = jet [:,:3 ]
556
+ for j in range (ng ):
557
+ for k in range (ng ):
558
+ prect = [np .array ([[corners [j ],corners [k ]],
559
+ [corners [j + 1 ],corners [k ]],
560
+ [corners [j + 1 ],corners [k + 1 ]],
561
+ [corners [j ],corners [k + 1 ]],
562
+ [corners [j ],corners [k ]]])]
563
+ pos = [np .array ([[corners [j + 1 ],corners [k ]+ sz / 2 ],
564
+ [corners [j ],corners [k ]+ sz / 2 ]])]
565
+ self .ROI_add (pos , prect , color = jet [j + k * ng ]* 255.0 )
566
+ self .ROI_selection ()
567
+
568
+ def dbROI_add (self , selected , color = None ):
569
+ if color is None :
570
+ color = np .random .randint (255 ,size = (3 ,))
571
+ self .ROIs .append (dbROI (selected , color , self ))
572
+ self .Rselected .append (self .ROIs [- 1 ].selected )
573
+ self .Rcolors .append (np .reshape (np .tile (self .ROIs [- 1 ].color , 10 * self .Rselected [- 1 ].size ),
574
+ (self .Rselected [- 1 ].size , 10 , 3 )))
575
+ self .ROIorder .append (len (self .ROIs )- 1 )
517
576
518
577
def ROI_add (self , pos , prect , color = None ):
519
578
if color is None :
@@ -570,9 +629,12 @@ def enable_embedded(self):
570
629
self .updateROI .setEnabled (True )
571
630
self .saveROI .setEnabled (True )
572
631
self .makegrid .setEnabled (True )
632
+ self .dbbutton .setEnabled (True )
633
+
573
634
self .updateROI .setStyleSheet (self .styleUnpressed )
574
635
self .saveROI .setStyleSheet (self .styleUnpressed )
575
636
self .makegrid .setStyleSheet (self .styleUnpressed )
637
+ self .dbbutton .setStyleSheet (self .styleUnpressed )
576
638
577
639
def disable_embedded (self ):
578
640
self .updateROI .setEnabled (False )
@@ -633,8 +695,6 @@ def mouse_moved_bar(self, pos):
633
695
ineur = min (self .colormat .shape [0 ]- 1 , max (0 , int (np .floor (y ))))
634
696
self .update_selected (ineur )
635
697
636
-
637
-
638
698
def plot_clicked (self , event ):
639
699
"""left-click chooses a cell, right-click flips cell to other view"""
640
700
flip = False
@@ -778,6 +838,7 @@ def load_mat(self, name=None):
778
838
self .ROI_selection ()
779
839
self .enable_loaded ()
780
840
self .show ()
841
+ print ('done loading' )
781
842
self .loaded = True
782
843
783
844
def load_iscell (self ):
0 commit comments