Skip to content

Instantly share code, notes, and snippets.

@dmsnell
Created November 5, 2016 20:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmsnell/7bc0c0e14ea05368ed534c2aa5b41f4c to your computer and use it in GitHub Desktop.
Save dmsnell/7bc0c0e14ea05368ed534c2aa5b41f4c to your computer and use it in GitHub Desktop.
Generate a star composite
const childProcess = require( 'child_process' )
const fs = require( 'fs' )
const spawn = childProcess.spawn
const spawnSync = childProcess.spawnSync
const l = m => { console.log( m ); return m }
const needsDir = dir => ! fs.existsSync( dir ) && fs.mkdirSync( dir )
// "mw-tsdm-12.tif" -> 12
const imageIndex = filename =>
filename
.split( '-' )[2]
.split( '.' )
.shift()
const getImages = () => {
const response = spawnSync( 'ls', [ 'src_tif' ], { encoding: 'utf-8' } )
return response
.stdout
.trim()
.split( "\n" )
.sort( ( a, b ) => imageIndex( a ) - imageIndex( b ) )
}
const resizeForTesting = ( folder, images, next ) => {
const newBase = './small/'
l( 'resizing for testing' )
needsDir( newBase )
images.forEach( image => {
if ( fs.existsSync( `${ newBase }${ image }` ) ) {
return l( `${ image } already exists, skipping` )
}
spawnSync( 'convert', [
`${ folder }/${ image }`,
'-resize', '640x',
`${ newBase }${ image }`
] )
} )
next[0]( newBase, images, next.slice( 1 ) )
}
const isolateStars = mask => ( folder, images, next ) => {
const newBase = './only-stars/'
l( 'Isolating the stars' )
needsDir( newBase )
images.forEach( image => {
if ( fs.existsSync( `${ newBase }${ image }` ) ) {
return l( `\talready isolated ${ image }`)
}
spawnSync( 'convert', [
mask,
`${ folder }${ image }`,
'-evaluate-sequence', 'subtract',
`${ newBase }${ image }`
] )
} )
next[0]( newBase, images, next.slice( 1 ) )
}
const convertToFits = ( folder, images, next = l ) => {
const newBase = './fits/'
l( 'converting to FITS' )
needsDir( newBase )
images.forEach( image => {
if ( fs.existsSync( `${ newBase }${ image.replace( /\.tif$/, '_1.fits' ) }` ) ) {
return l( `${ image.replace( /\.tif$/, '_1.fits' ) } already exists, skipping` )
}
spawnSync( 'convert', [
`${ folder }/${ image }`,
'-channel', 'rgb',
'-separate',
`${ newBase }${ image.replace( /\.tif$/, '_%d.fits') }`
] )
} )
next[0]( newBase, images, next.slice( 1 ) )
}
const identifyAlignment = ( folder, images, next ) => {
const newBase = './identifications/'
const anchor = images[ Math.floor( images.length / 2 ) ]
l( 'identifying alignment' )
needsDir( newBase )
images.forEach( image => {
if ( fs.existsSync( `${ newBase }identifications-${ image }.pickle` ) ) {
return l( `identifications for ${ image } already exist, skipping` )
}
spawnSync( 'rm', [
'identifications.pickle'
] )
spawnSync( 'python', [
'astro_align.py',
'--identify-only',
'-r', `${ folder }${ anchor.replace( /\.tif$/, '_1.fits' ) }`,
`${ folder }${ image.replace( /\.tif$/, '_1.fits' ) }`
] )
spawnSync( 'cp', [
'./identifications.pickle',
`${ newBase }identifications-${ image }.pickle`
] )
l( `\tidentified alignment for ${ image }` )
} )
next[0]( newBase, images, next.slice( 1 ) )
}
const alignImages = ( folder, images, next ) => {
const newBase = './alipy_out/'
const anchor = images[ Math.floor( images.length / 2 ) ]
l( 'aligning to anchor' )
needsDir( newBase )
images.forEach( image => {
if (
fs.existsSync( `${ newBase }${ image.replace( /\.tif$/, '_0_affineremap.fits' ) }` )
&&
fs.existsSync( `${ newBase }${ image.replace( /\.tif$/, '_1_affineremap.fits' ) }` )
&&
fs.existsSync( `${ newBase }${ image.replace( /\.tif$/, '_2_affineremap.fits' ) }` )
) {
return l( `${ image } already exists, skipping` )
}
spawnSync( 'python', [
'astro_align.py',
'-i', `./identifications/identifications-${ image }.pickle`
] )
l( `\taligned ${ image } to anchor`)
} )
next[0]( newBase, images, next.slice( 1 ) )
}
const copyOriginals = source => ( folder, images, next ) => {
const newBase = './only-stars/'
l( 'copying originals over no-stars' )
spawnSync( 'rm', [
'-rf', newBase
] )
needsDir( newBase )
spawnSync( 'cp', [
'-R', source, newBase
] )
l( 'originals copied' )
next[0]( folder, images, next.slice( 1 ) )
}
const combineFits = ( folder, images, next ) => {
const newBase = './rgb/'
l( 'combining FITS' )
if ( ! fs.existsSync( newBase ) ) {
fs.mkdirSync( newBase )
}
images.forEach( image => {
if ( fs.existsSync( `${ newBase }${ image }` ) ) {
return l( `${ image } already exists, skipping` )
}
spawnSync( 'convert', [
`${ folder }${ image.replace( /\.tif$/, '_0_affineremap.fits' ) }`,
`${ folder }${ image.replace( /\.tif$/, '_1_affineremap.fits' ) }`,
`${ folder }${ image.replace( /\.tif$/, '_2_affineremap.fits' ) }`,
'-combine', 'rgb',
`${ newBase }${ image }`
] )
} )
next[0]( newBase, images, next.slice( 1 ) )
}
const sumImages = ( folder, images, next ) => {
const newBase = './groups/'
const N = 4
const nextGroups = []
l( 'adding into groups' )
if ( ! fs.existsSync( newBase ) ) {
fs.mkdirSync( newBase )
}
// split into groups
const grouper = ( [ groups, images ] ) =>
images.length < N
? groups
: grouper( [ groups.concat( [ images.slice( 0, N ) ] ), images.slice( N ) ] )
const groups = grouper( [ [], images ] )
groups.forEach( ( group, i ) => {
if ( fs.existsSync( `${ newBase }group-${ i }.tif` ) ) {
nextGroups.push( i )
return l( `group-${ i } already exists, skipping` )
}
spawnSync( 'convert', [
...group.map( f => `${ folder }${ f }` ),
'-evaluate-sequence', 'add',
'-depth', '32',
`${ newBase }group-${ i }.tif`
] )
nextGroups.push( i )
} )
next[0]( newBase, nextGroups.map( i => `group-${ i }.tif` ), next.slice( 1 ) )
}
const denoiseMedian = ( folder, images, next ) => {
l( 'denoising with median' )
spawnSync( 'convert', l( [
...images.map( f => `${ folder }${ f }` ),
'-evaluate-sequence', 'median',
'median-result.tif'
] ) )
next[0]( '.', [ 'median-result.tif' ], next.slice( 1 ) )
}
const finish = ( folder, images ) => {
l( 'done' )
}
const main = () => {
const images = getImages()
const start = ( folder, images, next ) => next[0]( folder, images, next.slice(1) )
start( './src_tif/', images, [
resizeForTesting,
isolateStars( './coarse-mask.tif' ),
convertToFits,
identifyAlignment,
copyOriginals( './src_tif/' ),
alignImages,
combineFits,
sumImages,
denoiseMedian,
finish
] )
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment