1
/*===========================================================================
2
Copyright (C) 1991-2209 European Southern Observatory (ESO)
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License as
6
published by the Free Software Foundation; either version 2 of
7
the License, or (at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public
15
License along with this program; if not, write to the Free
16
Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,
19
Correspondence concerning ESO-MIDAS should be addressed as follows:
20
Internet e-mail: midas@eso.org
21
Postal address: European Southern Observatory
22
Data Management Division
23
Karl-Schwarzschild-Strasse 2
24
D 85748 Garching bei Muenchen
26
===========================================================================*/
28
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
29
/* .IDENT spematch.c */
30
/* .AUTHOR Pascal Ballester, ESO - Garching */
31
/* .KEYWORDS Spectroscopy, Echelle, */
32
/* .PURPOSE associates line catalog and computed wavelengths */
33
/* .VERSION 1.0 Creation 15-JAN-1991 PB */
35
/* 090904 last modif */
36
/* ------------------------------------------------------------- */
39
#include <midas_def.h>
43
#define ipos(col,row,nrow) (col-1)*nrow + row - 1
45
void stdev(), open_acc(), close_acc(), accumulate(), findmax();
48
/* All Global Definitions for the accumulation array */
50
#define ipos2D(col,row,npix) row*npix[0]+col
57
double start, step, stend;
66
/* Starting the main code */
71
char line[60], lincat[60];
73
int linwav, catwav, linid, lindif, liny, linerr, liniso;
74
int row, rowcat, null;
75
int order, ordref, bufsize, imno;
76
int status, kunit, actvals, tidlin, tidcat;
77
int nbcol, nsort, allcol, allrow;
78
int nbcolcat, nbrowcat, nsortcat, allcolcat, allrowcat;
79
int rowlow, rowupp, rowref, index, number;
81
double resref, reslow, resupp, residual, finres;
82
double resref_abs, reslow_abs, resupp_abs, res_abs;
83
double lambda_ref, lambda_low, lambda_upp;
84
double lambda_lin, lambda_cat, error, error_min;
86
float thres[3], fraction;
94
status = SCKRDR("INPUTR", 1, 1, &actvals, thres, &kunit, &null);
95
status = SCKGETC("IN_A", 1, 60, &actvals, line);
96
status = SCKGETC("IN_B", 1, 60, &actvals, lincat);
98
/* Read all keywords for the accumulator */
99
status = SCKGETC("OUT_A",1, 60, &actvals, name);
100
status = SCKRDI("INPUTI", 1, 1, &actvals, &npix, &kunit, &null);
101
status = SCKRDD("INPUTD", 1, 1, &actvals, &start,&kunit, &null);
102
status = SCKRDD("INPUTD", 2, 1, &actvals, &step, &kunit, &null);
103
status = SCKRDR("INPUTR", 2, 1, &actvals, &fraction, &kunit, &null);
105
if (TCTOPN(line, F_IO_MODE, &tidlin))
106
SCTPUT("**** Error while opening table line.tbl");
108
TCIGET(tidlin, &nbcol, &nbrow, &nsort, &allcol, &allrow);
110
if (TCTOPN(lincat, F_I_MODE, &tidcat))
111
SCTPUT("**** Error while opening line catalog");
113
TCIGET(tidcat, &nbcolcat, &nbrowcat, &nsortcat, &allcolcat, &allrowcat);
116
/* Finds column :WAVE in line catalog */
118
TCCSER(tidcat, ":WAVE", &catwav);
119
if (catwav == (-1)) SCTPUT("**** Column :WAVE not found");
122
/* Verification loop */
123
/* If the threshold parameter thres<0, the line catalog is explored to
124
make sure that wavelengths are sorted by increasing value and no
125
wavelength is duplicated */
129
TCERDD(tidcat, 1, catwav, &lambda_low, &null);
130
for (row=2; row<=nbrowcat; row++) {
131
TCERDD(tidcat, row, catwav, &lambda_upp, &null);
132
if (lambda_low > lambda_upp) {
133
printf("Warning: Column :WAVE of the table %s is not sorted by increasing wavelength\n",lincat);
137
if (lambda_low == lambda_upp) {
138
printf("Error: Column :WAVE of the table %s contains duplicated wavelength : %f\n",
140
SCKWRD("OUTPUTD",&lambda_low,1,1,&kunit);
144
lambda_low = lambda_upp;
146
status = SCKWRR("INPUTR", &thres[0], 1, 1, &kunit);
151
/* Locates columns :IDENT, :WAVEC, :RESIDUAL in table LINE */
153
TCCSER(tidlin, ":IDENT", &linid);
154
if (linid == (-1)) SCTPUT("**** Column :IDENT not found");
156
TCCSER(tidlin, ":WAVEC", &linwav);
157
if (linwav == (-1)) SCTPUT("**** Column :WAVEC not found");
159
TCCSER(tidlin, ":Y", &liny);
160
if (liny == (-1)) SCTPUT("**** Column :Y not found");
162
TCCSER(tidlin, ":ERROR", &linerr);
163
TCCSER(tidlin, ":DISTANCE", &liniso);
165
TCCSER(tidlin, ":RESIDUAL", &lindif);
166
if (lindif == (-1)) TCCINI(tidlin, D_R8_FORMAT, 1, "F10.3", "Angstrom",
167
"RESIDUAL", &lindif);
172
SCFCRE("buffer.bdf",D_R8_FORMAT,F_X_MODE,F_IMA_TYPE,bufsize,&imno);
173
SCFMAP(imno,F_X_MODE,1, bufsize, &actvals, (char **)&pntr_buf);
177
SCTPUT ("Identifying lines...\n");
180
for (row = 1; row <= nbrow; row++) {
182
/* Reads current wavelength to be identified and relative order number */
183
TCERDD(tidlin, row, linwav, &lambda_lin, &null);
184
TCERDI(tidlin, row, liny, &ordref, &null);
186
/* Read the error on wavelength if the column exists */
189
TCERDD(tidlin, row, linerr, &error, &null);
193
/* printf ("Reading line.tbl row = %d line = %f\n",row,lambda_lin); */
195
pntr_buf[ipos(6,row,nbrow)] = 0.;
197
if (lambda_lin != 0.) {
199
pntr_buf[ipos(6,row,nbrow)] = 1.;
200
reslow_abs = 99999.9;
201
resupp_abs = 99999.9;
203
/* Finds the residual to the nearest lower line in the same order */
206
TCERDI(tidlin, rowlow, liny, &order, &null);
207
if (order == ordref) {
208
TCERDD(tidlin, rowlow, linwav, &lambda_low, &null);
209
reslow = lambda_lin - lambda_low;
210
reslow_abs = (reslow < 0) ? -reslow : reslow; /* abs. value */
214
/* Finds the residual to the nearest upper line in the same order */
217
TCERDI(tidlin, rowupp, liny, &order, &null);
218
if (order == ordref) {
219
TCERDD(tidlin, rowupp, linwav, &lambda_upp, &null);
220
resupp = lambda_lin - lambda_upp;
221
resupp_abs = (resupp < 0) ? -resupp : resupp; /* abs. value */
225
/* Compares both residuals and selects the minimum */
226
if (row == 1) reslow_abs = resupp_abs;
227
if (row == nbrow) resupp_abs = reslow_abs;
228
/* printf("Table line: low,high %f %f\n",reslow_abs, resupp_abs); */
230
if (reslow_abs < resupp_abs)
231
pntr_buf[ipos(1,row,nbrow)] = reslow_abs;
233
pntr_buf[ipos(1,row,nbrow)] = resupp_abs;
236
/* Reads the line catalog at the first entry point and initializes variables */
237
/* printf ("Reading catalog thar.tbl rowcat = %d\n",rowcat); */
240
TCERDD(tidcat, rowlow, catwav, &lambda_low, &null);
242
TCERDD(tidcat, rowupp, catwav, &lambda_upp, &null);
243
reslow = lambda_lin - lambda_low;
244
reslow_abs = (reslow < 0) ? -reslow : reslow; /* abs. value */
245
resupp = lambda_lin - lambda_upp;
246
resupp_abs = (resupp < 0) ? -resupp : resupp; /* abs. value */
249
/* The line catalog is assumed to be ordered. Depending on which direction
250
is found the minimum residual, the catalog will be searched further in this
253
if (reslow_abs < resupp_abs) {
256
resref_abs = reslow_abs;
257
lambda_ref = lambda_low;
263
resref_abs = resupp_abs;
264
lambda_ref = lambda_upp;
268
res_abs = resref_abs;
270
lambda_cat = lambda_ref;
272
/* Explores the catalog in the direction indicated by index and finds the
273
position of the minimum residual */
274
while (res_abs <= resref_abs) {
276
resref_abs = res_abs;
277
lambda_ref = lambda_cat;
279
if (rowcat<=1 || rowcat >= (nbrowcat-1)) {
280
printf ("Error: reached limit of line catalog\n");
281
printf ("Wavelength: %f Position: %d\n",lambda_lin,rowcat);
285
TCERDD(tidcat, rowcat, catwav, &lambda_cat, &null);
286
/* printf ("Matching loop at rowcat = %d cat = %f\n",rowcat,lambda_cat); */
287
residual = lambda_lin - lambda_cat;
288
res_abs = (residual < 0) ? -residual : residual; /* abs. value */
292
rowref = rowcat - index;
293
/* printf("Ref: Read wavelength %f at position %d\n",lambda_ref,rowref); */
294
/* rowref is now the position of the minimum residual */
295
pntr_buf[ipos(2,row,nbrow)] = resref_abs;
296
pntr_buf[ipos(3,row,nbrow)] = lambda_ref;
297
pntr_buf[ipos(4,row,nbrow)] = lambda_lin;
301
TCERDD(tidcat, rowlow, catwav, &lambda_low, &null);
302
/* printf("Low: Read wavelength %f at position %d\n",lambda_low,rowlow); */
303
reslow = lambda_ref - lambda_low;
304
reslow_abs = (reslow < 0) ? -reslow : reslow; /* abs. value */
307
if (rowref < nbrowcat && rowref > 1) {
309
TCERDD(tidcat, rowupp, catwav, &lambda_upp, &null);
310
/* printf("Upp: Read wavelength %f at position %d\n",lambda_upp,rowupp); */
311
resupp = lambda_ref - lambda_upp;
312
resupp_abs = (resupp < 0) ? -resupp : resupp; /* abs. value */
315
if (rowref == 1) reslow_abs = resupp_abs;
316
if (rowref == nbrowcat) resupp_abs = reslow_abs;
317
/* printf("Catalog: low,high %f %f\n",reslow_abs, resupp_abs); */
319
if (reslow_abs < resupp_abs)
320
pntr_buf[ipos(5,row,nbrow)] = reslow_abs;
322
pntr_buf[ipos(5,row,nbrow)] = resupp_abs;
325
if (pntr_buf[ipos(1,row,nbrow)] < pntr_buf[ipos(5,row,nbrow)])
326
reslow = pntr_buf[ipos(1,row,nbrow)];
328
reslow = pntr_buf[ipos(5,row,nbrow)];
330
reslow = reslow * thres[0];
331
if (error < 0.) error = reslow;
332
finres = pntr_buf[ipos(2,row,nbrow)];
334
pntr_buf[ipos(7,row,nbrow)] = lambda_lin;
335
pntr_buf[ipos(8,row,nbrow)] = reslow;
336
pntr_buf[ipos(9,row,nbrow)] = error;
338
pntr_buf[ipos(10,row,nbrow)] = lambda_ref;
339
pntr_buf[ipos(11,row,nbrow)] = resref;
342
} /* End of if lambda_lin != 0. */
344
/* printf("Row %d Order %d - %f %f %f %f %f\n",row,ordref, */
345
/* pntr_buf[ipos(1,row,nbrow)],pntr_buf[ipos(2,row,nbrow)], */
346
/* pntr_buf[ipos(3,row,nbrow)],pntr_buf[ipos(4,row,nbrow)], */
347
/* pntr_buf[ipos(5,row,nbrow)]); */
349
} /* End of for row = */
352
/* Determines the standard error on a fraction of the most isolated lines TCEWRD(tidlin, row, liniso, &reslow); */
354
number = (int) ((float) nbrow / 10);
355
if (number < 10 ) number = 10;
356
stdev(number,&error_min);
357
sprintf(Msg,"Std Dev on %d lines: %g wav. units \n",number,error_min);
362
for (row = 1; row <= nbrow; row++) {
363
lambda_lin = pntr_buf[ipos(7,row,nbrow)];
365
if (lambda_lin != 0.) {
366
finres = pntr_buf[ipos(2,row,nbrow)];
367
reslow = pntr_buf[ipos(8,row,nbrow)];
369
error = pntr_buf[ipos(9,row,nbrow)];
371
accumulate(log(finres/error),log(reslow/error));
377
for (row = 1; row <= nbrow; row++) {
379
lambda_lin = pntr_buf[ipos(7,row,nbrow)];
381
if (lambda_lin != 0.) {
383
finres = pntr_buf[ipos(2,row,nbrow)];
384
reslow = pntr_buf[ipos(8,row,nbrow)];
385
error = pntr_buf[ipos(9,row,nbrow)]*exp(maxval);
386
/* error = 2.5*error_min; */
388
lambda_ref = pntr_buf[ipos(10,row,nbrow)];
389
resref = pntr_buf[ipos(11,row,nbrow)];
391
/* printf("Comparing line %f with catalog %f.\n ",lambda_ref,lambda_lin);
392
printf("Residual is %f and maximum residual is %f\n",finres,reslow); */
394
TCEWRD(tidlin, row, liniso, &reslow);
395
TCEWRD(tidlin, row, lindif, &resref);
396
if (finres < error && error <= reslow) {
397
TCEWRD(tidlin, row, linid, &lambda_ref);
398
/* printf("**** Identified line: %f %f\n",lambda_ref,resref); */
401
}} /* End of if lambda_lin and for (row = */
415
char ident[81], cunit[33];
418
strcpy(ident,"Error proportionality coefficient accumulator");
419
strcpy(cunit,"Frequency ");
421
SCIPUT(name,D_R4_FORMAT,F_IO_MODE,F_IMA_TYPE,1,&npix,
422
&start,&step,ident,cunit, (char **)&pntr, &imno);
424
stend = start + (npix-1)*step;
426
for (i=0; i<npix; i++) pntr[i] = 0.;
431
void accumulate(min,max)
437
int pixmin, pixmax, i;
440
if (max < min) return;
442
if (min < start) vmin = start;
445
if (max > stend) vmax = stend;
448
pixmin = (vmin-start)/step;
449
pixmax = (vmax-start)/step;
451
for (i=pixmin; i<=pixmax; i++) pntr[i] += 1;
460
void findmax(fraction)
466
int pixmax, i, pixopt;
472
for (i=1; i<npix; i++) {
473
if (pntr[i] > vmax) {
479
maxval = start + (pixmax-1)*step;
480
/* printf("Found optimum at %f . Value: %f\n",maxval,pntr[pixmax]); */
482
vopt = fraction*pntr[pixmax];
485
/* printf("Fraction: %f , Ref level: %f\n",fraction,vopt); */
487
while (vopt < pntr[pixopt] && pixopt < npix) {
489
/* printf("Current pos. %d Level: %f\n",pixopt,pntr[pixopt]); */
492
maxval = start + (pixopt-1)*step;
493
/* printf("Selection level at %f . Value: %f\n",maxval,pntr[pixopt]); */
497
void stdev(number, error)
504
int row, posval, nb, flag, i;
505
double maxval, val, res, lambda;
507
for (nb=1; nb<=number; nb++) {
509
maxval = -1.; /* Sort positive values */
512
for (row=1;row<=nbrow;row++) {
516
lambda = pntr_buf[ipos(7,row,nbrow)];
517
if (lambda < 1.) flag = 1;
519
for(i=1; i<nb; i++) {
520
if (row == tmp_pos[i]) {
525
val = pntr_buf[ipos(8,row,nbrow)];
526
res = pntr_buf[ipos(2,row,nbrow)];
527
if (val > res && val > maxval){
528
maxval = val; posval = row;
532
tmp_pos[nb] = posval;
533
tmp_iso[nb] = maxval;
534
tmp_res[nb] = pntr_buf[ipos(2,posval,nbrow)];
537
/* Now sorting tmp array by decreasing residual value */
547
for(row=2; row<=number; row++) {
548
if (tmp_res[row-1] < tmp_res[row]) {
550
tmpr = tmp_res[row-1], tmpi = tmp_iso[row-1], tmpp = tmp_pos[row-1];
551
tmp_res[row-1] = tmp_res[row];
552
tmp_iso[row-1] = tmp_iso[row];
553
tmp_pos[row-1] = tmp_pos[row];
554
tmp_res[row] = tmpr, tmp_iso[row] = tmpi, tmp_pos[row] = tmpp;
561
for (row=1; row<=number; row++) {
565
*error = sqrt(std/(nb-1));
568
*error = tmp_res[number/2];
570
/* Writing the residuals in a small auxiliary ascii file */
574
fp = fopen("dat.dat","w");
575
for (row=1; row<=number; row++)
576
fprintf(fp,"%f %f\n",tmp_res[row],tmp_iso[row]);