1. Richard Gerkin
  2. Recording Artist

Commits

Richard Gerkin  committed cbd95bf

-- Fixed SelectedMethod(), thus fixing:
-- Non-persistence of checkboxes in Analysis Window.
-- Setting of "Minimum" for the wrong analysis method.
-- Cursors location not being saved separately for each analysis method.
-- "Scale" button now scales the axis to the range of values between the cursors.
-- Made more controls jump over when Sweeps Window is resized.
-- Made controls jump over sooner when Analysis Window is resized.
-- Selecting "Minimum" no longer tries to do something with a Notebook window when Notebook window does not exist.

  • Participants
  • Parent commits 843ab80
  • Branches default

Comments (0)

Files changed (7)

File Acquisition/Acquisition Wave Functions.ipf

View file
 
 Function /S SelectedMethod()
 	string result=""
-	dfref analysisWinDF=Core#PackageHome(module,"analysisWin")
+	dfref analysisWinDF=Core#InstanceHome(module,"analysisWin","win0")
 	if(datafolderrefstatus(analysisWinDF))
 		wave /z/sdfr=analysisWinDF selWave
 		wave /z/t/sdfr=analysisWinDF listWave

File Acquisition/Acquisition Windows.ipf

View file
 	if(!PopupInput(info.eventCode))
 		return 0
 	endif
-	dfref analysisWinDF=Core#PackageHome(module,"analysisWin")
+	dfref analysisWinDF=Core#InstanceHome(module,"analysisWin","win0")
 	variable i
 	strswitch(info.ctrlName)
 		case "Minimum":
 				Variable time_since_start=(currSweep>0) ? datetime - expStartT : 0
 				
 				text="After sweep "+num2str(currSweep)+" ("+Secs2MinsAndSecs(time_since_start)+"): \r"+text
-				Notebook LogPanel#ExperimentLog text=text
+				if(wintype("LogPanel#ExperimentLog"))
+					Notebook LogPanel#ExperimentLog text=text
+				endif
 			endif
 			KillWaves /Z OldMinimum
 			break
   	
   variable fsize=GetFontSize()
 	Display /N=$win /W=(coords.left,coords.top,coords.right,coords.bottom) /K=2 as "Sweeps"
-	Button SetBaselineRegion,pos={575,3},size={75,15},fsize=fsize+1, proc=SweepsWinButtons,title="Set Baseline"
-	Checkbox AutoBaseline,pos={655,3},title="Auto"
+	Button SetBaselineRegion,pos={575,3},size={75,23},fsize=fsize+1, proc=SweepsWinButtons,title="Set Baseline"
+	Checkbox AutoBaseline,pos={655,4},title="Auto"
 	string default_view=Core#StrPackageSetting(module,"random","","defaultView",default_="Broad")
-	Checkbox SwitchView, pos={700,3},size={100,29},proc=SweepsWinCheckboxes,title="Focus",userData=default_view
-	Button ResetSweepAxes,pos={575,20},size={75,15},fsize=fsize+1,proc=SweepsWinButtons,title="Restore Axes"
+	Checkbox SwitchView, pos={655,21},size={100,29},proc=SweepsWinCheckboxes,title="Focus",userData=default_view
+	Button ResetSweepAxes,pos={575,20},size={75,23},fsize=fsize+1,proc=SweepsWinButtons,title="Restore Axes"
 	PopupMenu SweepOverlay,pos={655,20},title="Sweep Overlay",mode=0,value=#("PopupOptions(\""+win+"\",\"SweepOverlay\",\"Stack;By Mode;Split\")"),userData(selected)="Split",proc=SweepsWinPopupMenus
 	PopupMenu PulseOverlay,pos={755,20},title="Pulse Overlay",mode=0,value=#("PopupOptions(\""+win+"\",\"PulseOverlay\",\"None;Stacked\")"),userData(selected)="None",proc=SweepsWinPopupMenus
 	//Button SaveWin, pos={725,3},size={75,15},proc=SweepsWinButtons,title="Save Window"
 	DoUpdate; GetWindow $win,wsizeDC
 	
 	//Button RemoveAllTraces pos={V_right-284,5}, size={100,29}, title="Remove Traces", proc=RemoveTracesWrap
-	Button WaveSelector,pos={V_right-303,5},size={100,29},fsize=fsize+2,proc=SweepsWinButtons,title="Selector"
-	Button Logger,pos={V_right-101,5},size={100,29},fsize=fsize+2,proc=SweepsWinButtons,title="Log"
+	Button WaveSelector,pos={V_right-303,5},size={100,22},fsize=fsize+2,proc=SweepsWinButtons,title="Selector"
+	Button Logger,pos={V_right-101,5},size={100,22},fsize=fsize+2,proc=SweepsWinButtons,title="Log"
 	//Textbox/N=Recording/F=0/X=7/Y=1 "\\Z08Waiting..."
 	//NVar testPulsestart=root:parameters:testPulsestart
 	//Variable stim_point_start,test_point_start
 				return -1
 			endif
 			GetWindow $info.winname,wsizeDC
-			Variable narrow = (V_right-V_left<1275)
-			ControlBar /W=$info.winname /L 105*narrow
+			variable narrow = (v_right-v_left<1100)
+			ControlBar /W=$info.winname /L 125*narrow
+			SetWindow $info.winname, userData(isNarrow)=num2str(narrow)
+			String controls="SetBaselineRegion;ResetSweepAxes;SwitchView;AutoBaseline;SweepOverlay;PulseOverlay;WaveSelector;Logger;"
+			if(!narrow)
+				controls = ReverseListOrder(controls)
+			endif
+			variable numControls=itemsinlist(controls)
 			variable numChannels=GetNumChannels()
-			String sweepsWinButtons="WaveSelector;Logger"
-			variable i
-			for(i=0;i<ItemsInList(sweepsWinButtons);i+=1)
-				String buttonName=StringFromList(i,sweepsWinButtons)
-				Variable ypos=max(3,numChannels)*18+5
-				Button $buttonName pos={narrow ? 2 : V_right-(2-i)*201,narrow ? ypos+i*35 : 5}, fsize=GetFontSize()+2, win=$info.winname
+			variable xx = narrow ? 2 : v_right
+			variable yy = narrow ? max(3,numChannels)*18 : 2
+			variable i,j
+			for(i=0;i<numControls;i+=1)
+				string controlName = stringfromlist(i,controls)
+				ControlInfo /W=$info.winname $controlName
+				if(v_disable != 1) // If visible.  
+					variable isPopup=(V_flag==3)
+					variable isCheckbox=(V_flag==2)
+					if(narrow)
+						yy += i==0 ? 10 : 30
+					else
+						if(mod(i,2)==0)
+							xx -= 120+isPopup*25-isCheckbox*25
+							yy = 2
+						else
+							yy = 26
+						endif
+					endif
+					ModifyControl /Z $controlName pos={xx,yy+isPopup*3+isCheckbox*4}, win=$info.winname
+				endif
 			endfor
 			break
 		case "modified":
 			endif
 			break
 		case "mousedown":
-			print info.mouseLoc
 			if(info.mouseLoc.v<0 && (info.eventMod & 16))
 				PopupContextualMenu Core#ListPackageInstances(module,info.winname)+"_Save_"
 				if(v_flag>=0)
 				for(j=0;j<itemsinlist(controlNames);j+=1)
 					string controlName = stringfromlist(j,controlNames)
 					ControlInfo /W=$info.winname $controlName
-					Variable isPopup=(V_flag==3)
-					xx -= 80+isPopup*25
-					ModifyControl /Z $controlName pos={narrow ? 2 : xx,narrow ? 30+i*25 : numControls-isPopup*3}, win=$info.winname
+					if(v_disable != 1) // If visible.  
+						variable isPopup=(V_flag==3)
+						xx -= 80+isPopup*25
+						ModifyControl /Z $controlName pos={narrow ? 2 : xx,narrow ? 30+i*25 : numControls-isPopup*3}, win=$info.winname
+					endif
 				endfor
 			endfor
 			break
 	KillVariables /Z red,green,blue
 End
 
-Function AnalysisWinButtons(ctrlName) : ButtonControl
-	String ctrlName
-	strswitch(ctrlName)
+Function AnalysisWinButtons(info) : ButtonControl
+	struct wmbuttonaction &info
+	
+	if(info.eventCode!=2)
+		return 0
+	endif
+	strswitch(info.ctrlName)
 		case "AnalysisSelect":
 			ControlInfo AnalysisSelector
 			AnalysisSelector(V_flag)
 				DoAlert 0,"No axis is active."
 				return -1
 			endif
-			SetAxis /W=AnalysisWin /A=2 $("axis_"+num2str(axisNum))
+			string csr_trace = CursorTrace("A",win=info.win)
+			string axis = TraceYAxis(csr_trace,win=info.win)
+			string target_axis = "axis_"+num2str(axisNum)
+			if(stringmatch(axis,target_axis))
+				wave w = TraceNameToWaveRef(info.win,csr_trace)
+				wavestats /q/r=(xcsr(A),xcsr(B)) w
+				variable range = v_max-v_min
+				SetAxis /W=$info.win $target_axis,v_min-range/5,v_max+range/5
+			else	
+				SetAxis /W=$info.win /A=2 $target_axis
+			endif
 			break
 		case "Recalculate":
 			Recalculate()

File Basics/Graphing.ipf

View file
 	endif
 End
 
-Function /S TraceYAxis(trace,[win])
-	String trace,win
-	if(ParamIsDefault(win))
-		win=WinName(0,1)
-	endif
-	String info=TraceInfo(win,trace,0)
-	return StringByKey("YAxis",info)
-End
-
 // Brings a trace to the front of the window.  Actually removes it and reappends it, with all of its features intact.  
 Function BringToFront(trace,[win])
 	String trace,win
 	SetAxis /W=$win $axis,hcsr(A),hcsr(B)
 End
 
+function /s CursorTrace(csr,[win])
+	string csr,win
+	
+	if(ParamIsDefault(win))
+		win=WinName(0,1)
+	endif
+	string info = csrinfo($csr)
+	string trace = stringbykey("TNAME",info)
+	return trace
+end
+
 Function /S TraceXAxis(trace,[win])
 	String trace,win
 	if(ParamIsDefault(win))
 	return StringByKey("XAXIS",info)
 End
 
+Function /S TraceYAxis(trace,[win])
+	String trace,win
+	if(ParamIsDefault(win))
+		win=WinName(0,1)
+	endif
+	String info=TraceInfo(win,trace,0)
+	return StringByKey("YAxis",info)
+End
+
 Function PlotLevels(data,levels)
 	Wave data,levels
 	Variable i
    "-"
    "Toggle axis info",/Q
    SubMenu "Single Axis"
-       "Expand�",/Q, ax_single("Expand")
-       "Shrink�",/Q, ax_single("Shrink")
-       "Center�",/Q, ax_single("Center")
-       "Undo�  ",/Q, ax_single("Undo")
+       "Expand",/Q, ax_single("Expand")
+       "Shrink",/Q, ax_single("Shrink")
+       "Center",/Q, ax_single("Center")
+       "Undo",/Q, ax_single("Undo")
    End
 End
 

File Basics/I-O.ipf

View file
 	HDF5SaveGroup /O /R /T root:, fileID, "."
 	HDF5CloseFile /Z fileID  
 #else
-	print "HDF5 XOP not loaded."  
+	printf "HDF5 XOP not loaded.\r"  
 #endif
 end

File Basics/Signal Processing.ipf

View file
 	//overlap = paramisdefault(overlap) ? 0 : overlap
 	trim = paramisdefault(trim) ? 25 : trim
 	width/=dimdelta(w,0)
+	width = round(width)
+	width -= mod(width,2) != 0 ? 1 : 0
 	//overlap*=width
 	variable i,numFFTs=floor(numpnts(w)/width)//1+floor((numpnts(w)-width)/(width-overlap))
 	variable start=0

File Other/More Analysis.ipf

View file
 		MeanChange[i]=after/before
 		duplicate /free/r=(before1,before2) theWave,beforeWave
 		duplicate /free/r=(before1,before2) theWave,afterWave
-		before=1/(CV(beforeWave))
-		after=1/(CV(afterWave))
+		before=1/(ComputeCV(beforeWave))
+		after=1/(ComputeCV(afterWave))
 		CVSquaredChange[i]=after/before
 		print wave_name+" STDP Ratio: "+num2str(MeanChange[i])+"; 1/CV^2 change: "+num2str(CVSquaredChange[i])
 	endfor
 	Wave /T Locs,Vals
 	for(i=0;i<numpnts(Vals);i+=1)
 		if(strlen(Locs[i])>65535 || strlen(Vals[i])>65535)
-			print "Too many characters: Sweep "+num2str(i+1)
-			print "Locs="+num2str(strlen(Locs[i]))
-			print "Vals="+num2str(strlen(Vals[i]))
-			print "\r"
+			printf "Too many characters: Sweep %d.\r",num2str(i+1)
+			printf "Locs=%f\r",num2str(strlen(Locs[i]))
+			printf "Vals=%f\r\r",num2str(strlen(Vals[i]))
 		endif
 	endfor
 End
 Function /S PeakFinderOld(first,last,smooth_val[,refractory])
 	Variable first,last,smooth_val
 	Variable refractory
-	//print first,last
 	SetDataFolder root:reanalysis:SweepSummaries
 	NVar VC=VC
 	Wave CursorWave=CsrWaveRef(A)
 		Wave levels=W_FindLevels
 		for(i=0;i<numpnts(levels)-1;i+=1)
 			if(mean(theWave,levels[i],levels[i+1]) > thresh)
-				//print levels[i],levels[i+1]
 				WaveStats /Q/R=(levels[i],levels[i+1]) theWave // Search for a maximum in between those crossings.  
 				//if(!V_flag) // If a peak was found
 					peak_locs+=num2str(V_maxloc)+";"
 		Smooth smooth_val, smoothed
 		Wave levels=W_FindLevels
 		//Display smoothed
-		//print levels
 		for(i=0;i<numpnts(levels);i+=1)			
 			if(smoothed(levels[i])<0) // If the second derivative is negative (concave up, since the wave was flipped, indicating a peak in voltage clamp)
 				//Display hpf
 				if(theWave(levels[i])>-vcsr(A)) // and if the peak is above the original cutoff (larger than the point indicated by Cursor A)
 					peak_locs+=num2str(levels[i])+";" // Add it to the list
 					peak_vals+=num2str(theWave(levels[i]))+";" // ...
-					if(i<4)
-						//print levels[i]
-						//print theWave(levels[i])
-					endif
 				endif
 			endif
 		endfor
 	endif
-	//print peak_locs
 	SpacePeaks(refractory)
 	Variable left,right
 	for(i=1;i<ItemsInList(peak_locs);i+=1)
 	Duplicate /o $("root:cell"+popStr[4,5]+":ampl_"+popStr[0,1]+"_"+popStr[4,5]) $("root:cell"+popStr[4,5]+":ampl")
 End
 
-//Function AnalysisProc(ctrlName) : ButtonControl // Route the button press to the appropriate function.  
-//	String ctrlName
-//	SVar whichCells=root:reanalysis:whichCells
-//	SVar sweepString=root:reanalysis:sweepString
-//	NVar offset=root:reanalysis:offset
-//	NVar whichPulse=root:reanalysis:whichPulse
-//	NVar method=root:reanalysis:method
-//	NVar firstInduction=root:reanalysis:firstInduction
-//	NVar lastInduction=root:reanalysis:lastInduction
-//	NVar lowerTiming=root:reanalysis:lowerTiming
-//	Nvar upperTiming=root:reanalysis:upperTiming
-//	Svar inductionOrder=root:reanalysis:inductionOrder
-//	
-//	strswitch(ctrlName)		
-//		case "Data2Access":
-//			print whichCells+";"+sweepString
-//			print offset
-//			Data2Access(whichCells+";"+sweepString,offset)
-//		break
-//		case "RedoAmps":
-//			RedoAmps(whichCells,whichPulse,method)
-//		break
-//		case "HistoryGraph":
-//			HistoryGraph("poop",method)
-//		break
-//		case "RemoveAll":
-//			RemoveGraphsAndTables()
-//		break
-//		case "TimeDif":
-//			TimeDif()
-//		break
-//		case "Access2Igor":
-//			Access2Igor()
-//		break
-//		case "SelectN":
-//			SelectN(firstInduction,lastInduction,lowerTiming,upperTiming,poop)
-//		break
-//		case "SelectOrder":
-//			SelectOrder(inductionOrder,firstInduction,lastInduction,inputOrig)
-//		break
-//		case "ImpulseFuncs":
-//			GetImpulseResponses(str2num(whichCells[1]),method,offset)
-//			break
-//		case "RsComp":
-//			RsCompensateAll(str2num(whichCells[1]),method)
-//			break
-//		case "Redo1Amp":
-//			Redo1Amp(str2num(whichCells[1]))
-//			break
-//		case "Rid":
-//			Rid(offset,whichCells)
-//			break
-//		default:
-//			Print "Default case executed [AnalysisProc()]"
-//	endswitch
-//End
-
 Function Redo1Amp(channel)
 	Variable channel
 	NVar sweep_num=root:reanalysis:wave_number
 			Duplicate /o $("root:cellL2:sweep"+num2str(sweep_num)+appendString), smoothed
 			Smooth 15, smoothed
 			Wavestats/Q/R=(cursorX1,cursorX2) smoothed
-			print V_min
 			amplL2 [(sweep_num-1)] = mean(smoothed,ampl_zero_L2,ampl_zero_L2+0.04)-V_min
 			break
 		default:
-			print "Not a valid channel"
+			printf "Not a valid channel.\r"
 			return 0
 	endswitch
 End
 	Variable cursorX2=hcsr(B)
 	Variable n
 	
-	print whichCell
-	
 	cellString="root:cell"+whichCell[4,5]+":sweep"
 	Wave/Z ampl = $("root:cell"+whichCell[4,5]+":ampl_"+whichCell[0,1]+"_"+whichCell[4,5])//; Wave/Z ampl = $("root:cell"+whichCell[4,5]+":ampl") 
 	Wave/Z ampl2 = $("root:cell"+whichCell[4,5]+":ampl2"+whichCell[0,1]+"_"+whichCell[4,5])//; Wave/Z ampl = $("root:cell"+whichCell[4,5]+":ampl2") 
 			appendString="D"
 			break
 		case 4:
-			//print "poop"
 			if(!waveExists(root:impact) || !waveExists(root:fitCoefs))
-				Print "Run ImpactRs() first"
+				printf "Run ImpactRs() first.\r"
 				return 0
 			endif
 			appendString=""
 			for(n=1;n<=numpnts(ampl);n+=1)
 				timeConstants[n]=round(10000*timeConstants[n])
 				ampl[n-1]/=impact[timeConstants[n]]
-				print impact[timeConstants[n]]
 			endfor
 			return 0
 			break
 		default:
-			print "Not a valid adjustment value"
+			printf "Not a valid adjustment value.\r"
 			return 0
 	endswitch
 	
 				Redimension/n=(total_sweeps) ampl
 				waveN=cellString+num2str(n)+appendString
 				if(waveExists($waveN) )//&& series_res[n-1]!=0)
-					print n
 					//Duplicate /o $(cellString+num2str(n)+appendString), smoothed
 					//Smooth 25, smoothed
 					Wavestats/Q/R=(cursorX1,cursorX2) $waveN
 				endif
 			endfor
 		default:
-			print "Not a valid pulse number"
+			printf "Not a valid pulse number.\r"
 			return 0
 	endswitch
 End
 			sscanf actual_name, "sweep%d", sweep_num
 		endif
 		Variable stim_start=EarliestStim(sweep_num,channel_label=pre)
-		//print channel,sweep_num,stim_start
 		ModifyGraph /W=$win_name offset($trace_name)={-stim_start,-baseline+(is_post*post_mean*(1-post_vertical_align))}
 	endfor
 	
 	DoWindow/K AvgLayout
 	
 	if(!exists("root:cursA"))
-		print "Store cursor values with StoreCurs() first."
+		printf "Store cursor values with StoreCurs() first.\r"
 		return 0
 	endif
 	
 	Variable baselinestart,baselineend
 	NVar cursA=root:cursA
 	NVar cursB=root:cursB
-	print "ROI is "+num2str(cursA)+" to "+num2str(cursB)+" or "+num2str((cursB-cursA)/(1/60))+" wavelengths of 60 Hz"
-	print "Baseline is "+num2str(baselinestart)+" to "+num2str(baselineend)+" or "+num2str((baselineend-baselinestart)/(1/60))+" wavelengths of 60 Hz"
-	print "From Baseline start to ROI start is "+num2str((cursA-baselinestart)/(1/60))+" wavelengths of 60 Hz"
+	printf "ROI is %3f to %.3f or %.2f wavelengths of 60 Hz\r",num2str(cursA),num2str(cursB),num2str((cursB-cursA)/(1/60))
+	printf "Baseline is %.3f to %.3f or %.2f wavelengths of 60 Hz\r",num2str(baselinestart),num2str(baselineend),num2str((baselineend-baselinestart)/(1/60))
+	printf "From Baseline start to ROI start is %.2f wavelengths of 60 Hz",num2str((cursA-baselinestart)/(1/60))
 	SetDataFolder root:reanalysis:avgwaves
 	String waves=DataFolderDir(2) // Get a list of the waves in that directory
 	waves=StringFromList(0,RemoveListItem(0,waves,":")); // Clean up the list (remove the word WAVES and : and ;
 //		DoWindow /F $win
 //		if(numpnts(MeanWave)>5)
 //			FuncFit /Q IntegratedPowerLaw W_coef  MeanWave[1,] /D 
-//			print win,cutoff,W_Coef[0]
 //			Exponents[i][log(cutoff/100000)/log(2)]=W_Coef[0]
 //		endif
 //	endfor
 			cellFolder="root:cellL2:"
 			break
 		default:
-			Print "Not a valid channel choice!"
+			printf "Not a valid channel choice!\r"
 	endswitch
 	
 	Variable V_fitOptions=4
 					smoothed-=V_avg // Make the impulse response function decay to zero
 					smoothed=NormalizeToUnity(smoothed)
 					Duplicate /o smoothed $(cellFolder+"impulse"+num2str(n))
-					print n
 					break
 				case 1:
 					DeletePoints 0,x2pnt(WaveToFitA,0.035),waveToFitA
 					fitCoefs[n][2]=1/K2
 					fitCoefs[n][3]=K3
 					fitCoefs[n][4]=1/K4
-					print n
 					break
 				endswitch
 		endif
 			cellFolder="root:cellL2:"
 			break
 		default:
-			Print "Not a valid channel choice!"
+			printf "Not a valid channel choice!\r"
 	endswitch
 	
 	Variable n=1
 					RsCompensateTau(waveToCompensate,fitcoefs[n][2],n)
 					break
 				default:
-					print "Not a valid method! (RsCompensateAll)"
+					printf "Not a valid method! (RsCompensateAll)\r"
 					return 0
 			endswitch
 			Duplicate/o deconvoluted $(cellFolder+"sweep"+num2str(n)+"A")
-		print n
 		endif
 		n+=1
 	While(waveexists($(cellFolder+"sweep"+num2str(n))))
 	Wave /T Baseline_Sweeps,Post_Activity_Sweeps
 	Variable first_sweep=str2num(StringFromList(1,Baseline_Sweeps[0],","))
 	Variable last_sweep=str2num(StringFromList(0,Post_Activity_Sweeps[0],","))
-	print first_sweep,last_sweep
 	if(!numtype(first_sweep) && !numtype(last_sweep)) // If these values are both numbers.  
 		Variable j,sweep
 		for(j=0;j<ItemsInList(two_channels);j+=1)

File Other/Olfaction.ipf

View file
 			j+=1
 		endif
 	endfor
+end
+
+function RosePlot(tuningMatrix[,rates,no_plot])
+	wave tuningMatrix // Assumes this scaled to have phase (the unit circle) respresented in X.  
+	wave rates // Wave of corresponding average spike rates for color-coding.  
+	variable no_plot
+	
+	dfref df = getwavesdatafolderdfr(tuningMatrix)
+	variable n_phaseBins = dimsize(tuningMatrix,0)
+	variable n_cells = dimsize(tuningMatrix,1)
+	make /o/n=(n_phaseBins+1,n_cells) df:rosePlot_X /wave=XX,df:rosePlot_Y /wave=YY
+	copyscales /p tuningMatrix,XX,YY
+	if(!no_plot)
+		display as "Rose Plot"
+	endif
+	if(!paramisdefault(rates))
+		duplicate /free rates log_rates
+		log_rates = log(rates)+log(2)
+		wavestats /q/m=1 log_rates
+		variable min_rate = -2//v_min
+		variable max_rate = 2//v_max
+		colortab2wave yellowhot
+		make /o/n=5 df:tick_values /wave=tick_values = p-2
+		make /o/t/n=5 df:tick_labels /wave=tick_labels = num2str(10^(tick_values[p]))
+		wave m_colors
+		setscale x,min_rate,max_rate,m_colors
+	endif
+	variable cell
+	for(cell=0;cell<=n_cells;cell+=1)
+		XX[][cell] = tuningMatrix[mod(p,n_phaseBins)][cell]*cos(x)
+		YY[][cell] = tuningMatrix[mod(p,n_phaseBins)][cell]*sin(x)
+		if(!no_plot)
+			if(!paramisdefault(rates))
+				variable rate = log_rates[cell]
+				variable red = m_colors(rate)[0]
+				variable green = m_colors(rate)[1]
+				variable blue = m_colors(rate)[2]
+			endif
+			if(log_rates[cell]>-1.5)
+				appendtograph /c=(red,green,blue) YY[][cell] vs XX[][cell]
+			endif
+		endif
+	endfor
+	if(!no_plot)
+		ModifyGraph mode=0,marker=8,zero=4,noLabel=2,axThick=0,zeroThick=5
+		ColorScale /F=0 side=2, ctab={min_rate,max_rate,yellowhot,0} "Mean Firing Rate (Hz)"
+		ColorScale/C/N=text0 userTicks={tick_values,tick_labels}
+		SetDrawEnv fname="Symbol",fsize=18,save
+		SetDrawEnv xcoord=bottom
+		DrawText 0,0,"p/2"
+		SetDrawEnv xcoord=bottom
+		DrawText 0,1,"-p/2"
+		SetDrawEnv ycoord=left
+		DrawText 1,0,"0"
+		SetDrawEnv ycoord=left
+		DrawText 0,0,"+/- p"
+	endif
 end