File: astap_command_line.lpr

package info (click to toggle)
astap-cli 2024.05.01-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,320 kB
  • sloc: pascal: 7,116; sh: 194; makefile: 4
file content (285 lines) | stat: -rw-r--r-- 10,224 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
program astap_command_line;
{Copyright (C) 2017, 2024 by Han Kleijn, www.hnsky.org
 email: han.k.. at...hnsky.org

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.   }

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX or ANDROID}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, SysUtils, CustApp,
  unit_command_line_solving, unit_command_line_general;

type

  {Tastap}
  Tastap = class(TCustomApplication)
  protected
    procedure DoRun; override;
  public
    constructor Create(TheOwner: TComponent); override;
    destructor Destroy; override;
  end;
 {Tastap}


function fits_file_name(inp : string): boolean; {fits file name?}
begin
  inp:=uppercase(extractfileext(inp));
  result:=((inp='.FIT') or (inp='.FITS') or (inp='.FTS'));
end;


procedure Tastap.DoRun;
var
  file_loaded,filespecified,analysespecified, extractspecified, extractspecified2 : boolean;
  backgr, hfd_median,snr_min          : double;
  hfd_counter,report                  : integer;
begin
  {$IfDef Darwin}// for OS X,
    database_path:='/usr/local/opt/astap/';
  {$else}

  database_path:=extractfilepath(paramstr(0));{}

    {$ifdef mswindows}
    {$else} {UNIX or ANDROID}
    if copy(database_path,1,4)='/usr' then {for Linux distributions}
      database_path:='/usr/share/astap/data/';
    {$endif}
  {$endif}


  fov_specified:=false;{assume no FOV specification in commandline}

  if ((paramcount=0) or (hasOption('h','help'))) then
  begin
    writeln(
    'ASTAP astrometric solver version CLI-'+astap_version+#10+
    '(C) 2018, 2024 by Han Kleijn. License MPL 2.0, Webpage: www.hnsky.org'+#10+
    'Usage:'+#10+
    '-f  filename  {fits, tiff, png, jpg files}'+#10+
    '-r  radius_area_to_search[degrees]'+#10+      {changed}
    '-fov diameter_field[degrees] {enter zero for auto}'+#10+   {changed}
    '-ra  center_right_ascension[hours]'+#10+
    '-spd center_south_pole_distance[degrees]'+#10+
    '-s  max_number_of_stars  {default 500}'+#10+
    '-t  tolerance  {default 0.007}'+#10+
    '-m  minimum_star_size["]  {default 1.5}'+#10+
    '-z  downsample_factor[0,1,2,3,4] {Downsample prior to solving. 0 is auto}'+#10+

    '-check apply[y/n] {Apply check pattern filter prior to solving. Use for raw OSC images only when binning is 1x1}' +#10+
    '-d  path {specify a path to the star database}'+#10+
    '-D  abbreviation {Specify a star database [d80,d50,..]}'+#10+
    '-o  file {Name the output files with this base path & file name}'+#10+
    '-sip     {Add SIP (Simple Image Polynomial) coefficients}'+#10+
    '-speed mode[auto/slow] {Slow is forcing reading a larger area from the star database (more overlap) to improve detection}'+#10+
    '-wcs  {Write a .wcs file  in similar format as Astrometry.net. Else text style.}' +#10+
    '-log  {Write the solver log to file}'+#10+
    '-update  {update the FITS header with the found solution. Jpeg, png, tiff will be written as fits}' +#10+
    '-progress   {Log all progress steps and messages}'+#10+
    #10+
    'Analyse options:' +#10+
    '-analyse snr_min {Analyse only and report median HFD and number of stars used}'+#10+
    '-extract snr_min {As -analyse but additionally export info of all detectable stars to a .csv file}'+#10+
    '-extract2 snr_min {Solve and export info of all detectable stars to a .csv file including ra, dec.}'+#10+

    'Preference will be given to the command line values.'
    );

    esc_pressed:=true;{kill any running activity. This for APT}
    terminate;
    exit;
  end;

  filespecified:=hasoption('f');

  if filespecified then
  begin
    commandline_log:=hasoption('log');{log to file. In debug mode enable logging to memo2}
    solve_show_log:=hasoption('progress');{log all progress}
    if commandline_log then memo2_message(cmdline);{write the original commmand line}


    if filespecified then
    begin
      filename2:=GetOptionValue('f');
      file_loaded:=load_image; {load file first to give commandline parameters later priority}
      if file_loaded=false then errorlevel:=16;{error file loading}
    end
    else
    file_loaded:=false;

    {apply now overriding parameters}
    if hasoption('fov') then
    begin
      fov_specified:=true; {do not calculate it from header};
      search_fov1:=GetOptionValue('fov');
    end;
    if hasoption('r') then radius_search1:=GetOptionValue('r');
    if hasoption('ra') then
    begin
      ra0:=strtofloat2(GetOptionValue('ra'))*pi/12;
    end;
    {else ra from fits header}

    if hasoption('spd') then {south pole distance. Negative values can't be passed via commandline}
    begin
      dec0:=(strtofloat2(GetOptionValue('spd'))-90)*pi/180;{convert south pole distance to declination}
    end;
    {else dec from fits header}

    if hasoption('z') then downsample_for_solving1:=strtoint(GetOptionValue('z'));
    if hasoption('s') then max_stars:=strtoint(GetOptionValue('s'));
    if hasoption('t') then quad_tolerance1:=GetOptionValue('t');
    if hasoption('m') then min_star_size1:=GetOptionValue('m');
    if hasoption('sip') then add_sip1:='n'<>GetOptionValue('sip');
    if hasoption('speed') then force_oversize1:=pos('slow',GetOptionValue('speed'))<>0;
    if hasoption('check') then check_pattern_filter1:=('y'=GetOptionValue('check'));

    extractspecified:=hasoption('extract');
    extractspecified2:=hasoption('extract2');
    if extractspecified2 then add_sip1:=true;//force sip for high accuracy
    analysespecified:=hasoption('analyse');

    if ((file_loaded) and ((analysespecified) or (extractspecified)) ) then {analyse fits and report HFD value in errorlevel }
    begin
      if analysespecified then
      begin
         snr_min:=strtofloat2(getoptionvalue('analyse'));
         report:=0; {report nr stars and hfd only}
      end;
      if extractspecified then
      begin
        snr_min:=strtofloat2(getoptionvalue('extract'));
        report:=2; {report nr stars and hfd and export csv file}
      end;
      if snr_min=0 then snr_min:=30;
      analyse_image(img_loaded,snr_min,report, hfd_counter,backgr,hfd_median); {find background, number of stars, median HFD}
      if isConsole then {stdout available, compile targe option -wh used}
      begin
        writeln('HFD_MEDIAN='+floattostrF2(hfd_median,0,1));
        writeln('STARS='+inttostr(hfd_counter));
      end;

      {$IFDEF msWindows}
      halt(round(hfd_median*100)*1000000+hfd_counter);{report in errorlevel the hfd and the number of stars used}
      {$ELSE}
      halt(errorlevel);{report hfd in errorlevel. In linux only range 0..255 possible}
      {$ENDIF}
    end;{analyse fits and report HFD value}

    if hasoption('d') then
      database_path:=GetOptionValue('d')+DirectorySeparator; {specify a different database path}
    if hasoption('D') then
      star_database1:=GetOptionValue('D'); {specify a different database}



    if ((file_loaded) and (solve_image(img_loaded ))) then {find plate solution, filename2 extension will change to .fit}
    begin
      if hasoption('o') then filename2:=GetOptionValue('o');{change file name for .ini file}
      write_ini(true);{write solution to ini file}

      add_long_comment('cmdline:'+cmdline);{log command line in wcs file}

      if hasoption('update') then
      begin
        if fits_file_name(filename2) then SaveFITSwithupdatedheader1
        else
        save_fits16bit(img_loaded,ChangeFileExt(filename2,'.fits'));{save original png,tiff jpg to 16 bits fits file}
      end;

      remove_key('NAXIS1  =',true{one});
      remove_key('NAXIS2  =',true{one});
      update_integer('NAXIS   =',' / Minimal header                                 ' ,0);{2 for mono, 3 for colour}
      update_integer('BITPIX  =',' /                                                ' ,8);

      if hasoption('wcs') then
        write_astronomy_wcs  {write WCS astronomy.net style}
      else
        try Memo1.SavetoFile(ChangeFileExt(filename2,'.wcs'));{save header as wcs file} except {sometimes error using APT, locked?} end;

    end {solution}
    else
    begin {no solution}
      if hasoption('o') then filename2:=GetOptionValue('o'); {change file name for .ini file}
      write_ini(false);{write solution to ini file}
      errorlevel:=1;{no solution}
    end;

    if ((file_loaded) and (extractspecified2)) then
    begin
      snr_min:=strtofloat2(getoptionvalue('extract2'));
      if snr_min=0 then snr_min:=30;
      analyse_image(img_loaded,snr_min,2 {report, export CSV only}, hfd_counter,backgr,hfd_median); {find background, number of stars, median HFD}
    end;

    esc_pressed:=true;{kill any running activity. This for APT}
    if commandline_log then
             Memo2.SavetoFile(ChangeFileExt(filename2,'.log'));{save Memo2 log to log file}

    halt(errorlevel);

    //  Exit status:
    //  0 no errors.
    //  1 no solution.
    //  2 not enough stars detected.

    // 16 error reading image file.

    // 32 no star database found.
    // 33 error reading star database.

    // ini file is always written. Could contain:
    // ERROR=......
    // WARNING=......

    // wcs file is written when there is a solution. Could contain:
    // WARNING =.........
  end;{-f option}

  {$IfDef Darwin}// for OS X,
  {$IF FPC_FULLVERSION <= 30200} {FPC3.2.0}
     application.messagebox( pchar('Warning this code requires later LAZARUS 2.1 and FPC 3.3.1 version!!!'), pchar('Warning'),MB_OK);
  {$ENDIF}
  {$ENDIF}
  terminate;
end;



constructor Tastap.Create(TheOwner: TComponent);
begin
  inherited Create(TheOwner);
  memo1:=Tstringlist.Create;
  memo2:=Tstringlist.Create;
  StopOnException:=True;
end;

destructor Tastap.Destroy;
begin
  memo2.free;
  memo1.free;
  inherited Destroy;
end;


var
  Application: Tastap;

//{$R *.res}

{$R *.res}

begin
  Application:=Tastap.Create(nil);
  Application.Run;
  Application.Free;
end.