def main():
    try:
        try:
            usage = "usage: cam2map4stereo.py [--help][--manual][--map mapfile][--pixres CAMERA|MAP|MPP|PPD][--resolution float][--interp NN|BI|CC][--lat min:max][--lon min:max][--prefix string] [--suffix string] image1.cub image2.cub\n" + get_asp_version(
            )
            parser = optparse.OptionParser(usage=usage)
            parser.set_defaults(dryrun=False)
            parser.set_defaults(pixres='MPP')
            parser.set_defaults(prefix='')
            parser.set_defaults(suffix='map')
            parser.add_option("--manual",
                              action="callback",
                              callback=man,
                              help="Read the manual.")
            parser.add_option("-m",
                              "--map",
                              dest="map",
                              help="The mapfile to use for cam2map.")
            parser.add_option(
                "-p",
                "--pixres",
                dest="pixres",
                help="The pixel resolution mode to use for cam2map.")
            parser.add_option("-r",
                              "--resolution",
                              dest="resolution",
                              help="Resolution of final map for cam2map.")
            parser.add_option("-i",
                              "--interp",
                              dest="interp",
                              help="Pixel interpolation scheme for cam2map.")
            parser.add_option(
                "-a",
                "--lat",
                dest="lat",
                help="Latitude range for cam2map where LAT is minlat:maxlat.")
            parser.add_option(
                "-o",
                "--lon",
                dest="lon",
                help="Longitude range for cam2map where LON is minlon:maxlon.")
            parser.add_option(
                "--prefix",
                dest="prefix",
                help=
                "Make all output files use this prefix. Default: no prefix.")
            parser.add_option(
                "-s",
                "--suffix",
                dest="suffix",
                help="Suffix that gets inserted in the output file names.")
            parser.add_option(
                "-n",
                "--dry-run",
                dest="dryrun",
                action="store_true",
                help=
                "Make calculations, but print cam2map command, but don't actually run it."
            )

            (options, args) = parser.parse_args()

            if not args: parser.error("need .cub files")

        except optparse.OptionError as msg:
            raise Usage(msg)

        # Call camrange to get bounds. If the lon bounds come as [0, 360] then try a different group.
        success = False
        lonGroupNames = [
            'UniversalGroundRange', 'PositiveEast180', 'PositiveWest180',
            'PositiveWest360'
        ]
        for lonGroupName in lonGroupNames:
            image1 = camrange(args[0], lonGroupName, options)
            image2 = camrange(args[1], lonGroupName, options)
            lonRange = float(max(image1.maxlon, image2.maxlon)) - \
                       float(min(image1.minlon, image2.minlon))
            if lonRange >= 360.0:
                print("With lonGroupName = " + lonGroupName + " found a longitude range of " + \
                      str(lonRange) + ". Will try the next group from: " + (" ".join(lonGroupNames)))
            else:
                success = True
                break

        if not success:
            raise Exception(
                'ProcessError',
                'The longitude range keeps on coming as encompasing the entire planet. Something is wrong.'
            )

        mapout = ImgInfo()

        mapout.minlat = max(image1.minlat, image2.minlat)
        mapout.maxlat = min(image1.maxlat, image2.maxlat)
        mapout.minlon = max(image1.minlon, image2.minlon)
        mapout.maxlon = min(image1.maxlon, image2.maxlon)
        mapout.resolution = max(image1.resolution, image2.resolution)

        if (options.resolution): mapout.resolution = options.resolution
        if (options.lat):
            latrange = options.lat.split(':')
            if latrange[0]: mapout.minlat = latrange[0]
            if latrange[1]: mapout.maxlat = latrange[1]
        if (options.lon):
            lonrange = options.lon.split(':')
            if lonrange[0]: mapout.minlon = lonrange[0]
            if lonrange[1]: mapout.maxlon = lonrange[1]

        # call cam2map with the arguments

        cam2map = [
            'cam2map', 'from=' + args[0],
            'to=' + mapfile(args[0], options.prefix, options.suffix)
        ]

        if (options.map):
            cam2map.append('map=' + options.map)
        if (options.interp):
            cam2map.append('interp=' + options.interp)

        cam2map.append('pixres=' + options.pixres)
        cam2map.append('resolution=' + mapout.resolution)

        cam2map.append('defaultrange=MAP')
        cam2map.append('minlat=' + mapout.minlat)
        cam2map.append('maxlat=' + mapout.maxlat)
        cam2map.append('minlon=' + mapout.minlon)
        cam2map.append('maxlon=' + mapout.maxlon)

        # Run for first image

        # Need to put these together to keep ISIS from calling the GUI
        cam2map_cmd = ' '.join(cam2map)
        print(cam2map_cmd)
        if (not options.dryrun):
            code = subprocess.call(cam2map_cmd, shell=True)
            if not code == 0:
                raise Exception('ProcessError',
                                'Non zero return code (' + str(code) + ')')

        # Run for second image
        cam2map[1] = 'from=' + args[1]
        cam2map[2] = 'to=' + mapfile(args[1], options.prefix, options.suffix)
        cam2map_cmd = ' '.join(cam2map)
        print(cam2map_cmd)
        if (not options.dryrun):
            code = subprocess.call(cam2map_cmd, shell=True)
            if not code == 0:
                raise Exception('ProcessError',
                                'Non zero return code (' + str(code) + ')')

        print("Finished")
        return 0

    except Usage as err:
        print(err.msg, file=sys.stderr)
        # print >>sys.stderr, "for help use --help"
        return 2

    except MapExists as e:
        print('The file ' + e.msg + ' already exists, delete first.',
              file=sys.stderr)
        return 3
Beispiel #2
0
def main():
    try:
        try:
            usage = "usage: hiedr2mosaic.py [--help][--manual][--threads N][--keep][-m match] HiRISE-EDR.IMG-files\n  " + get_asp_version()
            parser = optparse.OptionParser(usage=usage)
            parser.set_defaults(delete=True)
            parser.set_defaults(match=5)
            parser.set_defaults(threads=4)
            parser.add_option("--manual", action="callback", callback=man,
                              help="Read the manual.")
            parser.add_option("--stop-at-no-proj", dest="stop_no_proj", action="store_true",
                              help="Process the IMG files only to have SPICE attached. This allows jigsaw to happen")
            parser.add_option("--resume-at-no-proj", dest="resume_no_proj", action="store_true",
                              help="Pick back up after spiceinit has happened or jigsaw. This was noproj uses your new camera information")
            parser.add_option("-t", "--threads", dest="threads",
                              help="Number of threads to use.",type="int")
            parser.add_option("-m", "--match", dest="match",type="int",
                              help="CCD number of match CCD, passed as the match argument to noproj (default 5).")
            parser.add_option("-k", "--keep", action="store_false",
                              dest="delete",
                              help="Will not delete intermediate files.")
            parser.add_option("--download-folder", dest="download_folder", default=None,
                              help="Download files to this folder. Hence the second argument to this is the URL of the page to download the files from.")

            (options, args) = parser.parse_args()

            if not args: 
                parser.error("need .IMG files or a URL")
            
            if options.download_folder:
                print ('Downloading HiRISE images from URL...')
                # For now we only fetch RED images.
                args = fetch_files(args[0], options.download_folder, image_type='RED')
                print ('Finished downloading ' + str(len(args)) + ' images.')

            # Verify that we have both of the specified match CCD's.
            # This is applicable only when we start with initial IMG files.
            if not options.resume_no_proj:            
                matchCount = 0
                for a in args:
                    if get_ccd(a) == options.match:
                        matchCount += 1
                        
                if matchCount != 2:
                    print ('Error: Found ' + str(matchCount) + ' files for match CCD ' 
                           + str(options.match) + ' instead of 2.')
                    return -1

            numCcds = len(args) / 2

        except optparse.OptionError as msg:
            raise Usage(msg)

        if not options.resume_no_proj:
            # hi2isis
            hi2isised = hi2isis( args, options.threads )

            # hical
            hicaled = hical( hi2isised, options.threads, options.delete )

            # histitch
            histitched = histitch( hicaled, options.threads, options.delete )

            # attach spice
            spice( histitched, options.threads )

        if options.stop_no_proj:
            print("Finished")
            return 0

        if options.resume_no_proj:
            histitched = args

        CCD_files = CCDs( histitched, options.match )

        # noproj
        noprojed_CCDs = noproj( CCD_files, options.threads, options.delete )

        # hijitreg
        averages = hijitreg( noprojed_CCDs, options.threads, options.delete )

        # mosaic handmos
        mosaicked = mosaic( noprojed_CCDs, averages )

        # Clean up noproj files
        if options.delete:
          for cub in noprojed_CCDs.values():
              os.remove( cub )

        # Run a final cubenorm across the image:
        cubenorm( mosaicked, options.delete )

        print("Finished")
        return 0

    except Usage as err:
        print (err.msg, file = sys.stderr)
        return 2
def main():
    try:
        try:
            usage = "usage: lronac2mosaic.py [--help][--manual][--crop][--threads N]" \
                    "[--keep] LRONAC.IMG-files\n  " + get_asp_version()
            parser = optparse.OptionParser(usage=usage)
            parser.set_defaults(delete=True)
            parser.set_defaults(cropAmount=0)
            parser.set_defaults(threads=4)
            parser.set_defaults(fakePvl=True)
            parser.add_option("--manual",
                              action="callback",
                              callback=man,
                              help="Read the manual.")
            parser.add_option("-o",
                              "--output-dir",
                              dest="outputFolder",
                              help="Output folder (default to input folder).",
                              type="string")
            parser.add_option(
                "--stop-at-no-proj",
                dest="stop_no_proj",
                action="store_true",
                help="Process the IMG files only to have SPICE attached.")
            parser.add_option(
                "--resume-at-no-proj",
                dest="resume_no_proj",
                action="store_true",
                help=
                "Pick back up after spiceinit has happened. This was noproj uses your new camera information"
            )
            parser.add_option(
                "-c",
                "--crop",
                dest="cropAmount",
                help="Process only the first N lines of the image.",
                type="int")
            parser.add_option("-t",
                              "--threads",
                              dest="threads",
                              help="Number of threads to use.",
                              type="int")
            parser.add_option("-k",
                              "--keep",
                              action="store_false",
                              dest="delete",
                              help="Will not delete intermediate files.")
            parser.add_option(
                "--p",
                dest="fakePvl",
                action="store_true",
                help="Don't automatically create a LRONAC pvl file")
            (options, args) = parser.parse_args()

            if not args: parser.error("need .IMG files")

        except optparse.OptionError as msg:
            raise Usage(msg)

        # Make sure only one pair of cubes was passed in
        input_file_pair = build_cube_pairs(args)
        if len(input_file_pair) > 1:
            raise Usage(
                'Input error: Only one pair of input files are allowed!')

        if not options.outputFolder:  # Set the output folder equal to the input folder
            options.outputFolder = os.path.dirname(args[0])
        print('Using output folder: ' + options.outputFolder)
        if not os.path.exists(
                options.outputFolder) and len(options.outputFolder) > 1:
            os.makedirs(options.outputFolder)

        print("Beginning processing.....")

        if not options.resume_no_proj:  # If not skipping to later point

            print(
                "lronac2isis")  # Per-file operation, returns list of new files
            lronac2isised = lronac2isis(args, options.threads,
                                        options.outputFolder)

            print("lronaccal")  # Per-file operation, returns list of new files
            lronaccaled = lronaccal(lronac2isised, options.threads,
                                    options.delete)

            print(
                "lronacecho")  # Per-file operation, returns list of new files
            lronacechod = lronacecho(lronaccaled, options.threads,
                                     options.delete)

            if (options.cropAmount >
                    0):  # Crop the input files as soon as ISIS calls allow it
                lronacechod = cropInputs(lronacechod, options.outputFolder,
                                         options.cropAmount, options.threads,
                                         options.delete)

            print(
                "spice")  # Attach spice info to cubes (adds to existing files)
            spice(lronacechod, options.threads)

        if options.stop_no_proj:  # Stop early if requested
            print("Finished")
            return 0

        if options.resume_no_proj:  # If resume option was set
            lronacechod = args

        print("build_cube_pairs")  # Detected corresponding pairs of cubes
        lronac_file_pairs = build_cube_pairs(lronacechod)

        print("noproj")  # Per-file operation
        noprojed_file_pairs = noproj(lronac_file_pairs, options.threads,
                                     options.delete, options.fakePvl,
                                     options.outputFolder)

        print("lronacjitreg")  # Determines mean shift for each file pair
        averages = lronacjitreg(noprojed_file_pairs, options.threads,
                                options.delete)

        print("mosaic")  # handmos - Use mean shifts to combine the file pairs
        mosaicked = mosaic(noprojed_file_pairs, averages, options.threads)

        # Clean up noproj files
        if (options.delete):
            for cub in noprojed_file_pairs.values():
                os.remove(cub[0])
                os.remove(cub[1])

        # Run a final cubenorm across the image:
        cubenorm(mosaicked, options.threads, options.delete)

        print("Finished")
        return 0

    except Usage as err:
        print >> sys.stderr, err.msg
        return 2
def main():
    try:
        try:
            usage = "usage: lronac2mosaic.py [--help][--manual][--crop][--threads N]" \
                    "[--keep] LRONAC.IMG-files\n  " + get_asp_version()
            parser = optparse.OptionParser(usage=usage)
            parser.set_defaults(delete =True)
            parser.set_defaults(cropAmount=0)
            parser.set_defaults(threads=4)
            parser.set_defaults(fakePvl=True)
            parser.add_option("--manual", action="callback", callback=man,
                              help="Read the manual.")
            parser.add_option("-o", "--output-dir", dest="outputFolder",
                              help="Output folder (default to input folder).",type="string")
            parser.add_option("--stop-at-no-proj", dest="stop_no_proj", action="store_true",
                              help="Process the IMG files only to have SPICE attached.")
            parser.add_option("--resume-at-no-proj", dest="resume_no_proj", action="store_true",
                              help="Pick back up after spiceinit has happened. This was noproj uses your new camera information")
            parser.add_option("-c", "--crop", dest="cropAmount",
                              help="Process only the first N lines of the image.",type="int")
            parser.add_option("-t", "--threads", dest="threads",
                              help="Number of threads to use.",type="int")
            parser.add_option("-k", "--keep", action="store_false",
                              dest="delete",
                              help="Will not delete intermediate files.")
            parser.add_option("--p", dest="fakePvl", action="store_true",
                              help="Don't automatically create a LRONAC pvl file")
            (options, args) = parser.parse_args()

            if not args: parser.error("need .IMG files")

        except optparse.OptionError as msg:
            raise Usage(msg)

        # Make sure only one pair of cubes was passed in
        input_file_pair = build_cube_pairs( args )
        if len(input_file_pair) > 1:
            raise Usage('Input error: Only one pair of input files are allowed!')

        if not options.outputFolder: # Set the output folder equal to the input folder
            options.outputFolder = os.path.dirname(args[0])
        print('Using output folder: ' + options.outputFolder)
        if not os.path.exists(options.outputFolder) and len(options.outputFolder) > 1:
            os.makedirs(options.outputFolder)

        print("Beginning processing.....")

        if not options.resume_no_proj: # If not skipping to later point

            print("lronac2isis") # Per-file operation, returns list of new files
            lronac2isised = lronac2isis( args, options.threads, options.outputFolder )

            print("lronaccal")   # Per-file operation, returns list of new files
            lronaccaled = lronaccal( lronac2isised, options.threads, options.delete )

            print("lronacecho")  # Per-file operation, returns list of new files
            lronacechod = lronacecho( lronaccaled, options.threads, options.delete )

            if (options.cropAmount > 0): # Crop the input files as soon as ISIS calls allow it
                lronacechod = cropInputs(lronacechod, options.outputFolder, options.cropAmount,
                                         options.threads, options.delete)

            print("spice")       # Attach spice info to cubes (adds to existing files)
            spice( lronacechod, options.threads )


        if options.stop_no_proj: # Stop early if requested
            print("Finished")
            return 0

        if options.resume_no_proj: # If resume option was set
            lronacechod = args

        print("build_cube_pairs") # Detected corresponding pairs of cubes
        lronac_file_pairs = build_cube_pairs( lronacechod )

        print("noproj")       # Per-file operation
        noprojed_file_pairs = noproj( lronac_file_pairs, options.threads, options.delete, options.fakePvl, options.outputFolder)

        print("lronacjitreg") # Determines mean shift for each file pair
        averages = lronacjitreg( noprojed_file_pairs, options.threads, options.delete )

        print("mosaic")       # handmos - Use mean shifts to combine the file pairs
        mosaicked = mosaic( noprojed_file_pairs, averages, options.threads )

        # Clean up noproj files
        if( options.delete ):
          for cub in noprojed_file_pairs.values():
              os.remove( cub[0] )
              os.remove( cub[1] )

        # Run a final cubenorm across the image:
        cubenorm( mosaicked, options.threads, options.delete )

        print("Finished")
        return 0

    except Usage as err:
        print(err.msg, file=sys.stderr)
        return 2
def main():
    try:
        try:
            usage = "usage: cam2map4stereo.py [--help][--manual][--map mapfile][--pixres CAMERA|MAP|MPP|PPD][--resolution float][--interp NN|BI|CC][--lat min:max][--lon min:max][--prefix string] [--suffix string] image1.cub image2.cub\n" + get_asp_version()
            parser = optparse.OptionParser(usage=usage)
            parser.set_defaults(dryrun=False)
            parser.set_defaults(pixres='MPP')
            parser.set_defaults(prefix='')
            parser.set_defaults(suffix='map')
            parser.add_option("--manual", action="callback", callback=man,
                              help="Read the manual.")
            parser.add_option("-m", "--map", dest="map",
                              help="The mapfile to use for cam2map.")
            parser.add_option("-p", "--pixres", dest="pixres",
                              help="The pixel resolution mode to use for cam2map.")
            parser.add_option("-r", "--resolution", dest="resolution",
                              help="Resolution of final map for cam2map.")
            parser.add_option("-i", "--interp", dest="interp",
                              help="Pixel interpolation scheme for cam2map.")
            parser.add_option("-a", "--lat", dest="lat",
                              help="Latitude range for cam2map where LAT is minlat:maxlat.")
            parser.add_option("-o", "--lon", dest="lon",
                              help="Longitude range for cam2map where LON is minlon:maxlon.")
            parser.add_option("--prefix", dest="prefix",
                              help="Make all output files use this prefix. Default: no prefix.")
            parser.add_option("-s", "--suffix", dest="suffix",
                              help="Suffix that gets inserted in the output file names.")
            parser.add_option("-n", "--dry-run", dest="dryrun",
                              action="store_true",
                              help="Make calculations, but print cam2map command, but don't actually run it.")

            (options, args) = parser.parse_args()

            if not args: parser.error("need .cub files")


        except optparse.OptionError as msg:
            raise Usage(msg)

        # Call camrange to get bounds. If the lon bounds come as [0, 360] then try a different group.
        success = False
        lonGroupNames = ['UniversalGroundRange',  'PositiveEast180',
                         'PositiveWest180', 'PositiveWest360']
        for lonGroupName in lonGroupNames:
            image1 = camrange( args[0], lonGroupName, options)
            image2 = camrange( args[1], lonGroupName, options)
            lonRange = float(max(image1.maxlon, image2.maxlon)) - \
                       float(min(image1.minlon, image2.minlon))
            if lonRange >= 360.0:
                print("With lonGroupName = " + lonGroupName + " found a longitude range of " + \
                      str(lonRange) + ". Will try the next group from: " + (" ".join(lonGroupNames)))
            else:
                success = True
                break

        if not success:
            raise Exception('ProcessError', 'The longitude range keeps on coming as encompasing the entire planet. Something is wrong.')
            
        mapout = ImgInfo()

        mapout.minlat     = max( image1.minlat,     image2.minlat )
        mapout.maxlat     = min( image1.maxlat,     image2.maxlat )
        mapout.minlon     = max( image1.minlon,     image2.minlon )
        mapout.maxlon     = min( image1.maxlon,     image2.maxlon )
        mapout.resolution = max( image1.resolution, image2.resolution )

        if( options.resolution ): mapout.resolution = options.resolution
        if( options.lat ):
            latrange = options.lat.split(':')
            if latrange[0]: mapout.minlat = latrange[0]
            if latrange[1]: mapout.maxlat = latrange[1]
        if( options.lon ):
            lonrange = options.lon.split(':')
            if lonrange[0]: mapout.minlon = lonrange[0]
            if lonrange[1]: mapout.maxlon = lonrange[1]

        # call cam2map with the arguments

        cam2map = ['cam2map', 'from=' + args[0], 'to='
                   + mapfile( args[0], options.prefix, options.suffix )]

        if( options.map ):
            cam2map.append( 'map=' + options.map )
        if( options.interp):
            cam2map.append( 'interp=' + options.interp)

        cam2map.append( 'pixres=' + options.pixres )
        cam2map.append( 'resolution=' + mapout.resolution )

        cam2map.append( 'defaultrange=MAP' )
        cam2map.append( 'minlat=' + mapout.minlat )
        cam2map.append( 'maxlat=' + mapout.maxlat )
        cam2map.append( 'minlon=' + mapout.minlon )
        cam2map.append( 'maxlon=' + mapout.maxlon )

        # Run for first image

        # Need to put these together to keep ISIS from calling the GUI
        cam2map_cmd = ' '.join(cam2map)
        print(cam2map_cmd)
        if( not options.dryrun ):
            code = subprocess.call(cam2map_cmd, shell=True)
            if not code == 0:
                raise Exception('ProcessError', 'Non zero return code ('+str(code)+')')

        # Run for second image
        cam2map[1] = 'from=' + args[1]
        cam2map[2] = 'to='+ mapfile( args[1], options.prefix, options.suffix )
        cam2map_cmd = ' '.join(cam2map)
        print(cam2map_cmd)
        if( not options.dryrun ):
            code = subprocess.call(cam2map_cmd, shell=True)
            if not code == 0:
                raise Exception('ProcessError', 'Non zero return code ('+str(code)+')')

        print("Finished")
        return 0

    except Usage as err:
        print (err.msg, file=sys.stderr)
        return 2

    except MapExists as e:
        print ('The file '+ e.msg +' already exists, delete first.', file=sys.stderr)
        return 3
Beispiel #6
0
def main():
    try:
        try:
            usage = "usage: hiedr2mosaic.py [--help][--manual][--threads N][--keep][-m match] HiRISE-EDR.IMG-files\n  " + get_asp_version(
            )
            parser = optparse.OptionParser(usage=usage)
            parser.set_defaults(delete=True)
            parser.set_defaults(match=5)
            parser.set_defaults(threads=4)
            parser.add_option("--manual",
                              action="callback",
                              callback=man,
                              help="Read the manual.")
            parser.add_option(
                "--stop-at-no-proj",
                dest="stop_no_proj",
                action="store_true",
                help=
                "Process the IMG files only to have SPICE attached. This allows jigsaw to happen"
            )
            parser.add_option(
                "--resume-at-no-proj",
                dest="resume_no_proj",
                action="store_true",
                help=
                "Pick back up after spiceinit has happened or jigsaw. This was noproj uses your new camera information"
            )
            parser.add_option("-t",
                              "--threads",
                              dest="threads",
                              help="Number of threads to use.",
                              type="int")
            parser.add_option("-m",
                              "--match",
                              dest="match",
                              help="CCD number of match CCD")
            parser.add_option("-k",
                              "--keep",
                              action="store_false",
                              dest="delete",
                              help="Will not delete intermediate files.")

            (options, args) = parser.parse_args()

            if not args:
                parser.error("need .IMG files")

            # Make sure there is a valid match CCD
            if len(args) % 2 != 0:
                raise Exception(
                    'An even number of input CCD files is required!')
            numCcds = len(args) / 2
            if options.match >= numCcds:
                print 'Warning: match argument is greater than number of input CCDs, forcing it lower!'
                options.match = numCcds - 1

        except optparse.OptionError as msg:
            raise Usage(msg)

        # # Determine Isis Version
        # post_isis_20 = is_post_isis_3_1_20();
        isisversion(True)

        if not options.resume_no_proj:
            # hi2isis
            hi2isised = hi2isis(args, options.threads)

            # hical
            hicaled = hical(hi2isised, options.threads, options.delete)

            # histitch
            histitched = histitch(hicaled, options.threads, options.delete)

            # attach spice
            spice(histitched, options.threads)

        if options.stop_no_proj:
            print("Finished")
            return 0

        if options.resume_no_proj:
            histitched = args

        CCD_files = CCDs(histitched, options.match)

        # noproj
        noprojed_CCDs = noproj(CCD_files, options.threads, options.delete)

        # hijitreg
        averages = hijitreg(noprojed_CCDs, options.threads)

        # mosaic handmos
        mosaicked = mosaic(noprojed_CCDs, averages)

        # Clean up noproj files
        if (options.delete):
            for cub in noprojed_CCDs.values():
                os.remove(cub)

        # Run a final cubenorm across the image:
        cubenorm(mosaicked, options.delete)

        print("Finished")
        return 0

    except Usage as err:
        print >> sys.stderr, err.msg
        # print >>sys.stderr, "for help use --help"
        return 2
def main():
    try:
        try:
            usage = "usage: hiedr2mosaic.py [--help][--manual][--threads N][--keep][-m match] HiRISE-EDR.IMG-files\n  " + get_asp_version()
            parser = optparse.OptionParser(usage=usage)
            parser.set_defaults(delete=True)
            parser.set_defaults(match=5)
            parser.set_defaults(threads=4)
            parser.add_option("--manual", action="callback", callback=man,
                              help="Read the manual.")
            parser.add_option("--stop-at-no-proj", dest="stop_no_proj", action="store_true",
                              help="Process the IMG files only to have SPICE attached. This allows jigsaw to happen")
            parser.add_option("--resume-at-no-proj", dest="resume_no_proj", action="store_true",
                              help="Pick back up after spiceinit has happened or jigsaw. This was noproj uses your new camera information")
            parser.add_option("-t", "--threads", dest="threads",
                              help="Number of threads to use.",type="int")
            parser.add_option("-m", "--match", dest="match",type="int",
                              help="CCD number of match CCD, passed as the match argument to noproj (default 5).")
            parser.add_option("-k", "--keep", action="store_false",
                              dest="delete",
                              help="Will not delete intermediate files.")
            parser.add_option("--download-folder", dest="download_folder", default=None,
                              help="Download files to this folder. Hence the second argument to this is the URL of the page to download the files from.")

            (options, args) = parser.parse_args()

            if not args: 
                parser.error("need .IMG files or a URL")
            
            if options.download_folder:
                print ('Downloading HiRISE images from URL...')
                # For now we only fetch RED images.
                args = fetch_files(args[0], options.download_folder, image_type='RED')
                print ('Finished downloading ' + str(len(args)) + ' images.')
            
            # Make sure there is a valid match CCD
            if len(args) % 2 != 0 and not options.resume_no_proj:
                raise Exception('An even number of input CCD files is required!')

            # Verify that we have both of the specified match CCD's.
            # This is applicable only when we start with initial IMG files.
            if not options.resume_no_proj:            
                matchCount = 0
                for a in args:
                    if get_ccd(a) == options.match:
                        matchCount += 1
                        
                if matchCount != 2:
                    print ('Error: Found ' + str(matchCount) + ' files for match CCD ' 
                           + str(options.match) + ' instead of 2.')
                    return -1

            numCcds = len(args) / 2

        except optparse.OptionError as msg:
            raise Usage(msg)

        # # Determine Isis Version
        # post_isis_20 = is_post_isis_3_1_20();
        isisversion( True )

        if not options.resume_no_proj:
            # hi2isis
            hi2isised = hi2isis( args, options.threads )

            # hical
            hicaled = hical( hi2isised, options.threads, options.delete )

            # histitch
            histitched = histitch( hicaled, options.threads, options.delete )

            # attach spice
            spice( histitched, options.threads )

        if options.stop_no_proj:
            print("Finished")
            return 0

        if options.resume_no_proj:
            histitched = args

        CCD_files = CCDs( histitched, options.match )

        # noproj
        noprojed_CCDs = noproj( CCD_files, options.threads, options.delete )

        # hijitreg
        averages = hijitreg( noprojed_CCDs, options.threads )

        # mosaic handmos
        mosaicked = mosaic( noprojed_CCDs, averages )

        # Clean up noproj files
        if( options.delete ):
          for cub in noprojed_CCDs.values():
              os.remove( cub )

        # Run a final cubenorm across the image:
        cubenorm( mosaicked, options.delete )

        print("Finished")
        return 0

    except Usage as err:
        print (err.msg, file = sys.stderr)
        return 2