Index: /trunk/ppStack/src/ppStackArguments.c
===================================================================
--- /trunk/ppStack/src/ppStackArguments.c	(revision 13514)
+++ /trunk/ppStack/src/ppStackArguments.c	(revision 13515)
@@ -17,5 +17,11 @@
 {
     fprintf(stderr, "\nPan-STARRS Image combination\n\n");
-    fprintf(stderr, "Usage: %s IMAGES.list MASKS.list OUTPUT_ROOT\n",
+    fprintf(stderr, "Usage: %s INPUTS.mdc OUTPUT_ROOT\n"
+            "where INPUTS.mdc contains:\n"
+            "\tIMAGE(STR):  Image filename\n"
+            "\tMASK(STR):   Mask filename\n"
+            "\tSEEING(F32): Seeing FWHM (pixels)\n"
+            "\tWEIGHT(F32): Relative weighting to be applied\n"
+            "\tSCALE(F32):  Relative scaling to be applied\n",
             program);
     fprintf(stderr, "\n");
@@ -85,18 +91,21 @@
     psMetadataAddU8(arguments,  PS_LIST_TAIL, "-mask-bad", 0, "Mask value for bad pixels", 0);
     psMetadataAddU8(arguments,  PS_LIST_TAIL, "-mask-blank", 0, "Mask value for blank region", 0);
-    psMetadataAddStr(arguments, PS_LIST_TAIL, "-seeing", 0, "Name of file with seeing FWHMs", NULL);
 
-    if (argc == 1 || !psArgumentParse(arguments, &argc, argv) || argc != 4) {
+    if (argc == 1 || !psArgumentParse(arguments, &argc, argv) || argc != 3) {
         usage(argv[0], arguments, config);
     }
 
-    psMetadataAddStr(config->arguments, PS_LIST_TAIL, "IMAGES.LIST", 0,
-                     "Name of the input image list", argv[1]);
-    psMetadataAddStr(config->arguments, PS_LIST_TAIL, "MASKS.LIST", 0,
-                     "Name of the input masks list", argv[2]);
+    int numBad = 0;                     // Number of bad lines
+    psMetadata *inputs = psMetadataConfigRead(NULL, &numBad, argv[1], false); // Information about inputs
+    if (!inputs || numBad > 0) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to cleanly read MDC file with inputs.");
+        goto ERROR;
+    }
+    psMetadataAddMetadata(config->arguments, PS_LIST_TAIL, "INPUTS", 0,
+                          "Metadata with input details", inputs);
     psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0,
-                     "Root name of the output image list", argv[3]);
+                     "Root name of the output image list", argv[2]);
 
-    valueArgStr(config, arguments, "-stat",      "STATS",         config->arguments);
+    valueArgStr(config, arguments, "-stat", "STATS", config->arguments);
 
     psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // Recipe for ppSim
Index: /trunk/ppStack/src/ppStackCamera.c
===================================================================
--- /trunk/ppStack/src/ppStackCamera.c	(revision 13514)
+++ /trunk/ppStack/src/ppStackCamera.c	(revision 13515)
@@ -13,49 +13,54 @@
 bool ppStackCamera(pmConfig *config)
 {
-    psString imageName = psMetadataLookupStr(NULL, config->arguments, "IMAGES.LIST"); // Image list filename
-    assert(imageName);
-    psString maskName = psMetadataLookupStr(NULL, config->arguments, "MASKS.LIST"); // Mask list filename
-    assert(maskName);
-
-    psString imageList = psSlurpFilename(imageName); // Contents of image list
-    if (!imageList) {
-        psError(PS_ERR_IO, false, "Unable to read list of image files %s", imageName);
-        return false;
-    }
-    psArray *images = psStringSplitArray(imageList, "\n", false); // The image filenames
-    psFree(imageList);
-
-    psString maskList = psSlurpFilename(maskName); // Contents of mask list
-    if (!maskList) {
-        psError(PS_ERR_IO, false, "Unable to read list of mask files %s", maskName);
-        return false;
-    }
-    psArray *masks = psStringSplitArray(maskList, "\n", false); // The mask filenames
-    psFree(maskList);
-    if (images->n != masks->n) {
-        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
-                "Number input images (%ld) does not match number of input masks (%ld).",
-                images->n, masks->n);
-        psFree(images);
-        psFree(masks);
-        return false;
-    }
-
-    for (int i = 0; i < images->n; i++) {
-        psString image = images->data[i]; // Name of image
-        if (!image || strlen(image) == 0) {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Image name %d is blank.", i);
-            psFree(images);
-            psFree(masks);
-            return false;
-        }
-        psString mask = masks->data[i]; // Name of mask
-        if (!mask || strlen(mask) == 0) {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Mask name %d is blank.", i);
-            psFree(images);
-            psFree(masks);
+    psMetadata *inputs = psMetadataLookupMetadata(NULL, config->arguments, "INPUTS"); // The inputs info
+    psMetadataIterator *iter = psMetadataIteratorAlloc(inputs, PS_LIST_HEAD, NULL); // Iterator
+    psMetadataItem *item;               // Item from iteration
+    int i = 0;                          // Counter
+    while ((item = psMetadataGetAndIncrement(iter))) {
+        if (item->type != PS_DATA_METADATA) {
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    "Component %s of the input metadata is not of type METADATA", item->name);
+            psFree(iter);
             return false;
         }
 
+        psMetadata *input = item->data.md; // The input metadata of interest
+
+        psString image = psMetadataLookupStr(NULL, input, "IMAGE"); // Name of image
+        if (!image || strlen(image) == 0) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Component %s lacks IMAGE of type STR", item->name);
+            psFree(iter);
+            return false;
+        }
+
+        psString mask = psMetadataLookupStr(NULL, input, "MASK"); // Name of mask
+        if (!mask || strlen(mask) == 0) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Component %s lacks MASK of type STR", item->name);
+            psFree(iter);
+            return false;
+        }
+
+        float seeing = psMetadataLookupF32(NULL, input, "SEEING"); // Seeing FWHM
+        if (isnan(seeing)) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Component %s lacks SEEING of type F32", item->name);
+            psFree(iter);
+            return false;
+        }
+
+        float weight = psMetadataLookupF32(NULL, input, "WEIGHT"); // Relative weight
+        if (isnan(weight)) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Component %s lacks WEIGHT of type F32", item->name);
+            psFree(iter);
+            return false;
+        }
+
+        float scale = psMetadataLookupF32(NULL, input, "SCALE"); // Relative scale
+        if (isnan(scale)) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Component %s lacks SCALE of type F32", item->name);
+            psFree(iter);
+            return false;
+        }
+
+        // Add the image file
         psArray *imageFiles = psArrayAlloc(1); // Array of filenames for this FPA
         imageFiles->data[0] = psMemIncrRefCounter(image);
@@ -68,15 +73,12 @@
         if (!imageFile || !found) {
             psError(PS_ERR_UNKNOWN, false, "Unable to define file from image %d (%s)", i, image);
-            psFree(images);
-            psFree(masks);
             return false;
         }
         if (imageFile->type != PM_FPA_FILE_IMAGE) {
             psError(PS_ERR_IO, true, "PPSTACK.INPUT is not of type IMAGE");
-            psFree(images);
-            psFree(masks);
             return false;
         }
 
+        // Add the mask file
         psArray *maskFiles = psArrayAlloc(1); // Array of filenames for this FPA
         maskFiles->data[0] = psMemIncrRefCounter(mask);
@@ -90,22 +92,25 @@
         if (!maskFile || !found) {
             psError(PS_ERR_UNKNOWN, false, "Unable to define file from mask %d (%s)", i, mask);
-            psFree(images);
-            psFree(masks);
             return false;
         }
         if (maskFile->type != PM_FPA_FILE_MASK) {
             psError(PS_ERR_IO, true, "PPSTACK.INPUT.MASK is not of type MASK");
-            psFree(images);
-            psFree(masks);
             return false;
         }
+
+        psMetadataAddF32(imageFile->fpa->analysis, PS_LIST_TAIL, "PPSTACK.SEEING", 0,
+                         "Seeing for image", seeing);
+        psMetadataAddF32(imageFile->fpa->analysis, PS_LIST_TAIL, "PPSTACK.WEIGHT", 0,
+                         "Relative weight for image", weight);
+        psMetadataAddF32(imageFile->fpa->analysis, PS_LIST_TAIL, "PPSTACK.SCALE", 0,
+                         "Relative scale for image", scale);
+
+        i++;
     }
+    psFree(iter);
     psMetadataRemoveKey(config->arguments, "IMAGE.FILENAMES");
     psMetadataRemoveKey(config->arguments, "MASK.FILENAMES");
 
-    psMetadataAddS32(config->arguments, PS_LIST_TAIL, "INPUTS.NUM", 0, "Number of input files", images->n);
-
-    psFree(images);
-    psFree(masks);
+    psMetadataAddS32(config->arguments, PS_LIST_TAIL, "INPUTS.NUM", 0, "Number of input files", i);
 
     // Output image
Index: /trunk/ppStack/src/ppStackReadout.c
===================================================================
--- /trunk/ppStack/src/ppStackReadout.c	(revision 13514)
+++ /trunk/ppStack/src/ppStackReadout.c	(revision 13515)
@@ -10,7 +10,4 @@
 
 #define ARRAY_BUFFER 16                 // Number to add to array at a time
-
-
-#define WEIGHT 1.0                      // Weighting
 
 bool ppStackReadout(pmConfig *config, const pmFPAview *view)
@@ -35,15 +32,19 @@
     // Get the input sources
     psArray *stack = psArrayAllocEmpty(ARRAY_BUFFER); // The stack of inputs
-    psMetadataIterator *inputIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD,
-                                                            "^PPSTACK.INPUT$"); // Iterator over input files
-    psMetadataItem *item;               // Item from iteration
+    psMetadataIterator *fileIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD,
+                                                           "^PPSTACK.INPUT$"); // Iterator over input files
+    psMetadataItem *fileItem;           // Item from iteration
     psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); // Statistics
     psRandom *rng = psRandomAlloc(0, PS_RANDOM_TAUS); // Random number generator
     int fileNum = 0;                    // Number of file
     float totExposure = 0.0;            // Total exposure time
-    while ((item = psMetadataGetAndIncrement(inputIter))) {
-        assert(item->type == PS_DATA_UNKNOWN);
-        pmFPAfile *inputFile = item->data.V; // An input file
+    while ((fileItem = psMetadataGetAndIncrement(fileIter))) {
+        assert(fileItem->type == PS_DATA_UNKNOWN);
+        pmFPAfile *inputFile = fileItem->data.V; // An input file
         pmReadout *ro = pmFPAviewThisReadout(view, inputFile->fpa); // Corresponding readout
+
+        float seeing = psMetadataLookupF32(NULL, inputFile->fpa->analysis, "PPSTACK.SEEING"); // Seeing FWHM
+        float weight = psMetadataLookupF32(NULL, inputFile->fpa->analysis, "PPSTACK.WEIGHT"); // Rel. weight
+        float scale = psMetadataLookupF32(NULL, inputFile->fpa->analysis, "PPSTACK.SCALE"); // Rel. scale
 
         // Brain-dead background subtraction
@@ -52,5 +53,5 @@
             psFree(stats);
             psFree(rng);
-            psFree(inputIter);
+            psFree(fileIter);
             psFree(stack);
             psFree(outRO);
@@ -58,4 +59,7 @@
         }
         (void)psBinaryOp(ro->image, ro->image, "-", psScalarAlloc(stats->robustMedian, PS_TYPE_F32));
+
+        // Apply scaling
+        (void)psBinaryOp(ro->image, ro->image, "*", psScalarAlloc(1.0 / scale, PS_TYPE_F32));
 
         // Normalise each input by the exposure time
@@ -66,5 +70,5 @@
             psFree(stats);
             psFree(rng);
-            psFree(inputIter);
+            psFree(fileIter);
             psFree(outRO);
             psFree(stack);
@@ -73,11 +77,10 @@
         totExposure += exposure;        // Total exposure time
         (void)psBinaryOp(ro->image, ro->image, "/", psScalarAlloc(exposure, PS_TYPE_F32));
-        pmStackData *data = pmStackDataAlloc(ro, seeing ? seeing->data.F32[fileNum] : 0.0,
-                                             WEIGHT); // Data to stack
+        pmStackData *data = pmStackDataAlloc(ro, seeing, weight); // Data to stack
         psArrayAdd(stack, ARRAY_BUFFER, data);
         psFree(data);                   // Drop reference
         fileNum++;
     }
-    psFree(inputIter);
+    psFree(fileIter);
     psFree(stats);
     psFree(rng);
