/* @(#)applic.c 17.1.1.1 (ES0-DMD) 01/25/02 17:29:51 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /* @(#)app_xident.c 1.0.0.0 (ESO-La Silla) 10/08/91 12:00:00 */ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .IDENT gspec.c .MODULE subroutines -- gmidas.exe .LANGUAGE C .AUTHOR Cristian Levin - ESO La Silla .PURPOSE This routines implement the application part of the Spectra context. .KEYWORDS application routines, Midas related routines. .VERSION 1.0 1-Mar-1991 Implementation .ENVIRONMENT UNIX ------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #define LINE_ADD_TABLE "lineadd" /******************* Local variables *******************/ static LCTAB * Lc = NULL; /* Line catalog table */ static float * LinePos; /* array of positions of LINE.tbl */ static float * LinePeak; /* array of intensities of LINE.tbl */ static float * Ident; /* array of :IDENT values of LINE.tbl */ static int * LineRow; /* row numbers. of each element of LinePos */ static int NumLinePos = 0; /* LinePos cardinality */ static char * List[MAXTEXT]; static int LincatAllocated = FALSE; static char LineTable[MAXLINE]; /********************************** application external variables **********************************/ extern char Wlc[], /* WLC name */ WlcIdent[], /* WLC identification */ Lincat[]; /* Line catalog name */ extern float LincatPos[]; /* :WAVE in 'Lincat' pointed by the user */ extern float WlcPos[]; /* :X values in LINE matching LincatPos[] */ extern int NumLincatPos; /* cardinality of LincatPos[] */ extern int NumWlcPos; /* cardinality of WlcPos[] */ extern int IdentBegin; float *fvector(); int *ivector(); /******************* local functions *******************/ void read_params_long(); void ident_spec(); void label_spec(); void free_lincat(); void label_spectrum(); void read_params_long() { int actval; /* actual values returned */ int unit; /* useless */ int nulval; /* useless */ SCKGETC("LINTAB", 1, 20, &actval, LineTable); SCKGETC("WLC", 1, 20, &actval, Wlc); SCKGETC("LINCAT", 1, 20, &actval, Lincat); SCKRDI("WRANG", 1, 2, &actval, Wrang, &unit, &nulval); SCKRDR("IMIN", 1, 1, &actval, &Imin, &unit, &nulval); SCKRDI("YSTART", 1, 1, &actval, &Ystart, &unit, &nulval); SCKRDI("NPIX", 1, 2, &actval, Npix, &unit, &nulval); } /***************************************************************** * read_lincat_table(): reads line catalog named by 'Lincat' and * stores the values in the 'Lc' structure, under the * restrictions Wrang & Imin. *****************************************************************/ int read_lincat_table() { if ( ! file_exists( Lincat, ".tbl" ) ) { SCTPUT( "*** Line catalogue doesn't exist ***" ); return(FALSE); } if ( Lc != NULL ) { /* deallocate space */ free_fvector(Lc->wave, 0, Lc->nrows - 1); free_fvector(Lc->intens, 0, Lc->nrows - 1); free_cmatrix(Lc->ion, 0, Lc->nrows - 1, 0, MAXION - 1); osmmfree((char *)Lc); } Lc = (LCTAB *)osmmget( sizeof(LCTAB) ); /* call to a library routine */ if( !read_catalog_table( Lc, Lincat, Wrang, Imin ) ) { Lc = NULL; return FALSE; } return TRUE; } /*************************************************************** * read_line_x(): reads columns :X and :PEAK of LINCAT table, * OUT: float LinePos[] = array of X values. * float LineRow[] = indexes to the rows in the table. * int NumLinePos = no. of elements of LinePos. */ int read_line_x( ident_step ) int ident_step; /* IDBEGIN ==> Identifications are cleared */ /* IDCONT ==> Identifications are read */ { int nulval, sortcol, aw, ar, ncols; int i, id, colid, colx, colpeak, colerased, selected; int lines_search = FALSE; char val_ok[2]; float valx, valpeak; static int nrows; if ( ! file_exists( LineTable, ".tbl" ) ) return; if ( NumLinePos > 0 ) { free_fvector(LinePos, 0, nrows - 1); free_fvector(LinePeak, 0, nrows - 1); free_fvector(Ident, 0, nrows - 1); free_ivector(LineRow, 0, nrows - 1); } sprintf(val_ok, "%c", VAL_OK); NumLinePos = 0; TCTOPN( LineTable, F_IO_MODE, &id ); TCIGET( id, &ncols, &nrows, &sortcol, &aw, &ar ); TCCSER( id, ":X", &colx ); TCCSER( id, ":PEAK", &colpeak ); TCCSER( id, ":ERASED", &colerased ); TCCSER( id, ":IDENT", &colid ); if ( colid == -1 ) TCCINI( id, D_R4_FORMAT, 1, "F10.3", "ANGSTROM", "IDENT", &colid ); /* allocate space for data */ LinePos = fvector(0, nrows - 1); LinePeak = fvector(0, nrows - 1); Ident = fvector(0, nrows - 1); LineRow = ivector(0, nrows - 1); for ( i = 1; i <= nrows; i++ ) { TCSGET(id, i, &selected); if ( selected ) { lines_search = TRUE; TCERDR( id, i, colx, &LinePos[NumLinePos], &nulval ); TCERDR( id, i, colpeak, &LinePeak[NumLinePos], &nulval ); Ident[NumLinePos] = Rnull; if ( ident_step == IDBEGIN ) { /* :IDENT <-- NULL */ TCEWRR( id, i, colid, &Rnull ); if ( colerased != -1 ) TCEWRC( id, i, colerased, val_ok ); } else TCERDR( id, i, colid, &Ident[NumLinePos], &nulval ); LineRow[NumLinePos] = i; NumLinePos++; } } TCTCLO( id ); if ( !lines_search ) { SCTPUT( "*** YSTART row doesn't have lines searched ***" ); return(FALSE); } return(TRUE); } int update_line_table( action ) int action; { char erased; char invalid_value = VAL_INVALID, valid_value = VAL_OK; int nulval, sortcol, aw, ar, ncols, nrows; int i, id, col; if ( ! file_exists( LineTable, ".tbl" ) ) { SCTPUT( "*** Lines have not been searched ***" ); return(FALSE); } if ( TCTOPN( LineTable, F_IO_MODE, &id ) != 0 ) { SCTPUT( "Table LINE couldn't be opened." ); return; } TCCSER( id, ":ERASED", &col ); if ( col == -1 ) /* nothing to update */ return; TCIGET( id, &ncols, &nrows, &sortcol, &aw, &ar ); for ( i = 0; i < nrows; i++ ) { erased = VAL_OK; TCERDC( id, i+1, col, &erased, &nulval ); if ( erased == VAL_ERASED && action == DELMARK ) TCEWRC( id, i+1, col, &invalid_value ); else if ( erased != VAL_OK && action == ADDMARK ) TCEWRC( id, i+1, col, &valid_value ); } TCTCLO(id); return(TRUE); } void display_lincat_table( wlist ) Widget wlist; { int i; XmStringTable str_list; XmString item; if ( LincatAllocated ) free_lincat(); LincatAllocated = TRUE; for ( i = 0; i < Lc->nrows; i++ ) List[i] = (char *)osmmget( 80 ); List[Lc->nrows] = NULL; for ( i = 0; i < Lc->nrows; i++ ) sprintf( List[i], " %8.2f %10.5g %10s", Lc->wave[i], Lc->intens[i], Lc->ion[i] ); str_list = (XmStringTable)XtMalloc(Lc->nrows * sizeof(XmString *)); for ( i = 0; i < Lc->nrows; i++ ) str_list[i] = XmStringCreateSimple(List[i]); XmListSetPos(wlist, 1); XmListDeleteAllItems(wlist); XmListAddItems(wlist, str_list, Lc->nrows, 1); for ( i = 0; i < Lc->nrows; i++ ) XmStringFree(str_list[i]); XtFree((char *)str_list); } void free_lincat() { int i; for ( i = 0; i < Lc->nrows; i++ ) osmmfree( List[i] ); } /***************************************************************** plot_spec() description: plot the starting line (Ystart) of the calibration image (Wlc). If label = LABEL_SPEC, it plots additionally the lines found and the previous identifications. use: line identification. line adding for directed search. */ int plot_spec( label ) int label; { int unit; /* useless */ int nulval, actval; /* useless */ int id; int naxis; if ( ! file_exists( Wlc, ".bdf" ) ) { SCTPUT( "*** Calibration image invalid ***" ); return(FALSE); } SCFOPN( Wlc, D_R4_FORMAT, 0, F_IMA_TYPE, &id ); SCDRDI( id, "NAXIS", 1, 1, &actval, &naxis, &unit, &nulval ); SCDRDI( id, "NPIX", 1, 2, &actval, Npix, &unit, &nulval ); SCFCLO(id); if ( Ystart > Npix[1] && naxis > 1 ) { SCTPUT( "*** Starting line out of bound ***" ); return(FALSE); } Areadim(Wlc, Ystart, 0, FALSE); if ( label == LABEL_SPEC ) label_spectrum(); return(TRUE); } void get_wlc_value() { float cpx = 0.0, cpy = 0.0; int key, valpix; int i = 0; if ( NumWlcPos > NumLincatPos ) /* clicking twice in graph. win */ NumWlcPos = NumLincatPos; XtSetSensitive((Widget) UxGetWidget(UxFindSwidget("menu3_p2")),FALSE); init_graphic(DEV_NO_ERASE); set_viewport(); AG_VLOC( &cpx, &cpy, &key, &valpix ); end_graphic(); if ( key == LEFT_BUT ) WlcPos[NumWlcPos++] = cpx; else XtSetSensitive((Widget) UxGetWidget(UxFindSwidget("menu3_p2")),TRUE); } void delete_idents() { float curr_delta, delta, cpx = 0.0, cpy = 0.0; float wlimits[4], x[2], y[2]; int i, id, colid, linepos, key, valpix; char str[MAXLINE]; if ( TCTOPN( LineTable, F_IO_MODE, &id ) != 0 ) { SCTPUT( "Line table could not be opened." ); return; } TCCSER( id, ":IDENT", &colid ); init_graphic(DEV_NO_ERASE); set_viewport(); AG_SSET( BLUE_COLOR ); AG_RGET( "WNDL", wlimits ); y[0] = wlimits[YMIN]; while ( 1 ) { /* forever */ AG_VLOC( &cpx, &cpy, &key, &valpix ); if ( key == MID_BUT ) break; delta = MAXDELTA; for ( i = 0; i < NumLinePos; i++ ) { curr_delta = fabs((double)(LinePos[i] - cpx)); if ( curr_delta < delta ) { linepos = i; delta = curr_delta; } } x[0] = x[1] = LinePos[linepos]; y[1] = LinePeak[linepos]; AG_GPLL( x, y, 2 ); sprintf( str, "Line removed : %.2f Wavelength: %.2f", LinePos[linepos], Ident[linepos] ); SCTPUT(str); Ident[linepos] = Rnull; TCEWRR(id, LineRow[linepos], colid, &Rnull); } AG_SSET( DEF_COLOR ); TCTCLO(id); end_graphic(); } void show_current_idents() { int i; char msg[MAXLINE]; SCTPUT( " " ); SCTPUT( "Current identifications" ); SCTPUT( "Position Wavelength" ); SCTPUT( "-----------------------" ); for ( i = 0; i < NumLinePos; i++ ) if ( Ident[i] != Rnull ) { sprintf( msg, "%7.1f %9.2f", LinePos[i], Ident[i] ); SCTPUT( msg ); } SCTPUT( " " ); } void ident_line() { int i, linepos = 0; int id, colid; double delta = MAXDELTA, curr_delta; float val; float x[1], y[1]; char str[MAXLINE]; val = WlcPos[NumWlcPos-1]; /* last value picked */ for ( i = 0; i < NumLinePos; i++ ) { curr_delta = fabs((double)(LinePos[i] - val)); if ( curr_delta < delta ) { linepos = i; delta = curr_delta; } } sprintf( str, "Line added : %.2f Wavelength: %.2f", LinePos[linepos], LincatPos[NumWlcPos-1] ); SCTPUT( str ); if ( TCTOPN( LineTable, F_IO_MODE, &id ) != 0 ) { SCTPUT( "Line table could not be opened." ); return; } TCCSER( id, ":IDENT", &colid ); TCEWRR( id, LineRow[linepos], colid, &LincatPos[NumWlcPos-1] ); TCTCLO( id ); Ident[linepos] = LincatPos[NumWlcPos-1]; x[0] = LinePos[linepos]; y[0] = LinePeak[linepos]; Alabelx(x, y, 1, GREEN_COLOR); } /**************************************************************************** exist_descriptor(): checks if the descriptor 'desc' exists in 'image'. */ int exist_descriptor( image, desc ) char *image; /* name of the image */ char *desc; /* descriptor name */ { int nulval, id; char type; if ( file_exists( image, ".bdf" ) ) { SCFOPN( image, D_R4_FORMAT, 0, F_IMA_TYPE, &id ); SCDFND( id, desc, &type, &nulval, &nulval ); if ( type != ' ' ) { SCFCLO(id); return(TRUE); } SCFCLO(id); } return(FALSE); } /**************************************************************** get_lines_to_add(): plot the spectrum and get x-coordinates of the spectral lines to add from the graphics cursor. */ void get_lines_to_add( plot_label) int plot_label; /* TRUE --> plot spectrum with existent lines */ /* FALSE --> plot spectrum without existent lines */ { float wlimits[4], x[2], y[2], cpx = 0.0, cpy = 0.0; int key, valpix; if ( !plot_spec(plot_label) ) /* plot 'WLC(Ystart)' */ return; NToAdd = 0; init_graphic(DEV_NO_ERASE); set_viewport(); AG_SSET( RED_COLOR ); AG_RGET( "WNDL", wlimits ); y[0] = wlimits[YMIN]; y[1] = wlimits[YMAX]; while( 1 ) { AG_VLOC( &cpx, &cpy, &key, &valpix ); if ( key == MID_BUT ) break; LinesToAdd[NToAdd] = cpx; x[0] = x[1] = cpx; AG_GPLL( x, y, 2 ); NToAdd++; } AG_SSET( DEF_COLOR ); end_graphic(); } /**************************************************************** create_add_table(): save the x-coordinates of the spectral lines to add into the table LINEADD.tbl. */ void create_add_table( n, lines ) int n; float lines[]; { int i, id, col; int unit; TCTINI( LINE_ADD_TABLE, F_TRANS, F_O_MODE, 3, 100, &id ); TCCINI( id, D_R4_FORMAT, 1, "F10.2", "PIXEL", "X", &col ); SCDWRI( id, "YSTART", &Ystart, 1, 1, &unit ); for ( i = 0; i < n; i++ ) TCRWRR( id, i+1, 1, &col, lines+i ); TCTCLO(id); } void label_spectrum() { float x[1], y[1]; int i; Alabelx( LinePos, LinePeak, NumLinePos, BLUE_COLOR ); for ( i = 0; i < NumLinePos; i++ ) if ( Ident[i] != Rnull ) { x[0] = LinePos[i]; y[0] = LinePeak[i]; Alabelx( x, y, 1, GREEN_COLOR ); } } int check_plot() { if ( !IdentBegin ) { read_params_long(); if ( ! read_lincat_table() ) return FALSE; if ( !read_line_x(IDCONT) ) { /* :X of line table */ SCTPUT( "*** Lines have not been searched ***" ); return FALSE; } if ( !plot_spec(LABEL_SPEC) ) return FALSE; } IdentBegin = TRUE; return TRUE; } void cutx_spectrum() { if ( !check_plot() ) return; while ( Acutx() != MID_BUT ) label_spectrum(); } void cuty_spectrum() { if ( !check_plot() ) return; while ( Acuty() != MID_BUT ) label_spectrum(); } void shift_spectrum() { if ( !check_plot() ) return; while ( Ashift() != MID_BUT ) label_spectrum(); } void unzoom_spectrum() { if ( !check_plot() ) return; Aunzoom(); label_spectrum(); } void getcur_spectrum() { if ( !check_plot() ) return; Agetcur(); } void redraw_plot() { init_graphic(DEV_NO_ERASE); set_viewport(); redraw_spectrum(); end_graphic(); label_spectrum(); }