#!/usr/bin/env ruby # # == Synopsis # A simple utility for listing visit details and scan acquistion # information from the terminal, either through freshly scanning # the filesystem or connecting to an imaging database and looking # up information through there (for Image Quality Checks, for # example. # # == Examples # # %> list_visit /Data/vtrak1/raw/ries.aware.visit1/awr001_7854_02102009 # # # list_visit # # If no raw data directory is given, the current directory will be assumed. # %> cd /Data/vtrak1/raw/ries.aware.visit1/awr001_7854_02102009 # %> list_visit # # == Usage # %> list_visit # # For help use: list_vist -h # # == Options # -h, --help Displays help message # # == Author # Erik Kastman # WADRC Imaging Core # $:.unshift File.join(File.dirname(__FILE__),'..','lib') require 'pathname' require 'logger' require 'metamri' require 'optparse' def run! options = parse_options # Default to scanning the current directory if no argument was given, # otherwise go through each list. unless ARGV.length >= 1 input_directories = [Dir.pwd] else input_directories = ARGV end unless input_directories.empty? input_directories.each do |raw_directory| begin list_visit raw_directory, options rescue StandardError => e puts e puts e.backtrace if $LOG.level <= Logger::DEBUG next end end else raise IOError, "No input directories specified." end end def list_visit(raw_directory, options = {}) unless $LOG $LOG = Logger.new(STDOUT) case options[:verbose] when true $LOG.level = Logger::DEBUG when nil $LOG.level = Logger::INFO when false $LOG.level = Logger::WARN end end # First try to lookup Visit and Datasets through active_resource # Then fall back to scanning them fresh using the metamri classes. begin raise ScriptError, "Scaning filesystem directly..." if options[:force_scan] lookup_path = File.dirname(raw_directory).split(File::Separator).last == "dicoms" ? File.join(raw_directory, '..') : raw_directory visit = VisitRawDataDirectoryResource.find(:first, :params => {:search => {:path_contains => File.expand_path(lookup_path)}}) raise IOError.new("Could not lookup visit using path #{lookup_path}.") unless visit raise IOError.new("Returned visit's path #{visit.path} does not match path.") unless visit.path == File.expand_path(lookup_path) rescue ActiveResource::ConnectionError, ScriptError, IOError => e puts e unless options[:verbose] == false visit = VisitRawDataDirectory.new(raw_directory) begin visit.scan(options) rescue IndexError => e $LOG.error "Are you sure #{raw_directory} is a valid raw visit directory?" raise e end end # Output a pretty version of the visit details. # Visit is Either a RawVisitDataDirectory or a RawVisitDataDirectoryResource, # and either should respond to to_s # # Either output the entire visit (or if a search is requested) just the # datasets that match the search. unless options[:grep] visit.to_s else datasets = visit.datasets.select{ |ds| ds.series_description =~ /#{options[:grep]}/i } puts datasets.collect {|ds| ds.methods.include?('directory') ? ds.directory : ds.path } end end def parse_options options = Hash.new parser = OptionParser.new do |opts| opts.banner = "Usage: #{File.basename(__FILE__)} [options] [directory]" opts.on('-s', '--scan', "Scan filesystem directly instead of checking database first.") do options[:force_scan] = true end opts.on('-v', '--verbose', "Be wordy.") do options[:verbose] = true end opts.on('-i', '--ignore REGEXP', Regexp, "A regular expression to ignore heavy directories.") do |regexp| options[:ignore_patterns] = [regexp] end opts.on('-g', '--grep GREP', "Search series descriptions") do |grep| options[:grep] = grep options[:verbose] = false end opts.on_tail('-h', '--help', "Show this message") { puts(parser); exit } opts.on_tail("If no directory is given, default is the current directory.") opts.on_tail("Example: #{File.basename(__FILE__)} pd006") end parser.parse!(ARGV) return options end if File.basename(__FILE__) == File.basename($PROGRAM_NAME) run! end