#!/usr/bin/perl -w

# Aim: determine how to detect when knock happens
# Suggested methods:
#   1)  knock_val / noise_val > k_1
#   2)  knock_val - noise_val > k_2

#   3) (knock_val > noise_val * k_1) && (knock_val - noise_val > k_2)

my $logfile = $ARGV[0];
open(DATA, "<$logfile") or die "can't open $logfile";

$file="fknock_log";
open(LOG, ">$file") or die "can't open $file";


$ignchmax=3;

for (my $i=0; $i<=$ignchmax; $i++) {
    $hist_igncount{$i}=0;
}

#print "adv\t rpm\t kpa \t knock_val\t noise_val\t kdiff\t kratio\n";

while($l = <DATA>) {
    if ($l =~ /^k=(.{15})/g) {
	my @buf = split //, $1;

#	    foreach $j (@buf) {
#		printf("%02x ", ord($j));
#	    }
#	    print "\n";

	$igncount = ord($buf[0]);
	if ($igncount > 3) { next; }

	$ignadv = sprintf("%0.2f", ord($buf[1]) / 4);

	$rpm = 256*ord($buf[2]) + ord($buf[3]);
	if ($rpm > 6000) { next; }
	    
	$kpa = (256*ord($buf[4]) + ord($buf[5])) / 4;
	if ($kpa > 6000) { next; }

	# the byte order of knock_cyl_t is reversed
	$knock_val = 256*ord($buf[7]) + ord($buf[6]);
	if ($knock_val > 1024) { next; }

	$noise_val = 256*ord($buf[9]) + ord($buf[8]);
	if ($noise_val > 1024) { next; }

	$knock_adjust = ord($buf[10]);

	$kdiff = $knock_val - $noise_val;
	$kratio = sprintf("%0.3f", $knock_val / $noise_val);

	print LOG "i=$igncount\t a=$ignadv\t r=$rpm\t m=$kpa \t kv=$knock_val\t nv=$noise_val\t kd=$kdiff\t kr=$kratio\t ka=$knock_adjust\t";
# these three constants are the ones to be determined:
	if ($kratio > 1.3 && $kdiff > 20 || $kdiff > 60) {
	    print LOG "\t KNOCK\n";

	    # count the number of time cylinder N knocked
	    if (defined($hist_igncount{$igncount})) {
		$hist_igncount{$igncount}++;
	    } else {
		$hist_igncount{$igncount}=1;
	    }

	    # used for 3d plot
	    push @{ $map_stat[$igncount] }, "$rpm\t$kpa\t$ignadv\n";

	} else {
	    print LOG "\n";
	}


	if ($kdiff >= 0) {
	    if (defined($hist_diff[$igncount]{$kdiff})) {
		$hist_diff[$igncount]{$kdiff}++;
	    } else {
		$hist_diff[$igncount]{$kdiff}=1;
	    }
	}

	$kr = sprintf("%0.2f", $knock_val / $noise_val);
	if (defined($hist_ratio[$igncount]{$kr})) {
	    $hist_ratio[$igncount]{$kr}++;
	} else {
	    $hist_ratio[$igncount]{$kr}=1;
	}
    }
}

$file="fknock_hist_diff";
open(DHISTOUT, ">$file") or die "can't open $file";

for (my $i=0; $i<=$ignchmax; $i++) {
    print DHISTOUT "# igncount=$i\n";
    foreach $k (sort {$a<=>$b} keys %{$hist_diff[$i]}) {
	print DHISTOUT "$k\t$hist_diff[$i]{$k}\n";
    }
    print DHISTOUT "\n\n";
}
close DHISTOUT;

$file="fknock_hist_ratio";
open(RHISTOUT, ">$file") or die "can't open $file";

for (my $i=0; $i<=$ignchmax; $i++) {
    print RHISTOUT "# igncount=$i\n";
    foreach $k (sort {$a<=>$b} keys %{$hist_ratio[$i]}) {
	print RHISTOUT "$k\t$hist_ratio[$i]{$k}\n";
    }
    print RHISTOUT "\n\n";
}
close RHISTOUT;

for (my $i=0; $i<=$ignchmax; $i++) {
    $file="fknock_3d_map" . $i;
    open(MAP, ">$file") or die "can't open $file";

    print MAP "# igncount=$i\n";
    foreach $k ( @{ $map_stat[$i] }) {
	print MAP $k;
    }
    print MAP "\n\n";
    close MAP;
}


print "knock statistics:\n";
foreach $k (sort {$a<=>$b} keys %hist_igncount) {
    print "igncount=$k:\t$hist_igncount{$k}\n";
}
