-
Notifications
You must be signed in to change notification settings - Fork 3
/
t2n.m
2447 lines (2284 loc) · 158 KB
/
t2n.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
function [out, origminterf,tree] = t2n(neuron,tree,options,exchfolder,server)
% t2n ("Trees toolbox to Neuron") is to generate and execute a NEURON
% simulation with the morphologies in tree, and parameters in the structure
% neuron. This is the main function.
% The output-file(s) of the NEURON function are read and transferred
% into the output variable out
% INPUTS
% neuron t2n neuron structure with already defined mechanisms (see documentation)
% tree tree cell array with morphologies (see documentation)
% options string with optional arguments (can be concatenated):
% -w waitbar
% -d Debug mode (NEURON is opened and some parameters are set)
% -q quiet mode -> suppress output
% -o open all NEURON instances instead of running them in
% the background
% -m let T2N recompile the nrnmech.dll. Useful if a mod file was modified.
% For safety of compiled dlls, this option does not work when an explicit
% name of a dll was given via neuron.params.nrnmech!
% -cl cluster mode -> files are prepared to be executed
% on a cluster (see documentation for more information)
% exchfolder (optional) relative name of folder where simulation data is
% saved. Default is t2n_exchfolder
% server (only required in cluster mode) structure with
% server and server folder access information
%
% This code is based on an idea of Johannes Kasper, a former group-member
% in the Lab of Hermann Cuntz, Frankfurt.
%
% *****************************************************************************************************
% * This function is part of the T2N software package. *
% * Copyright 2016-2019 Marcel Beining <marcel.beining@gmail.com> *
% *****************************************************************************************************
%%%%%%%%%%%%%%%%%%% CONFIGURATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
interf_file = 'neuron_runthis.hoc'; % the name of the main hoc file which will be written
%% check options and paths
t2npath = fileparts(which('t2n.m'));
modelFolder = pwd;
if nargin < 3 || isempty(options)
options = '';
end
if ~isempty(regexp(options,'-d','ONCE'))
debug = 1;
else
debug = 0;
end
%% check input
if ~exist('tree','var')
error('No tree specified in input')
end
if ~exist('neuron','var') % if no neuron structure was given, create standard parameter set
warning('No input about what to do was given! Standard test (HH + rectangle somatic stimulation) is used')
neuron.pp{1}.IClamp = struct('node', 1, 'del',100,'dur',50,'amp',0.05);
neuron.record{1}.cell = struct('node',1 ,'record', 'v');
neuron.APCount{1} = {1,-30}; % {node, tresh}
neuron.mech.all.pas = [];
neuron.mech.soma.hh = [];
neuron.mech.axon.hh = [];
end
[neuron,tree,usestreesof,nocell,nexchfolder,ppTag2Node,legacyOutput] = t2n_checkinput(neuron,tree);
if ~exist('exchfolder','var')
if ~isempty(nexchfolder)
exchfolder = nexchfolder;
else
exchfolder = 't2n_exchange';
end
end
if ~isempty(regexp(options,'-cl','ONCE')) % server mode
nrn_path = server.modelfolder;
if ~isfield(server,'walltime') || numel(server.walltime) ~=3
server.walltime = [5 0 0];
warning('Server walltime not specified correctly (1 by 3 vector in server.walltime). Walltime set to 5 hours');
end
if ~isfield(server,'memory') || numel(server.memory) ~=1
server.memory = 1;
warning('Max memory per node not specified correctly (1 scalar [GB] in server.memory). Max memory set to 1GB');
end
server.softwalltime = sum(server.walltime .* [3600,60,1])-30; %subtract 30 sec
server.softwalltime = floor([server.softwalltime/3600,rem(server.softwalltime,3600)/60,rem(server.softwalltime,60)]);
server.envstr = '';
server.qfold = '';
if isfield(server,'env') && isstruct(server.env)
envnames = fieldnames(server.env);
for v = 1:numel(envnames)
server.envstr = [server.envstr,'setenv ',envnames{v},' ',server.env.(envnames{v}),'; '];
end
if isfield(server.env,'SGE_ROOT') && isfield(server.env,'SGE_ARCH')
server.qfold = sprintf('%s/bin/%s/',server.env.SGE_ROOT,server.env.SGE_ARCH);
end
end
else
nrn_path = modelFolder;
if ~ispc()
[~,cmdout] = system('echo $0');
if isempty(regexp(cmdout,'bash','ONCE'))
error('It seems your system is not using bash shell as standard shell for Matlab! Please, before starting Matlab, define the environmental variable $MATLAB_SHELL to point to the bash shell, e.g. by "setenv MATLAB_SHELL /bin/bash"');
end
% search for the libstdc library in order to have matlab using the
% same libary than the system
% [~,cmdout] = system('find / -maxdepth 4 -name libstdc++.so.6 -print -quit');
[~,cmdout] = system('ldconfig -p | grep stdc++'); % search for the libstdc++ library that is used by the system
cmdout = strsplit(cmdout,'\n');
cmdout = cellfun(@(x) x(regexp(x,'=> /','end'):end),cmdout,'uni',0); % get the paths to the libraries
if any(cellfun(@(x) ~isempty(regexp(x,'64','ONCE')),cmdout)) % check for a 64 bit version otherwise take first one found
libstdcLocation = cmdout{cellfun(@(x) ~isempty(regexp(x,'64','ONCE')),cmdout)};
else
libstdcLocation = cmdout{1};
end
setenv('LD_PRELOAD',libstdcLocation) % preload the libstdc library from the system
end
end
nrn_path = regexprep(nrn_path,'\\','/');
if strcmp(nrn_path(end),'/') % remove "/" from path
nrn_path = nrn_path(1:end-1);
end
%% connect to server
if regexp(options,'-cl') % server mode
if ~exist('server','var')
error('No access data provided for Cluster server. Please specify in server')
else
if isfield(server,'connect')
else
if exist('sshj-master/sshj-0.0.0-no.git.jar','file')% exist('ganymed-ssh2-build250/ganymed-ssh2-build250.jar','file')
sshjfolder = fileparts(which('sshj-master/sshj-0.0.0-no.git.jar'));
javaaddpath(fullfile(sshjfolder,'sshj-0.0.0-no.git.jar'));%javaaddpath(which('ganymed-ssh2-build250/ganymed-ssh2-build250.jar'));
javaaddpath(fullfile(sshjfolder,'bcprov-ext-jdk15on-156.jar'));
javaaddpath(fullfile(sshjfolder,'bcpkix-jdk15on-1.56.jar'));
javaaddpath(fullfile(sshjfolder,'slf4j-1.7.23'));
else
try
sshfrommatlabinstall(1)
catch
error('Could not find the ganymed ssh zip file')
end
end
server.connect = sshfrommatlab(server);
end
if ~isfield(server,'modelfolder')
error('No folder on Server specified, please specify under server.modelfolder')
end
end
end
%% check for exchange folder (folder where files between Matlab and NEURON
% are exchanged)
if regexp(options,'-cl')
nrn_exchfolder = fullfile(server.modelfolder,exchfolder);
else
nrn_exchfolder = fullfile(modelFolder,exchfolder);
end
nrn_exchfolder = regexprep(nrn_exchfolder,'\\','/');
%% Check if NEURON software exists at the given path and assure that parallel NEURON can be executed if necessary
if ~isempty(regexp(options,'-cl','ONCE'))
[~, outp] = sshfrommatlabissue(server.connect,'module avail');
server.neuron = regexpi(outp.StdErr,'neuron/\d{1,2}\.\d{1,2}\s','match'); % available modules are reported to errorStream..dunno why
% server.envstr = [server.envstr, sprintf('module load %s; ',outp{1})]; % load first found neuron version
fprintf('Available neuron modules found:\n%s\nChoosing %s',sprintf('%s',server.neuron{:}),server.neuron{1})
else
if ispc
lookForCommand = 'where';
else
lookForCommand = 'which';
end
[~,outp] = system([lookForCommand, ' nrniv']);
% check if any nrniv has been found. if not and it is Windows, ask to
% search for the nrniv exe or look for the nrniv_win text file
if isempty(outp) || ~isempty(regexp(outp,'not found','ONCE')) || ~isempty(regexp(outp,'no nrniv','ONCE')) || ~isempty(regexp(outp,'not find','ONCE')) || strcmp(outp,sprintf('\n')) || isempty(regexp(outp,'nrniv','ONCE'))
if ispc
askflag = 0;
if ~exist(fullfile(t2npath,'nrniv_win.txt'),'file')
disp('Searching for nrniv.exe ...please wait')
printflag = true;
system(sprintf('where /R C:\\ nrniv.exe > "%s"&',fullfile(t2npath,'nrniv_win.txt')));
else
printflag = false;
end
fid = fopen(fullfile(t2npath,'nrniv_win.txt'),'r');
nrnivPath = fread(fid,'*char')';
fclose(fid);
if ~exist(nrnivPath,'file')
askflag = 1;
nrnivPath = strcat(' under "',nrnivPath,'"');
end
if askflag
[filename,pathname] = uigetfile('nrniv.exe',sprintf('No NEURON software found%s! Please select the nrniv.exe in your neuron installation',nrnivPath));
if isnumeric(filename) && filename == 0
error('Search for nrniv.exe was aborted. It is necessary that NEURON is installed and nrniv.exe is once localized by you (alternatively use the "Set DOS environment" option during NEURON installation).')
end
while isempty(regexp(filename,'nrniv.exe','ONCE'))
[filename,pathname] = uigetfile('nrniv.exe','You did not choose the nrniv.exe! Please select the nrniv.exe in your NEURON installation');
if isnumeric(filename) && filename == 0
error('Search for nrniv.exe was aborted. It is necessary that NEURON is installed and nrniv.exe is once localized by you (alternatively use the "Set DOS environment option during NEURON installation).')
end
end
nrnivPath = fullfile(pathname,filename);
fid = fopen(fullfile(t2npath,'nrniv_win.txt'),'w');
fprintf(fid,strrep(nrnivPath,'\','/'));
fclose(fid);
elseif printflag
fprintf('Neuron installation found in "%s"\n',nrnivPath)
end
elseif ismac
error('NEURON software (nrniv) not found on this Mac! Either not installed correctly or Matlab was not started from Terminal')
else
error('NEURON software (nrniv) not found on this Linux machine or module has not been loaded! Check for correct installation')
end
else
% get path to nrniv out of the which/where command output
nrnlocs = strsplit(outp,'\n');
nrnivPath = nrnlocs{find(cellfun(@(x) ~isempty(regexp(x,'nrniv','ONCE')) ,nrnlocs),1,'first')};
end
end
% now check for MPIexec provided that it would be used
if any(arrayfun(@(x) neuron{t2n_getref(x,neuron,'params')}.params.parallel,1:numel(neuron))) % check for the parallel NEURON flag
% look for mpi software on PC, extract the ones which do not come from
% Matlab and use them later
if ispc
mpisoftw = fullfile(fileparts(nrnivPath),'mpiexec'); % for Windows, the mpiexec can be found in the Neuron bin folder
else
% for Mac/Linux, mpiexec has to be installed
[~,mpilocs] = system([lookForCommand, ' mpiexec']);
try
if isempty(mpilocs) || ~isempty(regexp(mpilocs,'not find','ONCE')) || ~isempty(regexp(mpilocs,'not found','ONCE')) || ~isempty(regexp(mpilocs,'no mpiexec','ONCE'))
error('')
end
mpilocs = strsplit(mpilocs,'\n');
mpisoftw = mpilocs{find(cellfun(@(x) ~isempty(x) & isempty(regexpi(x,'matlab','ONCE')),mpilocs),1,'first')};
if isempty(mpisoftw)
error('')
end
catch
% if ispc
% error('No MPI (Message Passing Interface) implementation found on this Windows machine! You should install Microsoft MPI: https://msdn.microsoft.com/en-us/library/bb524831.aspx')
% else
if ismac
error('No MPI (Message Passing Interface) implementation found on this Mac! Either not installed correctly or Matlab was not started from Terminal. If installation is necessary, we recommend https://www.open-mpi.org/software/ompi/')
else
error('No MPI (Message Passing Interface) implementation found on this Linux machine or module has not been loaded! If installation is necessary, we recommend https://www.open-mpi.org/software/ompi/')
end
end
end
end
%% check for standard hoc files in the model folder and copy them if not existing
if ~ exist(fullfile(modelFolder,'lib_mech'),'dir') || ~ exist(fullfile(modelFolder,'lib_custom'),'dir') || ~ exist(fullfile(modelFolder,'morphos'),'dir') || ~ exist(fullfile(modelFolder,'lib_genroutines'),'dir')
answer = questdlg(sprintf('T2N detection that the current folder contains no T2N standard folders (lib_mech etc.). This is mandatory. Do you want to have them created now?'),'Initialize model folders?','Yes','No','Cancel','Cancel');
if strcmp(answer,'Yes')
t2n_initModelfolders(modelFolder);
else
error('Aborted creation of model folders.');
end
end
%% create the local and server exchange folder
if exist(fullfile(modelFolder,exchfolder),'dir') == 0
mkdir(fullfile(modelFolder,exchfolder));
end
if regexp(options,'-cl')
localfilename = {};
mechflag = false;
[server.connect,~] = sshfrommatlabissue(server.connect,sprintf('mkdir %s',server.modelfolder)); % check if mainfolder exists
[server.connect,outp] = sshfrommatlabissue(server.connect,sprintf('ls %s',server.modelfolder)); % check if mainfolder exists
if isempty(regexp(outp.StdOut,'lib_genroutines', 'once'))
[server.connect,~] = sshfrommatlabissue(server.connect,sprintf('mkdir %s/lib_genroutines',server.modelfolder));
fils = dir(fullfile(modelFolder,'lib_genroutines/')); % get files from folder
localfilename = cat(2,localfilename,fullfile(modelFolder,'lib_genroutines',{fils(~cellfun(@(x) strcmp(x,'.')|strcmp(x,'..'),{fils.name})).name})); % find all files
end
if isempty(regexp(outp.StdOut,'morphos/hocs', 'once'))
[server.connect,~] = sshfrommatlabissue(server.connect,sprintf('mkdir %s/%s',server.modelfolder,'morphos/hocs'));
fils = dir(fullfile(modelFolder,'morphos/hocs')); % get files from folder
localfilename = cat(2,localfilename,fullfile(modelFolder,'morphos/hocs',{fils(cellfun(@(x) ~isempty(regexpi(x,'.hoc')),{fils.name})).name})); % find all hoc files
end
if isempty(regexp(outp.StdOut,'lib_mech','ONCE'))
[server.connect,~] = sshfrommatlabissue(server.connect,sprintf('mkdir %s/lib_mech',server.modelfolder));
fils = dir(fullfile(modelFolder,'lib_mech/'));
localfilename = cat(2,localfilename,fullfile(modelFolder,'lib_mech',{fils(cellfun(@(x) ~isempty(regexpi(x,'.mod')),{fils.name})).name})); % find all mod files
mechflag = true;
end
if isempty(regexp(outp.StdOut,'lib_custom','ONCE'))
[server.connect,~] = sshfrommatlabissue(server.connect,sprintf('mkdir %s/lib_custom',server.modelfolder));
fils = dir(fullfile(modelFolder,'lib_custom/'));
localfilename = cat(2,localfilename,fullfile(modelFolder,'lib_custom',{fils(~cellfun(@(x) strcmp(x,'.')|strcmp(x,'..'),{fils.name})).name})); %find all files
end
if ~isempty(localfilename)
localfilename = regexprep(localfilename,'\\','/');
remotefilename = regexprep(localfilename,modelFolder,server.modelfolder);
sftpfrommatlab(server.user,server.host,server.pw,localfilename,remotefilename);
end
if mechflag % compile mod files
[server.connect,outp] = sshfrommatlabissue(server.connect,sprintf('cd %s/lib_mech;module load %s; nrnivmodl',server.modelfolder,server.neuron{1}));
display(outp.StdOut)
pause(5)
end
[server.connect,outp] = sshfrommatlabissue(server.connect,sprintf('cd %s/lib_mech/;ls -d */',server.modelfolder));
server.nrnmech = regexprep(fullfile(server.modelfolder,'lib_mech',outp.StdOut(1:regexp(outp.StdOut,'/')-1),'.libs','libnrnmech.so'),'\\','/'); % there should only be one folder in it
[server.connect,~] = sshfrommatlabissue(server.connect,sprintf('rm -rf %s',nrn_exchfolder));
[server.connect,~] = sshfrommatlabissue(server.connect,sprintf('mkdir %s',nrn_exchfolder));
end
%% initialize basic variables
noutfiles = 0; % counter for number of output files
readfiles = cell(0); % cell array that stores information about output files
sampleFields = {'Dt','tvec'};
out = cell(numel(neuron),1);
origminterf = cell(numel(tree),1);
for t = 1:numel(tree)
if ~isfield(tree{t},'artificial')
origminterf{t} = load(fullfile(modelFolder,'morphos','hocs',sprintf('%s_minterf.dat',tree{t}.NID)));
end
end
%% start writing hoc file
spines_flag = false(numel(neuron),1);
minterf = cell(numel(tree),1);
ppIdMap = repmat({struct()},numel(neuron),1);
for n = 1:numel(neuron)
makenewrect = true;
refPar = t2n_getref(n,neuron,'params');
refT = t2n_getref(n,neuron,'tvecs');
refM = t2n_getref(n,neuron,'mech');
refPP = t2n_getref(n,neuron,'pp');
refC = t2n_getref(n,neuron,'con');
refCust = t2n_getref(n,neuron,'custom');
refR = t2n_getref(n,neuron,'record');
refP = t2n_getref(n,neuron,'play');
refAP = t2n_getref(n,neuron,'APCount');
for t = 1:numel(neuron{refM}.mech) % check if any region of any tree has the spines mechanism
if ~isempty(neuron{refM}.mech{t})
fields = fieldnames(neuron{refM}.mech{t});
for f = 1:numel(fields)
if any(strcmpi(fieldnames(neuron{refM}.mech{t}.(fields{f})),'spines'))
spines_flag(n) = true;
break
end
end
if spines_flag(n)
break
end
end
end
if regexp(options,'-d')
tim = tic;
end
for tt = 1:numel(tree(neuron{n}.tree))
if ~isfield(tree{neuron{n}.tree(tt)},'artificial')
minterf{neuron{n}.tree(tt)} = t2n_makeNseg(tree{neuron{n}.tree(tt)},origminterf{neuron{n}.tree(tt)},neuron{refPar}.params,neuron{refM}.mech{neuron{n}.tree(tt)});
end
end
access = [find(~cellfun(@(y) isfield(y,'artificial'),tree(neuron{n}.tree)),1,'first'), 1]; % std accessing first non-artificial tree at node 1
thisfolder = sprintf('sim%d',n);
if exist(fullfile(modelFolder,exchfolder,thisfolder),'dir') == 0
mkdir(fullfile(modelFolder,exchfolder,thisfolder));
end
if exist(fullfile(modelFolder,exchfolder,thisfolder,'iamrunning'),'file')
answer = questdlg(sprintf('Warning!\n%s seems to be currently run by Neuron or the last T2N/Neuron run in this folder was aborted unexpectedly!\nIn the first case overwriting might cause errorneous output, in the last you are safe!\nIf you are sure that there is no simulation running, we can continue and overwrite. Are you sure? ',fullfile(exchfolder,thisfolder)),'Overwrite unfinished simulation','Yes to all','Yes','No (Cancel)','No (Cancel)');
switch answer
case 'Yes'
% iamrunning file is kept and script goes on...
case 'Yes to all' % delete all iamrunning files in that exchfolder except from the current simulation
folders = dir(exchfolder);
for f = 1:numel(folders) % ignore first two as these are . and ..
if ~isempty(strfind(folders(f).name,'sim')) && ~strcmp(folders(f).name,thisfolder) && exist(fullfile(modelFolder,exchfolder,folders(f).name,'iamrunning'),'file')
delete(fullfile(modelFolder,exchfolder,folders(f).name,'iamrunning'))
end
end
otherwise
error('T2N aborted')
end
% else
% ofile = fopen(fullfile(modelFolder,exchfolder,thisfolder,'iamrunning') ,'wt');
% fclose(ofile);
end
% delete the readyflag and log files if they exist
if exist(fullfile(modelFolder,exchfolder,thisfolder,'readyflag'),'file')
delete(fullfile(modelFolder,exchfolder,thisfolder,'readyflag'))
end
if exist(fullfile(modelFolder,exchfolder,thisfolder,'ErrorLogFile.txt'),'file')
delete(fullfile(modelFolder,exchfolder,thisfolder,'ErrorLogFile.txt'))
end
if exist(fullfile(modelFolder,exchfolder,thisfolder,'NeuronLogFile.txt'),'file')
delete(fullfile(modelFolder,exchfolder,thisfolder,'NeuronLogFile.txt'))
end
if ~isempty(regexp(options,'-cl','ONCE'))
[server.connect,~] = sshfrommatlabissue(server.connect,sprintf('mkdir %s/%s',nrn_exchfolder,thisfolder));
end
%% write interface hoc
nfile = fopen(fullfile(modelFolder,exchfolder,thisfolder,interf_file) ,'wt'); %open resulting hoc file in write modus
fprintf(nfile,'// ***** This is a NEURON hoc file automatically created by the Matlab-NEURON interface T2N. *****\n');
fprintf(nfile,'// ***** Copyright by Marcel Beining, Clinical Neuroanatomy, Goethe University Frankfurt*****\n\n');
%initialize variables in NEURON
fprintf(nfile,'// General variables: i, CELLINDEX, debug_mode, accuracy\n\n');
fprintf(nfile,'// ***** Initialize Variables *****\n');
fprintf(nfile,'strdef tmpstr,simfold // temporary string object\nobjref f\n');
fprintf(nfile,'objref pc,nil,cvode,strf,tmpvec,tvec,tvecs,cell,cellList,pp,ppList,con,conList,nilcon,nilconList,rec,recList,rect,rectList,playt,playtList,play,playList,APCrec,APCrecList,APC,APCList,APCcon,APCconList,thissec,thisseg,thisval \n cellList = new List() // comprises all instances of cell templates, also artificial cells\n ppList = new List() // comprises all Point Processes of any cell\n conList = new List() // comprises all NetCon objects\n tvecs = new List() //comprises all custom time vectors\n recList = new List() //comprises all recording vectors\n rectList = new List() //comprises all time vectors of recordings\n playtList = new List() //comprises all time vectors for play objects\n playList = new List() //comprises all vectors played into an object\n APCList = new List() //comprises all APC objects\n APCrecList = new List() //comprises all APC recording vectors\n nilconList = new List() //comprises all NULL object NetCons\n cvode = new CVode() //the Cvode object\n thissec = new Vector() //for reading range variables\n thisseg = new Vector() //for reading range variables\n thisval = new Vector() //for reading range variables\n\n');
fprintf(nfile,'\n\n');
fprintf(nfile,'// ***** Load standard libraries *****\n');
% fprintf(nfile,'\n\nchdir("%s/%s/%s") // change directory to folder of simulation #%d \n',nrn_path,exchfolder,thisfolder,n);
if isfield(neuron{refPar}.params,'nrnmech')
if iscell(neuron{refPar}.params.nrnmech)
for c = 1:numel(neuron{refPar}.params.nrnmech)
if ~exist(fullfile(modelFolder,'lib_mech',neuron{refPar}.params.nrnmech{c}),'file')
error('File %s is not existent in folder lib_mech',neuron{refPar}.params.nrnmech{c})
end
fprintf(nfile,'io = nrn_load_dll("../../lib_mech/%s")\n',neuron{refPar}.params.nrnmech{c});
end
else
if ~exist(fullfile(modelFolder,'lib_mech',neuron{refPar}.params.nrnmech),'file')
error('File %s is not existent in folder lib_mech',neuron{refPar}.params.nrnmech)
end
fprintf(nfile,'io = nrn_load_dll("../../lib_mech/%s")\n',neuron{refPar}.params.nrnmech);
end
else
if exist(fullfile(modelFolder,'lib_mech'),'dir')
if ispc
if ~exist(fullfile(modelFolder,'lib_mech','nrnmech.dll'),'file') || ~isempty(regexp(options,'-m','ONCE')) % check for existent file, otherwise compile dll
nrn_installfolder = regexprep(fileparts(fileparts(nrnivPath)),'\\','/');
if exist(fullfile(nrn_installfolder,'/mingw/bin/sh.exe'),'file')
shpath = [nrn_installfolder,'/mingw/bin/sh'];
elseif exist(fullfile(nrn_installfolder,'/mingw/usr/bin/sh.exe'),'file')
shpath = [nrn_installfolder,'/mingw/usr/bin/sh'];
else
error('Neurons sh.exe not found, please contact T2N developer on github')
end
tstr = sprintf('cd "%s" && %s "%s/mknrndll.sh" %s %s',[nrn_path,'/lib_mech'],shpath, regexprep(t2npath,'\\','/'), [' /cygdrive/',regexprep(nrn_installfolder,':','')]);
[~,cmdout] = system(tstr);
if isempty(regexp(cmdout,'nrnmech.dll was built successfully','ONCE'))
error('File nrnmech.dll was not found in lib_mech and compiling it with mknrndll failed! Check your mod files and run mknrndll manually\n Log of compiling:\n%s',cmdout)
else
disp('nrnmech.dll compiled from mod files in folder lib_mech')
end
t2n_renameNrnmech() % delete the o and c files
end
fprintf(nfile,'nrn_load_dll("../../lib_mech/nrnmech.dll")\n');
else
[~,cmdout] = system('uname -m'); % get machine specification
mechfile = fullfile('lib_mech',strrep(cmdout,sprintf('\n'),''),'.libs','libnrnmech.so');
% mechfold = dir(fullfile(modelFolder,'lib_mech','x86_*'));
if ~exist(fullfile(modelFolder,mechfile),'file') || ~isempty(regexp(options,'-m','ONCE')) % isempty(mechfold) % check for existent file, otherwise compile
[~,outp] = system(sprintf('cd "%s/lib_mech";nrnivmodl',modelFolder));
if ~isempty(regexp(outp,'Successfully','ONCE'))
disp('nrn mechanisms compiled from mod files in folder lib_mech')
else
rmdir(fullfile(modelFolder,'lib_mech',cmdout),'s');
% mechfold = dir(fullfile(modelFolder,'lib_mech','x86_*'));
% for m = 1:numel(mechfold)
% rmdir(fullfile(modelFolder,'lib_mech',mechfold(m).name),'s');
% end
error('There was an error during compiling of mechanisms:\n\n%s',outp)
end
end
fprintf(nfile,'nrn_load_dll("../../%s")\n',mechfile);
end
else
warning('No folder "lib_mech" found in your model directory and no nrnmech found to load in neuron{refP}.params.nrnmech. Only insertion of standard mechanisms (pas,hh,IClamp,AlphaSynapse etc.) possible.')
end
end
if ~isempty(regexp(options,'-o','ONCE'))
fprintf(nfile,'io = load_file("nrngui.hoc")\n'); % load the NEURON GUI
else
fprintf(nfile,'io = load_file("stdgui.hoc")\n'); % ony load other standard procedures
end
fprintf(nfile,'simfold = "../sim%d"\n',n); % das passt so!
fprintf(nfile, 'io = xopen("../../lib_genroutines/genroutines.hoc")\n' );
fprintf(nfile, 'io = xopen("../../lib_genroutines/pasroutines.hoc")\n' );
if neuron{refPar}.params.parallel
[GIDs,neuron{n},mindelay] = t2n_getGIDs(neuron{n},tree,neuron{n}.tree);
mindelay = max(mindelay,neuron{refPar}.params.dt); % make mindelay at least the size of dt
fprintf(nfile,'\n\n');
fprintf(nfile,'// ***** Initialize parallel manager *****\n');
fprintf(nfile,'pc = new ParallelContext(%d)\n',neuron{refPar}.params.parallel);
ofile = fopen(fullfile(modelFolder,exchfolder,thisfolder,'gid2node.dat') ,'wt'); %open dat file in write modus
fprintf(ofile,'%d\n',rem(cat(1,GIDs.cell),neuron{refPar}.params.parallel)); % distribute the gids in such a way that all sections/pps of one cell are on the same host, and do roundrobin for each cell
fclose(ofile);
fprintf(nfile,'set_gid2node()\n\n\n');
fprintf(nfile,'if (pc.id()==0){\n');
end
fprintf(nfile,'// ***** Make Matlab notice that NEURON is running here *****\n');
fprintf(nfile,'f = new File()\n'); %create a new filehandle
fprintf(nfile,'io = f.wopen("iamrunning")\n'); % create the readyflag file
fprintf(nfile,'io = f.close()\n'); % close the filehandle
if neuron{refPar}.params.parallel
fprintf(nfile,'}\n');
end
fprintf(nfile,'\n\n');
if neuron{refPar}.params.parallel
fprintf(nfile,'// ***** Create empty cell object (parallel NEURON) *****\n');
fprintf(nfile,'begintemplate emptyObject\nendtemplate emptyObject\nobjref eObj\neObj = new emptyObject()\n');
end
fprintf(nfile,'\n\n');
fprintf(nfile,'// ***** Define some basic parameters *****\n');
fprintf(nfile,'debug_mode = %d\n',debug);
if isfield(neuron{refPar}.params,'accuracy')
fprintf(nfile,'accuracy = %d\n',neuron{refPar}.params.accuracy);
else
fprintf(nfile,'accuracy = 0\n' );
end
fprintf(nfile,'strf = new StringFunctions()\n');
if neuron{refPar}.params.cvode
fprintf(nfile,'cvode.active(1)\n');
if neuron{refPar}.params.use_local_dt
fprintf(nfile,'io = cvode.use_local_dt(1)\n');
end
else
fprintf(nfile,'io = cvode.active(0)\n');
fprintf(nfile,'tvec = new Vector()\ntvec = tvec.indgen(%f,%f,%f)\n',neuron{refPar}.params.tstart,neuron{refPar}.params.tstop,neuron{refPar}.params.dt);
if refPar == n % only write tvec if parameters are not referenced from another sim
fprintf(nfile,'f = new File()\n'); %create a new filehandle
fprintf(nfile,'io = f.wopen("tvec.dat")\n' ); % open file for this time vector with write perm.
fprintf(nfile,'io = tvec.printf(f,"%%-20.10g\\n")\n'); % print the data of the vector into the file
fprintf(nfile,'io = f.close()\n');
end
end
if ~isnan(refT)
if n == refT
f = fopen(fullfile(modelFolder,exchfolder,thisfolder,'tvecs.dat'),'w');
for c = 1:numel(neuron{refT}.tvecs)
fprintf(f,'%.6f\n ', neuron{refT}.tvecs{c});
fprintf(f,'-1e15\n'); % this is the stop sentinel for each vec
end
fclose(f);
end
fprintf(nfile,'read_tvecs("sim%d")\n',refT);
end
fprintf(nfile,'\n\n');
fprintf(nfile,'\n// ***** Load custom libraries *****\n');
if ~isnan(refCust) && ~isempty(neuron{refCust}.custom)
for c = 1:size(neuron{refCust}.custom,1)
if strcmpi(neuron{refCust}.custom{c,2},'start')
if strcmp(neuron{refCust}.custom{c,1}(end-4:end),'.hoc') %check for hoc ending
if exist(fullfile(modelFolder,'lib_custom',neuron{refCust}.custom{c,1}),'file')
fprintf(nfile,'io = load_file("../../lib_custom/%s")\n',neuron{refCust}.custom{c,1});
else
fprintf('File "%s" does not exist',neuron{refCust}.custom{c,1})
end
else
fprintf(nfile,neuron{refCust}.custom{c,1}); % add string as custom neuron code
end
end
end
end
fprintf(nfile,'\n\n');
fprintf(nfile,'// ***** Load cell morphologies and create artificial cells *****\n');
fprintf(nfile,'io = xopen("../sim%d/init_cells.hoc")\n',usestreesof(n)); % das passt so!
fprintf(nfile,'\n\n');
if ~isnan(refM)
fprintf(nfile,'// ***** Load mechanisms and adjust nseg *****\n');
if refM~=n
fprintf(nfile,'io = load_file("../sim%d/init_mech.hoc")\n',refM);
else
fprintf(nfile,'io = xopen("init_mech.hoc")\n' );
end
fprintf(nfile,'\n\n');
end
if ~isnan(refPP)
fprintf(nfile,'// ***** Place Point Processes *****\n');
if refPP~=n
fprintf(nfile,'io = load_file("../sim%d/init_pp.hoc")\n',refPP );
else
fprintf(nfile,'io = xopen("init_pp.hoc")\n' );
end
fprintf(nfile,'\n\n');
end
if ~isnan(refC)
fprintf(nfile,'// ***** Define Connections *****\n');
if refC~=n
fprintf(nfile,'io = load_file("../sim%d/init_con.hoc")\n',refC );
else
fprintf(nfile,'io = xopen("init_con.hoc")\n' );
end
fprintf(nfile,'\n\n');
end
if ~isnan(refR) || ~isnan(refAP)
fprintf(nfile,'// ***** Define recording sites *****\n');
if refR~=n && refAP~=n && refR==refAP % if both reference to the same other sim, use this sim
fprintf(nfile,'io = load_file("../sim%d/init_rec.hoc")\n',refR );
else % else write an own file
fprintf(nfile,'io = xopen("init_rec.hoc")\n' );
end
fprintf(nfile,'\n\n');
end
if ~isnan(refP)
fprintf(nfile,'// ***** Define vector play sites *****\n');
if refP~=n
fprintf(nfile,'io = load_file("../sim%d/init_play.hoc")\n',refP );
else
fprintf(nfile,'io = xopen("init_play.hoc")\n' );
end
end
fprintf(nfile,'\n\n');
fprintf(nfile,'// ***** Last settings *****\n');
if isfield(neuron{refPar}.params,'celsius')
if neuron{refPar}.params.q10 == 1
fprintf(nfile,'\n\nobjref q10\nq10 = new Temperature()\n' ) ;
fprintf(nfile,'io = q10.correct(%g)\n\n',neuron{refPar}.params.celsius) ;
else
fprintf(nfile,'celsius = %g\n\n',neuron{refPar}.params.celsius) ;
end
end
if spines_flag(n)
fprintf(nfile,'addsurf_spines()\n');
end
fprintf(nfile,'tstart = %f\n',neuron{refPar}.params.tstart); %set tstart
fprintf(nfile,'tstop = %f + %f //advances one more step due to roundoff errors for high tstops\n',neuron{refPar}.params.tstop,neuron{refPar}.params.dt); %set tstop
fprintf(nfile,'dt = %f\n',neuron{refPar}.params.dt); % set dt
fprintf(nfile,'steps_per_ms = %f\n',1/neuron{refPar}.params.dt); % set steps per ms to avois changing dt on reinit
if isfield(neuron{refPar}.params,'v_init')
fprintf(nfile,'v_init = %f\n',neuron{refPar}.params.v_init);
end
fprintf(nfile,'prerun = %d\n',neuron{refPar}.params.prerun);
if numel(access) > 1 % if there is any non-artificial cell defined
if neuron{refPar}.params.parallel
fprintf(nfile,'if (pc.gid_exists(%d)) {\naccess cellList.o(%d).allregobj.o(%d).sec\n}\n',access(1)-1,access(1)-1,minterf{neuron{n}.tree(access(1))}(access(2),2));
else
fprintf(nfile,'access cellList.o(%d).allregobj.o(%d).sec\n',access(1)-1,minterf{neuron{n}.tree(access(1))}(access(2),2));
end
end
fprintf(nfile,'\n\n');
fprintf(nfile,'// ***** Include prerun or standard run replacing custom code *****\n');
if ~isnan(refCust) && ~isempty(neuron{refCust}.custom)
for c = 1:size(neuron{refCust}.custom,1)
if strcmpi(neuron{refCust}.custom{c,2},'mid')
if strcmp(neuron{refCust}.custom{c,1}(end-4:end),'.hoc') %check for hoc ending
if exist(fullfile(modelFolder,'lib_custom',neuron{refCust}.custom{c,1}),'file')
fprintf(nfile,'io = load_file("../../lib_custom/%s")\n',neuron{refCust}.custom{c,1});
else
fprintf('File "%s" does not exist',neuron{refCust}.custom{c,1})
end
else
fprintf(nfile,neuron{refCust}.custom{c,1}); % add string as custom neuron code
end
end
end
end
if neuron{refPar}.params.parallel
% fprintf(nfile,'pc.barrier()\n');
end
fprintf(nfile,'\n\n');
fprintf(nfile,'// ***** Run NEURON *****\n');
if ~neuron{refPar}.params.skiprun
if neuron{refPar}.params.parallel
fprintf(nfile,'pc.set_maxstep(%g)\nstdinit()\npc.psolve(tstop)\n',mindelay); %!%!%!%! change this! neuron{n}.con...... %!%! also include prerun
else
fprintf(nfile,'init()\n'); % this needs to be modified later since v_init might be restarted
fprintf(nfile,'run()\n'); % directly run the simulation
end
else
fprintf(nfile,'// Run is skipped due to custom code\n');
end
fprintf(nfile,'\n\n');
fprintf(nfile,'io = xopen("save_rec.hoc")\n' );
fprintf(nfile,'\n\n');
fprintf(nfile,'// ***** Include finishing custom code *****\n');
if ~isnan(refCust) && ~isempty(neuron{refCust}.custom)
for c = 1:size(neuron{refCust}.custom,1)
if strcmpi(neuron{refCust}.custom{c,2},'end')
if strcmp(neuron{refCust}.custom{c,1}(end-4:end),'.hoc') %check for hoc ending
if exist(fullfile(modelFolder,'lib_custom',neuron{refCust}.custom{c,1}),'file')
fprintf(nfile,'io = load_file("../../lib_custom/%s")\n',neuron{refCust}.custom{c,1});
else
fprintf('File "%s" does not exist',neuron{refCust}.custom{c,1})
end
else
fprintf(nfile,neuron{refCust}.custom{c,1}); % add string as custom neuron code
end
end
end
end
fprintf(nfile,'\n\n');
fprintf(nfile,'// ***** Make Matlab notice end of simulation *****\n');
if neuron{refPar}.params.parallel
fprintf(nfile,'if (pc.id()==0){\n');
end
fprintf(nfile,'f = new File()\n'); %create a new filehandle
fprintf(nfile,'io = f.wopen("readyflag")\n' ); % create the readyflag file
fprintf(nfile,'io = f.close()\n'); % close the filehandle
if isempty(regexp(options,'-o','ONCE'))
fprintf(nfile,'quit()\n'); % exit NEURON if it was defined so in the parameters
end
if neuron{refPar}.params.parallel
fprintf(nfile,'}\n');
end
fprintf(nfile,'\n\n');
fprintf(nfile,'// *-*-*-*-* END *-*-*-*-*\n');
fclose(nfile);
%% write init_cells.hoc
if usestreesof(n) == n % write only if morphologies are not referenced to other sim init_cell.hoc
ofile = fopen(fullfile(modelFolder,exchfolder,thisfolder,'init_cells.hoc') ,'wt'); %open morph hoc file in write modus
fprintf(ofile,'\n\n');
fprintf(ofile,'// ***** Load cell morphology templates and create artificial cells *****\n');
templates = cell(0);
for tt = 1:numel(neuron{n}.tree)
% load templates generated by neuron_template_tree, create one
% instance of them and add them to the cellList
if ~any(strcmp(templates,tree{neuron{n}.tree(tt)}.NID))
fprintf(ofile,'io = xopen("../../%s/%s.hoc")\n','morphos/hocs',tree{neuron{n}.tree(tt)}.NID );
templates = cat(1,templates,tree{neuron{n}.tree(tt)}.NID);
end
if neuron{refPar}.params.parallel
fprintf(ofile,'if (pc.gid_exists(%d)) {\n',tt-1);
end
fprintf(ofile,'cell = new %s()\n', tree{neuron{n}.tree(tt)}.NID );
if isfield(tree{neuron{n}.tree(tt)},'artificial')
fields = fieldnames( tree{neuron{n}.tree(tt)});
fields = setdiff(fields,{'NID','artificial','col','name'}); % get all fields that are not "NID" or "artificial". These should be parameters to define
for f = 1:numel(fields)
if ischar(tree{neuron{n}.tree(tt)}.(fields{f})) && regexpi(tree{neuron{n}.tree(tt)}.(fields{f}),'^(.*)$') % check if this is a class/value pair, then use the () instead of =
fprintf(ofile, 'cell.cell.%s%s\n',fields{f}, tree{neuron{n}.tree(tt)}.(fields{f}));
else
fprintf(ofile, 'cell.cell.%s = %g\n',fields{f}, tree{neuron{n}.tree(tt)}.(fields{f}));
end
end
end
if neuron{refPar}.params.parallel
fprintf(ofile,'}else{cell = eObj}\n');
end
fprintf(ofile, 'io = cellList.append(cell)\n');
end
fprintf(ofile, 'objref cell\n');
fprintf(ofile,'\n\n');
fclose(ofile);
elseif exist(fullfile(modelFolder,exchfolder,thisfolder,'init_cells.hoc'),'file')
delete(fullfile(modelFolder,exchfolder,thisfolder,'init_cells.hoc'));
end
%% write init_mech.hoc
if t2n_getref(n,neuron,'mech') == n %rewrite only if mechanism is not taken from previous sim
rangestr = '';
ofile = fopen(fullfile(modelFolder,exchfolder,thisfolder,'init_mech.hoc') ,'wt'); %open morph hoc file in write modus
fprintf(ofile,'\n\n');
fprintf(ofile,'// ***** Insert mechanisms *****\n');
if isfield(neuron{n},'mech')
flag_strion_all = false(numel(neuron{n}.tree),1);
strion_all = cell(numel(neuron{n}.tree),1);
flag_strnseg_all = false(numel(neuron{n}.tree),1);
strnseg_all = cell(numel(neuron{n}.tree),1);
strion_reg = cell(numel(neuron{n}.tree),1);
flag_strion_reg = cell(numel(neuron{n}.tree),1);
strnseg_reg = cell(numel(neuron{n}.tree),1);
flag_strnseg_reg = cell(numel(neuron{n}.tree),1);
for tt = 1:numel(neuron{n}.tree)
t = neuron{n}.tree(tt);
if numel(neuron{n}.mech) >= t && ~isempty(neuron{n}.mech{t}) && ~isfield(tree{neuron{n}.tree(tt)},'artificial') % if a mechanism is defined for this tree
if isstruct(neuron{n}.mech{t}) % input must be a structure
fields = fieldnames(neuron{n}.mech{t});
else
continue
end
if neuron{refPar}.params.parallel
fprintf(ofile,'if (pc.gid_exists(%d)) {\n',tt-1);
end
if any(strcmpi(fields,'all'))
str = sprintf('forsec cellList.o(%d).allreg {\n',tt-1); %neuron:go through this region
strion_all{tt} = sprintf('forsec cellList.o(%d).allreg {\n',tt-1); %neuron:go through this region
strnseg_all{tt} = sprintf('forsec cellList.o(%d).allreg {\n',tt-1); %neuron:go through this region
mechs = fieldnames(neuron{n}.mech{t}.all); % mechanism names are the fieldnames in the structure
if any(strcmp(mechs,'nseg'))
mechs = setdiff(mechs,'nseg');
strnseg_all{tt} = sprintf('%snseg = %d\n',strnseg_all{tt},neuron{n}.mech{t}.all.nseg); %neuron: define values
flag_strnseg_all(tt) = true;
end
for m = 1:numel(mechs) % loop through mechanisms
str = sprintf('%sinsert %s\n',str,mechs{m}); % neuron:insert this mechanism
if ~isempty(neuron{n}.mech{t}.all.(mechs{m}))
mechpar = fieldnames(neuron{n}.mech{t}.all.(mechs{m}));
for p = 1:numel(mechpar) % loop through mechanism parameters
if strcmpi(mechpar{p},'cm') || strcmpi(mechpar{p},'Ra') || (~isempty(strfind(mechs{m},'_ion')) && (numel(mechpar{p}) <= strfind(mechs{m},'_ion') || (numel(mechpar{p}) > strfind(mechs{m},'_ion') && ~strcmp(mechpar{p}(strfind(mechs{m},'_ion')+1),'0')))) %if mechanism is an ion or passive cm/Ra, leave out mechansim suffix
if ~isempty(strfind(mechs{m},'_ion')) && strcmpi(mechpar{p},'style')
if numel(neuron{n}.mech{t}.all.(mechs{m}).(mechpar{p})) ~= 5
for nn = 1:numel(neuron)
delete(fullfile(modelFolder,exchfolder,sprintf('sim%d',nn),'iamrunning')); % delete the running mark
end
error('Error! Style specification of ion "%s" should be 5 numbers (see NEURON or t2n documentation)',mechs{m})
end
strion_all{tt} = sprintf('%sion_style("%s",%d,%d,%d,%d,%d)\n',strion_all{tt},mechs{m},neuron{n}.mech{t}.all.(mechs{m}).(mechpar{p})); %neuron: define values
flag_strion_all(tt) = true;
else
str = sprintf('%s%s = %g\n',str,mechpar{p},neuron{n}.mech{t}.all.(mechs{m}).(mechpar{p})); %neuron: define values
end
else
str = sprintf('%s%s_%s = %g\n',str,mechpar{p},mechs{m},neuron{n}.mech{t}.all.(mechs{m}).(mechpar{p})); %neuron: define values
end
end
end
end
fprintf(ofile,'%s}\n\n',str);
end
if isfield(tree{neuron{n}.tree(tt)},'R')
uR = unique(tree{neuron{n}.tree(tt)}.R); % Region indices that exist in tree
if ~isempty(intersect(tree{neuron{n}.tree(tt)}.rnames(uR),fields)) %isstruct(neuron{n}.mech{t}.(fields{1})) %check if mechanism was defined dependent on existent region
regs = fields; %if yes (some of) the input are the regions
regs = intersect(tree{neuron{n}.tree(tt)}.rnames(uR),regs); % only use those region names which are existent in tree
strion_reg{tt} = cell(numel(regs),1);
flag_strion_reg{tt} = false(numel(regs),1);
strnseg_reg{tt} = cell(numel(regs),1);
flag_strnseg_reg{tt} = false(numel(regs),1);
for r = 1 : numel(regs)
str = sprintf('forsec cellList.o(%d).reg%s {\n',tt-1,regs{r}); %neuron:go through this region
strnseg_reg{tt}{r} = sprintf('forsec cellList.o(%d).reg%s {\n',tt-1,regs{r}); %neuron:go through this region
mechs = fieldnames(neuron{n}.mech{t}.(regs{r})); % mechanism names are the fieldnames in the structure
if any(strcmp(mechs,'nseg'))
mechs = setdiff(mechs,'nseg');
strnseg_reg{tt}{r} = sprintf('%snseg = %d\n',strnseg_reg{tt}{r},neuron{n}.mech{t}.(regs{r}).nseg); %neuron: define values
flag_strnseg_reg{tt}(r) = true;
end
for m = 1:numel(mechs) % loop through mechanisms
str = sprintf('%sinsert %s\n',str,mechs{m}); % neuron:insert this mechanism
if ~isempty(neuron{n}.mech{t}.(regs{r}).(mechs{m}))
mechpar = fieldnames(neuron{n}.mech{t}.(regs{r}).(mechs{m}));
for p = 1:numel(mechpar) % loop through mechanism parameters
if strcmpi(mechpar{p},'cm') || strcmpi(mechpar{p},'Ra') || (~isempty(strfind(mechs{m},'_ion')) && (numel(mechpar{p}) <= strfind(mechs{m},'_ion') || (numel(mechpar{p}) > strfind(mechs{m},'_ion') && ~strcmp(mechpar{p}(strfind(mechs{m},'_ion')+1),'0')))) %if mechanism is an ion or passive cm/Ra, leave out mechansim suffix
if ~isempty(strfind(mechs{m},'_ion')) && strcmpi(mechpar{p},'style')
if numel(neuron{n}.mech{t}.all.(mechs{m}).(mechpar{p})) ~= 5
for nn = 1:numel(neuron)
delete(fullfile(modelFolder,exchfolder,sprintf('sim%d',nn),'iamrunning')); % delete the running mark
end
error('Error! Style specification of ion "%s" should be 5 numbers (see NEURON or t2n documentation)',mechs{m})
end
strion_reg{tt}{r} = sprintf('%sion_style("%s",%d,%d,%d,%d,%d)\n',strion_reg{tt}{r},mechs{m},neuron{n}.mech{t}.(regs{r}).(mechs{m}).(mechpar{p})); %neuron: define values
flag_strion_reg{tt}(r) = true;
else
str = sprintf('%s%s = %g\n',str,mechpar{p},neuron{n}.mech{t}.(regs{r}).(mechs{m}).(mechpar{p})); %neuron: define values
end
else
if numel(neuron{n}.mech{t}.(regs{r}).(mechs{m}).(mechpar{p})) == 1
str = sprintf('%s%s_%s = %g\n',str,mechpar{p},mechs{m},neuron{n}.mech{t}.(regs{r}).(mechs{m}).(mechpar{p})); %neuron: define values
else
for nn = 1:numel(neuron)
delete(fullfile(modelFolder,exchfolder,sprintf('sim%d',nn),'iamrunning')); % delete the running mark
end
error('Parameter %s of mechanism %s in region %s has more than one value, please check.',mechpar{p},mechs{m},regs{r})
end
end
end
end
end
fprintf(ofile,'%s}\n\n',str);
end
end
end
if any(strcmpi(fields,'range'))
if ~isfield(tree{neuron{n}.tree(tt)},'artificial')
[~, indSeg] = unique(minterf{neuron{n}.tree(tt)}(:,[2,4]),'rows','stable'); % find real segments in neuron simulation
indSeg = indSeg(~isnan(minterf{neuron{n}.tree(tt)}(indSeg,4))); % remove start nodes of a segment (cause their value belongs to segment -1)
indSeg(numel(indSeg)+1) = size(minterf{neuron{n}.tree(tt)},1)+1; % add one entry
if any(strcmp(fieldnames(neuron{n}.mech{t}.range),'pas')) && any(strcmp(fieldnames(neuron{n}.mech{t}.range.pas),'Ra'))
[~, indSec] = unique(minterf{neuron{n}.tree(tt)}(:,2),'stable'); % find real sections in neuron simulation
indSec = indSec + 1; % add 1 to not start at segment 0 of the section
indSec(numel(indSec)+1) = size(minterf{neuron{n}.tree(tt)},1)+1; % add one entry
end
mechs = fieldnames(neuron{n}.mech{t}.range);
for m = 1:numel(mechs)
vars = fieldnames(neuron{n}.mech{t}.range.(mechs{m}));
for r = 1:numel(vars)
if numel(neuron{n}.mech{t}.range.(mechs{m}).(vars{r})) == numel(tree{neuron{n}.tree(tt)}.X)
allvals = zeros(3,0);
if strcmp(vars{r},'Ra') && strcmp(mechs{m},'pas')
for in = 1:numel(indSec)-1
% the value of Ra is the mean of all
% tree nodes which are
% simulated by this section, if
% last node is a start of
% another section, subtract one
% index more
thisval = nanmean(neuron{n}.mech{t}.range.(mechs{m}).(vars{r})(minterf{neuron{n}.tree(tt)}(indSec(in),1):minterf{neuron{n}.tree(tt)}(indSec(in+1)-1-isnan(minterf{neuron{n}.tree(tt)}(indSec(in+1)-1,4)),1)));
if ~isnan(thisval)
allvals = cat(2,allvals,[minterf{neuron{n}.tree(tt)}(indSec(in),2),0.5,thisval]'); % value of 0.5 will not be used by genroutines but is necessary for syntax
end
end
else
for in = 1:numel(indSeg)-1
% the value is the mean of all
% tree nodes which are
% simulated by this segment, if
% last node is a start of
% another section, subtract one
% index more
thisval = nanmean(neuron{n}.mech{t}.range.(mechs{m}).(vars{r})(minterf{neuron{n}.tree(tt)}(indSeg(in),1):minterf{neuron{n}.tree(tt)}(indSeg(in+1)-1-isnan(minterf{neuron{n}.tree(tt)}(indSeg(in+1)-1,4)),1)));
if ~isnan(thisval)
allvals = cat(2,allvals,[minterf{neuron{n}.tree(tt)}(indSeg(in),[2,4]),thisval]');
end
end
end
secname = sprintf('range_%s_%s_%s_sec.dat',tree{neuron{n}.tree(tt)}.NID,vars{r},mechs{m});
f = fopen(fullfile(modelFolder,exchfolder,thisfolder,secname) ,'Wt');
fprintf(f,'%g\n',allvals(1,:));
fclose(f);
segname = sprintf('range_%s_%s_%s_seg.dat',tree{neuron{n}.tree(tt)}.NID,vars{r},mechs{m});
f = fopen(fullfile(modelFolder,exchfolder,thisfolder,segname) ,'Wt');
fprintf(f,'%g\n',allvals(2,:));
fclose(f);
valname = sprintf('range_%s_%s_%s_val.dat',tree{neuron{n}.tree(tt)}.NID,vars{r},mechs{m});
f = fopen(fullfile(modelFolder,exchfolder,thisfolder,valname) ,'Wt');
fprintf(f,'%g\n',allvals(3,:));
fclose(f);
if any(strcmp({'cm','Ra'},vars{r})) % if variable is cm or Ra, do not write _"mech" behind it
rangestr = sprintf('%sset_range(%d,"%s","%s","%s","%s")\n',rangestr,tt-1,secname,segname,valname,vars{r});
else
rangestr = sprintf('%sset_range(%d,"%s","%s","%s","%s_%s")\n',rangestr,tt-1,secname,segname,valname,vars{r},mechs{m});
end
else
for nn = 1:numel(neuron)
delete(fullfile(modelFolder,exchfolder,sprintf('sim%d',nn),'iamrunning')); % delete the running mark
end
error('Range variable definition should be a vector with same number of elements as tree has nodes')
end
end
end
else
for nn = 1:numel(neuron)
delete(fullfile(modelFolder,exchfolder,sprintf('sim%d',nn),'iamrunning')); % delete the running mark
end
error('Setting range variables for artificial cells is invalid')
end
end
if neuron{refPar}.params.parallel
fprintf(ofile,'}\n');
end
end
end
fprintf(ofile,'\n\n');
if any(cellfun(@any,flag_strion_reg)) || any(flag_strion_all)
fprintf(ofile,'// ***** Now add specific ion styles *****\n');
if any(flag_strion_all)
for tt = 1:numel(neuron{n}.tree)
if flag_strion_all(tt)
if neuron{refPar}.params.parallel
fprintf(ofile,'if (pc.gid_exists(%d)) {\n',tt-1);
end
fprintf(ofile,'%s}\n\n',strion_all{tt});
if neuron{refPar}.params.parallel
fprintf(ofile,'}\n');
end
end
end
end