sub rebinner_interp{ #Rebinning portion of analysis code. Define local variables used in this subroutine my $idx, my $buf, my $i, my $j, my @calibcoeff; my @energy_rebin, my @values, my @energy_before; my $chn; my @acoeff, my @bcoeff, my @ccoeff; #Note: $spec, %slope[] and %intercept[] are global variables that have been defined earlier #User to input their bin-width of choice, define new energy binning structure that is universal for all spectra printf STDOUT "Please enter the energy width (in keV) of each bin\n"; chomp (my $rebin_width = ); for ($i=0; $i<16834; $i++){ $energy_rebin[$i] = ($rebin_width * $i); } #For each spectrum, $idx, read in original spectrum in VAX format to array @rawchannel for ($idx=0; $idx<=$spec; $idx++){ my @rawchannel; open (INFILE, "<", "filename.spc") or die "Can't find spectrum: filename.spc"; while (read(INFILE, $buf, 4) == 4) { if (length($buf) > 0 && length ($buf) < 4){ next; } else{ push @rawchannel, scalar unpack('V',$buf); } } close INFILE; #For $idx, determine the energy binning before from pre-determined calibration $chn = 0; $i = 1; for ($chn=0;$chn<16384;$chn++){ if ($i == $calib_points){ $energy_before[$chn] = ($slope{$idx}[$i]*${chn})+$intercept{$idx}[$i]; } if (($chn<=$channel{$idx}[$i])&&($i<$calib_points)){ $energy_before[$chn] = ($slope{$idx}[$i]*$chn)+$intercept{$idx}[$i]; } elsif (($chn > $channel{$idx}[$i]) && ($i < $calib_points)){ $i += 1; $energy_before[$chn] = ($slope{$idx}[$i]*$chn)+$intercept{$idx}[$i]; } } #Originally, test script placed here to check the output of each @energy_rebin and @energy_before. So the script should be fine up to here. #Define @counts_rebin for each spectrum which will contain the number of counts per channel for each rebinned spectrum $j=0; my $k = 0; my @counts_rebin; my $value; #Loops to generate rebinned spectrum. First part intended to define a value for $counts_rebin[$j] if undefined. Then depending on the order add all or part of the bin as fit. Note, from test $k is always less than 16382. for($j=0; $j<=16831; $j++){ if(($energy_rebin[$k] >= $energy_before[$j])){ # l:1148 if ((defined($counts_rebin[$k]))==0){ $counts_rebin[$k]=0; } $value = $rawchannel[$j]; $counts_rebin[$k] = ($counts_rebin[$k] + $value); # l:1153 next; } if(($energy_rebin[$k] < $energy_before[$j]) && $j!=0){ my $totcount = $rawchannel[$j]; my $split1 = (($energy_before[$j]-$energy_rebin[$k])*$totcount)/($energy_before[$j]-$energy_before[${j}-1]); # l:1158 if ((defined($counts_rebin[$k]))==0){ $counts_rebin[$k]=0; } $counts_rebin[$k]=($counts_rebin[$k]+($totcount-$split1)); # l:1162 $counts_rebin[$k+1]=$split1; $k+=1; next; } if(($energy_rebin[$k]<$energy_before[$j]) && $j==0){ until ($energy_rebin[$k]>=$energy_before[$j]){ $k += 1; } $value = $rawchannel[$j]; $counts_rebin[$k] = $counts_rebin[$k] + $value; next; } } #As $counts_rebin[$j] only partially filled, define the rest of the array (up to 16382) as undefined $j=0; for ($j=0;$j<=16381;$j++){ if (defined($counts_rebin[$j])){ next; } else{ $counts_rebin[$j]=0; } } #Output the file in a little-endian VAX format open (REBINOUT, ">", "filename.spr"); binmode REBINOUT, ":raw"; for ($i=0;$i<=16831;$i++){ printf REBINOUT pack('V',$counts_rebin[$i]); # l: 1188 } close REBINOUT; } }