def twogalaxies(name1, ra1, dec1, name2, ra2, dec2): name = "%s %s" % (name1, name2) ra = float(ra1) dec = float(dec1) ra2 = float(ra2) dec2 = float(dec2) remradius = 6. fieldradius = 6. threads = None itune1 = 5 itune2 = 5 ntune = 0 nocache = True #Radius should be in arcminutes if threads: mp = multiproc(nthreads=threads) else: mp = multiproc() IRLS_scale = 25. dr9 = True dr8 = False noarcsinh = False print(name) prefix = '%s' % (name.replace(' ', '_')) prefix1 = '%s' % (name1.replace(' ', '_')) prefix2 = '%s' % (name2.replace(' ', '_')) print('Removal Radius', remradius) print('Field Radius', fieldradius) print('RA,Dec', ra, dec) print(os.getcwd()) rcfs = radec_to_sdss_rcf(ra, dec, radius=math.hypot(fieldradius, 13. / 2.), tablefn="dr9fields.fits") print(rcfs) assert (len(rcfs) > 0) assert (len(rcfs) < 15) sras, sdecs, smags = tychoMatch(ra, dec, (fieldradius * 1.5) / 60.) for sra, sdec, smag in zip(sras, sdecs, smags): print(sra, sdec, smag) imkw = dict(psf='dg') if dr9: getim = st.get_tractor_image_dr9 getsrc = st.get_tractor_sources_dr9 imkw.update(zrange=[-3, 100]) elif dr8: getim = st.get_tractor_image_dr8 getsrc = st.get_tractor_sources_dr8 imkw.update(zrange=[-3, 100]) else: getim = st.get_tractor_image getsrc = st.get_tractor_sources_dr8 imkw.update(useMags=True) bands = ['u', 'g', 'r', 'i', 'z'] bandname = 'r' flipBands = ['r'] print(rcfs) imsrcs = mp.map( get_ims_and_srcs, [(rcf + (bands, ra, dec, fieldradius * 60. / 0.396, imkw, getim, getsrc)) for rcf in rcfs]) timgs = [] sources = [] allsources = [] for ims, s in imsrcs: if ims is None: continue if s is None: continue timgs.extend(ims) allsources.extend(s) sources.append(s) #rds = [rcf[3:5] for rcf in rcfs] plotarea(ra, dec, fieldradius, name, prefix, timgs) #, rds) lvl = logging.DEBUG logging.basicConfig(level=lvl, format='%(message)s', stream=sys.stdout) tractor = st.Tractor(timgs, allsources, mp=mp) sa = dict(debug=True, plotAll=False, plotBands=False) if noarcsinh: sa.update(nlscale=0) elif dr8 or dr9: sa.update(chilo=-8., chihi=8.) if nocache: tractor.cache = NullCache() sg.disable_galaxy_cache() zr = timgs[0].zr print("zr is: ", zr) print(bands) print("Number of images: ", len(timgs)) # for timg,band in zip(timgs,bands): # data = timg.getImage()/np.sqrt(timg.getInvvar()) # plt.hist(data,bins=100) # plt.savefig('hist-%s.png' % (band)) saveAll('initial-' + prefix, tractor, **sa) #plotInvvar('initial-'+prefix,tractor) for sra, sdec, smag in zip(sras, sdecs, smags): print(sra, sdec, smag) for img in tractor.getImages(): wcs = img.getWcs() starx, stary = wcs.positionToPixel(RaDecPos(sra, sdec)) starr = 25 * (2**(max(11 - smag, 0.))) if starx + starr < 0. or starx - starr > img.getWidth( ) or stary + starr < 0. or stary - starr > img.getHeight(): continue X, Y = np.meshgrid(np.arange(img.getWidth()), np.arange(img.getHeight())) R2 = (X - starx)**2 + (Y - stary)**2 img.getStarMask()[R2 < starr**2] = 0 for timgs, sources in imsrcs: timg = timgs[0] wcs = timg.getWcs() xtr, ytr = wcs.positionToPixel(RaDecPos(ra, dec)) print(xtr, ytr) xt = xtr yt = ytr r = ((remradius * 60.)) / .396 #radius in pixels for src in sources: xs, ys = wcs.positionToPixel(src.getPosition(), src) if (xs - xt)**2 + (ys - yt)**2 <= r**2: #print "Removed:", src #print xs,ys tractor.removeSource(src) #saveAll('removed-'+prefix, tractor,**sa) newShape = sg.GalaxyShape((remradius * 60.) / 10., 1., 0.) newBright = ba.Mags(r=15.0, g=15.0, u=15.0, z=15.0, i=15.0, order=['u', 'g', 'r', 'i', 'z']) EG = st.ExpGalaxy(RaDecPos(ra, dec), newBright, newShape) newShape2 = sg.GalaxyShape((remradius * 60.) / 10., 1., 0.) newBright2 = ba.Mags(r=15.0, g=15.0, u=15.0, z=15.0, i=15.0, order=['u', 'g', 'r', 'i', 'z']) EG2 = st.ExpGalaxy(RaDecPos(ra2, dec2), newBright2, newShape2) print(EG) print(EG2) tractor.addSource(EG) tractor.addSource(EG2) saveAll('added-' + prefix, tractor, **sa) #print 'Tractor has', tractor.getParamNames() for im in tractor.images: im.freezeAllParams() im.thawParam('sky') tractor.catalog.freezeAllBut(EG) tractor.catalog.thawParams(EG2) #print 'Tractor has', tractor.getParamNames() #print 'values', tractor.getParams() for i in range(itune1): tractor.optimize() tractor.changeInvvar(IRLS_scale) saveAll('itune1-%d-' % (i + 1) + prefix, tractor, **sa) tractor.clearCache() sg.get_galaxy_cache().clear() gc.collect() print(resource.getpagesize()) print(resource.getrusage(resource.RUSAGE_SELF)[2]) CGPos = EG.getPosition() CGShape1 = EG.getShape().copy() CGShape2 = EG.getShape().copy() EGBright = EG.getBrightness() CGu = EGBright[0] + 0.75 CGg = EGBright[1] + 0.75 CGr = EGBright[2] + 0.75 CGi = EGBright[3] + 0.75 CGz = EGBright[4] + 0.75 CGBright1 = ba.Mags(r=CGr, g=CGg, u=CGu, z=CGz, i=CGi, order=['u', 'g', 'r', 'i', 'z']) CGBright2 = ba.Mags(r=CGr, g=CGg, u=CGu, z=CGz, i=CGi, order=['u', 'g', 'r', 'i', 'z']) print(EGBright) print(CGBright1) CG = st.CompositeGalaxy(CGPos, CGBright1, CGShape1, CGBright2, CGShape2) CG2Pos = EG2.getPosition() CG2Shape1 = EG2.getShape().copy() CG2Shape2 = EG2.getShape().copy() EG2Bright = EG2.getBrightness() CG2u = EG2Bright[0] + 0.75 CG2g = EG2Bright[1] + 0.75 CG2r = EG2Bright[2] + 0.75 CG2i = EG2Bright[3] + 0.75 CG2z = EG2Bright[4] + 0.75 CG2Bright1 = ba.Mags(r=CG2r, g=CG2g, u=CG2u, z=CG2z, i=CG2i, order=['u', 'g', 'r', 'i', 'z']) CG2Bright2 = ba.Mags(r=CG2r, g=CG2g, u=CG2u, z=CG2z, i=CG2i, order=['u', 'g', 'r', 'i', 'z']) CG2 = st.CompositeGalaxy(CG2Pos, CG2Bright1, CG2Shape1, CG2Bright2, CG2Shape2) tractor.removeSource(EG) tractor.removeSource(EG2) tractor.addSource(CG) tractor.addSource(CG2) tractor.catalog.freezeAllBut(CG) tractor.catalog.thawParams(CG2) print(resource.getpagesize()) print(resource.getrusage(resource.RUSAGE_SELF)[2]) for i in range(itune2): tractor.optimize() tractor.changeInvvar(IRLS_scale) saveAll('itune2-%d-' % (i + 1) + prefix, tractor, **sa) tractor.clearCache() sg.get_galaxy_cache().clear() print(resource.getpagesize()) print(resource.getrusage(resource.RUSAGE_SELF)[2]) tractor.catalog.thawAllParams() for i in range(ntune): tractor.optimize() tractor.changeInvvar(IRLS_scale) saveAll('ntune-%d-' % (i + 1) + prefix, tractor, **sa) #plotInvvar('final-'+prefix,tractor) sa.update(plotBands=True) saveAll('allBands-' + prefix, tractor, **sa) print(CG) print(CG.getPosition()) print(CGBright1) print(CGBright2) print(CGShape1) print(CGShape2) print(CGBright1 + CGBright2) print(CG.getBrightness()) pfn = '%s.pickle' % prefix pickle_to_file([CG, CG2], pfn) makeflipbook(prefix, len(tractor.getImages()), itune1, itune2, ntune) pickle_to_file(CG, "%s.pickle" % prefix1) pickle_to_file(CG2, "%s.pickle" % prefix2) os.system('cp %s.pickle RC3_Output' % prefix1) os.system('cp %s.pickle RC3_Output' % prefix2)
def main(): import optparse parser = optparse.OptionParser(usage='%prog [options] <NGC-number>') parser.add_option('--threads', dest='threads', type=int, help='use multiprocessing') parser.add_option('--itune1',dest='itune1',type=int,help='Individual tuning, first stage',default=5) parser.add_option('--itune2',dest='itune2',type=int,help='Individual tuning, second stage',default=5) parser.add_option('--ntune',dest='ntune',type=int,help='All objects tuning',default=0) parser.add_option('--nocache',dest='nocache',action='store_true',default=False,help='Disable caching for memory reasons') opt,args = parser.parse_args() if len(args) != 1: parser.print_help() sys.exit(-1) if opt.threads: mp = multiproc(nthreads=opt.threads) else: mp = multiproc() ngc = int(args[0]) j = getNGC(ngc) print j ra = float(j['RA'][0]) dec = float(j['DEC'][0]) itune1 = opt.itune1 itune2 = opt.itune2 ntune = opt.ntune IRLS_scale = 25. radius = (10.**j['LOG_D25'][0])/10. dr8 = True noarcsinh = False print 'Radius', radius print 'RA,Dec', ra, dec sras, sdecs, smags = tychoMatch(ra,dec,(radius*1.5)/60.) for sra,sdec,smag in zip(sras,sdecs,smags): print sra,sdec,smag rcfs = radec_to_sdss_rcf(ra,dec,radius=math.hypot(radius,13./2.),tablefn="dr8fields.fits") print rcfs #fieldPlot(ra,dec,radius,ngc) imkw = dict(psf='dg') if dr8: getim = st.get_tractor_image_dr8 getsrc = st.get_tractor_sources_dr8 imkw.update(zrange=[-3,100]) else: getim = st.get_tractor_image getsrc = st.get_tractor_sources_dr8 imkw.update(useMags=True) bands=['u','g','r','i','z'] #bands=['r'] bandname = 'r' flipBands = ['r'] imsrcs = mp.map(get_ims_and_srcs, [(rcf + (bands, ra, dec, radius*60./0.396, imkw, getim, getsrc)) for rcf in rcfs]) timgs = [] sources = [] allsources = [] for ims,s in imsrcs: if ims is None: continue if s is None: continue timgs.extend(ims) allsources.extend(s) sources.append(s) #rds = [rcf[3:5] for rcf in rcfs] plotarea(ra, dec, radius, ngc, timgs) #, rds) lvl = logging.DEBUG logging.basicConfig(level=lvl,format='%(message)s',stream=sys.stdout) tractor = st.Tractor(timgs, allsources, mp=mp) sa = dict(debug=True, plotAll=False,plotBands=False) if noarcsinh: sa.update(nlscale=0) elif dr8: sa.update(chilo=-8.,chihi=8.) if opt.nocache: tractor.cache = NullCache() sg.disable_galaxy_cache() zr = timgs[0].zr print "zr is: ",zr print bands print "Number of images: ", len(timgs) # for timg,band in zip(timgs,bands): # data = timg.getImage()/np.sqrt(timg.getInvvar()) # plt.hist(data,bins=100) # plt.savefig('hist-%s.png' % (band)) prefix = 'ngc%d' % (ngc) saveAll('initial-'+prefix, tractor,**sa) #plotInvvar('initial-'+prefix,tractor) for sra,sdec,smag in zip(sras,sdecs,smags): print sra,sdec,smag for img in tractor.getImages(): wcs = img.getWcs() starx,stary = wcs.positionToPixel(RaDecPos(sra,sdec)) starr=25*(2**(max(11-smag,0.))) if starx+starr<0. or starx-starr>img.getWidth() or stary+starr <0. or stary-starr>img.getHeight(): continue X,Y = np.meshgrid(np.arange(img.getWidth()), np.arange(img.getHeight())) R2 = (X - starx)**2 + (Y - stary)**2 img.getStarMask()[R2 < starr**2] = 0 #star = [(x,y) for x in range(img.getWidth()) for y in range(img.getHeight()) if (x-starx)**2+(y-stary)**2 <= starr**2] #for (x,y) in star: # img.getStarMask()[y][x] = 0 for timgs,sources in imsrcs: timg = timgs[0] wcs = timg.getWcs() xtr,ytr = wcs.positionToPixel(RaDecPos(ra,dec)) print xtr,ytr xt = xtr yt = ytr r = ((radius*60.))/.396 #radius in pixels for src in sources: xs,ys = wcs.positionToPixel(src.getPosition(),src) if (xs-xt)**2+(ys-yt)**2 <= r**2: print "Removed:", src print xs,ys tractor.removeSource(src) #saveAll('removed-'+prefix, tractor,**sa) newShape = sg.GalaxyShape(30.,1.,0.) newBright = ba.Mags(r=15.0,g=15.0,u=15.0,z=15.0,i=15.0,order=['u','g','r','i','z']) EG = st.ExpGalaxy(RaDecPos(ra,dec),newBright,newShape) print EG tractor.addSource(EG) saveAll('added-'+prefix,tractor,**sa) print 'Tractor has', tractor.getParamNames() for im in tractor.images: im.freezeAllParams() im.thawParam('sky') tractor.catalog.freezeAllBut(EG) print 'Tractor has', tractor.getParamNames() print 'values', tractor.getParams() for i in range(itune1): tractor.optimize() print resource.getpagesize() print resource.getrusage(resource.RUSAGE_SELF)[2] tractor.changeInvvar(IRLS_scale) print resource.getpagesize() print resource.getrusage(resource.RUSAGE_SELF)[2] saveAll('itune1-%d-' % (i+1)+prefix,tractor,**sa) print resource.getpagesize() print resource.getrusage(resource.RUSAGE_SELF)[2] tractor.clearCache() sg.get_galaxy_cache().clear() gc.collect() print resource.getpagesize() print resource.getrusage(resource.RUSAGE_SELF)[2] CGPos = EG.getPosition() CGShape1 = EG.getShape().copy() CGShape2 = EG.getShape().copy() EGBright = EG.getBrightness() CGu = EGBright[0] + 0.75 CGg = EGBright[1] + 0.75 CGr = EGBright[2] + 0.75 CGi = EGBright[3] + 0.75 CGz = EGBright[4] + 0.75 CGBright1 = ba.Mags(r=CGr,g=CGg,u=CGu,z=CGz,i=CGi,order=['u','g','r','i','z']) CGBright2 = ba.Mags(r=CGr,g=CGg,u=CGu,z=CGz,i=CGi,order=['u','g','r','i','z']) print EGBright print CGBright1 CG = st.CompositeGalaxy(CGPos,CGBright1,CGShape1,CGBright2,CGShape2) tractor.removeSource(EG) tractor.addSource(CG) tractor.catalog.freezeAllBut(CG) print resource.getpagesize() print resource.getrusage(resource.RUSAGE_SELF)[2] for i in range(itune2): tractor.optimize() tractor.changeInvvar(IRLS_scale) saveAll('itune2-%d-' % (i+1)+prefix,tractor,**sa) print resource.getpagesize() print "RUsage is: ",resource.getrusage(resource.RUSAGE_SELF)[2] tractor.clearCache() sg.get_galaxy_cache().clear() print resource.getpagesize() print resource.getrusage(resource.RUSAGE_SELF)[2] tractor.catalog.thawAllParams() for i in range(ntune): tractor.optimize() tractor.changeInvvar(IRLS_scale) saveAll('ntune-%d-' % (i+1)+prefix,tractor,**sa) #plotInvvar('final-'+prefix,tractor) sa.update(plotBands=True) saveAll('allBands-' + prefix,tractor,**sa) print CG print CG.getPosition() print CGBright1 print CGBright2 print CGShape1 print CGShape2 print CGBright1+CGBright2 print CG.getBrightness() pfn = 'ngc-%d.pickle' % ngc pickle_to_file(CG,pfn) makeflipbook(prefix,len(tractor.getImages()),itune1,itune2,ntune)
def general(name, ra, dec, remradius, fieldradius, threads=None, itune1=5, itune2=5, ntune=0, nocache=False, scale=1, ab=1., angle=0.): #Radius should be in arcminutes if threads: mp = multiproc(nthreads=threads) else: mp = multiproc() IRLS_scale = 25. dr9 = True dr8 = False noarcsinh = False print name prefix = 'swapCG_%s' % (name.replace(' ', '_')) print 'Removal Radius', remradius print 'Field Radius', fieldradius print 'RA,Dec', ra, dec print os.getcwd() print ra, dec, math.hypot(fieldradius, 13. / 2.) rcfs = radec_to_sdss_rcf(ra, dec, radius=math.hypot(fieldradius, 13. / 2.), tablefn="dr9fields.fits") print 'RCFS:', rcfs print len(rcfs) assert (len(rcfs) > 0) if 10 <= len(rcfs) < 20: scale = 2 elif 20 <= len(rcfs) < 40: scale = 4 elif 40 <= len(rcfs) < 80: scale = 8 assert (len(rcfs) < 80) sras, sdecs, smags = tychoMatch(ra, dec, (fieldradius * 1.5) / 60.) imkw = dict(psf='kl-gm') if dr9: getim = st.get_tractor_image_dr9 getsrc = st.get_tractor_sources_dr9 imkw.update(zrange=[-3, 100]) elif dr8: getim = st.get_tractor_image_dr8 getsrc = st.get_tractor_sources_dr8 imkw.update(zrange=[-3, 100]) else: getim = st.get_tractor_image getsrc = st.get_tractor_sources_dr8 imkw.update(useMags=True) bands = ['u', 'g', 'r', 'i', 'z'] #bands=['r'] bandname = 'r' flipBands = ['r'] print rcfs imsrcs = mp.map( get_ims_and_srcs, [(rcf + (bands, ra, dec, fieldradius * 60. / 0.396, imkw, getim, getsrc)) for rcf in rcfs]) timgs = [] sources = [] allsources = [] for ims, s in imsrcs: if ims is None: continue if s is None: continue if scale > 1: for im in ims: timgs.append(st.scale_sdss_image(im, scale)) else: timgs.extend(ims) allsources.extend(s) sources.append(s) #rds = [rcf[3:5] for rcf in rcfs] #plotarea(ra, dec, fieldradius, name, prefix, timgs) #, rds) #lvl = logging.DEBUG #logging.basicConfig(level=lvl,format='%(message)s',stream=sys.stdout) tractor = st.Tractor(timgs, allsources, mp=mp) sa = dict(debug=True, plotAll=False, plotBands=False) if noarcsinh: sa.update(nlscale=0) elif dr8 or dr9: sa.update(chilo=-8., chihi=8.) if nocache: tractor.cache = NullCache() sg.disable_galaxy_cache() zr = timgs[0].zr print "zr is: ", zr print bands print "Number of images: ", len(timgs) #for timg,band in zip(timgs,bands): # data = timg.getImage()/np.sqrt(timg.getInvvar()) # plt.hist(data,bins=100) # plt.savefig('hist-%s.png' % (band)) saveAll('initial-' + prefix, tractor, **sa) #plotInvvar('initial-'+prefix,tractor) for sra, sdec, smag in zip(sras, sdecs, smags): for img in tractor.getImages(): wcs = img.getWcs() starx, stary = wcs.positionToPixel(RaDecPos(sra, sdec)) starr = 25 * (2**(max(11 - smag, 0.))) if starx + starr < 0. or starx - starr > img.getWidth( ) or stary + starr < 0. or stary - starr > img.getHeight(): continue X, Y = np.meshgrid(np.arange(img.getWidth()), np.arange(img.getHeight())) R2 = (X - starx)**2 + (Y - stary)**2 img.getStarMask()[R2 < starr**2] = 0 for timgs, sources in imsrcs: timg = timgs[0] wcs = timg.getWcs() xtr, ytr = wcs.positionToPixel(RaDecPos(ra, dec)) xt = xtr yt = ytr r = ((remradius * 60.)) / .396 #radius in pixels for src in sources: xs, ys = wcs.positionToPixel(src.getPosition(), src) if (xs - xt)**2 + (ys - yt)**2 <= r**2: #print "Removed:", src #print xs,ys tractor.removeSource(src) #saveAll('removed-'+prefix, tractor,**sa) newShape = sg.GalaxyShape((remradius * 60.) / 10., ab, angle) newBright = ba.Mags(r=15.0, g=15.0, u=15.0, z=15.0, i=15.0, order=['u', 'g', 'r', 'i', 'z']) EG = st.ExpGalaxy(RaDecPos(ra, dec), newBright, newShape) print EG tractor.addSource(EG) saveAll('added-' + prefix, tractor, **sa) #print 'Tractor has', tractor.getParamNames() for im in tractor.images: im.freezeAllParams() im.thawParam('sky') tractor.catalog.freezeAllBut(EG) #print 'Tractor has', tractor.getParamNames() #print 'values', tractor.getParams() for i in range(itune1): tractor.optimize() tractor.changeInvvar(IRLS_scale) saveAll('itune1-%d-' % (i + 1) + prefix, tractor, **sa) tractor.clearCache() sg.get_galaxy_cache().clear() gc.collect() print resource.getpagesize() print resource.getrusage(resource.RUSAGE_SELF)[2] CGPos = EG.getPosition() CGShape1 = EG.getShape().copy() CGShape2 = EG.getShape().copy() EGBright = EG.getBrightness() CGu = EGBright[0] + 0.75 CGg = EGBright[1] + 0.75 CGr = EGBright[2] + 0.75 CGi = EGBright[3] + 0.75 CGz = EGBright[4] + 0.75 CGBright1 = ba.Mags(r=CGr, g=CGg, u=CGu, z=CGz, i=CGi, order=['u', 'g', 'r', 'i', 'z']) CGBright2 = ba.Mags(r=CGr, g=CGg, u=CGu, z=CGz, i=CGi, order=['u', 'g', 'r', 'i', 'z']) print EGBright print CGBright1 CG = st.CompositeGalaxy(CGPos, CGBright1, CGShape1, CGBright2, CGShape2) tractor.removeSource(EG) tractor.addSource(CG) tractor.catalog.freezeAllBut(CG) print resource.getpagesize() print resource.getrusage(resource.RUSAGE_SELF)[2] for i in range(itune2): tractor.optimize() tractor.changeInvvar(IRLS_scale) saveAll('itune2-%d-' % (i + 1) + prefix, tractor, **sa) tractor.clearCache() sg.get_galaxy_cache().clear() print resource.getpagesize() print resource.getrusage(resource.RUSAGE_SELF)[2] tractor.catalog.thawAllParams() for i in range(ntune): tractor.optimize() tractor.changeInvvar(IRLS_scale) saveAll('ntune-%d-' % (i + 1) + prefix, tractor, **sa) #plotInvvar('final-'+prefix,tractor) sa.update(plotBands=True) saveAll('allBands-' + prefix, tractor, **sa) print "end of first round of optimization:", tractor.getLogLikelihood() print CG print CG.getPosition() print CGBright1 print CGBright2 print CGShape1 print CGShape2 print CGBright1 + CGBright2 print CG.getBrightness() pfn = '%s.pickle' % prefix pickle_to_file(CG, pfn) makeflipbook(prefix, len(tractor.getImages()), itune1, itune2, ntune) # now SWAP exp and dev and DO IT AGAIN newCG = st.CompositeGalaxy(CG.getPosition, CG.brightnessDev.copy(), CG.shapeDev.copy(), CG.brightnessExp.copy(), CG.shapeExp.copy()) tractor.removeSource(CG) tractor.addSource(newCG) tractor.catalog.thawAllParams() for i in range(ntune): tractor.optimize() tractor.changeInvvar(IRLS_scale) saveAll('ntune-swap-%d-' % (i + 1) + prefix, tractor, **sa) #plotInvvar('final-'+prefix,tractor) sa.update(plotBands=True) saveAll('allBands-swap-' + prefix, tractor, **sa) print "end of second (swapped) round of optimization:", tractor.getLogLikelihood( ) print newCG print newCG.getPosition() print newCG.getBrightness() pfn = '%s-swap.pickle' % prefix pickle_to_file(newCG, pfn) makeflipbook(prefix + "-swap", len(tractor.getImages()), itune1, itune2, ntune)