XMM-Newton SAS Home Page
XMM-Newton Science Analysis System


emchain (emchain-12.0.1) [xmmsas_20230412_1735-21.0.0]


Algorithm

   subroutine emchain

      Read parameters.

      if startfromodf then call processOdf
      else if runevlistcomb then call mergeEvents

      if makeflaregti then
         Loop over the *MIEVLI0000.FIT files
            call makeFlareTS
            if globalflare  call mergeTS  else  call tsToGTI
         end loop
         if globalflare  call tsToGTI
      endif

      Loop over the *MIEVLI0000.FIT files
         if addtaglenoise call emtaglenoise
         if withflaregti  call applyFlareGTI
         if addvigweight  call evigweight ineventset=eventfile
      end loop

      if not keepintermediate then  rm -f *.in.mos *.out.mos merged.*.mos

   end subroutine emchain

   subroutine processOdf

      Set SAS_ODF to odf (for OAL).

      Call atthkgen if no tracking history file or withatthkgen is true.
      Call tabgtigen with expression='!isNull(DAHFPNT) && DAHFPNT<atttol'
      Call hkgtigen if no HK GTI is present.
      gtiext = 'T' // obsid // inst // 'X000EXTGTI0000'.FIT'
      Call gtimerge gtitable=$gtiext on attitude GTI (if filteratt),
                     HK GTI (if filterhk) and user GTI (if present)

      Look in odf for ODF files pertaining to selected instrument,
      ending in IME, TIE, RIE or CTE.FIT (possibly .gz or .FTZ).
      Deduce all exposures present.

      Loop over selected exposures
         if badpixfindalgo ne 'NO' then
            call ccdLoop (forbadpixfind=Y)
            call badpixLoop (no flare screening)
            call mergeEvents
            call ebadpixpixupdate
            call buildFlareGTI
            call badpixLoop (with flare screening and low energy run)
         endif

         call ccdLoop (forbadpixfind=N)
         if runevlistcomb then call mergeEvents
      end loop over exposures

   end subroutine processOdf

   subroutine ccdLoop

      Loop over selected CCDs and nodes

         Identify event file name event0 ending in IME, TIE, RIE or CTE.FIT.
         Deduce ccd and node. nccd = node // ccd
         core = obsid // inst // expid

         aux = substring($event0 - last 9 characters) // '00AUX.FIT'
         gtiin = 'T' // core // 'RAWGTI00' // nccd // '.FIT'
         gtiout = 'T' // core // 'LOCGTI00' // nccd // '.FIT'
         frameout = 'T' // core // 'FRAMLI00' // nccd // '.FIT'
         eventin = 'T' // core // 'RWEVLI00' // nccd // '.FIT'
         eventout = 'T' // core // 'CLEVLI00' // nccd // '.FIT'
         eventcal = 'T' // core // 'CAEVLI00' // nccd // '.FIT'
         emframes auxiliaryset=frame.in odfeventset=$event0 \
                  outeventset=$eventin frameset=$frameout outgtiset=$gtiin
         if ($gtiext exists) then
            flagbadtimes=Y ingtiset=$gtiext

         if (not processlowgain and GAIN_CCD='LOW') next

         bad = 'T' // core // 'BPXFLI00' // nccd // '.FIT'
         if $bad does not exist then
            bad = 'P*' // instid // '*BADPIX00' // nccd // '.FIT'

         if withbadpix and not forbadpixfind then
            mv $eventin $eventout
            badpix eventset=$eventout outset=$eventin windowfilter=Y
            if ($bad exists) then
               getuplnkbadpix=Y getotherbadpix=N getnewbadpix=Y badpixset=$bad
            rm $eventout
         endif

         off = odf // * // instrument // * // ccd // node // 'OVE.FIT'
         emevents frameset=$frameout odfeventset=$eventin eventset=$eventout
         if ($off exists) then  offvarsets=$off
         if not randomizeP then  randomizeposition=N
         if     randomizeT then  randomizetime=Y
         if forbadpixfind then  analysepatterns=N flagbadpixels=N \
                                splitdiagonals=N randomizeposition=N

         if ($gtiext exists) then
            hkgti = 'T' // core // 'HKXGTI00' // nccd // '.FIT'
            gtialign gtitable=$gtiext:STDGTI eventset=$eventout \
                     outset=$hkgti
            extname = 'STDGTI' // node // ccd
            gtimerge tables="$hkgti $gtiin" mergemode=and \
                     gtitable=$gtiout:$extname

         cp $eventout $eventcal
         if withattcalc and not forbadpixfind then
            attcalc eventset=$eventcal

         emenergy ineventset=$eventcal
         if not imaging mode then  getccdbkg=N
         if not randomizeE then    randomizeenergy=N
         if forbadpixfind then     correctcti=N correctgain=N randomizeenergy=N
         bkg = 'P' // core // 'CCDBKG00' // nccd // '.FIT'
         if writeccdbackground then backgroundset=$bkg

         if rejectbadevents or forbadpixfind then
            evselect table=$eventcal destruct=Y keepfilteroutput=Y \
                     expression="(FLAG & 0x$rejectionflag) == 0"

      end loop over CCDs and nodes

   end subroutine ccdLoop

   subroutine badpixLoop

      Loop over selected CCDs and nodes

         bad = 'T' // core // 'BPXFLI00' // nccd // '.FIT'
         eventfilt = 'T' // core // 'FTEVLI00' // nccd // '.FIT'
         evmap = 'T' // core // 'IMAGPR00' // nccd // '.FIT'

         evselect table=$eventcal filteredset=$eventfilt  \
                  keepfilteroutput=Y  destruct=Y writedss=Y updateexposure=Y \
                  expression="TIME in GTI($gtiflare)"

         if badpixfindalgo == 'EM' then
            emeventsproj eventset=$eventfilt rejectbadevents=Y evimageset=$evmap
            embadpixfind evimageset=$evmap badpixset=$bad

            if (lowenerbadpix) select PHA < 150 and run again incrementally
         else
            badpixfind eventset=$eventfilt thresholdlabel=rate \
                       badpixset=$bad  \
                       hithresh=0.005 narrowerthanpsf=3.0 backgroundrate=1.E-5
         endif

      end loop over CCDs and nodes

      if stopafterbadpixfind  stop

   end subroutine badpixLoop

   subroutine mergeEvents

      imerge = 'T' // core // 'MIEVLM0000.FIT'
      tmerge = 'T' // core // 'TIEVLM0000.FIT'

      evlistcomb eventsets='T'//core//'CAEVLI00*.FIT' imagingset=$imerge \
                 timingset=$tmerge maintable='EVENTS OFFSETS'
      if fulloutput then
         emosimgcolnames="TIME RAWX RAWY DETX DETY X Y PHA PI FLAG PATTERN
             FRAME ENERGYE1 ENERGYE2 ENERGYE3 ENERGYE4 PERIPIX OFFSETX OFFSETY"
         emosimgcoltypes="double int16 int16 int16 int16 int32 int32 int16
             int16 int32 int8 int32 int16 int16 int16 int16 int8 int16 int16"
      endif

      if applyccdgti then
         Loop over 'T'//core//'LOCGTI00*.FIT' files
         expr = expr // '|| (CCDNR==' // nccd // ' && GTI($gtiout,TIME))'
      endif

      eventim = 'P' // core // 'MIEVLI0000.FIT'
      evselect table=$imerge filteredset=$eventim \
               expression=$expr destruct=Y keepfilteroutput=Y

      fparkey "EPIC MOS IMAGING MODE EVENT LIST" $eventim[0] CONTENT \
         add=Y insert=DATE"
      fappend $sasccf[CALINDEX] $eventim

      if ($tmerge exists) then
         eventti = 'P' // core // 'TIEVLI00000.FIT'
         evselect table=$tmerge filteredset=$eventti \
                  expression=$expr destruct=Y keepfilteroutput=Y
         fparkey "EPIC TIMING MODE EVENT LIST" $eventti[0] CONTENT \
            add=Y insert=DATE"
         fappend $sasccf[CALINDEX] $eventti
      endif

   end subroutine mergeEvents

   subroutine makeFlareTs
      expr = "(PATTERN==0) && ((FLAG & 0x762b8000) == 0) && #XMMEA_22"
      flarets = 'P' // core // 'FBKTSR0000.FIT'
      check that expected counts per bin in quiet conditions is > 10,
         otherwise increase $flaretimebin
      evselect table=$eventim expression=$expr updateexposure=N \
               rateset=$flarets timebinsize=$flaretimebin \
               timecolumn=TIME maketimecolumn=Y makeratecolumn=Y
      add FRACEXP column (currently done by looking at full timeseries)
      divide by CCD area (IN_FOV keyword) and FRACEXP
   end subroutine makeFlareTs

   subroutine mergeTs
      globts = 'P' // obsid // 'EMX000FBKTSR0000.FIT'
      if $globts exists then
         multiply by CCD area and FRACEXP
         merge columns of $flarets and $globts:
         RATE    = RATE1 + RATE2
         ERROR   = SQRT(ERROR1**2 + ERROR2**2)
         FRACEXP = FRACEXP1 + FRACEXP2
         divide by CCD area and FRACEXP
      endif else then
         cp $flarets $globts
      endelse
   end subroutine mergeTs

   subroutine tsToGTI
      gtiflare = timeseries prefix //  'FBKGTI0000.FIT'
      tabgtigen table=$flarets expression="RATE<$flaremaxrate" \
                gtiset=$gtiflare
      evselect table=$gtiflare writedss=N updateexposure=N keepfilteroutput=Y \
               expression="(STOP - START) > 1.5*$flaretimebin"
   end subroutine tsToGTI

   subroutine applyFlareGTI
      expr = "GTI($gtiflare,TIME)"
      evselect table=$eventim destruct=Y keepfilteroutput=Y expression=$expr
      evselect table=$eventti destruct=Y keepfilteroutput=Y expression=$expr
   end subroutine applyFlareGTI



XMM-Newton SOC -- 2023-04-16