Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Are images sources off by one? #50

Closed
hamogu opened this issue May 20, 2021 · 3 comments · Fixed by #62
Closed

Are images sources off by one? #50

hamogu opened this issue May 20, 2021 · 3 comments · Fixed by #62

Comments

@hamogu
Copy link
Member

hamogu commented May 20, 2021

reported by @kglotfelty

I'm trying to do something with marx using an input image and
I think that there might be a pixel-shift/offset happening.

I tried to simplify things as much as possible. I've attached my
input "S-ImageFile" which is just a single pixel (delta function):

$ dmstat "delta.img" cen+
delta.img(x, y)
    min: 0      @: ( 4047 4047 )
    max: 1      @: ( 4097 4097 )
cntrd[log] : ( 51 51 )
cntrd[phys]: ( 4097 4097 )
sigma_cntrd: ( 0.509999 0.509999 )
   good: 10000
   null: 0

So the centroid/pixel is at 4097,4097. In ra/dec it's

$ punlearn dmcoords
$ dmcoords delta.img op=sky x=4097 y=4097 celfmt=deg
$ pget dmcoords ra dec
195.93423610867
-24.229557226578

I'm using obsid 7901 so you can grab the asol file from the archive

download_chandra_obsid 7901 asol
mv 7901/primary/pcadf07901_000N002_asol1.fits.gz .
gunzip pcadf07901_000N002_asol1.fits.gz

Okay, now set up a copy of marx.par

cp `paccess marx` marx_delta.par
pset marx_delta.par \
  TStart=2006.92 \
  ExposureTime=37144.58925002813 \
  OutputDir=delta_out \
  RandomSeed=107254701 \
  Verbose=no \
  GratingType=NONE \
  DetIdeal=yes \
  SourceFlux=0.01 \
  MinEnergy=1 \
  MaxEnergy=1 \
  SourceRA=195.9341611742938 \
  SourceDEC=-24.22948889322631 \
  SourceType=IMAGE \
  S-ImageFile=delta.img \
  DitherModel=FILE \
  DitherFile=pcadf07901_000N002_asol1.fits \
  DetOffsetX=0.001444942264670734 \
  DetOffsetZ=-0.01005726120280315 \
  AspectBlur=0.07000000000000001 \
  RA_Nom=195.93423610867 \
  Dec_Nom=-24.229557226578 \
  Roll_Nom=80.721746267494 \
  DetExtendFlag=yes \
  ACIS_Exposure_Time=3.1 \
  ACIS_Frame_Transfer_Time=0

and now run marx and marx2fits

marx @@marx_delta.par
marx2fits delta_out delta_out.fits
dmcopy delta_out.fits"[bin x=4046.5:4146.5:1,y=4046.5:4146.5:1][opt type=i4]" delta_out.img clob+

The x/y grid is the same grid I used to make delta.img. Now check
the centroid

$ dmstat "delta_out.img" cen+
EVENTS_IMAGE(X, Y)
    min: 0      @: ( 4047 4047 )
    max: 103480      @: ( 4096 4097 )
cntrd[log] : ( 49.994187047 50.999774219 )
cntrd[phys]: ( 4095.994187 4096.9997742 )
sigma_cntrd: ( 116.93425318 122.2354233 )
   good: 10000
   null: 0

We see that the centroid is off-by-1 pixel in the X direction 4096
instead of 4097.

I can also see it in ds9

ds9 delta_out.img -zoom to 16 -log -mask color red -mask delta.img \
  -saveimage png ds9.png -exit

(image attached).

Any idea what might be going on? This is the first time I've tried using
SourceType=IMAGE so I'm not sure if there is some parameter(s) I need to
tweak.

(Note: The attached file is a fits file called "delta.img". However, github does not allow arbitrary file extensions for attached files, so I simply added ".png" to the end to fool github. To use the file, download and rename is "delta.img" again.)
delta img

@hamogu
Copy link
Member Author

hamogu commented May 20, 2021

ds9

hamogu added a commit to hamogu/marx that referenced this issue Nov 19, 2023
Once an interval was narrowed down to just two elements, the binary search algorithm always returned the lower of the two. That's not correct.

This bug was found by simulations of a one-pixel source that happens to be off by one pixel. If, in that example, the source would have been located at +1 or -1 pixel compared to the test that was run, this bug would have gone unnoticed.

Changes in "s-image.c" are mostly cosmetic to make it easier to reason why the formula works,
by removing the double negative. I *think* there was als oa 0.5 pixel offset before, but since it's hard to reason about, I opted for simplifying and making sure it's correct by testing a simulation.

fixes Chandra-MARX#50
closes Chandra-MARX#54
@hamogu
Copy link
Member Author

hamogu commented Nov 27, 2023

As I do more testing, I find that there is even more to it:
Screenshot 2023-11-27 at 11 40 10 AM

Left is an asymetric input image, right is the marx simulated eventlist for that input image.
So, the "off by one" that this issue started with seems to be a happy accident of placing the one pixel about in the middle of the input image, which also means that the "fix" that closed this issue is incomplete.

@hamogu hamogu reopened this Nov 27, 2023
@hamogu
Copy link
Member Author

hamogu commented Nov 27, 2023

This is all a misunderstanding of how the IMAGE source works, complicated by the fact that the initial bug report used a good-for-testing special case.

From https://space.mit.edu/cxc/marx/indetail/models.html#image-source: "marx inspects the header of the file for a WCS specification and extracts the pixel scale. However, it does not extract the position or orientation on the sky. marx will just assume that the image is centered on the optical axis and that the axes directions are aligned with the detector axes."

What happens here is that the input image have a WCS coordinate system, but marx ignores all of that except for the absolute value of "CDELT1" and "CDELT2". That leads to the flip that I showed in the comment above (because one of the CDELT keywords is negative, which is ignored by marx) and it also leads to the original bug report: The single pixel is located at integer pixel (50,50) which is not exactly the middle of a (100,100) array. When flipped in one direction (because marx ignore the sign of the CDELT), that pixel would be at (51, 50) - which is just one pixel off. And that "one pixel off" location is correctly simulated by marx.

So, after many, many hours of investigation, I can confirm that marx behaves exactly as advertised and this is, in fact, not a bug. The behavior might be confusing and not what most users expect, but given the long heritage, I won't change it. Instead, I will try to make this more clear in the documentation. If a simulation with an image using the full WCS information is required, use a SIMPUT source and the external SIMPUT library.

#57 discussed the possibility of adding a new native marx source "IMAGE with WCS", but decided that that's out of scope for marx and would be a duplication of effort since the same effect can be achieved with a SIMPUT source.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant