function [charge_array_preinduc,charge_array_postinduc,meanpreindwave,meanpostindwave,special_waveform_matrix_preinduc,special_waveform_matrix_postinduc]=careful_charge_calculator(suffix,number_of_APs,...
    minutes_per_trial,num_samples_per_event,values_to_average_for_local_correction,activate_local_offset_correction,general_time_window_before,general_time_window_after,specific_time_window_before,specific_time_window_after,...
    patchtitle,casecolor,current_expt,general_figure_position,carefulcharge_interval_selection_method,first_waveform_only,success_waveforms_only,pulse_duration,...
    IPIs_fullepoch_preinduc,IPIs_fullepoch_postinduc,rawtraces_fullepoch_preinduc,rawtraces_fullepoch_postinduc,critlogical_fullepoch_preinduc,critlogical_fullepoch_postinduc,...
    numtrials_fullepoch_preinduc,numtrials_fullepoch_postinduc,ensure_equal_lengths,tooshorttomeasurenames)
%calculates the mean charge transferred over all PSCs or just PSCo over a portion of the pre and postsynaptic epochs.  5 ways of picking said portion are available.
%carefulcharge_interval_selection_method 1 is use all pre and postinduction trials, 2 is use the general continuous window used for all cases, 3 is use the specific continuous window, 4 is use the specific discrete window, 5 is find the maximal window from all trials
%for picking these portions, careful_charge_calculator in principle needs access to all the time windows, so they are recreated here
%called by: analyze_across_sd_stdp_expts
%calls: careful_charge_calculator_core, find_greatest_n_consecutive_vals, iterative_curve_fit, lsqfit_template_generator, poor_mans_waterfall
%code confirmed date:

num_consec_trials_for_best_window=10;  %applies if carefulcharge_interval_selection_method==5; see below
generate_fits=0;
plot_mean_waveforms=1;
plot_individual_waveforms=0;
show_all_raw=0;
    show_trace_number=0;

samples_per_ms=10;samples_per_second=10000;
added_samples_for_clearance=7;
starting_row_for_measurement=200+(pulse_duration*samples_per_ms)+added_samples_for_clearance;  %raw is generally saved s.t. the first AP is at the 202th sample (two samples of metadata having been added at the beginning)
startingrow_foroffsetcorrection=1;
endingrow_foroffsetcorrection=180; %correction using baseline recorded before the first AP
windowing_style_labels={'all trials' 'standard windows' 'expt-spec continuous windows' 'expt-spec discrete windows' 'maximal windows'};

%num_samples_per_event is now set for each expt in the database
% if find(IPIarray_fullepoch_prepostinduc(1,:)==12.5)
%     num_samples_per_event=110;    %using 200 for display of waveforms and 110 for charge measurements
% elseif find(IPIarray_fullepoch_prepostinduc(1,:)==25)
%     num_samples_per_event=150;  %using 200 for display of waveforms and 150 for charge measurements
% else
%     num_samples_per_event=160;  %using 200 for display of waveforms and 160 for charge measurements
% end
if strfind(suffix,'to'),num_samples_per_event=55,end%very short window for the short-latency release sites in the dual site expts

if number_of_APs==4,
    IPIs_fullepoch_preinduc=[IPIs_fullepoch_preinduc;repmat(50,1,size(IPIs_fullepoch_preinduc,2))];
    IPIs_fullepoch_postinduc=[IPIs_fullepoch_postinduc;repmat(50,1,size(IPIs_fullepoch_postinduc,2))];
end
if number_of_APs==3,chekro=1;elseif number_of_APs==4,chekro=2;end
if any(~rawtraces_fullepoch_preinduc(chekro,:)==IPIs_fullepoch_preinduc(chekro,:)),error('file misalignment?'),end
if any(~rawtraces_fullepoch_postinduc(chekro,:)==IPIs_fullepoch_postinduc(chekro,:)),error('file misalignment?'),end
rawtraces_fullepoch_preinduc=rawtraces_fullepoch_preinduc(3:end,:);
rawtraces_fullepoch_postinduc=rawtraces_fullepoch_postinduc(3:end,:);
localbaselines_pre=mean(rawtraces_fullepoch_preinduc(startingrow_foroffsetcorrection:endingrow_foroffsetcorrection,:)); 
rawtraces_fullepoch_preinduc=rawtraces_fullepoch_preinduc-repmat(localbaselines_pre,size(rawtraces_fullepoch_preinduc,1),1);
localbaselines_post=mean(rawtraces_fullepoch_postinduc(startingrow_foroffsetcorrection:endingrow_foroffsetcorrection,:)); 
rawtraces_fullepoch_postinduc=rawtraces_fullepoch_postinduc-repmat(localbaselines_post,size(rawtraces_fullepoch_postinduc,1),1);

%determining which trials to evaluate.  trial numbering is within-epoch (i.e., the first postinduction trial is '1')
if find(carefulcharge_interval_selection_method==[1 5])
    livetrials_preinduc_alltrials=[1:numtrials_fullepoch_preinduc];
    livetrials_postinduc_alltrials=[1:numtrials_fullepoch_postinduc];
    beflive=livetrials_preinduc_alltrials;
    aflive=livetrials_postinduc_alltrials;
elseif carefulcharge_interval_selection_method==2
    general_trials_window_before=round(inv(minutes_per_trial)*general_time_window_before);
    general_trials_window_before=[general_trials_window_before(1):general_trials_window_before(2)];
    livetrials_preinduc_generalwindow=numtrials_fullepoch_preinduc+general_trials_window_before;
    if livetrials_preinduc_generalwindow(1)<1,disp(strcat('Insufficient preinduction expt duration to measure ', patchtitle));tooshorttomeasurenames=[tooshorttomeasurenames,patchtitle];return,end
    general_trials_window_after=round(inv(minutes_per_trial)*general_time_window_after);
    livetrials_postinduc_generalwindow=[general_trials_window_after(1):general_trials_window_after(2)];
    if livetrials_postinduc_generalwindow(end)>numtrials_fullepoch_postinduc,disp(strcat('Insufficent postinduction expt duration to measure ',patchtitle));tooshorttomeasurenames=[tooshorttomeasurenames,patchtitle];return,end
    %equalize lengths if needed -- only applicable to general windows
    if ensure_equal_lengths &&(length(livetrials_preinduc_generalwindow)~=length(livetrials_postinduc_generalwindow))
        beflengen=length(livetrials_preinduc_generalwindow);aflengen=length(livetrials_postinduc_generalwindow);
        holddgen=[beflengen aflengen];
        livetrials_preinduc_generalwindow=livetrials_preinduc_generalwindow(end-(holddgen((beflengen>aflengen)+1)-1):end)
        livetrials_postinduc_generalwindow=livetrials_postinduc_generalwindow(1:holddgen((beflengen>aflengen)+1))
    end
    beflive=livetrials_preinduc_generalwindow;
    aflive=livetrials_postinduc_generalwindow;     
elseif find(carefulcharge_interval_selection_method==[3 4])
    specific_trials_window_before=round(inv(minutes_per_trial)*specific_time_window_before);
    specific_trials_window_before=[specific_trials_window_before(1):specific_trials_window_before(2)];
    livetrials_preinduc_specificwindow=numtrials_fullepoch_preinduc+specific_trials_window_before;
    beflive=livetrials_preinduc_specificwindow;
    specific_trials_window_after=round(inv(minutes_per_trial)*specific_time_window_after);
    if carefulcharge_interval_selection_method==3
        livetrials_postinduc_contigspecificwindow=[1:specific_trials_window_after(2)];
        aflive=livetrials_postinduc_contigspecificwindow;
    elseif carefulcharge_interval_selection_method==4
        livetrials_postinduc_discretespecificwindow=[specific_trials_window_after(1):specific_trials_window_after(2)];
        aflive=livetrials_postinduc_discretespecificwindow;
    end
end

[charge_array_preinduc,waveform_matrix_preinduc,special_waveform_matrix_preinduc]=careful_charge_calculator_core(rawtraces_fullepoch_preinduc,critlogical_fullepoch_preinduc,beflive,first_waveform_only,success_waveforms_only,...
    number_of_APs,IPIs_fullepoch_preinduc,starting_row_for_measurement,activate_local_offset_correction,values_to_average_for_local_correction,num_samples_per_event,samples_per_ms,samples_per_second);

[charge_array_postinduc, waveform_matrix_postinduc,special_waveform_matrix_postinduc]=careful_charge_calculator_core(rawtraces_fullepoch_postinduc,critlogical_fullepoch_postinduc,aflive,first_waveform_only,success_waveforms_only,...
    number_of_APs,IPIs_fullepoch_postinduc,starting_row_for_measurement,activate_local_offset_correction,values_to_average_for_local_correction,num_samples_per_event,samples_per_ms,samples_per_second);

if carefulcharge_interval_selection_method==5 %uses the total charge each trial over the whole of each epoch to see which num_consec_trials_for_best_window trials have the greatest net charge
    if ~first_waveform_only,sum_charge_array_preinduc=sum(charge_array_preinduc);sum_charge_array_postinduc=sum(charge_array_postinduc);
    else sum_charge_array_preinduc=charge_array_preinduc;sum_charge_array_postinduc=charge_array_postinduc;
    end
    
    bestpreinducstartspot=find_greatest_n_consecutive_vals(num_consec_trials_for_best_window,sum_charge_array_preinduc);
    [charge_array_preinduc, waveform_matrix_preinduc,special_waveform_matrix_preinduc]=careful_charge_calculator_core(rawtraces_fullepoch_preinduc,critlogical_fullepoch_preinduc,((bestpreinducstartspot-1)+[1:num_consec_trials_for_best_window]),...
        first_waveform_only,success_waveforms_only,number_of_APs,IPIs_fullepoch_preinduc,starting_row_for_measurement,activate_local_offset_correction,values_to_average_for_local_correction,num_samples_per_event,samples_per_ms,samples_per_second);
    
    bestpostinducstartspot=find_greatest_n_consecutive_vals(num_consec_trials_for_best_window,sum_charge_array_postinduc);
    [charge_array_postinduc, waveform_matrix_postinduc,special_waveform_matrix_postinduc]=careful_charge_calculator_core(rawtraces_fullepoch_postinduc,critlogical_fullepoch_postinduc,(((bestpostinducstartspot-1)+size(preinduction_raw,2))+[1:num_consec_trials_for_best_window]),...
        first_waveform_only,success_waveforms_only,number_of_APs,IPIs_fullepoch_postinduc,starting_row_for_measurement,activate_local_offset_correction,values_to_average_for_local_correction,num_samples_per_event,samples_per_ms,samples_per_second);
    
    charge_ratio=sum(sum(charge_array_postinduc))/sum(sum(charge_array_preinduc))
else
    bestpreinducstartspot=nan;bestpostinducstartspot=nan;
end

if show_all_raw     %used in looking at all raw waveforms, generally for checking all waveforms manually
	figure%(current_expt+200)
	downsamplestep=10;
	for i=1:size(waveform_matrix_preinduc,1),plot(waveform_matrix_preinduc(i,:),'k+:','markersize',1),hold on, end
	for j=1:size(waveform_matrix_postinduc,1),plot(waveform_matrix_postinduc(j,:),'r+:','markersize',1),end
    if show_trace_number
		for k=1:size(waveform_matrix_preinduc,1)
            current_sweep_preinduc=waveform_matrix_preinduc(k,:);
            text([1:downsamplestep:size(waveform_matrix_preinduc,2)],current_sweep_preinduc([1:downsamplestep:size(waveform_matrix_preinduc,2)]),num2str(((k-1)+number_of_APs)/number_of_APs),'fontsize',12,'color','k'),hold on,end
		for m=1:size(waveform_matrix_postinduc,1)
            current_sweep_postinduc=waveform_matrix_postinduc(m,:);
            text([1:downsamplestep:size(waveform_matrix_postinduc,2)],current_sweep_postinduc([1:downsamplestep:size(waveform_matrix_postinduc,2)]),num2str(((m-1)+number_of_APs)/number_of_APs),'fontsize',12,'color','r'),hold on,end
	end
    title(patchtitle)
end

if ~isempty(waveform_matrix_preinduc),meanpreindwave=mean(waveform_matrix_preinduc);else meanpreindwave=repmat(nan,1,num_samples_per_event);end
if ~isempty(waveform_matrix_postinduc),meanpostindwave=mean(waveform_matrix_postinduc);else meanpostindwave=repmat(nan,1,num_samples_per_event);end

if plot_mean_waveforms
	figure(current_expt+100),set(gcf,'position',general_figure_position)
	subplot('position',[.05+(first_waveform_only/2)+(success_waveforms_only/4) (carefulcharge_interval_selection_method*.125)+.175 .15 .1])
	set(gca,'xticklabel',[])
	set(gcf,'paperorientation','landscape')
	set(gcf,'paperposition',[.2 .2 10 7.5])
	if generate_fits
        template_preindwave_forplotting=iterative_curve_fit(meanpreindwave');
        template_preindwave_formeasuring=lsqfit_template_generator([template_preindwave_forplotting(end-10:end-7) 0 0],1:length(meanpreindwave)); %eliminating latency and y-offset for measuring
        %template_preindwave_formeasuring=[0 0 0 0 0 template_preindwave_formeasuring];
        template_preindwave_forplotting=template_preindwave_forplotting(1:end-11);
        template_postindwave_forplotting=iterative_curve_fit(meanpostindwave');
        template_postindwave_formeasuring=lsqfit_template_generator([template_postindwave_forplotting(end-10:end-7) 0 0],1:length(meanpostindwave));
        %template_postindwave_formeasuring=[0 0 0 0 0 template_postindwave_formeasuring];
        template_postindwave_forplotting=template_postindwave_forplotting(1:end-11);
		hold on,plot(meanpreindwave,'k','linewidth',2),plot(template_preindwave_forplotting,'k','linewidth',.1),plot(meanpostindwave,'r','linewidth',2),plot(template_postindwave_forplotting,'r','linewidth',.1)
		averaged_info=strcat('averaged pre:',num2str(sum(meanpreindwave)),',','averaged post:',num2str(sum(meanpostindwave)));
		fitted_info=strcat('fitted pre:',num2str(sum(template_preindwave_formeasuring)),',','fitted post:',num2str(sum(template_postindwave_formeasuring)));
		length_diff=length(averaged_info)-length(fitted_info);
		if length_diff>0,fitted_info=strcat(fitted_info,repmat('.',1,length_diff));
		elseif length_diff<0,averaged_info=strcat(averaged_info,repmat('.',1,-1*length_diff));
		end
		title([averaged_info;fitted_info])  
	else
		hold on,plot(meanpreindwave,'k','linewidth',1.5),plot(meanpostindwave,'r','linewidth',1.5)
		averaged_info=strcat('averaged pre:',num2str(sum(meanpreindwave)),',','averaged post:',num2str(sum(meanpostindwave)));
        title(averaged_info)
	end
    if ~first_waveform_only && ~success_waveforms_only,ylabel(windowing_style_labels{carefulcharge_interval_selection_method}),end
    if carefulcharge_interval_selection_method==5,legend(num2str(bestpreinducstartspot),num2str(bestpostinducstartspot)),end
end

%waterfall plots of PSCb/c, whichever is last, and PSCo
%first_waveform_only and success_waveforms_only should both be 0 for the waterfall plots to work as intended
if plot_individual_waveforms
	zlim_trough=min([min(min(waveform_matrix_preinduc')) min(min(waveform_matrix_postinduc'))]);
	for before_or_after=1:2
        for firstPSC_or_lastPSC=1:2
            if before_or_after==1 && firstPSC_or_lastPSC==1, data_array=waveform_matrix_preinduc(1:number_of_APs:end,:);figure_addon=200;title_string='Preinduction PSCo';
            elseif before_or_after==1 && firstPSC_or_lastPSC==2, data_array=waveform_matrix_preinduc(number_of_APs:number_of_APs:end,:);figure_addon=400;title_string='Preinduction PSCend';
            elseif before_or_after==2 && firstPSC_or_lastPSC==1, data_array=waveform_matrix_postinduc(1:number_of_APs:end,:);figure_addon=300;title_string='Postinduction PSCo';
            elseif before_or_after==2 && firstPSC_or_lastPSC==2, data_array=waveform_matrix_postinduc(number_of_APs:number_of_APs:end,:);figure_addon=500;title_string='Postinduction PSCend';
            end
			poor_mans_waterfall(data_array',current_expt,figure_addon,title_string,zlim_trough,[1:size(data_array,1)]',minutes_per_trial)
        end
	end
end