/* identification */ #define VERSION "2.9" /* version number */ #define PROGRAM "LRSCAL" /* program name */ /* lrscal.c COPYRIGHT (c) 1990 Kapteyn Astronomical Institute - University of Groningen P.O. Box 800, 9700 AV Groningen, The Netherlands #> lrscal.dc1 Program: LRSCAL Purpose: Generate a calibrated LRS spectrum from data in an IRDS Category: IRAS File: lrscal.c Author: P.R. Roelfsema Keywords: IRSET= Name of input IR data set [quit] IRSETOUT= Name of output IR data set [no output] POS= Position at which spectrum is to be generated [ same as before ] Giving Q(UIT) at this keyword will stop the program. SNIP= Give snip number of spectrum to process [ all remaining spectra ] Possible answers are : Q(UIT) - loop the program back to the POS= keyword. A(LL) - (re)process all spectra in the data set. n - process snip number n. If all spectra have been calibrated has the same effect as typing Q(UIT). *** ISLIM= In-Scan offset where spectrum extraction starts in arcsec [ 2000 ] *** SINGLE= Use single baseline component ? [ N ] The baseline subtraction for LRS is best done using two separate baselines; one for those data from before the source crossed the aperture and one derived from the data after the aperture crossing. This is the standard mode (SINGLE=N). In low signal to noise conditions this approach gives rise to wildly varying baslines, and thus in that case it is better to determine one global baseline level, this can be forced by specifying SINGLE=Y. *** BWIN= Set default window for ALL snips [ -1000 -250 250 1000 ] *** BWINn= Windows (inscan) for baseline of snip n [ BWIN= value] This keyword can be used to specify up to two windows in the in-scan direction. Through the data within these windows a straight line is fitted which is subsequently subtracted from the data. e.g. BWIN3=-300 -200 200 300 (in arcsec). UNITS= Give units of data after calibration [LFL] Options are: Jy - F(lambda) in Jy Wm - F(lambda) in Wm^-2mu^-1 LFL - lambda*F(lambda) in Wm^-2 L4FL - lambda^4*F(lamba) in Wm^-2mu^3 GRDEVICE= Give graphics device for display [ list available devices ] ***COHEN= Apply Cohen correction factors? [ Yes ] ***MXGAIN= Specify maximum cross-scan gain to be applied [ 2 ] This keyword allows the user to discard data taken with the source of interest very close to the edge of a detector. This is done by setting a limit on the maximum correction for the cross-scan gain variations. The cross-scan gain corrections vary from 1.0 at the centre of the detectors upto 5-6 near the edges. ***ALIGN= Align spectral halves? [ Yes ] If no is specified the short wave and long wave spectral halves are not aligned. ***MINMAX= Min and max levels to be plotted [ min and max of data ]. ***PSC= Point source catalogue fluxes (Jy) at 12 and 25 mu [ none ]. ***THICK= Do you want thick lies in plot? [ Yes ]. Updates: May 10, 1990: PRR, Document created. Dec 17, 1990: PRR, Version 1.0. Feb 11, 1991: PRR, Upgrade for PGPLOT. Feb 13, 1991: PRR, Major rewrite. Jun 12, 1991: PRR, new flux-calibration. Aug 9, 1991: PRR, min nr. of ticks implemented rms noise calculation. Oct 10, 1991: WZ, PGPLOT standard names implemented Mar 19, 1992: HB, New interface to irds_enquire_snip Sep 23, 1992: PRR, Changed BWIN default, baseline subtraction, more UNITS. Mar 23, 1993: PRR, GRDEVICE not cancelled anymore Jul 20, 1993: PRR, added Cohen correction factors Jul 22, 1993: PRR, added MXGAIN and ALIGN options Aug 9, 1993: PRR, solved (?) crashes on HP Aug 11, 1993: PRR, changed BWIN= to BWINn= Aug 13, 1993: PRR, added BWIN= to BWINn= #< */ #include "stdio.h" #include "string.h" #include "ctype.h" #include "stdlib.h" #include "math.h" #include "gipsyc.h" #include "cmain.h" #include "nelc.h" #include "init.h" #include "finis.h" #include "anyout.h" #include "status.h" #include "cancel.h" #include "error.h" #include "gds_exist.h" #include "gdsc_word.h" #include "gdsd_rchar.h" #include "gdsd_wchar.h" #include "gdsd_rint.h" #include "gdsd_rreal.h" #include "userint.h" #include "userlog.h" #include "userreal.h" #include "userdble.h" #include "userangle.h" #include "usertext.h" #include "sortra.h" #include "minmax4.h" #include "setfblank.h" #include "spline1.h" #include "irds_exist.h" #include "irds_enquire.h" #include "irds_enquire_snip.h" #include "irds_rd_samples.h" #include "irds_rd_detoff.h" #include "ircc_bandnr.h" #include "ircc_detnr.h" #include "ircc_mask.h" #include "ircc_times.h" #include "irlrs_set_exist.h" #include "irlrs_set_create.h" #include "irlrs_set_addsnip.h" #include "irlrs_set_wrsnip.h" #include "irlrs_dettype.h" #include "irlrs_pos2wave.h" #include "irlrs_jyperpwm2.h" #include "irlrs_pwm2permv.h" #include "irlrs_lgain.h" #include "irlrs_cohen_gain.h" #include "irlrs_xgain.h" #include "irlrs_adroop.h" #include "irco_precess.h" #include "irco_number.h" #include "pgbeg.h" #include "pgqinf.h" #include "pgswin.h" #include "pgsvp.h" #include "pgsch.h" #include "pgslw.h" #include "pgsls.h" #include "pgtext.h" #include "pgptxt.h" #include "pgmtxt.h" #include "pgdraw.h" #include "pgmove.h" #include "pgline.h" #include "pgbox.h" #include "pglab.h" #include "pgiden.h" #include "pgend.h" /* definitions for error levels */ static fint error_level_fatal = 4; #define FATAL_ERROR ( &error_level_fatal ) /*static fint error_level_serious = 3; #define SERIOUS_ERROR ( &error_level_serious ) static fint error_level_minor = 2; #define MINOR_ERROR ( &error_level_minor )*/ static fint error_level_warning = 1; #define WARNING ( &error_level_warning ) /* definitions for anyout levels */ static fint anyout_level_default = 0 ; #define ANYOUT_DEF ( &anyout_level_default ) /*static fint anyout_level_terminal = 1 ; #define ANYOUT_TERM ( &anyout_level_terminal ) static fint anyout_level_logfile = 2 ; #define ANYOUT_LOG ( &anyout_level_logfile ) static fint anyout_level_dumb_user = 8 ; #define ANYOUT_NOEXP ( &anyout_level_dumb_user )*/ static fint anyout_level_test = 16 ; #define ANYOUT_TST ( &anyout_level_test ) /* definitions for default levels */ /*static fint default_no_default = 0 ; #define DFLT_NONE ( &default_no_default )*/ static fint default_has_default = 1 ; #define DFLT_DEF ( &default_has_default ) static fint default_hidden_key = 2 ; #define DFLT_HIDD ( &default_hidden_key ) /*static fint default_exact_number = 4 ; #define DFLT_EXACT ( &default_exact_number)*/ /* keywords and USER*** message strings */ #define INSET_KEY tofchar("IRSET=") #define INSET_MES tofchar("Give input LRS data set [quit]") #define OUTSET_KEY tofchar("IRSETOUT=") #define OUTSET_MES tofchar("Give output LRS data set [no output set]") #define POS_KEY tofchar("POS=") #define SNIP_KEY tofchar("SNIP=") #define ISLIM_KEY tofchar("ISLIM=") #define ISLIM_MES tofchar("In-Scan offset where spectrum extraction starts in arcsec [ 500 ]") #define THPF_KEY tofchar("THPF=") #define THPF_MES tofchar("Time constant for high-pass filter in seconds [ 10 ]") #define ADLIM_KEY tofchar("ADLIM=") #define ADLIM_MES tofchar("Anti-droop limits in V [ 0.01 , 0.01 , 0.01 , 0.01 , 0.01 ]") #define UNITS_KEY tofchar("UNITS=") #define UNITS_MES tofchar("Give units of data after calibration [LFL] ") #define COHEN_KEY tofchar("COHEN=") #define COHEN_MES tofchar("Apply Cohen correction factors? [ Yes ]" ) #define MXGAIN_KEY tofchar("MXGAIN=") #define MXGAIN_MES tofchar("Specify max. cross-scan gain [ 2 ]" ) #define ALIGN_KEY tofchar("ALIGN=") #define ALIGN_MES tofchar("Align the spectral halves? [ Yes ]" ) #define MINMAX_KEY tofchar("MINMAX=") #define MINMAX_MES tofchar("Min and max levels to be plotted [ min and max of data ]") #define PSC_KEY tofchar("PSC=") #define PSC_MES tofchar("Point source catalogue fluxes (Jy) at 12 and 25 mu [ none ]") #define THICK_KEY tofchar("THICK=") #define THICK_MES tofchar("Do you want thick lies in plot? [ Yes ]" ) #define finit( fc , len ) { fc.a = malloc( ( len + 1 ) * sizeof( char ) ) ; \ if( !fc.a ) error_c( WARNING , tofchar( "FINIT problem" ) ) ; \ fc.a[ len ] = 0 ; \ fc.l = len ; } /* miscellaneous definitions */ #define true 1 #define false 0 #define MAXTXTLEN 160 /* length of textlines */ #define PI (double) 3.14159265358979 #define RADPERDEG ( PI / (double) 180.0 ) /* radians per degree */ #define EPS (double) 1e-9 #define NRDETS 5 /* number of LRS detectors */ #define SAMPPERSAT 32 /* number of samps/satcal */ #define MAXSATS 1000 /* maximum number of satcals */ #define MAXSNIPS 100 /* maximum number of snips */ #define NRSAMP MAXSATS * SAMPPERSAT /* nr of samples in spectra */ #define SPECLENGTH 20 /* rd 20 ticks around source */ #define MINSPECLENGTH 5 /* min. nr. of ticks */ #define SPECSAMP SPECLENGTH * SAMPPERSAT /* nr of samples extracted */ #define ISCANLIM (float) 2000.0 /* start read 2000" from src */ #define BEGINWAVE 2.0 /* start wavelength (micron) */ #define STEPWAVE 0.1 /* wavelength step (micron) */ #define NWAVE 250 /* nr. of wavelengths */ #define LWHIEDGE 22.5 /* hi wavel. edge of LW det. */ #define LWLOEDGE 11.0 /* low wavel. edge of LW det. */ #define SWHIEDGE 13.25 /* hi wavel. edge of SW det. */ #define SWLOEDGE 8.0 /* low wavel. edge of SW det. */ static fint first_spectrum_printed = false ; /* is the first sp. printed? */ /* type definitions */ typedef struct { /* type for set info */ char name[ MAXTXTLEN ] ; /* IRDS name */ double lonlat[2] ; /* position of LRS spectra */ double center[2] ; /* center of IRDS */ double size[2] ; /* on sky size of IRDS */ fint nsnips ; /* number of snips in set */ fint cosys ; /* coordinate system of set */ char coname[ MAXTXTLEN ] ; /* name of coord. system */ char object[ MAXTXTLEN ] ; /* name of object */ float epoch ; /* epoch of coord. system */ } LRSSet ; typedef long *NextSpectrumPtr ; /* pointer to next spectrum */ typedef struct { /* type for spectrum list */ fint snip ; /* snip nr. of spectrum */ fint snipdur ; /* length of original snip */ fint satcal ; /* satcal of begin of snip */ fint sop ; /* SOP of spectrum */ fint att ; /* ATT of spectrum */ fint process ; /* process this spectrum ? */ fint done ; /* is this spectrum done ? */ NextSpectrumPtr next ; /* pointer to next spectrum */ } Spectrum ; typedef struct { /* type: data of 1 detector */ bool onsource ; /* did detector see source? */ fint detno ; /* detector number */ fint ns ; /* nr. of samples in spectrum */ float sigfl ; /* error in flux */ float siglm ; /* error in lambda */ float is[ SPECSAMP ] ; /* in-scan offsets */ float xs[ SPECSAMP ] ; /* cross-scan offsets */ float lm[ SPECSAMP ] ; /* calibrated wavelengths */ float fl[ SPECSAMP ] ; /* calibrated fluxes */ float max ; /* maximum flux */ float min ; /* minimum flux */ fint nspec ; /* number of spectra averaged */ } DetData ; typedef struct { /* type: raw LRS snip data */ fint snip ; /* snip nr. spectrum */ float satcal ; /* satcal of mid of spectrum */ char units[ MAXTXTLEN ] ; /* units of fluxes */ DetData det[ NRDETS + 1 ] ; /* all detectors + total */ float wave[ NWAVE ] ; /* wavelengths for resampling */ } LRSData ; /* InitialiseSpectrum is used to initailize one element in the list of spectra which are to be processed by LRSCAL. The next element will be NULL after initialization, the spectrum is not processed yet, and should be processed. The argument of InitialiseSpectrum can be used to identify a sequence of spectra. */ Spectrum *InitialiseSpectrum( fint snip , fint snipdur , fint satcal , fint sop , fint att ) { Spectrum *spectrum; anyout_c( ANYOUT_TST , tofchar(" - InitialiseSpectrum") ) ; spectrum = NULL ; spectrum = malloc( sizeof( Spectrum ) ) ; if ( spectrum ){ spectrum->snip = snip ; spectrum->snipdur = snipdur ; spectrum->satcal = satcal ; spectrum->sop = sop ; spectrum->att = att ; spectrum->process = false ; spectrum->done = false ; spectrum->next = NULL ; return( spectrum ); } else { error_c( FATAL_ERROR , tofchar( "Cannot get memory for list-element") ) ; return( NULL ); } } /* InitialiseSpectrum */ /* LastSpectrum finds out whether the current spectrum is the last to be processed. */ bool LastSpectrum( Spectrum *spectrum ) { Spectrum *temp ; temp = spectrum ; while ( temp ) { if ( temp->process && !temp->done ) { return( false ) ; } temp = (Spectrum *) temp->next ; } return( true ) ; } /* LastSpectrum */ /* InitialiseLRSData is used to Initialise the LRSData struct for further use. */ LRSData *InitialiseLRSData( fint snip ) { LRSData *raw = NULL ; fint n , sdet ; float blank ; anyout_c( ANYOUT_TST , tofchar(" - InitialiseLRSData") ) ; setfblank_c( &blank ) ; /* find blank value */ raw = malloc( sizeof( LRSData ) ) ; if ( !raw ) error_c( FATAL_ERROR , tofchar( "Cannot get memory to store data" ) ) ; raw->snip = snip ; /* snip nr. spectrum */ raw->satcal = 0.0 ; /* satcal of mid-spectrum */ sprintf( &raw->units[ 0 ] , "pWm-2" ) ; /* units of fluxes */ for ( sdet = 0 ; sdet <= NRDETS ; sdet++ ) { /* data for all detectors */ raw->det[ sdet ].onsource = false ; /* source not (yet) seen */ raw->det[ sdet ].detno = 70 + sdet ; /* set detector number */ raw->det[ sdet ].ns = 0 ; /* nr. of samples in spectrum */ raw->det[ sdet ].sigfl = 0.0 ; /* no errors yet */ raw->det[ sdet ].siglm = 0.0 ; /* no errors yet */ raw->det[ sdet ].max = 0.0 ; /* no data yet */ raw->det[ sdet ].min = 0.0 ; /* no data yet */ raw->det[ sdet ].nspec = 0 ; /* zero spectra averaged */ for ( n = 0 ; n < SPECSAMP ; n++ ) { raw->det[ sdet ].is[ n ] = 0.0 ; /* no data yet */ raw->det[ sdet ].xs[ n ] = 0.0 ; /* no data yet */ raw->det[ sdet ].lm[ n ] = 0.0 ; /* no data yet */ if ( snip == 0 ) { raw->det[ sdet ].fl[ n ] = 0.0 ; /* no average yet */ } else { setfblank_c( &raw->det[ sdet ].fl[ n ] ) ; /* no data yet */ } } } raw->det[ 0 ].detno = 0 ; /* total spectrum in sdet 0 */ for ( n = 0 ; n < NWAVE ; n++ ) { raw->wave[ n ] = BEGINWAVE + n * STEPWAVE ;/* wavelengths for average */ } return( raw ); } /* InitialiseLRSSet */ /* InitialiseLRSSet is used to Initialise the LRSSet struct for further use. */ LRSSet *InitialiseLRSSet( fchar setname ) { LRSSet *set = NULL ; anyout_c( ANYOUT_TST , tofchar(" - InitialiseLRSSet") ) ; set = malloc( sizeof(LRSSet) ); if( !set ) error_c( FATAL_ERROR , tofchar( "Cannot create set-pointer" ) ); set->name[ 0 ] = 0 ; set->lonlat[0] = 0 ; set->lonlat[1] = 0 ; set->nsnips = 0 ; set->cosys = 0 ; set->coname[ 0 ] = 0 ; set->object[ 0 ] = 0 ; set->epoch = 0 ; sprintf( set->name , "%.*s" , nelc_c( setname ) , setname.a ) ; return( set ); } /* InitialiseLRSSet */ /* BaseSub subtracts a straight line baseline from the data if the user gives limits in inscan-distance where data should be used to fit the baseline to . */ void BaseSub( float *x , float *y , fint *ndata , fint *snip ) { bool single = false ; char line[ MAXTXTLEN ] , key[ MAXTXTLEN ] ; fint n , as = 0 , bs = 0 , one = 1 , four = 4 ; float aslope = 0 , ainter = 0 ; float bslope = 0 , binter = 0 ; float wnds[ 4 ] ; float asx = 0.0 , asxx = 0.0 , asy = 0.0 , asxy = 0.0 ; float bsx = 0.0 , bsxx = 0.0 , bsy = 0.0 , bsxy = 0.0 ; float blank ; float maxX , minX , yloc = 0 , zloc = 0 , ysize = 0 , zsize = 0 ; anyout_c( ANYOUT_TST , tofchar(" - BaseSub") ) ; setfblank_c( &blank ) ; /* find blank value */ n = userlog_c( &single , &one , DFLT_HIDD , tofchar( "SINGLE=" ) , tofchar( "Use a single baseline? [ N }" ) ) ; wnds[ 0 ] = -1000 ; wnds[ 1 ] = -250 ; wnds[ 2 ] = 250 ; wnds[ 3 ] = 1000 ; sprintf( key , "BWIN=" ) ; sprintf( line , "Default window for all snips [ %6.1f %6.1f %6.1f %6.1f ]" , wnds[ 0 ] , wnds[ 1 ] , wnds[ 2 ] , wnds[ 3 ] ) ; n = userreal_c( wnds , &four , DFLT_HIDD , tofchar( key ) , tofchar( line ) ) ; sprintf( key , "BWIN%d=" , *snip ) ; sprintf( line , "Windows for baseline in snip %d [ %6.1f %6.1f %6.1f %6.1f ]" , *snip , wnds[ 0 ] , wnds[ 1 ] , wnds[ 2 ] , wnds[ 3 ] ) ; n = userreal_c( wnds , &four , DFLT_HIDD , tofchar( key ) , tofchar( line ) ) ; if ( fabs( wnds[ 0 ] ) <= 1e-5 ) return ; sortra_c( wnds , &n ) ; for ( n = 0 ; n < 4 ; n++ ) wnds[ n ] = wnds[ n ] / 3600 ; for ( n = 0 ; n < *ndata ; n++ ) { if ( ( x[ n ] > wnds[ 0 ] ) && ( x[ n ] < wnds[ 1 ] ) && ( y[ n ] != blank ) ) { as += 1 ; asx += x[ n ] ; asxx += x[n ] * x[ n ] ; asy += y[ n ] ; asxy += x[ n ] * y[ n ] ; } if ( ( x[ n ] > wnds[ 2 ] ) && ( x[ n ] < wnds[ 3 ] ) && ( y[ n ] != blank ) ) { bs += 1 ; bsx += x[ n ] ; bsxx += x[n ] * x[ n ] ; bsy += y[ n ] ; bsxy += x[ n ] * y[ n ] ; } } if ( as == 0 && bs == 0 ) return ; if ( single ) { as = as + bs ; asx = asx + bsx ; asxx = asxx + bsxx ; asy = asy + bsy ; asxy = asxy + bsxy ; ainter = ( asxx * asy - asx * asxy ) / ( as * asxx - asx * asx ) ; aslope = ( as * asxy - asx * asy ) / ( as * asxx - asx * asx ) ; binter = ainter ; bslope = aslope ; } else { if ( as != 0 ) { ainter = ( asxx * asy - asx * asxy ) / ( as * asxx - asx * asx ) ; aslope = ( as * asxy - asx * asy ) / ( as * asxx - asx * asx ) ; } if ( bs != 0 ) { binter = ( bsxx * bsy - bsx * bsxy ) / ( bs * bsxx - bsx * bsx ) ; bslope = ( bs * bsxy - bsx * bsy ) / ( bs * bsxx - bsx * bsx ) ; } } n = -5 ; (void) ircc_mask_c( &n , &yloc , &zloc , &ysize , &zsize ) ; maxX = ysize / 2 /60 ; minX = -ysize / 2 /60 ; for ( n = 0 ; n <= *ndata ; n++ ) { if ( x[ n ] <= maxX && y[ n ] != blank ) { y[ n ] = y[ n ] - ( ainter + aslope * x[ n ] ) ; } else if ( y[ n ] != blank ) { y[ n ] = y[ n ] - ( binter + bslope * x[ n ] ) ; } } } /* BaseSub */ /* GetSpectrumList will create the list of spectra for processing. This is done by searching the input IRDS coordinate system for positions corresponding to those given by the user, and subsequently putting the relevant positioning parameters in the spectrum list. These can than later be used to extract the data. */ Spectrum *GetSpectrumList( LRSSet *set , double lonlat[ 2 ] , Spectrum *spectrumlist ) { Spectrum *temp ; char line[ MAXTXTLEN ] ; fchar scantype ; float psi , psirate , theta ; fint sop , obs , att , detno , zero = 0 , one = 1 , sunref ; fint scancal , scandur , snipcal , snipdur ; fint snip , sample , status , nsamples ; double inscan[ NRSAMP ] , xscan[ NRSAMP ] , twist[ NRSAMP ] ; double lon , lat ; finit( scantype , MAXTXTLEN ) ; anyout_c( ANYOUT_TST , tofchar(" - GetSpectrumList") ) ; if ( ( spectrumlist == NULL ) || ( fabs( lonlat[ 0 ] - set->lonlat[ 0 ] ) > EPS ) || ( fabs( lonlat[ 1 ] - set->lonlat[ 1 ] ) > EPS ) ) { while ( spectrumlist != NULL ){ /* clear the spectrumlist */ temp = spectrumlist ; spectrumlist = (Spectrum *) spectrumlist->next ; free( temp ) ; } sprintf( line , "Searching set %s for snips passing (%7.2f,%7.2f)" , set->name , set->lonlat[ 0 ] , set->lonlat[ 1 ] ) ; status_c( tofchar( line ) ) ; /* Initialise top of list */ spectrumlist = InitialiseSpectrum( 0 , 0 , 0 , 0 , 0 ); temp = spectrumlist ; temp->process = false ; /* top is dummy */ detno = 0 ; /* boresight */ sunref = 5 ; lon = set->lonlat[ 0 ] * RADPERDEG ; lat = set->lonlat[ 1 ] * RADPERDEG ; for ( snip = 1 ; snip <= set->nsnips ; snip++ ) { sprintf( line , "Checking if %s, snip %d is passing (%7.2f,%7.2f)" , set->name , snip , set->lonlat[ 0 ] , set->lonlat[ 1 ] ) ; status_c( tofchar( line ) ) ; /* read snip-stuff */ irds_enquire_snip_c( tofchar( set->name ) , &snip , &sop , &obs , &att , scantype , &scancal , &scandur , &snipcal , &snipdur , &psi , &psirate , &theta , &status ) ; sprintf( line , "Considering snip %4d, sop/att (%3d,%3d) (status %d)" , snip , sop , att , status ) ; anyout_c( ANYOUT_TST , tofchar( line ) ) ; if ( snipdur >= MINSPECLENGTH ) { nsamples = snipdur * SAMPPERSAT ; sample = irds_rd_detoff_c( tofchar( set->name ) , &snip , &detno , &one , &set->cosys , &lon , &lat , &sunref , &zero , inscan , xscan , twist , &nsamples , &status ) ; sprintf( line , "Output of IRDS_RD_DETOFF : closest at sample %d (%10.5f,%10.5f,%10.5f)" , sample , inscan[ (int) labs( sample ) ] / RADPERDEG , xscan[ (int) labs( sample ) ] / RADPERDEG , twist[ (int) labs( sample ) ] / RADPERDEG ) ; anyout_c( ANYOUT_TST , tofchar( line ) ) ; if ( status == 0 && sample > 0 ) { temp->next = (NextSpectrumPtr) InitialiseSpectrum( snip , snipdur , scancal + snipcal + 1 , sop , att ) ; temp = (Spectrum *) temp->next ; sprintf( line , "Source within aperture at tick %4d" , sample / SAMPPERSAT + 1 ) ; anyout_c( ANYOUT_TST , tofchar( line ) ) ; } } } temp = spectrumlist ; spectrumlist = (Spectrum *) temp->next ; temp->next = NULL ; free( temp ) ; } else { temp = spectrumlist ; while ( temp != NULL ){ temp->process = false ; temp->done = false ; temp = (Spectrum *) temp->next ; } } return( spectrumlist ); } /* GetSpectrumList */ /* NextSpectrum asks the user which spectrum from the spectrum list he/she wants to process. */ Spectrum *NextSpectrum( Spectrum *spectrumlist ) { Spectrum *temp ; char line[ MAXTXTLEN ] , snipmes[ MAXTXTLEN ] ; fchar fbuf ; fint snip[ MAXSNIPS ] , maxsnips = MAXSNIPS ; fint n , nitems = 0 , nsnips = 0 ; anyout_c( ANYOUT_TST , tofchar(" - NextSpectrum") ) ; finit( fbuf , MAXTXTLEN ) ; fbuf.a[ 0 ] = ' ' ; fbuf.a[ 1 ] = 0 ; temp = spectrumlist ; while ( temp ) { if ( temp->process && !temp->done ) { return( temp ) ; } temp = (Spectrum *) temp->next ; } temp = spectrumlist ; nsnips = 0 ; while ( temp ) { if ( !temp->done ) { snip[ nsnips++ ] = temp->snip ; } temp = (Spectrum *) temp->next ; } sprintf( snipmes , "Give snip number to process [ all remaining spectra ]" ) ; if ( nsnips > 1 ) { sprintf( line , "Spectra" ) ; for ( n = 0 ; n < nsnips - 1 ; n++ ) { sprintf( &line[ nelc_c(tofchar(line)) ] , " %3d," , snip[ n ] ) ; if ( nelc_c( tofchar( line ) ) > MAXTXTLEN - 10 ) { anyout_c( ANYOUT_DEF , tofchar( line ) ) ; line[0] = 0 ; } } sprintf( &line[ nelc_c(tofchar(line)) ] , " and %3d are not yet calibrated." , snip[ nsnips - 1 ] ) ; } else if ( nsnips == 1 ) { sprintf( line , "Spectrum %3d is not yet calibrated." , snip[ 0 ] ) ; } else { sprintf( line , "All spectra have been calibrated" ) ; sprintf( snipmes , "Give snip number to process [ ask POS= ]" ) ; fbuf.a[0] = 'Q' ; fbuf.a[1] = 0 ; } anyout_c( ANYOUT_DEF , tofchar( line ) ) ; nitems = usertext_c( fbuf , DFLT_DEF , SNIP_KEY , tofchar( snipmes ) ) ; if ( fbuf.a[0] == 'Q' || fbuf.a[0] == 'q' ) { cancel_c( SNIP_KEY ) ; return( NULL ) ; } else if ( fbuf.a[0] == 'A' || fbuf.a[0] == 'a' ) { temp = spectrumlist ; nsnips = 0 ; while ( temp ) { snip[ nsnips++ ] = temp->snip ; temp = (Spectrum *) temp->next ; } } else { nitems = userint_c( snip , &maxsnips , DFLT_DEF , SNIP_KEY , tofchar( snipmes ) ) ; if( nitems != 0 ) nsnips = nitems ; } cancel_c( SNIP_KEY ) ; temp = spectrumlist ; for ( n = 0 ; n < nsnips ; n++ ) { while ( temp ) { if ( temp && ( temp->snip == snip[ n ] ) ) { temp->process = true ; temp->done = false ; break; } temp = (Spectrum *) temp->next ; } temp = spectrumlist ; } while ( temp && ( temp->done || !temp->process ) ) { temp = (Spectrum *) temp->next ; } return( temp ) ; } /* GetLRSSet asks the user for an IRDS to process. The routine checks whether the IRDS exists and whether it is an LRS data set. If so control returns to the caller, if not the user is prompted for a new IRSD name. If is given to the keyword the routine returns NULL indicating that the user wants to terminate the program. */ LRSSet *GetLRSSet( ) { LRSSet *set = NULL ; char line[MAXTXTLEN] ; fint ierr = 0 ; fint nitems = 0 ; fint status = 0 ; fint refsys ; fint naxes ; fint axes[ 4 ] ; fchar setname ; fchar instrument ; fchar coosys ; fchar object ; float twothou = 2000.0 ; int found = 0 ; int done = 0 ; anyout_c( ANYOUT_TST , tofchar(" - GetLRSSet") ) ; finit( setname , MAXTXTLEN ) ; /* Initialise fchars */ finit( instrument , MAXTXTLEN ) ; finit( coosys , MAXTXTLEN ) ; finit( object , MAXTXTLEN ) ; while ( !done && !found ) { nitems = usertext_c( setname, DFLT_DEF, INSET_KEY, INSET_MES );/*get set*/ done = ( nitems == 0 ) ; /* did user type CR? */ if( !done ) { found = irds_exist_c( setname , &ierr ); /* does INSET exist? */ if( found != 0 ) { /* INSET is not Irds */ (void) sprintf( line , "IRSET %.*s is not a good IR data set (%d)" , (int) nelc_c( setname ) , setname.a , found ); error_c( WARNING , tofchar( line ) ); /* tell user */ cancel_c( INSET_KEY ); /* give another chance */ found = false ; } else { /* INSET does exist */ found = true ; set = InitialiseLRSSet( setname ) ; /* Initialise the set */ anyout_c( ANYOUT_TST , tofchar( "After IniLRSSet" ) ) ; irds_enquire_c( setname , object , instrument , &naxes , axes , set->center , set->size , coosys , &set->epoch , &status ) ; anyout_c( ANYOUT_TST , tofchar( "After irds_enquire" ) ) ; if ( !strstr( instrument.a , "LRS" ) ){ /* not LRS data set */ (void) sprintf( line , "IRSET %.*s does not contain LRS data" , (int) nelc_c( setname ) , setname.a ); error_c( WARNING , tofchar( line ) ); /* tell user */ cancel_c( INSET_KEY ); /* give another chance */ found = false ; free( set ) ; set = NULL ; } } } } anyout_c( ANYOUT_TST , tofchar( "GetLRSSet got a set" ) ) ; if ( found && !done ){ set->nsnips = axes[ 3 ] ; sprintf( set->coname , "%.*s" , nelc_c( coosys ) , coosys.a ) ; sprintf( set->object , "%.*s" , nelc_c( object ) , object.a ) ; set->lonlat[ 0 ] = set->center[ 0 ] ; set->lonlat[ 1 ] = set->center[ 1 ] ; refsys = irco_number_c( coosys , &twothou ) ; if ( set->epoch == twothou ) { set->cosys = refsys ; } else { set->cosys = 0 ; irco_precess_c( &refsys , &set->epoch , &set->cosys ) ; } } else { /* user wants to stop */ if ( !set ){ free( set ) ; /* free space */ set = NULL ; /* set pointer to NULL */ } } return( set ); } /* GetLRSSet */ /* MakeLRSOutset creates an output LRS set. It uses information from the inputset inset to create the output set (outset) header. The parameters of outset are stored in an LRSSet struct. */ LRSSet *MakeLRSOutset( LRSSet *inset ) { LRSSet *set = NULL ; char line[MAXTXTLEN] ; fint ierr = 0 ; fint nitems = 0 ; fchar setname ; int outset = 0 ; int done = 0 ; float lmlo = BEGINWAVE ; float lmhi = BEGINWAVE + ( NWAVE - 1 ) * STEPWAVE ; float lmstep = STEPWAVE ; anyout_c( ANYOUT_TST , tofchar(" - MakeLRSOutset") ) ; finit( setname , MAXTXTLEN ) ; /* Initialise setname */ while ( !done && !outset ) { nitems = usertext_c( setname, DFLT_DEF, OUTSET_KEY, OUTSET_MES );/*get set*/ done = ( nitems == 0 ) ; /* did user type CR? */ if( !done ) { if( irlrs_set_exist_c( setname ) != 0 ) {/* OUTSET does exist */ (void) sprintf( line , "IRSETOUT %.*s already exists " , (int) nelc_c( setname ) , setname.a ); error_c( WARNING , tofchar( line ) ); /* tell user */ outset = false ; cancel_c( OUTSET_KEY ); } else { /* OUTSET does not exist */ outset = true ; irlrs_set_create_c( tofchar( inset->name ) , &lmlo , &lmhi , &lmstep , setname , &ierr ) ; if ( ierr < 0 ) { sprintf( line , "IRLRS_SET_CREATE error nr %d" , ierr ); error_c( FATAL_ERROR , tofchar( line ) ) ; } } } } /* cancel the keyword */ if ( outset && !done ){ set = InitialiseLRSSet( setname ) ; /* Initialise the set */ } else { /* user wants no outset */ if ( !set ){ free( set ) ; /* free space */ set = NULL ; /* set pointer to NULL */ } } return( set ); } /* MakeLRSOutset */ /* GetSpectrumPosition will ask the user for a position for which spectra should be extracted and calibrated. The routine will chek to see whether the desired position lies within the boundaries of the IRDS. If not the user gets another chance. When is entered at the prompt the program will stop. */ int GetSpectrumPosition( LRSSet *set ) { char line[MAXTXTLEN] ; fchar fbuf ; fint nitems ; int done; double pos[ 2 ] ; anyout_c( ANYOUT_TST , tofchar(" - GetSpectrumPosition") ) ; finit( fbuf , MAXTXTLEN ) ; /* Initialise fchars */ pos[ 0 ] = set->lonlat[ 0 ] ; pos[ 1 ] = set->lonlat[ 1 ] ; do { sprintf( line , "Give Q(uit) or position (%.*s %6.1f) [%6.2f,%6.2f]" , nelc_c( tofchar( set->coname ) ) , set->coname , set->epoch , pos[ 0 ] , pos[ 1 ] ) ; nitems = usertext_c( fbuf, DFLT_DEF, POS_KEY, tofchar( line ) ) ; done = ( fbuf.a[0] == 'Q' || fbuf.a[0] == 'q' ) ; /* did user type Quit? */ if ( !done ) { nitems = 2 ; /* get 2 numbers */ nitems = userangle_c( pos , &nitems , DFLT_DEF , POS_KEY , tofchar( line ) ) ; if ( nitems == 0 ) nitems = 2 ; /* CR -> old position */ if ( nitems != 2 ) { /* NOT two numbers */ error_c( WARNING , /* give a warning */ tofchar("You must give TWO numbers or for a position")); } else if ( ( pos[0] < set->center[0] - set->size[0] ) || ( pos[0] > set->center[0] + set->size[0] ) || ( pos[1] < set->center[1] - set->size[1] ) || ( pos[1] > set->center[1] + set->size[1] ) ) { sprintf( line , "(LON,LAT)=(%7.3f, %7.3f ) outside set, try again!", pos[0] , pos[1] ); error_c( WARNING , tofchar( line ) ); nitems = 0 ; } else { /* good input */ set->lonlat[ 0 ] = pos[ 0 ] ; set->lonlat[ 1 ] = pos[ 1 ] ; sprintf( line , "Desired position (LON,LAT)= (%7.3f, %7.3f )", set->lonlat[0] , set->lonlat[1] ); anyout_c( ANYOUT_TST , tofchar( line ) ); } } cancel_c( POS_KEY ); /* cancel the keyword */ } while( !done && nitems!=2 ); return( done ); } /* GetSpectrumPosition */ /* ReadSpectrum will read the raw LRS data from the input IRDS into the LRSData struct raw. These data can then be processed by CalibrateSpectrum. */ LRSData *ReadSpectrum( LRSSet *set , Spectrum *spectrum ) { char line[MAXTXTLEN] ; fint sdet , nitems , zero = 0 , one = 1 ; fint error = 0 , status , sunref ; fint sample , samplestart = 0 , readstart , nsamples ; float islim , databuffer[ SPECSAMP ]; double inscan[ NRSAMP ] , xscan[ NRSAMP ] , twist[ NRSAMP ] ; double lon , lat ; LRSData *raw = NULL ; anyout_c( ANYOUT_TST , tofchar(" - ReadSpectrum") ) ; if ( spectrum->process && !spectrum->done ){ /* do this one ? */ sprintf(line,"Spectrum of snip %d (sop,att = %d,%d) from set %s" , spectrum->snip, spectrum->sop, spectrum->att, set->name ); anyout_c( ANYOUT_TST , tofchar( line ) ); sprintf(line,"Reading snip %d from set %s", spectrum->snip, set->name ); status_c( tofchar( line ) ); raw = InitialiseLRSData( spectrum->snip ) ; sunref = 5 ; lon = set->lonlat[ 0 ] * RADPERDEG ; lat = set->lonlat[ 1 ] * RADPERDEG ; sdet = 0 ; nsamples = spectrum->snipdur * SAMPPERSAT ; sample = irds_rd_detoff_c( tofchar( set->name ) , &spectrum->snip , &sdet , &one , &set->cosys , &lon , &lat , &sunref , &zero , inscan , xscan , twist , &nsamples , &status ) ; raw->satcal = (float) spectrum->satcal + fabs( sample ) / SAMPPERSAT ; if ( status == 0 ) { islim = ISCANLIM ; nitems = userreal_c( &islim , &one , DFLT_HIDD , ISLIM_KEY , ISLIM_MES ) ; islim = islim / 3600 * RADPERDEG ; samplestart = ( sample > 0 ) ? sample : -sample ; while( ( samplestart > 0 ) && ( fabs( inscan[ samplestart ] ) < fabs( islim ) ) ) { samplestart = samplestart - 1 ; } } raw->snip = spectrum->snip ; readstart = samplestart / SAMPPERSAT ; samplestart = readstart * SAMPPERSAT ; if ( ( spectrum->snipdur - ( readstart + 1 ) ) > SPECLENGTH ) { raw->det[ 1 ].ns = SPECSAMP ; } else { raw->det[ 1 ].ns = ( spectrum->snipdur - ( readstart + 1 ) ) * SAMPPERSAT ; } readstart = readstart + 1 ; for ( sdet = 1 ; ( sdet < NRDETS + 1 ) ; sdet++ ) { raw->det[ sdet ].ns = raw->det[ 1 ].ns ; sample = irds_rd_detoff_c( tofchar( set->name ) , &spectrum->snip , &sdet , &one , &set->cosys , &lon , &lat , &sunref , &zero , inscan , xscan , twist , &nsamples , &status ) ; raw->det[ sdet ].onsource = ( sample > 0 ) ; if ( raw->det[ sdet ].onsource ) { sprintf( line , "Source in sdet %d, extract %d ticks from tick %d onwards" , sdet , raw->det[ sdet ].ns / SAMPPERSAT , readstart ) ; } else { sprintf( line , "Source not in sdet %d, extract %d ticks from tick %d onwards" , sdet , raw->det[ sdet ].ns / SAMPPERSAT , readstart ) ; } anyout_c( ANYOUT_TST , tofchar( line ) ); irds_rd_samples_c( tofchar( set->name ) , &raw->snip , &sdet , &readstart , databuffer , &raw->det[ sdet ].ns , &error ) ; for ( sample = 0 ; sample < raw->det[ sdet ].ns ; sample++ ) { if ( databuffer[ sample ] == 0.0 ) setfblank_c( &databuffer[ sample ] ) ; } irlrs_adroop_c( &raw->det[ sdet ].detno , databuffer , &raw->det[ sdet ].ns ) ; if ( inscan[ 1 ] > inscan[ 0 ] ) { anyout_c( ANYOUT_TST , tofchar( "Will invert data-order to get increasing lambda" ) ) ; for ( sample = 0 ; sample < raw->det[ sdet ].ns ; sample++ ) { raw->det[ sdet ].is[ sample ] = inscan[ raw->det[ sdet ].ns - 1 - sample + samplestart ] / RADPERDEG ; raw->det[ sdet ].xs[ sample ] = xscan[ raw->det[ sdet ].ns - 1 - sample + samplestart ] / RADPERDEG ; raw->det[ sdet ].fl[ sample ] = databuffer[ raw->det[ sdet ].ns - 1 - sample ] ; } } else { anyout_c( ANYOUT_TST , tofchar( "Will NOT invert data-order to get increasing lambda" ) ) ; for ( sample = 0 ; sample < raw->det[ sdet ].ns ; sample++ ) { raw->det[ sdet ].is[ sample ] = inscan[ sample + samplestart - 1 ] / RADPERDEG ; raw->det[ sdet ].xs[ sample ] = xscan[ sample + samplestart - 1 ] / RADPERDEG ; raw->det[ sdet ].fl[ sample ] = databuffer[ sample ] ; } } } } return( raw ) ; } /* ReadSpectrum */ /* CalibrateSpectrum does the actual calibration of individual spectra. */ void CalibrateSpectrum( Spectrum *spectrum , LRSData *raw ) { char line[MAXTXTLEN] ; bool cohen = true ; fint one = 1 ; fint n = 0 , sdet ; float factor = 0.0 ; float max_gain = 2 ; float blank ; anyout_c( ANYOUT_TST , tofchar(" - CalibrateSpectrum") ) ; n = userlog_c( &cohen , &one , DFLT_HIDD , COHEN_KEY , COHEN_MES ) ; n = userreal_c( &max_gain , &one , DFLT_HIDD , MXGAIN_KEY , MXGAIN_MES ) ; setfblank_c( &blank ) ; if ( spectrum->process && !spectrum->done ){ /* do this one ? */ sprintf( line , "Calibrating spectrum number %d" , spectrum->snip ); status_c( tofchar( line ) ); for ( sdet = 1 ; sdet < NRDETS + 1 ; sdet ++ ) { BaseSub( raw->det[ sdet ].is , raw->det[ sdet ].fl , &raw->det[ sdet ].ns , &spectrum->snip ) ; (void) irlrs_pos2wave_c( &raw->det[ sdet ].detno , raw->det[ sdet ].is , &raw->det[ sdet ].ns , raw->det[ sdet ].lm ) ; factor = irlrs_pwm2permv_c( &raw->det[ sdet ].detno ) ; for( n = 0 ; n < raw->det[ sdet ].ns ; n++ ) { if ( ( raw->det[ sdet ].lm[ n ] != 0 ) && ( raw->det[ sdet ].fl[ n ] != blank ) ) { raw->det[ sdet ].fl[ n ] = raw->det[ sdet ].fl[ n ] * raw->det[ sdet ].lm[ n ] * factor ; } else { setfblank_c( &raw->det[ sdet ].fl[ n ] ) ; } } (void) irlrs_lgain_c( &raw->det[ sdet ].detno , raw->det[ sdet ].lm , &raw->det[ sdet ].ns , raw->det[ sdet ].fl ) ; (void) irlrs_xgain_c( &raw->det[ sdet ].detno , &max_gain , raw->det[ sdet ].xs , &raw->det[ sdet ].ns , raw->det[ sdet ].fl ) ; if( cohen ) { (void) irlrs_cohen_gain_c( raw->det[ sdet ].lm , &raw->det[ sdet ].ns , raw->det[ sdet ].fl ) ; } if ( raw->units[0] == 'J' || raw->units[0] == 'j' ) { irlrs_jyperpwm2_c( raw->det[ sdet ].lm , raw->det[ sdet ].fl , &raw->det[ sdet ].ns , raw->det[ sdet ].fl ) ; } else if ( raw->units[7] == '-' ) { /* F(lambda) wanted */ for ( n = 0 ; n < raw->det[ sdet ].ns ; n++ ) { if( raw->det[ sdet ].fl[ n ] != blank ) raw->det[ sdet ].fl[ n ] = raw->det[ sdet ].fl[ n ] / raw->det[ sdet ].lm[ n ] ; } } else if ( raw->units[7] == '3' ) { /* lambda^4F(lambda) wanted */ for ( n = 0 ; n < raw->det[ sdet ].ns ; n++ ) { if( raw->det[ sdet ].fl[ n ] != blank ) raw->det[ sdet ].fl[ n ] = raw->det[ sdet ].fl[ n ] * raw->det[ sdet ].lm[ n ] * raw->det[ sdet ].lm[ n ] * raw->det[ sdet ].lm[ n ] ; } } } spectrum->done = true ; /* this one's done */ } } /* CalibrateSpectrum */ /* SampleSpectrum will resample the spectra to a regular wavelength grid. */ void SampleSpectrum( LRSData *raw ) { char line[ MAXTXTLEN ] ; fint sdet , nwaves , n , error , nblank , count ; fint imin = 0 , imax = 0 ; float flux[ NWAVE ] , blank ; anyout_c( ANYOUT_TST , tofchar(" - SampleSpectrum") ) ; setfblank_c( &blank ) ; for ( sdet = 1 ; sdet < NRDETS + 1 ; sdet++ ) { count = 0 ; nblank = 0 ; imin = 0 ; imax = 0 ; minmax4_c( raw->det[ sdet ].fl , &raw->det[ sdet ].ns , &raw->det[ sdet ].min , &raw->det[ sdet ].max , &imin , &imax , &nblank , &count ) ; sprintf( line , "Detector %2d , gave %d points, %4d blanks of %4d points" , raw->det[ sdet ].detno , raw->det[ sdet ].ns , nblank , count ) ; anyout_c( ANYOUT_TST , tofchar( line ) ) ; sprintf( line , "Found min/max (%f,%f) at %3d/%3d" , raw->det[ sdet ].min , raw->det[ sdet ].max , imin , imax ) ; anyout_c( ANYOUT_TST , tofchar( line ) ) ; nwaves = NWAVE ; for( n = 0 ; ( n < nwaves ) && ( raw->det[ sdet ].lm[ 0 ] > raw->wave[ n ] ) ; n++ ) setfblank_c( &flux[ n ] ) ; nwaves = nwaves - n ; error = spline1_c( raw->det[ sdet ].lm , raw->det[ sdet ].fl , &raw->det[ sdet ].ns , &raw->wave[ n ] , &flux[ n ] , &nwaves ) ; sprintf( line , "SPLINE1 got %4d points, call returned %d" , raw->det[ sdet ].ns , error ) ; anyout_c( ANYOUT_TST , tofchar( line ) ) ; if ( ( error < 0 ) && ( error != -3 ) ) { sprintf( line , "Error %2d in SPLINE1" , error ) ; error_c( WARNING , tofchar( line ) ) ; } for ( n = 0 ; ( n < NWAVE ) && ( n < SPECSAMP ) && ( raw->wave[ n ] < raw->det[ sdet ].lm[ raw->det[ sdet ].ns - 1 ] ) ; n++ ) { raw->det[ sdet ].lm[ n ] = raw->wave[ n ] ; raw->det[ sdet ].fl[ n ] = flux[ n ] ; } raw->det[ sdet ].ns = n - 1 ; count = 0 ; nblank = 0 ; imin = 0 ; imax = 0 ; minmax4_c( raw->det[ sdet ].fl , &raw->det[ sdet ].ns , &raw->det[ sdet ].min , &raw->det[ sdet ].max , &imin , &imax , &nblank , &count ) ; sprintf( line , "Detector %2d , gave %d points, %4d blanks of %4d points" , raw->det[ sdet ].detno , raw->det[ sdet ].ns , nblank , count ) ; anyout_c( ANYOUT_TST , tofchar( line ) ) ; sprintf( line , "Found min/max (%f,%f) at %3d/%3d" , raw->det[ sdet ].min , raw->det[ sdet ].max , imin , imax ) ; anyout_c( ANYOUT_TST , tofchar( line ) ) ; } } /* SampleSpectrum */ /* AlignSpectrum aligns the two halves of the spectrum */ void AlignSpectrum( LRSData *raw ) { bool align = true ; char line[ MAXTXTLEN ] ; fint one = 1 ; fint sdet , n ; fint swcount = 0 , lwcount = 0 ; fint swdet = 0 , lwdet = 0 ; float blank ; float swsum = 0 , lwsum = 0 ; float swgain , lwgain ; anyout_c( ANYOUT_TST , tofchar(" - AlignSpectrum") ) ; n = userlog_c( &align , &one , DFLT_HIDD , ALIGN_KEY , ALIGN_MES ) ; if ( !align ) return ; setfblank_c( &blank ) ; for ( sdet = 1 ; sdet < NRDETS + 1 ; sdet++ ) { if ( raw->det[ sdet ].onsource ) { if ( irlrs_dettype_c( &raw->det[ sdet ].detno ) == 1 ) { swcount = 0 ; swsum = 0.0 ; swdet = sdet ; for ( n = 0 ; n < raw->det[ swdet ].ns ; n++ ) { if ( ( raw->det[ swdet ].fl[ n ] != blank ) && ( raw->det[ swdet ].lm[ n ] > LWLOEDGE ) && ( raw->det[ swdet ].lm[ n ] < SWHIEDGE ) ) { swsum = swsum + raw->det[ swdet ].fl[ n ] ; swcount += 1 ; } } } else { lwcount = 0 ; lwsum = 0.0 ; lwdet = sdet ; for ( n = 0 ; n < raw->det[ lwdet ].ns ; n++ ) { if ( ( raw->det[ lwdet ].fl[ n ] != blank ) && ( raw->det[ lwdet ].lm[ n ] > LWLOEDGE ) && ( raw->det[ lwdet ].lm[ n ] < SWHIEDGE ) ) { lwsum = lwsum + raw->det[ lwdet ].fl[ n ] ; lwcount += 1 ; } } } } } if ( ( swcount > 0 ) && ( lwcount > 0 ) && ( swsum > 0 ) && ( lwsum > 0 ) ) { swgain = 0.5 * ( 1 + lwsum/lwcount / ( swsum/swcount ) ) ; lwgain = 0.5 * ( 1 + swsum/swcount / ( lwsum/lwcount ) ) ; for ( n = 0 ; n < raw->det[ swdet ].ns ; n++ ) { if ( raw->det[ swdet ].fl[ n ] != blank ) raw->det[ swdet ].fl[ n ] = swgain * raw->det[ swdet ].fl[ n ] ; } raw->det[ swdet ].max = swgain * raw->det[ swdet ].max ; raw->det[ swdet ].min = swgain * raw->det[ swdet ].min ; for ( n = 0 ; n < raw->det[ lwdet ].ns ; n++ ) { if ( raw->det[ lwdet ].fl[ n ] != blank ) raw->det[ lwdet ].fl[ n ] = lwgain * raw->det[ lwdet ].fl[ n ] ; } raw->det[ lwdet ].max = lwgain * raw->det[ lwdet ].max ; raw->det[ lwdet ].min = lwgain * raw->det[ lwdet ].min ; } else { sprintf( line , "Snip %d cannot be aligned, data not corrected" , raw->snip ) ; error_c( WARNING , tofchar( line ) ) ; } } /* SumSpectrum will add the short and long wavelengh parts of the spectrum. */ void SumSpectrum( LRSData *raw , LRSData *average ) { fint sdet , n , flcount[ NWAVE ]; fint count , nblank , imin = 0 , imax = 0 ; float blank ; anyout_c( ANYOUT_TST , tofchar(" - SumSpectrum") ) ; for ( n = 0 ; n < NWAVE ; n++ ) { raw->det[ 0 ].fl[ n ] = 0.0 ; raw->det[ 0 ].lm[ n ] = raw->wave[ n ] ; flcount[ n ] = 0 ; } raw->det[ 0 ].ns = NWAVE ; setfblank_c( &blank ) ; for ( sdet = 1 ; sdet < NRDETS + 1 ; sdet++ ) { if ( raw->det[ sdet ].onsource ) { if ( irlrs_dettype_c( &raw->det[ sdet ].detno ) == 1 ) { for ( n = 0 ; n < raw->det[ sdet ].ns ; n++ ) { if ( ( raw->det[ sdet ].fl[ n ] != blank ) && ( raw->det[ sdet ].lm[ n ] < SWHIEDGE ) ) { raw->det[ 0 ].fl[ n ] = raw->det[ 0 ].fl[ n ] + raw->det[ sdet ].fl[ n ] ; flcount[ n ] += 1 ; } } } else { for ( n = 0 ; n < raw->det[ sdet ].ns ; n++ ) { if ( ( raw->det[ sdet ].fl[ n ] != blank ) && ( raw->det[ sdet ].lm[ n ] >= SWHIEDGE ) ) { raw->det[ 0 ].fl[ n ] = raw->det[ 0 ].fl[ n ] + raw->det[ sdet ].fl[ n ] ; flcount[ n ] += 1 ; } } } } } sprintf( average->units , "%s" , raw->units ) ; raw->det[ 0 ].onsource = true ; for ( n = 0 ; n < NWAVE ; n++ ) { if ( flcount[ n ] == 0 ) { setfblank_c( &raw->det[ 0 ].fl[ n ] ) ; } else { raw->det[ 0 ].fl[ n ] = raw->det[ 0 ].fl[ n ] / flcount[ n ] ; } } for ( sdet = 0 ; sdet < NRDETS + 1 ; sdet++ ) { if ( raw->det[ sdet ].onsource ) { average->det[ sdet ].onsource = true ; for ( n = 0 ; n < NWAVE ; n++ ) { if ( raw->det[ sdet ].fl[ n ] != blank ) { average->det[ sdet ].fl[ n ] = ( average->det[ sdet ].fl[ n ] * average->det[ sdet].nspec + raw->det[ sdet ].fl[ n ] ) / ( average->det[ sdet ].nspec + 1 ) ; } } average->det[ sdet ].nspec = average->det[ sdet ].nspec + 1 ; average->det[ sdet ].ns = NWAVE ; count = 0 ; nblank = 0 ; minmax4_c( average->det[ sdet ].fl , &average->det[ sdet ].ns , &average->det[ sdet ].min , &average->det[ sdet ].max , &imin , &imax , &nblank , &count ) ; } } } /* SumSpectrum */ /* ReportSpectrum reports on the calibrated spectrum */ void ReportSpectrum( Spectrum *spectrum , LRSData *raw ) { char line[ MAXTXTLEN ] ; fint n ; fint sdet , lodet = 0 , hidet = 0 ; fint imin = 0 , imax = 0 , nblank = 0 , count = 0 ; float rms = 0 , sum , sumsq , blank ; float ratio12mu = 0.0 , ratio25mu = 0.0 ; anyout_c( ANYOUT_TST , tofchar(" - ReportSpectrum") ) ; setfblank_c( &blank ) ; for ( sdet = 1 ; sdet <= NRDETS ; sdet++ ) { if ( raw->det[ sdet ].onsource ) { if ( sdet < 4 ) { hidet = sdet ; } else { lodet = sdet ; } } } minmax4_c( raw->det[ 0 ].fl , &raw->det[ 0 ].ns , &raw->det[ 0 ].min , &raw->det[ 0 ].max , &imin , &imax , &nblank , &count ) ; rms = 0.0 ; sum = 0.0 ; sumsq = 0.0 ; count = 0 ; for ( n = 0 ; n < raw->det[ 0 ].ns ; n++ ) { if ( ( ( raw->det[ 0 ].lm[ n ] < SWLOEDGE ) || ( raw->det[ 0 ].lm[ n ] > LWHIEDGE ) ) && ( raw->det[ 0 ].fl[ n ] != blank ) ) { sum = sum + raw->det[ 0 ].fl[ n ] ; sumsq = sumsq + raw->det[ 0 ].fl[ n ] * raw->det[ 0 ].fl[ n ] ; count += 1 ; } } if ( count > 0 ) rms = sqrt( ( sumsq - sum * sum / count ) / count ) ; if ( !first_spectrum_printed ) { sprintf( line , " snip | sop/att | LW/SW | spectrum maximum | r.m.s. noise | 12 mu | 25 mu |" ) ; anyout_c( ANYOUT_DEF , tofchar( line ) ); sprintf( line , "------|---------|-------|----------------------------|----------------|-------|-------|" ) ; anyout_c( ANYOUT_DEF , tofchar( line ) ); first_spectrum_printed = true ; } sprintf( line , " %4d | %3d/%-3d | %2d/%2d | %9.2g %5.5s at %4.1f mu | %8.1g %5.5s | %5.2f | %5.2f |" , spectrum->snip , spectrum->sop , spectrum->att , raw->det[ lodet ].detno , raw->det[ hidet ].detno , (double) raw->det[ 0 ].max , raw->units , (double) raw->det[ 0 ].lm[ imax ] , (double) rms , raw->units , (double) ratio12mu , (double) ratio25mu ) ; anyout_c( ANYOUT_DEF , tofchar( line ) ) ; if ( LastSpectrum( spectrum ) ) { /* last spectrum ? */ sprintf( line , "------|---------|-------|----------------------------|----------------|-------|-------|" ) ; anyout_c( ANYOUT_DEF , tofchar( line ) ); first_spectrum_printed = false ; } return ; } /* PlotLine is a help function to plot a series of points while skipping blanks. */ void PlotLine( fint *npts, float *x , float *y ) { fint m , n ; float blank ; float *xi , *yi ; setfblank_c( &blank ) ; xi = (float *) malloc( ( *npts ) * sizeof( float ) ) ; yi = (float *) malloc( ( *npts ) * sizeof( float ) ) ; if ( !xi || !yi ) error_c( FATAL_ERROR , tofchar( "Cannot get memory for plot arrays" ) ) ; m = 0 ; for( n = 0 ; n < *npts ; n++ ) { if( y[ n ] != blank ){ xi[ m ] = x[ n ] ; yi[ m ] = y[ n ] ; m += 1 ; } } if( m > 1 ) pgline_c( &m , xi , yi ) ; free( xi ) ; free( yi ) ; return ; } /* PlotLine */ /* PlotSpectrum plots the data in LRSData */ void PlotSpectrum( LRSSet *inset , Spectrum *spectrum , LRSData *raw , LRSData *average ) { fint n , zero = 0 , one = 1 , two = 2 , sign = 1 ; fint error = 0 , dd = 0 , mm = 0 , nitems = 0 ; fint thinlines = 1 , thicklines = 5 ; fint full_line = 1 , dotted_line = 4 ; fint first , last , sdet , swtolw ; fchar pgreply ; char label[ MAXTXTLEN ] ; bool thick = false ; float xmin , xmax , xsize ; float ymin , ymax , ysize ; float ds = 0 ; float minmax[ 2 ] , psc[ 2 ] , edgepos[ 2 ] , edgewav[ 2 ] ; float fzero = 0.0 , x ,y , just , charsize , blank ; float wxmin , wxmax , wymin , wymax ; finit( pgreply , MAXTXTLEN ) ; setfblank_c( &blank ) ; if ( raw->snip != 0 ) { sprintf( label , "Plotting snip nr. %d" , spectrum->snip ) ; status_c( tofchar( label ) ) ; } else { status_c( tofchar( "Plotting average spectrum" ) ) ; } xmin = 0 ; xmax = 27.5 ; xsize = xmax - xmin ; ymax = raw->det[ 0 ].max ; ymin = raw->det[ 0 ].min ; ysize = ymax - ymin ; ymin = ymin - 0.15 * ysize ; ymax = ymax + 0.35 * ysize ; n = userreal_c( minmax , &two , DFLT_HIDD , MINMAX_KEY , MINMAX_MES ) ; if ( n == 2 ) { ymin = minmax[ 0 ] ; ymax = minmax[ 1 ] ; } ysize = ymax - ymin ; /* open plot device */ error = pgbeg_c( &zero , tofchar( "?" ) , &one , &one ) ; if ( error != 1 ) { error_c( FATAL_ERROR , tofchar( "pgbeg error ... " ) ) ; } pgqinf_c( tofchar( "TYPE" ) , pgreply , &n ) ; if ( !strncmp( pgreply.a , "TEK4010" , 6 ) ) { thick = true ; nitems = userlog_c( &thick , &one , DFLT_HIDD , THICK_KEY , THICK_MES ) ; if ( nitems !=0 && !thick ) { thicklines = thinlines ; } } charsize = 1.5 ; pgsch_c( &charsize ) ; /* set charactersize */ pgslw_c( &thicklines ) ; /* set linewidth */ wxmin = 0.20 ; /* set viewport/window */ wxmax = 0.95 ; wymin = 0.15 ; wymax = 0.90 ; pgsvp_c( &wxmin , &wxmax , &wymin , &wymax ) ; pgswin_c( &xmin , &xmax , &ymin , &ymax ) ; /* plot frame */ pgbox_c( tofchar( "BCNTS" ) , &fzero , &zero , tofchar( "BCNTSV" ) , &fzero , &zero ) ; /* plot labels */ pglab_c( tofchar( "Wavelength (\\gm)" ), tofchar( "" ), tofchar( "" ) ) ; x = 0.5 ; /* add Y-label */ y = 5.0 ; just = 0.5 ; if ( raw->units[0] == 'J' ) { pgmtxt_c( tofchar( "L" ) , &y , &x , &just , tofchar( "Intensity (Jy)" ) ) ; } else if ( raw->units[7] == '-' ) { pgmtxt_c( tofchar( "L" ) , &y , &x , &just , tofchar( "F\\d\\gl\\u (10 \\u-12\\d Wm\\u-2\\d\\gm\\u-1\\d)" ) ) ; } else if ( raw->units[7] == '3' ) { pgmtxt_c( tofchar( "L" ) , &y , &x , &just , tofchar( "\\gl\\u4\\d F\\d\\gl\\u (10 \\u-12\\d Wm\\u-2\\d\\gm\\u3\\d)" ) ) ; } else { pgmtxt_c( tofchar( "L" ) , &y , &x , &just , tofchar( "\\gl F\\d\\gl\\u (10 \\u-12\\d Wm\\u-2\\d)" ) ) ; } /* annotate the plot */ x = 0.0 ; /* program ID */ y = 0.5 ; just = 0.0 ; sprintf( label , "LRSCAL v. %s" , VERSION ) ; pgmtxt_c( tofchar( "T" ) , &y , &x , &just , tofchar( label ) ) ; charsize = 1.2 ; pgsch_c( &charsize ) ; /* set charactersize */ x = 1.0 ; /* set specification */ y = 0.5 ; just = 1.0 ; if ( raw->snip == 0 ) { sprintf( label , "set %s, average" , inset->name ) ; } else { sprintf( label , "set %s, snip nr.%d" , inset->name , raw->snip ) ; } pgmtxt_c( tofchar( "T" ) , &y , &x , &just , tofchar( label ) ) ; just = 1.0 ; x = xmin + 0.95 * xsize ; /* source name */ y = ymin + 0.82 * ysize ; pgptxt_c( &x , &y , &fzero , &just , tofchar( inset->object ) ) ; if ( !strncmp( inset->coname , "EQU" , 3 ) ) { dd = (int) ( inset->lonlat[0] / 15 ) ; mm = (int) ( (float) 60 * ( ( inset->lonlat[0] / 15 ) - dd ) ) ; ds = ( (float) 3600 * ( ( inset->lonlat[0] / 15 ) - dd ) - 60 * mm ) ; sprintf( label , "\\ga%4d\\uh\\d%2d\\um\\d%4.1f\\us\\d",dd,mm,(double)ds ) ; } else { dd = (int) inset->lonlat[0] ; mm = (int) ( (float) 60 * ( inset->lonlat[0] - dd ) ) ; ds = ( (float) 3600 * ( inset->lonlat[0] - dd ) - 60 * mm ) ; sprintf( label , "\\sl%4d\\ud\\d%2d\\um\\d%4.1f\\us\\d",dd,mm,(double)ds ) ; } x = xmin + 0.95 * xsize ; /* source position */ y = ymin + 0.92 * ysize ; pgptxt_c( &x , &y , &fzero , &just , tofchar( label ) ) ; sign = inset->lonlat[1] / fabs( inset->lonlat[1] ) ; dd = (int) fabs( inset->lonlat[1] ) ; mm = (int) ( (float) 60 * ( fabs( inset->lonlat[1] ) - dd ) ) ; ds = ( (float) 3600 * ( fabs( inset->lonlat[1] ) - dd ) - 60 * mm ) ; dd = dd * sign ; if ( !strncmp( inset->coname , "EQU" , 3 ) ) { sprintf( label , "\\gd%4d\\ud\\d%2d\\um\\d%4.1f\\us\\d",dd,mm,(double)ds ) ; } else { sprintf( label , "\\sb%4d\\ud\\d%2d\\um\\d%4.1f\\us\\d",dd,mm,(double)ds ) ; } y = ymin + 0.87 * ysize ; pgptxt_c( &x , &y , &fzero , &just , tofchar( label ) ) ; if ( raw != average ) { x = xmin + 0.05 * xsize ; y = ymin + 0.92 * ysize ; sprintf( label , "sop/att %d/%d" , spectrum->sop , spectrum->att ) ; pgtext_c( &x , &y , tofchar( label ) ) ; } n = userreal_c( psc , &two , DFLT_HIDD , PSC_KEY , PSC_MES ) ; if ( n > 0 ) { if ( ( raw->units[0] != 'J' ) && ( raw->units[0] != 'j' ) ) { psc[ 0 ] = psc[ 0 ] * 2.998 / 11.8 ; if ( raw->units[7] == '-' ) { psc[ 0 ] = psc[ 0 ] / 11.8 ; } else if ( raw->units[7] == '3' ) { psc[ 0 ] = psc[ 0 ] * 11.8 * 11.8 * 11.8 ; } } charsize = 1.1 ; pgsch_c( &charsize ) ; /* set charactersize */ pgslw_c( &thinlines ) ; pgsls_c( &dotted_line ) ; x = 1.0 ; pgmove_c( &x , &psc[ 0 ] ) ; x = 2.0 ; pgdraw_c( &x , &psc[ 0 ] ) ; pgslw_c( &thicklines ) ; pgtext_c( &x , &psc[ 0 ] , tofchar( "PSC 12\\gm" ) ) ; pgslw_c( &thinlines ) ; x = 8.6 ; pgmove_c( &x , &psc[ 0 ] ) ; x = 15.0 ; pgdraw_c( &x , &psc[ 0 ] ) ; } if ( n == 2 ) { if ( ( raw->units[0] != 'J' ) && ( raw->units[0] != 'j' ) ) { psc[ 1 ] = psc[ 1 ] * 2.998 / 25 ; if ( raw->units[7] == '-' ) { psc[ 1 ] = psc[ 1 ] / 25 ; } else if ( raw->units[7] == '3' ) { psc[ 1 ] = psc[ 1 ] * 25 * 25 * 25 ; } } pgslw_c( &thinlines ) ; x = 18.5 ; pgmove_c( &x , &psc[ 1 ] ) ; x = 25.0 ; pgdraw_c( &x , &psc[ 1 ] ) ; x = 24.0 ; pgslw_c( &thicklines ) ; pgtext_c( &x , &psc[ 1 ] , tofchar( "PSC 25\\gm" ) ) ; } pgslw_c( &thinlines ) ; /* add detector edges */ pgsls_c( &full_line ) ; edgepos[ 0 ] = 0.05 ; edgepos[ 1 ] = -0.05 ; n = 71 ; (void) irlrs_pos2wave_c( &n, edgepos , &two, edgewav ) ; y = ymin + 0.05 * ysize ; pgmove_c( &edgewav[0] , &y ) ; y = ymin + 0.025 * ysize ; pgdraw_c( &edgewav[0] , &y ) ; pgdraw_c( &edgewav[1] , &y ) ; y = ymin + 0.05 * ysize ; pgdraw_c( &edgewav[1] , &y ) ; n = 74 ; (void) irlrs_pos2wave_c( &n, edgepos , &two, edgewav ) ; y = ymin + 0.10 * ysize ; pgmove_c( &edgewav[0] , &y ) ; y = ymin + 0.075 * ysize ; pgdraw_c( &edgewav[0] , &y ) ; pgdraw_c( &edgewav[1] , &y ) ; y = ymin + 0.10 * ysize ; pgdraw_c( &edgewav[1] , &y ) ; if ( ymin < 0 && ymax > 0 ) { /* add baseline */ pgslw_c( &thinlines ) ; pgsls_c( &full_line ) ; x = xmin ; y = 0.0 ; pgmove_c( &x , &y ) ; x = xmax ; pgdraw_c( &x , &y ) ; } if ( raw != average ) { for( sdet = 1 ; sdet < NRDETS + 1 ; sdet++ ) { pgslw_c( &thicklines ) ; /* add detector numbers */ if ( raw->det[ sdet ].onsource ) { if ( irlrs_dettype_c( &raw->det[ sdet ].detno ) == 1 ) { pgsls_c( &full_line ) ; x = xmin + 0.05 * xsize ; y = ymin + 0.87 * ysize ; pgmove_c( &x , &y ) ; x = xmin + 0.09 * xsize ; pgdraw_c( &x , &y ) ; x = xmin + 0.10 * xsize ; sprintf( label , "SW det. %2d" , raw->det[ sdet ].detno ) ; pgtext_c( &x , &y , tofchar( label ) ) ; n = 71 ; (void) irlrs_pos2wave_c( &n, edgepos , &two, edgewav ) ; } else if ( irlrs_dettype_c( &raw->det[ sdet ].detno ) == 2 ) { pgsls_c( &dotted_line ) ; x = xmin + 0.05 * xsize ; y = ymin + 0.82 * ysize ; pgmove_c( &x , &y ) ; x = xmin + 0.09 * xsize ; pgdraw_c( &x , &y ) ; x = xmin + 0.10 * xsize ; sprintf( label , "LW det. %2d" , raw->det[ sdet ].detno ) ; pgtext_c( &x , &y , tofchar( label ) ) ; n = 74 ; (void) irlrs_pos2wave_c( &n, edgepos , &two, edgewav ) ; } /* find end of data */ first = -1 ; last = raw->det[ sdet ].ns ; for ( n = 0 ; n < raw->det[ sdet ].ns ; n++ ) { if ( first < 0 ) { if ( raw->det[ sdet ].lm[ n ] > edgewav[ 0 ] ) { first = n ; } } else { if ( raw->det[ sdet ].lm[ n ] > edgewav[ 1 ] ) { last = n ; break ; } } } sprintf( label , "Detector %2d, plot %3d to %3d, in detector %d to %d" , raw->det[ sdet ].detno, 0 , raw->det[ sdet ].ns , first , last ) ; anyout_c( ANYOUT_TST , tofchar( label ) ) ; pgslw_c( &thinlines ) ; n = first + 1 ; PlotLine( &n , &raw->det[ sdet ].lm[ 0 ] , &raw->det[ sdet ].fl[ 0 ] ) ; n = last - first + 1 ; pgslw_c( &thicklines ) ; PlotLine( &n , &raw->det[ sdet ].lm[ first ] , &raw->det[ sdet ].fl[ first ] ) ; n = raw->det[ sdet ].ns - last - 1 ; pgslw_c( &thinlines ) ; PlotLine( &n , &raw->det[ sdet ].lm[ last ] , &raw->det[ sdet ].fl[ last ] ) ; } } } if ( average ) { first = -1 ; last = -1 ; for ( n = 0 ; n < NWAVE ; n++ ) { if ( first == -1 ) { if ( average->wave[ n ] > SWLOEDGE ) { first = n ; n = n + ( 10 / STEPWAVE ) ; } } else { last = n - 1 ; if ( average->wave[ n ] > LWHIEDGE ) { break ; } } } swtolw = (int) ( (float) ( SWHIEDGE - BEGINWAVE ) / STEPWAVE ) + 1 ; if ( ( first != -1 ) && ( last != -1 ) ) { pgsls_c( &full_line ) ; pgslw_c( &thinlines ) ; n = first + 1 ; PlotLine( &n , &average->wave[ 0 ] , &average->det[ 0 ].fl[ 0 ] ) ; pgslw_c( &thicklines ) ; n = swtolw - first + 1 ; PlotLine( &n , &average->wave[ first ] , &average->det[ 0 ].fl[ first ] ) ; n = last - swtolw ; PlotLine( &n , &average->wave[ swtolw + 1 ] , &average->det[ 0 ].fl[ swtolw + 1 ] ) ; n = NWAVE - last ; pgslw_c( &thinlines ) ; PlotLine( &n , &average->wave[ last ] , &average->det[ 0 ].fl[ last ] ) ; } } pgiden_c( ) ; /* add identification */ pgend_c( ) ; /* close plot */ } /* WriteSpectrum will write a table of calibrated LRS data (calib) to the IRDS outset on disk. */ void WriteSpectrum( LRSSet *outset , Spectrum *spectrum , LRSData *raw , LRSData *average ) { fint status , sdet = 0 , ndata = 0 ; char line[MAXTXTLEN] ; anyout_c( ANYOUT_TST , tofchar(" - WriteSpectrum") ) ; if ( outset /* do this one ? */ && spectrum->done && spectrum->process ){ sprintf( line , "Writing spectrum of snip %d to set %s" , raw->snip , outset->name ); status_c( tofchar( line ) ); irlrs_set_addsnip_c( tofchar( outset->name ) , &raw->snip , &spectrum->sop , &spectrum->att , &raw->satcal , &status ) ; if ( status != 0 ) { sprintf( line , "IRLRS_SET_ADDSNIP error number %d" , status ) ; error_c( WARNING , tofchar( line ) ) ; } else { for ( sdet = 0 ; sdet < NRDETS + 1 ; sdet++ ) { sprintf( line , "Writing spectrum of snip %d to set %s (detector %2d)" , raw->snip , outset->name , raw->det[ sdet ].detno ); status_c( tofchar( line ) ); ndata = NWAVE ; irlrs_set_wrsnip_c( tofchar( outset->name ) , &raw->snip , &sdet , raw->det[ sdet ].fl , &ndata , &status ) ; irlrs_set_wrsnip_c( tofchar( outset->name ) , &average->snip , &sdet , average->det[ sdet ].fl , &ndata , &status ) ; if ( status != 0 ) { sprintf( line , "IRLRS_SET_WRSNIP error number %d" , status ) ; error_c( WARNING , tofchar( line ) ) ; } } } } } /* WriteSpectrum */ MAIN_PROGRAM_ENTRY { char line[MAXTXTLEN] ; fchar units ; fint toplevel = 0, status = 0, nitems ; int done; LRSSet *inset = NULL ; LRSSet *outset = NULL ; Spectrum *spectrumlist = NULL ; Spectrum *spectrum = NULL ; LRSData *raw = NULL ; LRSData *average = NULL ; LRSData *nullptr = NULL ; double oldlonlat[ 2 ] = { 0 , 0 } ; init_c( ); /* get in touch with HERMES */ IDENTIFICATION( PROGRAM , VERSION ) ; /* show user who we are */ finit( units , MAXTXTLEN ) ; inset = GetLRSSet( ); /* ask for an input IRDS */ /* start processing data; outer loop processes different on-sky positions */ done = ( inset == NULL ) ; /* stop ? */ if( !done ) { if ( outset != NULL ) free( outset ); outset = MakeLRSOutset( inset ) ; /* ask for output set */ sprintf( units.a , "LFL" ) ; nitems = usertext_c( units , DFLT_DEF , UNITS_KEY , UNITS_MES ) ; if ( units.a[0] == 'W' || units.a[0] == 'w' ) { sprintf( units.a , "pWm-2mu-1" ) ; } else if ( ( units.a[0] == 'L' || units.a[0] == 'l' ) && units.a[1] == '4' ) { sprintf( units.a , "pWm-2mu3 " ) ; } else if ( units.a[0] == 'J' || units.a[0] == 'j' ) { sprintf( units.a , "Jy " ) ; } else { sprintf( units.a , "pWm-2 " ) ; } if( outset ){ status = 0 ; gdsd_wchar_c( tofchar(outset->name), tofchar("BUNIT"), &toplevel, units, &status ) ; gdsd_wchar_c( tofchar(outset->name), tofchar("CUNIT1"), &toplevel, tofchar("mu"), &status ) ; } } while( !done ) { done = GetSpectrumPosition( inset ); /* ask for a position */ if( !done ) { /* generate a list of spectra */ spectrumlist = GetSpectrumList( inset , oldlonlat , spectrumlist ); } if( !done ) { sprintf( line , "Working on set %s at (%f,%f)", inset->name , inset->lonlat[0], inset->lonlat[1] ); anyout_c( ANYOUT_DEF , tofchar( line ) ); spectrum = NextSpectrum( spectrumlist ) ;/* start with the first */ if ( average ) free( average ) ; average = InitialiseLRSData( 0 ) ; /* initialise average */ while( spectrum ) { /* loop on spectra */ if ( raw ) free( raw ) ; /* read data */ raw = ReadSpectrum( inset , spectrum ) ; sprintf( raw->units, "%s " , units.a ) ; /* calibrate this spectrum */ CalibrateSpectrum( spectrum , raw ) ; /* put to regular grid */ SampleSpectrum( raw ) ; /* align spectral halves */ AlignSpectrum( raw ) ; /* add detectors together */ SumSpectrum( raw , average ) ; /* report to the user */ ReportSpectrum( spectrum , raw ) ; /* plot this spectrum */ PlotSpectrum( inset , spectrum , raw , nullptr ) ; /* write the table to disk */ WriteSpectrum( outset , spectrum , raw , average ) ; if ( LastSpectrum( spectrum ) ) { /* last spectrum ? */ /* yes -> plot average */ PlotSpectrum( inset , spectrum , average , average ) ; /* and delete average */ if ( average ) free( average ) ; average = InitialiseLRSData( 0 ) ; } /* goto next spectrum */ spectrum = NextSpectrum( spectrumlist ) ; } } oldlonlat[ 0 ] = inset->lonlat[ 0 ] ; oldlonlat[ 1 ] = inset->lonlat[ 1 ] ; } finis_c( ); /* bye, bye HERMES */ return( 0 ) ; }