C****************************************************************************** C SELECTOR TASK: C wgain C C FILE: C wgain.f C C DESCRIPTION: C Process a SAX-WFC FITS file of events containing In-Flight C Calibration (IFC) sources to calculate a gain table. C C AUTHOR: C Gerrit J. Wiersma C C MODIFICATION HISTORY: C $Log: wgain.f,v $ c Revision 1.10 99/10/13 17:02:24 17:02:24 gerwie (Gerrit J. Wiersma) c corrected T_SCALE keyword to 1.0 c drop producing gain record with ZERO counts c c Revision 1.9 97/09/16 12:30:08 12:30:08 gerwie (Gerrit J. Wiersma) c no longer insert TASK_ID in program version c C Revision 1.8 1997/09/16 12:24:28 gerwie C added extracting IFC regions from raw (rn0) event file C added warning output if no IFC events found C added header keywords ONTIME, CD/FE_MEAN and CD/FE_INSTY C C Revision 1.7 1997/05/28 08:48:17 gerwie C changed comment '#' to 'c' C C Revision 1.6 1997/04/08 13:59:33 gerwie C added test on empty input file C fix bug with calculating (n * step) from start C c Revision 1.5 1996/12/17 09:31:51 gerwie c commentary changes c c Revision 1.4 1996/12/04 13:05:08 gerwie c revised Fe to Cd ADC peak factor c c Revision 1.3 1996/11/28 16:18:37 gerwie c changed kev to pha routine c C C NOTES: C - wgain supported in IRAF and HOST environments C - The last bin will may not contain a full bin-time C - caurrent gain factors for Cd : 2.841 / 2.958 C C ARGUMENTS: C none C C PRIMARY LOCAL VARIABLES: C ifcfile - input event file C gtifile - input GTI FITS C outfile - output gain file C cal1file - calibration file for WFC1 C cal2file - calibration file for WFC2 C imask - array holding selection mask C xmax - maximam x-dimension of imask C ymax - maximam y-dimension of imask C bintime - time of event binning in seconds C blockio - fast block io option C verbsty - verbosity volume level C C CALLED ROUTINES: C subroutine grunpar - gets run parameters from environment C subroutine procifc - process input FITS file with IFC events C C****************************************************************************** SUBROUTINE wgain C CHARACTER*160 ifcfile, gtifile, outfile, cal1file, cal2file INTEGER verbsty LOGICAL blockio DOUBLE PRECISION bintime C INTEGER xmax,ymax PARAMETER (xmax = 1023) ! 767 PARAMETER (ymax = 1023) ! 767 INTEGER*2 imask(0:xmax,0:ymax) C CHARACTER RCS_ID*256 DATA RCS_ID /'$Header: wgain.f,v 1.10 99/10/13 17:02:24 gerwie Exp $'/ CHARACTER TASK_ID*128 DATA TASK_ID /'$State: Exp $'/ C CHARACTER ctime*8,cdate*9,fdate*8 COMMON /wtim/ ctime,cdate,fdate CHARACTER*40 taskname COMMON /task/ taskname INTEGER i1,i2 C ctime = ' ' CALL Wgtime(ctime,cdate,fdate) taskname = 'wgain' i1 = INDEX(RCS_ID,'.f,v ') + 5 i2 = INDEX(RCS_ID(i1:),' ') + i1 - 1 IF(i1.GT.0 .AND. i2.GT.i1) taskname= 'wgain rev_'//RCS_ID(i1:i2) IF(INDEX(TASK_ID,'Exp').LE.0) taskname = TASK_ID C verbsty = 0 bintime = 1D0 blockio = .FALSE. ifcfile = ' ' gtifile = ' ' outfile = ' ' cal1file = ' ' cal2file = ' ' C CALL grunpar(ifcfile,gtifile,cal1file,cal2file,outfile, & imask,xmax,ymax,bintime,blockio,verbsty) C CALL procifc(ifcfile,gtifile,cal1file,cal2file,outfile, & imask,xmax,ymax,bintime,blockio,verbsty) C RETURN END C****************************************************************************** C SUBROUTINE: C grunpar C C DESCRIPTION: C Get parameters from parameter file C C AUTHOR: C Janice Tarrant 3/24/92 C Gerrit Wiersma 96-iv-4 C C MODIFICATION HISTORY: C C NOTES: C uses F77/VOS like CALLs to read parameter from .par file C C USAGE: C CALL grunpar(ifcfile,gtifile,cal1file,cal2file,gainfile, C & bintime,blockio,verbsty) C C ARGUMENTS: C ifcfile - input events FITS filename C gtifile - input GTI FITS filename C cal1file - calibration filename for WFC1 C cal2file - calibration filename for WFC2 C gainfile - output gain filename C imask - array holding selection mask C xmax - maximam x-dimension of imask C ymax - maximam y-dimension of imask C bintime - time in seconds to bin events C blockio - fast block i/o option C verbsty - verbosity volume level C C PRIMARY LOCAL VARIABLES: C title - comment string C errstr - error message C status - error number C C CALLED ROUTINES: C subroutine fcerr - echo error message to terminal C subroutine uclgst - get string parameter C subroutine uclgsb - get boolean parameter C subroutine uclgsi - get integer parameter C subroutine uclgsr - get real parameter C subroutine uclgsd - get double real parameter C subroutine wparsavt - get string parameter C subroutine wparsavb - get boolean parameter C subroutine wparsavi - get integer parameter C subroutine wparsavr - get real parameter C subroutine wparsavd - get double real parameter C C****************************************************************************** SUBROUTINE grunpar(ifcfile,gtifile,cal1file,cal2file,gainfile, & imask,xmax,ymax,bintime,blockio,verbsty) CHARACTER*(*) ifcfile,gtifile,cal1file,cal2file,gainfile LOGICAL blockio INTEGER verbsty INTEGER xmax, ymax INTEGER*2 imask(0:xmax,0:ymax) DOUBLE PRECISION bintime C CHARACTER errstr*80, title*256 INTEGER status C C initialize variables status = 0 C C= get the name of the IFC event FITS file CALL uclgst('ifcfile',ifcfile,status) IF(status.NE.0) THEN errstr = 'could not get IFCFILE parameter' GOTO 999 ENDIF CALL wparsavt('ifcfile',ifcfile,status) IF(status.NE.0) GOTO 990 C C= get the name of the events GTI FITS file CALL uclgst('gtifile',gtifile,status) IF(status.NE.0) THEN errstr = 'could not get GTIFILE parameter' GOTO 999 ENDIF CALL wparsavt('gtifile',gtifile,status) IF(status.NE.0) GOTO 990 C C= get the name of the output gain file CALL uclgst('gainfile',gainfile,status) IF(status.NE.0) THEN errstr = 'could not get GAINFILE parameter' GOTO 999 ENDIF CALL wparsavt('gainfile',gainfile,status) IF(status.NE.0) GOTO 990 C C= get the name of the WFC1 calibration file CALL uclgst('calfile1',cal1file,status) IF(status.NE.0) THEN errstr = 'could not get CALFILE1 parameter' GOTO 999 ENDIF CALL wparsavt('calfile1',cal1file,status) IF(status.NE.0) GOTO 990 C C= get the name of the WFC2 calibration file CALL uclgst('calfile2',cal2file,status) IF(status.NE.0) THEN errstr = 'could not get CALFILE2 parameter' GOTO 999 ENDIF CALL wparsavt('calfile2',cal2file,status) IF(status.NE.0) GOTO 990 C C= get the bintime parameter CALL uclgsd('bintime',bintime,status) IF(status.NE.0) THEN errstr = 'could not get BINTIME parameter' GOTO 999 ENDIF CALL wparsavd('bintime',bintime,status) IF(status.NE.0) GOTO 990 C C= get block io option CALL uclgsb('blockio',blockio,status) IF(status.NE.0) THEN errstr = 'could not find BLOCKIO factor' GOTO 999 ENDIF CALL wparsavb('blockio',blockio,status) IF(status.NE.0) GOTO 990 C C= get verbosity factor CALL uclgsi('verbsty',verbsty,status) IF(status.NE.0) THEN errstr = 'could not find VERBSTY factor' GOTO 999 ENDIF CALL wparsavi('verbsty',verbsty,status) IF(status.NE.0) GOTO 990 C C= get the TITLE string CALL uclgst('title',title,status) IF(status.NE.0) THEN errstr = 'could not get TITLE parameter' GOTO 999 ENDIF CALL wparsavt('title',title,status) IF(status.NE.0) GOTO 990 C C= normal end RETURN C C= error condition 990 errstr = 'parameter buffer overflow' C 999 CALL fcerr('*****ERROR: '//errstr) STOP C END C****************************************************************************** C SUBROUTINE: C procifc C C DESCRIPTION: C Reads the FITS file and writes the GTI filtered gaib values to C a FITS file C C AUTHOR: C Gerrit J. Wiersma (SRON) 96-iv-2 C C MODIFICATION HISTORY: C C NOTES: C C USAGE: C CALL procifc(ifcfile,gtifile,cal1file,cal2file,outfile, C & imask,xmax,ymax,bintime,blockio,verbsty) C C ARGUMENTS: C ifcfile - input events FITS file C gtifile - input GTI FITS file C cal1file - calibration file for WFC1 C cal2file - calibration file for WFC2 C outfile - output file name C imask - array holding selection mask C xmax - maximam x-dimension of imask C ymax - maximam y-dimension of imask C bintime - time in seconds to bin eventtimes C blockio - fast block io option C verbsty - verbosity volume level C C PRIMARY LOCAL VARIABLES: C maxcl - maximum number of columns C filename - name of FITS file C ftstat - FITSIO error number C errstr - error message C context - general message C tcolnum - column number for time field C xcolnum - column number for x-position field C ycolnum - column number for y-position field C zcolnum - column number for z-position field C negflag - exclude name flag C obstime - observation start time keyword C odate - observation start date C otime - observation start time C toffs - observation time offset C tscale - observation time unit C redfec - reduction factor C regs - array holding coordinates of selection regions C nreg - number of regions used C C C CALLED ROUTINES: C subroutine evtproc C subroutine total_gti C subroutine getcalrec C subroutine getadckev C subroutine getifcregs C subroutine wparfits C subroutine fcecho - echo message to terminal C subroutine fcerrm - report an error number to terminal C subroutine fcgcls - get column list based on parameter C subroutine fcpars - parse off filename and extension number C function fcstln - getlength of string C subroutine ftadef - define ASCII extension C subroutine ftbdef - define binary extension C subroutine ftclos - close a FITS file C subroutine ftcrhd - create a new header C subroutine ftgbnh - get BINARY table header C subroutine ftgcno - get column number associated with name C subroutine ftgkys - get string keyword value C subroutine ftgprh - get primary header keywords from CHU C subroutine ftgtbh - get ASCII table header C subroutine ftinit - create a new FITS file C subroutine ftmahd - absolute move to FITS header C subroutine ftmrhd - relative move to FITS header C subroutine ftopen - open a FITS file C subroutine ftpbnh - put binary table header keywords into CHU C subroutine ftpdef - define structure of primary array C subroutine ftphis - put history keyword record C subroutine ftpprh - put primary header keywords into CHU C subroutine ftptbh - put ASCII table header keywords into CHU C C****************************************************************************** C SUBROUTINE procifc(ifcfile,gtifile,cal1file,cal2file,outfile, & imask,xmax,ymax,bintime,blockio,verbsty) CHARACTER*(*) ifcfile,gtifile,cal1file,cal2file,outfile LOGICAL blockio INTEGER verbsty INTEGER xmax, ymax INTEGER*2 imask(0:xmax,0:ymax) DOUBLE PRECISION bintime C INTEGER maxcl PARAMETER (maxcl = 512) CHARACTER*160 filename CHARACTER*80 context, errstr, tcolnam CHARACTER*70 ttype(maxcl), tform(maxcl), tunit(maxcl), extname, & comment, detcalrev LOGICAL iopen, gopen, oopen, exact, negflag, simple, extend INTEGER ftstat, iunit, gunit, ounit, block, extnum, htype, & gcount, irows, tfields, varidat, & bitpix, naxis, naxes(99), pcount, mkywd INTEGER tcolnum, cunit, camera, next, redfac, ntotal, nrows, gorow DOUBLE PRECISION toffs, tscale, obstime, mjdmin, mjdmax, totalt REAL adcmean(33),feadcnom,cdadcnom,feadclo,feadchi,cdadclo,cdadchi C REAL femean,cdmean,feinty,cdinty,cmean INTEGER caccu,i,enomfe,enomcd INTEGER regs(4,50),nreg,x,y LOGICAL rawevents C INTEGER ncdlo, ncdhi, nfelo, nfehi DOUBLE PRECISION chantot,ontime COMMON /ifcstat/ ncdlo,ncdhi,nfelo,nfehi,chantot(32),ontime C CHARACTER ctime*8,cdate*9,fdate*8 COMMON /wtim/ ctime,cdate,fdate C CHARACTER*40 taskname COMMON /task/ taskname C C initialize variables ftstat = 0 iunit = 15 gunit = 16 ounit = 17 cunit = 18 iopen = .FALSE. gopen = .FALSE. oopen = .FALSE. negflag = .FALSE. exact = .TRUE. tscale = 1D0 mjdmax = 0D0 mjdmin = 999999D0 ntotal = 0 gorow = 0 C nfelo = 8 nfehi = 20 ncdlo = 25 ncdhi = 32 enomfe = 5.98 ! 13.58 chan enomcd = 22.60 ! 29.55 chan DO i = 1,32 chantot(i) = 0 ENDDO ontime = 0D0 C C= get the filename and extension number CALL fcpars(ifcfile,filename,extnum,ftstat) C C= open the event input FITS file and check contents C CALL FTopen(iunit,filename,0,block,ftstat) IF(ftstat.NE.0) THEN errstr = 'unable to open ifcfile' GOTO 990 ENDIF CALL ftgprh(iunit,simple,bitpix,naxis,naxes,pcount, & gcount,extend,ftstat) iopen = .TRUE. C CALL FTgkys(iunit,'CONTENT',context,comment,ftstat) rawevents = .TRUE. IF(context.EQ.'SCI_IFC') rawevents = .FALSE. IF(context.NE.'SCI_NM' .AND. rawevents) THEN errstr = 'illegal input file type' GOTO 990 ENDIF C camera = 0 CALL FTgkys(iunit,'INSTRUME',context,comment,ftstat) IF(context.EQ.'WFC1') camera = 1 IF(context.EQ.'WFC2') camera = 2 IF(camera.LE.0) THEN errstr = 'bad camera specified' GOTO 990 ENDIF C CALL ftmahd(iunit,2,htype,ftstat) IF(ftstat.NE.0) THEN errstr = 'Cannot move to extension header' GOTO 990 ENDIF obstime = -1D0 CALL FTgkyd(iunit,'MJD_OBS',obstime,comment,ftstat) IF(ftstat.NE.0) THEN ftstat = 0 CALL FTgkyd(iunit,'MJD-OBS',obstime,comment,ftstat) ENDIF IF(ftstat.NE.0) THEN errstr = 'No MJD_OBS specified' GOTO 990 ENDIF CALL ftmahd(iunit,1,htype,ftstat) IF(ftstat.NE.0) THEN errstr = 'Cannot move to primary header' GOTO 990 ENDIF C C= read from the calibration FITS file IF(camera.EQ.1) THEN CALL getcalrev(cunit,cal1file,detcalrev,ftstat) IF(ftstat.NE.0) THEN errstr = 'Cannot open detcalfile wfc1' GOTO 990 ENDIF CALL getadckev(cunit,cal1file,obstime,adcmean,feadcnom,cdadcnom, & feadclo,feadchi,cdadclo,cdadchi,ftstat) IF(cdadcnom.LT.feadcnom) cdadcnom = feadcnom * 2.841 ELSE CALL getcalrev(cunit,cal2file,detcalrev,ftstat) IF(ftstat.NE.0) THEN errstr = 'Cannot open detcalfile wfc2' GOTO 990 ENDIF CALL getadckev(cunit,cal2file,obstime,adcmean,feadcnom,cdadcnom, & feadclo,feadchi,cdadclo,cdadchi,ftstat) IF(cdadcnom.LT.feadcnom) cdadcnom = feadcnom * 2.958 ENDIF IF(ftstat.NE.0) THEN errstr = 'channel conversion table not found' GOTO 990 ENDIF C C= init IFC mask array (0 = accept, -1 = reject , +1 = store seperate) C DO y= 0,ymax DO x= 0,xmax IF(x.LT.768 .AND. y.LT.768) THEN IF(rawevents) THEN imask(x,y) = 0 ELSE imask(x,y) = 99 ENDIF ELSE imask(x,y) = -1 ENDIF ENDDO ENDDO C C- read IFC regions if not filtered eventfile C IF(rawevents) THEN IF(camera.EQ.1)THEN CALL getifcregs(cunit,cal1file,obstime,regs,nreg,ftstat) ELSE CALL getifcregs(cunit,cal2file,obstime,regs,nreg,ftstat) ENDIF IF(ftstat.NE.0) THEN errstr = 'CAL_SOURCES regions not found' GOTO 990 ENDIF C DO i=1,nreg DO y= regs(2,i),regs(4,i) DO x= regs(1,i),regs(3,i) imask(x,y) = nreg ENDDO ENDDO ENDDO ENDIF C C= open the GTI input FITS file C IF(gtifile.NE.' ' .AND. gtifile.NE.'-') THEN CALL FTopen(gunit,gtifile,0,block,ftstat) IF(ftstat.NE.0) THEN errstr = 'unable to open gtifile' GOTO 990 ENDIF c-- CALL ftgprh(gunit,simple,bitpix,naxis,naxes,pcount, c-- & gcount,extend,ftstat) CALL ftmahd(gunit,2,htype,ftstat) IF(ftstat.NE.0) THEN errstr = 'incorrect gtifile' GOTO 990 ENDIF CALL FTgkyj(gunit,'NAXIS2',nrows,comment,ftstat) IF(ftstat.NE.0 .OR. nrows.LE.0) THEN errstr = 'incorrect or empty gtifile' GOTO 990 ENDIF gopen = .TRUE. ENDIF C C= open the new event output FITS file CALL ftinit(ounit,outfile,1,ftstat) IF(ftstat .NE. 0) THEN errstr = 'unable to open outfile' GOTO 990 ENDIF oopen = .TRUE. C C= copy and modify primary header for the new file C CALL ftmahd(iunit,1,htype,ftstat) mkywd = 0 CALL ftcopy(iunit,ounit,mkywd,ftstat) CALL fthdef(ounit,15,ftstat) C CALL ftmkys(ounit,'DATE',fdate,'&',ftstat) IF(ftstat.NE.0) THEN errstr = 'keyword DATE not found' GOTO 990 ENDIF C CALL FTmkys(ounit,'DATE' , fdate,'&',ftstat) CALL FTmkys(ounit,'CREATOR' , taskname,'&',ftstat) CALL FTmkys(ounit,'CONTENT' , 'GAINS','&',ftstat) CALL FTmkyj(ounit,'REVISION', 2,'&',ftstat) CALL FTmkyj(ounit,'WFC_EXTS', 1,'&',ftstat) IF(ftstat.NE.0) THEN errstr = 'standard keywords not found' GOTO 990 ENDIF C IF(camera.EQ.1) THEN CALL FTmkys(ounit,'CAL_FILE',cal1file,'&',ftstat) IF(ftstat.NE.0) THEN ftstat = 0 CALL FTpkls(ounit,'CAL_FILE',cal1file,'Name of det. cal. file',ftstat) ENDIF ELSE CALL FTmkys(ounit,'CAL_FILE',cal2file,'&',ftstat) IF(ftstat.NE.0) THEN ftstat = 0 CALL FTpkls(ounit,'CAL_FILE',cal2file,'Name of det. cal. file',ftstat) ENDIF ENDIF IF(ftstat.NE.0) THEN errstr = 'cannot update CAL_FILE keyword' GOTO 990 ENDIF CALL FTmkys(ounit,'DETREVN',detcalrev,'&',ftstat) IF(ftstat.NE.0) THEN ftstat = 0 CALL FTpkys(ounit,'DETREVN',detcalrev,'Rev. of det. cal. file',ftstat) ENDIF IF(ftstat.NE.0) THEN errstr = 'cannot update DETREVN keyword' GOTO 990 ENDIF C CALL wparfits(ounit,taskname,ftstat) IF(ftstat.NE.0) THEN errstr = 'unable to save run parameters' GOTO 990 ENDIF CALL ftrdef(ounit,ftstat) IF(ftstat.NE.0) THEN errstr = 'unable to copy header' GOTO 990 ENDIF C CALL fonew(ounit,bintime,ftstat) IF(ftstat.NE.0) GOTO 999 C C= create a new extension C next = 1 500 next = next + 1 C C= move to the input extension number or stop processing if not available C CALL ftmahd(iunit,next,htype,ftstat) IF(ftstat.NE.0) GOTO 600 C C= get the binary extension header C CALL ftgbnh(iunit,irows,tfields,ttype,tform,tunit, & extname,varidat,ftstat) IF(ftstat.NE.0) THEN errstr = 'no time column found' GOTO 990 ENDIF C= check that column name exists and get its position in the input file C tcolnam = 'TIME' IF(ttype(1).EQ.tcolnam) THEN CALL ftgcno(iunit,exact,tcolnam,tcolnum,ftstat) ELSE tcolnam = 'TIME_WFC' IF(ttype(1).EQ.tcolnam) THEN CALL ftgcno(iunit,exact,tcolnam,tcolnum,ftstat) ELSE errstr = 'no time column found' GOTO 990 ENDIF ENDIF IF(ftstat.NE.0) THEN errstr = 'bad time column' GOTO 990 ENDIF C C get the time scale CALL ftgkyd(iunit,'T_SCALE',tscale,comment,ftstat) IF(ftstat .NE. 0) THEN errstr = 'cannot get time unit' GOTO 990 ENDIF tscale = tscale / 86400D0 C get the time offset CALL ftgkyd(iunit,'MJDREF',toffs,comment,ftstat) IF(ftstat.NE.0) THEN toffs = 0.D0 ftstat = 0 ENDIF C C get the reduction factor CALL ftgkyj(iunit,'RED_FAC',redfac,comment,ftstat) IF(ftstat.NE.0) THEN errstr = 'cannot get reduction factor' GOTO 990 ENDIF C== C= process events C CALL evtproc(iunit,gunit,ounit,blockio,gopen,irows,redfac, & tscale,toffs,camera,bintime,verbsty,imask,xmax,ymax, & adcmean,feadcnom,cdadcnom,feadclo,feadchi,cdadclo,cdadchi, & mjdmin,mjdmax,ntotal,gorow,ftstat) IF(ftstat.NE.0) GOTO 999 C C= calculate effective ontime C IF(gopen) THEN CALL total_gti(gunit,mjdmin,mjdmax,totalt,verbsty) ELSE totalt = mjdmax - mjdmin ENDIF IF(verbsty.GE.2) WRITE(*,*) (mjdmax-mjdmin)*86400D0, totalt*86400D0 ontime = ontime + totalt * 86400D0 C C= goto next extension C GOTO 500 C=== C= all extensions processed / modify dates in headers C C= calculate mean and intensity of total events C 600 ftstat = 0 C C= correct the number of rows keyword (width is same for output and ifc) C IF(gorow.GT.0) THEN IF(verbsty.GT.0) WRITE(*,*) 'total gain values: ',gorow,' from ',ntotal CALL ftmkyj(ounit,'NAXIS2',gorow,'&',ftstat) CALL ftrdef(ounit, ftstat) IF(ftstat.NE.0) THEN errstr = 'cannot update keyword' RETURN ENDIF ELSE WRITE(*,*) '***WARNING: ZERO GAIN values' ENDIF C C= store statistics C caccu = 0 cmean = 0.0 DO i = nfelo,nfehi caccu = caccu + chantot(i) cmean = cmean + chantot(i) * i ENDDO femean = cmean / caccu feinty = caccu / ontime IF(verbsty.GE.2) WRITE(*,*) 'Fe: ',caccu,cmean,ontime caccu = 0 cmean = 0.0 DO i = ncdlo,ncdhi caccu = caccu + chantot(i) cmean = cmean + chantot(i) * i ENDDO cdmean = cmean / caccu cdinty = caccu / ontime IF(verbsty.GE.2) WRITE(*,*) 'Cd: ',caccu,cmean,ontime C CALL FTmkyd(ounit,'ONTIME' ,ontime,12,'&',ftstat) CALL FTmkye(ounit,'CD_MEAN' ,cdmean,6,'&',ftstat) CALL FTmkye(ounit,'FE_MEAN' ,femean,6,'&',ftstat) CALL FTmkye(ounit,'CD_INSTY',cdinty,6,'&',ftstat) CALL FTmkye(ounit,'FE_INSTY',feinty,6,'&',ftstat) IF(ftstat.NE.0) THEN errstr = 'cannot update keywords' GOTO 990 ENDIF IF(verbsty.GE.2) WRITE(*,*) mjdmin,mjdmax,(mjdmax-mjdmin)*86400D0 C ftstat = 0 CALL ftmkyd(ounit,'MJD_OBS',mjdmin,12,'Obs. start MJD',ftstat) IF(ftstat.NE.0) THEN ftstat = 0 CALL ftpkyd(ounit,'MJD_OBS',mjdmin,12,'Obs. start MJD',ftstat) ENDIF IF(ftstat.NE.0) THEN errstr = 'cannot update keyword in header' GOTO 990 ENDIF C CALL ftmkyd(ounit,'MJD_END',mjdmax,12,'Obs. end MJD',ftstat) IF(ftstat.NE.0) THEN ftstat = 0 CALL ftpkyd(ounit,'MJD_END',mjdmax,12,'Obs. start MJD',ftstat) ENDIF IF(ftstat.NE.0) THEN errstr = 'cannot update keyword in header' GOTO 990 ENDIF C CALL ftpkyj(ounit,'E_TOTAL',ntotal,'total accepted events',ftstat) IF(ftstat.NE.0) THEN errstr = 'cannot add keyword to header' GOTO 990 ENDIF C CALL upd_mjdobs(ounit,mjdmin,mjdmax,ftstat) C C= close files and return on error C 990 IF(ftstat.NE.0) CALL fcerr('*****ERROR: '//errstr) C 999 IF(ftstat.NE.0) CALL fcerrm(ftstat) ftstat = 0 IF(iopen) CALL ftclos(iunit,ftstat) ftstat = 0 IF(gopen) CALL ftclos(gunit,ftstat) ftstat = 0 IF(oopen) CALL ftclos(ounit,ftstat) C 1000 FORMAT(A34,I3) RETURN END C****************************************************************************** C SUBROUTINE: C fonew C C DESCRIPTION: C create new extension for output gain file C C AUTHOR/DATE: C Gerrit J. Wiersma C C MODIFICATION HISTORY: C C NOTES: C C USAGE: C CALL fonew(outlu,ftstat) C C ARGUMENTS: C outlu - pointing file LOGICAL unit number C bintime - length of the bin in seconds C ftstat - return I/O status on FITS file C C PRIMARY LOCAL VARIABLES: C tfield - number of fields (columns) in a record (row) C C CALLED ROUTINES: C subroutine ftcrhd - create extension header C subroutine ftpbnh - initiate binary extension header C subroutine fcerr - oiutput error message C C****************************************************************************** SUBROUTINE fonew(outlu,bintime,ftstat) INTEGER outlu,ftstat DOUBLE PRECISION bintime C INTEGER pcount, tfield CHARACTER*16 ttype(9),tform(9),tunit(9),extnam C C- define columns for FITS extended header C tfield= 8 ! number of fields C ttype(1)='TIME' tform(1)='1D' ! r8 tunit(1)='MJD' C ttype(2)='FE_GAIN' tform(2)='1E' ! r4 tunit(2)='factor' C ttype(3)='CD_GAIN' tform(3)='1E' ! r4 tunit(3)='factor' C ttype(4)='FE_MEAN' tform(4)='1E' ! r4 tunit(4)='adc_chan' C ttype(5)='CD_MEAN' tform(5)='1E' ! r4 tunit(5)='adc_chan' C ttype(6)='FE_EFF' tform(6)='1E' ! r4 tunit(6)='factor' C ttype(7)='CD_EFF' tform(7)='1E' ! r4 tunit(7)='factor' C ttype(8)='COUNTS' tform(8)='1J' ! i4 tunit(8)='number' C C= row-length is 8 + 7 * 4 = 36 bytes ( 80 * 36 = 2880 ) C ftstat = 0 C C= init new extension C extnam = 'GAINS' pcount= 0 CALL FTcrhd(outlu,ftstat) CALL FTpbnh(outlu,0,tfield,ttype,tform,tunit,extnam,pcount,ftstat) IF(ftstat.NE.0) THEN CALL fcerr('*****ERROR cannot create extension header ') RETURN ENDIF C C= write some keywords C CALL FThdef(outlu,15,ftstat) CALL FTpkyd(outlu,'TBIN_GN' ,bintime,12,'gain binning time in s.',ftstat) CALL FTpkyd(outlu,'MJDREF' ,0D0,12,'reference date',ftstat) CALL FTpkyd(outlu,'T_SCALE' ,86400D0,12,'time scale',ftstat) CALL FTpkyd(outlu,'MJD_OBS' ,0D0,12,'start of obs. (MJD)',ftstat) CALL FTpkyd(outlu,'MJD_END' ,0D0,12,'end of obs. (MJD)',ftstat) CALL FTpkyd(outlu,'ONTIME' ,0D0,12,'accumulated seconds',ftstat) CALL FTpkye(outlu,'CD_MEAN' ,0.0,6,'mean channel',ftstat) CALL FTpkye(outlu,'FE_MEAN' ,0.0,6,'mean channel',ftstat) CALL FTpkye(outlu,'CD_INSTY',0.0,6,'intensity cts/sec.',ftstat) CALL FTpkye(outlu,'FE_INSTY',0.0,6,'intensity cts/sec.',ftstat) IF(ftstat.NE.0) THEN CALL fcerr('*****ERROR: cannot add keywords') RETURN ENDIF CALL ftbdef(outlu,tfield,tform,pcount,0,ftstat) C RETURN END C***************************************************************************** C SUBROUTINE: C evtproc C C DESCRIPTION: C read IFC events and store in arrays C C AUTHOR/DATE: C Gerrit J. Wiersma C C MODIFICATION HISTORY: C C NOTES: C - It is assumed that the input file is time ordered C - C C USAGE: C CALL evtproc(iunit,gunit,ounit,blockio,gopen,irows,redfac, C tscale,toffs,camera,bintime,verbsty,ftstat) C C ARGUMENTS: C iunit - input event file LOGICAL unit number C gunit - input GTI file LOGICAL unit number C ounit - output gain file LOGICAL unit number C blockio - fast blockio reading of file C gopen - use GTI file for time selection C irows - maximum number of rows of input file (extension) C toffs - offset of times in MJD C tscale - scale factor of times units in seconds C verbsty - output verbosity volume C bintime - binning time in seconds for one gain calculation C ntotal - total number of accepted events C gorow - output row number C mjdmin - time of earliest accepted event C mjdmax - time of latest accepted event C C PRIMARY LOCAL VARIABLES: C width - width of table C frow - beginning row number C remain - number of rows remaining C nelem - number of data elements C time - observation times C time1 - start time of bin C time2 - stop time of bin C tmid - middle time of timebin C C esum - array holding summed energy bins C C CALLED ROUTINES: C subrouitne anafun - analyse the function C C subroutine ftgcfe - get real column values C subroutine ftgkyj - get INTEGER keyword value C subroutine ftmkyj - modify INTEGER keyword value C C****************************************************************************** C SUBROUTINE evtproc(iunit,gunit,ounit,blockio,gopen,irows,redfac, & tscale,toffs,camera,bintime,verbsty,imask,xmax,ymax, & adcmean,feadcnom,cdadcnom,feadclo,feadchi,cdadclo,cdadchi, & mjdmin,mjdmax,ntotal,gorow,ftstat) C INTEGER iunit, gunit, ounit, irows, camera, verbsty INTEGER redfac, ntotal, gorow DOUBLE PRECISION bintime, tscale, toffs, mjdmin, mjdmax REAL adcmean(*),feadcnom,cdadcnom,feadclo,feadchi,cdadclo,cdadchi LOGICAL blockio, gopen INTEGER xmax, ymax INTEGER*2 imask(0:xmax,0:ymax) C INTEGER BUFMAX PARAMETER (BUFMAX = 1000) C CHARACTER comment*70 LOGICAL anyf, flagvals(BUFMAX) INTEGER width, frow, felem, remain, nelem, ftstat INTEGER i, n, nbin, nadc, nstep c-- INTEGER tcolnum,xcolnum,ycolnum,zcolnum DOUBLE PRECISION t,tev,time1,time2,tmid,tstep REAL sumfac LOGICAL inside_gti, binstart, inside, latest C INTEGER*4 time(BUFMAX) INTEGER*2 eval(BUFMAX), xval(BUFMAX), yval(BUFMAX) INTEGER*4 buf4(3,BUFMAX) INTEGER*2 buf2(6,BUFMAX) EQUIVALENCE (buf4,buf2) C REAL esum(32), adc C INTEGER x, y REAL e, zcd, zfe, efffe, effcd REAL cpeak, cmean, cmedn, sigma REAL fwhm, cfwhm, ew50, ew68, ew90 REAL cmeancd, cmeanfe, gaincd, gainfe INTEGER ipeak C INTEGER ncdlo, ncdhi, nfelo, nfehi DOUBLE PRECISION chantot,ontime COMMON /ifcstat/ ncdlo,ncdhi,nfelo,nfehi,chantot(32),ontime C= C== end of declarations C=== binstart = .FALSE. nstep = 1 tstep = bintime / 86400D0 sumfac = redfac + 1 C C- reset sum arrays C DO n = 1,32 esum(n) = 0. ENDDO C C= get the input row width C ftstat=0 CALL ftgkyj(iunit,'NAXIS1',width,comment,ftstat) IF(ftstat.NE.0) THEN CALL fcerr('*****ERROR: cannot read keyword from event input file') RETURN ENDIF IF(verbsty.GE.2) WRITE(*,*) 'procevt ',bintime,irows,width C C= get (next) buffer of input file records C latest = .FALSE. nbin = 0 frow = 1 felem = 1 remain = irows 10 IF(remain .GE. BUFMAX) THEN nelem = BUFMAX ELSE nelem = remain ENDIF C C= read buffer of BUFMAX events C IF(blockio) THEN CALL FTgtbb(iunit,frow,1,width*nelem,buf2,ftstat) ELSE CALL ftgcfj(iunit,1,frow,felem,nelem,time,flagvals,anyf,ftstat) CALL ftgcfi(iunit,2,frow,felem,nelem,xval,flagvals,anyf,ftstat) CALL ftgcfi(iunit,3,frow,felem,nelem,yval,flagvals,anyf,ftstat) c-- CALL ftgcfi(iunit,4,frow,felem,nelem,zval,flagvals,anyf,ftstat) CALL ftgcfi(iunit,5,frow,felem,nelem,eval,flagvals,anyf,ftstat) ENDIF IF(ftstat.NE.0) THEN CALL fcerr('*****ERROR: cannot read events from input file') RETURN ENDIF C== C= process each single event in buffer C DO 50 i = 1, nelem IF(remain.EQ.i) latest = .TRUE. C C= get next event time and energy channel C IF(blockio) THEN t = buf4(1,i) x = buf2(3,i) y = buf2(4,i) e = buf2(6,i) + 1 ELSE t = time(i) x = xval(i) y = yval(i) e = eval(i) + 1 ENDIF IF(e.GT.32) STOP '*****ERROR in wgain: E .GT. 31' C C- test if event inside time window C inside = .TRUE. IF(t.LE.0D0) THEN inside = .FALSE. ELSE tev = ( t * tscale ) + toffs IF(gopen) inside = inside_gti(gunit,tev,verbsty) ENDIF C C= skip events until begin timebin with first correct event time C IF(.NOT.binstart) THEN IF(inside) THEN time1 = tev time2 = time1 + tstep binstart = .TRUE. ELSE GOTO 50 ENDIF ENDIF C C- test if inside region C IF(inside) THEN IF(imask(x,y).LE.0) inside = .FALSE. ENDIF IF(inside) THEN IF(tev.GT.mjdmax) mjdmax = tev IF(tev.LT.mjdmin) mjdmin = tev chantot(e) = chantot(e) + sumfac ntotal= ntotal + 1 ENDIF C C= set end of time bin if last event C= test whether inside Good Time Interval C C if tev G.E. time2 dan is that de eerste voor de volgende bin C C time2 = end time of bin C IF(latest) THEN IF(inside) THEN nbin = nbin + 1 esum(e) = esum(e) + sumfac ENDIF tmid = ( time2 + tev - tstep ) * 0.5D0 ELSE IF(.NOT.inside) GOTO 50 IF(tev.LT.time2) THEN nbin = nbin + 1 esum(e) = esum(e) + sumfac GOTO 50 ENDIF tmid = time2 - ( tstep * 0.5D0 ) ENDIF C C= now process complete energy bin C IF(verbsty.GE.3) THEN DO n = 1,32 WRITE(*,*) n-1,esum(n) ENDDO ENDIF IF(nbin.GT.1) THEN C C= analyze the two different energy peaks its position, mean and fwhm C CALL anafun(esum,nfelo,nfehi,zfe,ipeak,cpeak,cmean,cmedn,sigma, & fwhm,cfwhm,ew50,ew68,ew90) nadc = 0 cmeanfe = 0.0 DO n = 1,32 adc = adcmean(n) IF(adc.GT.feadclo .AND. adc.LT.feadchi) THEN nadc = nadc + esum(n) cmeanfe = cmeanfe + adc * esum(n) ENDIF ENDDO IF(nadc.GT.0) THEN cmeanfe = cmeanfe / nadc gainfe = cmeanfe / feadcnom ELSE IF(verbsty.GT.0) WRITE(*,*) '*WARNING: zero Fe coints' cmeanfe = -1.0 ENDIF IF(verbsty.GE.2) WRITE(*,*) nadc,cmeanfe,cmean-1.0,fwhm C CALL anafun(esum,ncdlo,ncdhi,zcd,ipeak,cpeak,cmean,cmedn,sigma, & fwhm,cfwhm,ew50,ew68,ew90) nadc = 0 cmeancd = 0.0 DO n = 1,32 adc = adcmean(n) IF(adc.GT.cdadclo .AND. adc.LT.cdadchi) THEN nadc = nadc + esum(n) cmeancd = cmeancd + adc * esum(n) ENDIF ENDDO IF(nadc.GT.0) THEN cmeancd = cmeancd / nadc gaincd = cmeancd / cdadcnom ELSE IF(verbsty.GT.0) WRITE(*,*) '*WARNING: zero Cd coints' cmeancd = -1.0 ENDIF IF(verbsty.GE.2) WRITE(*,*) nadc,cmeancd,cmean-1.0,fwhm IF(verbsty.GE.2) WRITE(*,*) ' ' C efffe = 1. effcd = 1. C IF(cmeancd.GT.0.0 .AND. cmeanfe.GT.0.0 ) THEN gorow = gorow + 1 CALL FTpcld(ounit,1,gorow,1,1,tmid,ftstat) CALL FTpcle(ounit,2,gorow,1,1,gainfe,ftstat) CALL FTpcle(ounit,3,gorow,1,1,gaincd,ftstat) CALL FTpcle(ounit,4,gorow,1,1,cmeanfe,ftstat) CALL FTpcle(ounit,5,gorow,1,1,cmeancd,ftstat) CALL FTpcle(ounit,6,gorow,1,1,efffe,ftstat) CALL FTpcle(ounit,7,gorow,1,1,effcd,ftstat) CALL FTpclj(ounit,8,gorow,1,1,nbin,ftstat) IF(ftstat.NE.0) THEN CALL fcerr('ERROR: cannot write gain record') RETURN ENDIF ENDIF C ENDIF C 40 nstep = nstep + 1 time2 = time1 + nstep * tstep IF(time2.LE.tev) GOTO 40 DO n = 1,32 IF(verbsty.GE.3) WRITE(*,*) n,esum(n) esum(n) = 0. ENDDO esum(e) = sumfac nbin = 1 C 50 CONTINUE C C= process mext buffer if more events remain C frow = frow + nelem remain = remain - nelem IF(remain.GT.0) GOTO 10 C RETURN END C C***************************************************************************** C SUBROUTINE: C xmktie C C DESCRIPTION: C This subroutine moves the extra keywords,i.e., the C keywords which don't contain: XTENSION,BITPIX, C NAXIS*,PCOUNT,GCOUNT,TFIELDS,TTYPE*,TFORM*,TUNIT*, C END,TBCOL*,and EXTNAME, from the input file to C the output file C C AUTHOR/DATE: C James Kent Blackburn 6/09/92 C C MODIFICATION HISTORY: C C C NOTES: C C USAGE: C call xmktie(iunit,ounit,status) C C ARGUMENTS: C iunit - input unit number C ounit - output unit number C fname - input FITS file name C status - error number C C PRIMARY LOCAL VARIABLES: C i* -index to substring C l* - substring presence flag C nkeys - number of keywords C copyflg - copy keyword flag C C CALLED ROUTINES: C subroutine ftghsp - get number of keywords in extension C subroutine ftgrec - get keyword record C subroutine ftprec - put keyword record C C*************************************************************************** subroutine xmktie(iunit,ounit,status) integer iunit,ounit,status integer i1,i2,i3,i4,i5,i6,i7,i8,i9,ia,ib,ic,id integer i,nkeys,nmore logical l1,l2,l3,l4,l5,l6,l7,l8,l9,la,lb,lc,ld logical copyflg character*80 record C CALL ftghsp(iunit,nkeys,nmore,status) DO 10 i = 1, nkeys CALL ftgrec(iunit,i,record,status) i1 = index(record(1:8),'XTENSION') i2 = index(record(1:6),'BITPIX') i3 = index(record(1:5),'NAXIS') i4 = index(record(1:6),'PCOUNT') i5 = index(record(1:6),'GCOUNT') i6 = index(record(1:7),'TFIELDS') i7 = index(record(1:5),'TTYPE') i8 = index(record(1:5),'TFORM') i9 = index(record(1:5),'TUNIT') ia = index(record(1:7),'EXTNAME') ib = index(record(1:3),'END') ic = index(record(1:5),'TBCOL') id = index(record(1:7),'HDUCLAS') l1 = i1 .eq. 0 l2 = i2 .eq. 0 l3 = i3 .eq. 0 l4 = i4 .eq. 0 l5 = i5 .eq. 0 l6 = i6 .eq. 0 l7 = i7 .eq. 0 l8 = i8 .eq. 0 l9 = i9 .eq. 0 la = ia .eq. 0 lb = ib .eq. 0 lc = ic .eq. 0 ld = id .eq. 0 copyflg = l1 .and. l2 .and. l3 .and. l4 .and. l5 & .and. l6 .and. l7 .and. l8 .and. l9 .and. la & .and. lb .and. lc .and. ld IF( copyflg ) THEN CALL ftprec(ounit,record,status) ENDIF 10 CONTINUE C RETURN END *******************************************************************************