# Avizo-Script-Object V3.0 ############################################################## # Script Search Slice # # Register all slices (or a region of slice) of a core sample to a reference slice, # in order to find the slice of the core sample which is the closest to the reference. # # The result of all alignments is saved in a spreadsheet, with maximum and minimum # metric result for all slices tested. The approximative position of the reference # slice in the core sample can be found : it corresponds to the slice with the higher # distance in the spreadsheet. # # author: Amouda Joseph (ajoseph@vsg3d.com) # (C) copyright 2012, VSG, SAS # ############################################################## # ######################################################################### # Constructor # ######################################################################### $this proc constructor {} { # Create the reference port $this newPortConnection slice HxUniformScalarField3 $this slice setLabel "Slice" # Create the port of considered slice in core sample $this newPortIntTextN bound 2 $this bound setLabel "Slices considered" $this bound setLabel 0 "Begin" $this bound setLabel 1 "End" $this bound setValue 0 1 $this bound setValue 1 1 set volumedata [$this data source] if { $volumedata != "" } { set volumeDims [$volumedata getDims] set maxSlice [lindex $volumeDims 2] $this bound setValue 1 $maxSlice $this bound setMinMax 0 1 $maxSlice $this bound setMinMax 1 1 $maxSlice } # Create a list of metric available for registration $this newPortButtonMenu metricChoice 0 1 $this metricChoice setLabel "Metric" $this metricChoice setNumOptEntries 4 $this metricChoice setOptLabel 0 "Normalized Mutual Information" $this metricChoice setOptLabel 1 "Mutual Information" $this metricChoice setOptLabel 2 "Euclidean" $this metricChoice setOptLabel 3 "Correlation" # Create histogram ranges for Mutual Information metrics $this newPortIntTextN refRange 2 $this refRange setLabel "Histogram range reference" $this refRange setLabel 0 "Min" $this refRange setLabel 1 "Max" $this refRange setValue 0 0 $this refRange setValue 1 0 $this newPortIntTextN modRange 2 $this modRange setLabel "Histogram range model" $this modRange setLabel 0 "Min" $this modRange setLabel 1 "Max" $this modRange setValue 0 0 $this modRange setValue 1 0 # Set histogram range values for model to data range if { $volumedata != "" } { set modelRange [$volumedata getRange] $this modRange setValue 0 [lindex $modelRange 0] $this modRange setValue 1 [lindex $modelRange 1] $this modRange setMinMax 0 [lindex $modelRange 0] [lindex $modelRange 1] $this modRange setMinMax 1 [lindex $modelRange 0] [lindex $modelRange 1] } # Set histogram range values for reference to reference slice range set imagedata [$this slice source] if { $imagedata != "" } { set referenceRange [$imagedata getRange] $this refRange setValue 0 [lindex $referenceRange 0] $this refRange setValue 1 [lindex $referenceRange 1] $this refRange setMinMax 0 [lindex $referenceRange 0] [lindex $referenceRange 1] $this refRange setMinMax 1 [lindex $referenceRange 0] [lindex $referenceRange 1] } # Create toggle list for transformation types $this newPortToggleList transformType 4 $this transformType setLabel "Transformation" $this transformType setLabel 0 "Rigid" $this transformType setLabel 1 "Iso-scale" $this transformType setLabel 2 "Aniso-scale" $this transformType setLabel 3 "Shear" # Set default transformation to rigid $this transformType setValue 0 1 $this transformType setValue 1 0 $this transformType setValue 2 0 $this transformType setValue 3 0 $this newPortDoIt doit $this script hide } # ######################################################################### # Destructor # ######################################################################### $this proc destructor {} { if {[$this hasVar extracter]} {remove [$this getVar extracter]} if {[$this hasVar register]} {remove [$this getVar register]} if {[$this hasVar displaySlice]} {remove [$this getVar displaySlice]} if {[$this hasVar outputImage]} {remove [$this getVar outputImage]} } # ######################################################################### # Defines the actions when the port data, reference and metricChoice is modified # ######################################################################### $this proc update {} { # Show histogram ranges if Mutual Information metrics are selected set metricNumber [$this metricChoice getOptValue 0] if {$metricNumber == 0 || $metricNumber == 1} { $this modRange show $this refRange show } # Hide histogram ranges if Correlation or Euclidean metrics are selected if {$metricNumber == 2 || $metricNumber == 3} { $this modRange hide $this refRange hide } # Update bound port and histogram ranges for model if data is modified if {[$this data isNew]} { set volumedata [$this data source] if { $volumedata != "" } { set dims [$volumedata getDims] # $this bound setValue 1 [lindex $dims 2] $this bound setMinMax 0 1 [lindex $dims 2] $this bound setMinMax 1 1 [lindex $dims 2] set modelRange [$volumedata getRange] $this modRange setValue 0 [lindex $modelRange 0] $this modRange setValue 1 [lindex $modelRange 1] $this modRange setMinMax 0 [lindex $modelRange 0] [lindex $modelRange 1] $this modRange setMinMax 1 [lindex $modelRange 0] [lindex $modelRange 1] } } # Update histogram ranges for reference if reference slice is modified if {[$this slice isNew]} { set imagedata [$this slice source] if {$imagedata != ""} { set referenceRange [$imagedata getRange] $this refRange setValue 0 [lindex $referenceRange 0] $this refRange setValue 1 [lindex $referenceRange 1] $this refRange setMinMax 0 [lindex $referenceRange 0] [lindex $referenceRange 1] $this refRange setMinMax 1 [lindex $referenceRange 0] [lindex $referenceRange 1] } } } # ######################################################################### # Defines action when button Apply was hit # ######################################################################### $this proc compute {} { # Check if Apply was hit if { ![$this doit wasHit 0] } { return } # Check if there is data on data port set volumedata [$this data source] if { $volumedata == "" } { echo "Please connect a Volume object" return } # Check if there is data on reference slice port set imagedata [$this slice source] if { $imagedata == "" } { echo "Please connect a image object" return } # Check if the reference slice is a 2D object set imageDims [$imagedata getDims] set imageDepth [lindex $imageDims 2] if { $imageDepth != 1 } { echo "ERROR : Please connect a 2D image." return } set volumeDims [$volumedata getDims] set volumeDepth [lindex $volumeDims 2] # Check if the data is a 3D object if { $volumeDepth == 1 } { echo "ERROR : The model must be a 3D image" return } # Get the initial and the final slice number of core sample to consider set init [$this bound getValue 0] set end [$this bound getValue 1] # Create spreadsheet with slice number, min and max distance set sheet [create HxSpreadSheet] $sheet setNumRows [expr $end - $init +1] $sheet addColumn "Slice Number" int $sheet addColumn "Min Distance" float $sheet addColumn "Max Distance" float # For each slice of core sample to consider for {set i $init } { $i < $end+1} {incr i} { echo "------------ Slice $i ------------" if {$i != $init} { $outputImage setTransform } # Create a Extract subvolume module if {$i == $init} { set extracter [create HxLatticeAccess] $this setVar extracter $extracter $extracter data connect $volumedata $extracter boxMin setValue 0 0 $extracter boxMin setValue 1 0 $extracter boxMin setValue 2 [expr $i - 1] $extracter boxSize setValue 0 [lindex $volumeDims 0] $extracter boxSize setValue 1 [lindex $volumeDims 1] $extracter boxSize setValue 2 1 $extracter options setValue 1 0 $extracter action hit $extracter fire set outputImage [$extracter getResult] $this setVar outputImage $outputImage } else { $extracter boxMin setValue 2 [expr $i - 1] $extracter action hit $extracter fire } # Display the slice if {$i == $init} { set displaySlice [create HxOrthoSlice] $this setVar displaySlice $displaySlice $displaySlice data connect $outputImage } set box [$outputImage getBoundingBox] # Replace the extracted image in z plan if {$i == $init} { set minX [lindex $box 0] set maxX [lindex $box 1] set minY [lindex $box 2] set maxY [lindex $box 3] set centerX [expr ($maxX - $minX)/2+$minX] set centerY [expr ($maxY - $minY)/2+$minY] } set minZ [lindex $box 4] set maxZ [lindex $box 5] set boxDepth [expr $maxZ - $minZ] set refBox [$imagedata getBoundingBox] set refMinZ [lindex $refBox 4] #$outputImage setBoundingBox $minX $maxX $minY $maxY 0 $boxDepth #$outputImage setBoundingBox $minX $maxX $minY $maxY $refMinZ $refMinZ $imagedata setTranslation 0 0 [expr $minZ-$refMinZ] # Create a Register Images module if {$i == $init} { set register [create HxAffineRegistration] $this setVar register $register $register model connect $outputImage $register reference connect $imagedata set metricNumber [$this metricChoice getOptValue 0] $register metric setValue $metricNumber $register extendedOptions setValue 0 1 $register fire if {$metricNumber == 0 || $metricNumber == 1} { $register histogramRangeRef setValue 0 [$this refRange getValue 0] $register histogramRangeRef setValue 1 [$this refRange getValue 1] $register histogramRangeMod setValue 0 [$this modRange getValue 0] $register histogramRangeMod setValue 1 [$this modRange getValue 1] $register fire } $register transform setValue 0 [$this transformType getValue 0] $register transform setValue 1 [$this transformType getValue 1] $register transform setValue 2 [$this transformType getValue 2] $register transform setValue 3 [$this transformType getValue 3] # Set the inital stepwidth for translation set initialStep [$register step getValue 0] $register step setValue 0 [expr $initialStep/4] } set minDistance inf set maxDistance -inf for {set theta 0} {$theta < 360} {incr theta 90} { $outputImage setTransform $outputImage setRotation -center $centerX $centerY 0 0 0 1 $theta #$outputImage setRotation 0 0 1 $theta #$register action setValue 0 #$register fire if {$metricNumber == 0 || $metricNumber == 1} { $register histogramRangeRef setValue 0 [$this refRange getValue 0] $register histogramRangeRef setValue 1 [$this refRange getValue 1] $register histogramRangeMod setValue 0 [$this modRange getValue 0] $register histogramRangeMod setValue 1 [$this modRange getValue 1] $register fire } $register action setValue 2 $register fire # Compute the minimal and maximal distance set lastDistance [$register getLastImageDistance] if {$minDistance > $lastDistance} { set minDistance $lastDistance } if {$maxDistance < $lastDistance} { set maxDistance $lastDistance } } # Save distance in the spreadsheet $sheet setValue 0 [expr $i - $init] $i $sheet setValue 1 [expr $i - $init] $minDistance $sheet setValue 2 [expr $i - $init] $maxDistance } }