var fh%; var inputCh% := 8; 'Channel to analyse... var eventCh1% := -1; var eventCh2% := -1; var p; var eventChDis% := -1; var eventCh3% := -1; var eventCh4% := -1; var eventCh5% := -1; var discrim% := -1; var BurstCh1% := -1; var BurstCh2% :=-1; var setCutOff1; var setCutOff2; var setMinBurstSep := 0.5; var setMinDomFreq% := 4000; var sTime; var eTime; var results[4]; const resDuration1% := 0; const resSpikes1% := 1; const resSpikeFreq1% := 2; const resDuration2% := 0; const resSpikes2% := 1; const resSpikeFreq2% := 2; var numburst; var startBurst2[1000]; var endBurst2[1000]; var startBurst1[1000]; var endBurst1[1000]; var phaseon[300]; var phaseoff[300]; var burstnum; var ok%; var ret%; var again%; var another%; ToolbarVisible(1); 'Must be open data-file... fh% := View(); 'holt die Viewnummer, nur groesser Null ist valid if fh% <= 0 then Halt(); endif; if ViewKind() <> 0 then ' der viewkind Null bedeutet eine Timeview (Datenfile halt) Message("Current view must be a data-file..."); Halt(); endif; repeat FrontView(fh%); 'Get channel to analyse... View(fh%); DlgCreate("Select a channel to analyse..."); 'startet Layout des Dialogfelds (popup) DlgChan(1, "Channel:",17); 'definiert erlaubte Kanaele (muss man immer nachschauen, was z.B. 17 heisst ok% := DlgShow(inputCh%); 'gibt eine 1 wenn NICHT cancel gedrueckt wurde und weisst inputCH den Kanal zu if not ok% then Halt(); endif; 'falls cancel gedrueckt wurde -> haelt script an 'Just show input channel... ChanHide(-1); 'versteckt alle Kanaele ChanShow(inputCh%); 'oeffnet nur den einen Kanal Interact("Place the cursors around the region to be analysed...", 1023); 'die 1023 erlaubt dem User alles am Fenster zu verstellen CursorRenumber(); 'renumbered cursor -> linker cursor wird cursor 1 sTime := Cursor(1); eTime := Cursor(2); XRange(sTime - (eTime - sTime)/5, eTime + (eTime - sTime)/5); 'setzt die X-Achse fest, die spaeter dargestellt werden soll GetLevel(); 'springt zu Getlevel Abschnitt GetBurstSettings(); 'springt zu GetBurstSettings Abschnitt 'Get burst sequences with different settings until OK... repeat again% := 0; 'setzt again auf Null CalculateBursts(); 'springt zu Calculate burst ret% := Interact("Change the analysis parameters or continue...", 1023, 0, "OK", "Change"); 'zeigt Statuszeile oben, man kann alles aendern im Datenfile, aber dann nur OK oder Change druecken, wenn change gedrueckt wird, returned eine 2 (2. Button) ResetCursors(); 'springt zu Resetcursor Abschnitt if ret% = 2 then 'falls CHANGE gedrueckt wurde GetLevel(); 'springt zu Getlevel Abschnitt GetBurstSettings(); 'springt zu GetBurstSettings Abschnitt again% := 1; 'setzt again auf 1 endif; until not again%; 'falls again Null ist dann weiter 'Now write results to log file... ok% := Query("Write results for this section?"); 'fragt nach ob die ergebnisse geshrieben werden sollen if ok% then 'fall ok% nicht Null ist WriteResults(); 'springt zu Ergebnisschreiben endif; 'Go again? another% := Query("Go again?"); 'nochmal ?? until not another%; 'wenn cancel gedrueckt, dann nicht 'delete channels? var delchannel%; delchannel% := Query("delete temp. channels?"); 'delete channels? if delchannel%=1 then 'falls Delet gedrueckt wird 'Delete temporary channels... ChanDelete(eventCh1%); ChanDelete(eventCh2%); 'ChanDelete(eventCh3%); ChanDelete(eventCh4%); ChanDelete(eventCh5%); ChanDelete(BurstCh1%); ChanDelete(BurstCh2%); endif; Halt(); 'und aus! 'Get the parameters for forming the bursts... proc GetBurstSettings() DlgCreate("Enter parameters..."); 'erzeugt ein Popup DlgReal(1, "Maximum interval between spike in a burst:", 0.01, 10); 'fragt nach Interval zwischen 0.01 und 10 DlgShow(setMinBurstSep); 'zeigt das POpup und holt den Wert end; 'Get cut-off level for peak extraction... proc GetLevel() while HCursorDelete() 'loescht jeweils den hoechsten Hcursor, bis keiner mehr da ist do; wend; HCursorNew(inputCh%); 'setzte Hcursor in Kanal Interact("Place the horizontal cursor so that events above it will be included...", 0 ); 'erlaubt user nur den Cursor zu setzen sonst nix setCutOff1 := HCursor(1); HCursorNew(inputCh%); Interact("Place the horizontal cursor so that events below it will be included...", 0 ); 'wie oben, nur fuer den 2. Hcursor setCutOff2 :=HCursor(2); 'SetCutOff2 = 0; 'discrim :=SetCutOff1-SetCutOff2; 'fehlt hier ein return???? end; 'Get bursts for Bursts and for pulses... proc CalculateBursts() 'Delete last set of data... if eventCh1% > 0 then ChanDelete(eventCh1%); endif; 'loescht den eventch 1 usw... if eventCh1% > 0 then ChanDelete(eventCh2%); endif; 'if eventCh1% > 0 then ChanDelete(eventCh3%); endif; if eventCh1% > 0 then ChanDelete(eventCh4%); endif; 'if eventCh1% > 0 then ChanDelete(eventCh5%); endif; if BurstCh1% > 0 then ChanDelete(BurstCh1%); endif; if BurstCh1% > 0 then ChanDelete(BurstCh2%); endif; 'Get events (cut-off x2 because want peak amplitude above y=0 line)... eventCh1% := MemChan(2); 'legt neuen Memorychannel an. 2 steht fuer Eventchannel, 1 waere data 'eventCh3% := MemChan(2); MemImport(eventCh1%, inputCh%, sTime, eTime, 2, 0, setCutOff1); 'holt die Daten in den Memorykanal (eventch1) aus inputch% von sTime bis eTime, '2 heisst, wenn daten die schwelle ueberschreiten, 0 heisst dass kein Zeitintervall da sein soll und die letzte Variable gibt die Schwelle (hcursor) 'MemImport(eventCh3%, inputCh%, sTime, eTime, 2, 0, setCutOff1); ChanShow(eventCh1%); 'zeigt den Kanal eventCh2% := MemChan(2); 'holt die falling times aus der Kurve MemImport(eventCh2%, inputCh%, sTime, eTime, 3, 0, setCutOff1); ChanShow(eventCh2%); eventCh4% := MemChan(2); '??? weiss nicht so recht, was das jetzt soll... verhindert das Loeschen der DATEN !!! MemImport(eventCh4%, inputCh%, sTime, eTime, 2, 0, setCutOff2); ChanShow(eventCh4%); ' ok, hier suchen wir nach Spikes und nicht nach Durchgaengen! eventCh5% := MemChan(2); var punkt; 'punkt gibt die rising time des ersten Spikes var punkt2; 'punkt2 gibt die falling time des ersten Spikes 'var looktime; var peakamp; ' peakamp ist die Amplitude des Spikes 'looktime:=1; punkt:=sTime; while punkt>0 do 'wir suchen nach SpikeEvents, die wir weiter oben schon in einen Kanal geschrieben haben 'looktime:=looktime+1; punkt:=nexttime(eventCh1%,punkt); 'rising time of spike punkt2:=nexttime(eventCh2%,punkt2); 'falling time of spike if punkt>0 then peakamp:=ChanMeasure(inputCh%,8,punkt,punkt2); 'amplitude of spike endif; ' PrintLog("amplitude",peakamp); if peakamp100 then 'NOTBREMSE 'halt; 'endif; wend; 'ende des loops ChanShow(eventCh5%); ' und Kanal zeigen 'eventCh5% := MemChan(2); 'eventCh3% -=eventCh4%; 'eventCh5% :=MemChan(2); 'MemImport(eventCh5%, eventCh3%, sTime, eTime); 'if (eventCh3%-eventCh4%) = 0 then 'eventCh5% := MemChan(2); 'eventCh5% := eventCh3% - eventCh4%; 'endif; 'ChanShow(eventCh5%); 'eventCh3% := eventCh2%; 'eventCh4% := MemChan(2); 'MemImport(eventCh4%, eventCh3%, sTime, eTime); 'Get Bursts... BurstCh1% := MemChan(4); BurstMake(BurstCh1%, eventCh5%, sTime, eTime, setMinBurstSep); 'erstellt einen Kanal mit Bursts drin (Burstch1) 'aus dem eventch mit Anfangstime sTime und Endzeit eTime, die letzte Variable setzt den maximalen Abstand zwischen 'zwei events, die noch zu einem Burst gehoeren ChanShow(BurstCh1%); 'zeigt den Kanal BurstCh2% :=MemChan(4); BurstMake(BurstCh2%, eventCh4%, sTime, eTime, setMinBurstSep); ChanShow(BurstCh2%); end; 'Write results for Bursts in time range selected... proc WriteResults() var ok%; var sBurst, eBurst; 'definiert variablen (reale werte) View(fh%); Window(0,0,60,100); View(LogHandle()); 'legt den aktuellen View auf das Logfenster Window(60,0,100,100); 'legt das Fenster an eine bestimmt Stelle innerhalb vom Spike2 Fenster FrontView(LogHandle()); 'und bringt es nach vorne ok% := Query("Append results or clear?", "Append", "Clear"); 'Fragt, ob geloescht oder appended werden soll if not ok% then 'wenn CLEAR gedrueckt wurde View(LogHandle()); 'legt den aktuellen View auf das Logfenster EditSelectAll(); 'selektiert alles, was zum Clipboard kopiert werden kann (also hier allen Text im Logfenster) EditClear(); 'und loescht ihn (alles, was ausgewaehlt ist... endif; View(fh%); 'anscheinend ein Versuch, ins Logfile zu schreiben PrintLog("\n\nFile: %s Channel: %d\n\n", FileName$(), inputCh%); PrintLog("Start: %f End: %f Duration: %f\n\n", sTime, eTime, eTime - sTime); PrintLog("Burst # Burst duration # of Spikes Spike Frequency (Hz) Time of Burst Onset (sec) Time of Burst Offset (sec) \n"); PrintLog("_______ ______________ ___________ ____________________ _________________________ __________________________ \n"); sBurst := sTime; 'gibt den ersten Cursor wider eBurst := sTime; while sBurst >= 0 and eBurst >= 0 do 'falls beide Zeitpunkte groesser Null var burstnum; sBurst := NextTime(BurstCh1%, eBurst); 'suche in Burstch1 nach Burstanfang if sBurst > 0 then 'falls Burst gefunden eBurst := NextTime(BurstCh1%, sBurst); 'suche Ende von Burst if eBurst > 0 then 'falls Ende gefunden AnalyseBurst(sBurst, eBurst, burstnum); 'gehe zu AnalyseBurst und uebergebe Variablen burstnum :=1+burstnum; 'erhoehe die Burstnummer numburst := burstnum; PrintLog(" %d %10.5f %d %10.5f %f %f \n", burstnum, results[resDuration1%], results[resSpikes1%], results[resSpikeFreq1%], sBurst, eBurst); endif; endif; wend; ' ab hier 2. Kanal PrintLog("\n second channel (only the spike above 2. cursor) \n"); PrintLog(" \n"); burstnum:=0; sBurst := sTime; eBurst := sTime; 'ok das hier sieht nach Debbie aus while sBurst >= 0 and eBurst >= 0 do sBurst := NextTime(BurstCh2%, eBurst); if sBurst > 0 then eBurst := NextTime(BurstCh2%, sBurst); if eBurst > 0 then AnalyseBurst2(sBurst, eBurst, burstnum); 'sprint zu AnalyseBurst und uebergibt Variablen burstnum :=1+burstnum; PrintLog(" %d %10.5f %d %10.5f %f %f \n", burstnum, results[resDuration2%], results[resSpikes2%], results[resSpikeFreq2%], sBurst, eBurst); endif; endif; wend; Interact("Inspect results and press OK to continue to Phaseanalysis...", 1023); PrintLog("\n"); phaseanal(); end; 'Collect data for one burst... proc AnalyseBurst(sBurst, eBurst, burstnum) var stats[4]; 'legt 4 stats als variablen fest 'ab hier dann Ausrechnen von Ergebnissen fuer die Bursts startBurst1[burstnum] := sBurst; endBurst1[burstnum] := eBurst; results[resDuration1%] := eBurst - sBurst; results[resSpikes1%] := Count(eventCh1%, sBurst, eBurst); results[resSpikeFreq1%] := results[resSpikes1%]/results[resDuration1%]; end; 'Collect data for 2nd. burstchannel... proc AnalyseBurst2(sBurst, eBurst, burstnum) var stats[4]; 'legt 4 stats als variablen fest 'ab hier dann Ausrechnen von Ergebnissen fuer die Bursts startBurst2[burstnum] := sBurst; endBurst2[burstnum] := eBurst; results[resDuration2%] := eBurst - sBurst; results[resSpikes2%] := Count(eventCh4%, sBurst, eBurst); results[resSpikeFreq2%] := results[resSpikes2%]/results[resDuration2%]; end; 'Phaseanalysis func phaseanal() if startBurst2[1] > startBurst1[1] then for p := 0 to numburst-1 do if startBurst1[p+1] > 0 then phaseon[p] := (startBurst2[p] - startBurst1[p]) / (startBurst1[p+1] - startBurst1[p]); phaseoff[p] := (endBurst2[p] - startBurst1[p]) / (startBurst1[p+1] - startBurst1[p]); PrintLog("Phaseon of burst# ",p+1 , " = ", phaseon[p], " on second channel - Phaseoff of burst# ",p+1 , " = ", phaseoff[p]); endif; next; else PrintLog("Phaseanalysis makes no sense - second burst before first burst"); endif; end; 'Reset the cursors... proc ResetCursors() CursorSet(2); 'macht 2 cursors und loescht alle anderen Cursor(1, sTime); 'setzt cursor 1 an stelle sTime Cursor(2, eTime); 'dito fuer cursor 2 XRange(sTime - (eTime - sTime)/5, eTime + (eTime - sTime)/5); 'setzte X-Achse fuer Datenfile view end;