#
# This TCL script walks through a set of raw Mark IV images,
# looks at edge pixels, calculates an additive shift for the master
# dark frame, shifts the master dark frame, then subtracts it from
# the raw image.
#    
# MWR 2/27/2000
#
# Added "xvista_dir" to all calls to XVista programs
#   --  MWR 2/9/2001

if { [catch { set debug } ] == 1 } {
  set debug 2
}


###########################################################################
# subtract a shifted dark image from each of the given raw images
#
#      imagedir         directory in which image files are located
#      namepattern      act on all files matching the pattern
#      masterdark       name of a master dark file
#      box_start        when defining BOXes (in XVista) to calculate
#                            dark levels on edges of image, start
#                            with this box number and work upwards as needed
#
#      edgecols         a TCL list of edge columns to use for matching
#                            the master dark frame to each raw image file
#                            If the list consists of the single value "-1",
#                            then the master dark frame is used as-is,
#                            with NO shift
#
#      trim_start_row   calculate dark pixel values near edges, starting
#                            with this row ...
#      trim_end_row     ... and ending with this row
#
# This procedure modifies the raw image files!
# 
# RETURNS
#    0           if all goes well
#    1           if there's a problem
#    
proc sub_dark { imagedir namepattern masterdark box_start edgecols \
                         trim_start_row trim_end_row } {
  global debug

  if { $debug > 0 } {
    puts "entering sub_dark"
  }
  if { $debug > 1 } {
    puts "  args are $imagedir $namepattern $masterdark $box_start $edgecols "
    puts "           $trim_start_row $trim_end_row "
  }
 
  # the XVista programs live in this directory
  set xvista_dir [get_directory "xvista_dir"]
  if { $xvista_dir == {} } {
    puts stderr "sub_dark: get_directory fails for xvista_dir"
    return 1
  }

  # we use this as the name of a temporary file
  set temporary_copy "sub_dark.fit"

  # some sanity checks
  if { [file exist $masterdark] != 1 } {
    puts stderr "sub_dark: can't find master dark file $masterdark"
    return 1
  }
 
  # define boxes (starting at $box_start) for the edge column(s)
  set boxno $box_start
  set num_rows [expr 1+($trim_end_row-$trim_start_row)]
  set boxlist {}
  if { [do_not_use_edgecols $edgecols] == 1 } {
    if { $debug > 1 } {
      puts "sub_dark: skipping edge col calculations"
    }
  } else {
    foreach col $edgecols {

      # sanity check
      if { $col < 0 } {
        puts stderr "sub_dark: edge col $col is less than zero -- invalid"
	return 1
      }

      if { $debug > 1 } {
        puts "next column is $col"
        puts "about to: box $boxno sr=$trim_start_row nr=$num_rows sc=$col nc=1"
      }

      exec $xvista_dir/box $boxno sr=$trim_start_row nr=$num_rows sc=$col nc=1
      if { $debug > 1 } {
        puts "   finished box okay "
      }
      lappend boxlist $boxno
      incr boxno
    }
  }

  if { $debug > 0 } {
    puts "here comes the list of edge boxes ..."
    foreach box $boxlist {
      puts "  box $box"
    }
  }

  # calculate the mean inside each edge box for the master dark frame
  foreach box $boxlist {
    set master_mean($box) [calc_mean_in_box $masterdark $box]
    if { $debug > 0 } {
      puts [format "  master box $box has mean %7.0f" $master_mean($box) ]
    }
  }

  set globber ${imagedir}/${namepattern}
  set lis [ glob $globber ]
  foreach file $lis {
  
    set ll [split $file / ]
    set len [llength $ll]
    set image [lindex $ll [expr $len-1]]
    if { $debug > 1 } {
      puts "next file is $image "
    }

    # we make a copy of the master dark file, 
    #   and then (if necessary) we shift it by a constant amount
    exec cp $masterdark $imagedir/$temporary_copy

    # for each image, we need to calculate the mean inside each edge column
    #    we're using to shift the master dark; then we calculate the 
    #    average difference
    #    
    #      delta  =  this image's edge columns  -  master dark edge columns
    #
    #    and we'll use delta in a moment to shift a copy of the master 
    #    dark before we perform the dark subtraction

    if { [do_not_use_edgecols $edgecols] == 0 } {
      set mean_sum 0
      set mean_n 0
      foreach box $boxlist {
        set this_mean($box) [calc_mean_in_box $file $box]
        set diff [expr $this_mean($box) - $master_mean($box)]
        if { $debug > 1 } {
          puts [format "  box $box image $image: mean %7.0f diff %7.0f "  \
                             $this_mean($box) $diff]
        }
        set mean_sum [expr $mean_sum+$diff]
        incr mean_n
      }
      if { $mean_n <= 0 } {
        puts stderr "sub_dark: can't calculate delta, zero boxes?"
        return 1
      }
      set delta [expr $mean_sum/$mean_n]
      if { $debug > 0 } {
        puts [format "sub_dark: for image $image, delta is %7.2f " $delta]
      }

      # okay, now that we know how by how much we need to shift 
      #    the master dark, we shift it 
      exec $xvista_dir/add $imagedir/$temporary_copy const=$delta

    } else {

      # in this case, we don't need to shift the master dark
      set delta 0
    }
      
    # and now we subtract that copy of the master dark (which might have
    #    been shifted) from the raw image
    #    
    exec $xvista_dir/sub $file $imagedir/$temporary_copy

    # now write some comments in the FITS header of the file to indicate
    #    that we've subtracted a master dark file
    set datestr [exec date]
    exec $xvista_dir/comment $file "subtracted master dark file $masterdark"
    exec $xvista_dir/comment $file "  with delta $delta on $datestr"

    
  }


  # now clean up
  if { [file exists $imagedir/$temporary_copy] == 1 } {
    exec /bin/rm -f $imagedir/$temporary_copy
  }

  return 0
}



#############################################################################
# Given a FITS file, and a box number (which has already been defined
#    to contain one of the edge columns), run the "mn" program to
#    calculate the mean value inside the box.
#    
# RETURNS
#    the mean value
#  
proc calc_mean_in_box { imagefile box } {

  # the XVista programs live in this directory
  set xvista_dir [get_directory "xvista_dir"]
  if { $xvista_dir == {} } {
    puts stderr "sub_dark: get_directory fails for xvista_dir"
    return 1
  }

  set vals [exec $xvista_dir/mn $imagefile box=$box]
  set ll [lindex $vals 0]
  set mean [lindex [split $ll =] 1]

  return $mean
}


#############################################################################
# PROCEDURE: do_not_use_edgecols
# 
# DESCRIPTION: figure out if we should use the edge columns to 
#              shift the dark current by a constant amount, or not.
#             
#              If the only value for "edgecols" is -1, then 
#                 we do NOT want to shift dark current.
#                 In that case, return 1
#
#              If there are any other values in "edgecols" besides -1,
#                 then we DO want to shift the dark current.
#                 In that case, return 0
#    
# RETURNS
#      0           if we should shift dark current
#      1           if we should NOT
#  
proc do_not_use_edgecols { edgecols } {
  global debug

  if { $edgecols == -1 } {
    if { $debug > 1 } {
      puts "do_not_use_edgecols: do NOT use edgecols"
    }
    set ret 1
  } else {
    if { $debug > 1 } {
      puts "do_not_use_edgecols: DO use edgecols"
    }
    set ret 0
  }

  return $ret
}



