From: Maps Date: Thu, 12 Dec 2024 10:25:21 +0000 (+0100) Subject: Work on analysis.cxx X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=a271c52808e2b1d469ea1db15409aaef44e71da5;p=mimosis_chain.git Work on analysis.cxx --- diff --git a/scripts/Mimosis.pm b/scripts/Mimosis.pm deleted file mode 100755 index 2ee3f04..0000000 --- a/scripts/Mimosis.pm +++ /dev/null @@ -1,1675 +0,0 @@ -package Mimosis; - -use warnings; -use strict; -no warnings "portable"; -use HADES::TrbNet; -use Time::HiRes qw(usleep); -use Time::HiRes qw( time ); -use Term::ANSIColor; -use Data::Dump qw(dump); -use POSIX; - - -my $adc_addr = 0x48; -my $adc_wreg = 0x1; -my $adc_cmdV = 0xa380; -my $adc_cmdI = 0x9380; -my $adc_rreg = 0x0; -my $adcConv = ( 2 * 4096 ) / 2**16; - -my $chipid = 0x1; -my $transport = "I2C"; - - - -sub make_require { - do "/d/jspc37/mimosis/scripts/TrbNetUart.pm"; - TNU_set_device("/dev/ttyUSB0"); -} - - - -sub set_chipid { - - my ($cid) = @_; - - if ( $cid >= 0 && - $cid <= 3 ) { - $chipid = $cid; - - } else { - - print "Mimosis::set_chipid(): input not between 0 and 7. Exiting.\n"; - exit 1; - } -} - - -sub get_chipid { - - return $chipid; -} - - - -sub set_transport { - my ( $trans ) = @_; - $transport = $trans; -} - -sub get_transport { - - return $transport; -} - - - - -sub adc_i2c_command -{ - my ( $fpga, $addr, $cmd, $data, $readwrite, $skipcmd, $wordbyte ) = @_; - - my $reg_data = ( $data << 16 ) + ( $cmd << 8 ) + 0x80 + $addr; - my $reg_flag = ( $readwrite << 8 ) + ( $skipcmd << 4 ) + $wordbyte; - - if ( $readwrite == 0 ) { - - trb_register_write_mem( $fpga, - 0xd681, - 0, - [ $reg_flag, $reg_data ], - 2 ); - - } elsif ( $readwrite == 1 ) { - - trb_register_write_mem( $fpga, - 0xd681, - 0, - [ $reg_flag, $reg_data ], - 2 ); usleep(1000); - - my $reg_return = trb_register_read( $fpga, 0xd684 ); - return $reg_return->{$fpga} & 0xffff; - } -} - - - -sub mimosis_i2c_command -{ - my ( $fpga, $addr, $cmd, $data, $readwrite, $skipcmd, $wordbyte ) = @_; - - - my $reg_data = ( $data << 16 ) + ( $cmd << 8 ) + ( $addr << 1 ); - my $reg_flag = ( $readwrite << 8 ) + ( $skipcmd << 4 ) + $wordbyte; - - - if($transport eq "I2C") { - - } elsif ( $transport eq "UART" ) { - - } - - if ( $readwrite == 0 ) - { - # printf( "%x %x %x %x\n", $fpga, $addr, $cmd, $data ); - # printf( "%x %x\n", $reg_flag, $reg_data ); - trb_register_write_mem( $fpga, 0xde01, 0, [ $reg_flag, $reg_data, 0x1 ], 3 ); - } - elsif ( $readwrite == 1 ) - { - trb_register_write_mem( $fpga, 0xde01, 0, [ $reg_flag, $reg_data, 0x1 ], 3 ); - usleep(1000); - my $reg_return = trb_register_read( $fpga, 0xde04 ); - return $reg_return->{$fpga} & 0xffff; - } -} - - - -sub mimosis_register_write{ - - my ( $fpga, $mimosis_reg, $mimosis_data, $singleaccess ) = @_; - - my $addr = ($chipid << 4) + 0x2; - my $cmd = ( $mimosis_reg >> 8 ); - my $data = ( ( $mimosis_reg & 0xff ) << 8 ) + $mimosis_data; - - # printf( "%x %x\n", $cmd, $data ); - if ($singleaccess) - { - mimosis_i2c_command( $fpga, $addr, 0, $mimosis_reg>>8, 0, 1, 0); - usleep(1000); - mimosis_i2c_command( $fpga, $addr+1, 0, $mimosis_reg, 0, 1, 0); - usleep(1000); - mimosis_i2c_command( $fpga, $addr+2, 0, $mimosis_data, 0, 1, 0); - } - else - { - mimosis_i2c_command( $fpga, $addr, $cmd, $data, 0, 0, 1); - # print "check Mimosis::mimosis_register_write()\n"; - } - usleep(1000); -} - - -sub mimosis_register_write_indirect -{ - my ( $fpga, $mimosis_reg, $mimosis_data, $singleaccess ) = @_; - - my $addr = ($chipid << 4) + 0x2; - my $cmd = ( $mimosis_reg >> 8 ); - my $data = ( ( $mimosis_reg & 0xff ) << 8 ) + $mimosis_data; - - # printf( "%x %x\n", $cmd, $data ); - if ($singleaccess) - { - mimosis_i2c_command( $fpga, $addr, 0, $mimosis_reg>>8, 0, 1, 0); - usleep(1000); - mimosis_i2c_command( $fpga, $addr+1, 0, $mimosis_reg, 0, 1, 0); - usleep(1000); - mimosis_i2c_command( $fpga, $addr+2, 0, $mimosis_data, 0, 1, 0); - } - else - { - mimosis_i2c_command( $fpga, $addr, $cmd, $data, 0, 0, 1); - # print "check Mimosis::mimosis_register_write()\n"; - } - usleep(1000); -} - - - -sub mimosis_register_read -{ - my ( $fpga, $mimosis_reg, $singleaccess) = @_; - - # printf("%x %x\n",$fpga,$mimosis_reg); - my $addr = ($chipid << 4) + 0x2; - my $cmd = ( $mimosis_reg >> 8 ); - my $data = ( $mimosis_reg & 0xff ); - - if ($singleaccess) - { - mimosis_i2c_command( $fpga, $addr, 0, $mimosis_reg>>8, 0, 1, 0); - usleep(1000); - mimosis_i2c_command( $fpga, $addr+1, 0, $mimosis_reg, 0, 1, 0); - } - else - { - # printf( "%x %x %x %x\n", $fpga, $addr, $cmd, $data ); - mimosis_i2c_command( $fpga, $addr, $cmd, $data, 0, 0, 0); - } - - usleep(1000); - $addr = ($chipid << 4) + 0x5; - my $val = mimosis_i2c_command( $fpga, $addr, 0, 0, 1, 1, 0 ); - - # printf( "%x\n", $val ); - return $val & 0xff; -} - - - -sub mimosis_instr_write -{ - my ( $fpga, $command ) = @_; - trb_register_write_mem( $fpga, 0xde01, 0, [ 0x0, ( $command << 8 ) + ( 0x11 << 1 ), 0x1 ], 3 ); -} - - - -sub mimosis_load_file { - my %params = @_; - - my $fpga = $params{'fpga'}; - my $slow = $params{'slow'}; - my $a = $params{'a'}; - my $file = $params{'file'}; - my $printall = $params{'printall'}; - my $printwrong = $params{'printwrong'}; - - defined $fpga or die "Mimosis::mimosis_load_file: Must provide \$fpga."; - defined $file or die "Mimosis::mimosis_load_file: Must provide \$file."; - - $a = defined $a ? $a : 0; - $slow = defined $slow ? $slow : 10000; - $printall = defined $printall ? 1 : 0; - $printwrong = defined $printwrong ? 1 : 0; - - my @config = do $file; - - foreach my $i (@config) - { - if ( defined( @$i[1] ) ) - { - Mimosis::mimosis_register_write( $fpga, @$i[0], @$i[1], $a ); usleep($slow); - if( $printall ) { printf( "%x %x %x\n", $fpga, @$i[0], @$i[1] ); } - } - } - - if ( $printall || $printwrong ) - { - foreach my $i (@config) - { - if ( defined( @$i[1] ) ) - { - my $val = Mimosis::mimosis_register_read $fpga, @$i[0]; usleep($slow); - unless(($val & 0xff) == @$i[1]) - { - my $reg_return = trb_register_read $fpga, 0xde04 ; - - foreach my $k (keys %{$reg_return}) { - my $status = (($reg_return->{$k}//0) >> 16 ) & 0xff; - printf "%x %x %x Status: %x\n", $k, @$i[0], $val, $status; - } - # my $status = (($reg_return->{$fpga}//0) >> 16 ) & 0xff; - # printf "%x %x Status: %x\n", @$i[0], $val, $status; - } - } - } - } -} - - - -sub mimosis_dacscan_initial_test { - - my %odac = ( - 1 => 0x0045, - 2 => 0x0044, - 6 => 0x0043, - #1 => 0x0046, - ); - - my %odac_reset = ( - 1 => 0x68, - 2 => 0x57, - 6 => 0xab, - #1 => 0, - ); - - my %params = @_; - - my $fpga = $params{'fpga'}; - my $slow = $params{'slow'}; - my $a = $params{'a'}; - my $ikf = $params{'ikf'}; - my $printall = $params{'printall'}; - my $name = $params{'plotname'}; - - defined $fpga or die "Mimosis::mimosis_dacscan: Must provide \$fpga."; - - $a = defined $a ? $a : 0; - $ikf = defined $ikf ? $ikf : 0; - $slow = defined $slow ? $slow : 10000; - $printall = defined $printall ? 1 : 0; - - my $other_file_n = $name . "/other_data.csv"; - - trb_register_write( $fpga, 0xd680, 0x1e ); #write speed 30 to adc - - if ( $ikf ) - { - $adc_cmdV = 0xe380; - $adc_cmdI = 0xd380; - } - - #MONVOLT_others - open( FH, '>', $other_file_n ) or die $!; - - #loop over dacs - for my $dac ( sort keys %odac ) - { - if( $printall ){ printf "Scan: %x\n", $odac{$dac}; } - - #set MONVOLT to $dac - Mimosis::mimosis_register_write( $fpga, 0x0026, $dac, $a ); usleep($slow); - - #loop over settings - for ( my $set = 0; $set <= 0xff; $set += 10 ) - { - #set dac to $set - Mimosis::mimosis_register_write( $fpga, $odac{$dac}, $set, $a ); usleep($slow); - Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_wreg, $adc_cmdV, 0, 0, 1 ); usleep($slow); - my $rawV = Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_rreg, 0x0, 1, 0, 1 ); - printf( FH "%x\t%i\t%i\n", $odac{$dac}, $set, $rawV * $adcConv ); - } - - #set DAC to reset value - Mimosis::mimosis_register_write( $fpga, $odac{$dac}, $odac_reset{$dac}, $a ); usleep($slow); - printf( FH "\n\n" ); - } - - #VPHF Scan - Mimosis::mimosis_register_write( $fpga, 0x0026, 1, $a ); usleep($slow); - - for ( my $set = 0; $set <= 2**8 - 1; $set += 10 ) - { - - Mimosis::mimosis_register_write( $fpga, 0x0046, $set, $a ); usleep($slow); - Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_wreg, $adc_cmdV, 0, 0, 1 ); usleep($slow); - my $rawV = Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_rreg, 0x0, 1, 0, 1 ); - printf( FH "%x\t%i\t%i\n", 0x0046, $set, $rawV * $adcConv ); - } - - Mimosis::mimosis_register_write( $fpga, 0x0046, 0, $a ); usleep($slow); - - close(FH); - - my $img_n = $name . "/" . $name . ".png"; - - my $message_png = <<"END_MESSAGE"; -gnuplot -p -e "set terminal pngcairo size 1000,1000; -set output \\"$img_n\\"; -set key Left left top box; -set xlabel \\"set.\\"; -set ylabel \\"[mV]\\"; -array names2[4] = [\\"VRESET\\", \\"VPH\\", \\"VPL\\", \\"VPHF\\"]; -plot \\"good_range_vphf.txt\\" using 1:2:3 ls 4 w filledcu fc \\"grey\\", \\"good_range_odac.txt\\" using 1:2:3 ls 4 w filledcu fc \\"grey\\", for [i=0:3] \\"$other_file_n\\" using 2:3 index i with l title names2[i+1]"; -END_MESSAGE - system $message_png; - - system "display $name/$name.png &"; -} - - -sub mimosis_dacscan -{ - my %vdac = ( - 3 => 0x004c, - 4 => 0x0047, - 5 => 0x004d, - 7 => 0x0048, - 8 => 0x0049, - 9 => 0x004a, - 10 => 0x004b, - ); - - my %vdac_reset = ( - 3 => 0x53, - 4 => 0x43, - 5 => 0x32, - 7 => 0x53, - 8 => 0x53, - 9 => 0x53, - 10 => 0x53, - ); - - my %idac = ( - 1 => 0x0040, - 2 => 0x0042, - 3 => 0x0041, - ); - - my %idac_reset = ( - 1 => 0x40, - 2 => 0x1c, - 3 => 0x34, - ); - - my %odac = ( - 1 => 0x0045, - 2 => 0x0044, - 6 => 0x0043, - ); - - my %odac_reset = ( - 1 => 0x68, - 2 => 0x57, - 6 => 0xab, - ); - - my %params = @_; - - my $fpga = $params{'fpga'}; - my $slow = $params{'slow'}; - my $a = $params{'a'}; - my $ikf = $params{'ikf'}; - my $name = $params{'name'}; - my $cleanup = $params{'cleanup'}; - my $imagefileonly = $params{'imagefileonly'}; - my $printall = $params{'printall'}; - - defined $fpga or die "Mimosis::mimosis_dacscan: Must provide \$fpga."; - - $ikf = defined $ikf ? $ikf : 0; - $a = defined $a ? $a : 0; - $slow = defined $slow ? $slow : 10000; - $printall = defined $printall ? 1 : 0; - - #write speed 30 to adc - trb_register_write( $fpga, 0xd680, 0x1e ); - - #generate file name - my $vmon_file_n; - my $imon_file_n; - my $other_file_n; - - if( $name ) - { - mkdir( $name ) or $!{EEXIST} # Don't die if $dir_qfn exists. - or die("Can't create directory \"$name\": $!\n"); - $vmon_file_n = $name . "/" . "vmon_data.csv"; - $imon_file_n = $name . "/" . "imon_data.csv"; - $other_file_n = $name . "/" . "other_data.csv"; - } - else - { - mkdir( 'data' ) or $!{EEXIST} # Don't die if $dir_qfn exists. - or die( "Can't create directory \"data\": $!\n" ); - $vmon_file_n = "data/vmon_data.csv"; - $imon_file_n = "data/imon_data.csv"; - $other_file_n = "data/other_data.csv"; - } - - #generate adc addresses - if ( $ikf ) - { - $adc_cmdV = 0xe380; - $adc_cmdI = 0xd380; - } - - #MONVOLT - open( FH, '>', $vmon_file_n ) or die $!; - - #loop over dacs - for my $dac ( sort keys %vdac ) - { - if( $printall ) { printf "Scan: %x\n", $vdac{$dac}; } - - Mimosis::mimosis_register_write( $fpga, 0x0026, $dac, $a ); usleep($slow); - - #loop over settings - for my $set ( 0 .. 0x8f ) - { - Mimosis::mimosis_register_write( $fpga, $vdac{$dac}, $set, $a ); usleep($slow); - Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_wreg, $adc_cmdV, 0, 0, 1 ); usleep($slow); - my $rawV = Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_rreg, 0x0, 1, 0, 1 ); - printf( FH "%x\t%f\t%i\n", $vdac{$dac}, $set, $rawV * $adcConv ); - } - - #set DAC to reset value - Mimosis::mimosis_register_write( $fpga, $vdac{$dac}, $vdac_reset{$dac}, $a ); usleep($slow); - printf( FH "\n\n" ); - # last; - } - - close(FH); - - - #MONCURR - open( FH, '>', $imon_file_n ) or die $!; - - #loop over dacs - for my $dac ( sort keys %idac ) - { - if( $printall ){ printf "Scan: %x\n", $idac{$dac}; } - - #set MONCURR to $dac - # Mimosis::mimosis_register_write( $fpga, 0x0025, $dac, $a ); usleep($slow); - - #loop over settings - for my $set ( 0 .. 2**8 - 1 ) - { - Mimosis::mimosis_register_write( $fpga, $idac{$dac}, $set, $a ); usleep($slow); - Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_wreg, $adc_cmdI, 0, 0, 1 ); usleep($slow); - my $rawV = Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_rreg, 0x0, 1, 0, 1 ); - printf( FH "%x\t%i\t%i\n", $idac{$dac}, $set, $rawV * $adcConv ); - } - - Mimosis::mimosis_register_write( $fpga, $idac{$dac}, $idac_reset{$dac}, $a ); usleep($slow); - printf( FH "\n\n" ); - } - close(FH); - - - #MONVOLT_others - open( FH, '>', $other_file_n ) or die $!; - - #loop over dacs - for my $dac ( sort keys %odac ) - { - if( $printall ){ printf "Scan: %x\n", $odac{$dac}; } - - Mimosis::mimosis_register_write( $fpga, 0x0026, $dac, $a ); usleep($slow); - - #loop over settings - for my $set ( 0 .. 2**8 - 1 ) - { - Mimosis::mimosis_register_write( $fpga, $odac{$dac}, $set, $a ); usleep($slow); - Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_wreg, $adc_cmdV, 0, 0, 1 ); usleep($slow); - my $rawV = Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_rreg, 0x0, 1, 0, 1 ); - printf( FH "%x\t%i\t%i\n", $odac{$dac}, $set, $rawV * $adcConv ); - } - - Mimosis::mimosis_register_write( $fpga, $odac{$dac}, $odac_reset{$dac}, $a ); usleep($slow); - printf( FH "\n\n" ); - } - close(FH); - - - my ( $sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst ) = localtime(time); - $year = sprintf("%02d", $year % 100); - $mon = sprintf("%02d", $mon + 1); - $mday = sprintf("%02d", $mday); - $min = sprintf("%02d", $min); - $hour = sprintf("%02d", $hour); - my $timestamp = $hour . ":" . $min . "-" . $mday . "-" . $mon . "-" . $year; - my $img_n; - if( $name ) - { - $img_n = $name . "/" . $name . "_" . $timestamp . ".png"; - } - else - { - $img_n = "data/" . $timestamp . ".png"; - } - my $message_png = <<"END_MESSAGE"; -gnuplot -p -e "set terminal pngcairo size 1000,1000; -set output \\"$img_n\\"; -set multiplot layout 2,2; -set key Left left top box; -set xlabel \\"set.\\"; -set ylabel \\"[mV]\\"; -array names0[7] = [\\"VCASND\\", \\"VCASN2\\", \\"VCASP\\", \\"VCLIP\\", \\"VCASNA\\", \\"VCASNB\\", \\"VCASNC\\"]; -plot for [i=0:6] \\"$vmon_file_n\\" using 2:3 index i with l title names0[i+1]; -array names1[3] = [\\"IBIAS\\", \\"IDB\\", \\"ITHR\\"]; -plot for [i=0:2] \\"$imon_file_n\\" using 2:3 index i with l title names1[i+1]; -array names2[3] = [\\"VPH\\", \\"VPL\\", \\"VRESET\\"]; -plot for [i=0:2] \\"$other_file_n\\" using 2:3 index i with l title names2[i+1];" -END_MESSAGE - system $message_png; - - if( !defined $imagefileonly ) { system ( "display $img_n &" ); } - - if( $cleanup ) - { - if( $name ) { system( "rm -r $name" ); } - else { system( "rm -r data/" ); } - } -} - - -sub mimosis_dacscan_sf { - - my %vdac = ( - 1 => 0x0045, - 2 => 0x0044, - 3 => 0x004c, - 4 => 0x0047, - 5 => 0x004d, - 6 => 0x0043, - 7 => 0x0048, - 8 => 0x0049, - 9 => 0x004a, - 10 => 0x004b, - ); - - my %vdac_reset = ( - 1 => 0x68, - 2 => 0x57, - 3 => 0x53, - 4 => 0x43, - 5 => 0x32, - 6 => 0xab, - 7 => 0x53, - 8 => 0x53, - 9 => 0x53, - 10 => 0x53, - ); - - my %idac = ( - 1 => 0x0040, - 2 => 0x0042, - 3 => 0x0041, - ); - - my %idac_reset = ( - 1 => 0x40, - 2 => 0x1c, - 3 => 0x34, - ); - - my %names = ( - 0x0040 => 'IBIAS', - 0x0041 => 'ITHR', - 0x0042 => 'IDB', - 0x0043 => 'VRESET', - 0x0044 => 'VPL', - 0x0045 => 'VPH', - 0x0046 => 'VPH_FINE', - 0x0047 => 'VCASP', - 0x0048 => 'VCASNA', - 0x0049 => 'VCASNB', - 0x004a => 'VCASNC', - 0x004b => 'VCASND', - 0x004c => 'VCASN2', - 0x004d => 'VCLIP', - 0x004e => 'IBUFBIAS', - ); - - my %params = @_; - - my $fpga = $params{'fpga'}; - my $slow = $params{'slow'}; - my $a = $params{'a'}; - my $ikf = $params{'ikf'}; - my $printall = $params{'printall'}; - - defined $fpga or die "Mimosis::mimosis_dacscan: Must provide \$fpga."; - - $a = defined $a ? $a : 0; - $ikf = defined $ikf ? $ikf : 0; - $slow = defined $slow ? $slow : 10000; - $printall = defined $printall ? 1 : 0; - - - trb_register_write( $fpga, 0xd680, 0x1e ); #write speed 30 to adc - - if ( $ikf ) - { - $adc_cmdV = 0xe380; - $adc_cmdI = 0xd380; - } - - - my %results = ( - 0x0040 => [], - 0x0041 => [], - 0x0042 => [], - 0x0043 => [], - 0x0044 => [], - 0x0045 => [], - 0x0046 => [], - 0x0047 => [], - 0x0048 => [], - 0x0049 => [], - 0x004a => [], - 0x004b => [], - 0x004c => [], - 0x004d => [], - 0x004e => [], - ); - - #MONVOLT - while( my ($key, $dac) = each(%vdac) ) { - - my $fname = $names{$dac} . '.csv'; - open( FH, '>', $fname ) or die $!; - - if( $printall ) { printf "Scan: %x\n", $dac; } - - # Set MONVOLT - Mimosis::mimosis_register_write( $fpga, 0x0026, $key, $a ); usleep($slow); - - for my $set ( 0 .. 0xff ) { - - Mimosis::mimosis_register_write( $fpga, $dac, $set, $a ); usleep($slow); - Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_wreg, $adc_cmdV, 0, 0, 1 ); usleep($slow); - - my $rawV = Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_rreg, 0x0, 1, 0, 1 ); - printf( FH "%x\t%i\t%f\n", $dac, $set, $rawV * $adcConv ); - push ( @{$results{$dac}}, $rawV*$adcConv ); - } - - close(FH); - - Mimosis::mimosis_register_write( $fpga, $dac, $vdac_reset{$key}, $a ); usleep($slow); - } - - - - #MONCURR - while( my ($key, $dac) = each(%idac) ) { - - my $fname = $names{$dac} . '.csv'; - open( FH, '>', $fname ) or die $!; - - if( $printall ){ printf "Scan: %x\n", $dac; } - - Mimosis::mimosis_register_write( $fpga, 0x0025, $key, $a ); usleep($slow); - - for my $set ( 0 .. 0xff) { - - Mimosis::mimosis_register_write( $fpga, $dac, $set, $a ); usleep($slow); - Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_wreg, $adc_cmdI, 0, 0, 1 ); usleep($slow); - my $rawV = Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_rreg, 0x0, 1, 0, 1 ); - printf( FH "%x\t%i\t%f\n", $dac, $set, $rawV * $adcConv ); - push ( @{$results{$dac}}, $rawV*$adcConv ); - } - - close(FH); - - Mimosis::mimosis_register_write( $fpga, $dac, $idac_reset{$key}, $a ); usleep($slow); - } - - - - #VPH_FINE - my $fname = $names{0x0046 } . '.csv'; - open( FH, '>', $fname ) or die $!; - - if( $printall ){ printf "Scan: %x\n", 0x0046; } - - Mimosis::mimosis_register_write( $fpga, 0x0045, 0, $a ); usleep($slow); - - Mimosis::mimosis_register_write( $fpga, 0x0026, 1, $a ); usleep($slow); - - for my $set ( 0 .. 0xff ) { - - Mimosis::mimosis_register_write( $fpga, 0x0046, $set, $a ); usleep($slow); - Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_wreg, $adc_cmdV, 0, 0, 1 ); usleep($slow); - my $rawV = Mimosis::adc_i2c_command( $fpga, $adc_addr, $adc_rreg, 0x0, 1, 0, 1 ); - printf( FH "%x\t%i\t%f\n", 0x0046, $set, $rawV * $adcConv ); - push ( @{$results{0x0046}}, $rawV*$adcConv ); - } - - close(FH); - - Mimosis::mimosis_register_write( $fpga, 0x0046, 0x0, $a ); usleep($slow); - - return %results; -} - - - -sub send_params_scurve -{ - my %params = @_; - my $state = $params{'state'}; - my $ySta = $params{'ySta'}; - my $yEnd = $params{'yEnd'}; - my $yTra = $params{'yTra'}; - my $xSta = $params{'xSta'}; - my $xEnd = $params{'xEnd'}; - my $setSta = $params{'setSta'}; - my $setEnd = $params{'setEnd'}; - my $setTra = $params{'setTra'}; - my $setCnt = $params{'setCnt'}; - my $mod = $params{'mod'}; - my $region = $params{'region'}; - my $vcasn= $params{'vcasn'}; - my $singleAccess = $params{'singleAccess'}; - my $fpga = $params{'fpga'}; - - $state = defined $state ? $state : "DONE"; - $ySta = defined $ySta ? $ySta : 0; - $yEnd = defined $yEnd ? $yEnd : 0; - $yTra = defined $yTra ? $yTra : 0; - $xSta = defined $xSta ? $xSta : 0; - $xEnd = defined $xEnd ? $xEnd : 0; - $setSta = defined $setSta ? $setSta : 0; - $setEnd = defined $setEnd ? $setEnd : 0; - $setTra = defined $setTra ? $setTra : 1; - $setCnt = defined $setCnt ? $setCnt : 0; - $mod = defined $mod ? $mod : 3; - $region = defined $region ? $region : 'A'; - $vcasn= defined $vcasn ? $vcasn : 0; - $singleAccess= defined $singleAccess ? $singleAccess : 0; - $fpga = defined $fpga ? $fpga : 0xa000; - - my $frameWr = "START-" . - $state . "-" . - $ySta . "-" . - $yEnd . "-" . - $yTra . "-" . - $xSta . "-" . - $xEnd . "-" . - $setSta . "-" . - $setEnd . "-" . - $setTra . "-" . - $setCnt . "-" . - $mod . "-" . - $region . "-" . - $vcasn . "-" . - $singleAccess . "-" . - $fpga . "-END"; - - my $pipeNameWr = "/tmp/scurveipipe"; - my $fdPipeWr = POSIX::open($pipeNameWr, &POSIX::O_WRONLY); - POSIX::write($fdPipeWr,$frameWr,length($frameWr)); - POSIX::close($fdPipeWr); -} - - - -sub kill_proc_by_pid_file -{ - my ($pidName) = @_; - - my $pidFile = POSIX::open($pidName, &POSIX::O_RDONLY) or return; - my $buf; - my $bytes = POSIX::read($pidFile,$buf,10); - POSIX::close($pidFile); - - kill 15, $buf; - - unlink($pidName); -} - - - -sub await_ack -{ - my $pipeNameRd = "/tmp/scurveapipe"; - my $fdPipeRd = POSIX::open($pipeNameRd); - my $frameRd; - my $reading = 1; - while($reading) { - my $buf; - my $bytes = POSIX::read($fdPipeRd,$buf,1); - $frameRd .= $buf; - if($frameRd =~ /ACK/) { - $reading = 0; - } - } - POSIX::close($fdPipeRd); -} - - - -sub mimosis_scan_region -{ - my %params = @_; - my $fpga = $params{'fpga'}; - my $slow = $params{'slow'}; - my $a = $params{'a'}; - my $region = $params{'region'}; - my $ySta = $params{'ySta'}; - my $yEnd = $params{'yEnd'}; - my $yTra = $params{'yTra'}; - my $xSta = $params{'xSta'}; - my $xEnd = $params{'xEnd'}; - my $setSta = $params{'setSta'}; - my $setEnd = $params{'setEnd'}; - my $setTra = $params{'setTra'}; - my $setCnt = $params{'setCnt'}; - my $analogalima = $params{'analogalima'}; - my $analogalimb = $params{'analogalimb'}; - my $analogdlima = $params{'analogdlima'}; - my $analogdlimb = $params{'analogdlimb'}; - my $mod = $params{'mod'}; - - defined $fpga or die "mimosis::mimosis_scan_region: must provide $fpga."; - defined $region or die "mimosis::mimosis_scan_region: must provide $region."; - - my %collim = ( - 'A' => [ 0, 127 ], - 'B' => [ 128, 511 ], - 'C' => [ 512, 895 ], - 'D' => [ 896, 1023 ] - ); - - my %rowadd = ( 'A' => 4, 'B' => 2, 'C' => 2, 'D' => 4 ); - - $slow = defined $slow ? $slow : 10000; - $a = defined $a ? $a : 0; - $ySta = defined $ySta ? $ySta : 0; - $yEnd = defined $yEnd ? $yEnd : 504; - $yTra = defined $yTra ? $yTra : $rowadd{$region}; - $xSta = defined $xSta ? $xSta : $collim{$region}[0]; - $xEnd = defined $xEnd ? $xEnd : $collim{$region}[1]; - $setSta = defined $setSta ? $setSta : 0x0; - $setEnd = defined $setEnd ? $setEnd : 0xff; - $setTra = defined $setTra ? $setTra : 1; - $setCnt = defined $setCnt ? $setCnt : 4000; - my $pixpulsea_a = defined $params{'pixpulsea_a'} ? $params{'pixpulsea_a'} : 25; - my $pixpulsea_b = defined $params{'pixpulsea_b'} ? $params{'pixpulsea_b'} : 75; - my $pixpulsed_a = defined $params{'pixpulsed_a'} ? $params{'pixpulsed_a'} : 0; - my $pixpulsed_b = defined $params{'pixpulsed_b'} ? $params{'pixpulsed_b'} : 0; - $mod = defined $mod ? $mod : 3; - - Mimosis::mimosis_register_write( $fpga, 0x0020, 0x40, $a ); usleep($slow); #en_pixelmask to 0 for pulse - Mimosis::mimosis_instr_write( $fpga, 0x3f ); usleep($slow); #instr select all pixels - Mimosis::mimosis_instr_write( $fpga, 0x04 ); usleep($slow); #instr reset mask - Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #instr unselect all pixels - Mimosis::mimosis_register_write( $fpga, 0x0066, $pixpulsea_a & 0x00ff , $a ); usleep($slow); #analog pulsing pulse a, limit a - Mimosis::mimosis_register_write( $fpga, 0x0166, ( $pixpulsea_a & 0xff00 ) >> 8, $a ); usleep($slow); - Mimosis::mimosis_register_write( $fpga, 0x0076, $pixpulsea_b & 0x00ff , $a ); usleep($slow); # analog pulsing pulse a, limit b - Mimosis::mimosis_register_write( $fpga, 0x0176, ( $pixpulsea_b & 0xff00 ) >> 8, $a ); usleep($slow); - Mimosis::mimosis_register_write( $fpga, 0x0067, $pixpulsed_a & 0x00ff , $a ); usleep($slow); # analog pulsing pulse d, limit a - Mimosis::mimosis_register_write( $fpga, 0x0167, ( $pixpulsed_a & 0xff00 ) >> 8, $a ); usleep($slow); - Mimosis::mimosis_register_write( $fpga, 0x0077, $pixpulsed_b & 0x00ff , $a ); usleep($slow); # analog pulsing pulse d, limit b - Mimosis::mimosis_register_write( $fpga, 0x0177, ( $pixpulsed_b & 0xff00 ) >> 8, $a ); usleep($slow); - Mimosis::mimosis_register_write( $fpga, 0x007d, $mod, $a ); usleep($slow); #set modpulse. possible values: 1f/1, 1f/2, 1f/4, 1f/8, 1f/16, 1f/32, 1f/64, 1f/128 - - send_params_scurve( - state => "TAKEDATA", - ySta => $ySta, - yEnd => $yEnd, - yTra => $yTra, - xSta => $xSta, - xEnd => $xEnd, - setSta => $setSta, - setEnd => $setEnd, - setTra => $setTra, - setCnt => $setCnt, - mod => $mod, - region => $region, - vcasn => 0, - singleAccess => $a, - fpga => $fpga - ); - await_ack(); -} - - - -sub mimosis_scan_region_loop -{ - my %params = @_; - my $fpga = $params{'fpga'}; - my $slow = $params{'slow'}; - my $a = $params{'a'}; - my $region = $params{'region'}; - my $vcasnSta = $params{'vcasnSta'}; - my $vcasnEnd = $params{'vcasnEnd'}; - my $vcasnStep = $params{'vcasnStep'}; - my $ySta = $params{'ySta'}; - my $yEnd = $params{'yEnd'}; - my $yTra = $params{'yTra'}; - my $xSta = $params{'xSta'}; - my $xEnd = $params{'xEnd'}; - my $setSta = $params{'setSta'}; - my $setEnd = $params{'setEnd'}; - my $setTra = $params{'setTra'}; - my $setCnt = $params{'setCnt'}; - my $analogAlimA = $params{'analogalima'}; - my $analogAlimB = $params{'analogalimb'}; - my $analogDlimA = $params{'analogdlima'}; - my $analogDlimB = $params{'analogdlimb'}; - my $printall = $params{'printall'}; - my $mod = $params{'mod'}; - - defined $fpga or die "Mimosis::mimosis_scan_region_loop: must provide $fpga."; - defined $region or die "Mimosis::mimosis_scan_region_loop: must provide $region."; - - - my %regCharToStr = ( - A => 'VCASNA', - B => 'VCASNB', - C => 'VCASNC', - D => 'VCASND' - ); - - my %dacs = ( - IBIAS => 0x0040, - ITHR => 0x0041, - IDB => 0x0042, - VRESET => 0x0043, - VPL => 0x0044, - VPH => 0x0045, - VPH_FINE => 0x0046, - VCASP => 0x0047, - VCASNA => 0x0048, - VCASNB => 0x0049, - VCASNC => 0x004a, - VCASND => 0x004b, - VCASN2 => 0x004c, - VCLIP => 0x004d, - IBUFBIAS => 0x004e - ); - - my $vcasnStr = $regCharToStr{$region}; - my $vcasnVal = mimosis_register_read( $fpga, $dacs{$vcasnStr}, $a ); - $vcasnSta = defined $vcasnSta ? $vcasnSta : $vcasnVal; - $vcasnEnd = defined $vcasnEnd ? $vcasnEnd : $vcasnSta; - $vcasnStep = defined $vcasnStep ? $vcasnStep : 1; - - system("/d/jspc37/mimosis/cpp/build/scurve-scan mbss://localhost:36789 &"); - - for ( my $vcasnSet = $vcasnSta; - $vcasnSet <= $vcasnEnd; - $vcasnSet += $vcasnStep ) { - #set vcasn - mimosis_register_write( $fpga, $dacs{$vcasnStr}, $vcasnSet, $a ); usleep($slow); - - if( $printall ) { printf("dac: $vcasnSet\n"); } - - mimosis_scan_region( - fpga => $fpga, - slow => $slow, - a => $a, - region => $region, - ySta => $ySta, - yEnd => $yEnd, - yTra => $yTra, - xSta => $xSta, - xEnd => $xEnd, - setSta => $setSta, - setEnd => $setEnd, - setTra => $setTra, - setCnt => $setCnt, - analogAlimA => $analogAlimA, - analogAlimB => $analogAlimB, - analogDlimA => $analogDlimA, - analogDlimB => $analogDlimB, - mod => $mod, - ); - - send_params_scurve( - state => "FIT", - region => $regCharToStr{$region}, - vcasn => $vcasnSet - ); - - await_ack(); - } - - send_params_scurve( state => "DONE" ); - await_ack(); - kill_proc_by_pid_file("/tmp/hldprint-pid"); -} - -sub mimosis_pulse_region -{ - my %params = @_; - my $fpga = $params{'fpga'}; - my $slow = $params{'slow'}; - my $a = $params{'a'}; - my $region = $params{'region'}; - my $ySta = $params{'ySta'}; - my $yEnd = $params{'yEnd'}; - my $yTra = $params{'yTra'}; - my $analogAlimA = $params{'analogAlimA'}; - my $analogAlimB = $params{'analogAlimB'}; - my $analogDlimA = $params{'analogDlimA'}; - my $analogDlimB = $params{'analogDlimB'}; - my $modpulse = $params{'modpulse'}; - - defined $fpga or die "Mimosis::mimosis_scan_region: Must provide --fpga."; - defined $region or die "mimosis::mimosis_scan_region: must provide --region."; - - my %rowadd = ( 'A' => 4, 'B' => 2, 'C' => 2, 'D' => 4 ); - - $slow = defined $slow ? $slow : 10000; - $a = defined $a ? $a : 0; - $ySta = defined $ySta ? $ySta : 0; - $yEnd = defined $yEnd ? $yEnd : 503; - $yTra = defined $yTra ? $yTra : $rowadd{$region}; - my $pixpulseA_A = defined $params{'pixpulsea_a'} ? $params{'pixpulsea_a'} : 25; - my $pixpulseA_B = defined $params{'pixpulsea_b'} ? $params{'pixpulsea_b'} : 75; - my $pixpulseD_A = defined $params{'pixpulsed_a'} ? $params{'pixpulsed_a'} : 0; - my $pixpulseD_B = defined $params{'pixpulsed_b'} ? $params{'pixpulsed_b'} : 0; - $modpulse = defined $modpulse ? $modpulse : 3; - - Mimosis::mimosis_register_write( $fpga, 0x0020, 0x40, $a ); usleep($slow); #EN_PIXELMASK to 0 for pulse - - Mimosis::mimosis_instr_write( $fpga, 0x3f ); usleep($slow); #INSTR select all pixels - Mimosis::mimosis_instr_write( $fpga, 0x04 ); usleep($slow); #INSTR reset mask - Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR unselect all pixels - - Mimosis::mimosis_register_write( $fpga, 0x0066, $pixpulseA_A & 0x00ff , $a ); usleep($slow); #analog pulsing pulse A, limit A - Mimosis::mimosis_register_write( $fpga, 0x0166, ( $pixpulseA_A & 0xff00 ) >> 8, $a ); usleep($slow); - Mimosis::mimosis_register_write( $fpga, 0x0076, $pixpulseA_B & 0x00ff , $a ); usleep($slow); # analog pulsing pulse A, limit B - Mimosis::mimosis_register_write( $fpga, 0x0176, ( $pixpulseA_B & 0xff00 ) >> 8, $a ); usleep($slow); - Mimosis::mimosis_register_write( $fpga, 0x0067, $pixpulseD_A & 0x00ff , $a ); usleep($slow); # analog pulsing pulse D, limit A - Mimosis::mimosis_register_write( $fpga, 0x0167, ( $pixpulseD_A & 0xff00 ) >> 8, $a ); usleep($slow); - Mimosis::mimosis_register_write( $fpga, 0x0077, $pixpulseD_B & 0x00ff , $a ); usleep($slow); # analog pulsing pulse D, limit B - Mimosis::mimosis_register_write( $fpga, 0x0177, ( $pixpulseD_B & 0xff00 ) >> 8, $a ); usleep($slow); - Mimosis::mimosis_register_write( $fpga, 0x007d, $modpulse, $a ); usleep($slow); #set modpulse. possible values: 1f/1, 1f/2, 1f/4, 1f/8, 1f/16, 1f/32, 1f/64, 1f/128 - - for( my $yOff = $ySta; - $yOff <= $yEnd; - $yOff += $yTra) - { - my $y = $yOff; - - for(; ($y<$yOff+$yTra) && ($y <= $yEnd); $y+=1) - { - my $regAdd = $y/8; - my $regBit = $y%8; - my $regWord = ( $regAdd << 8 ) + 0x84; - Mimosis::mimosis_register_write( $fpga, $regWord, ( 0x1 << $regBit ), $a ); usleep($slow); - Mimosis::mimosis_instr_write( $fpga, 0x27 ); usleep($slow); #INSTR select all pixels - Mimosis::mimosis_instr_write( $fpga, 0x05 ); usleep($slow); #INSTR set mask pulse - Mimosis::mimosis_register_write( $fpga, 0x4087, 0x0, $a ); usleep($slow); #unselect all pixels (register wise) - Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR unselect all pixels - } - } -} - - - -# sub mimosis_scan_pixel -# { -# my %params = @_; -# my $fpga = $params{'fpga'}; -# my $x = $params{'x'}; -# my $y = $params{'y'}; -# my $add = $params{'add'}; -# my $pulseonly = $params{'pulseonly'}; -# my $setSta = $params{'firstset'}; -# my $setEnd = $params{'lastset'}; -# my $setDiv = $params{'setdiv'}; -# my $setTime = $params{'settime'}; -# my $slow = $params{'slow'}; -# my $a = $params{'a'}; -# my $printall = $params{'printall'}; -# my $analogAlimA = $params{'analogAlimA'}; -# my $analogAlimB = $params{'analogAlimB'}; -# my $analogDlimA = $params{'analogDlimA'}; -# my $analogDlimB = $params{'analogDlimB'}; -# my $modpulse = $params{'modpulse'}; - -# defined $fpga or die "Mimosis::mimosis_scan_region: Must provide --fpga."; -# defined $x or die "Mimosis::mimosis_scan_region: Must provide --x."; -# defined $y or die "Mimosis::mimosis_scan_region: Must provide --y."; - -# $setSta = defined $setSta ? $setSta : 0x0; -# $setEnd = defined $setEnd ? $setEnd : 0xff; -# $setDiv = defined $setDiv ? $setDiv : 1; -# $setTime = defined $setTime ? $setTime : 1000; -# $slow = defined $slow ? $slow : 10000; -# $a = defined $a ? $a : 0; -# $printset = defined $printset ? 1 : 0; -# $printall = defined $printall ? 1 : 0; -# $pixpulseA_A = defined $pixpulseA_A ? $pixpulseA_A : 25; -# $pixpulseA_B = defined $pixpulseA_B ? $pixpulseA_B : 75; -# $pixpulseD_A = defined $pixpulseD_A ? $pixpulseD_A : 0; -# $pixpulseD_B = defined $pixpulseD_B ? $pixpulseD_B : 0; -# $modpulse = defined $modpulse ? $modpulse : 3; - -# Mimosis::mimosis_register_write( $fpga, 0x0020, 0x40, $a ); usleep($slow); #EN_PIXELMASK to 0 for pulse - -# unless(defined $add) -# { -# Mimosis::mimosis_instr_write( $fpga, 0x3f ); usleep($slow); #INSTR select all pixels -# Mimosis::mimosis_instr_write( $fpga, 0x04 ); usleep($slow); #INSTR reset mask -# Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR unselect all pixels -# } - -# Mimosis::mimosis_register_write( $fpga, 0x0066, $pixpulseA_A & 0x00ff , $a ); usleep($slow); #analog pulsing pulse A, limit A -# Mimosis::mimosis_register_write( $fpga, 0x0166, ( $pixpulseA_A & 0xff00 ) >> 8, $a ); usleep($slow); -# Mimosis::mimosis_register_write( $fpga, 0x0076, $pixpulseA_B & 0x00ff , $a ); usleep($slow); # analog pulsing pulse A, limit B -# Mimosis::mimosis_register_write( $fpga, 0x0176, ( $pixpulseA_B & 0xff00 ) >> 8, $a ); usleep($slow); -# Mimosis::mimosis_register_write( $fpga, 0x0067, $pixpulseD_A & 0x00ff , $a ); usleep($slow); # analog pulsing pulse D, limit A -# Mimosis::mimosis_register_write( $fpga, 0x0167, ( $pixpulseD_A & 0xff00 ) >> 8, $a ); usleep($slow); -# Mimosis::mimosis_register_write( $fpga, 0x0077, $pixpulseD_B & 0x00ff , $a ); usleep($slow); # analog pulsing pulse D, limit B -# Mimosis::mimosis_register_write( $fpga, 0x0177, ( $pixpulseD_B & 0xff00 ) >> 8, $a ); usleep($slow); -# Mimosis::mimosis_register_write( $fpga, 0x007d, $modpulse, $a ); usleep($slow); #set modpulse. possible values: 1f/1, 1f/2, 1f/4, 1f/8, 1f/16, 1f/32, 1f/64, 1f/128 - -# { -# my $regAdd = $x/16; #region address -# my $regBit = ($x/2)%8; #double column in region -# my $regWord = $regAdd << 8; -# if (($x%2 == 1)) { $regWord += 0x82; } -# elsif (($x%2 == 0)) { $regWord += 0x81; } -# Mimosis::mimosis_register_write( $fpga, $regWord, ( 0x1 << $regBit ), $a ); usleep($slow); -# } - -# { -# my $regAdd = $y/8; -# my $regBit = $y%8; -# my $regWord = ( $regAdd << 8 ) + 0x84; -# Mimosis::mimosis_register_write( $fpga, $regWord, ( 0x1 << $regBit ), $a ); usleep($slow); -# } - -# Mimosis::mimosis_instr_write( $fpga, 0x05 ); usleep($slow); #INSTR set mask pulse -# Mimosis::mimosis_register_write( $fpga, 0x4087, 0x0, $a ); usleep($slow); #unselect all pixels (register wise) - -# unless($pulseonly) -# { -# send_params_scurve("TAKEDATA", $y, 1, $x, $x+1, 0, 0); -# await_ack(); - -# my $setCnt = 0; -# for my $set (reverse ($setSta .. $setEnd) ) -# { -# $setCnt = $setCnt + 1; -# if( ($setCnt-1)%$setDiv != 0) { next; } - -# my $pulseMsg = ($set << 24) + 0x00c00000; -# trb_register_write_mem( $fpga, 0xa209, 0, [ $pulseMsg ], 1 ); usleep($slow); -# Mimosis::mimosis_register_write( $fpga, 0x0046, $set, $a ); usleep($setTime); - -# if( $printset || $printall ) { printf("set: $set\n"); } -# } - -# unless(defined $add) -# { -# Mimosis::mimosis_instr_write( $fpga, 0x3f ); usleep($slow); #INSTR select all pixels -# Mimosis::mimosis_instr_write( $fpga, 0x04 ); usleep($slow); #INSTR reset mask -# Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR unselect all pixels -# } - -# trb_register_write_mem( $fpga, 0xa209, 0, [ 0x00400000 ], 1 ); usleep($slow); -# send_params_scurve("WAITDAQ", 0, 0, 0, 0, 0, 0); -# await_ack(); -# trb_register_write_mem( $fpga, 0xa209, 0, [ 0x00000000 ], 1 ); usleep($slow); -# } -# } - - - -sub mimosis_mask -{ - my %params = @_; - - my $fpga = $params{'fpga'}; - my $slow = $params{'slow'}; - my $a = $params{'a'}; - my $region = $params{'region'}; - my $row = $params{'row'}; - my $col = $params{'col'}; - my $maskall = $params{'maskall'}; - my $unmaskall = $params{'unmaskall'}; - my $hline = $params{'hline'}; - my $vline = $params{'vline'}; - my $square = $params{'square'}; - my $printall = $params{'printall'}; - - defined $fpga or die "Mimosis::mimosis_mask: Must provide $fpga."; - - $slow = defined $slow ? $slow : 10000; - $a = defined $a ? $a : 0; - - - if ( defined $maskall ) - { - Mimosis::mimosis_register_write( $fpga, 0x0020, 0x42, $a ); usleep($slow); #EN_PIXELMASK - Mimosis::mimosis_instr_write( $fpga, 0x3f ); usleep($slow); #INSTR select all pixels - Mimosis::mimosis_instr_write( $fpga, 0x05 ); usleep($slow); #INSTR set mask pulse - Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR unselect all pixels - exit; - } - - if ( defined $unmaskall ) - { - Mimosis::mimosis_register_write( $fpga, 0x0020, 0x42, $a ); usleep($slow); #EN_PIXELMASK - Mimosis::mimosis_instr_write( $fpga, 0x3f ); usleep($slow); #INSTR select all pixels - Mimosis::mimosis_instr_write( $fpga, 0x04 ); usleep($slow); #INSTR reset mask pulse - Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR unselect all pixels - exit; - } - - if ( defined $hline ) - { - Mimosis::mimosis_register_write( $fpga, 0x0020, 0x42, $a ); usleep($slow); #EN_PIXELMASK - Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR unselect all pixels - Mimosis::mimosis_instr_write( $fpga, 0x27 ); usleep($slow); #select all columns - Mimosis::mimosis_register_write( $fpga, 0x0584, 0xff, $a ); usleep($slow); #select some rows - Mimosis::mimosis_instr_write( $fpga, 0x05 ); usleep($slow); #INSTR set mask pulse - Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR unselect all pixels - Mimosis::mimosis_register_write( $fpga, 0x4087, 0x0, $a ); usleep($slow); #unselect all pixels (register wise) - exit; - } - - if ( defined $vline ) - { - Mimosis::mimosis_register_write( $fpga, 0x0020, 0x42, $a ); usleep($slow); #EN_PIXELMASK - Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR unselect all the pixels - Mimosis::mimosis_register_write( $fpga, 0x0d83, 0xff, $a ); usleep($slow); #select some columns - Mimosis::mimosis_instr_write( $fpga, 0x39 ); usleep($slow); #select all rows - Mimosis::mimosis_instr_write( $fpga, 0x05 ); usleep($slow); #INSTR set mask pulse - Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR unselect all pixels - Mimosis::mimosis_register_write( $fpga, 0x4087, 0x0, $a ); usleep($slow); #unselect all pixels (register wise) - exit; - } - - if ( defined $square ) - { - Mimosis::mimosis_register_write( $fpga, 0x0020, 0x42, $a ); usleep($slow); #EN_PIXELMASK - Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR unselect all pixels - Mimosis::mimosis_register_write( $fpga, 0x0887, 0xff, $a ); usleep($slow); - Mimosis::mimosis_register_write( $fpga, 0x0987, 0xff, $a ); usleep($slow); - Mimosis::mimosis_register_write( $fpga, 0x0a87, 0xff, $a ); usleep($slow); - Mimosis::mimosis_register_write( $fpga, 0x0b87, 0xff, $a ); usleep($slow); - Mimosis::mimosis_instr_write( $fpga, 0x05 ); usleep($slow); #INSTR set mask pulse - Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR unselect all pixels - Mimosis::mimosis_register_write( $fpga, 0x4087, 0x0, $a ); usleep($slow); #unselect all pixels (register wise) - exit; - } - - my $col_limits = { - A => [ 0, 127 ], - B => [ 128, 511 ], - C => [ 512, 895 ], - D => [ 896, 1023 ] - }; - my $row_limits = { - A => [ 0, 503 ], - B => [ 0, 503 ], - C => [ 0, 503 ], - D => [ 0, 503 ], - }; - - - my $cl; - my $ch; - - if ( defined $col && $col =~ /(\b[0-9]{1,4}),([0-9]{1,4}\b)/ && $1 < $2 && $1 < 1024 && $2 < 1024) - { - $cl = $1; - $ch = $2; - } - elsif ( defined $col && $col =~ /(^[0-9]{1,4}$)/ && $1 < 1024) - { - $cl = $1; - $ch = $1; - } - elsif ( defined $region ) - { - $cl = $col_limits->{$region}->[0]; - $ch = $col_limits->{$region}->[1]; - } - else - { - $cl = 0; - $ch = 1023; - } - - my $rl; - my $rh; - - if ( defined $row && $row =~ /(\b[0-9]{1,3}),([0-9]{1,3}\b)/ && $1 < $2 && $1 < 504 && $2 < 504) - { - $rl = $1; - $rh = $2; - } - elsif ( defined $row && $row =~ /(^[0-9]{1,3})$/ && $1 < 504) - { - $rl = $1; - $rh = $1; - } - elsif ( defined $region ) - { - $rl = 0; - $rh = 503; - } - else - { - $rl = 0; - $rh = 503; - } - - - Mimosis::mimosis_register_write( $fpga, 0x0020, 0x42, $a ); usleep($slow); #EN_PIXELMASK - Mimosis::mimosis_instr_write( $fpga, 0x3e ); usleep($slow); #INSTR unselect all the pixels - - - # Select pixels to mask - for my $x ($cl .. $ch) - { - my $rAddrC = $x/16; #region address - my $bitC = ($x/2)%8; #double column in region - my $add_regC = $rAddrC << 8; - if (($x%2 == 1)) { $add_regC += 0x82; } - elsif (($x%2 == 0)) { $add_regC += 0x81; } - - for my $y ($rl .. $rh) - { - my $rAddrR = $y/8; - my $bitR = $y%8; - my $add_regR = ( $rAddrR << 8 ) + 0x84; - - Mimosis::mimosis_register_write( $fpga, $add_regC, ( 0x1 << $bitC ), $a ); usleep($slow); - Mimosis::mimosis_register_write( $fpga, $add_regR, ( 0x1 << $bitR ), $a ); usleep($slow); - Mimosis::mimosis_instr_write( $fpga, 0x05 ); usleep($slow); #INSTR set mask pulse - Mimosis::mimosis_register_write( $fpga, 0x4087, 0x0, $a ); usleep($slow); #unselect all pixels (register wise) - - if( $printall ){ printf "%d %x %x %d %d %x\n", $x, $add_regC, ( 1 << $bitC ), $y, $add_regR, ( 1 << $bitR ); } - } - } -} - - - -sub help_global { - my $message = <<'END_MESSAGE'; - =+- =*= - +*==: :##=- - -::::-:. .-:::=:. =+@*. .+@+- .-::::::::--:. - .= .*-. .=. :#=. .*%- .:-----------=%%=----*+. .:--. - .:- .*-..=: =*:..:%%==-::::::::::-#%-::==*- -----: ==.. - .....=. :*--: ++-==+#+::::::::::::+#*==-.:- +#+--==++. :*:.. - .......+ - :#= .- .-=+-:::--:::::::::::=*#-....= :%+:.....:=: -*:.. - ......:- .%+ . .#%+=--=*====##==========#%=....=- *#-.......:+ #=... - .......=. =#+= :#*=+ *+:..*@#========*@#======+*+-+#=:........= +*:.. - .......= **--= :#*-.-- :#+==-#%=::::::-%%-::-=+-. .#*:.........+ **:.. - .....:= :%+:.-= :#*-...+::-==-:::-=-::::::-=--==-=- *#-.........-- :%+.. - ...-: =#-...-+#*-..:=*#+===+=====++=====++=-...= =%+:........-- *#-. - .= #*:....:-:......:+ :#-..:#%:..:%%:....=. :#*=--------:. .##=. - .= :%=. . .-: ++:. -%*..+@= :- :+#+-. - :+:::+#-. .=:::-#-. +@--%*. .+-::::::::::::::--=*#*=:. - :++++=. .-++++-. .%%%%: :=+++++++++++++++==-:. - =@@+ - ##. - -usage: mimosis [GLOBAL OPTIONS] [COMMAND OPTIONS] - -GLOBAL OPTIONS are: - -f, --fpga=HEX -> Hex address of the FPGA. Defaults to 0xa000. - -s, --slow=NUM -> Execute I2C commands with a pause of NUM microseconds in between. - -a, --singleaccess -> Select single access mode. - -h, --help -> Print this or specific help. - - are: - load Load a configuration file for mimosis. - dacscan Make a DAC scan. - scurves Make a S-Curve scan of mimosis or some parts of it. - mask Mask some pixels. - instr Send an instruction to mimosis. - reg Write into a register. - vnc Open a vncviewer with the setup. - -For every a short description is accessible with the -h option. -END_MESSAGE - - print $message; - exit 0; -} - - - -sub help_load { - my $message = <<'END_MESSAGE'; - -usage: mimosis [GLOBAL OPTIONS] load [COMMAND OPTIONS] PATH - -GLOBAL OPTIONS are: - -f, --fpga=HEX -> Hex address of the FPGA. Defaults to 0xa000. - -s, --slow=NUM -> Execute I2C commands with a pause of NUM microseconds in between. - -a, --singleaccess -> Select single access mode. - -h, --help -> Print this or specific help. - -COMMAND OPTIONS are: - -p, --printall -> Print all settings from file to stdout. - -w, --printwrong -> Print all settings, that were not loaded to mimosis correctly stdout. - -h, --help -> Print this help. -END_MESSAGE - - print $message; - exit 0; -} - - - -sub help_dacscan { - my $message = <<'END_MESSAGE'; - -usage: mimosis [GLOBAL OPTIONS] dacscan [COMMAND OPTIONS] - -GLOBAL OPTIONS are: - -f, --fpga=HEX -> Hex address of the FPGA. Defaults to 0xa000. - -s, --slow=NUM -> Execute I2C commands with a pause of NUM microseconds in between. - -a, --singleaccess -> Select single access mode. - -h, --help -> Print this or specific help. - -COMMAND OPTIONS are: - -i, --ikf -> Use this flag for scans on the IKFv2 proxy. - -m, --imagefile-only -> Print only image files, don't open gnuplot terminal. - -n, --name=NAME -> Sensor name. If defined, images and data files will be marked with this name. - -c, --cleanup -> Delete data and image files afterwards. - -h, --help -> Print this help. -END_MESSAGE - - print $message; - exit 0; -} - - - -sub help_scurves { - my $message = <<'END_MESSAGE'; - -usage: mimosis [GLOBAL OPTIONS] scurves [COMMAND OPTIONS] - -The data will be priveded in a folder in the current directory with the time started as name. -The data is sorted by the VCASN, if --vcasn is not provided, or by - -GLOBAL OPTIONS are: - -f, --fpga=HEX -> Hex address of the FPGA. Defaults to 0xa000. - -s, --slow=NUM -> Execute I2C commands with a pause of NUM microseconds in between. - -a, --singleaccess -> Select single access mode. - -h, --help -> Print this or specific help. - -COMMAND OPTIONS are: - -r, --region A|B|C|D -> Region to pulse. Most be provided. - - --firstrow Y -> First row to scan. - --lastrow Y -> Last row to scan. - --rowdiv ROWDIV -> Just pulse every ROWDIV row. - --nrows N -> How many rows to pulse at once. Default depends on region. For A,D: N = 4, for B,D: N = 2. - - --firstset S -> Start s-curve scan at VPH_FINE=S - --lastset S -> Stop s-curve scan at VPH_FINE=S - --setdiv SETDIV -> Just use every SETDIV value of VPH_FINE. - --settime T -> Take data for each VPH_FINE for T milliseconds. - - --firstvcasn V -> Start s-curve taking with VCASN=V. - --lastvcasn V -> Stop s-curve taking at VCASN=V. - --vcasndiv V -> Take s-curve every V steps. - - --pulseonly -> If set, mark specified pixels only for pulsing and dont do a scan. - --modpulse MOD -> Exponent of the power of two, which gives the divider of the frames to pulse. - - --printdac -> Print the current setting of the DAC. - --printset -> Print the current VPH_FINE setting. - --printrow -> Print current row to set. - -p, --printall -> Print all informations available. - - --analogAlimA -> Not implemented yet. - --analogAlimB -> Not implemented yet. - --analogDlimA -> Not implemented yet. - --analogDlimB -> Not implemented yet. - - -h, --help -> Print this help. -END_MESSAGE - - print $message; - exit 0; -} - - - -sub help_analyse { - my $message = <<'END_MESSAGE'; - -usage: mimosis [GLOBAL OPTIONS] analyse [COMMAND OPTIONS] - -Analyse data from scurve scans. Needs to be executed from the run folder, where the METADATA file is. - -GLOBAL OPTIONS are: - -f, --fpga=HEX -> Hex address of the FPGA. Defaults to 0xa000. - -s, --slow=NUM -> Execute I2C commands with a pause of NUM microseconds in between. - -a, --singleaccess -> Select single access mode. - -h, --help -> Print this or specific help. - -COMMAND OPTIONS are: - --vcasn=NUM -> Analyse data from only the run where VCASN is NUM. - -t, --threads -> Number of threads to use. Defaults to 1. - - -h, --help -> Print this help. -END_MESSAGE - - print $message; - exit 0; -} - - - -sub help_mask { - my $message = <<'END_MESSAGE'; - -usage: mimosis [GLOBAL OPTIONS] mask [COMMAND OPTIONS] - -GLOBAL OPTIONS are: - -f, --fpga=HEX -> Hex address of the FPGA. Defaults to 0xa000. - -s, --slow=NUM -> Execute I2C commands with a pause of NUM microseconds in between. - -a, --singleaccess -> Select single access mode. - -h, --help -> Print this or specific help. - -COMMAND OPTIONS are: - --region A|B|C|D -> Region to pulse. If provided, ignores --collow, --colhig, --rowlow and --rowhig - -x, --column INT -> Select column of the Pixel to mask. If not specified, but --region is given, all columns in this region are selected. If neither --region nor --column are given, all columns are selected. - -y, --row INT -> Select Rows of the Pixel to mask. If not specified, all rows are selected. Pixels whos rows and columns are selected will be masked. - --mask-all -> Mask all pixels with via an instructions. - --unmask-all -> Unmask all pixels with via an instructions. - --hline -> Mask a horizontal line. - --vline -> Mask a vertical line. - --square -> Mask a square. - -h, --help -> Print this help. -END_MESSAGE - - print $message; - exit 0; -} - - - - -sub help_instr { - my $message = <<'END_MESSAGE'; - -usage: mimosis [GLOBAL OPTIONS] instr INSTR - -GLOBAL OPTIONS are: - -f, --fpga=HEX -> Hex address of the FPGA. Defaults to 0xa000. - -s, --slow=NUM -> Execute I2C commands with a pause of NUM microseconds in between. - -a, --singleaccess -> Select single access mode. - -h, --help -> Print this or specific help. -END_MESSAGE - - print $message; - exit 0; -} - - - -sub help_reg { - my $message = <<'END_MESSAGE'; - -usage: mimosis [GLOBAL OPTIONS] reg REGISTER VALUE - -GLOBAL OPTIONS are: - -f, --fpga=HEX -> Hex address of the FPGA. Defaults to 0xa000. - -s, --slow=NUM -> Execute I2C commands with a pause of NUM microseconds in between. - -a, --singleaccess -> Select single access mode. - -h, --help -> Print this or specific help. -END_MESSAGE - - print $message; - exit 0; -} - - - -sub help_vnc { - my $message = <<'END_MESSAGE'; - -usage: mimosis vnc - -END_MESSAGE - - print $message; - exit 0; -} - - - -1; - -__END__ diff --git a/scripts/cpp/analysis.cxx b/scripts/cpp/analysis.cxx new file mode 100644 index 0000000..7613eee --- /dev/null +++ b/scripts/cpp/analysis.cxx @@ -0,0 +1,952 @@ +// #include "mimosis.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "TMath.h" +#include "TString.h" +#include "TGraph.h" +#include "TH1D.h" +#include "TH1I.h" +#include "TH2I.h" +#include "TF1.h" +#include "TFile.h" +#include "TText.h" +#include "TCanvas.h" + +#include "analysis.hpp" + +#include "mimosis.hpp" +#include "trbnet.h" + +#include "hadaq/api.h" + +// TH1I* split(std::string text, char delim, int stepsize, int start, int end) { + +// using namespace std; + +// string line; + +// stringstream ss(text); +// TH1I* h = new TH1I("h", "h",(end-start)/stepsize,start,end); +// Int_t counter = 0; +// while(getline(ss, line, delim)) { +// TString lline (line); +// if ((counter+3) % stepsize == 0){ +// //cout << lline << endl; +// h->SetBinContent(counter/stepsize, lline.Atoi());} +// counter++; +// } +// return h; +// // delete h; +// } + + + +TH1I* split(std::string text, char delim, int stepsize=1) { + + using namespace std; + + string line; + + stringstream ss(text); + TH1I* h = new TH1I("h", "h",255/stepsize,0, 255); + Int_t counter = 0; + while(getline(ss, line, delim)) { + TString lline (line); + if (counter > 1 && ((counter-2) % stepsize == 0)){ + //cout << lline << endl; + h->SetBinContent(counter/stepsize, lline.Atoi());} + counter++; + } + return h; + // delete h; +} + +Int_t GetBadX(std::string text, char delim) { + + using namespace std; + + string line; + + stringstream ss(text); + Int_t counter = 0; + while(getline(ss, line, delim)) { + TString lline (line); + if (counter == 0){ + //cout << lline << endl; + return lline.Atoi(); + + } + counter++; + } +} + +Int_t GetBadY(std::string text, char delim) { + + using namespace std; + + string line; + + stringstream ss(text); + Int_t counter = 0; + while(getline(ss, line, delim)) { + TString lline (line); + if (counter == 1){ + //cout << lline << endl; + return lline.Atoi(); + + } + counter++; + } +} + + + +void +decode_pixel( + const uint32_t& word, + unsigned int& column, + unsigned int& row, + unsigned int& region ) +{ + unsigned int pixelcode = (word >> 6) & 0x3ff; + + unsigned int side = 0, topdown = 0; + + if((pixelcode&3) == 0x1 || (pixelcode&3) == 0x2) side = 1; + if((pixelcode&3) == 0x3 || (pixelcode&3) == 0x2) topdown = 1; + + row = (pixelcode>>2)*2 + topdown; + column = (((word>>3)&0x7) + region*8)*2 + side; +} + + +void +analysis:: +make_fit( + char* file, + float offset, + float slopex, + int stepsize=1, + int maxPulse=500) { + + using namespace std; + + vector v_x(255/stepsize); // Make x axis for hists + + TH1D* Fpn = new TH1D("FPNHist", "FPNHist", 255, 0, 255); + TH1D* ThN = new TH1D("ThermNoiseHist", "ThermNoiseHist", 40, 0, 20); + + cout << "Reading data from CSV..." << endl; + + cout << file << '\n'; + + ifstream ifs(file); + + string line; + Int_t linecounter = 0; + Int_t failedFit = 0; + Int_t noisy = 0; + Int_t dead = 0; + Float_t max = maxPulse + 0.; + + Int_t noisyCondition = (255 - 50.) /(stepsize * max); // Pixel noisy if it responds 100 % of time above 50 electrons + Int_t deadCondition = (255 - 200.) /(stepsize * max); // Pixel dead if it responds less than 100 % of times after 205 electrons + + while (getline(ifs, line)) { + + TH1I* SCurve = split(line, '\t', stepsize); + TF1 *ferrf = new TF1("ferrf", "0.5*[0]*(1+TMath::Erf((x-[1])/(TMath::Sqrt2()*[2])))",0,250); + ferrf->SetParameter(0,max); + ferrf->SetParameter(1, 150); + ferrf->SetParameter(2, 5); + + try{ + SCurve->Fit("ferrf", "Q"); + + if (ferrf->Eval(0) >= 0.08 * max) {++noisy;} + else if (ferrf->Eval(250) <= 0.7 * max) {++dead;} + + else { + Fpn->Fill(ferrf->GetParameter(1)); + ThN->Fill(ferrf->GetParameter(2)); + } + + + + } + catch (...) {++failedFit;} + + + // Fill thermal noise hist + delete SCurve; + delete ferrf; + + ++linecounter; + } + + cout << "Fitting S curves done." << endl; + cout << "Fitting Threshold and Noise Histograms." << endl; + TCanvas *t1 = new TCanvas(); + + TF1 *gausThn = new TF1("gausThn", "gaus", 1, 20); + TF1 *gausFpn = new TF1("gausFpn", "gaus", 30, 255); + gausFpn->SetParameter(1, 150); + gausFpn->SetParameter(2, 10); + gausThn->SetParameter(1, 5); + gausThn->SetParameter(2, 4); + //ThN->Draw(); + ThN->Fit("gausThn"); + TString thnText = "Thermal noise: " + to_string(gausThn->GetParameter(1) * slopex); + TText* mylatexThn = new TText(0,0,thnText); + mylatexThn->Draw(); + t1->SaveAs("THN.png"); + + TCanvas *t2 = new TCanvas(); + Fpn->Fit("gausFpn"); + TString fpnText = "Mean: " + to_string(gausFpn->GetParameter(1)*slopex + offset) + ", FPN: " + to_string(gausFpn->GetParameter(2)*slopex) + ", Dead: " + to_string(dead) + ", Noisy: " + to_string(noisy); + TText* mylatexFpn = new TText(2,6,fpnText); + mylatexFpn->SetTextSize(0.02); + mylatexFpn->Draw(); + t2->SaveAs("FPN.png"); + + cout << gausThn->GetParameter(0) << endl; + cout << gausThn->GetParameter(1) << endl; + + cout << "Thermal Noise: " << gausThn->GetParameter(1) * slopex << endl; + cout << "Mean Threshold: " << gausFpn->GetParameter(1) * slopex + offset << endl; + cout << "Fixed Pattern Noise: " << gausFpn->GetParameter(2) * slopex << endl; + cout << "Dead: " << dead << endl; + cout << "Noisy: " << noisy << endl; + cout << "Data read. Fitting now..." << endl; + + TFile* t = new TFile("histograms.root", "recreate"); + t->WriteObject(Fpn, "FPN"); + t->WriteObject(ThN, "THN"); + t->Close(); +} + +// float GetMeanHist(TH1I* input, int stepsize){ +// using namespace std; +// TH1I* he1 = new TH1I("he1", "he1",255/stepsize,0, 255); +// +// for (int i = 1; i < (255/stepsize)-1; ++i){ +// +// he1->SetBinContent(i, input->GetBinContent(i+1) - input->GetBinContent(i)); +// +// } +// cout << he1->GetMean(1) << endl; +// he1->ResetStats(); +// return he1->GetMean(1); +// he1->Reset(); +// +// } + +void +analysis:: +make_quick_fit( + char* file, + float offset, + float slopex, + int stepsize=1, + int maxPulse=500, + int start=0, + int end=255) { + +using namespace std; + + vector v_x(255/stepsize); // Make x axis for hists + + TH1D* Fpn = new TH1D("FPNHist", "FPNHist", 255, 0, 255); + TH1D* ThN = new TH1D("ThermNoiseHist", "ThermNoiseHist", 40, 0, 20); + + cout << "Reading data from CSV..." << endl; + + cout << file << '\n'; + + ifstream ifs(file); + + string line; + Int_t linecounter = 0; + Int_t failedFit = 0; + Int_t noisy = 0; + Int_t dead = 0; + Int_t badFit = 0; + Float_t max = maxPulse + 0.; + float startx = 150; + float width = 10; + float minThrLimit = 20; + float maxThrLimit = 230; + float minNoiseLim = 0.5; + float maxNoiseLim = 20; + ofstream outfile("BadFittedPixels.txt"); + + + while (getline(ifs, line)) { + + TH1I* SCurve = split(line, '\t', stepsize); + TF1 *ferrf = new TF1("ferrf", "0.5*[0]*(1+TMath::Erf((x-[1])/(TMath::Sqrt2()*[2])))",start,end); + ferrf->FixParameter(0,max); + ferrf->SetParameter(1, startx); + ferrf->SetParLimits(1,minThrLimit,maxThrLimit); + ferrf->SetParameter(2, width); + ferrf->SetParLimits(2,minNoiseLim,maxNoiseLim); + ferrf->SetParError(1, 0.1); + ferrf->SetParError(2, 0.001); + + try{ + SCurve->Fit("ferrf", "Q"); + // SCurve->Draw("L same"); + + if (ferrf->GetParameter(1) == 150 || ferrf->GetParameter(1) <= minThrLimit + 0.1 || ferrf->GetParameter(1) >= maxThrLimit - 0.1 || ferrf->GetParameter(2) <= minNoiseLim + 0.002 || ferrf->GetParameter(2) >= maxNoiseLim - 0.002) { + ++badFit; + outfile << GetBadX(line, '\t') << "\t" << GetBadY(line, '\t') << endl; + } + else if (ferrf->Eval(start) >= 0.2 * max) {++noisy;} + else if (ferrf->Eval(end) <= 0.8 * max) {++dead;} + + else { + Fpn->Fill(ferrf->GetParameter(1)); + ThN->Fill(ferrf->GetParameter(2)); + ferrf->DrawCopy("same"); + } + + + } + catch (...) {++failedFit;} + + + // Fill thermal noise hist + delete SCurve; + delete ferrf; + + ++linecounter; + + } + outfile.close(); + cout << "Fitting S curves done." << endl; + cout << "Fitting Threshold and Noise Histograms." << endl; + TCanvas *t1 = new TCanvas(); + + TF1 *gausThn = new TF1("gausThn", "gaus", 1, 20); + TF1 *gausFpn = new TF1("gausFpn", "gaus", 30, 255); + gausFpn->SetParameter(1, Fpn->GetMean(1)); + gausFpn->SetParameter(2, Fpn->GetStdDev(1)); + gausThn->SetParameter(1, ThN->GetMean(1)); + gausThn->SetParameter(2, ThN->GetStdDev(1)); + //ThN->Draw(); + ThN->Fit("gausThn"); + TString thnText = "Thermal noise: " + to_string(gausThn->GetParameter(1) * slopex); + TText* mylatexThn = new TText(0,0,thnText); + mylatexThn->Draw(); + t1->SaveAs("THN.png"); + + TCanvas *t2 = new TCanvas(); + Fpn->Fit("gausFpn"); + TString fpnText = "Mean: " + to_string(gausFpn->GetParameter(1)*slopex + offset) + ", FPN: " + to_string(gausFpn->GetParameter(2)*slopex) + ", Bad Fit:" + to_string(badFit); + TText* mylatexFpn = new TText(2,6,fpnText); + mylatexFpn->SetTextSize(0.02); + mylatexFpn->Draw(); + t2->SaveAs("FPN.png"); + + cout << gausThn->GetParameter(0) << endl; + cout << gausThn->GetParameter(1) << endl; + + cout << "Thermal Noise: " << gausThn->GetParameter(1) * slopex << endl; + cout << "Mean Threshold: " << gausFpn->GetParameter(1) * slopex + offset << endl; + cout << "Fixed Pattern Noise: " << gausFpn->GetParameter(2) * slopex << endl; + cout << "Dead: " << dead << endl; + cout << "Noisy: " << noisy << endl; + cout << "Data read. Fitting now..." << endl; + + TFile* t = new TFile("histograms.root", "recreate"); + t->WriteObject(Fpn, "FPN"); + t->WriteObject(ThN, "THN"); + t->Close(); +} + + + +// void +// analysis:: +// pixel_dump( +// int fpga, +// int frameLimit, +// char* src="mbss://localhost:36790") +// { +// int maxCounts = frameLimit; +// TH2I* PixelMatrix = new TH2I("PixelMatrix", "PixelMatrix", 1024, 0, 1023, 504, 0, 503); +// +// +// char * source = src; +// hadaq::ReadoutHandle ref = hadaq::ReadoutHandle::Connect(source); +// if (ref.null()) return; +// hadaq::RawEvent *evnt = nullptr; +// +// int mimTra = 0; +// +// while( mimTraNextSubevent(sub)) != nullptr) +// { +// if (sub->GetId() == fpga) +// { +// unsigned size = sub->GetNrOfDataWords(); +// +// int headerNow = 0; +// +// uint32_t mimFraCnt; +// uint32_t mimFraCntOpt; +// +// unsigned region = 0, column = 0, row = 0; +// +// for( unsigned i = 0; i(sub->Data(i)); +// +// if((data & 0xFF000000) == 0xFE000000) { +// +// ++headerNow; +// +// if(headerNow == 1) { +// +// mimFraCnt = (data & 0xFF0000) >> 16; +// mimFraCnt += (data & 0xFF) << 8; +// +// } else if(headerNow == 2) { +// +// mimFraCnt += data & 0xFF0000; +// mimFraCnt += (data & 0xFF) << 24; +// +// } else if(headerNow == 3) { +// mimFraCntOpt = (data & 0xFF0000) >> 16; +// mimFraCntOpt += (data & 0xFF) << 8; +// } else if(headerNow == 4) { +// mimFraCntOpt += data & 0xFF0000; +// mimFraCntOpt += (data & 0xFF) << 24; +// } +// +// } else if((data & 0xFF000000) == 0xFF000000) { +// +// headerNow = 0; +// mimTra++; +// +// } else { +// +// if( (data & 0xFF000000) == 0xFD000000 ) { +// +// int tmp = (data>>16) & 0xFF; +// if(tmp > 63) continue; +// region = tmp; +// +// } else { +// +// decode_pixel(data>>16,column,row,region); +// PixelMatrix->Fill(column, row); +// } +// +// if((data & 0x0000FF00) != 0x0000FC00) { +// +// decode_pixel(data&0xFFFF,column,row,region); +// PixelMatrix->Fill(column, row); +// } +// } +// +// if(mimTra >= maxCounts) { +// goto MAXCOUNTS; +// } +// } // End loop over data in sub event +// } +// } // End loop over sub-events in event +// } +// MAXCOUNTS: +// ; +// ref.Disconnect(); +// +// TFile* t = new TFile("PixelMatrix.root", "recreate"); +// t->WriteObject(PixelMatrix, "PixelMatrix"); +// t->Close(); +// +// TCanvas *t2 = new TCanvas(); +// PixelMatrix->Draw(); +// +// PixelMatrix->SaveAs("NoiseHist.pdf","pdf"); +// +// delete PixelMatrix; +// } + + +void +analysis:: +pixel_dump( + int fpga, + int frameLimit, + char* src="mbss://localhost:36790") +{ + int maxCounts = frameLimit; + TH2I* PixelMatrix = new TH2I("PixelMatrix", "PixelMatrix", 1024, 0, 1023, 504, 0, 503); + + + char * source = src; + hadaq::ReadoutHandle ref = hadaq::ReadoutHandle::Connect(source); + if (ref.null()) return; + hadaq::RawEvent *evnt = nullptr; + + int mimTra = 0; + + while( mimTraNextSubevent(sub)) != nullptr) + { + if (sub->GetId() == fpga) + { + unsigned size = sub->GetNrOfDataWords(); + + int headerNow = 0; + + uint32_t mimFraCnt; + uint32_t mimFraCntOpt; + + unsigned region = 0, column = 0, row = 0; + + for( unsigned i = 0; i(sub->Data(i)); + + if((data & 0xFF000000) == 0xFE000000) { + + ++headerNow; + + if(headerNow == 1) { + + mimFraCnt = (data & 0xFF0000) >> 16; + mimFraCnt += (data & 0xFF) << 8; + + } else if(headerNow == 2) { + + mimFraCnt += data & 0xFF0000; + mimFraCnt += (data & 0xFF) << 24; + + } else if(headerNow == 3) { + mimFraCntOpt = (data & 0xFF0000) >> 16; + mimFraCntOpt += (data & 0xFF) << 8; + } else if(headerNow == 4) { + mimFraCntOpt += data & 0xFF0000; + mimFraCntOpt += (data & 0xFF) << 24; + } + + } else if((data & 0xFF000000) == 0xFF000000) { + + headerNow = 0; + mimTra++; + + } + + else { + + if( (data & 0xFF000000) == 0xFD000000 ) { + + int tmp = (data>>16) & 0xFF; + if(tmp > 63) continue; + region = tmp; + + } else { + + decode_pixel(data>>16,column,row,region); + PixelMatrix->Fill(column, row); + + int code = (data >> 16) & 0b111; + + if ( code & 0b1) { + + int codeTmp = 1; + decode_pixel(((data >> 16) + (codeTmp << 6)), column, row, region); + PixelMatrix->Fill(column, row); + } + + if ( code & 0b10) { + + int codeTmp = 2; + decode_pixel(((data >> 16) + (codeTmp << 6)), column, row, region); + PixelMatrix->Fill(column, row); + } + + if ( code & 0b100) { + + int codeTmp = 3; + decode_pixel(((data >> 16) + (codeTmp << 6)), column, row, region); + PixelMatrix->Fill(column, row); + } + } + + if((data & 0x0000FF00) != 0x0000FC00) { + + decode_pixel(data&0xFFFF,column,row,region); + PixelMatrix->Fill(column, row); + + int code = (data & 0xFFFF) & 0b111; + + if ( code & 0b1) { + + int codeTmp = 1; + decode_pixel(((data & 0xFFFF) + (codeTmp << 6)), column, row, region); + PixelMatrix->Fill(column, row); + } + + if ( code & 0b10) { + + int codeTmp = 2; + decode_pixel(((data & 0xFFFF) + (codeTmp << 6)), column, row, region); + PixelMatrix->Fill(column, row); + } + + if ( code & 0b100) { + + int codeTmp = 3; + decode_pixel(((data & 0xFFFF) + (codeTmp << 6)), column, row, region); + PixelMatrix->Fill(column, row); + } + } + } + + if(mimTra >= maxCounts) { + goto MAXCOUNTS; + } + } // End loop over data in sub event + } + } // End loop over sub-events in event + } + MAXCOUNTS: + ; + ref.Disconnect(); + + TFile* t = new TFile("PixelMatrix.root", "recreate"); + t->WriteObject(PixelMatrix, "PixelMatrix"); + t->Close(); + + TCanvas *t2 = new TCanvas(); + PixelMatrix->Draw(); + + PixelMatrix->SaveAs("NoiseHist.pdf","pdf"); + + delete PixelMatrix; +} + + +void +analysis:: +find_noisy_pixels( + char* file, + int frameLimit, + float noiseLimit) +{ + using namespace std; + + TFile inputFile (file); + TH2I* PixelMatrix = nullptr; + inputFile.GetObject("PixelMatrix",PixelMatrix); + string noisyPix = "x-coordinate\ty-coordinate\tRate\n"; + + for (Int_t x = 0; x < 1024; ++x) { + + for (Int_t y = 0; y < 504; ++y) { + + if (PixelMatrix->GetBinContent(PixelMatrix->GetBin(x,y)) >= frameLimit * noiseLimit) { + + noisyPix.append(to_string(x) + "\t" + to_string(y) + "\t" + to_string((PixelMatrix->GetBinContent(PixelMatrix->GetBin(x,y)) + 0.) / frameLimit) + "\n"); + + } + + } + + } + + ofstream outfile("noisyPixels.txt"); + outfile << noisyPix; + outfile.close(); + +} + +void +analysis:: +plot_dead_pixels( + char* matA, + char* matB, + char* matC, + char* matD +) { + using namespace std; + TH2I* PixelMatrix = new TH2I("PixelMatrix", "PixelMatrix", 1024, 0, 1023, 504, 0, 503); + + ifstream ifsA(matA); + string lineA; + + while (getline(ifsA, lineA)) { + + stringstream ss(lineA); + Int_t counter = 0; + Int_t x; + Int_t y; + while(getline(ss, lineA, '\t')) { + TString llineA (lineA); + if (counter == 0) {x = llineA.Atoi();} + if (counter == 1) {y = llineA.Atoi();} + ++counter; + } + PixelMatrix->Fill(x, y); + + } + + ifstream ifsB(matB); + string lineB; + + while (getline(ifsB, lineB)) { + + stringstream ss(lineB); + Int_t counter = 0; + Int_t x; + Int_t y; + while(getline(ss, lineB, '\t')) { + TString llineB (lineB); + if (counter == 0) {x = llineB.Atoi();} + if (counter == 1) {y = llineB.Atoi();} + ++counter; + } + PixelMatrix->Fill(x, y); + + } + + ifstream ifsC(matC); + string lineC; + + while (getline(ifsC, lineC)) { + + stringstream ss(lineC); + Int_t counter = 0; + Int_t x; + Int_t y; + while(getline(ss, lineC, '\t')) { + TString llineC (lineC); + if (counter == 0) {x = llineC.Atoi();} + if (counter == 1) {y = llineC.Atoi();} + ++counter; + } + PixelMatrix->Fill(x, y); + + } + + ifstream ifsD(matD); + string lineD; + + while (getline(ifsD, lineD)) { + + stringstream ss(lineD); + Int_t counter = 0; + Int_t x; + Int_t y; + while(getline(ss, lineD, '\t')) { + TString llineD (lineD); + if (counter == 0) {x = llineD.Atoi();} + if (counter == 1) {y = llineD.Atoi();} + ++counter; + } + PixelMatrix->Fill(x, y); + + } + + TCanvas *t2 = new TCanvas(); + PixelMatrix->Draw(); + + t2->SaveAs("DeadPixels.png", "png"); + + +} + + +int +analysis:: +find_rough_threshold( + int fpga, + bool singleaccess, + int threshElectron, + int lowerLimitVCASN, + int higherLimitVCASN, + int VCASNStepSize, + int numberOfFrames, + char* matrix) +{ + using namespace std; + + mimosis::register_write_sec(fpga, 0x46, threshElectron, singleaccess); + + if (matrix == "A") { + + mimosis::register_write_sec(fpga, 0x49, 1, singleaccess); + mimosis::register_write_sec(fpga, 0x4A, 1, singleaccess); + mimosis::register_write_sec(fpga, 0x4B, 1, singleaccess); + + } + + else if (matrix == "B") { + + mimosis::register_write_sec(fpga, 0x48, 1, singleaccess); + mimosis::register_write_sec(fpga, 0x4A, 1, singleaccess); + mimosis::register_write_sec(fpga, 0x4B, 1, singleaccess); + + } + + else if (matrix == "C") { + + mimosis::register_write_sec(fpga, 0x48, 1, singleaccess); + mimosis::register_write_sec(fpga, 0x49, 1, singleaccess); + mimosis::register_write_sec(fpga, 0x4B, 1, singleaccess); + + } + + else if (matrix == "D") { + + mimosis::register_write_sec(fpga, 0x48, 1, singleaccess); + mimosis::register_write_sec(fpga, 0x49, 1, singleaccess); + mimosis::register_write_sec(fpga, 0x4A, 1, singleaccess); + + } + + else {return -1;} + + vector time (((higherLimitVCASN - lowerLimitVCASN) / VCASNStepSize) + 1); +// +// for (int iter = 0; iter <= (((higherLimitVCASN - lowerLimitVCASN) / VCASNStepSize) + 1); ++iter) { +// +// if (matrix == "A") {register_write_sec(fpga, 0x48, (lowerLimitVCASN + iter * VCASNStepSize), singleaccess);} +// if (matrix == "B") {register_write_sec(fpga, 0x49, (lowerLimitVCASN + iter * VCASNStepSize), singleaccess);} +// if (matrix == "C") {register_write_sec(fpga, 0x4A, (lowerLimitVCASN + iter * VCASNStepSize), singleaccess);} +// if (matrix == "D") {register_write_sec(fpga, 0x4B, (lowerLimitVCASN + iter * VCASNStepSize), singleaccess);} +// +// trb_register_write(fpga, 0x9209, iter); +// usleep(SLEEPVAL); +// auto start = high_resolution_clock::now(); +// +// int mimTra = 0; +// +// while( mimTraNextSubevent(sub)) != nullptr) && (sub->GetId() == fpga)) // Does not work!! +// while ((sub = evnt->NextSubevent(sub)) != nullptr) +// { +// if (sub->GetId() == fpga) +// { +// unsigned size = sub->GetNrOfDataWords(); +// +// int headerNow = 0; +// +// uint32_t mimFraCnt; +// uint32_t mimFraCntOpt; +// +// unsigned region = 0, column = 0, row = 0; +// +// for( unsigned i = 0; i(sub->Data(i)); +// +// if((data & 0xFF000000) == 0xFE000000) { +// +// ++headerNow; +// +// if(headerNow == 1) { +// +// mimFraCnt = (data & 0xFF0000) >> 16; +// mimFraCnt += (data & 0xFF) << 8; +// +// } else if(headerNow == 2) { +// +// mimFraCnt += data & 0xFF0000; +// mimFraCnt += (data & 0xFF) << 24; +// +// // std::printf("%x\n",mimFraCnt); +// +// } else if(headerNow == 3) { +// mimFraCntOpt = (data & 0xFF0000) >> 16; +// mimFraCntOpt += (data & 0xFF) << 8; +// } else if(headerNow == 4) { +// mimFraCntOpt += data & 0xFF0000; +// mimFraCntOpt += (data & 0xFF) << 24; +// } +// +// } else if((data & 0xFF000000) == 0xFF000000) { +// +// headerNow = 0; +// if(mimFraCnt%pulse == mod && +// mimFraCntOpt == iter) mimTra++; +// +// } else { +// +// if( (data & 0xFF000000) == 0xFD000000 ) { +// +// int tmp = (data>>16) & 0xFF; +// if(tmp > 63) continue; +// region = tmp; +// +// } +// +// if(mimTra >= maxCounts) { +// goto MAXCOUNTS; +// } +// } // End loop over data in sub event +// } +// } // End loop over sub-events in event +// } +// MAXCOUNTS: +// auto stop = high_resolution_clock::now(); +// trb_register_write(fpga, 0x9209, 0xaaaaaaaa); +// } +// +// time[iter] = duration_cast(stop-start); +// +// } +// +// double timeDiff = time[((higherLimitVCASN - lowerLimitVCASN) / VCASNStepSize) + 1] - time[0]; +// +// if (timeDiff <= 500) {return -1;} +// +// else { +// +// int lowestVCASN; +// double timediff = numeric_limits::max(); +// +// for (int iter = 0; iter <= ((higherLimitVCASN - lowerLimitVCASN) / VCASNStepSize) + 1; ++iter) { +// +// if (abs(time[iter] - timeDiff) < timediff) { +// +// lowestVCASN = lowerLimitVCASN + iter * VCASNStepSize; +// timediff = abs(time[iter] - timeDiff); +// +// } +// +// } +// +// return lowestVCASN; +// +// } + +} diff --git a/scripts/cpp/analysis.hpp b/scripts/cpp/analysis.hpp new file mode 100644 index 0000000..296baaa --- /dev/null +++ b/scripts/cpp/analysis.hpp @@ -0,0 +1,52 @@ +#ifndef ANALYSIS_HPP +#define ANALYSIS_HPP + +namespace analysis +{ + void make_fit( + char* file, + float offset, + float slopex, + int stepsize, + int maxPulse ); + + void make_quick_fit( + char* file, + float offset, + float slopex, + int stepsize, + int maxPulse, + int start, + int end); + + void pixel_dump( + int fpga, + int frameLimit, + char* src); + + void find_noisy_pixels( + char* file, + int frameLimit, + float noiseLimit + ); + + void plot_dead_pixels( + char* matA, + char* matB, + char* matC, + char* matD + ); + + int find_rough_threshold( + int fpga, + bool singleaccess, + int threshElectron, + int lowerLimitVCASN, + int higherLimitVCASN, + int VCASNStepSize, + int numberOfFrames, + char* matrix + ); +}; + +#endif //ANALYSIS_HPP