1  /*
2 				xml.c
3 
4 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 *
6 *	Part of:	SCAMP
7 *
8 *	Author:		E.BERTIN (IAP)
9 *
10 *	Contents:	XML logging.
11 *
12 *	Last modify:	14/07/2006
13 *
14 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15 */
16 
17 #ifdef HAVE_CONFIG_H
18 #include	"config.h"
19 #endif
20 
21 #include <math.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <time.h>
26 
27 #include "define.h"
28 #include "globals.h"
29 #include "fits/fitscat.h"
30 #include "field.h"
31 #include "key.h"
32 #include "prefs.h"
33 #include "xml.h"
34 
35 extern time_t		thetimet,thetimet2;	/* from makeit.c */
36 extern pkeystruct	key[];			/* from preflist.h */
37 extern char		keylist[][32];		/* from preflist.h */
38 xmlstruct		*xmlstack = NULL;
39 int			nxml=0, nxmlmax=0;
40 
41 /****** init_xml ************************************************************
42 PROTO	int	init_xml(void)
43 PURPOSE	Initialize a set of meta-data kept in memory before being written to the
44 	XML file
45 INPUT	Number of image extensions.
46 OUTPUT	RETURN_OK if everything went fine, RETURN_ERROR otherwise.
47 NOTES	-.
48 AUTHOR	E. Bertin (IAP)
49 VERSION	03/07/2006
50  ***/
init_xml(int next)51 int	init_xml(int next)
52   {
53   QMALLOC(xmlstack, xmlstruct, next);
54   nxml = 0;
55   nxmlmax = next;
56 
57   return EXIT_SUCCESS;
58   }
59 
60 
61 /****** end_xml ************************************************************
62 PROTO	int	end_xml(void)
63 PURPOSE	Free the set of meta-data kept in memory.
64 INPUT	-.
65 OUTPUT	RETURN_OK if everything went fine, RETURN_ERROR otherwise.
66 NOTES	-.
67 AUTHOR	E. Bertin (IAP)
68 VERSION	12/07/2006
69  ***/
end_xml(void)70 int	end_xml(void)
71   {
72   free(xmlstack);
73 
74   return EXIT_SUCCESS;
75   }
76 
77 /****** update_xml ***********************************************************
78 PROTO	int	update_xml(void)
79 PURPOSE	Update a set of meta-data kept in memory before being written to the
80 	XML file
81 INPUT	-.
82 OUTPUT	RETURN_OK if everything went fine, RETURN_ERROR otherwise.
83 NOTES	-.
84 AUTHOR	E. Bertin (IAP)
85 VERSION	11/07/2006
86  ***/
update_xml(sexcatstruct * sexcat,picstruct * dfield,picstruct * field,picstruct * dwfield,picstruct * wfield)87 int	update_xml(sexcatstruct *sexcat, picstruct *dfield, picstruct *field,
88 		picstruct *dwfield, picstruct *wfield)
89   {
90    xmlstruct	*x;
91 
92   if (nxml >= nxmlmax)
93     error(EXIT_FAILURE, "*Internal Error*: too many extensions in XML stack",
94 			"");
95   x = &xmlstack[nxml++];
96   x->currext = sexcat->currext;
97   x->ndetect = sexcat->ndetect;
98   x->ntotal = sexcat->ntotal;
99   strcpy(x->ext_date, sexcat->ext_date);
100   strcpy(x->ext_time, sexcat->ext_time);
101   x->ext_elapsed = sexcat->ext_elapsed;
102   strcpy(x->ident[0], dfield->ident);
103   strcpy(x->ident[1], field->ident);
104   x->backmean[0] = dfield->backmean;
105   x->backmean[1] = field->backmean;
106   x->backsig[0] = dfield->backsig;
107   x->backsig[1] = field->backsig;
108   x->sigfac[0] = dfield->sigfac;
109   x->sigfac[1] = field->sigfac;
110   x->thresh[0] = dfield->dthresh;
111   x->thresh[1] = field->thresh;
112   x->pixscale[0] = dfield->pixscale;
113   x->pixscale[1] = field->pixscale;
114   x->epoch[0] = dfield->epoch;
115   x->epoch[1] = field->epoch;
116 
117   return EXIT_SUCCESS;
118   }
119 
120 
121 /****** write_xml ************************************************************
122 PROTO	int	write_xml(char *filename)
123 PURPOSE	Save meta-data to an XML file/stream.
124 INPUT	XML file name.
125 OUTPUT	RETURN_OK if everything went fine, RETURN_ERROR otherwise.
126 NOTES	-.
127 AUTHOR	E. Bertin (IAP)
128 VERSION	14/07/2006
129  ***/
write_xml(char * filename)130 int	write_xml(char *filename)
131   {
132    FILE		*file;
133 
134   if (!(file = fopen(prefs.xml_name, "w")))
135     return RETURN_ERROR;
136 
137   write_xml_header(file);
138   write_vo_fields(file);
139 
140   fprintf(file, "   <DATA>\n");
141   if (prefs.cat_type == FITS_LDAC || prefs.cat_type == FITS_TPX
142 	|| prefs.cat_type == FITS_10)
143     fprintf(file,
144 	"   <FITS extnum=\"%d\"><STREAM href=\"%s%s\" /> </FITS>",
145 	prefs.cat_type == FITS_10? 1:2,
146 	prefs.cat_name[0] == '/'? "file://" : "file:",
147 	prefs.cat_name);
148   fprintf(file, "   </DATA>\n");
149   fprintf(file, "  </TABLE>\n");
150 
151   write_xml_meta(file, (char *)NULL);
152 
153   fprintf(file, "</RESOURCE>\n");
154   fprintf(file, "</VOTABLE>\n");
155 
156   fclose(file);
157 
158   return RETURN_OK;
159   }
160 
161 
162 /****** write_xml_header ******************************************************
163 PROTO	int	write_xml_header(FILE *file)
164 PURPOSE	Save an XML-VOtable header to an XML file/stream
165 INPUT	file or stream pointer.
166 OUTPUT	RETURN_OK if everything went fine, RETURN_ERROR otherwise.
167 NOTES	-.
168 AUTHOR	E. Bertin (IAP)
169 VERSION	14/07/2006
170  ***/
write_xml_header(FILE * file)171 int	write_xml_header(FILE *file)
172   {
173    char		*filename, *rfilename;
174 
175 /* A short, "relative" version of the filename */
176   filename = prefs.image_name[prefs.nimage_name>1? 1:0];
177   if (!(rfilename = strrchr(filename, '/')))
178     rfilename = filename;
179   else
180     rfilename++;
181 
182   fprintf(file, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
183   fprintf(file, "<?xml-stylesheet type=\"text/xsl\" href=\"%s\"?>\n",
184 	prefs.xsl_name);
185   fprintf(file, "<VOTABLE "
186 	"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
187 	"xsi:noNamespaceSchemaLocation="
188 	"\"http://www.ivoa.net/xml/VOTable/v1.1\">\n");
189   fprintf(file, "<DESCRIPTION>produced by %s</DESCRIPTION>\n", BANNER);
190   fprintf(file, "<!-- VOTable description at "
191 	"http://www.ivoa.net/Documents/latest/VOT.html -->\n");
192   fprintf(file, "<RESOURCE ID=\"%s\" name=\"%s\">\n", BANNER, rfilename);
193   fprintf(file, " <DESCRIPTION>Catalog of sources extracted with %s"
194 	"</DESCRIPTION>\n", BANNER);
195   fprintf(file, " <INFO name=\"QUERY_STATUS\" value=\"OK\" />\n");
196   fprintf(file, " <COOSYS ID=\"J2000\" equinox=\"J2000\""
197 	" epoch=\"J%.10g\" system=\"%s\"/>\n", prefs.epoch, prefs.coosys);
198   fprintf(file, " <TABLE ID=\"Source_List\" name=\"%s/out\">\n", rfilename);
199   fprintf(file,
200 	"  <DESCRIPTION>Table of sources detected in image</DESCRIPTION>\n");
201   fprintf(file,
202 	"  <!-- Now comes the definition of each %s parameter -->\n", BANNER);
203 
204   return RETURN_OK;
205   }
206 
207 
208 /****** write_xml_meta ********************************************************
209 PROTO	int	write_xml_meta(FILE *file, char *error)
210 PURPOSE	Save meta-data to an XML-VOTable file or stream
211 INPUT	Pointer to the output file (or stream),
212 	Pointer to an error msg (or NULL).
213 OUTPUT	RETURN_OK if everything went fine, RETURN_ERROR otherwise.
214 NOTES	-.
215 AUTHOR	E. Bertin (IAP)
216 VERSION	14/07/2006
217  ***/
write_xml_meta(FILE * file,char * error)218 int	write_xml_meta(FILE *file, char *error)
219   {
220    char			*pspath,*psuser, *pshost, *str;
221    struct tm		*tm;
222    int			n;
223 
224 /* Processing date and time if msg error present */
225   if (error)
226     {
227     thetimet2 = time(NULL);
228     tm = localtime(&thetimet2);
229     sprintf(prefs.sdate_end,"%04d-%02d-%02d",
230         tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
231     sprintf(prefs.stime_end,"%02d:%02d:%02d",
232         tm->tm_hour, tm->tm_min, tm->tm_sec);
233     prefs.time_diff = difftime(thetimet2, thetimet);
234     }
235 
236 /* Username */
237   psuser = pspath = pshost = NULL;
238 #ifdef HAVE_GETENV
239   if (!(psuser=getenv("USERNAME")))	/* Cygwin,... */
240     psuser = getenv("LOGNAME");		/* Linux,... */
241   pspath = getenv("PWD");
242   pshost = getenv("HOSTNAME");
243 #endif
244 
245   fprintf(file, " <RESOURCE ID=\"MetaData\" name=\"MetaData\">\n");
246   fprintf(file, "  <DESCRIPTION>%s meta-data</DESCRIPTION>\n", BANNER);
247   fprintf(file, "  <INFO name=\"QUERY_STATUS\" value=\"OK\" />\n");
248   fprintf(file, "  <PARAM name=\"Software\" datatype=\"char\" arraysize=\"*\""
249 	" ucd=\"meta.title;meta.software\" value=\"%s\"/>\n",
250 	BANNER);
251   fprintf(file, "  <PARAM name=\"Version\" datatype=\"char\" arraysize=\"*\""
252 	" ucd=\"meta.version;meta.software\" value=\"%s\"/>\n",
253 	MYVERSION);
254   fprintf(file, "  <PARAM name=\"Soft_URL\" datatype=\"char\" arraysize=\"*\""
255 	" ucd=\"meta.ref.url;meta.software\" value=\"%s\"/>\n",
256 	WEBSITE);
257   fprintf(file, "  <PARAM name=\"Soft_Auth\" datatype=\"char\" arraysize=\"*\""
258 	" ucd=\"meta.bib.author;meta.software\" value=\"%s\"/>\n",
259 	"Emmanuel Bertin");
260   fprintf(file, "  <PARAM name=\"Soft_Ref\" datatype=\"char\" arraysize=\"*\""
261 	" ucd=\"meta.bib.bibcode;meta.software\" value=\"%s\"/>\n",
262 	"1996A&amp;AS..117..393B");
263   fprintf(file, "  <PARAM name=\"NThreads\" datatype=\"int\""
264 	" ucd=\"meta.number;meta.software\" value=\"%d\"/>\n",
265     	prefs.nthreads);
266   fprintf(file, "  <PARAM name=\"Date\" datatype=\"char\" arraysize=\"*\""
267 	" ucd=\"time.event.end;meta.software\" value=\"%s\"/>\n",
268 	prefs.sdate_end);
269   fprintf(file, "  <PARAM name=\"Time\" datatype=\"char\" arraysize=\"*\""
270 	" ucd=\"time.event.end;meta.software\" value=\"%s\"/>\n",
271 	prefs.stime_end);
272   fprintf(file, "  <PARAM name=\"Duration\" datatype=\"float\""
273 	" ucd=\"time.event;meta.software\" value=\"%.0f\" unit=\"s\"/>\n",
274 	prefs.time_diff);
275 
276   fprintf(file, "  <PARAM name=\"User\" datatype=\"char\" arraysize=\"*\""
277 	" ucd=\"meta.curation\" value=\"%s\"/>\n",
278 	psuser);
279   fprintf(file, "  <PARAM name=\"Host\" datatype=\"char\" arraysize=\"*\""
280 	" ucd=\"meta.curation\" value=\"%s\"/>\n",
281 	pshost);
282   fprintf(file, "  <PARAM name=\"Path\" datatype=\"char\" arraysize=\"*\""
283 	" ucd=\"meta.dataset\" value=\"%s\"/>\n",
284 	pspath);
285 
286   fprintf(file,
287 	"  <PARAM name=\"Image_Name\" datatype=\"char\" arraysize=\"*\""
288 	" ucd=\"obs.image;meta.fits\" value=\"%s", prefs.image_name[0]);
289   if (prefs.nimage_name>1)
290     fprintf(file, ",%s", prefs.image_name[1]);
291   fprintf(file, "\"/>\n");
292 
293   if (error)
294     {
295     fprintf(file, "\n  <!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
296 	"!!!!!!!!!!!!!!!!!!!! -->\n");
297     fprintf(file, "  <!-- !!!!!!!!!!!!!!!!!!!!!! an Error occured"
298 	" !!!!!!!!!!!!!!!!!!!!! -->\n");
299     fprintf(file, "  <!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
300 	"!!!!!!!!!!!!!!!!!!!! -->\n");
301     fprintf(file,"  <PARAM name=\"Error_Msg\" datatype=\"char\" arraysize=\"*\""
302 	" ucd=\"meta\" value=\"%s\"/>\n", error);
303     fprintf(file, "  <!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
304 	"!!!!!!!!!!!!!!!!!!!! -->\n");
305     fprintf(file, "  <!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
306 	"!!!!!!!!!!!!!!!!!!!! -->\n\n");
307     }
308 
309 /* Meta-data for each extension */
310   fprintf(file, "  <TABLE ID=\"Extension_Data\" name=\"Extension_Data\">\n");
311   fprintf(file, "   <DESCRIPTION>Data gathered by %s for every FITS"
312 	" extension</DESCRIPTION>\n", BANNER);
313   fprintf(file, "   <!-- NExtensions may be 0"
314 	" if an error occurred early in the processing -->\n");
315   fprintf(file, "   <PARAM name=\"NExtensions\" datatype=\"int\""
316 	" ucd=\"meta.number;meta.dataset\" value=\"%d\"/>\n",
317 	nxmlmax);
318   fprintf(file, "   <!-- CurrExtension may differ fromq n_extensions"
319 	" if an error occurred -->\n");
320   fprintf(file, "   <PARAM name=\"CurrExtension\" datatype=\"int\""
321 	" ucd=\"meta.number;meta.dataset\" value=\"%d\"/>\n",
322 	nxml);
323   fprintf(file, "   <FIELD name=\"Extension\" datatype=\"int\""
324 	" ucd=\"meta.record\"/>\n");
325   fprintf(file, "   <FIELD name=\"Date\" datatype=\"char\" arraysize=\"*\""
326 	" ucd=\"meta.record;time.event.end\"/>\n");
327   fprintf(file, "   <FIELD name=\"Time\" datatype=\"char\" arraysize=\"*\""
328 	" ucd=\"meta.record;time.event.end\"/>\n");
329   fprintf(file, "   <FIELD name=\"Duration\" datatype=\"float\""
330 	" ucd=\"meta.record;time.event.end\"/>\n");
331   fprintf(file, "   <FIELD name=\"NDetect\" datatype=\"int\""
332 	" ucd=\"meta.number;src.sample\"/>\n");
333   fprintf(file, "   <FIELD name=\"NSextracted\" datatype=\"int\""
334 	" ucd=\"meta.number;src.sample\"/>\n");
335   fprintf(file, "   <FIELD name=\"Image_Ident\" datatype=\"char\""
336 	" arraysize=\"*\" ucd=\"meta.id;obs\"/>\n");
337   fprintf(file, "   <FIELD name=\"Background_Mean\" datatype=\"float\""
338 	" arraysize=\"%d\" ucd=\"instr.skyLevel;obs.image;stat.median\""
339 	" unit=\"ct\"/>\n", prefs.nimage_name);
340   fprintf(file, "   <FIELD name=\"Background_StDev\" datatype=\"float\""
341 	" arraysize=\"%d\" ucd=\"stat.stdev;obs.image;stat.median\""
342 	" unit=\"ct\"/>\n", prefs.nimage_name);
343   fprintf(file, "   <FIELD name=\"Threshold\" datatype=\"float\""
344 	" arraysize=\"%d\" ucd=\"instr.sensitivity;obs.image;stat.median\""
345 	" unit=\"ct\"/>\n", prefs.nimage_name);
346   fprintf(file, "   <FIELD name=\"Weight_Scaling\" datatype=\"float\""
347 	" arraysize=\"%d\" ucd=\"arith.factor;obs.image;stat.median\"/>\n",
348 	prefs.nimage_name);
349   fprintf(file, "   <FIELD name=\"Pixel_Scale\" datatype=\"float\""
350 	" arraysize=\"%d\" ucd=\"instr.scale;obs.image;stat.mean\""
351 	" unit=\"arcsec\"/>\n", prefs.nimage_name);
352   fprintf(file, "   <FIELD name=\"Epoch\" datatype=\"float\""
353 	" arraysize=\"%d\" ucd=\"time.epoch;obs\" unit=\"yr\"/>\n",
354 	prefs.nimage_name);
355   fprintf(file, "   <DATA><TABLEDATA>\n");
356   for (n=0; n<nxml; n++)
357     if (prefs.nimage_name>1)
358       fprintf(file, "     <TR>\n"
359 	"      <TD>%d</TD><TD>%s</TD><TD>%s</TD><TD>%.0f</TD>"
360 	"<TD>%d</TD><TD>%d</TD>\n"
361 	"      <TD>%s,%s</TD>\n"
362 	"      <TD>%g %g</TD><TD>%g %g</TD><TD>%g %g</TD>"
363 	"<TD>%g %g</TD><TD>%g %g</TD>\n"
364 	"     </TR>\n",
365 	xmlstack[n].currext,
366 	xmlstack[n].ext_date,
367 	xmlstack[n].ext_time,
368 	xmlstack[n].ext_elapsed,
369 	xmlstack[n].ndetect,
370 	xmlstack[n].ntotal,
371 	xmlstack[n].ident[0], xmlstack[n].ident[1],
372 	xmlstack[n].backmean[0], xmlstack[n].backmean[1],
373 	xmlstack[n].backsig[0], xmlstack[n].backsig[1],
374 	xmlstack[n].sigfac[0], xmlstack[n].sigfac[1],
375 	xmlstack[n].thresh[0], xmlstack[n].thresh[1],
376 	xmlstack[n].pixscale[0], xmlstack[n].pixscale[1]);
377     else
378       fprintf(file, "    <TR>\n"
379 	"     <TD>%d</TD><TD>%s</TD><TD>%s</TD><TD>%.0f</TD>"
380 	"<TD>%d</TD><TD>%d</TD>\n"
381 	"     <TD>%s</TD>\n"
382 	"     <TD>%g</TD><TD>%g</TD><TD>%g</TD><TD>%g</TD><TD>%g</TD>\n"
383 	"    </TR>\n",
384 	xmlstack[n].currext,
385 	xmlstack[n].ext_date,
386 	xmlstack[n].ext_time,
387 	xmlstack[n].ext_elapsed,
388 	xmlstack[n].ndetect,
389 	xmlstack[n].ntotal,
390 	xmlstack[n].ident[0],
391 	xmlstack[n].backmean[0],
392 	xmlstack[n].backsig[0],
393 	xmlstack[n].sigfac[0],
394 	xmlstack[n].thresh[0],
395 	xmlstack[n].pixscale[0]);
396   fprintf(file, "   </TABLEDATA></DATA>\n");
397   fprintf(file, "  </TABLE>\n");
398 
399 /* Warnings */
400   fprintf(file, "  <TABLE ID=\"Warnings\" name=\"Warnings\">\n");
401   fprintf(file,
402 	"   <DESCRIPTION>%s warnings (limited to the last %d)</DESCRIPTION>\n",
403 	BANNER, WARNING_NMAX);
404   fprintf(file, "   <FIELD name=\"Date\" datatype=\"char\" arraysize=\"*\""
405 	" ucd=\"meta;time.event.end\"/>\n");
406   fprintf(file, "   <FIELD name=\"Time\" datatype=\"char\" arraysize=\"*\""
407 	" ucd=\"meta;time.event.end\"/>\n");
408   fprintf(file, "   <FIELD name=\"Msg\" datatype=\"char\" arraysize=\"*\""
409 	" ucd=\"meta\"/>\n");
410   fprintf(file, "   <DATA><TABLEDATA>\n");
411   for (str = warning_history(); *str; str = warning_history())
412     fprintf(file, "    <TR><TD>%10.10s</TD><TD>%8.8s</TD><TD>%s</TD></TR>\n",
413 	str, str+11, str+22);
414   fprintf(file, "   </TABLEDATA></DATA>\n");
415   fprintf(file, "  </TABLE>\n");
416 
417 /* Configuration file */
418   fprintf(file, "  <RESOURCE ID=\"Config\" name=\"Config\">\n");
419   fprintf(file, "   <DESCRIPTION>%s configuration</DESCRIPTION>\n", BANNER);
420   fprintf(file,
421 	"   <PARAM name=\"Command_Line\" datatype=\"char\" arraysize=\"*\""
422 	" ucd=\"obs.param\" value=\"%s",
423 	prefs.command_line[0]);
424   for (n=1; n<prefs.ncommand_line; n++)
425     fprintf(file, " %s", prefs.command_line[n]);
426   fprintf(file, "\"/>\n");
427   fprintf(file,
428 	"   <PARAM name=\"Prefs_Name\" datatype=\"char\" arraysize=\"*\""
429 	" ucd=\"obs.param;meta.file\" value=\"%s\"/>\n",
430 	prefs.prefs_name);
431 
432   if (!error)
433     {
434     fprintf(file,
435 	"   <PARAM name=\"Catalog_Type\" datatype=\"char\" arraysize=\"*\""
436 	" ucd=\"meta\" value=\"%s\"/>\n",
437     	key[findkeys("CATALOG_TYPE",keylist,
438 			FIND_STRICT)].keylist[prefs.cat_type]);
439     fprintf(file,
440 	"   <PARAM name=\"Catalog_Name\" datatype=\"char\" arraysize=\"*\""
441 	" ucd=\"meta.dataset;meta.file\" value=\"%s\"/>\n",
442 	prefs.cat_name);
443     fprintf(file,
444 	"   <PARAM name=\"Parameters_Name\" datatype=\"char\" arraysize=\"*\""
445 	" ucd=\"obs.param;meta.file\" value=\"%s\"/>\n",
446 	prefs.param_name);
447     fprintf(file,
448 	"   <PARAM name=\"Detect_Type\" datatype=\"char\" arraysize=\"*\""
449 	" ucd=\"meta.code;instr.det;obs.param\" value=\"%s\"/>\n",
450     	key[findkeys("DETECT_TYPE", keylist,
451 			FIND_STRICT)].keylist[prefs.detect_type]);
452     fprintf(file, "   <PARAM name=\"Detect_MinArea\" datatype=\"int\""
453 	" ucd=\"phys.area;obs.param\" value=\"%d\" unit=\"pix2\"/>\n",
454     	prefs.ext_minarea);
455 
456     fprintf(file,
457 	"   <PARAM name=\"Thresh_Type\" datatype=\"char\" arraysize=\"*\""
458 	" ucd=\"meta.code;instr.sensitivity;obs.param\" value=\"%s",
459     	key[findkeys("THRESH_TYPE", keylist,
460 			FIND_STRICT)].keylist[prefs.thresh_type[0]]);
461     if (prefs.nthresh_type>1)
462       fprintf(file, ",%s", key[findkeys("THRESH_TYPE", keylist,
463 			FIND_STRICT)].keylist[prefs.thresh_type[1]]);
464     fprintf(file, "\"/>\n");
465 
466     fprintf(file, "   <PARAM name=\"Detect_Thresh\" datatype=\"float\""
467 	" arraysize=\"%d\" ucd=\"instr.sensitivity;obs.param\" value=\"%g",
468 	prefs.ndthresh, prefs.dthresh[0]);
469     if (prefs.ndthresh>1)
470       fprintf(file, " %g", prefs.dthresh[1]);
471     fprintf(file, "\"/>\n");
472 
473     fprintf(file, "   <PARAM name=\"Analysis_Thresh\" datatype=\"float\""
474 	" arraysize=\"%d\" ucd=\"instr.sensitivity;obs.param\" value=\"%g",
475 	prefs.nthresh, prefs.thresh[0]);
476     if (prefs.nthresh>1)
477       fprintf(file, " %g", prefs.thresh[1]);
478     fprintf(file, "\"/>\n");
479 
480     fprintf(file,
481 	"   <PARAM name=\"Filter\" datatype=\"boolean\""
482 	" ucd=\"meta.code;obs.param\" value=\"%c\"/>\n",
483     	prefs.filter_flag? 'T':'F');
484     fprintf(file,
485 	"   <PARAM name=\"Filter_Name\" datatype=\"char\" arraysize=\"*\""
486 	" ucd=\"meta.dataset;meta.file;obs.param\" value=\"%s\"/>\n",
487 	prefs.filter_name);
488 
489     if (prefs.nfilter_thresh)
490       {
491       fprintf(file, "   <PARAM name=\"Filter_Thresh\" datatype=\"float\""
492 	" arraysize=\"%d\" ucd=\"instr.sensitivity;obs.param\" value=\"%g",
493 	prefs.nfilter_thresh, prefs.filter_thresh[0]);
494       if (prefs.nfilter_thresh>1)
495         fprintf(file, " %g", prefs.filter_thresh[1]);
496       fprintf(file, "\"/>\n");
497       }
498 
499     fprintf(file, "   <PARAM name=\"Deblend_NThresh\" datatype=\"int\""
500 	" ucd=\"meta.number;obs.param\" value=\"%d\"/>\n",
501     	prefs.deblend_nthresh);
502     fprintf(file, "   <PARAM name=\"Deblend_MinCont\" datatype=\"float\""
503 	" ucd=\"obs.param;arith.ratio\" value=\"%g\"/>\n",
504     	prefs.deblend_mincont);
505     fprintf(file,
506 	"   <PARAM name=\"Clean\" datatype=\"boolean\""
507 	" ucd=\"meta.code;obs.param\" value=\"%c\"/>\n",
508     	prefs.clean_flag? 'T':'F');
509     fprintf(file, "   <PARAM name=\"Clean_Param\" datatype=\"float\""
510 	" ucd=\"meta\" value=\"%g\"/>\n",
511     	prefs.clean_param);
512     fprintf(file,
513 	"   <PARAM name=\"Mask_Type\" datatype=\"char\" arraysize=\"*\""
514 	" ucd=\"meta.code;obs.param;\" value=\"%s\"/>\n",
515     	key[findkeys("MASK_TYPE", keylist,
516 			FIND_STRICT)].keylist[prefs.mask_type]);
517 
518     fprintf(file,
519 	"   <PARAM name=\"Weight_Type\" datatype=\"char\" arraysize=\"*\""
520 	" ucd=\"meta.code;obs.param\" value=\"%s",
521     	key[findkeys("WEIGHT_TYPE", keylist,
522 			FIND_STRICT)].keylist[prefs.weight_type[0]]);
523     if (prefs.nweight_type>1)
524       fprintf(file, ",%s", key[findkeys("WEIGHT_TYPE", keylist,
525 			FIND_STRICT)].keylist[prefs.weight_type[1]]);
526     fprintf(file, "\"/>\n");
527 
528     fprintf(file, "   <PARAM name=\"Weight_Thresh\" datatype=\"float\""
529 	" arraysize=\"%d\" ucd=\"instr.sensitivity;obs.param\" value=\"%g",
530 	prefs.nweight_thresh, prefs.weight_thresh[0]);
531     if (prefs.nweight_thresh>1)
532       fprintf(file, " %g", prefs.weight_thresh[1]);
533     fprintf(file, "\"/>\n");
534 
535     if ((prefs.weight_type[0] != WEIGHT_NONE
536 		&& prefs.weight_type[0] != WEIGHT_FROMBACK)
537 	|| (prefs.weight_type[1] != WEIGHT_NONE
538 		&& prefs.weight_type[1] != WEIGHT_FROMBACK))
539       {
540       fprintf(file,
541 	"   <PARAM name=\"Weight_Image\" datatype=\"char\" arraysize=\"*\""
542 	" ucd=\"obs.image;meta.fits;obs.param\" value=\"%s",
543     	(prefs.weight_type[0] != WEIGHT_NONE
544 	&& prefs.weight_type[0] != WEIGHT_FROMBACK) ?
545 		prefs.wimage_name[0] : NULL);
546       if (prefs.weight_type[1] != WEIGHT_NONE
547 		&& prefs.weight_type[1] != WEIGHT_FROMBACK)
548         fprintf(file, ",%s", prefs.wimage_name[1]);
549       fprintf(file, "\"/>\n");
550       }
551 
552     fprintf(file,
553 	"   <PARAM name=\"Weight_Gain\" datatype=\"boolean\""
554 	" ucd=\"meta.code;obs.param\" value=\"%c\"/>\n",
555     	prefs.weightgain_flag? 'T':'F');
556 
557     if (prefs.nimaflag)
558       {
559       fprintf(file,
560 	"   <PARAM name=\"Flag_Image\" datatype=\"char\" arraysize=\"*\""
561 	" ucd=\"obs.image;meta.fits\" value=\"%s",
562     	prefs.fimage_name[0]);
563       for (n=1; n<prefs.nimaflag; n++)
564         fprintf(file, ",%s", prefs.fimage_name[n]);
565       fprintf(file, "\"/>\n");
566       fprintf(file,
567 	"   <PARAM name=\"Flag_Type\" datatype=\"char\" arraysize=\"*\""
568 	" ucd=\"meta.code\" value=\"%s",
569     	key[findkeys("FLAG_TYPE", keylist,
570 			FIND_STRICT)].keylist[prefs.flag_type[0]]);
571       for (n=1; n<prefs.nimaflag; n++)
572         fprintf(file, ",%s", key[findkeys("FLAG_TYPE", keylist,
573 			FIND_STRICT)].keylist[prefs.flag_type[n]]);
574       fprintf(file, "\"/>\n");
575       }
576 
577     fprintf(file, "   <PARAM name=\"Phot_Apertures\" datatype=\"float\""
578 	" arraysize=\"%d\" ucd=\"obs.param\" value=\"%g",
579 	prefs.naper, prefs.apert[0]);
580     for (n=1; n<prefs.naper; n++)
581       fprintf(file, " %g", prefs.apert[n]);
582     fprintf(file, "\" unit=\"pix\"/>\n");
583 
584     fprintf(file, "   <PARAM name=\"Phot_AutoParams\" datatype=\"float\""
585 	" arraysize=\"%d\" ucd=\"obs.param;phot\" value=\"%g",
586 	prefs.nautoparam, prefs.autoparam[0]);
587     for (n=1; n<prefs.nautoparam; n++)
588       fprintf(file, " %g", prefs.autoparam[n]);
589     fprintf(file, "\"/>\n");
590 
591     fprintf(file, "   <PARAM name=\"Phot_PetroParams\" datatype=\"float\""
592 	" arraysize=\"%d\" ucd=\"obs.param;phot\" value=\"%g",
593 	prefs.npetroparam, prefs.petroparam[0]);
594     for (n=1; n<prefs.npetroparam; n++)
595       fprintf(file, " %g", prefs.petroparam[n]);
596     fprintf(file, "\"/>\n");
597 
598     fprintf(file, "   <PARAM name=\"Phot_AutoApers\" datatype=\"float\""
599 	" arraysize=\"%d\" ucd=\"obs.param;phot\" value=\"%g",
600 	prefs.nautoaper, prefs.autoaper[0]);
601     for (n=1; n<prefs.nautoaper; n++)
602       fprintf(file, " %g", prefs.autoaper[n]);
603     fprintf(file, "\"/>\n");
604 
605     fprintf(file, "   <PARAM name=\"Phot_FluxFrac\" datatype=\"float\""
606 	" arraysize=\"%d\" ucd=\"arith.factor;obs.param;phot\" value=\"%g",
607 	prefs.nflux_frac, prefs.flux_frac[0]);
608     for (n=1; n<prefs.nflux_frac; n++)
609       fprintf(file, " %g", prefs.flux_frac[n]);
610     fprintf(file, "\"/>\n");
611 
612     fprintf(file, "   <PARAM name=\"Satur_Level\" datatype=\"float\""
613 	" ucd=\"instr.saturation;phot.count;obs.param\" value=\"%g\""
614 	" unit=\"ct\"/>\n", prefs.satur_level);
615     fprintf(file, "   <PARAM name=\"Mag_ZeroPoint\" datatype=\"float\""
616 	" ucd=\"phot.calib;phot.mag;obs.param\" value=\"%g\" unit=\"mag\"/>\n",
617     	prefs.mag_zeropoint);
618     fprintf(file, "   <PARAM name=\"Mag_Gamma\" datatype=\"float\""
619 	" ucd=\"phot.calib;obs.param\" value=\"%g\"/>\n",
620     	prefs.mag_gamma);
621     fprintf(file, "   <PARAM name=\"Gain\" datatype=\"float\""
622 	" ucd=\"instr.param;obs.param\" value=\"%g\"/>\n",
623     	prefs.gain);
624     fprintf(file, "   <PARAM name=\"Pixel_Scale\" datatype=\"float\""
625 	" ucd=\"instr.scale;obs.param\" value=\"%g\" unit=\"arcsec\"/>\n",
626     	prefs.pixel_scale);
627     fprintf(file, "   <PARAM name=\"Seeing_FWHM\" datatype=\"float\""
628 	" ucd=\"instr.det.psf;stat.mean;obs.param\" value=\"%g\""
629 	" unit=\"pix\"/>\n", prefs.seeing_fwhm);
630     fprintf(file,
631 	"   <PARAM name=\"StarNNW_Name\" datatype=\"char\" arraysize=\"*\""
632 	" ucd=\"meta.dataset;meta.file;obs.param\" value=\"%s\"/>\n",
633 	prefs.nnw_name);
634 
635     fprintf(file, "   <PARAM name=\"Back_Size\" datatype=\"int\""
636 	" arraysize=\"%d\" ucd=\"obs.param\" value=\"%d",
637 	prefs.nbacksize, prefs.backsize[0]);
638     for (n=1; n<prefs.nbacksize; n++)
639       fprintf(file, " %d", prefs.backsize[n]);
640     fprintf(file, "\" unit=\"pix\"/>\n");
641 
642     fprintf(file, "   <PARAM name=\"Back_FilterSize\" datatype=\"int\""
643 	" arraysize=\"%d\" ucd=\"obs.param\" value=\"%d",
644 	prefs.nbackfsize, prefs.backfsize[0]);
645     for (n=1; n<prefs.nbackfsize; n++)
646       fprintf(file, " %d", prefs.backfsize[n]);
647     fprintf(file, "\"/>\n");
648 
649     fprintf(file,
650 	"   <PARAM name=\"BackPhoto_Type\" datatype=\"char\" arraysize=\"*\""
651 	" ucd=\"meta.code;obs.param;\" value=\"%s\"/>\n",
652     	key[findkeys("BACKPHOTO_TYPE", keylist,
653 			FIND_STRICT)].keylist[prefs.pback_type]);
654 
655     fprintf(file, "   <PARAM name=\"BackPhoto_Thick\" datatype=\"int\""
656 	" ucd=\"obs.param\" value=\"%d\" unit=\"pix\"/>\n",
657     	prefs.pback_size);
658 
659     fprintf(file, "   <PARAM name=\"Back_FiltThresh\" datatype=\"float\""
660 	" ucd=\"phot.count;arith.ratio;obs.param\" value=\"%g\"/>\n",
661     	prefs.backfthresh);
662 
663     fprintf(file,
664 	"   <PARAM name=\"CheckImage_Type\" datatype=\"char\" arraysize=\"*\""
665 	" ucd=\"meta.code\" value=\"%s",
666     	key[findkeys("CHECKIMAGE_TYPE", keylist,
667 			FIND_STRICT)].keylist[prefs.check_type[0]]);
668     for (n=1; n<prefs.ncheck_type; n++)
669       fprintf(file,
670 	",%s",
671     	key[findkeys("CHECKIMAGE_TYPE", keylist,
672 			FIND_STRICT)].keylist[prefs.check_type[n]]);
673     fprintf(file, "\"/>\n");
674 
675     fprintf(file,
676 	"   <PARAM name=\"CheckImage_Name\" datatype=\"char\" arraysize=\"*\""
677 	" ucd=\"meta.file\" value=\"%s",
678     	prefs.check_name[0]);
679     for (n=1; n<prefs.ncheck_type; n++)
680       if (prefs.check_type[n] != CHECK_NONE)
681         fprintf(file, ",%s", prefs.check_name[n]);
682     fprintf(file, "\"/>\n");
683 
684     fprintf(file, "   <PARAM name=\"Memory_ObjStack\" datatype=\"int\""
685 	" ucd=\"meta.number;src;obs.param\" value=\"%d\"/>\n",
686     	prefs.clean_stacksize);
687     fprintf(file, "   <PARAM name=\"Memory_PixStack\" datatype=\"int\""
688 	" ucd=\"meta.number;obs.param\" value=\"%d\"/>\n",
689     	prefs.mem_pixstack);
690     fprintf(file, "   <PARAM name=\"Memory_BufSize\" datatype=\"int\""
691 	" ucd=\"meta.number;obs.param\" value=\"%d\"/>\n",
692     	prefs.mem_bufsize);
693 
694     fprintf(file,
695 	"   <PARAM name=\"Assoc_Name\" datatype=\"char\" arraysize=\"*\""
696 	" ucd=\"meta.dataset;meta.file\" value=\"%s\"/>\n",
697 	prefs.assoc_name);
698     if (prefs.nassoc_data)
699       {
700       fprintf(file, "   <PARAM name=\"Assoc_Data\" datatype=\"int\""
701 	" arraysize=\"%d\" ucd=\"meta.code;obs.param\" value=\"%d",
702 	prefs.nassoc_data, prefs.assoc_data[0]);
703       for (n=1; n<prefs.nassoc_data; n++)
704         fprintf(file, " %d", prefs.assoc_data[n]);
705       fprintf(file, "\"/>\n");
706       }
707     if (prefs.nassoc_param)
708       {
709       fprintf(file, "   <PARAM name=\"Assoc_Params\" datatype=\"int\""
710 	" arraysize=\"%d\" ucd=\"meta.code;obs.param\" value=\"%d",
711 	prefs.nassoc_param, prefs.assoc_param[0]);
712       for (n=1; n<prefs.nassoc_param; n++)
713         fprintf(file, " %d", prefs.assoc_param[n]);
714       fprintf(file, "\"/>\n");
715       }
716     fprintf(file, "   <PARAM name=\"Assoc_Radius\" datatype=\"float\""
717 	" ucd=\"phys.size.radius;obs.param\" value=\"%g\" unit=\"pix\"/>\n",
718     	prefs.assoc_radius);
719     fprintf(file,
720 	"   <PARAM name=\"Assoc_Type\" datatype=\"char\" arraysize=\"*\""
721 	" ucd=\"meta.code;obs.param\" value=\"%s\"/>\n",
722     	key[findkeys("ASSOC_TYPE", keylist,
723 			FIND_STRICT)].keylist[prefs.assoc_type]);
724     fprintf(file,
725 	"   <PARAM name=\"AssocSelec_Type\" datatype=\"char\" arraysize=\"*\""
726 	" ucd=\"meta.code;obs.param\" value=\"%s\"/>\n",
727     	key[findkeys("ASSOCSELEC_TYPE", keylist,
728 			FIND_STRICT)].keylist[prefs.assocselec_type]);
729 
730     fprintf(file,
731 	"   <PARAM name=\"Verbose_Type\" datatype=\"char\" arraysize=\"*\""
732 	" ucd=\"meta.code\" value=\"%s\"/>\n",
733     	key[findkeys("VERBOSE_TYPE", keylist,
734 			FIND_STRICT)].keylist[prefs.verbose_type]);
735 
736     fprintf(file,
737 	"   <PARAM name=\"FITS_Unsigned\" datatype=\"boolean\""
738 	" ucd=\"meta.code;obs.param\" value=\"%c\"/>\n",
739     	prefs.fitsunsigned_flag? 'T':'F');
740 
741     fprintf(file,
742 	"   <PARAM name=\"PSF_Name\" datatype=\"char\" arraysize=\"*\""
743 	" ucd=\"meta.dataset;meta.file;obs.param\" value=\"%s\"/>\n",
744 	prefs.psf_name[0]);
745     fprintf(file, "   <PARAM name=\"PSF_NMax\" datatype=\"int\""
746 	" ucd=\"meta.number;obs.param\" value=\"%d\"/>\n",
747     	prefs.psf_npsfmax);
748     fprintf(file,
749 	"   <PARAM name=\"PSFDisplay_Type\" datatype=\"char\" arraysize=\"*\""
750 	" ucd=\"meta.code;obs.param\" value=\"%s\"/>\n",
751     	key[findkeys("PSFDISPLAY_TYPE", keylist,
752 			FIND_STRICT)].keylist[prefs.psfdisplay_type]);
753 
754     fprintf(file,
755 	"   <PARAM name=\"SOM_Name\" datatype=\"char\" arraysize=\"*\""
756 	" ucd=\"meta.dataset;meta.file;obs.param\" value=\"%s\"/>\n",
757 	prefs.som_name);
758     }
759 
760   fprintf(file, "  </RESOURCE>\n");
761   fprintf(file, " </RESOURCE>\n");
762 
763   return RETURN_OK;
764   }
765 
766 
767 
768 
769 /****** write_xmlerror ******************************************************
770 PROTO	int	write_xmlerror(char *error)
771 PURPOSE	Save meta-data to a simplified XML file in case of a catched error
772 INPUT	a character string.
773 OUTPUT	RETURN_OK if everything went fine, RETURN_ERROR otherwise.
774 NOTES	-.
775 AUTHOR	E. Bertin (IAP)
776 VERSION	14/07/2006
777  ***/
write_xmlerror(char * filename,char * error)778 void	write_xmlerror(char *filename, char *error)
779   {
780    FILE			*file;
781 
782   if (!(file = fopen(filename, "w")))
783     return;
784 
785   write_xml_header(file);
786 
787   fprintf(file, " </TABLE>\n");
788 
789   write_xml_meta(file, error);
790 
791   fprintf(file, "</RESOURCE>\n");
792   fprintf(file, "</VOTABLE>\n");
793 
794   fclose(file);
795 
796   return;
797   }
798 
799 
800