Index: branches/eam_branches/ipp-20130419/ippconfig/dvo.photcodes
===================================================================
--- branches/eam_branches/ipp-20130419/ippconfig/dvo.photcodes	(revision 35420)
+++ branches/eam_branches/ipp-20130419/ippconfig/dvo.photcodes	(revision 35421)
@@ -165,4 +165,5 @@
   3004  SYNTH.z              ref   0.000  0.000 0.000     -     - 0.0000     0     4     nan 0.000 2.000  0.600   0x0000 0x0000  0x0000 0x0000
   3005  SYNTH.y              ref   0.000  0.000 0.000     -     - 0.0000     0     5     nan 0.000 2.000  0.600   0x0000 0x0000  0x0000 0x0000
+  3006  SYNTH.w              ref   0.000  0.000 0.000     -     - 0.0000     0     9     nan 0.000 2.000  0.600   0x0000 0x0000  0x0000 0x0000
 
   100   MEGACAM.u.00         dep  25.280 -0.350 0.000     -     - 0.0000     0     -   0.000 0.000 1.000  0.000   0x0000 0x3888  0x0000 0x0000
@@ -836,64 +837,64 @@
   10475 GPC1.y.XY75          dep  23.320 -0.073 0.000     -     - 0.0000     0     5   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
   10476 GPC1.y.XY76          dep  23.320 -0.073 0.000     -     - 0.0000     0     5   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10501 GPC1.w.XY01          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10502 GPC1.w.XY02          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10503 GPC1.w.XY03          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10504 GPC1.w.XY04          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10505 GPC1.w.XY05          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10506 GPC1.w.XY06          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10510 GPC1.w.XY10          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10511 GPC1.w.XY11          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10512 GPC1.w.XY12          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10513 GPC1.w.XY13          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10514 GPC1.w.XY14          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10515 GPC1.w.XY15          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10516 GPC1.w.XY16          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10517 GPC1.w.XY17          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10520 GPC1.w.XY20          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10521 GPC1.w.XY21          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10522 GPC1.w.XY22          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10523 GPC1.w.XY23          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10524 GPC1.w.XY24          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10525 GPC1.w.XY25          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10526 GPC1.w.XY26          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10527 GPC1.w.XY27          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10530 GPC1.w.XY30          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10531 GPC1.w.XY31          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10532 GPC1.w.XY32          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10533 GPC1.w.XY33          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10534 GPC1.w.XY34          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10535 GPC1.w.XY35          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10536 GPC1.w.XY36          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10537 GPC1.w.XY37          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10540 GPC1.w.XY40          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10541 GPC1.w.XY41          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10542 GPC1.w.XY42          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10543 GPC1.w.XY43          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10544 GPC1.w.XY44          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10545 GPC1.w.XY45          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10546 GPC1.w.XY46          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10547 GPC1.w.XY47          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10550 GPC1.w.XY50          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10551 GPC1.w.XY51          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10552 GPC1.w.XY52          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10553 GPC1.w.XY53          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10554 GPC1.w.XY54          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10555 GPC1.w.XY55          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10556 GPC1.w.XY56          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10557 GPC1.w.XY57          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10560 GPC1.w.XY60          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10561 GPC1.w.XY61          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10562 GPC1.w.XY62          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10563 GPC1.w.XY63          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10564 GPC1.w.XY64          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10565 GPC1.w.XY65          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10566 GPC1.w.XY66          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10567 GPC1.w.XY67          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10571 GPC1.w.XY71          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10572 GPC1.w.XY72          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10573 GPC1.w.XY73          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10574 GPC1.w.XY74          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10575 GPC1.w.XY75          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
-  10576 GPC1.w.XY76          dep  25.000  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10501 GPC1.w.XY01          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10502 GPC1.w.XY02          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10503 GPC1.w.XY03          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10504 GPC1.w.XY04          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10505 GPC1.w.XY05          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10506 GPC1.w.XY06          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10510 GPC1.w.XY10          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10511 GPC1.w.XY11          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10512 GPC1.w.XY12          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10513 GPC1.w.XY13          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10514 GPC1.w.XY14          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10515 GPC1.w.XY15          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10516 GPC1.w.XY16          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10517 GPC1.w.XY17          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10520 GPC1.w.XY20          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10521 GPC1.w.XY21          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10522 GPC1.w.XY22          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10523 GPC1.w.XY23          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10524 GPC1.w.XY24          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10525 GPC1.w.XY25          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10526 GPC1.w.XY26          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10527 GPC1.w.XY27          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10530 GPC1.w.XY30          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10531 GPC1.w.XY31          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10532 GPC1.w.XY32          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10533 GPC1.w.XY33          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10534 GPC1.w.XY34          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10535 GPC1.w.XY35          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10536 GPC1.w.XY36          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10537 GPC1.w.XY37          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10540 GPC1.w.XY40          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10541 GPC1.w.XY41          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10542 GPC1.w.XY42          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10543 GPC1.w.XY43          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10544 GPC1.w.XY44          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10545 GPC1.w.XY45          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10546 GPC1.w.XY46          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10547 GPC1.w.XY47          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10550 GPC1.w.XY50          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10551 GPC1.w.XY51          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10552 GPC1.w.XY52          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10553 GPC1.w.XY53          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10554 GPC1.w.XY54          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10555 GPC1.w.XY55          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10556 GPC1.w.XY56          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10557 GPC1.w.XY57          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10560 GPC1.w.XY60          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10561 GPC1.w.XY61          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10562 GPC1.w.XY62          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10563 GPC1.w.XY63          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10564 GPC1.w.XY64          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10565 GPC1.w.XY65          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10566 GPC1.w.XY66          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10567 GPC1.w.XY67          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10571 GPC1.w.XY71          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10572 GPC1.w.XY72          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10573 GPC1.w.XY73          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10574 GPC1.w.XY74          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10575 GPC1.w.XY75          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
+  10576 GPC1.w.XY76          dep  26.060  0.000 0.000     -     - 0.0000     0     9   0.015 0.000 1.000  0.000   0x0000 0x0000  0xe0440130 0x1003bc88
   11000 GPC1.g.SkyChip       dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
   11100 GPC1.r.SkyChip       dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
Index: branches/eam_branches/ipp-20130419/ippconfig/recipes/filerules-mef.mdc
===================================================================
--- branches/eam_branches/ipp-20130419/ippconfig/recipes/filerules-mef.mdc	(revision 35420)
+++ branches/eam_branches/ipp-20130419/ippconfig/recipes/filerules-mef.mdc	(revision 35421)
@@ -118,7 +118,7 @@
 PSWARP.VARIANCE         INPUT    @FILES        CHIP       VARIANCE
 PSWARP.MASK             INPUT    @FILES        CHIP       MASK
-PSWARP.SKYCELL          INPUT    @FILES        CHIP       IMAGE
-PSWARP.ASTROM           INPUT    @FILES        CHIP       CMF
-PSWARP.BKGMODEL		  INPUT	   @FILES	 CHIP	    IMAGE
+PSWARP.SKYCELL          INPUT    @FILES        CHIP       WCS
+PSWARP.ASTROM           INPUT    @FILES        CHIP       WCS
+PSWARP.BKGMODEL         INPUT    @FILES	       CHIP	  IMAGE
 
 ## files used by ppsub
Index: branches/eam_branches/ipp-20130419/ippconfig/recipes/filerules-simple.mdc
===================================================================
--- branches/eam_branches/ipp-20130419/ippconfig/recipes/filerules-simple.mdc	(revision 35420)
+++ branches/eam_branches/ipp-20130419/ippconfig/recipes/filerules-simple.mdc	(revision 35421)
@@ -88,6 +88,6 @@
 PSWARP.VARIANCE           INPUT    @FILES        FPA        VARIANCE
 PSWARP.MASK               INPUT    @FILES        FPA        MASK
-PSWARP.SKYCELL            INPUT    @FILES        FPA        IMAGE     
-PSWARP.ASTROM             INPUT    @FILES        FPA        CMF
+PSWARP.SKYCELL            INPUT    @FILES        FPA        WCS
+PSWARP.ASTROM             INPUT    @FILES        FPA        WCS
 PSWARP.BKGMODEL		  INPUT	   @FILES	 CHIP	    IMAGE
 
Index: branches/eam_branches/ipp-20130419/ippconfig/recipes/filerules-split.mdc
===================================================================
--- branches/eam_branches/ipp-20130419/ippconfig/recipes/filerules-split.mdc	(revision 35420)
+++ branches/eam_branches/ipp-20130419/ippconfig/recipes/filerules-split.mdc	(revision 35421)
@@ -106,6 +106,8 @@
 PSWARP.VARIANCE           INPUT    @FILES        CHIP       VARIANCE
 PSWARP.MASK               INPUT    @FILES        CHIP       MASK
-PSWARP.SKYCELL            INPUT    @FILES        FPA        IMAGE
-PSWARP.ASTROM             INPUT    @FILES        CHIP       CMF
+PSWARP.SKYCELL            INPUT    @FILES        CHIP       WCS
+PSWARP.ASTROM             INPUT    @FILES        CHIP       WCS
+#PSWARP.SKYCELL            INPUT    @FILES        CHIP       CMF
+#PSWARP.ASTROM             INPUT    @FILES        CHIP       CMF
 PSWARP.BKGMODEL		  INPUT	   @FILES	 CHIP	    IMAGE
                           
Index: branches/eam_branches/ipp-20130419/ippconfig/recipes/psphot.config
===================================================================
--- branches/eam_branches/ipp-20130419/ippconfig/recipes/psphot.config	(revision 35420)
+++ branches/eam_branches/ipp-20130419/ippconfig/recipes/psphot.config	(revision 35421)
@@ -317,4 +317,5 @@
 TEST_FIT_X                          F32   NAN
 TEST_FIT_Y                          F32   NAN
+TEST_FIT_CONVOLVED		    BOOL  FALSE
 
 TEST_FIT_PAR0                       F32   NAN
Index: branches/eam_branches/ipp-20130419/ppImage/src/ppImageParseCamera.c
===================================================================
--- branches/eam_branches/ipp-20130419/ppImage/src/ppImageParseCamera.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/ppImage/src/ppImageParseCamera.c	(revision 35421)
@@ -22,28 +22,4 @@
     ppImageOptions *options = ppImageOptionsParse(config);
 
-    // parse the header to extract out whether this OTA has video cells.
-    // CZW: 2012-05-01 I'm somewhat ashamed of what needs to be done to get to the header. There has to be a simpler way, right?
-/*     pmFPAview *view = pmFPAviewAlloc(0);// View for level of interest */
-/*     pmChip *chip;                       // Chip from FPA */
-/*     while ((chip = pmFPAviewNextChip(view, input->fpa, 1)) != NULL) { */
-/*       if (!chip->process || !chip->file_exists) { */
-/* 	continue; */
-/*       } */
-/* /\*       if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { *\/ */
-/* /\* 	continue; *\/ */
-/* /\*       } *\/ */
-/*       psWarning("VIDEO: %d %d %d\n",(int) options->hasVideo,(int) options->useVideoDark, (int) options->useVideoMask); */
-/*       if (psMetadataLookupStr(NULL,chip->hdu->header,"CELLMODE")) { */
-/* 	psWarning("VIDEO: %d %d %d\n",(int) options->hasVideo,(int) options->useVideoDark, (int) options->useVideoMask); */
-/* 	char *Vptr = strchr(psMetadataLookupStr(NULL,chip->hdu->header,"CELLMODE"),'V'); */
-/* 	if (Vptr) { */
-/* 	  options->hasVideo = true; */
-/* 	  psWarning("VIDEO: %d %d %d\n",(int) options->hasVideo,(int) options->useVideoDark, (int) options->useVideoMask); */
-/* 	} */
-/*       } */
-/*     } */
-/*     pmFPAviewReset(view); */
-/*     psFree(view); */
-    
     // the following are defined from the argument list, if given,
     // otherwise they revert to the config information
Index: branches/eam_branches/ipp-20130419/ppStack/src/ppStackCamera.c
===================================================================
--- branches/eam_branches/ipp-20130419/ppStack/src/ppStackCamera.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/ppStack/src/ppStackCamera.c	(revision 35421)
@@ -47,6 +47,5 @@
     }
     bool convolve = psMetadataLookupBool(NULL, recipe, "CONVOLVE"); // Convolve images before stack?
-    bool doBackground = psMetadataLookupBool(NULL, recipe, "BACKGROUND.MODEL");
-    //    fprintf(stderr,"ppSC: %d\n",doBackground);    
+
     psArray *runImages = pmFPAfileDefineMultipleFromRun(&status, NULL, config,
                                                         "PPSTACK.INPUT"); // Input images from previous run
@@ -218,36 +217,19 @@
 
 	    // Grab bkgmodel information here
-	    
-	    //	    if (doBackground) {
-	      if ((!bkgmodel) || (strlen(bkgmodel) == 0)) {
-		// We have no background models.
-		//		fprintf(stderr,"No backgrounds specified, resettting recipe value.\n");
-		doBackground = false;
-		psMetadataAddBool(recipe, PS_LIST_TAIL, "BACKGROUND.MODEL", PS_META_REPLACE,
-				  "Do photometry on stacked image?", false);
-
+	    if ((!bkgmodel) || (strlen(bkgmodel) == 0)) {
+	      // We have no background models.
+	      psMetadataAddBool(recipe, PS_LIST_TAIL, "BACKGROUND.MODEL", PS_META_REPLACE, "Do photometry on stacked image?", false);
+	    } else {
+	      pmFPAfile *inputBKG = defineFile(config,NULL,"PPSTACK.INPUT.BKGMODEL",bkgmodel, PM_FPA_FILE_IMAGE);
+	      if (!inputBKG) {
+		psMetadataAddBool(recipe, PS_LIST_TAIL, "BACKGROUND.MODEL", PS_META_REPLACE, "Do photometry on stacked image?", false);
+
+#if (0)
+		psError(psErrorCodeLast(), false,
+			"Unable to define file from bkgmodel %d (%s)",i,bkgmodel);
+		return(false);
+#endif
 	      }
-	      else {
-		pmFPAfile *inputBKG = defineFile(config,NULL,"PPSTACK.INPUT.BKGMODEL",bkgmodel,
-						 PM_FPA_FILE_IMAGE);
-		if (!inputBKG) {
-		  // We failed to generate an pmFPAfile, so disable the background construction and continue.
-		  //		  fprintf(stderr,"No backgrounds specified, resettting recipe value.\n");
-		  doBackground = false;
-		  psMetadataAddBool(recipe, PS_LIST_TAIL, "BACKGROUND.MODEL", PS_META_REPLACE,
-				    "Do photometry on stacked image?", false);
-
-#if (0)
-		  psError(psErrorCodeLast(), false,
-			  "Unable to define file from bkgmodel %d (%s)",i,bkgmodel);
-		  return(false);
-#endif
-		}
-	      }// End bkgmodel
-	      //	    }
-
-
-	    
-	    
+	    } // End bkgmodel
             i++;
         }
Index: branches/eam_branches/ipp-20130419/psLib/src/math/psEllipse.c
===================================================================
--- branches/eam_branches/ipp-20130419/psLib/src/math/psEllipse.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psLib/src/math/psEllipse.c	(revision 35421)
@@ -155,4 +155,5 @@
 
 // ellipse rotation (major, minor, theta) -> (sx, sy, sxy)
+// theta is postive rotation of major axis away from x-axis
 psEllipseShape psEllipseAxesToShape(psEllipseAxes axes)
 {
Index: branches/eam_branches/ipp-20130419/psModules/src/astrom/pmAstrometryUtils.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/astrom/pmAstrometryUtils.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/astrom/pmAstrometryUtils.c	(revision 35421)
@@ -23,4 +23,7 @@
 #include "pmAstrometryUtils.h"
 
+// this is used by the test output block
+static int Nout = 0;
+
 // given a 2D transformation -- L(x,y),M(x,y) -- find the coordinates x,y
 // for which L,M = 0,0. tol is the allowed error on x,y.
@@ -33,4 +36,20 @@
     double Xo = (trans->y->coeff[0][0]*trans->x->coeff[0][1] - trans->x->coeff[0][0]*trans->y->coeff[0][1])/R;
     double Yo = (trans->x->coeff[0][0]*trans->y->coeff[1][0] - trans->y->coeff[0][0]*trans->x->coeff[1][0])/R;
+
+    if (0) {
+      // this is a test output block, not used in normal operations
+      char filename[64];
+      snprintf (filename, 64, "trans.%03d.md", Nout);
+      FILE *f = fopen (filename, "w");
+
+      psMetadata *md = psMetadataAlloc();
+
+      psPolynomial2DtoMetadata (md, trans->x, "X");
+      psPolynomial2DtoMetadata (md, trans->y, "Y");
+      psMetadataConfigPrint (f, md);
+      psFree (md);
+      fclose (f);
+      Nout ++;
+    }
 
     // iterate to actual solution: requires small non-linear terms
@@ -52,11 +71,13 @@
         for (int i = 0; (dPos > tol) && (i < 20); i++) {
             // NOTE: order for Alpha is: [y][x]
+            // original Alpha->data.F32[1][0] = psPolynomial2DEval (XdY, Xo, Yo);
+            // original Alpha->data.F32[0][1] = psPolynomial2DEval (YdX, Xo, Yo);
             Alpha->data.F32[0][0] = psPolynomial2DEval (XdX, Xo, Yo);
-            Alpha->data.F32[1][0] = psPolynomial2DEval (XdY, Xo, Yo);
-            Alpha->data.F32[0][1] = psPolynomial2DEval (YdX, Xo, Yo);
+            Alpha->data.F32[0][1] = psPolynomial2DEval (XdY, Xo, Yo);
+            Alpha->data.F32[1][0] = psPolynomial2DEval (YdX, Xo, Yo);
             Alpha->data.F32[1][1] = psPolynomial2DEval (YdY, Xo, Yo);
 
-            Beta->data.F32[0] = psPolynomial2DEval (trans->x, Xo, Yo);
-            Beta->data.F32[1] = psPolynomial2DEval (trans->y, Xo, Yo);
+            Beta->data.F32[0] = -1.0 * psPolynomial2DEval (trans->x, Xo, Yo);
+            Beta->data.F32[1] = -1.0 * psPolynomial2DEval (trans->y, Xo, Yo);
 
             if (!psMatrixGJSolve (Alpha, Beta)) {
@@ -71,8 +92,8 @@
 	    }
 
-            Xo -= Beta->data.F32[0];
-            Yo -= Beta->data.F32[1];
+            Xo += Beta->data.F32[0];
+            Yo += Beta->data.F32[1];
             dPos = hypot(Beta->data.F32[0], Beta->data.F32[1]);
-
+	    psTrace ("psastro", 5, "i: %d, Xo,Yo : %f %f  dX, dY: %f %f dPos: %f\n", i, Xo, Yo, Beta->data.F32[0], Beta->data.F32[1], dPos);
         }
         psFree (Alpha);
Index: branches/eam_branches/ipp-20130419/psModules/src/camera/pmFPAMaskWeight.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/camera/pmFPAMaskWeight.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/camera/pmFPAMaskWeight.c	(revision 35421)
@@ -301,6 +301,8 @@
     psRegion *trimsec = psMetadataLookupPtr(&mdok, cell->concepts, "CELL.TRIMSEC"); // Trim section
     if (!mdok || psRegionIsNaN(*trimsec)) {
-        psError(PS_ERR_IO, true, "CELL.TRIMSEC is not set --- unable to set variance.\n");
-        return false;
+      // if trimsec is not defined, use the full image
+      trimsec = psRegionAlloc(0,0,0,0);
+      // psError(PS_ERR_IO, true, "CELL.TRIMSEC is not set --- unable to set variance.\n");
+      // return false;
     }
 
Index: branches/eam_branches/ipp-20130419/psModules/src/camera/pmFPAfileDefine.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/camera/pmFPAfileDefine.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/camera/pmFPAfileDefine.c	(revision 35421)
@@ -446,7 +446,131 @@
 }
 
+// given a filename, convert to UNIX namespace and read the PHU 
+psMetadata *readPHUfromFilename (char *filename, pmConfig *config) {
+
+    // Need to generate an FPA
+    psString realName = pmConfigConvertFilename(filename, config, false, false);
+    if (!realName) {
+	psError(psErrorCodeLast(), false, "Failed to convert file name %s", filename);
+	return NULL;
+    }
+
+    // load the header of the first image
+    // EXTWORD (fits->extword) is not relevant to the PHU
+    psFits *fits = psFitsOpen(realName, "r"); // FITS file
+    if (!fits) {
+	psError(psErrorCodeLast(), false, "Failed to open file %s", realName);
+	psFree(realName);
+	return NULL;
+    }
+
+    psMetadata *phu = psFitsReadHeader (NULL, fits); // Primary header
+    if (!phu) {
+	psError(psErrorCodeLast(), false, "Failed to read file header %s", realName);
+	psFree(realName);
+	return NULL;
+    }
+
+    if (!psFitsClose(fits)) {
+	psError(psErrorCodeLast(), false, "Failed to close file %s", realName);
+	psFree(realName);
+	psFree(phu);
+	return NULL;
+    }
+
+    return phu;
+}
+
+// this this function wants to return:
+// pmFPA, PHU, fileLevel, outConfig
+// camera, cameraName, formatName
+typedef struct {
+    pmFPA *fpa;
+    psMetadata *phu;
+    psMetadata *format;
+    pmFPALevel fileLevel;
+    psString cameraName;
+    psString formatName;
+} pmFPAfromFilenameOutput;
+
+// for the given filename, read PHU and determine camera format; build an FPA for the file
+bool pmFPAfromFilename (pmFPAfromFilenameOutput *output, pmConfig **outConfig, pmConfig *sysConfig, char *filename){
+
+    // Need to generate an FPA
+    psMetadata *phu = readPHUfromFilename (filename, sysConfig);
+    if (!phu) {
+	psError(psErrorCodeLast(), false, "Failed to read PHU for %s", filename);
+	return false;
+    }
+
+    // if we expect the loaded FPA to differ in configuration from the current system configuration
+    // generate an output config for this FPA
+    pmConfig *config = NULL;
+    if (outConfig) {
+	config = pmConfigAlloc();
+	config->user = psMemIncrRefCounter(sysConfig->user);
+	config->system = psMemIncrRefCounter(sysConfig->system);
+
+	psFree (config->files);
+	config->files = psMemIncrRefCounter(sysConfig->files);
+	psFree (config->arguments);
+	config->arguments = psMemIncrRefCounter(sysConfig->arguments);
+
+	*outConfig = config;
+    } else {
+	config = sysConfig;
+    }
+
+    // values which are returned to calling function
+    psString formatName = NULL;	// Name of camera format
+    psString cameraName = NULL;	// Name of camera
+    psMetadata *camera = NULL;	// Camera configuration
+
+    // Determine the current format from the header; determine camera if not specified already.
+    psMetadata *format = pmConfigCameraFormatFromHeader(&camera, &cameraName, &formatName, config, phu, true);
+    if (!format) {
+	psError(psErrorCodeLast(), false, "Failed to determine camera format for %s", filename);
+	psFree(camera);
+	psFree(formatName);
+	psFree(phu);
+	return false;
+    }
+
+    pmFPALevel fileLevel = pmFPAPHULevel(format);
+    if (fileLevel == PM_FPA_LEVEL_NONE) {
+	psError(PM_ERR_CONFIG, true, "Unable to determine file level for %s", filename);
+	psFree(camera);
+	psFree(formatName);
+	psFree(phu);
+	return false;
+    }
+
+    // build the template fpa, set up the basic view
+    // we supply the metaCamera name (if NULL, baseCamera name is used)
+    pmFPA *fpa = pmFPAConstruct(camera, cameraName);
+    psFree(camera);
+
+    if (!fpa) {
+	psError(psErrorCodeLast(), false, "Failed to construct FPA from %s", filename);
+	psFree(formatName);
+	psFree(format);
+	psFree(phu);
+	return NULL;
+    }
+
+    output->fpa = fpa;
+    output->phu = phu;
+    output->format = format;
+    output->fileLevel = fileLevel;
+    output->cameraName = cameraName;
+    output->formatName = formatName;
+
+    return true;
+
+}
 
 /// Define a file from an array of filenames
-static pmFPAfile *fpaFileDefineFromArray(pmConfig *config, // Configuration
+static pmFPAfile *fpaFileDefineFromArray(pmConfig **outConfig, // output configuration
+					 pmConfig *sysConfig, // global configuration
                                          pmFPAfile *bind, // File to bind to, or NULL
                                          const char *name, // Name of file
@@ -454,5 +578,5 @@
     )
 {
-    PS_ASSERT_PTR_NON_NULL(config, NULL);
+    PS_ASSERT_PTR_NON_NULL(sysConfig, NULL);
     PS_ASSERT_STRING_NON_EMPTY(name, NULL);
 
@@ -463,4 +587,5 @@
     pmFPALevel fileLevel = PM_FPA_LEVEL_NONE; // Level for files
     psMetadata *phu = NULL;             // Primary header
+
     if (bind) {
         // Use the FPA we're binding to
@@ -468,67 +593,17 @@
         fileLevel = bind->fileLevel;
     } else {
-        // Need to generate an FPA
-        psString realName = pmConfigConvertFilename(filenames->data[0], config, false, false);
-        if (!realName) {
-            psError(psErrorCodeLast(), false, "Failed to convert file name %s", (char *)filenames->data[0]);
-            return NULL;
-        }
-
-        // load the header of the first image
-        // EXTWORD (fits->extword) is not relevant to the PHU
-        psFits *fits = psFitsOpen(realName, "r"); // FITS file
-        if (!fits) {
-            psError(psErrorCodeLast(), false, "Failed to open file %s", realName);
-            psFree(realName);
-            return NULL;
-        }
-        phu = psFitsReadHeader (NULL, fits); // Primary header
-        if (!phu) {
-            psError(psErrorCodeLast(), false, "Failed to read file header %s", realName);
-            psFree(realName);
-            return NULL;
-        }
-        if (!psFitsClose(fits)) {
-            psError(psErrorCodeLast(), false, "Failed to close file %s", realName);
-            psFree(realName);
-            return NULL;
-        }
-
-        // Determine the current format from the header; determine camera if not specified already.
-        psMetadata *camera = NULL;      // Camera configuration
-        format = pmConfigCameraFormatFromHeader(&camera, &cameraName, &formatName, config, phu, true);
-        if (!format) {
-            psError(psErrorCodeLast(), false, "Failed to determine camera format for %s", realName);
-            psFree(camera);
-            psFree(formatName);
-            psFree(realName);
-            psFree(phu);
-            return NULL;
-        }
-
-        fileLevel = pmFPAPHULevel(format);
-        if (fileLevel == PM_FPA_LEVEL_NONE) {
-            psError(PM_ERR_CONFIG, true, "Unable to determine file level for %s", realName);
-            psFree(camera);
-            psFree(formatName);
-            psFree(realName);
-            psFree(phu);
-            return NULL;
-        }
-
-        // build the template fpa, set up the basic view
-        // XXX do we want this to be the baseCamera name or the metaCamera name?
-        fpa = pmFPAConstruct(camera, cameraName);
-        psFree(camera);
-        if (!fpa) {
-            psError(psErrorCodeLast(), false, "Failed to construct FPA from %s", realName);
-            psFree(formatName);
-            psFree(realName);
-            psFree(format);
-            psFree(phu);
-            return NULL;
-        }
-        psFree(realName);
-    }
+	pmFPAfromFilenameOutput output;
+	if (!pmFPAfromFilename (&output, outConfig, sysConfig, filenames->data[0])) {
+	    return NULL;
+	}
+	fpa = output.fpa;
+	phu = output.phu;
+	format = output.format;
+	fileLevel = output.fileLevel;
+	cameraName = output.cameraName;
+	formatName = output.formatName;
+    }
+
+    pmConfig *config = outConfig ? *outConfig : sysConfig;
 
     // load the given filerule (from config->camera) and bind it to the fpa
@@ -561,27 +636,9 @@
         // Check that the file corresponds to the same camera and format
         if (!phu) {
-            psString realName = pmConfigConvertFilename(filenames->data[i], config, false, false);
-            if (!realName) {
-                psError(psErrorCodeLast(), false, "Failed to convert file name %s", (char*)filenames->data[i]);
+	    phu = readPHUfromFilename (filenames->data[i], config);
+            if (!phu) {
+                psError(psErrorCodeLast(), false, "Failed to read PHU for %s", (char *)filenames->data[i]);
                 return NULL;
             }
-            psFits *fits = psFitsOpen(realName, "r"); // FITS file
-            if (!fits) {
-                psError(psErrorCodeLast(), false, "Failed to open file %s", realName);
-                psFree(realName);
-                return NULL;
-            }
-            phu = psFitsReadHeader(NULL, fits);
-            if (!psFitsClose(fits)) {
-                psError(psErrorCodeLast(), false, "Failed to close file %s", realName);
-                psFree(realName);
-                return NULL;
-            }
-            if (!phu) {
-                psError(psErrorCodeLast(), false, "Failed to read file header %s", realName);
-                psFree(realName);
-                return NULL;
-            }
-            psFree(realName);
         }
 
@@ -651,7 +708,6 @@
 }
 
-
-pmFPAfile *pmFPAfileDefineFromArgs(bool *success, pmConfig *config,
-                                   const char *filename, const char *argname)
+// find the file associated with the argname & generate a pmFPAfile for it based on the filerule
+pmFPAfile *pmFPAfileDefineFromArgs(bool *success, pmConfig *config, const char *filename, const char *argname)
 {
     PS_ASSERT_PTR_NON_NULL(config, NULL);
@@ -676,5 +732,5 @@
     }
 
-    pmFPAfile *file = fpaFileDefineFromArray(config, NULL, filename, filenames); // File of interest
+    pmFPAfile *file = fpaFileDefineFromArray(NULL, config, NULL, filename, filenames); // File of interest
 
     if (success) {
@@ -685,6 +741,6 @@
 }
 
-pmFPAfile *pmFPAfileBindFromArgs(bool *success, pmFPAfile *input, pmConfig *config,
-                                 const char *filename, const char *argname)
+// find the file associated with the argname & bind it to the given pmFPAfile for it based on the filerule
+pmFPAfile *pmFPAfileBindFromArgs(bool *success, pmFPAfile *input, pmConfig *config, const char *filename, const char *argname)
 {
     PS_ASSERT_PTR_NON_NULL(input, NULL);
@@ -710,5 +766,5 @@
     }
 
-    pmFPAfile *file = fpaFileDefineFromArray(config, input, filename, filenames); // File of interest
+    pmFPAfile *file = fpaFileDefineFromArray(NULL, config, input, filename, filenames); // File of interest
 
     if (success) {
@@ -719,6 +775,6 @@
 }
 
-pmFPAfile *pmFPAfileDefineSingleFromArgs(bool *success, pmConfig *config, const char *filename,
-                                         const char *argname, int entry)
+// find the specific file associated with the argname & generate a pmFPAfile for it based on the filerule
+pmFPAfile *pmFPAfileDefineSingleFromArgs(bool *success, pmConfig *config, const char *filename, const char *argname, int entry)
 {
     PS_ASSERT_PTR_NON_NULL(config, NULL);
@@ -746,5 +802,5 @@
     psArray *single = psArrayAlloc(1);  // Array of single filename of interest
     single->data[0] = psMemIncrRefCounter(filenames->data[entry]);
-    pmFPAfile *file = fpaFileDefineFromArray(config, NULL, filename, single); // File of interest
+    pmFPAfile *file = fpaFileDefineFromArray(NULL, config, NULL, filename, single); // File of interest
     psFree(single);
 
@@ -756,4 +812,5 @@
 }
 
+// find the file in the config list & generate a pmFPAfile for it based on the filerule
 pmFPAfile *pmFPAfileDefineFromRun(bool *success, pmFPAfile *bind, pmConfig *config, const char *filename)
 {
@@ -769,5 +826,5 @@
     }
 
-    pmFPAfile *file = fpaFileDefineFromArray(config, bind, filename, filenames); // File of interest
+    pmFPAfile *file = fpaFileDefineFromArray(NULL, config, bind, filename, filenames); // File of interest
     psFree(filenames);
 
@@ -779,4 +836,5 @@
 }
 
+// find the files in the config list & generate an array of pmFPAfiles for them based on the filerule
 psArray *pmFPAfileDefineMultipleFromRun(bool *success, psArray *bind, pmConfig *config, const char *filename)
 {
@@ -808,5 +866,5 @@
         dummy->data[0] = files->data[i];
         pmFPAfile *bindFile = bind ? bind->data[i] : NULL; // File to which to bind
-        files->data[i] = psMemIncrRefCounter(fpaFileDefineFromArray(config, bindFile, filename, dummy));
+        files->data[i] = psMemIncrRefCounter(fpaFileDefineFromArray(NULL, config, bindFile, filename, dummy));
         if (!files->data[i]) {
             psError(psErrorCodeLast(), false, "Unable to define file %s %d", filename, i);
@@ -823,4 +881,38 @@
 
     return files;
+}
+
+// find the file associated with the argname & generate a pmFPAfile for it based on the filerule
+pmFPAfile *pmFPAfileDefineNewConfig(bool *success, pmConfig **outConfig, pmConfig *sysConfig, const char *filename, const char *argname)
+{
+    PS_ASSERT_PTR_NON_NULL(outConfig, NULL);
+    PS_ASSERT_PTR_NON_NULL(sysConfig, NULL);
+    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
+    PS_ASSERT_STRING_NON_EMPTY(argname, NULL);
+
+    // Search the argument data for the named fileset (argname)
+    bool status;                        // Status of MD lookup
+    psArray *filenames = psMetadataLookupPtr(&status, sysConfig->arguments, argname); // Filenames for file
+    if (!status) {
+        if (success) {
+            *success = true;
+        }
+        return NULL;
+    }
+    if (filenames->n == 0) {
+        psError(PM_ERR_CONFIG, true, "No files in array in %s in arguments", argname);
+        if (success) {
+            *success = false;
+        }
+        return NULL;
+    }
+
+    pmFPAfile *file = fpaFileDefineFromArray(outConfig, sysConfig, NULL, filename, filenames); // File of interest
+
+    if (success) {
+        *success = file ? true : false;
+    }
+
+    return file;
 }
 
Index: branches/eam_branches/ipp-20130419/psModules/src/camera/pmFPAfileDefine.h
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/camera/pmFPAfileDefine.h	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/camera/pmFPAfileDefine.h	(revision 35421)
@@ -81,4 +81,14 @@
     const char *filename                ///< Name of file
     );
+
+// find the file associated with the argname & generate a pmFPAfile for it based on the filerule
+pmFPAfile *pmFPAfileDefineNewConfig(
+    bool *success,                      ///< Found files?
+    pmConfig **outConfig, 		///< output configuration for this file
+    pmConfig *sysConfig, 		///< existing system config info
+    const char *filename, 		///< name of filerule
+    const char *argname			///< argument entry
+    );
+
 
 // look for the given argname on the argument list.  find the give filename from the file rules
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_DEV.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_DEV.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_DEV.c	(revision 35421)
@@ -295,5 +295,5 @@
 // make an initial guess for parameters
 // 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters
-bool PM_MODEL_GUESS (pmModel *model, pmSource *source)
+bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
 {
     psF32 *PAR  = model->params->data.F32;
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_DEV.h
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_DEV.h	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_DEV.h	(revision 35421)
@@ -5,5 +5,5 @@
 psF32 pmModelFunc_DEV(psVector *deriv, const psVector *params, const psVector *pixcoord);
 bool pmModelLimits_DEV(psMinConstraintMode mode, int nParam, float *params, float *beta);
-bool pmModelGuess_DEV(pmModel *model, pmSource *source);
+bool pmModelGuess_DEV(pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal);
 psF64 pmModelFlux_DEV(const psVector *params);
 psF64 pmModelRadius_DEV(const psVector *params, psF64 flux);
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_EXP.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_EXP.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_EXP.c	(revision 35421)
@@ -287,5 +287,5 @@
 // make an initial guess for parameters
 // 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters
-bool PM_MODEL_GUESS (pmModel *model, pmSource *source)
+bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
 {
     psF32 *PAR  = model->params->data.F32;
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_EXP.h
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_EXP.h	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_EXP.h	(revision 35421)
@@ -5,5 +5,5 @@
 psF32 pmModelFunc_EXP(psVector *deriv, const psVector *params, const psVector *pixcoord);
 bool pmModelLimits_EXP(psMinConstraintMode mode, int nParam, float *params, float *beta);
-bool pmModelGuess_EXP(pmModel *model, pmSource *source);
+bool pmModelGuess_EXP(pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal);
 psF64 pmModelFlux_EXP(const psVector *params);
 psF64 pmModelRadius_EXP(const psVector *params, psF64 flux);
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_GAUSS.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_GAUSS.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_GAUSS.c	(revision 35421)
@@ -192,5 +192,5 @@
 // make an initial guess for parameters
 // 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters
-bool PM_MODEL_GUESS (pmModel *model, pmSource *source)
+bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
 {
     psF32 *PAR  = model->params->data.F32;
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_GAUSS.h
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_GAUSS.h	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_GAUSS.h	(revision 35421)
@@ -5,5 +5,5 @@
 psF32 pmModelFunc_GAUSS(psVector *deriv, const psVector *params, const psVector *pixcoord);
 bool pmModelLimits_GAUSS(psMinConstraintMode mode, int nParam, float *params, float *beta);
-bool pmModelGuess_GAUSS(pmModel *model, pmSource *source);
+bool pmModelGuess_GAUSS(pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal);
 psF64 pmModelFlux_GAUSS(const psVector *params);
 psF64 pmModelRadius_GAUSS(const psVector *params, psF64 flux);
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_PGAUSS.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_PGAUSS.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_PGAUSS.c	(revision 35421)
@@ -193,5 +193,5 @@
 // make an initial guess for parameters
 // 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters
-bool PM_MODEL_GUESS (pmModel *model, pmSource *source)
+bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
 {
     psF32 *PAR  = model->params->data.F32;
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_PGAUSS.h
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_PGAUSS.h	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_PGAUSS.h	(revision 35421)
@@ -5,5 +5,5 @@
 psF32 pmModelFunc_PGAUSS(psVector *deriv, const psVector *params, const psVector *pixcoord);
 bool pmModelLimits_PGAUSS(psMinConstraintMode mode, int nParam, float *params, float *beta);
-bool pmModelGuess_PGAUSS(pmModel *model, pmSource *source);
+bool pmModelGuess_PGAUSS(pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal);
 psF64 pmModelFlux_PGAUSS(const psVector *params);
 psF64 pmModelRadius_PGAUSS(const psVector *params, psF64 flux);
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_PS1_V1.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_PS1_V1.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_PS1_V1.c	(revision 35421)
@@ -212,5 +212,5 @@
 // make an initial guess for parameters
 // 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters
-bool PM_MODEL_GUESS (pmModel *model, pmSource *source)
+bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
 {
     psF32 *PAR  = model->params->data.F32;
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_PS1_V1.h
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_PS1_V1.h	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_PS1_V1.h	(revision 35421)
@@ -5,5 +5,5 @@
 psF32 pmModelFunc_PS1_V1(psVector *deriv, const psVector *params, const psVector *pixcoord);
 bool pmModelLimits_PS1_V1(psMinConstraintMode mode, int nParam, float *params, float *beta);
-bool pmModelGuess_PS1_V1(pmModel *model, pmSource *source);
+bool pmModelGuess_PS1_V1(pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal);
 psF64 pmModelFlux_PS1_V1(const psVector *params);
 psF64 pmModelRadius_PS1_V1(const psVector *params, psF64 flux);
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_QGAUSS.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_QGAUSS.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_QGAUSS.c	(revision 35421)
@@ -213,5 +213,5 @@
 // make an initial guess for parameters
 // 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters
-bool PM_MODEL_GUESS (pmModel *model, pmSource *source)
+bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
 {
     psF32 *PAR  = model->params->data.F32;
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_QGAUSS.h
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_QGAUSS.h	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_QGAUSS.h	(revision 35421)
@@ -5,5 +5,5 @@
 psF32 pmModelFunc_QGAUSS(psVector *deriv, const psVector *params, const psVector *pixcoord);
 bool pmModelLimits_QGAUSS(psMinConstraintMode mode, int nParam, float *params, float *beta);
-bool pmModelGuess_QGAUSS(pmModel *model, pmSource *source);
+bool pmModelGuess_QGAUSS(pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal);
 psF64 pmModelFlux_QGAUSS(const psVector *params);
 psF64 pmModelRadius_QGAUSS(const psVector *params, psF64 flux);
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_RGAUSS.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_RGAUSS.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_RGAUSS.c	(revision 35421)
@@ -202,5 +202,5 @@
 // make an initial guess for parameters
 // 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters
-bool PM_MODEL_GUESS (pmModel *model, pmSource *source)
+bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
 {
     psF32 *PAR  = model->params->data.F32;
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_RGAUSS.h
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_RGAUSS.h	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_RGAUSS.h	(revision 35421)
@@ -5,5 +5,5 @@
 psF32 pmModelFunc_RGAUSS(psVector *deriv, const psVector *params, const psVector *pixcoord);
 bool pmModelLimits_RGAUSS(psMinConstraintMode mode, int nParam, float *params, float *beta);
-bool pmModelGuess_RGAUSS(pmModel *model, pmSource *source);
+bool pmModelGuess_RGAUSS(pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal);
 psF64 pmModelFlux_RGAUSS(const psVector *params);
 psF64 pmModelRadius_RGAUSS(const psVector *params, psF64 flux);
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_SERSIC.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_SERSIC.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_SERSIC.c	(revision 35421)
@@ -307,5 +307,5 @@
 // make an initial guess for parameters
 // 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters
-bool PM_MODEL_GUESS (pmModel *model, pmSource *source)
+bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
 {
     pmMoments *moments = source->moments;
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_SERSIC.h
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_SERSIC.h	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_SERSIC.h	(revision 35421)
@@ -5,5 +5,5 @@
 psF32 pmModelFunc_SERSIC(psVector *deriv, const psVector *params, const psVector *pixcoord);
 bool pmModelLimits_SERSIC(psMinConstraintMode mode, int nParam, float *params, float *beta);
-bool pmModelGuess_SERSIC(pmModel *model, pmSource *source);
+bool pmModelGuess_SERSIC(pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal);
 psF64 pmModelFlux_SERSIC(const psVector *params);
 psF64 pmModelRadius_SERSIC(const psVector *params, psF64 flux);
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_TRAIL.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_TRAIL.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_TRAIL.c	(revision 35421)
@@ -168,4 +168,13 @@
         dPAR[PM_PAR_THETA]  = PAR[PM_PAR_I0] * dPdT;
         dPAR[PM_PAR_SIGMA]  = 0;	// we don't actually allow this to vary, so we do not need to calculate it
+
+	for (int i = 0; i < 7; i++) {
+	  if (isnan(dPAR[i])) {
+	    fprintf (stderr, "*");
+	  }
+	}
+    }
+    if (isnan(f)) {
+      fprintf (stderr, "!");
     }
     return(f);
@@ -228,7 +237,111 @@
 }
 
+# define NA 21
+# define NR 21
+static float flux[NA][NR];
+static float npix[NA][NR];
+
+bool pmTrailGetAngle (float *To, float *Io, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal, float sigma) {
+
+  float Xo, Yo;
+  if (!pmModelSetPosition(&Xo, &Yo, source)) return false;
+
+  psImage *image = source->pixels;
+  psImage *mask = source->maskObj;
+  psF32 **imData = image->data.F32;
+  psImageMaskType **mkData = mask->data.PS_TYPE_IMAGE_MASK_DATA;
+
+  // do a loop over the pixels, generating (dX,dY) dot (cos(theta),sin(theta))
+  int dP;
+  int dX = Xo - mask->col0;
+  dP = mask->numCols - dX;
+  int DX = PS_MAX(dP, dX);
+  int NX = mask->numCols;
+
+  int dY = Yo - mask->row0;
+  dP = mask->numRows - dY;
+  int DY = PS_MAX(dP, dY);
+  int NY = mask->numRows;
+
+  // just hard wire this for now...
+  float radius = 10.0;
+  float radius2 = PS_SQR(radius);
+
+  // we have an array of Angles x Radii
+  float dT = M_PI / NA;
+  for (int na = 0; na < NA; na++) {
+    memset (flux[na], 0, NR*sizeof(float));
+    memset (npix[na], 0, NR*sizeof(float));
+  }
+
+  // we skip any pixels [real or virtual] outside of the specified radius (nominally the aperture radius)
+  // ix and iy track pixels relative to the centroid
+  for (int ix = -DX; ix < DX + 1; ix++) {
+    if (ix > radius) continue;
+    int mx = ix + dX;
+    for (int iy = -DY; iy < DY + 1; iy++) {
+      if (iy > radius) continue;
+      if (ix*ix + iy*iy > radius2) continue;
+      int my = iy + dY;
+      
+      // include count only the unmasked pixels within the image area
+      if (mx < 0) continue;
+      if (my < 0) continue;
+      if (mx >= NX) continue;
+      if (my >= NY) continue;
+      
+      // count pixels which are masked only with bad pixels
+      if (mkData[my][mx] & maskVal)continue;
+
+      // we have defined NA to be 21
+      int na = 0;
+      for (float angle = 0.0; na < NA; angle += dT, na ++) {
+
+	// XXX optimization : pre-compute the angle sines and cosines
+	float Rad = (ix * cos(angle)) + (iy * sin(angle));
+	int nr = PS_MAX (PS_MIN (NR, Rad + 0.5*NR), 0);
+
+	flux[na][nr] += imData[my][mx];
+	npix[na][nr] ++;
+      }
+    }
+  }
+
+  // generate a psf model (with integral of 1.0)
+  float Ao = 1.0 / sqrt(2*M_PI) / sigma;
+  float psf[NR];
+  for (int nr = 0; nr < NR; nr++) {
+    psf[nr] = Ao*exp(-0.5*PS_SQR((nr - 0.5*NR)/sigma));
+  }
+
+  float fangle[NA];
+  for (int na = 0; na < NA; na++) {
+    float fpsf = 0.0;
+    for (int nr = 0; nr < NR; nr++) {
+      fpsf += psf[nr]*flux[na][nr];
+    }
+    fangle[na] = fpsf;
+    // fprintf (stderr, "fpsf: %f, theta = %f\n", fpsf, PS_DEG_RAD*dT*na);
+  }
+
+  float peak = fangle[0];
+  int pbin = 0;
+  for (int na = 0; na < NA; na++) {
+    if (fangle[na] > peak) {
+      peak = fangle[na];
+      pbin = na;
+    }
+  }
+
+  // result is peak, pbin -> angle
+  *To = dT * pbin;
+  *Io = peak * Ao;
+  
+  return true;
+}
+
 // make an initial guess for parameters
 // 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters
-bool PM_MODEL_GUESS (pmModel *model, pmSource *source)
+bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
 {
     psF32 *PAR  = model->params->data.F32;
@@ -260,4 +373,7 @@
     //else { size = psfAxes.major; }
 
+    float theta, peak;
+    pmTrailGetAngle (&theta, &peak, source, maskVal, markVal, psfAxes.major);
+
     // axes.major is a sigma in the major direction; scale to 
     PAR[PM_PAR_LENGTH] = 1.5*2.35*size; // a tophat of length L has L = 1.5 * 2.35 * sigma
@@ -266,7 +382,8 @@
 
     // set the model normalization
-    if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) {
-      return false;
-    }
+    // if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) {
+    //   return false;
+    // }
+    PAR[PM_PAR_I0] = peak;
 
     // set the model position
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_TRAIL.h
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_TRAIL.h	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/models/pmModel_TRAIL.h	(revision 35421)
@@ -5,5 +5,5 @@
 psF32 pmModelFunc_TRAIL(psVector *deriv, const psVector *params, const psVector *pixcoord);
 bool pmModelLimits_TRAIL(psMinConstraintMode mode, int nParam, float *params, float *beta);
-bool pmModelGuess_TRAIL(pmModel *model, pmSource *source);
+bool pmModelGuess_TRAIL(pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal);
 psF64 pmModelFlux_TRAIL(const psVector *params);
 psF64 pmModelRadius_TRAIL(const psVector *params, psF64 flux);
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/pmModelFuncs.h
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/pmModelFuncs.h	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/pmModelFuncs.h	(revision 35421)
@@ -107,5 +107,5 @@
 //  This function provides the model guess parameters based on the details of
 //  the given source.
-typedef bool (*pmModelGuessFunc)(pmModel *model, pmSource *source);
+typedef bool (*pmModelGuessFunc)(pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal);
 
 //  This function constructs the PSF model for the given source based on the
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/pmPSF.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/pmPSF.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/pmPSF.c	(revision 35421)
@@ -350,5 +350,7 @@
 	shape.sx  = modelPar[PM_PAR_SXX];
 	shape.sy  = modelPar[PM_PAR_SYY];
-	shape.sxy = modelPar[PM_PAR_SXY];
+	shape.sxy = modelPar[PM_PAR_SXY] / 2.0;
+	// XXX I *think* dividing by 2.0 is the right direction, but this 
+	// needs to be checked with a real test
     } else {
 	shape.sx  = modelPar[PM_PAR_SXX] / M_SQRT2;
@@ -392,5 +394,5 @@
 	modelPar[PM_PAR_SXX] = shape.sx;
 	modelPar[PM_PAR_SYY] = shape.sy;
-	modelPar[PM_PAR_SXY] = shape.sxy;
+	modelPar[PM_PAR_SXY] = shape.sxy; // XXX NEED factor of 2 here for correct angle conversion
     } else {
 	modelPar[PM_PAR_SXX] = shape.sx * M_SQRT2;
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/pmPSFtryFitEXT.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/pmPSFtryFitEXT.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/pmPSFtryFitEXT.c	(revision 35421)
@@ -83,5 +83,5 @@
         }
 
-        source->modelEXT = pmSourceModelGuess (source, options->type);
+        source->modelEXT = pmSourceModelGuess (source, options->type, maskVal, markVal);
         if (source->modelEXT == NULL) {
             psTrace ("psModules.objects", 4, "masking %d (%d,%d) : failed to generate model guess\n", i, source->peak->x, source->peak->y);
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceFitModel.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceFitModel.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceFitModel.c	(revision 35421)
@@ -75,5 +75,7 @@
     PS_ASSERT_PTR_NON_NULL(source->pixels, false);
     PS_ASSERT_PTR_NON_NULL(source->maskObj, false);
-    PS_ASSERT_PTR_NON_NULL(source->variance, false);
+
+    // XXX if variance is NULL, use pixels instead (wrong, but not badly wrong)
+    // PS_ASSERT_PTR_NON_NULL(source->variance, false);
 
     psBool fitStatus = true;
@@ -93,4 +95,7 @@
     float Xo = model->params->data.F32[PM_PAR_XPOS];
     float Yo = model->params->data.F32[PM_PAR_YPOS];
+
+    // if variance is NULL, we pretend pixels == variance
+    float **vWgt = source->variance ? source->variance->data.F32 : source->pixels->data.F32;
 
     // fill in the coordinate and value entries
@@ -103,15 +108,16 @@
             }
             // skip zero-variance points
-            if (source->variance->data.F32[i][j] == 0) {
+            if (vWgt[i][j] == 0) {
                 continue;
             }
             // skip nan values in image
             if (!isfinite(source->pixels->data.F32[i][j])) {
+		fprintf (stderr, "WARNING: unmasked nan in image : %x vs %x\n", source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[i][j], maskVal);
                 continue;
             }
 
             // skip nan values in image
-            if (!isfinite(source->variance->data.F32[i][j])) {
-		fprintf (stderr, "impossible! %x vs %x\n", source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[i][j], maskVal);
+            if (!isfinite(vWgt[i][j])) {
+		fprintf (stderr, "WARNING: unmasked nan in variance : %x vs %x\n", source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[i][j], maskVal);
 		continue;
             }
@@ -140,5 +146,5 @@
             // source sky variance
             if (options->poissonErrors) {
-                yErr->data.F32[nPix] = 1.0 / source->variance->data.F32[i][j];
+                yErr->data.F32[nPix] = 1.0 / vWgt[i][j];
             } else {
                 yErr->data.F32[nPix] = 1.0 / options->weight;
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceFitPCM.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceFitPCM.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceFitPCM.c	(revision 35421)
@@ -145,5 +145,5 @@
 bool pmSourceModelGuessPCM (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal) {
 
-    if (!pcm->modelConv->modelGuess(pcm->modelConv, source)) {
+  if (!pcm->modelConv->modelGuess(pcm->modelConv, source, maskVal, markVal)) {
 	return false;
     }
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceIO.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceIO.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceIO.c	(revision 35421)
@@ -980,4 +980,5 @@
 	    return false;
         }
+
         // if this is not TRUE, the output files only contain the psf measurements.
         bool XSRC_OUTPUT = psMetadataLookupBool(&status, recipe, "EXTENDED_SOURCE_ANALYSIS");
@@ -1005,4 +1006,15 @@
             hdu->header = psFitsReadHeader (NULL, file->fits);
         }
+
+	// "WCS" is CMF without detected objects
+	if (file->type == PM_FPA_FILE_WCS) {
+	  psTrace("psModules.objects", 6, "read CMF table from %s : %s : %s", file->filename, headname, dataname);
+	  psFree (headname);
+	  psFree (dataname);
+	  psFree (deteffname);
+	  break;
+	}
+
+	// EXTDATA is the PSF data associated with this image header
 
         // we need to find the corresponding table EXTNAME.
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceMoments.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceMoments.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceMoments.c	(revision 35421)
@@ -151,5 +151,5 @@
 
 	float *vPix = source->pixels->data.F32[row];
-	float *vWgt = source->variance->data.F32[row];
+	float *vWgt = source->variance ? source->variance->data.F32[row] : source->pixels->data.F32[row];
 
 	psImageMaskType  *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];
@@ -266,6 +266,6 @@
 
     float **vPix = source->pixels->data.F32;
-    float **vWgt = source->variance->data.F32;
-    psImageMaskType  **vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA;
+    float **vWgt = source->variance ? source->variance->data.F32 : source->pixels->data.F32;
+    psImageMaskType **vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA;
 
     float RF = 0.0;
@@ -467,5 +467,5 @@
 
 	float *vPix = source->pixels->data.F32[row];
-	float *vWgt = source->variance->data.F32[row];
+	float *vWgt = source->variance ? source->variance->data.F32[row] : source->pixels->data.F32[row];
 
 	psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceSky.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceSky.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceSky.c	(revision 35421)
@@ -122,8 +122,13 @@
     psTrace("psModules.objects", 10, "---- %s() begin ----\n", __func__);
     PS_ASSERT_PTR_NON_NULL(source, false);
-    PS_ASSERT_IMAGE_NON_NULL(source->variance, false);
     PS_ASSERT_IMAGE_NON_NULL(source->maskObj, false);
     PS_ASSERT_PTR_NON_NULL(source->peak, false);
     PS_ASSERT_INT_POSITIVE(Radius, false);
+
+    if (source->variance == NULL) {
+      // XXX this is needed so psphotCheckRadiusPSF has a real value
+      source->moments->dSky = 1.0;
+      return true;
+    }
 
     // maskVal is used to test for rejected pixels, and must include markVal
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceUtils.c
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceUtils.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceUtils.c	(revision 35421)
@@ -46,8 +46,8 @@
 
 /******************************************************************************
-    pmSourceModelGuess(source, model): This function allocates a new
-    pmModel structure based on the given modelType specified in the argument list.
-    The corresponding pmModelGuess function is returned, and used to
-    supply the values of the params array in the pmModel structure.
+    pmSourceModelGuess(source, model, maskVal, markVal): This function allocates a new
+    pmModel structure based on the given modelType specified in the argument list.  The
+    corresponding pmModelGuess function is returned, and used to supply the values of the
+    params array in the pmModel structure.
  
     XXX: Many parameters are based on the src->moments structure, which is in
@@ -55,6 +55,5 @@
     functions will be in image, not subImage coords.  Remember this.
 *****************************************************************************/
-pmModel *pmSourceModelGuess(pmSource *source,
-                            pmModelType modelType)
+pmModel *pmSourceModelGuess(pmSource *source, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal)
 {
     psTrace("psModules.objects", 10, "---- %s() begin ----\n", __func__);
@@ -65,5 +64,5 @@
     pmModel *model = pmModelAlloc(modelType);
 
-    if (!model->modelGuess(model, source)) {
+    if (!model->modelGuess(model, source, maskVal, markVal)) {
 	psFree (model);
 	return NULL;
Index: branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceUtils.h
===================================================================
--- branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceUtils.h	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psModules/src/objects/pmSourceUtils.h	(revision 35421)
@@ -27,5 +27,7 @@
 pmModel *pmSourceModelGuess(
     pmSource *source,   ///< The input pmSource
-    pmModelType model   ///< The type of model to be created.
+    pmModelType model,   ///< The type of model to be created.
+    psImageMaskType maskVal, 
+    psImageMaskType markVal
 );
 
Index: branches/eam_branches/ipp-20130419/psphot/src/models/pmModel_STRAIL.c
===================================================================
--- branches/eam_branches/ipp-20130419/psphot/src/models/pmModel_STRAIL.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psphot/src/models/pmModel_STRAIL.c	(revision 35421)
@@ -475,5 +475,5 @@
 
 //fixed I think...no good way of guessing as far as I can tell
-bool PM_MODEL_GUESS (pmModel *model, pmSource *source)
+bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
 {
     pmMoments *Smoments = source->moments;
Index: branches/eam_branches/ipp-20130419/psphot/src/models/pmModel_TEST1.c
===================================================================
--- branches/eam_branches/ipp-20130419/psphot/src/models/pmModel_TEST1.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psphot/src/models/pmModel_TEST1.c	(revision 35421)
@@ -123,5 +123,5 @@
 
 // make an initial guess for parameters
-bool PM_MODEL_GUESS (pmModel *model, pmSource *source)
+bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
 {
     pmMoments *moments = source->moments;
Index: branches/eam_branches/ipp-20130419/psphot/src/psphotExtendedSourceFits.c
===================================================================
--- branches/eam_branches/ipp-20130419/psphot/src/psphotExtendedSourceFits.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psphot/src/psphotExtendedSourceFits.c	(revision 35421)
@@ -90,4 +90,21 @@
     assert (markVal);
 
+    // source fitting parameters for extended source fits
+    int fitIter = psMetadataLookupS32(&status, recipe, "EXT_FIT_ITER"); // Max number of fit iterations
+    assert (status && fitIter > 0);
+
+    float fitMinTol = psMetadataLookupF32 (&status, recipe, "EXT_FIT_MIN_TOL"); // Fit tolerance
+    if (!status || !isfinite(fitMinTol) || fitMinTol <= 0) {
+	fitMinTol = psMetadataLookupF32 (&status, recipe, "PSF_FIT_TOL"); // Fit tolerance
+	if (!status || !isfinite(fitMinTol) || fitMinTol <= 0) {
+	    psAbort("PSF_FIT_MIN_TOL (and PSF_FIT_TOL) not defined or positive");
+	}
+    }
+
+    float fitMaxTol = psMetadataLookupF32 (&status, recipe, "EXT_FIT_MAX_TOL"); // Fit tolerance
+    if (!status || !isfinite(fitMaxTol) || fitMaxTol <= 0) {
+	fitMaxTol = 1.0;
+    }
+
     // maskVal is used to test for rejected pixels, and must include markVal
     maskVal |= markVal;
@@ -181,4 +198,8 @@
 
             PS_ARRAY_ADD_SCALAR(job->args, psfSize, PS_TYPE_S32);
+            PS_ARRAY_ADD_SCALAR(job->args, fitIter, PS_TYPE_S32);
+            PS_ARRAY_ADD_SCALAR(job->args, fitMinTol, PS_TYPE_F32);
+            PS_ARRAY_ADD_SCALAR(job->args, fitMaxTol, PS_TYPE_F32);
+
             PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_IMAGE_MASK);
             PS_ARRAY_ADD_SCALAR(job->args, markVal, PS_TYPE_IMAGE_MASK);
@@ -293,6 +314,9 @@
     psRegion *region        = job->args->data[4];
     int psfSize             = PS_SCALAR_VALUE(job->args->data[5],S32);
-    psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[6],PS_TYPE_IMAGE_MASK_DATA);
-    psImageMaskType markVal = PS_SCALAR_VALUE(job->args->data[7],PS_TYPE_IMAGE_MASK_DATA);
+    int fitIter             = PS_SCALAR_VALUE(job->args->data[6],S32);
+    float fitMinTol         = PS_SCALAR_VALUE(job->args->data[7],F32);
+    float fitMaxTol         = PS_SCALAR_VALUE(job->args->data[8],F32);
+    psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[9],PS_TYPE_IMAGE_MASK_DATA);
+    psImageMaskType markVal = PS_SCALAR_VALUE(job->args->data[10],PS_TYPE_IMAGE_MASK_DATA);
 
     // Define source fitting parameters for extended source fits
@@ -301,10 +325,7 @@
     fitOptions->saveCovariance = true;  // XXX make this a user option?
     fitOptions->covarFactor    = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix
-
-    // XXX for now, use the defaults for the rest:
-    // fitOptions->nIter         = fitIter;
-    // fitOptions->tol           = fitTol;
-    // fitOptions->poissonErrors = poisson;
-    // fitOptions->weight        = PS_SQR(skySig);
+    fitOptions->nIter          = fitIter;
+    fitOptions->minTol         = fitMinTol;
+    fitOptions->maxTol         = fitMaxTol;
 
     // choose the sources of interest
@@ -335,4 +356,7 @@
 	// set the fit radius based on the first radial moment (also sets the mask pixels)
 	psphotSetRadiusMomentsExact(&fitRadius, &windowRadius, readout, source, markVal); // NOTE : 6 allocs
+
+	// XXX WATCH OUT HERE!!
+	// fitRadius = 30;
 
 	// UPDATE : we have changed the moments calculation.  There is now an iteration within 
@@ -498,23 +522,23 @@
 
     // change the value of a scalar on the array (wrap this and put it in psArray.h)
-    scalar = job->args->data[8];
+    scalar = job->args->data[11];
     scalar->data.S32 = Next;
 
-    scalar = job->args->data[9];
+    scalar = job->args->data[12];
     scalar->data.S32 = Nconvolve;
 
-    scalar = job->args->data[10];
+    scalar = job->args->data[13];
     scalar->data.S32 = NconvolvePass;
 
-    scalar = job->args->data[11];
+    scalar = job->args->data[14];
     scalar->data.S32 = Nplain;
 
-    scalar = job->args->data[12];
+    scalar = job->args->data[15];
     scalar->data.S32 = NplainPass;
 
-    scalar = job->args->data[13];
+    scalar = job->args->data[16];
     scalar->data.S32 = Nfaint;
 
-    scalar = job->args->data[14];
+    scalar = job->args->data[17];
     scalar->data.S32 = Nfail;
 
Index: branches/eam_branches/ipp-20130419/psphot/src/psphotFakeSources.c
===================================================================
--- branches/eam_branches/ipp-20130419/psphot/src/psphotFakeSources.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psphot/src/psphotFakeSources.c	(revision 35421)
@@ -24,5 +24,5 @@
 
         pmModelType modelType = pmModelClassGetType ("PS_MODEL_QGAUSS");
-        source->modelPSF = pmSourceModelGuess (source, modelType);
+        source->modelPSF = pmSourceModelGuess (source, modelType, 0, 0);
         sources->data[i] = source;
     }
Index: branches/eam_branches/ipp-20130419/psphot/src/psphotMakeResiduals.c
===================================================================
--- branches/eam_branches/ipp-20130419/psphot/src/psphotMakeResiduals.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psphot/src/psphotMakeResiduals.c	(revision 35421)
@@ -105,7 +105,7 @@
         if (model == NULL) continue;  // model must be defined
 
-        psImage *image  = psImageCopy (NULL, source->pixels,   PS_TYPE_F32);
-        psImage *variance = psImageCopy (NULL, source->variance,   PS_TYPE_F32);
-        psImage *mask   = psImageCopy (NULL, source->maskView, PS_TYPE_IMAGE_MASK);
+        psImage *image    = psImageCopy (NULL, source->pixels,     PS_TYPE_F32);
+        psImage *mask     = psImageCopy (NULL, source->maskView ? source->maskView : source->maskObj,  PS_TYPE_IMAGE_MASK);
+        psImage *variance = psImageCopy (NULL, source->variance ? source->variance : source->pixels,   PS_TYPE_F32);
         pmModelSub (image, mask, model, PM_MODEL_OP_FUNC, maskVal);
 
Index: branches/eam_branches/ipp-20130419/psphot/src/psphotModelTestArguments.c
===================================================================
--- branches/eam_branches/ipp-20130419/psphot/src/psphotModelTestArguments.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psphot/src/psphotModelTestArguments.c	(revision 35421)
@@ -151,4 +151,10 @@
     }
 
+    // chip selection is used to limit chips to be processed
+    if ((N = psArgumentGet (argc, argv, "-moments-radius"))) {
+        psArgumentRemove (N, &argc, argv);
+        psMetadataAddBool (config->arguments, PS_LIST_TAIL, "TEST_MOMENTS_RADIUS", PS_DATA_BOOL, "", true);
+    }
+
     // if these command-line options are supplied, load the file name lists into config->arguments
     // override any configuration-specified source for these files
@@ -160,4 +166,6 @@
     pmConfigFileSetsMD (config->arguments, &argc, argv, "SRC", "-src", "-srclist");
     pmConfigFileSetsMD (config->arguments, &argc, argv, "SRCTEXT", "-srctext", "-srctextlist");
+
+    pmConfigFileSetsMD (config->arguments, &argc, argv, "PSPHOT.PSF", "-psf",      "-psflist");
 
     if (argc == 1) {
Index: branches/eam_branches/ipp-20130419/psphot/src/psphotModelTestReadout.c
===================================================================
--- branches/eam_branches/ipp-20130419/psphot/src/psphotModelTestReadout.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psphot/src/psphotModelTestReadout.c	(revision 35421)
@@ -5,4 +5,6 @@
 
     bool status;
+
+    psTimerStart ("modelTest");
 
     pmModelClassSetLimits(PM_MODEL_LIMITS_LAX);
@@ -41,4 +43,11 @@
     }
 
+    // load the psf model, if suppled.  FWHM_MAJ,FWHM_MIN,etc are determined and saved on
+    // readout->analysis. NOTE: this function currently only loads from PSPHOT.PSF.LOAD
+    if (!psphotLoadPSF (config, view, filerule)) { // ??? need to supply 2 ?
+        psError (PSPHOT_ERR_UNKNOWN, false, "error loading psf model");
+        return psphotReadoutCleanup (config, view, filerule);
+    }
+
     float MIN_KRON_RADIUS = 5.0;
 
@@ -53,4 +62,8 @@
     // maskVal is used to test for rejected pixels, and must include markVal
     maskVal |= markVal;
+
+    // what fraction of the PSF is used? (radius in pixels : 2 -> 5x5 box)
+    int psfSize = psMetadataLookupS32 (&status, recipe, "PCM_BOX_SIZE");
+    assert (status);
 
     // find the currently selected readout
@@ -84,5 +97,5 @@
 
     // define the source of interest
-   float xObj     = psMetadataLookupF32 (&status, recipe, "TEST_FIT_X");
+    float xObj     = psMetadataLookupF32 (&status, recipe, "TEST_FIT_X");
     float yObj     = psMetadataLookupF32 (&status, recipe, "TEST_FIT_Y");
     if (!isfinite(xObj) || !isfinite(yObj)) psAbort ("object position is not defined");
@@ -99,9 +112,12 @@
     source->type = PM_SOURCE_TYPE_EXTENDED;
 
+    bool TEST_FIT_CONVOLVED = psMetadataLookupBool (&status, recipe, "TEST_FIT_CONVOLVED");
+
     // find the local sky
     status = pmSourceLocalSky (source, PS_STAT_SAMPLE_MEDIAN, INNER, maskVal, markVal);
     if (!status) psAbort("pmSourceLocalSky error");
 
-    { 
+    bool testMomentsRadius = psMetadataLookupBool (&status, config->arguments, "TEST_MOMENTS_RADIUS");
+    if (testMomentsRadius) { 
 	// XXX I want to test an iterative aperture for brighter sources
 	float radius = mRADIUS;
@@ -109,5 +125,5 @@
 
 	    // get the source moments
-	    status = pmSourceMoments (source, radius, 0.0, 0.0, MIN_KRON_RADIUS, maskVal);
+	    status = pmSourceMoments (source, radius, 0.25*radius, 0.0, MIN_KRON_RADIUS, maskVal);
 	    if (!status) psAbort("psSourceMoments error");
 
@@ -121,5 +137,5 @@
 
     // get the source moments
-    status = pmSourceMoments (source, mRADIUS, 0.0, 0.0, MIN_KRON_RADIUS, maskVal);
+    status = pmSourceMoments (source, mRADIUS, 0.25*mRADIUS, 0.0, MIN_KRON_RADIUS, maskVal);
     if (!status) psAbort("psSourceMoments error");
 
@@ -135,6 +151,14 @@
     fprintf (stderr, "axes: %f @ (%f, %f)\n", axes.theta*180/M_PI, axes.major, axes.minor);
 
+    pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");
+    if (psf) {
+      // set PSF parameters for this model (apply 2D shape model to coordinates Xo, Yo)
+      source->peak->rawFlux = source->moments->Peak;
+      float Io = source->moments->Peak;
+      source->modelPSF = pmModelFromPSFforXY(psf, xObj, yObj, Io);
+    }
+
     // get the initial model parameter guess
-    pmModel *model = pmSourceModelGuess (source, modelType);
+    pmModel *model = pmSourceModelGuess (source, modelType, maskVal, markVal);
     source->modelEXT = model;
 
@@ -159,12 +183,15 @@
     fprintf (stderr, "peak: %f @ (%f, %f)\n", source->moments->Sum*area, (double)source->peak->x, (double)source->peak->y);
 
-    // list model input shape
-    psEllipseShape shape;
-    shape.sx  = 1.4 / model->params->data.F32[4];
-    shape.sy  = 1.4 / model->params->data.F32[5];
-    shape.sxy = model->params->data.F32[6];
-    axes = psEllipseShapeToAxes (shape, 20.0);
-
-    fprintf (stderr, "guess: %f @ (%f, %f)\n", axes.theta*180/M_PI, axes.major, axes.minor);
+    if (modelType == pmModelClassGetType("PS_MODEL_TRAIL")) {
+	fprintf (stderr, "guess: %f @ (%f, %f)\n", params[6]*180/M_PI, params[4], params[5]);
+    } else {
+	// list model input shape
+	psEllipseShape shape;
+	shape.sx  = 1.4 / model->params->data.F32[4];
+	shape.sy  = 1.4 / model->params->data.F32[5];
+	shape.sxy = model->params->data.F32[6];
+	axes = psEllipseShapeToAxes (shape, 20.0);
+	fprintf (stderr, "guess: %f @ (%f, %f)\n", axes.theta*180/M_PI, axes.major, axes.minor);
+    }
 
     fprintf (stderr, "input parameters: \n");
@@ -190,5 +217,24 @@
     fitOptions->covarFactor   = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix
 
-    status = pmSourceFitModel (source, model, fitOptions, maskVal);
+    if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
+	fitOptions->mode = PM_SOURCE_FIT_NO_INDEX;
+    }
+    if (modelType == pmModelClassGetType("PS_MODEL_TRAIL")) {
+	fitOptions->mode = PM_SOURCE_FIT_TRAIL;
+    }
+
+    if (TEST_FIT_CONVOLVED) {
+      pmPCMdata *pcm = pmPCMinit (source, fitOptions, model, maskVal, psfSize);
+      if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {
+	psphotSersicModelClassGuessPCM (pcm, source);
+      } else {
+	pmSourceModelGuessPCM (pcm, source, maskVal, markVal);
+      }
+      pmPCMupdate(pcm, source, fitOptions, model);
+      pmSourceFitPCM (pcm, source, fitOptions, maskVal, markVal, psfSize);
+      psFree (pcm);
+    } else {
+      status = pmSourceFitModel (source, model, fitOptions, maskVal);
+    }
 
     // measure the source mags
Index: branches/eam_branches/ipp-20130419/psphot/src/psphotSetThreads.c
===================================================================
--- branches/eam_branches/ipp-20130419/psphot/src/psphotSetThreads.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psphot/src/psphotSetThreads.c	(revision 35421)
@@ -40,5 +40,5 @@
     psFree(task);
 
-    task = psThreadTaskAlloc("PSPHOT_EXTENDED_FIT", 15);
+    task = psThreadTaskAlloc("PSPHOT_EXTENDED_FIT", 18);
     task->function = &psphotExtendedSourceFits_Threaded;
     psThreadTaskAdd(task);
Index: branches/eam_branches/ipp-20130419/psphot/src/psphotSourceFits.c
===================================================================
--- branches/eam_branches/ipp-20130419/psphot/src/psphotSourceFits.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/psphot/src/psphotSourceFits.c	(revision 35421)
@@ -457,5 +457,5 @@
 
     // use the source moments, etc to guess basic model parameters
-    pmModel *model = pmSourceModelGuess (source, modelType);
+    pmModel *model = pmSourceModelGuess (source, modelType, maskVal, markVal);
     if (!model) {
 	psTrace ("psphot", 5, "failed to generate a model for source: moments: %f %f\n", source->moments->Mxx, source->moments->Myy);
@@ -625,5 +625,5 @@
 	model->params->data.F32[PM_PAR_7] = 0.5/indexGuess[i];
 
-	if (!model->modelGuess(model, source)) {
+	if (!model->modelGuess(model, source, maskVal, markVal)) {
 	    model->flags |= PM_MODEL_STATUS_BADARGS;
 	    return false;
@@ -648,5 +648,5 @@
     model->flags = PM_MODEL_STATUS_NONE; // do not attempt to handle failures here, let the next iteration deal with it
     model->params->data.F32[PM_PAR_7] = 0.5/indexGuess[iMin];
-    model->modelGuess(model, source);
+    model->modelGuess(model, source, maskVal, markVal);
 
     return true;
@@ -677,5 +677,5 @@
 	model->params->data.F32[PM_PAR_7] = indexGuess[i];
 	
-	if (!model->modelGuess(model, source)) {
+	if (!model->modelGuess(model, source, maskVal, markVal)) {
 	    model->flags |= PM_MODEL_STATUS_BADARGS;
 	    return false;
Index: branches/eam_branches/ipp-20130419/pswarp/doc/notes.20130406.txt
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/doc/notes.20130406.txt	(revision 35421)
+++ branches/eam_branches/ipp-20130419/pswarp/doc/notes.20130406.txt	(revision 35421)
@@ -0,0 +1,82 @@
+
+examinging pswarp to handle inverse transformations or more general transformations:
+
+pswarp:
+  * setup / init functions (psLibInit, psphotInit, etc)
+  * pswarpArguments   : parse things like -file (name), -list (name), etc
+  * pswarpParseCamera : examine minimal files, define cameras & pmFPAfile + pmFPA
+    		        this function reads headers for files
+
+			uses pmFPAfileDefineFromArgs / pmFPAfileBindFromArgs for inputs
+			uses pswarpDefineSkycell for outputs
+
+  * pswarpOptions     : check the recipe options, reconcile with cmd-line options
+
+  * pswarpDefine      : create output image pixels, update related concepts, 
+    		      	associate output astrometry (skycell) with output pmFPA structures
+			
+
+
+in pswarpParseCamera:
+  * pswarpDefineSkycell : this function is based on pmFPAfileDefineFromArgs
+    			* reads fileset from config->arguments (a fileset is an array of filenames)
+			* select first filename & translate to UNIX namespace
+			* open fits file
+			* read fits header (PHU)
+			* inherit some config elements from input config (user, system, files, arguments)
+			* determine format from header
+			  (NOTE: currently does not examine or set fileLevel)
+			* build the pmFPA structure based on camera & name
+			* bind filerule to fpa, generate the pmFPAfile
+			* sets file->fileLevel based on format, but slightly out of sync wrt pmFPAfileDefineFromArgs
+  			  (NOTE: does not expect / examine any other file)
+
+
+in pswarpLoop (major blocks):
+
+   * find the needed recipe / filerules / etc
+   * pswarpIOChecksBefore() : generate the outputs?  (isn't this done in pswarpDefine?)
+   * read input astrometry headers (also loads sources or not?)
+   * apply astrometry headers to input->fpa
+   * pswarpTransformReadout : transform pixels, etc
+   * pswarpPixelsLit : measure filling & masks stats
+   * modify the covariance
+   * modify the ZP & trimsec (seems like these should be encapsulated)
+   * update headers
+   * measure the PSF	
+   * measure pixel stats on output
+   * add MD5 to header
+   
+   
+
+----
+
+pswarp issues:
+
+1) operations need to loop over the output astrometry / targets for fpa/chip/cell levels
+   a) I replaced pswarpDefineSkycell with an update to pmFPAfileDefineXX which does the looping
+   b) is it identical in behavior to pswarpDefineSkycell?
+      * YES : I can drop pswarpDefineSkycell 
+
+2) how do we load the SOURCES?
+
+   * I need to load the headers for the astrometry, and I do this by
+     setting the type of the input astrometry to be WCS.  is this the
+     same as CMF, but the latter reads the sources??
+
+   * by changing the filerules entry CMF <-> WCS pswarpDefine.c either does or does not read the sources
+
+     (for testing, I want to use a skycell image or template to define the astrometry; this would not have sources to be read)
+
+3) does the I/O loop in pswarpLoop (pswarpIOChecksBefore) do anything useful?
+   ** I don't think so... this operation is done in pswarpDefine.
+
+4) how do I determine the overlaps correctly? (I'd like to do this before I load sources or pixels)
+
+   ** pswarpMapSetLocalModel does not seem to depend on astrometry model style (GOOD!)
+   
+-----
+
+Changes to support arbitrary fpa to arbitrary fpa:
+
+pswarpDefine : 
Index: branches/eam_branches/ipp-20130419/pswarp/src/Makefile.am
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/Makefile.am	(revision 35420)
+++ branches/eam_branches/ipp-20130419/pswarp/src/Makefile.am	(revision 35421)
@@ -28,8 +28,12 @@
 	pswarp.c			\
 	pswarpArguments.c		\
-	pswarpExit.c			\
+	pswarpExitCode.c		\
 	pswarpLoop.c			\
+	pswarpLoopBackground.c		\
+	pswarpCleanup.c			\
+	pswarpStatsFile.c		\
 	pswarpDefine.c			\
-	pswarpDefineSkycell.c		\
+	pswarpDefineBackground.c	\
+	pswarpDefineSkycell.c	\
 	pswarpErrorCodes.c		\
 	pswarpMapGrid.c			\
Index: branches/eam_branches/ipp-20130419/pswarp/src/pswarp.c
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/pswarp.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/pswarp/src/pswarp.c	(revision 35421)
@@ -12,5 +12,4 @@
 
 #include "pswarp.h"
-#include "pswarpFileNames.h"
 
 int main (int argc, char **argv)
@@ -22,12 +21,10 @@
     psphotInit();
 
-    const char *statsName = NULL;       // Filename for statistics
-    psMetadata *stats = NULL;           // Container for statistics
-    FILE *statsFile = NULL;             // File stream for statistics
-
     pmConfig *config = pswarpArguments(argc, argv);
     if (!config) {
-        goto DIE;
+        pswarpCleanup(config, NULL);
     }
+
+    pswarpStatsFile *statsFile = pswarpStatsFileOpen (config);
 
     pswarpVersionPrint();
@@ -35,111 +32,34 @@
     // load identify the data sources
     if (!pswarpParseCamera(config)) {
-        goto DIE;
+        pswarpCleanup(config, statsFile);
     }
 
     if (!pswarpOptions(config)) {
-        goto DIE;
+        pswarpCleanup(config, statsFile);
     }
 
-    // load the skycell layout information
+    // load the skycell layout information:
+    //   read the output astrometry description
+    //   generate the output pixels
+    //   convert header astrometry to pmFPA astrometry structures
     if (!pswarpDefine(config)) {
-        goto DIE;
+        pswarpCleanup(config, statsFile);
     }
-    if (psMetadataLookupBool(NULL,config->arguments,"BACKGROUND.MODEL")) {
-      if (!pswarpDefineBackground(config)) {
-	goto DIE;
-      }
-    }
-
-    // Open the statistics file
-    bool mdok;                          ///< Status of MD lookup
-    statsName = psMetadataLookupStr(&mdok, config->arguments, "STATS"); ///< Filename for statistics
-    if (mdok && statsName && strlen(statsName) > 0) {
-        psString resolved = pmConfigConvertFilename(statsName, config, true, true);
-        statsFile = fopen(resolved, "w");
-        if (!statsFile) {
-            psError(PS_ERR_IO, true, "Unable to open statistics file %s for writing.\n", resolved);
-            psFree(resolved);
-            goto DIE;
-        }
-        psFree(resolved);
-        stats = psMetadataAlloc();
-        psMetadataAddS32(stats, PS_LIST_TAIL, "QUALITY", 0, "No problems", 0);
+    if (!pswarpDefineBackground(config)) {
+        pswarpCleanup(config, statsFile);
     }
 
     // load and warp
-    if (!pswarpLoop(config, stats)) {
-        goto DIE;
+    if (!pswarpLoop(config, statsFile->md)) {
+        pswarpCleanup(config, statsFile);
     }
-    if (psMetadataLookupBool(NULL,config->arguments,"BACKGROUND.MODEL")) {
-      if (!pswarpLoopBackground(config, stats)) {
+    if (!pswarpLoopBackground(config, statsFile->md)) {
 	fprintf(stderr,"Dying!\n");
-        goto DIE;
-      }
+        pswarpCleanup(config, statsFile);
     }
 
     psLogMsg("pswarp", PS_LOG_INFO, "complete pswarp run: %f sec\n", psTimerMark("pswarp"));
+    pswarpCleanup(config, statsFile);
+}
 
-DIE:
-    {
-        psExit exitValue = pswarpExitCode(PS_EXIT_SUCCESS); // Exit code
-
-        // Ensure everything is written out, at every level
-        pswarpFileActivation(config, detectorFiles, true);
-        pswarpFileActivation(config, skycellFiles, true);
-        pswarpFileActivation(config, photFiles, true);
-        pswarpFileActivation(config, independentFiles, true);
-        if (!pswarpIOChecksAfter(config)) {
-            psError(psErrorCodeLast(), false, "Unable to write files.");
-            exitValue = pswarpExitCode(exitValue);
-            pmFPAfileFreeSetStrict(false);
-        }
-
-        // Write out summary statistics
-        if (stats && statsFile) {
-            psMetadataAddF32(stats, PS_LIST_TAIL, "DT_WARP", 0, "Time for warp completion",
-                             psTimerMark("pswarp"));
-
-            const char *statsMDC = psMetadataConfigFormat(stats);
-            if (!statsMDC) {
-                psError(psErrorCodeLast(), false, "Unable to get statistics file.");
-                exitValue = pswarpExitCode(exitValue);
-            }
-            psFree(stats);
-            if (fprintf(statsFile, "%s", statsMDC) != strlen(statsMDC)) {
-                psError(PSWARP_ERR_IO, true, "Unable to write statistics file.");
-                exitValue = pswarpExitCode(exitValue);
-            }
-            psFree(statsMDC);
-            if (fclose(statsFile) == EOF) {
-                psError(PSWARP_ERR_IO, true, "Unable to close statistics file.");
-                exitValue = pswarpExitCode(exitValue);
-            }
-            pmConfigRunFilenameAddWrite(config, "STATS", statsName);
-        }
-
-        // Dump configuration
-        psString dump_file = psMetadataLookupStr(&mdok, config->arguments, "DUMP_CONFIG");
-        if (dump_file) {
-            if (!pmConfigDump(config, dump_file)) {
-                psError(psErrorCodeLast(), false, "Unable to dump configuration");
-                exitValue = pswarpExitCode(exitValue);
-            }
-        }
-
-        psThreadPoolFinalize();
-        psMemCheckCorruption(stderr, true);
-
-        psFree(config);
-
-        psTimerStop();
-        pmVisualClose();
-        pmModelClassCleanup();
-        pmConceptsDone();
-        pmConfigDone();
-        psLibFinalize();
-
-        exitValue = pswarpExitCode(exitValue);
-        return exitValue;
-    }
-}
+// NOTE: pswarpCleanup calls exit
Index: branches/eam_branches/ipp-20130419/pswarp/src/pswarp.h
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/pswarp.h	(revision 35420)
+++ branches/eam_branches/ipp-20130419/pswarp/src/pswarp.h	(revision 35421)
@@ -77,4 +77,10 @@
     double jacobian;                    ///< (Square root of) local Jacobian
 } pswarpTransformTileArgs;
+
+typedef struct {
+    FILE *f;				// File stream for statistics
+    char *name;				// Filename for statistics
+    psMetadata *md;			// Container for statistics
+} pswarpStatsFile;
 
 pswarpTransformTileArgs *pswarpTransformTileArgsAlloc(void);
@@ -160,2 +166,8 @@
     );
 
+pswarpStatsFile *pswarpStatsFileAlloc ();
+pswarpStatsFile *pswarpStatsFileOpen (pmConfig *config);
+bool pswarpStatsFileSave (pmConfig *config, pswarpStatsFile *statsFile);
+
+// cleanup memory and exit
+void pswarpCleanup (pmConfig *config, pswarpStatsFile *statsFile) PS_ATTR_NORETURN;
Index: branches/eam_branches/ipp-20130419/pswarp/src/pswarpArguments.c
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/pswarpArguments.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/pswarp/src/pswarpArguments.c	(revision 35421)
@@ -183,14 +183,9 @@
     
     // Set recipe values in the recipe (since we've possibly altered some)
-    psMetadataAddS32(recipe, PS_LIST_TAIL, "GRID.NX", PS_META_REPLACE,
-                     "Iso-astrom grid spacing in x", nGridX);
-    psMetadataAddS32(recipe, PS_LIST_TAIL, "GRID.NY", PS_META_REPLACE,
-                     "Iso-astrom grid spacing in y", nGridY);
-    psMetadataAddStr(recipe, PS_LIST_TAIL, "INTERPOLATION.MODE", PS_META_REPLACE,
-                     "Interpolation mode", name);
-    psMetadataAddS32(recipe, PS_LIST_TAIL, "INTERPOLATION.NUM", PS_META_REPLACE,
-                     "Interpolation pre-calculated kernels", numKernels);
-    psMetadataAddF32(recipe, PS_LIST_TAIL, "POOR.FRAC", PS_META_REPLACE,
-                     "Fraction of bad flux for a pixel to be marked as poor", poorFrac);
+    psMetadataAddS32(recipe, PS_LIST_TAIL, "GRID.NX", PS_META_REPLACE, "Iso-astrom grid spacing in x", nGridX);
+    psMetadataAddS32(recipe, PS_LIST_TAIL, "GRID.NY", PS_META_REPLACE, "Iso-astrom grid spacing in y", nGridY);
+    psMetadataAddStr(recipe, PS_LIST_TAIL, "INTERPOLATION.MODE", PS_META_REPLACE, "Interpolation mode", name);
+    psMetadataAddS32(recipe, PS_LIST_TAIL, "INTERPOLATION.NUM", PS_META_REPLACE, "Interpolation pre-calculated kernels", numKernels);
+    psMetadataAddF32(recipe, PS_LIST_TAIL, "POOR.FRAC", PS_META_REPLACE, "Fraction of bad flux for a pixel to be marked as poor", poorFrac);
     psMetadataAddBool(recipe, PS_LIST_TAIL, "PSF", PS_META_REPLACE, "Generate a PSF Model?", PSF);
     psMetadataAddBool(recipe, PS_LIST_TAIL, "BACKGROUND.MODEL", PS_META_REPLACE, "Generate the warped background model?", doBKG);
@@ -198,16 +193,10 @@
     psMetadataAddS32(recipe, PS_LIST_TAIL, "BKG.YGRID", PS_META_REPLACE, "Ysize of background model", bkgYgrid);
     
-    
     // Set recipe values in the arguments
-    psMetadataAddS32(config->arguments, PS_LIST_TAIL, "GRID.NX", 0,
-                     "Iso-astrom grid spacing in x", nGridX);
-    psMetadataAddS32(config->arguments, PS_LIST_TAIL, "GRID.NY", 0,
-                     "Iso-astrom grid spacing in y", nGridY);
-    psMetadataAddS32(config->arguments, PS_LIST_TAIL, "INTERPOLATION.MODE", 0,
-                     "Interpolation mode", interpolationMode);
-    psMetadataAddS32(config->arguments, PS_LIST_TAIL, "INTERPOLATION.NUM", 0,
-                     "Interpolation pre-calculated kernels", numKernels);
-    psMetadataAddF32(config->arguments, PS_LIST_TAIL, "POOR.FRAC", 0,
-                     "Fraction of bad flux for a pixel to be marked as poor", poorFrac);
+    psMetadataAddS32(config->arguments, PS_LIST_TAIL, "GRID.NX", 0, "Iso-astrom grid spacing in x", nGridX);
+    psMetadataAddS32(config->arguments, PS_LIST_TAIL, "GRID.NY", 0, "Iso-astrom grid spacing in y", nGridY);
+    psMetadataAddS32(config->arguments, PS_LIST_TAIL, "INTERPOLATION.MODE", 0, "Interpolation mode", interpolationMode);
+    psMetadataAddS32(config->arguments, PS_LIST_TAIL, "INTERPOLATION.NUM", 0, "Interpolation pre-calculated kernels", numKernels);
+    psMetadataAddF32(config->arguments, PS_LIST_TAIL, "POOR.FRAC", 0, "Fraction of bad flux for a pixel to be marked as poor", poorFrac);
     psMetadataAddBool(config->arguments, PS_LIST_TAIL, "PSF", PS_META_REPLACE, "Generate a PSF Model?", PSF);
     psMetadataAddBool(config->arguments, PS_LIST_TAIL, "BACKGROUND.MODEL", PS_META_REPLACE, "Generate the warped background model?", doBKG);
@@ -215,5 +204,5 @@
     psMetadataAddS32(config->arguments, PS_LIST_TAIL, "BKG.YGRID", PS_META_REPLACE, "Ysize of background model", bkgYgrid);
 
-    psTrace("pswarp", 1, "Done with pswarpArguments...\n");
+    psTrace("pswarp", 1, "Done with pswarpOptions...\n");
 
     return (config);
Index: branches/eam_branches/ipp-20130419/pswarp/src/pswarpCleanup.c
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/pswarpCleanup.c	(revision 35421)
+++ branches/eam_branches/ipp-20130419/pswarp/src/pswarpCleanup.c	(revision 35421)
@@ -0,0 +1,60 @@
+/** @file pswarp.c
+ *
+ *  @brief cleanup the open files & memory then exit
+ *  @ingroup pswarp
+ *
+ *  @author IfA
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-11 23:27:58 $
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+# include "pswarp.h"
+# include "pswarpFileNames.h"
+
+void pswarpCleanup (pmConfig *config, pswarpStatsFile *statsFile)
+{
+    psExit exitValue = pswarpExitCode(PS_EXIT_SUCCESS); // Exit code
+
+    // Ensure everything is written out, at every level
+    pswarpFileActivation(config, detectorFiles, true);
+    pswarpFileActivation(config, skycellFiles, true);
+    pswarpFileActivation(config, photFiles, true);
+    pswarpFileActivation(config, independentFiles, true);
+
+    if (!pswarpIOChecksAfter(config)) {
+	psError(psErrorCodeLast(), false, "Unable to write files.");
+	exitValue = pswarpExitCode(exitValue);
+	pmFPAfileFreeSetStrict(false);
+    }
+
+    if (!pswarpStatsFileSave (config, statsFile)) {
+	psError(psErrorCodeLast(), false, "Unable to save stats file.");
+	exitValue = pswarpExitCode(exitValue);
+    }
+
+    // Dump configuration
+    bool mdok = false;
+    psString dump_file = psMetadataLookupStr(&mdok, config->arguments, "DUMP_CONFIG");
+    if (dump_file) {
+	if (!pmConfigDump(config, dump_file)) {
+	    psError(psErrorCodeLast(), false, "Unable to dump configuration");
+	    exitValue = pswarpExitCode(exitValue);
+	}
+    }
+
+    psThreadPoolFinalize();
+    psMemCheckCorruption(stderr, true);
+
+    psFree(config);
+
+    psTimerStop();
+    pmVisualClose();
+    pmModelClassCleanup();
+    pmConceptsDone();
+    pmConfigDone();
+    psLibFinalize();
+
+    exitValue = pswarpExitCode(exitValue);
+    exit (exitValue);
+}
Index: branches/eam_branches/ipp-20130419/pswarp/src/pswarpDefine.c
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/pswarpDefine.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/pswarp/src/pswarpDefine.c	(revision 35421)
@@ -1,6 +1,5 @@
 /** @file pswarpDefine.c
  *
- *  @brief
- *
+ *  @brief generates the output images
  *  @ingroup pswarp
  *
@@ -13,7 +12,4 @@
 # include "pswarp.h"
 
-/**
- * loads the skycell metadata
- */
 bool pswarpDefine (pmConfig *config) {
 
@@ -42,53 +38,90 @@
     }
     
-    // open the full skycell file; no need to defer different depths. only load the header data
-    pmFPAview *view = pmFPAviewAlloc (0);
-    pmFPAfileOpen (skycell, view, config);
+    // Read the output astrometry
+    // XXX this section loops over the input skycell to load the header info
+    {
+        pmFPAview *view = pmFPAviewAlloc(0);
 
-    // Read header and create target
-    {
-        if (!pmFPAReadHeaderSet(skycell->fpa, skycell->fits, config)) {
-            psError(psErrorCodeLast(), false, "Unable to read headers for skycell.");
-            psFree(view);
-            return false;
-        }
-        view->chip = 0;
-        view->cell = 0;
-        view->readout = 0;
-        pmCell *source = pmFPAfileThisCell(config->files, view, "PSWARP.SKYCELL"); ///< Source cell
-        pmHDU *hdu = pmHDUFromCell(source); ///< HDU for source
-        if (!hdu || !hdu->header) {
-            psError(PM_ERR_PROG, false, "Unable to find header for sky cell.");
-            psFree(view);
-            return false;
-        }
-        int numCols = psMetadataLookupS32(NULL, hdu->header, "NAXIS1"); ///< Number of columns
-        int numRows = psMetadataLookupS32(NULL, hdu->header, "NAXIS2"); ///< Number of rows
-        if ((numCols == 0) || (numRows == 0)) {
-            psError(PSWARP_ERR_DATA, false, "skycell has invalid dimensions %d x %d", numCols, numRows);
-            psFree(view);
-            return false;
-        }
+        pmChip *chip;
+	if (!pmFPAfileRead (skycell, view, config)) {
+	    psError(PS_ERR_IO, false, "failed READ at FPA %s", skycell->name);
+	    psFree(view);
+	    return false;
+	}
+        while ((chip = pmFPAviewNextChip (view, skycell->fpa, 1)) != NULL) {
+            psTrace ("pswarp", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
+            if (!chip->process || !chip->file_exists) { continue; }
+	    if (!pmFPAfileRead (skycell, view, config)) {
+                psError(psErrorCodeLast(), false, "failed READ at CHIP %s", skycell->name);
+		psFree(view);
+		return false;
+            }
+            pmCell *cell;
+            while ((cell = pmFPAviewNextCell (view, skycell->fpa, 1)) != NULL) {
+                psTrace ("pswarp", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
+                if (!cell->process || !cell->file_exists) { continue; }
+		if (!pmFPAfileRead (skycell, view, config)) {
+		    psError(psErrorCodeLast(), false, "failed READ at CELL %s", skycell->name);
+		    psFree(view);
+		    return false;
+                }
+		if (!pmFPAfileClose(skycell, view)) {
+		    psError(psErrorCodeLast(), false, "failed CLOSE at CELL %s", skycell->name);
+		    psFree (view);
+		    return false;
+		}
 
-        pmCell *target = pmFPAviewThisCell(view, output->fpa); ///< Target cell
-        pmReadout *readout = pmReadoutAlloc(target); ///< Target readout
-        readout->image = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-        psImageInit(readout->image, NAN);
-        psFree(readout);                // Drop reference
-
-        bool status = false;
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.XBIN");
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.YBIN");
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.XSIZE");
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.YSIZE");
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.XPARITY");
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.YPARITY");
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.X0");
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.Y0");
-
-	
+		// we've got the output astrom header
+		pmHDU *hdu = pmHDUFromCell(cell); ///< HDU for source
+		if (!hdu || !hdu->header) {
+		    psError(PM_ERR_PROG, false, "Unable to find header for sky cell.");
+		    psFree(view);
+		    return false;
+		}
+		int numCols = psMetadataLookupS32(NULL, hdu->header, "NAXIS1"); ///< Number of columns
+		int numRows = psMetadataLookupS32(NULL, hdu->header, "NAXIS2"); ///< Number of rows
+		if ((numCols == 0) || (numRows == 0)) {
+		    psError(PSWARP_ERR_DATA, false, "skycell has invalid dimensions %d x %d", numCols, numRows);
+		    psFree(view);
+		    return false;
+		}
+		
+		// XXX generate the output pixels
+		pmCell *target = pmFPAviewThisCell(view, output->fpa); ///< Target cell
+		pmReadout *readout = pmReadoutAlloc(target); ///< Target readout
+		readout->image = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+		psImageInit(readout->image, NAN);
+		psFree(readout);                // Drop reference
+		
+		bool status = false;
+		psMetadataItemSupplement(&status, target->concepts, cell->concepts, "CELL.XBIN");
+		psMetadataItemSupplement(&status, target->concepts, cell->concepts, "CELL.YBIN");
+		psMetadataItemSupplement(&status, target->concepts, cell->concepts, "CELL.XSIZE");
+		psMetadataItemSupplement(&status, target->concepts, cell->concepts, "CELL.YSIZE");
+		psMetadataItemSupplement(&status, target->concepts, cell->concepts, "CELL.XPARITY");
+		psMetadataItemSupplement(&status, target->concepts, cell->concepts, "CELL.YPARITY");
+		psMetadataItemSupplement(&status, target->concepts, cell->concepts, "CELL.X0");
+		psMetadataItemSupplement(&status, target->concepts, cell->concepts, "CELL.Y0");
+            }
+	    if (!pmFPAfileClose(skycell, view)) {
+		psError(psErrorCodeLast(), false, "failed CLOSE at CHIP %s", skycell->name);
+		psFree (view);
+		return false;
+	    }
+	}
+	if (!pmFPAfileClose(skycell, view)) {
+	    psError(psErrorCodeLast(), false, "failed CLOSE at FPA %s", skycell->name);
+	    psFree (view);
+	    return false;
+	}
+	psFree(view);
     }
 
-    // XXX this is not a sufficient test
+    // the section below converts the header astrometry info (in skycell) to the pmFPA
+    // astrometry structures, saving them on the output fpa structure.
+
+    // XXX this block should be modified to loop over all chips
+
+    pmFPAview *view = pmFPAviewAlloc (0);
     view->chip = 0;
     view->cell = 0;
@@ -134,144 +167,2 @@
 }
 
-bool pswarpDefineBackground (pmConfig *config) {
-
-    // load the PSWARP recipe
-    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSWARP_RECIPE);
-    if (!recipe) {
-        psError(PSWARP_ERR_CONFIG, true, "Can't find PSWARP recipe!\n");
-        return false;
-    }
-
-    // select the input data sources
-    pmFPAfile *skycell = psMetadataLookupPtr (NULL, config->files, "PSWARP.SKYCELL");
-    if (!skycell) {
-        psError(PSWARP_ERR_CONFIG, false, "Can't find skycell data!\n");
-        return false;
-    }
-    pmFPAfile *output = psMetadataLookupPtr(NULL, config->files, "PSWARP.OUTPUT.BKGMODEL");
-    if (!output) {
-        psError(PSWARP_ERR_CONFIG, false, "Can't find output data!\n");
-        return false;
-    }
-    pmFPAfile *input = psMetadataLookupPtr(NULL, config->files, "PSWARP.INPUT");
-    if (!input) {
-        psError(PSWARP_ERR_CONFIG, false, "Can't find input data!\n");
-        return false;
-    }
-    
-    // open the full skycell file; no need to defer different depths. only load the header data
-    pmFPAview *view = pmFPAviewAlloc (0);
-    pmFPAfileOpen (skycell, view, config);
-
-    // Read header and create target
-    {
-        if (!pmFPAReadHeaderSet(skycell->fpa, skycell->fits, config)) {
-            psError(psErrorCodeLast(), false, "Unable to read headers for skycell.");
-            psFree(view);
-            return false;
-        }
-        view->chip = 0;
-        view->cell = 0;
-        view->readout = 0;
-        pmCell *source = pmFPAfileThisCell(config->files, view, "PSWARP.SKYCELL"); ///< Source cell
-        pmHDU *hdu = pmHDUFromCell(source); ///< HDU for source
-        if (!hdu || !hdu->header) {
-            psError(PM_ERR_PROG, false, "Unable to find header for sky cell.");
-            psFree(view);
-            return false;
-        }
-        int numCols = psMetadataLookupS32(NULL, hdu->header, "NAXIS1"); ///< Number of columns
-        int numRows = psMetadataLookupS32(NULL, hdu->header, "NAXIS2"); ///< Number of rows
-        if ((numCols == 0) || (numRows == 0)) {
-            psError(PSWARP_ERR_DATA, false, "skycell has invalid dimensions %d x %d", numCols, numRows);
-            psFree(view);
-            return false;
-        }
-
-        pmCell *target = pmFPAviewThisCell(view, output->fpa); ///< Target cell
-        pmReadout *readout = pmReadoutAlloc(target); ///< Target readout
-        readout->image = psImageAlloc(numCols / output->xBin, numRows / output->yBin, PS_TYPE_F32);
-        psImageInit(readout->image, NAN);
-        psFree(readout);                // Drop reference
-
-        bool status = false;
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.XBIN");
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.YBIN");
-/* 	psMetadataAddS32(target->concepts,PS_LIST_TAIL,"CELL.XBIN",PS_META_REPLACE,"",output->xBin); */
-/* 	psMetadataAddS32(target->concepts,PS_LIST_TAIL,"CELL.YBIN",PS_META_REPLACE,"",output->yBin); */
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.XSIZE");
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.YSIZE");
-/* 	psMetadataAddS32(target->concepts,PS_LIST_TAIL,"CELL.XSIZE",PS_META_REPLACE,"",numCols / output->xBin); */
-/* 	psMetadataAddS32(target->concepts,PS_LIST_TAIL,"CELL.YSIZE",PS_META_REPLACE,"",numRows / output->yBin); */
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.XPARITY");
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.YPARITY");
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.X0");
-        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.Y0");
-
-	
-    }
-
-    // XXX this is not a sufficient test
-    view->chip = 0;
-    view->cell = 0;
-    view->readout = -1;
-    pmHDU *phu = pmFPAviewThisPHU(view, skycell->fpa); ///< Skycell PHU
-    pmHDU *hdu = pmFPAviewThisHDU(view, skycell->fpa); ///< Skycell header
-
-    pmAstromWCS *WCS = pmAstromWCSfromHeader(hdu->header);
-
-    double cd1f = 1.0 * output->xBin;
-    double cd2f = 1.0 * output->yBin;
-    
-    WCS->crpix1 = WCS->crpix1 / cd1f;
-    WCS->crpix2 = WCS->crpix2 / cd2f;
-    
-    WCS->cdelt1 *= cd1f;
-    WCS->cdelt2 *= cd2f;
-
-    WCS->trans->x->coeff[1][0] *= cd1f;
-    WCS->trans->x->coeff[0][1] *= cd2f;
-    WCS->trans->y->coeff[1][0] *= cd1f;
-    WCS->trans->y->coeff[0][1] *= cd2f;
-    
-    
-    pmAstromWCStoHeader (hdu->header,WCS);
-
-    bool bilevelAstrometry = false;
-    if (phu) {
-        char *ctype = psMetadataLookupStr(NULL, phu->header, "CTYPE1");
-        if (ctype) {
-            bilevelAstrometry = !strcmp(&ctype[4], "-DIS");
-        }
-    }
-
-    // We read from the skycell into the output.  i.e., the output receives the desired astrometry.
-    pmChip *outputChip = pmFPAviewThisChip(view, output->fpa); ///< Chip in the output
-    if (bilevelAstrometry) {
-        if (!pmAstromReadBilevelMosaic(output->fpa, phu->header)) {
-            psError(psErrorCodeLast(), false, "Unable to read bilevel mosaic astrometry for skycell.");
-            psFree(view);
-            return false;
-        }
-        if (!pmAstromReadBilevelChip(outputChip, hdu->header)) {
-            psError(psErrorCodeLast(), false, "Unable to read bilevel chip astrometry for skycell.");
-            psFree(view);
-            return false;
-        }
-    } else {
-        // we use a default FPA pixel scale of 1.0
-      if (!pmAstromReadWCS(output->fpa, outputChip, hdu->header, 1.0)) {
-            psError(psErrorCodeLast(), false, "Unable to read WCS astrometry for skycell.");
-            psFree(view);
-            return false;
-        }
-    }
-
-    
-    view->chip = view->cell = view->readout = -1;
-    pmFPAAddSourceFromView(output->fpa, view, output->format);
-
-
-    psFree (view);
-    return true;
-}
Index: branches/eam_branches/ipp-20130419/pswarp/src/pswarpDefineBackground.c
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/pswarpDefineBackground.c	(revision 35421)
+++ branches/eam_branches/ipp-20130419/pswarp/src/pswarpDefineBackground.c	(revision 35421)
@@ -0,0 +1,155 @@
+/** @file pswarpDefineBackground.c
+ * 
+ *  @brief generates the output background model
+ *  @ingroup pswarp
+ *
+ *  @author IfA
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-05 20:44:04 $
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+# include "pswarp.h"
+
+bool pswarpDefineBackground (pmConfig *config) {
+
+    if (!psMetadataLookupBool(NULL,config->arguments,"BACKGROUND.MODEL")) return true;
+
+    // load the PSWARP recipe
+    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSWARP_RECIPE);
+    if (!recipe) {
+        psError(PSWARP_ERR_CONFIG, true, "Can't find PSWARP recipe!\n");
+        return false;
+    }
+
+    // select the input data sources
+    pmFPAfile *skycell = psMetadataLookupPtr (NULL, config->files, "PSWARP.SKYCELL");
+    if (!skycell) {
+        psError(PSWARP_ERR_CONFIG, false, "Can't find skycell data!\n");
+        return false;
+    }
+    pmFPAfile *output = psMetadataLookupPtr(NULL, config->files, "PSWARP.OUTPUT.BKGMODEL");
+    if (!output) {
+        psError(PSWARP_ERR_CONFIG, false, "Can't find output data!\n");
+        return false;
+    }
+    pmFPAfile *input = psMetadataLookupPtr(NULL, config->files, "PSWARP.INPUT");
+    if (!input) {
+        psError(PSWARP_ERR_CONFIG, false, "Can't find input data!\n");
+        return false;
+    }
+    
+    // open the full skycell file; no need to defer different depths. only load the header data
+    pmFPAview *view = pmFPAviewAlloc (0);
+    pmFPAfileOpen (skycell, view, config);
+
+    // Read header and create target
+    {
+        if (!pmFPAReadHeaderSet(skycell->fpa, skycell->fits, config)) {
+            psError(psErrorCodeLast(), false, "Unable to read headers for skycell.");
+            psFree(view);
+            return false;
+        }
+        view->chip = 0;
+        view->cell = 0;
+        view->readout = 0;
+        pmCell *source = pmFPAfileThisCell(config->files, view, "PSWARP.SKYCELL"); ///< Source cell
+        pmHDU *hdu = pmHDUFromCell(source); ///< HDU for source
+        if (!hdu || !hdu->header) {
+            psError(PM_ERR_PROG, false, "Unable to find header for sky cell.");
+            psFree(view);
+            return false;
+        }
+        int numCols = psMetadataLookupS32(NULL, hdu->header, "NAXIS1"); ///< Number of columns
+        int numRows = psMetadataLookupS32(NULL, hdu->header, "NAXIS2"); ///< Number of rows
+        if ((numCols == 0) || (numRows == 0)) {
+            psError(PSWARP_ERR_DATA, false, "skycell has invalid dimensions %d x %d", numCols, numRows);
+            psFree(view);
+            return false;
+        }
+
+        pmCell *target = pmFPAviewThisCell(view, output->fpa); ///< Target cell
+        pmReadout *readout = pmReadoutAlloc(target); ///< Target readout
+        readout->image = psImageAlloc(numCols / output->xBin, numRows / output->yBin, PS_TYPE_F32);
+        psImageInit(readout->image, NAN);
+        psFree(readout);                // Drop reference
+
+        bool status = false;
+        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.XBIN");
+        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.YBIN");
+ 	// psMetadataAddS32(target->concepts,PS_LIST_TAIL,"CELL.XBIN",PS_META_REPLACE,"",output->xBin);
+ 	// psMetadataAddS32(target->concepts,PS_LIST_TAIL,"CELL.YBIN",PS_META_REPLACE,"",output->yBin);
+        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.XSIZE");
+        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.YSIZE");
+ 	// psMetadataAddS32(target->concepts,PS_LIST_TAIL,"CELL.XSIZE",PS_META_REPLACE,"",numCols / output->xBin); 
+ 	// psMetadataAddS32(target->concepts,PS_LIST_TAIL,"CELL.YSIZE",PS_META_REPLACE,"",numRows / output->yBin);
+        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.XPARITY");
+        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.YPARITY");
+        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.X0");
+        psMetadataItemSupplement(&status, target->concepts, source->concepts, "CELL.Y0");
+    }
+
+    // XXX this is not a sufficient test
+    view->chip = 0;
+    view->cell = 0;
+    view->readout = -1;
+    pmHDU *phu = pmFPAviewThisPHU(view, skycell->fpa); ///< Skycell PHU
+    pmHDU *hdu = pmFPAviewThisHDU(view, skycell->fpa); ///< Skycell header
+
+    pmAstromWCS *WCS = pmAstromWCSfromHeader(hdu->header);
+
+    double cd1f = 1.0 * output->xBin;
+    double cd2f = 1.0 * output->yBin;
+    
+    WCS->crpix1 = WCS->crpix1 / cd1f;
+    WCS->crpix2 = WCS->crpix2 / cd2f;
+    
+    WCS->cdelt1 *= cd1f;
+    WCS->cdelt2 *= cd2f;
+
+    WCS->trans->x->coeff[1][0] *= cd1f;
+    WCS->trans->x->coeff[0][1] *= cd2f;
+    WCS->trans->y->coeff[1][0] *= cd1f;
+    WCS->trans->y->coeff[0][1] *= cd2f;
+    
+    
+    pmAstromWCStoHeader (hdu->header,WCS);
+
+    bool bilevelAstrometry = false;
+    if (phu) {
+        char *ctype = psMetadataLookupStr(NULL, phu->header, "CTYPE1");
+        if (ctype) {
+            bilevelAstrometry = !strcmp(&ctype[4], "-DIS");
+        }
+    }
+
+    // We read from the skycell into the output.  i.e., the output receives the desired astrometry.
+    pmChip *outputChip = pmFPAviewThisChip(view, output->fpa); ///< Chip in the output
+    if (bilevelAstrometry) {
+        if (!pmAstromReadBilevelMosaic(output->fpa, phu->header)) {
+            psError(psErrorCodeLast(), false, "Unable to read bilevel mosaic astrometry for skycell.");
+            psFree(view);
+            return false;
+        }
+        if (!pmAstromReadBilevelChip(outputChip, hdu->header)) {
+            psError(psErrorCodeLast(), false, "Unable to read bilevel chip astrometry for skycell.");
+            psFree(view);
+            return false;
+        }
+    } else {
+        // we use a default FPA pixel scale of 1.0
+      if (!pmAstromReadWCS(output->fpa, outputChip, hdu->header, 1.0)) {
+            psError(psErrorCodeLast(), false, "Unable to read WCS astrometry for skycell.");
+            psFree(view);
+            return false;
+        }
+    }
+
+    
+    view->chip = view->cell = view->readout = -1;
+    pmFPAAddSourceFromView(output->fpa, view, output->format);
+
+
+    psFree (view);
+    return true;
+}
Index: branches/eam_branches/ipp-20130419/pswarp/src/pswarpDefineSkycell.c
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/pswarpDefineSkycell.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/pswarp/src/pswarpDefineSkycell.c	(revision 35421)
@@ -73,15 +73,18 @@
     psFitsClose(fits);
 
-    // We need to force the format for the skycell to be equivalent to SIMPLE.  Determine
-    // the current format from the header; Determine camera if not specified already
-    // XXX EAM : this operation should be defined as a pmConfig function (pmConfigCopy?)
-    skyConfig = pmConfigAlloc();
-    skyConfig->user = psMemIncrRefCounter(config->user);
-    skyConfig->system = psMemIncrRefCounter(config->system);
+    { // this bit is unique to pswarpDefineSkycell:
 
-    psFree (skyConfig->files);
-    skyConfig->files = psMemIncrRefCounter(config->files);
-    psFree (skyConfig->arguments);
-    skyConfig->arguments = psMemIncrRefCounter(config->arguments);
+      // We need to force the format for the skycell to be equivalent to SIMPLE.  Determine
+      // the current format from the header; Determine camera if not specified already
+      // XXX EAM : this operation should be defined as a pmConfig function (pmConfigCopy?)
+      skyConfig = pmConfigAlloc();
+      skyConfig->user = psMemIncrRefCounter(config->user);
+      skyConfig->system = psMemIncrRefCounter(config->system);
+
+      psFree (skyConfig->files);
+      skyConfig->files = psMemIncrRefCounter(config->files);
+      psFree (skyConfig->arguments);
+      skyConfig->arguments = psMemIncrRefCounter(config->arguments);
+    }
 
     format = pmConfigCameraFormatFromHeader (NULL, NULL, NULL, skyConfig, phu, false);
@@ -94,6 +97,6 @@
 
     // Record the camera name of the skycell, so we can save its configuration
-    psMetadataAddStr(config->arguments, PS_LIST_TAIL, "SKYCELL.CAMERA", 0, "Name of camera for skycell",
-                     skyConfig->cameraName);
+    // XXX this can be put outside of the f
+    psMetadataAddStr(config->arguments, PS_LIST_TAIL, "SKYCELL.CAMERA", 0, "Name of camera for skycell", skyConfig->cameraName);
 
     // build the template fpa, set up the basic view
Index: branches/eam_branches/ipp-20130419/pswarp/src/pswarpExit.c
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/pswarpExit.c	(revision 35420)
+++ 	(revision )
@@ -1,82 +1,0 @@
-/** @file pswarpExit.c
- *
- *  @brief
- *
- *  @ingroup pswarp
- *
- *  @author IfA
- *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-05 20:44:04 $
- *  Copyright 2009 Institute for Astronomy, University of Hawaii
- */
-
-# include "pswarp.h"
-
-
-psExit pswarpExitCode(psExit exitValue)
-{
-    if (exitValue != PS_EXIT_SUCCESS) {
-        return exitValue;
-    }
-
-    // gcc -Wswitch complains here if err is declared as type psErrorCode
-    // the collection of ps*ErrorCode values are enums defined separately for 
-    // each module (psphot, pswarp, etc).  the lowest type, psErrorCode is only the base set and does
-    // not include the possible psphot values
-
-    // for now, to get around this, we just use an int for the switch
-
-    // psErrorCode errorCode = psErrorCodeLast(); // Error code
-    int errorCode = psErrorCodeLast(); // Error code
-
-    if (errorCode != PS_ERR_NONE) {
-        pmFPAfileFreeSetStrict(false);
-        psErrorStackPrint(stderr, "Unable to perform warp.");
-        switch (errorCode) {
-          case PSWARP_ERR_UNKNOWN:
-          case PS_ERR_UNKNOWN:
-            psLogMsg("pswarp", PS_LOG_WARN, "Unknown error code: %x", errorCode);
-            return PS_EXIT_UNKNOWN_ERROR;
-          case PM_ERR_CONFIG:
-            // We get this when the config file is not readable. Set to data like error
-            psLogMsg("pswarp", PS_LOG_WARN, "Config Error: %x", errorCode);
-            exitValue = PS_EXIT_SYS_ERROR;
-            break;
-          case PS_ERR_IO:
-          case PS_ERR_DB_CLIENT:
-          case PS_ERR_DB_SERVER:
-          case PS_ERR_BAD_FITS:
-          case PS_ERR_OS_CALL_FAILED:
-          case PM_ERR_SYS:
-          case PSWARP_ERR_IO:
-            psLogMsg("pswarp", PS_LOG_WARN, "I/O error code: %x", errorCode);
-            return PS_EXIT_SYS_ERROR;
-          case PS_ERR_BAD_PARAMETER_VALUE:
-          case PS_ERR_BAD_PARAMETER_TYPE:
-          case PS_ERR_BAD_PARAMETER_NULL:
-          case PS_ERR_BAD_PARAMETER_SIZE:
-          case PSWARP_ERR_ARGUMENTS:
-          case PSWARP_ERR_CONFIG:
-            psLogMsg("pswarp", PS_LOG_WARN, "Configuration error code: %x", errorCode);
-            return PS_EXIT_CONFIG_ERROR;
-          case PSPHOT_ERR_PSF:
-          case PSWARP_ERR_DATA:
-          case PSWARP_ERR_NO_OVERLAP:
-            psLogMsg("pswarp", PS_LOG_WARN, "Data error code: %x", errorCode);
-            return PS_EXIT_DATA_ERROR;
-          case PS_ERR_UNEXPECTED_NULL:
-          case PS_ERR_PROGRAMMING:
-          case PSWARP_ERR_NOT_IMPLEMENTED:
-            psLogMsg("pswarp", PS_LOG_WARN, "Programming error code: %x", errorCode);
-            exitValue = PS_EXIT_PROG_ERROR;
-            break;
-          default:
-            // It's a programming error if we're not dealing with the error correctly
-            psLogMsg("pswarp", PS_LOG_WARN, "Unrecognised error code: %x", errorCode);
-            return PS_EXIT_PROG_ERROR;
-        }
-    }
-
-    return exitValue;
-}
-
Index: branches/eam_branches/ipp-20130419/pswarp/src/pswarpExitCode.c
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/pswarpExitCode.c	(revision 35421)
+++ branches/eam_branches/ipp-20130419/pswarp/src/pswarpExitCode.c	(revision 35421)
@@ -0,0 +1,76 @@
+/** @file pswarpExit.c
+ *
+ *  @brief
+ *
+ *  @ingroup pswarp
+ *
+ *  @author IfA
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-05 20:44:04 $
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+# include "pswarp.h"
+
+psExit pswarpExitCode(psExit exitValue)
+{
+    if (exitValue != PS_EXIT_SUCCESS) {
+        return exitValue;
+    }
+
+    // gcc -Wswitch complains here if err is declared as type psErrorCode
+    // the collection of ps*ErrorCode values are enums defined separately for 
+    // each module (psphot, pswarp, etc).  the lowest type, psErrorCode is only the base set and does
+    // not include the possible psphot values
+
+    // for now, to get around this, we just use an int for the switch
+
+    // psErrorCode errorCode = psErrorCodeLast(); // Error code
+    int errorCode = psErrorCodeLast(); // Error code
+
+    if (errorCode != PS_ERR_NONE) {
+        pmFPAfileFreeSetStrict(false);
+        psErrorStackPrint(stderr, "Unable to perform warp.");
+        switch (errorCode) {
+          case PSWARP_ERR_UNKNOWN:
+          case PS_ERR_UNKNOWN:
+            psLogMsg("pswarp", PS_LOG_WARN, "Unknown error code: %x", errorCode);
+            return PS_EXIT_UNKNOWN_ERROR;
+          case PS_ERR_IO:
+          case PS_ERR_DB_CLIENT:
+          case PS_ERR_DB_SERVER:
+          case PS_ERR_BAD_FITS:
+          case PS_ERR_OS_CALL_FAILED:
+          case PM_ERR_SYS:
+          case PSWARP_ERR_IO:
+            psLogMsg("pswarp", PS_LOG_WARN, "I/O error code: %x", errorCode);
+            return PS_EXIT_SYS_ERROR;
+          case PS_ERR_BAD_PARAMETER_VALUE:
+          case PS_ERR_BAD_PARAMETER_TYPE:
+          case PS_ERR_BAD_PARAMETER_NULL:
+          case PS_ERR_BAD_PARAMETER_SIZE:
+          case PSWARP_ERR_ARGUMENTS:
+          case PSWARP_ERR_CONFIG:
+            psLogMsg("pswarp", PS_LOG_WARN, "Configuration error code: %x", errorCode);
+            return PS_EXIT_CONFIG_ERROR;
+          case PSPHOT_ERR_PSF:
+          case PSWARP_ERR_DATA:
+          case PSWARP_ERR_NO_OVERLAP:
+            psLogMsg("pswarp", PS_LOG_WARN, "Data error code: %x", errorCode);
+            return PS_EXIT_DATA_ERROR;
+          case PS_ERR_UNEXPECTED_NULL:
+          case PS_ERR_PROGRAMMING:
+          case PSWARP_ERR_NOT_IMPLEMENTED:
+            psLogMsg("pswarp", PS_LOG_WARN, "Programming error code: %x", errorCode);
+            exitValue = PS_EXIT_PROG_ERROR;
+            break;
+          default:
+            // It's a programming error if we're not dealing with the error correctly
+            psLogMsg("pswarp", PS_LOG_WARN, "Unrecognised error code: %x", errorCode);
+            return PS_EXIT_PROG_ERROR;
+        }
+    }
+
+    return exitValue;
+}
+
Index: branches/eam_branches/ipp-20130419/pswarp/src/pswarpLoop.c
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/pswarpLoop.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/pswarp/src/pswarpLoop.c	(revision 35421)
@@ -1,6 +1,5 @@
 /** @file pswarpLoop.c
  *
- *  @brief
- *
+ *  @brief mail processing loop for pswarp
  *  @ingroup pswarp
  *
@@ -17,6 +16,4 @@
 #define WCS_NONLIN_TOL 0.001            // Non-linear tolerance for header WCS
 #define TESTING 0                       // Testing output?
-
-
 
 // Loop over the inputs, warp them to the output skycell and then write out the output.
@@ -80,15 +77,18 @@
     // Turn all skycell files on to generate them, and then turn them off for the loop over the input images
     // the input, which is in a different format.
-    {
-        pswarpFileActivation(config, detectorFiles, false);
-        pswarpFileActivation(config, photFiles, false);
-        pswarpFileActivation(config, independentFiles, false);
-        pswarpFileActivation(config, skycellFiles, true);
-        if (!pswarpIOChecksBefore(config)) {
-            psError(psErrorCodeLast(), false, "Unable to read files.");
-            goto DONE;
-        }
-        pswarpFileActivation(config, skycellFiles, false);
-    }
+    // XXX why is this being done here, doesn't it duplicate the work in pswarpDefine.c??
+    pswarpFileActivation(config, detectorFiles, false);
+    pswarpFileActivation(config, photFiles, false);
+    pswarpFileActivation(config, independentFiles, false);
+    pswarpFileActivation(config, skycellFiles, false);
+    
+    // pswarpFileActivation(config, skycellFiles, true);
+    // if (0) {
+    //   if (!pswarpIOChecksBefore(config)) {
+    //     psError(psErrorCodeLast(), false, "Unable to read files.");
+    //     goto DONE;
+    //   }
+    // }
+   
 
     // Read the input astrometry
@@ -155,5 +155,4 @@
             psError(psErrorCodeLast(), false, "Unable to read bilevel mosaic astrometry for input FPA.");
             psFree(view);
-            psFree(stats);
             goto DONE;
         }
@@ -168,4 +167,5 @@
     }
 
+    // *** main transformation block
     pmChip *chip;
     while ((chip = pmFPAviewNextChip (view, input->fpa, 1)) != NULL) {
@@ -185,5 +185,4 @@
                 psError(psErrorCodeLast(), false, "Unable to read bilevel chip astrometry for input FPA.");
                 psFree(view);
-                psFree(stats);
                 goto DONE;
             }
@@ -193,5 +192,4 @@
                 psError(psErrorCodeLast(), false, "Unable to read WCS astrometry for input FPA.");
                 psFree(view);
-                psFree(stats);
                 goto DONE;
             }
@@ -301,5 +299,4 @@
     if (!pmConceptsAverageCells(outCell, cells, NULL, NULL, false)) {
         psError(psErrorCodeLast(), false, "Unable to average cell concepts.");
-        psFree(stats);
         psFree(cells);
         psFree(view);
@@ -313,5 +310,4 @@
     if (!psMetadataCopy(outFPA->concepts, input->fpa->concepts)) {
         psError(psErrorCodeLast(), false, "Unable to copy FPA concepts from input to output.");
-        psFree(stats);
         psFree(view);
         goto DONE;
@@ -345,5 +341,4 @@
     if (!pmAstromWriteWCS(hdu->header, outFPA, outChip, WCS_NONLIN_TOL)) {
         psError(psErrorCodeLast(), false, "Unable to generate WCS header.");
-        psFree(stats);
         goto DONE;
     }
@@ -452,354 +447,2 @@
     return true;
 }
-
-// Loop over the inputs, warp them to the output skycell and then write out the output.
-bool pswarpLoopBackground(pmConfig *config, psMetadata *stats)
-{
-    bool status;
-    bool mdok;                          // Status of MD lookup
-    const char *skyCamera = psMetadataLookupStr(NULL, config->arguments,
-                                                "SKYCELL.CAMERA");  // Name of camera for skycell
-    pmConfigCamerasCull(config, skyCamera);
-    pmConfigRecipesCull(config, "PSWARP,PPSTATS,PSPHOT,PSASTRO,MASKS,JPEG");
-
-    // load the recipe
-    psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSWARP_RECIPE);
-    if (!recipe) {
-        psError(PSWARP_ERR_CONFIG, false, "missing recipe %s", PSWARP_RECIPE);
-        return false;
-    }
-
-    if (!pswarpSetMaskBits(config)) {
-        psError(psErrorCodeLast(), false, "failed to set mask bits");
-        return NULL;
-    }
-
-    // select the input data sources
-    pmFPAfile *input = psMetadataLookupPtr(NULL, config->files, "PSWARP.BKGMODEL");
-    if (!input) {
-        psError(PSWARP_ERR_CONFIG, true, "Can't find input data!\n");
-        return false;
-    }
-
-    // use the external astrometry source if supplied
-    pmFPAfile *astrom = psMetadataLookupPtr(NULL, config->files, "PSWARP.ASTROM");
-    if (!astrom) {
-        astrom = input;
-    }
-
-    if (astrom->camera != input->camera) {
-        psError(PSWARP_ERR_DATA, true, "Input camera and astrometry camera do not match.");
-        return false;
-    }
-
-    // select the output readout
-    pmFPAview *view = pmFPAviewAlloc(0);
-    view->chip = 0;
-    view->cell = 0;
-    view->readout = 0;
-    pmReadout *output = pmFPAfileThisReadout(config->files, view, "PSWARP.OUTPUT.BKGMODEL");
-    if (!output) {
-        psError(PSWARP_ERR_CONFIG, true, "Can't find output background data!\n");
-        return false;
-    }
-    psFree (view);
-    // Turn all skycell files on to generate them, and then turn them off for the loop over the input images
-    // the input, which is in a different format.
-    {
-        pswarpFileActivation(config, detectorFiles, false);
-        pswarpFileActivation(config, photFiles, false);
-        pswarpFileActivation(config, independentFiles, false);
-        pswarpFileActivation(config, skycellFiles, true);
-        if (!pswarpIOChecksBefore(config)) {
-            psError(psErrorCodeLast(), false, "Unable to read files.");
-            goto DONE;
-        }
-        pswarpFileActivation(config, skycellFiles, false);
-    }
-    // Read the input astrometry
-    // XXX rather than use the activations here, this should just explicitly loop over the desired filerule
-    {
-
-      pmFPAfileActivate(config->files, true, "PSWARP.ASTROM");
-
-        pmChip *chip;
-        pmFPAview *view = pmFPAviewAlloc(0);
-        if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
-            psError(psErrorCodeLast(), false, "Unable to read files.");
-            goto DONE;
-        }
-
-        while ((chip = pmFPAviewNextChip (view, input->fpa, 1)) != NULL) {
-#if 0
-	  // This needs to be removed because otherwise it throws an error of duplicate PSPHOT.DETECTIONS.
-            if (!chip->process || !chip->file_exists) { continue; }
-            if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
-                psError(psErrorCodeLast(), false, "Unable to read files.");
-                goto DONE;
-            }
-#endif
-            pmCell *cell;
-            while ((cell = pmFPAviewNextCell (view, input->fpa, 1)) != NULL) {
-	      psTrace ("pswarp", 4, "ACell %d: %x %x %d\n", view->cell, cell->file_exists, cell->process,psErrorCodeLast());
-                if (!cell->process || !cell->file_exists) { continue; }
-                if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE) ||
-                    !pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) {
-                    psError(psErrorCodeLast(), false, "Unable to read files.");
-                    goto DONE;
-                }
-            }
-            if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) {
-                psError(psErrorCodeLast(), false, "Unable to write files.");
-                goto DONE;
-            }
-        }
-        if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) {
-            psError(psErrorCodeLast(), false, "Unable to write files.");
-            goto DONE;
-        }
-        psFree(view);
-        pswarpFileActivation(config, detectorFiles, true);
-        pmFPAfileActivate(config->files, false, "PSWARP.ASTROM");
-    }
-
-    // Don't care about the skycell anymore --- we've read it, and that's all we need to do.
-    pmFPAfileActivate(config->files, false, "PSWARP.SKYCELL");
-    view = pmFPAviewAlloc(0);
-
-    // find the FPA phu
-    bool bilevelAstrometry = false;
-    pmHDU *phu = pmFPAviewThisPHU(view, astrom->fpa);
-
-    //    pmAstromWCS *WCSF = pmAstromWCSfromHeader(phu->header);
-    
-    if (phu) {
-        char *ctype = psMetadataLookupStr(NULL, phu->header, "CTYPE1");
-        if (ctype) {
-            bilevelAstrometry = !strcmp (&ctype[4], "-DIS");
-        }
-    }
-    if (bilevelAstrometry) {
-        if (!pmAstromReadBilevelMosaic(input->fpa, phu->header)) {
-            psError(psErrorCodeLast(), false, "Unable to read bilevel mosaic astrometry for input FPA.");
-            psFree(view);
-            psFree(stats);
-            goto DONE;
-        }
-    }
-
-    psList *cells = psListAlloc(NULL);  // List of cells, for concepts averaging
-
-    // files associated with the science image
-    if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) {
-        psError(psErrorCodeLast(), false, "Unable to read files.");
-        goto DONE;
-    }
-    pmChip *chip;
-    while ((chip = pmFPAviewNextChip (view, input->fpa, 1)) != NULL) {
-        psTrace ("pswarp", 4, "DChip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
-        if (!chip->process || !chip->file_exists) { continue; }
-        if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) {
-            psError(psErrorCodeLast(), false, "Unable to read files.");
-            goto DONE;
-        }
-
-	// Pull information from the header of the background files so we can use it to set values.
-	pmHDU *hdu = pmFPAviewThisHDU(view,input->fpa);
-	psMetadata *header = hdu->header;
-	
-	int IMAXIS1 = psMetadataLookupS32(NULL,header,"IMNAXIS1");
-	int IMAXIS2 = psMetadataLookupS32(NULL,header,"IMNAXIS2");
-	int NAXIS1 = psMetadataLookupS32(NULL,header,"NAXIS1");
-	int NAXIS2 = psMetadataLookupS32(NULL,header,"NAXIS2");
-	char *CCDSUM = psMetadataLookupStr(NULL,header,"CCDSUM");
-	int CCDSUM1 = atoi(strtok(CCDSUM," "));
-	int CCDSUM2 = atoi(strtok(NULL," "));
-	
-	psMetadataAddF32(config->arguments,PS_LIST_TAIL,"BKG_WARP_XOFFSET", PS_META_REPLACE,
-			 "xoffset for background model data", (NAXIS1 * CCDSUM1 - IMAXIS1) / (2.0 * CCDSUM1));
-	psMetadataAddF32(config->arguments,PS_LIST_TAIL,"BKG_WARP_YOFFSET", PS_META_REPLACE,
-			 "yoffset for background model data", (NAXIS2 * CCDSUM2 - IMAXIS2) / (2.0 * CCDSUM2));
-	psTrace("pswarp",5,"%d %d %d %d %d %d %g %g %d %d",
-		psMetadataLookupS32(NULL,header,"IMNAXIS1"),
-		psMetadataLookupS32(NULL,header,"IMNAXIS2"),
-		psMetadataLookupS32(NULL,header,"NAXIS1"),
-		psMetadataLookupS32(NULL,header,"NAXIS2"),
-		CCDSUM1,CCDSUM2,
-		psMetadataLookupF32(NULL,config->arguments,"BKG_WARP_XOFFSET"),
-		psMetadataLookupF32(NULL,config->arguments,"BKG_WARP_YOFFSET"),
-		psMetadataLookupS32(NULL,config->arguments,"BKG.XGRID"),
-		psMetadataLookupS32(NULL,config->arguments,"BKG.YGRID"));
-	
-	
-        // read WCS data from the corresponding header
-        hdu = pmFPAviewThisHDU (view, astrom->fpa);
-
-	pmAstromWCS *WCS = pmAstromWCSfromHeader(hdu->header);
-
-	double cd1f = (1.0 * CCDSUM1);// * (1.0 * psMetadataLookupS32(NULL,config->arguments,"BKG.XGRID"));
-	double cd2f = (1.0 * CCDSUM2);// * (1.0 * psMetadataLookupS32(NULL,config->arguments,"BKG.YGRID"));
-
-	WCS->cdelt1 *= cd1f;
-	WCS->cdelt2 *= cd2f;
-	WCS->crpix1 = WCS->crpix1 / cd1f;
-	WCS->crpix2 = WCS->crpix2 / cd2f;
-
-	// WCS->trans->x->nX/nY
-	for (int q = 0; q <= WCS->trans->x->nX; q++) {
-	  for (int r = 0; r <= WCS->trans->x->nY; r++) {
-	    WCS->trans->x->coeff[q][r] *= pow(cd1f,q) * pow(cd2f,r);
-	  }
-	}
-	for (int q = 0; q <= WCS->trans->y->nX; q++) {
-	  for (int r = 0; r <= WCS->trans->y->nY; r++) {
-	    WCS->trans->y->coeff[q][r] *= pow(cd1f,q) * pow(cd2f,r);
-	  }
-	}
-	pmAstromWCStoHeader (hdu->header,WCS);
-	
-        if (bilevelAstrometry) {
-            if (!pmAstromReadBilevelChip (chip, hdu->header)) {
-                psError(psErrorCodeLast(), false, "Unable to read bilevel chip astrometry for input FPA.");
-                psFree(view);
-                psFree(stats);
-                goto DONE;
-            }
-        } else {
-            // we use a default FPA pixel scale of 1.0
-            if (!pmAstromReadWCS (astrom->fpa, chip, hdu->header, 1.0)) {
-                psError(psErrorCodeLast(), false, "Unable to read WCS astrometry for input FPA.");
-                psFree(view);
-                psFree(stats);
-                goto DONE;
-            }
-        }
-	// Modify structure here.
-
-	
-        pmCell *cell;
-        while ((cell = pmFPAviewNextCell (view, input->fpa, 1)) != NULL) {
-            psTrace ("pswarp", 4, "DCell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
-            if (!cell->process || !cell->file_exists) { continue; }
-            if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) {
-                psError(psErrorCodeLast(), false, "Unable to read files.");
-                goto DONE;
-            }
-
-            psListAdd(cells, PS_LIST_TAIL, cell);
-
-            // process each of the readouts
-            pmReadout *readout;
-            while ((readout = pmFPAviewNextReadout(view, input->fpa, 1)) != NULL) {
-                if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
-                    psError(psErrorCodeLast(), false, "Unable to read files.");
-                    goto DONE;
-                }
-                if (!readout->data_exists) {
-                    continue;
-                }
-
-		for (int x = 0; x < readout->image->numCols; x++) {
-		  for (int y = 0; y < readout->image->numRows; y++) {
-		    readout->image->data.F32[y][x] = readout->image->data.F32[y][x] * (cd1f * cd2f) /
-		      (psMetadataLookupS32(&mdok,config->arguments,"BKG.XGRID") *
-		       psMetadataLookupS32(&mdok,config->arguments,"BKG.YGRID"));
-		  }
-		}
-		
-		psMetadataAddS32(config->arguments,PS_LIST_TAIL, "INTERPOLATION.MODE", PS_META_REPLACE, "", 8);
-
-		psMetadataAddBool(config->arguments,PS_LIST_TAIL, "BACKGROUND_WARPING", PS_META_REPLACE, "", true);
-                pswarpTransformReadout(output, readout, config);
-		psMetadataAddBool(config->arguments,PS_LIST_TAIL, "BACKGROUND_WARPING", PS_META_REPLACE, "", false);
-
-                if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
-                    psError(psErrorCodeLast(), false, "Unable to write files.");
-                    goto DONE;
-                }
-            }
-            if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
-                psError(psErrorCodeLast(), false, "Unable to write files.");
-                goto DONE;
-            }
-        }
-        if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
-            psError(psErrorCodeLast(), false, "Unable to write files.");
-            goto DONE;
-        }
-    }
-    if (!output->data_exists) {
-        psWarning("No overlap between input and skycell.");
-        psphotFilesActivate(config, false);
-        psFree(cells);
-        psFree(view);
-        goto DONE;
-    }
-    pmCell *outCell = output->parent;   ///< Output cell
-    pmChip *outChip = outCell->parent;  ///< Output chip
-    pmFPA *outFPA = outChip->parent;    ///< Output FP
-
-/*     if (!pswarpPixelsLit(output, stats, config)) { */
-/*         psError(psErrorCodeLast(), false, "Unable to calculate pixel regions."); */
-/*         psFree(cells); */
-/*         psFree(view); */
-/*         goto DONE; */
-/*     } */
-    psRegion *trimsec = psMetadataLookupPtr(NULL, outCell->concepts, "CELL.TRIMSEC"); ///< Trim section
-    trimsec->x0 = trimsec->x1 = trimsec->y0 = trimsec->y1 = 0; ///< All pixels
-
-    if (!psMetadataCopy(outFPA->concepts, input->fpa->concepts)) {
-        psError(psErrorCodeLast(), false, "Unable to copy FPA concepts from input to output.");
-        psFree(stats);
-        psFree(view);
-        goto DONE;
-    }
-
-    pmHDU *hdu = outFPA->hdu;           ///< HDU for the output warped image
-
-    // Copy header from target
-    {
-        pmFPAview *skyView = pmFPAviewAlloc(0); ///< View into skycell
-        skyView->chip = skyView->cell = 0;
-        pmCell *cell = pmFPAfileThisCell(config->files, skyView, "PSWARP.SKYCELL"); // Skycell cell
-        psFree(skyView);
-        pmHDU *skyHDU = pmHDUFromCell(cell); ///< HDU
-        if (!skyHDU) {
-            psError(PSWARP_ERR_DATA, false, "Unable to find skycell HDU.");
-            psFree(view);
-            goto DONE;
-        }
-        hdu->header = psMetadataCopy(hdu->header, skyHDU->header);
-    }
-    pswarpVersionHeader(hdu->header);
-    
-    if (!pmAstromWriteWCS(hdu->header, outFPA, outChip, WCS_NONLIN_TOL)) {
-        psError(psErrorCodeLast(), false, "Unable to generate WCS header.");
-        psFree(stats);
-        goto DONE;
-    }
-    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
-        psError(psErrorCodeLast(), false, "Unable to write files.");
-        goto DONE;
-    }
-    // Done with the detector side of things
-    pswarpFileActivation(config, detectorFiles, false);
-    pswarpFileActivation(config, independentFiles, false);
-
-
-    // Add MD5 information for readout
-    const char *chipName = psMetadataLookupStr(NULL, output->parent->parent->concepts, "CHIP.NAME");
-    const char *cellName = psMetadataLookupStr(NULL, output->parent->concepts, "CELL.NAME");
-    psString headerName = NULL; ///< Header name for MD5
-    psStringAppend(&headerName, "MD5_%s_%s_%d", chipName, cellName, view->readout);
-    psVector *md5 = psImageMD5(output->image); ///< md5 hash
-    psString md5string = psMD5toString(md5); ///< String
-    psFree(md5);
-    psMetadataAddStr(hdu->header, PS_LIST_TAIL, headerName, PS_META_REPLACE,
-                     "Image MD5", md5string);
-    psFree(md5string);
-    psFree(headerName);
-    psFree(view);
- DONE:
-
-    return true;
-}
Index: branches/eam_branches/ipp-20130419/pswarp/src/pswarpLoopBackground.c
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/pswarpLoopBackground.c	(revision 35421)
+++ branches/eam_branches/ipp-20130419/pswarp/src/pswarpLoopBackground.c	(revision 35421)
@@ -0,0 +1,370 @@
+/** @file pswarpLoopBackground.c
+ *
+ *  @brief background model processing loop for pswarp
+ *  @ingroup pswarp
+ *
+ *  @author IfA
+ *  @version $Revision: 1.38 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-13 21:54:32 $
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+#include "pswarp.h"
+#include <ppStats.h>
+#include "pswarpFileNames.h"            // Lists of file rules used at different stages
+
+#define WCS_NONLIN_TOL 0.001            // Non-linear tolerance for header WCS
+#define TESTING 0                       // Testing output?
+
+// Loop over the inputs, warp them to the output skycell and then write out the output.
+bool pswarpLoopBackground(pmConfig *config, psMetadata *stats)
+{
+    bool status;
+    bool mdok;                          // Status of MD lookup
+    const char *skyCamera = psMetadataLookupStr(NULL, config->arguments,
+                                                "SKYCELL.CAMERA");  // Name of camera for skycell
+    if (!psMetadataLookupBool(NULL,config->arguments,"BACKGROUND.MODEL")) return true;
+
+    pmConfigCamerasCull(config, skyCamera);
+    pmConfigRecipesCull(config, "PSWARP,PPSTATS,PSPHOT,PSASTRO,MASKS,JPEG");
+
+    // load the recipe
+    psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSWARP_RECIPE);
+    if (!recipe) {
+        psError(PSWARP_ERR_CONFIG, false, "missing recipe %s", PSWARP_RECIPE);
+        return false;
+    }
+
+    if (!pswarpSetMaskBits(config)) {
+        psError(psErrorCodeLast(), false, "failed to set mask bits");
+        return NULL;
+    }
+
+    // select the input data sources
+    pmFPAfile *input = psMetadataLookupPtr(NULL, config->files, "PSWARP.BKGMODEL");
+    if (!input) {
+        psError(PSWARP_ERR_CONFIG, true, "Can't find input data!\n");
+        return false;
+    }
+
+    // use the external astrometry source if supplied
+    pmFPAfile *astrom = psMetadataLookupPtr(NULL, config->files, "PSWARP.ASTROM");
+    if (!astrom) {
+        astrom = input;
+    }
+
+    if (astrom->camera != input->camera) {
+        psError(PSWARP_ERR_DATA, true, "Input camera and astrometry camera do not match.");
+        return false;
+    }
+
+    // select the output readout
+    pmFPAview *view = pmFPAviewAlloc(0);
+    view->chip = 0;
+    view->cell = 0;
+    view->readout = 0;
+    pmReadout *output = pmFPAfileThisReadout(config->files, view, "PSWARP.OUTPUT.BKGMODEL");
+    if (!output) {
+        psError(PSWARP_ERR_CONFIG, true, "Can't find output background data!\n");
+        return false;
+    }
+    psFree (view);
+    // Turn all skycell files on to generate them, and then turn them off for the loop over the input images
+    // the input, which is in a different format.
+    {
+        pswarpFileActivation(config, detectorFiles, false);
+        pswarpFileActivation(config, photFiles, false);
+        pswarpFileActivation(config, independentFiles, false);
+        pswarpFileActivation(config, skycellFiles, true);
+        if (!pswarpIOChecksBefore(config)) {
+            psError(psErrorCodeLast(), false, "Unable to read files.");
+            goto DONE;
+        }
+        pswarpFileActivation(config, skycellFiles, false);
+    }
+    // Read the input astrometry
+    // XXX rather than use the activations here, this should just explicitly loop over the desired filerule
+    {
+
+      pmFPAfileActivate(config->files, true, "PSWARP.ASTROM");
+
+        pmChip *chip;
+        pmFPAview *view = pmFPAviewAlloc(0);
+        if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
+            psError(psErrorCodeLast(), false, "Unable to read files.");
+            goto DONE;
+        }
+
+        while ((chip = pmFPAviewNextChip (view, input->fpa, 1)) != NULL) {
+#if 0
+	  // This needs to be removed because otherwise it throws an error of duplicate PSPHOT.DETECTIONS.
+            if (!chip->process || !chip->file_exists) { continue; }
+            if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
+                psError(psErrorCodeLast(), false, "Unable to read files.");
+                goto DONE;
+            }
+#endif
+            pmCell *cell;
+            while ((cell = pmFPAviewNextCell (view, input->fpa, 1)) != NULL) {
+	      psTrace ("pswarp", 4, "ACell %d: %x %x %d\n", view->cell, cell->file_exists, cell->process,psErrorCodeLast());
+                if (!cell->process || !cell->file_exists) { continue; }
+                if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE) ||
+                    !pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) {
+                    psError(psErrorCodeLast(), false, "Unable to read files.");
+                    goto DONE;
+                }
+            }
+            if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) {
+                psError(psErrorCodeLast(), false, "Unable to write files.");
+                goto DONE;
+            }
+        }
+        if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) {
+            psError(psErrorCodeLast(), false, "Unable to write files.");
+            goto DONE;
+        }
+        psFree(view);
+        pswarpFileActivation(config, detectorFiles, true);
+        pmFPAfileActivate(config->files, false, "PSWARP.ASTROM");
+    }
+
+    // Don't care about the skycell anymore --- we've read it, and that's all we need to do.
+    pmFPAfileActivate(config->files, false, "PSWARP.SKYCELL");
+    view = pmFPAviewAlloc(0);
+
+    // find the FPA phu
+    bool bilevelAstrometry = false;
+    pmHDU *phu = pmFPAviewThisPHU(view, astrom->fpa);
+
+    //    pmAstromWCS *WCSF = pmAstromWCSfromHeader(phu->header);
+    
+    if (phu) {
+        char *ctype = psMetadataLookupStr(NULL, phu->header, "CTYPE1");
+        if (ctype) {
+            bilevelAstrometry = !strcmp (&ctype[4], "-DIS");
+        }
+    }
+    if (bilevelAstrometry) {
+        if (!pmAstromReadBilevelMosaic(input->fpa, phu->header)) {
+            psError(psErrorCodeLast(), false, "Unable to read bilevel mosaic astrometry for input FPA.");
+            psFree(view);
+            psFree(stats);
+            goto DONE;
+        }
+    }
+
+    psList *cells = psListAlloc(NULL);  // List of cells, for concepts averaging
+
+    // files associated with the science image
+    if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) {
+        psError(psErrorCodeLast(), false, "Unable to read files.");
+        goto DONE;
+    }
+    pmChip *chip;
+    while ((chip = pmFPAviewNextChip (view, input->fpa, 1)) != NULL) {
+        psTrace ("pswarp", 4, "DChip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
+        if (!chip->process || !chip->file_exists) { continue; }
+        if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) {
+            psError(psErrorCodeLast(), false, "Unable to read files.");
+            goto DONE;
+        }
+
+	// Pull information from the header of the background files so we can use it to set values.
+	pmHDU *hdu = pmFPAviewThisHDU(view,input->fpa);
+	psMetadata *header = hdu->header;
+	
+	int IMAXIS1 = psMetadataLookupS32(NULL,header,"IMNAXIS1");
+	int IMAXIS2 = psMetadataLookupS32(NULL,header,"IMNAXIS2");
+	int NAXIS1 = psMetadataLookupS32(NULL,header,"NAXIS1");
+	int NAXIS2 = psMetadataLookupS32(NULL,header,"NAXIS2");
+	char *CCDSUM = psMetadataLookupStr(NULL,header,"CCDSUM");
+	int CCDSUM1 = atoi(strtok(CCDSUM," "));
+	int CCDSUM2 = atoi(strtok(NULL," "));
+	
+	psMetadataAddF32(config->arguments,PS_LIST_TAIL,"BKG_WARP_XOFFSET", PS_META_REPLACE,
+			 "xoffset for background model data", (NAXIS1 * CCDSUM1 - IMAXIS1) / (2.0 * CCDSUM1));
+	psMetadataAddF32(config->arguments,PS_LIST_TAIL,"BKG_WARP_YOFFSET", PS_META_REPLACE,
+			 "yoffset for background model data", (NAXIS2 * CCDSUM2 - IMAXIS2) / (2.0 * CCDSUM2));
+	psTrace("pswarp",5,"%d %d %d %d %d %d %g %g %d %d",
+		psMetadataLookupS32(NULL,header,"IMNAXIS1"),
+		psMetadataLookupS32(NULL,header,"IMNAXIS2"),
+		psMetadataLookupS32(NULL,header,"NAXIS1"),
+		psMetadataLookupS32(NULL,header,"NAXIS2"),
+		CCDSUM1,CCDSUM2,
+		psMetadataLookupF32(NULL,config->arguments,"BKG_WARP_XOFFSET"),
+		psMetadataLookupF32(NULL,config->arguments,"BKG_WARP_YOFFSET"),
+		psMetadataLookupS32(NULL,config->arguments,"BKG.XGRID"),
+		psMetadataLookupS32(NULL,config->arguments,"BKG.YGRID"));
+	
+	
+        // read WCS data from the corresponding header
+        hdu = pmFPAviewThisHDU (view, astrom->fpa);
+
+	pmAstromWCS *WCS = pmAstromWCSfromHeader(hdu->header);
+
+	double cd1f = (1.0 * CCDSUM1);// * (1.0 * psMetadataLookupS32(NULL,config->arguments,"BKG.XGRID"));
+	double cd2f = (1.0 * CCDSUM2);// * (1.0 * psMetadataLookupS32(NULL,config->arguments,"BKG.YGRID"));
+
+	WCS->cdelt1 *= cd1f;
+	WCS->cdelt2 *= cd2f;
+	WCS->crpix1 = WCS->crpix1 / cd1f;
+	WCS->crpix2 = WCS->crpix2 / cd2f;
+
+	// WCS->trans->x->nX/nY
+	for (int q = 0; q <= WCS->trans->x->nX; q++) {
+	  for (int r = 0; r <= WCS->trans->x->nY; r++) {
+	    WCS->trans->x->coeff[q][r] *= pow(cd1f,q) * pow(cd2f,r);
+	  }
+	}
+	for (int q = 0; q <= WCS->trans->y->nX; q++) {
+	  for (int r = 0; r <= WCS->trans->y->nY; r++) {
+	    WCS->trans->y->coeff[q][r] *= pow(cd1f,q) * pow(cd2f,r);
+	  }
+	}
+	pmAstromWCStoHeader (hdu->header,WCS);
+	
+        if (bilevelAstrometry) {
+            if (!pmAstromReadBilevelChip (chip, hdu->header)) {
+                psError(psErrorCodeLast(), false, "Unable to read bilevel chip astrometry for input FPA.");
+                psFree(view);
+                psFree(stats);
+                goto DONE;
+            }
+        } else {
+            // we use a default FPA pixel scale of 1.0
+            if (!pmAstromReadWCS (astrom->fpa, chip, hdu->header, 1.0)) {
+                psError(psErrorCodeLast(), false, "Unable to read WCS astrometry for input FPA.");
+                psFree(view);
+                psFree(stats);
+                goto DONE;
+            }
+        }
+	// Modify structure here.
+
+	
+        pmCell *cell;
+        while ((cell = pmFPAviewNextCell (view, input->fpa, 1)) != NULL) {
+            psTrace ("pswarp", 4, "DCell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
+            if (!cell->process || !cell->file_exists) { continue; }
+            if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) {
+                psError(psErrorCodeLast(), false, "Unable to read files.");
+                goto DONE;
+            }
+
+            psListAdd(cells, PS_LIST_TAIL, cell);
+
+            // process each of the readouts
+            pmReadout *readout;
+            while ((readout = pmFPAviewNextReadout(view, input->fpa, 1)) != NULL) {
+                if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
+                    psError(psErrorCodeLast(), false, "Unable to read files.");
+                    goto DONE;
+                }
+                if (!readout->data_exists) {
+                    continue;
+                }
+
+		for (int x = 0; x < readout->image->numCols; x++) {
+		  for (int y = 0; y < readout->image->numRows; y++) {
+		    readout->image->data.F32[y][x] = readout->image->data.F32[y][x] * (cd1f * cd2f) /
+		      (psMetadataLookupS32(&mdok,config->arguments,"BKG.XGRID") *
+		       psMetadataLookupS32(&mdok,config->arguments,"BKG.YGRID"));
+		  }
+		}
+		
+		psMetadataAddS32(config->arguments,PS_LIST_TAIL, "INTERPOLATION.MODE", PS_META_REPLACE, "", 8);
+
+		psMetadataAddBool(config->arguments,PS_LIST_TAIL, "BACKGROUND_WARPING", PS_META_REPLACE, "", true);
+                pswarpTransformReadout(output, readout, config);
+		psMetadataAddBool(config->arguments,PS_LIST_TAIL, "BACKGROUND_WARPING", PS_META_REPLACE, "", false);
+
+                if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
+                    psError(psErrorCodeLast(), false, "Unable to write files.");
+                    goto DONE;
+                }
+            }
+            if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
+                psError(psErrorCodeLast(), false, "Unable to write files.");
+                goto DONE;
+            }
+        }
+        if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
+            psError(psErrorCodeLast(), false, "Unable to write files.");
+            goto DONE;
+        }
+    }
+    if (!output->data_exists) {
+        psWarning("No overlap between input and skycell.");
+        psphotFilesActivate(config, false);
+        psFree(cells);
+        psFree(view);
+        goto DONE;
+    }
+    pmCell *outCell = output->parent;   ///< Output cell
+    pmChip *outChip = outCell->parent;  ///< Output chip
+    pmFPA *outFPA = outChip->parent;    ///< Output FP
+
+/*     if (!pswarpPixelsLit(output, stats, config)) { */
+/*         psError(psErrorCodeLast(), false, "Unable to calculate pixel regions."); */
+/*         psFree(cells); */
+/*         psFree(view); */
+/*         goto DONE; */
+/*     } */
+    psRegion *trimsec = psMetadataLookupPtr(NULL, outCell->concepts, "CELL.TRIMSEC"); ///< Trim section
+    trimsec->x0 = trimsec->x1 = trimsec->y0 = trimsec->y1 = 0; ///< All pixels
+
+    if (!psMetadataCopy(outFPA->concepts, input->fpa->concepts)) {
+        psError(psErrorCodeLast(), false, "Unable to copy FPA concepts from input to output.");
+        psFree(stats);
+        psFree(view);
+        goto DONE;
+    }
+
+    pmHDU *hdu = outFPA->hdu;           ///< HDU for the output warped image
+
+    // Copy header from target
+    {
+        pmFPAview *skyView = pmFPAviewAlloc(0); ///< View into skycell
+        skyView->chip = skyView->cell = 0;
+        pmCell *cell = pmFPAfileThisCell(config->files, skyView, "PSWARP.SKYCELL"); // Skycell cell
+        psFree(skyView);
+        pmHDU *skyHDU = pmHDUFromCell(cell); ///< HDU
+        if (!skyHDU) {
+            psError(PSWARP_ERR_DATA, false, "Unable to find skycell HDU.");
+            psFree(view);
+            goto DONE;
+        }
+        hdu->header = psMetadataCopy(hdu->header, skyHDU->header);
+    }
+    pswarpVersionHeader(hdu->header);
+    
+    if (!pmAstromWriteWCS(hdu->header, outFPA, outChip, WCS_NONLIN_TOL)) {
+        psError(psErrorCodeLast(), false, "Unable to generate WCS header.");
+        psFree(stats);
+        goto DONE;
+    }
+    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
+        psError(psErrorCodeLast(), false, "Unable to write files.");
+        goto DONE;
+    }
+    // Done with the detector side of things
+    pswarpFileActivation(config, detectorFiles, false);
+    pswarpFileActivation(config, independentFiles, false);
+
+    // Add MD5 information for readout
+    const char *chipName = psMetadataLookupStr(NULL, output->parent->parent->concepts, "CHIP.NAME");
+    const char *cellName = psMetadataLookupStr(NULL, output->parent->concepts, "CELL.NAME");
+    psString headerName = NULL; ///< Header name for MD5
+    psStringAppend(&headerName, "MD5_%s_%s_%d", chipName, cellName, view->readout);
+    psVector *md5 = psImageMD5(output->image); ///< md5 hash
+    psString md5string = psMD5toString(md5); ///< String
+    psFree(md5);
+    psMetadataAddStr(hdu->header, PS_LIST_TAIL, headerName, PS_META_REPLACE,
+                     "Image MD5", md5string);
+    psFree(md5string);
+    psFree(headerName);
+    psFree(view);
+ DONE:
+
+    return true;
+}
Index: branches/eam_branches/ipp-20130419/pswarp/src/pswarpParseCamera.c
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/pswarpParseCamera.c	(revision 35420)
+++ branches/eam_branches/ipp-20130419/pswarp/src/pswarpParseCamera.c	(revision 35421)
@@ -55,7 +55,4 @@
 }
 
-
-
-
 bool pswarpParseCamera(pmConfig *config)
 {
@@ -70,7 +67,21 @@
     }
 
-    pmFPAfile *astrom = defineInputFile(config, NULL, "PSWARP.ASTROM", "ASTROM", PM_FPA_FILE_CMF);
+    // XXX I should allow the astrometry input to be either WCS or CMF
+    // Define the input astrometry file(s)
+    bool status = false;
+    pmFPAfile *astrom = pmFPAfileDefineFromArgs(&status, config, "PSWARP.ASTROM", "ASTROM");
+    if (!astrom) {
+        // look for the file on the RUN metadata
+        astrom = pmFPAfileDefineFromRun(&status, NULL, config, "PSWARP.ASTROM"); // File to return
+        if (!status) {
+            psLogMsg("pswarp", PS_LOG_INFO, "Failed to load file definition for %s", "PSWARP.ASTROM");
+        }
+    }
+    if ((astrom->type != PM_FPA_FILE_CMF) && (astrom->type != PM_FPA_FILE_WCS)) {
+	psLogMsg("pswarp", PS_LOG_INFO, "%s is neither CMF nor WCS", "PSWARP.ASTROM");
+    }
     psLogMsg("pswarp", PS_LOG_INFO, "Astrometry source: %s", astrom ? "supplied" : "header");
 
+    // Define the input mask file(s)
     pmFPAfile *inMask = defineInputFile(config, input, "PSWARP.MASK", "MASK", PM_FPA_FILE_MASK);
     if (!inMask) {
@@ -78,4 +89,5 @@
     }
 
+    // Define the input variance file(s)
     pmFPAfile *inVariance = defineInputFile(config, input, "PSWARP.VARIANCE", "VARIANCE",
                                             PM_FPA_FILE_VARIANCE);
@@ -91,12 +103,20 @@
     
     // The input skycell is a required argument: it defines the output image
-    // XXX we may need a different skycell structure here
+    pmConfig *skyConfig = NULL;
     pmFPAfile *skycell = NULL;
-    pmConfig *skyConfig = NULL;
-    bool status = pswarpDefineSkycell(&skycell, &skyConfig, config, "PSWARP.SKYCELL", "SKYCELL");
-    if (!status) {
-        psError(psErrorCodeLast(), false, "Failed to build FPA from PSWARP.SKYCELL");
-        return false;
-    }
+
+# define USE_PSWARP_DEFINE_SKYCELL 0
+# if (USE_PSWARP_DEFINE_SKYCELL)
+    // XXX this function is no longer needed; drop
+    status = pswarpDefineSkycell(&skycell, &skyConfig, config, "PSWARP.SKYCELL", "SKYCELL");
+# else
+    skycell = pmFPAfileDefineNewConfig(&status, &skyConfig, config, "PSWARP.SKYCELL", "SKYCELL");
+# endif
+
+    if (!status || !skycell) {
+      psError(psErrorCodeLast(), false, "Failed to build FPA from PSWARP.SKYCELL");
+      return false;
+      }
+    psMetadataAddStr(config->arguments, PS_LIST_TAIL, "SKYCELL.CAMERA", 0, "Name of camera for skycell", skyConfig->cameraName);
     psFree(skyConfig);
 
@@ -142,8 +162,4 @@
     if (inBackground && psMetadataLookupBool(&mdok, recipe, "BACKGROUND.MODEL")) {
       pmFPAfile *outBackground = pmFPAfileDefineSkycell(config, NULL, "PSWARP.OUTPUT.BKGMODEL");
-/*       pmFPAfile *outBackground = pmFPAfileDefineFromFPA(config,output->fpa, */
-/* 							psMetadataLookupS32(&mdok,recipe,"BKG.XGRID"), */
-/* 							psMetadataLookupS32(&mdok,recipe,"BKG.YGRID"), */
-/* 							"PSWARP.OUTPUT.BKGMODEL"); */
       outBackground->xBin = psMetadataLookupS32(&mdok, recipe, "BKG.XGRID");
       outBackground->yBin = psMetadataLookupS32(&mdok, recipe, "BKG.YGRID");
Index: branches/eam_branches/ipp-20130419/pswarp/src/pswarpStatsFile.c
===================================================================
--- branches/eam_branches/ipp-20130419/pswarp/src/pswarpStatsFile.c	(revision 35421)
+++ branches/eam_branches/ipp-20130419/pswarp/src/pswarpStatsFile.c	(revision 35421)
@@ -0,0 +1,94 @@
+/** @file pswarpStatsFile.c
+ *
+ *  @brief functions for managing the stats file (or return NULL, or exit with an error)
+ *  @ingroup pswarp
+ *
+ *  @author IfA
+ *  @version $Revision: 1.38 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-13 21:54:32 $
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+#include "pswarp.h"
+
+static void pswarpStatsFileFree (pswarpStatsFile *statsFile) {
+    psFree (statsFile->name);
+    psFree (statsFile->md);
+}
+
+pswarpStatsFile *pswarpStatsFileAlloc () {
+
+    pswarpStatsFile *statsFile = psAlloc(sizeof(pswarpStatsFile));
+    psMemSetDeallocator(statsFile, (psFreeFunc)pswarpStatsFileFree);
+
+    statsFile->f = NULL;
+    statsFile->name = NULL;
+    statsFile->md = NULL;
+
+    return statsFile;
+}
+
+// Open the statistics file
+pswarpStatsFile *pswarpStatsFileOpen (pmConfig *config) {
+
+    bool mdok;
+
+    char *name = psMetadataLookupStr(&mdok, config->arguments, "STATS"); ///< Filename for statistics
+
+    pswarpStatsFile *statsFile = pswarpStatsFileAlloc ();
+    statsFile->name = name;
+
+    if (!mdok) return statsFile; // XXX this is probably a config error, but treat as ok for now
+    if (!name) return statsFile;
+    if (strlen(name) == 0) return statsFile;
+
+    psString resolved = pmConfigConvertFilename(name, config, true, true);
+
+    statsFile->f = fopen(resolved, "w");
+    if (!statsFile->f) {
+	psError(PS_ERR_IO, true, "Unable to open statistics file %s for writing.\n", resolved);
+	psFree(resolved);
+        pswarpCleanup(config, statsFile);
+    }
+    psFree(resolved);
+
+    statsFile->md = psMetadataAlloc();
+    psMetadataAddS32(statsFile->md, PS_LIST_TAIL, "QUALITY", 0, "No problems", 0);
+
+    return statsFile;
+}
+
+bool pswarpStatsFileSave (pmConfig *config, pswarpStatsFile *statsFile) {
+
+    if (!statsFile) return true;
+    if (!statsFile->md) return true;
+
+    // Write out summary statistics
+    psMetadataAddF32(statsFile->md, PS_LIST_TAIL, "DT_WARP", 0, "Time for warp completion", psTimerMark("pswarp"));
+
+    // convert the psMetadata to a string block
+    const char *statsMDC = psMetadataConfigFormat(statsFile->md);
+    if (!statsMDC) {
+	psError(psErrorCodeLast(), false, "Unable to get statistics file.");
+	return false;
+    }
+
+    if (fprintf(statsFile->f, "%s", statsMDC) != strlen(statsMDC)) {
+	psError(PSWARP_ERR_IO, true, "Unable to write statistics file.");
+	return false;
+    }
+    psFree(statsMDC);
+
+    if (fclose(statsFile->f) == EOF) {
+	psError(PSWARP_ERR_IO, true, "Unable to close statistics file.");
+	statsFile->f = NULL;
+	return false;
+    }
+    statsFile->f = NULL;
+
+    pmConfigRunFilenameAddWrite(config, "STATS", statsFile->name);
+    psFree(statsFile);
+
+    return true;
+}
+
