// File: /workspace/github_c_makefile_star2_O2/stonezwr[P]SpiKL-IP/neuron.C
// Function: Neuron::LSMNextTimeStep(int, _IO_FILE*, bool, int)
void Neuron::LSMNextTimeStep(int t, FILE * Foutp, bool train, int end_time){

    if(_mode == DEACTIVATED) return;
    if(_mode == READCHANNEL ){
        if(_mode != READCHANNEL){
            // if training the input-reservoir/reservoir-readout synapses, need to keep track the cal!
            _lsm_v_mem_pre = _lsm_v_mem;
            _lsm_calcium_pre = _lsm_calcium;
            _lsm_calcium -= _lsm_calcium/TAU_C;
        }
        if(_t_next_spike == -1) return;
        if(t < _t_next_spike) return;
        if(_mode != READCHANNEL){
            _lsm_calcium += one;
        }

        /** Hand the firing behavior here for both input neurons and reservoir neurons */
        /** @param1: is the neuron only used to output spike? **/
        HandleFiringActivity(true, t, train);
        _fired = true;

        _t_next_spike = _lsm_channel->NextSpikeT();
        if(_t_next_spike == -1) {
            _network->LSMChannelDecrement(_lsm_channel->Mode()); 
        }
        return;
    }
    

    // the following code is to simulate the mode of NORMAL, WRITECHANNEL, and STDP
    _lsm_v_mem_pre = _lsm_v_mem;
    _lsm_calcium_pre = _lsm_calcium;
    _lsm_calcium -= _lsm_calcium/TAU_C;

    if((_teacherSignal==1)&&(_lsm_calcium < LSM_CAL_MID+1)){
        _lsm_v_mem += 20;
    }else if((_teacherSignal==-1)&&(_lsm_calcium > LSM_CAL_MID-1)){
        _lsm_v_mem -= 15*0.75;
    }

    list<Synapse*>::iterator iter;

    int pos;
    double value;
	if(_name[0]=='r')
		ExpDecay(_lsm_v_mem, _lsm_t_m_c);
	else
		ExpDecay(_lsm_v_mem, LSM_T_M_C);
    ExpDecay(_lsm_state_EP, _lsm_tau_EP);
    ExpDecay(_lsm_state_EN, _lsm_tau_EN);
    ExpDecay(_lsm_state_IP, _lsm_tau_IP);
    ExpDecay(_lsm_state_IN, _lsm_tau_IN);

    // sum up the effect
    _lsm_state_EP += _prev_delta_ep;
    _lsm_state_EN += _prev_delta_en;
    _lsm_state_IP += _prev_delta_ip;
    _lsm_state_IN += _prev_delta_in;

    double temp = NOrderSynapticResponse();
    _lsm_v_mem += _lsm_R*temp/_lsm_t_m_c;
	_lsm_input=temp;
	if(temp>0){
		_fire_start=true;
	}

    if(_lsm_ref > 0){
        _lsm_ref--;
        _lsm_v_mem = LSM_V_REST;
        _fired = false;
        return;
    }

    _fired = false;

    if(_lsm_v_mem > _lsm_v_thresh){
        _lsm_calcium += one;

        // 1. handle the _outputSyns after the neuron fires and activate the _outputSyns
        // 2. keep track of the t_spike_pre for the corresponding syns
        // 3. @para1: whether or not the current neuron is only used as a dummy input
        HandleFiringActivity(false, t, train);
        _fired = true;

        _lsm_v_mem = LSM_V_RESET;

		_lsm_ref = LSM_T_REFRAC;

        if(_name[0] == 'o' || _name[0] == 'h'){
            _f_count ++;
            assert(t > (_fire_timings.empty() ? -1 : _fire_timings.back()));
            _fire_timings.push_back(t);
        }
		else
			_f_count++;

        if(_mode == WRITECHANNEL&&_generate_transient){
            if(_lsm_channel == NULL){
                cout<<"Failure to assign a channel ptr to the neuron: "<<_name<<endl;
                assert(_lsm_channel);
            }
            _lsm_channel->AddSpike(t);
        }

    }
#ifdef SPIKL_IP
    if(_SpiKL_ip && _network->LSMGetNetworkMode()==TRANSIENTSTATE)  
        SpiKL_IP(t);
#endif
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x10, %rsp
movl %esi, 0xc(%rsp)
movl 0x8(%rdi), %eax
testl %eax, %eax
je 0x62dd
movl %ecx, %r14d
movl %esi, %ebp
movq %rdi, %rbx
cmpl $0x1, %eax
jne 0x603c
movl 0x218(%rbx), %eax
cmpl $-0x1, %eax
sete %cl
cmpl %ebp, %eax
setg %al
orb %cl, %al
jne 0x62dd
movzbl %r14b, %ecx
pushq $0x1
popq %rsi
movq %rbx, %rdi
movl %ebp, %edx
callq 0x8bbe
movb $0x1, 0x130(%rbx)
movq 0x210(%rbx), %rdi
callq 0x39c0
movl %eax, 0x218(%rbx)
cmpl $-0x1, %eax
jne 0x62dd
movq 0x120(%rbx), %rdi
movq 0x210(%rbx), %rax
movl 0x44(%rax), %esi
addq $0x10, %rsp
popq %rbx
popq %r14
popq %rbp
jmp 0xe752
movsd 0x168(%rbx), %xmm0
movsd %xmm0, 0x170(%rbx)
movsd 0x178(%rbx), %xmm2
movsd %xmm2, 0x180(%rbx)
movsd 0xe604(%rip), %xmm1     # 0x14668
mulsd %xmm2, %xmm1
addsd %xmm2, %xmm1
movsd %xmm1, 0x178(%rbx)
movl 0x114(%rbx), %eax
cmpl $0x1, %eax
jne 0x6097
movsd 0xe5f1(%rip), %xmm2     # 0x14678
ucomisd %xmm1, %xmm2
jbe 0x6097
movsd 0xe5db(%rip), %xmm1     # 0x14670
jmp 0x60ae
cmpl $-0x1, %eax
jne 0x60ba
ucomisd 0xe5e4(%rip), %xmm1     # 0x14688
jbe 0x60ba
movsd 0xe5d2(%rip), %xmm1     # 0x14680
addsd %xmm1, %xmm0
movsd %xmm0, 0x168(%rbx)
movq 0x10(%rbx), %rax
cmpb $0x72, (%rax)
je 0x60d1
movsd 0xe5c5(%rip), %xmm1     # 0x14690
mulsd %xmm0, %xmm1
jmp 0x60dd
movapd %xmm0, %xmm1
divsd 0x1f0(%rbx), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x168(%rbx)
movupd 0x1a8(%rbx), %xmm0
movupd 0x188(%rbx), %xmm1
movapd %xmm1, %xmm2
divpd %xmm0, %xmm2
subpd %xmm2, %xmm1
movupd 0xd0(%rbx), %xmm0
addpd %xmm1, %xmm0
movupd %xmm0, 0x188(%rbx)
movupd 0x1b8(%rbx), %xmm0
movupd 0x198(%rbx), %xmm1
movapd %xmm1, %xmm2
divpd %xmm0, %xmm2
subpd %xmm2, %xmm1
movupd 0xe0(%rbx), %xmm0
addpd %xmm1, %xmm0
movupd %xmm0, 0x198(%rbx)
movq %rbx, %rdi
callq 0x8c4a
movsd 0x1d8(%rbx), %xmm1
mulsd %xmm0, %xmm1
divsd 0x1f0(%rbx), %xmm1
addsd 0x168(%rbx), %xmm1
movsd %xmm1, 0x168(%rbx)
movsd %xmm0, 0x1f8(%rbx)
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm0
jbe 0x618e
movb $0x1, 0x1e8(%rbx)
movl 0x208(%rbx), %eax
testl %eax, %eax
jle 0x61b4
decl %eax
movl %eax, 0x208(%rbx)
andq $0x0, 0x168(%rbx)
movb $0x0, 0x130(%rbx)
jmp 0x62dd
movb $0x0, 0x130(%rbx)
ucomisd 0x1d0(%rbx), %xmm1
jbe 0x62bc
movsd 0x178(%rbx), %xmm0
addsd 0xe4bf(%rip), %xmm0     # 0x14698
movsd %xmm0, 0x178(%rbx)
movzbl %r14b, %ecx
movq %rbx, %rdi
xorl %esi, %esi
movl %ebp, %edx
callq 0x8bbe
movb $0x1, 0x130(%rbx)
andq $0x0, 0x168(%rbx)
movl $0x2, 0x208(%rbx)
movq 0x10(%rbx), %rax
movzbl (%rax), %eax
cmpl $0x6f, %eax
je 0x621b
cmpl $0x68, %eax
jne 0x6236
incl 0x12c(%rbx)
movq 0x90(%rbx), %rax
cmpq %rax, 0x88(%rbx)
je 0x623e
movl -0x4(%rax), %eax
jmp 0x6241
incl 0x12c(%rbx)
jmp 0x625a
pushq $-0x1
popq %rax
cmpl %ebp, %eax
jge 0x62e6
leaq 0x88(%rbx), %rdi
leaq 0xc(%rsp), %rsi
callq 0x3d58
cmpl $0x2, 0x8(%rbx)
jne 0x62bc
movsd 0x200(%rbx), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x6274
jnp 0x62bc
movq 0x210(%rbx), %rdi
testq %rdi, %rdi
jne 0x62b3
movq 0x19d41(%rip), %rdi     # 0x1ffc8
leaq 0xe521(%rip), %rsi      # 0x147af
callq 0x32a0
movq 0x10(%rbx), %rsi
movq %rax, %rdi
callq 0x32a0
movq %rax, %rdi
callq 0x3160
movq 0x210(%rbx), %rdi
testq %rdi, %rdi
je 0x6305
movl 0xc(%rsp), %esi
callq 0x38ea
cmpb $0x1, 0x140(%rbx)
jne 0x62dd
movq 0x120(%rbx), %rax
cmpl $0x0, 0x2c0(%rax)
jne 0x62dd
movq %rbx, %rdi
callq 0x6324
addq $0x10, %rsp
popq %rbx
popq %r14
popq %rbp
retq
leaq 0xe444(%rip), %rdi      # 0x14731
leaq 0xe475(%rip), %rsi      # 0x14769
leaq 0xe477(%rip), %rcx      # 0x14772
movl $0x18e, %edx            # imm = 0x18E
callq 0x31b0
leaq 0xe4d3(%rip), %rdi      # 0x147df
leaq 0xe456(%rip), %rsi      # 0x14769
leaq 0xe458(%rip), %rcx      # 0x14772
movl $0x197, %edx            # imm = 0x197
callq 0x31b0