June 24 2026 APP 2.0.0-beta46 has been released !
Improved internal memory configuration (lower ! memory usage), fixed beta45 startup issue, fixed Set Save Directory & 2-panel mosaics.
May 27 2026 APP 2.0.0-beta45 has been released !
Fully Multi-Threaded LNC, many improvements for the registration engine, platform upgrade, and further tuning of internal memory consumption and memory release back to OS.
Apr 14 2026: Google Pay, Apple Pay & WeChat Pay added as payment options
Update on the 2.0.0 release & the full manual
We are getting close to the 2.0.0 stable release and the full manual. The manual will soon become available on the website and also in PDF format. Both versions will be identical and once released, will start to follow the APP release cycle and thus will stay up-to-date to the latest APP version.
Once 2.0.0 is released, the price for APP will increase. Owner's license holders will not need to pay an upgrade fee to use 2.0.0, neither do Renter's license holders.
RFCs - Request for changes
4
Posts
3
Users
3
Reactions
2,249
Views
Topic starter
February 11, 2022 20:08
Hey!Â
It would be realy nice if all Fits Headers will be kept in saved calibrated frames.
Currently some worthfull informations like Rotation Angle and Coords are lost :'(
Â
Thanks
Philip
Mabula-Admin reacted
February 11, 2022 21:55
@pmneo Thanks for the request. I asked Mabula to reply.
Mabula-Admin reacted
February 12, 2022 13:04
Hi @pmneo,
Thank you very much for your suggestion. It is on our ToDo list to keep as much info as possible in the Fits headers 😉
Mabula
Topic starter
February 13, 2022 11:07
Thanks @mabula-admin
Â
Until then, i have wrote a simple Java helper to copy all not present FITS Headers:
Â
package sandbox;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import nom.tam.fits.Fits;
import nom.tam.fits.FitsException;
import nom.tam.fits.Header;
import nom.tam.fits.HeaderCard;
import nom.tam.util.Cursor;
public class CopyFitsHeaders {
public static void main(String[] args) throws IOException, FitsException {
File root = new File("C:\\ASI1600\\Nikkor");
for( File base : root.listFiles() ) {
if( base.isDirectory() == false ) {
continue;
}
System.out.println( "Processing " + base );
LinkedList lights = collectFits( new File( base, "Light" ) );
LinkedList calibratedLights = collectFits( base );
calibratedLights.removeAll( lights );
for( File light : lights ) {
final LinkedList matchingCalibratedLights = new LinkedList<>();
for( File c : calibratedLights ) {
if( c.getName().startsWith( light.getName().substring(0, light.getName().length() - ".fits".length() ) ) ) {
matchingCalibratedLights.add( c );
break;
}
}
if( matchingCalibratedLights.size() == 0 ) {
System.err.println( "No calbirated light found for " + light );
continue;
}
Fits f = new Fits( light );
try {
for( File calibratedLight : matchingCalibratedLights ) {
Fits t = new Fits( calibratedLight );
try {
Header header = f.getHDU(0).getHeader();
Header targetHeader = t.getHDU(0).getHeader();
Map<String, HeaderCard> targetHeaders = new HashMap<>();
Cursor<String, HeaderCard> ti = targetHeader.iterator();
while( ti.hasNext() ) {
HeaderCard h = ti.next();
targetHeaders.put( h.getKey(), h );
}
int written = 0;
Cursor<String, HeaderCard> i = header.iterator();
while( i.hasNext() ) {
HeaderCard h = i.next();
if( targetHeaders.get( h.getKey() ) == null ) {
//System.err.println( h );
//System.err.flush();
ti.add( h.copy() );
written++;
}
}
if( written > 0 ) {
System.out.println( "Updating " + written + " FITS headers to " + calibratedLight );
t.write( calibratedLight );
}
}
finally {
t.close();
}
}
}
finally {
f.close();
}
}
}
System.out.println( "Finished" );
}
private static LinkedList collectFits(File lights) {
LinkedList allLights = new LinkedList( listFilesAsList(lights) );
LinkedList allFits = new LinkedList( );
while( allLights.size() > 0 ) {
File light = allLights.removeFirst();
if( light.isDirectory() ) {
allLights.addAll( listFilesAsList(light) );
}
else if( light.getName().endsWith( ".fits" ) ) {
allFits.add( light );
}
}
return allFits;
}
private static List listFilesAsList(File lights) {
File files[] = lights.listFiles();
if( files == null ) {
return Collections.emptyList();
}
else {
return Arrays.asList( files );
}
}
}
CS
Wouter van Reeven reacted