Blame view

php/classes/VOTableMgr.php 17.1 KB
16035364   Benjamin Renard   First commit
1
2
3
<?php
/**
 * @class VOTableMgr
f534c4a8   Nathanael Jourdane   Make the VOTable ...
4
 * @version $Id: VOTableMgr.php 2916 2015-05-19 13:08:33Z elena $
16035364   Benjamin Renard   First commit
5
6
 */

16035364   Benjamin Renard   First commit
7
//set DEBUG_MODE to TRUE to have some log information in user data dir
f534c4a8   Nathanael Jourdane   Make the VOTable ...
8
define("DEBUG_MODE", TRUE);
16035364   Benjamin Renard   First commit
9
10
11


class VOTableMgr {
5de62950   Nathanael Jourdane   Improve the VOTab...
12
13
14
15
	private $xml, $xp;
	private $logVotable; // The log file.
	private $stream; // The stream in the VOTable
	private $c; // Current character position on the stream
e581690d   Nathanael Jourdane   Fix VOtable conve...
16
	private $is_little_endian;
5de62950   Nathanael Jourdane   Improve the VOTab...
17
18
19
20
21
22

	function __construct()
	{
		if (DEBUG_MODE)
			$this->logVotable = fopen(LOG_DIR . "VOTable.log", "a");
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
23

5de62950   Nathanael Jourdane   Improve the VOTab...
24
25
26
27
28
	function addLog($msg)
	{
		 if (DEBUG_MODE)
		fwrite($this->logVotable, date("h:i:s A") . ": " . $msg . "\n");
	}
16035364   Benjamin Renard   First commit
29

f534c4a8   Nathanael Jourdane   Make the VOTable ...
30
31
	function load($fileName) {
		$this->addLog("File name" . $fileName);
e581690d   Nathanael Jourdane   Fix VOtable conve...
32
		$this->is_little_endian = array_values(unpack('L1L', pack('V', 1)))[0] == 1;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
33
34
35
36
37
38
39
40
41

		// see http://php.net/manual/en/domdocument.load.php#91384
		$opts = array(
			'http' => array('user_agent' => 'PHP libxml agent')
		);
		$context = stream_context_create($opts);
		libxml_set_streams_context($context);

		$this->xml = new DomDocument();
5de62950   Nathanael Jourdane   Improve the VOTab...
42
43
44
45
46
		$res = $this->xml->load($fileName);

		if(!$res) {
			$this->addLog("Can not load VOTAble.");
			return false;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
		}

		$this->checkIDAttribute();
		/*if ($this->xml->namespaceURI == '')
		{
			$this->addLog("File don't have a namespace defined\n");
			if (!$this->xml->createAttributeNS('http://www.ivoa.net/xml/VOTable/v1.1','xmlns'))
			$this->addLog("Cannot create namespace attribute\n");
		}
		$this->addLog($this->xml->namespaceURI."\n");*/

		$rootNamespace = $this->xml->lookupNamespaceUri($this->xml->namespaceURI);
		$this->xp = new domxpath($this->xml);
		$this->xp->registerNameSpace('x', $rootNamespace);

		$this->addLog($fileName . " loaded.");
		return true;
	}

5de62950   Nathanael Jourdane   Improve the VOTab...
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
	function isValidSchema()
	{
		if (!$this->xml)
			return FALSE;

		$infos = $this->xp->query($this->queryResourceInfo());
		foreach($infos as $info) {
			if($info->getAttribute('value') == 'ERROR') {
				$this->addLog("There is an error on the VOTable: " . $info->textContent);
				return FALSE;
			}
		}

		//ToDo - BRE - add validation!!
		return TRUE;

		 if (DEBUG_MODE)
			 libxml_use_internal_errors(true);

		 $vers = $this->getVersion();

		 $this->addLog("VOTable version : ".$vers."\n");

		 $result = FALSE;

		 switch ($vers)
		 {
		 	 case '1.2' :
		 	 	 $result = $this->xml->schemaValidate(XMLPATH.'VOTable-1.2.xsd');
		 	 case '1.0' :
		 	 	 $result = $this->xml->schemaValidate(XMLPATH.'VOTable-1.0.xsd');
		 	 default :
		 		 $result = $this->xml->schemaValidate(XMLPATH.'VOTable-1.1.xsd');
		 }

		 if (DEBUG_MODE)
		 {
			 $errors = libxml_get_errors();

			 foreach ($errors as $error)
			 {
			 	 $msg = '';

				switch ($error->level)
				{
					case LIBXML_ERR_WARNING:
						$msg .= ("WARNING ".$error->code.": ");
						break;
					case LIBXML_ERR_ERROR:
						$msg .= ("ERROR ".$error->code.": ");
						break;
					case LIBXML_ERR_FATAL:
						$msg .= ("FATAL ".$error->code.": ");
						break;
				}
				$msg .= ($error->message." - In line : ".$error->line." - Of file : ".$error->file."\n");

				$this->addLog($msg);
			 }

			 libxml_use_internal_errors(false);
		 }

		return $result;
	}

	protected function queryResource()
	{
		 return "//x:RESOURCE";
	}

	protected function queryResourceInfo()
	{
		return $this->queryResource()."/x:INFO";
	}

	protected function queryTable()
	{
		 return $this->queryResource()."/x:TABLE";
	}

	protected function queryDescription()
	{
		 return $this->queryTable()."/x:DESCRIPTION";
	}

	protected function queryFields()
	{
		 return $this->queryTable()."/x:FIELD";
	}

	protected function queryField($field_id)
	{
		 return $this->queryFields()."[@ID='".$field_id."']";
	}

	protected function queryFieldByName($field_id)
	{
		 return $this->queryFields()."[@name='".$field_id."']";
	}
	protected function queryFieldDescription($field_id)
	{
		 return $this->queryField($field_id)."/x:DESCRIPTION";
	}

	protected function queryData()
	{
		 return $this->queryTable()."/x:DATA";
	}

	protected function queryTableData()
	{
		 return $this->queryData()."/x:TABLEDATA";
	}

	protected function queryTR()
	{
		 return $this->queryTableData()."/x:TR";
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
185
186
187
188
189
190
191
192
193
194

	protected function queryBinaryData() {
		return $this->queryData()."/x:BINARY";
	}

	protected function queryStream() {
		return $this->queryBinaryData()."/x:STREAM";
	}


5de62950   Nathanael Jourdane   Improve the VOTab...
195
196
197
198
199
	public function getVersion()
	{
		 if (!$this->xml)
		 		return '';
		 $root = $this->xml->documentElement;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
200

5de62950   Nathanael Jourdane   Improve the VOTab...
201
202
		 return $root->getAttribute('version');
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
203

5de62950   Nathanael Jourdane   Improve the VOTab...
204
205
206
207
	public function getDescription()
	{
		 if (!$this->xp)
			 return '';
f534c4a8   Nathanael Jourdane   Make the VOTable ...
208

5de62950   Nathanael Jourdane   Improve the VOTab...
209
		 $desc = $this->xp->query($this->queryDescription());
f534c4a8   Nathanael Jourdane   Make the VOTable ...
210

5de62950   Nathanael Jourdane   Improve the VOTab...
211
212
		 if ($desc->length < 1)
			 return '';
f534c4a8   Nathanael Jourdane   Make the VOTable ...
213

5de62950   Nathanael Jourdane   Improve the VOTab...
214
215
216
		 return $desc->item(0)->nodeValue;
	}

e581690d   Nathanael Jourdane   Fix VOtable conve...
217
218
219
220
221
222
223
224
	private function get_row_size($field_node) {
		$datatype = $field_node->getAttribute("datatype");

		if($datatype == 'boolean') {
			return 1;
		}

		switch($datatype) {
5de62950   Nathanael Jourdane   Improve the VOTab...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
			case 'unsignedByte':
			case 'char':
				$block_size = 1;
				break;
			case 'unicodeChar':
			case 'short':
				$block_size = 2;
				break;
			case 'int':
			case 'float':
				$block_size = 4;
				break;
			case 'long':
			case 'double':
			case 'float_complex':
				$block_size = 8;
				break;
			case 'double_complex':
e581690d   Nathanael Jourdane   Fix VOtable conve...
243
				$block_size = 16;
5de62950   Nathanael Jourdane   Improve the VOTab...
244
245
246
247
			default:
				$block_size = 0;
				break;
		}
5de62950   Nathanael Jourdane   Improve the VOTab...
248

5de62950   Nathanael Jourdane   Improve the VOTab...
249
250
251
		if($field_node->getAttribute("arraysize") == NULL) {
			$array_size = $block_size;
		} else if("*" == $field_node->getAttribute("arraysize")) {
5de62950   Nathanael Jourdane   Improve the VOTab...
252
			$array_size = unpack("Ns", substr($this->stream, $this->c, 4))["s"] * $block_size;
5de62950   Nathanael Jourdane   Improve the VOTab...
253
254
255
256
257
258
			$this->c+=4;
		} else {
			$array_size = (int)($field_node->getAttribute("arraysize")) * $block_size;
		}
		return $array_size;
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
259
260

	/** Get the VOTable stream content.*/
5de62950   Nathanael Jourdane   Improve the VOTab...
261
262
263
264
265
266
267
268
269
270
271
	public function parseStream() {
		$data = Array();
		$fields = $this->xp->query($this->queryFields());
		$nb_columns = $fields->length;
		$row = Array();
		$n_value = 0; // index of current value
		$this->c = 0; // initialize cursor position.
		$query_stream = $this->xp->query($this->queryStream())->item(0);
		if($query_stream == NULL)
			return NULL;
		$this->stream = base64_decode($query_stream->textContent);
5de62950   Nathanael Jourdane   Improve the VOTab...
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
		$stream_len = strlen($this->stream);
		if($stream_len == 0)
			return NULL;
		while($this->c < strlen($this->stream)) {
			$col_id = $n_value % $nb_columns;
			$field_node = $fields[$col_id];

			// echo "c=$this->c, n_value=$n_value, nb_columns=$nb_columns, col_id=$col_id, column_name=" . $field_node->getAttribute("ID") . "\n";

			if($col_id == 0) {
				$row = Array();
			}
			$row[$field_node->getAttribute("ID")] = $this->process_datablock($field_node);
			if($col_id == $nb_columns-1) {
				array_push($data, $row);
f534c4a8   Nathanael Jourdane   Make the VOTable ...
287
			}
5de62950   Nathanael Jourdane   Improve the VOTab...
288
289
			$n_value+=1;
			// echo "Char pos: $this->c\n";
f534c4a8   Nathanael Jourdane   Make the VOTable ...
290
		}
5de62950   Nathanael Jourdane   Improve the VOTab...
291
292
		return $data;
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
293

e581690d   Nathanael Jourdane   Fix VOtable conve...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
	private function JDTodate($jd) {
		list($month, $day, $year) = split('/', JDToGregorian($jd));
		return "$day/$month/$year";
	}

	# because unpack for floats is hardware dependant
	// private function big_endian_unpack ($format, $data) {
	// 	$ar = unpack ($format, $data);
	// 	$vals = array_values ($ar);
	// 	echo "vals: " . json_encode($vals) . "\n";
	// 	$f = explode ('/', $format);
	// 	$i = 0;
	// 	foreach ($f as $f_k => $f_v) {
	// 		$repeater = intval (substr ($f_v, 1));
	//
	// 		if ($repeater == 0) {
	// 			$repeater = 1;
	// 		}
	// 		if ($f_v{1} == '*') {
	// 			$repeater = count ($ar) - $i;
	// 		}
	// 		if ($f_v{0} != 'd') {
	// 			$i += $repeater; continue;
	// 		}
	// 		$j = $i + $repeater;
	//
	// 		for ($a = $i; $a < $j; ++$a) {
	// 			$p = pack ('d', $vals[$i]);
	// 			$p = strrev ($p);
	// 			++$i;
	// 		}
	// 	}
	// 	$a = 0;
	// 	foreach ($ar as $ar_k => $ar_v) {
	// 		$ar[$ar_k] = $vals[$a];
	// 		++$a;
	// 	}
	// 	return $ar;
	// }

5de62950   Nathanael Jourdane   Improve the VOTab...
334
335
336
	private function process_datablock($field_node) {
		$data_type = $field_node->getAttribute("datatype");
		$row_size = $this->get_row_size($field_node);
e581690d   Nathanael Jourdane   Fix VOtable conve...
337
338
		$substr = substr($this->stream, $this->c, $row_size);

5de62950   Nathanael Jourdane   Improve the VOTab...
339
340
341
		switch ($data_type) {
			case 'boolean':
			case 'unsignedByte':
e581690d   Nathanael Jourdane   Fix VOtable conve...
342
343
				$b = $substr;
				$res = $b == "T" || $b == "t" || $b == "1";
5de62950   Nathanael Jourdane   Improve the VOTab...
344
345
346
				break;
			case 'char':
			case 'unicodeChar':
e581690d   Nathanael Jourdane   Fix VOtable conve...
347
				$res = $row_size!=0 ? $substr : NULL;
5de62950   Nathanael Jourdane   Improve the VOTab...
348
349
				break;
			case 'short':
e581690d   Nathanael Jourdane   Fix VOtable conve...
350
				$res = unpack("ss", $substr)["s"];
5de62950   Nathanael Jourdane   Improve the VOTab...
351
352
				break;
			case 'int':
e581690d   Nathanael Jourdane   Fix VOtable conve...
353
				$res = unpack("Ns", $substr)["s"];
5de62950   Nathanael Jourdane   Improve the VOTab...
354
355
				break;
			case 'long':
e581690d   Nathanael Jourdane   Fix VOtable conve...
356
				$res = unpack("Js", $substr)["s"];  // /!\ J -> PHP 5.6 only
5de62950   Nathanael Jourdane   Improve the VOTab...
357
358
				break;
			case 'float':
e581690d   Nathanael Jourdane   Fix VOtable conve...
359
360
361
362
363
364
				$res = unpack("fs", $substr)["s"];

				// If machine is little endian:
				if($this->is_little_endian) {
					$res = unpack('f1f', strrev(pack('f', $res)))["f"];
				}
5de62950   Nathanael Jourdane   Improve the VOTab...
365
366
				break;
			case 'double':
e581690d   Nathanael Jourdane   Fix VOtable conve...
367
368
369
370
371
372
				$res = unpack("ds", $substr)["s"];

				// If machine is little endian:
				if($this->is_little_endian) {
					$res = unpack('d1d', strrev(pack('d', $res)))["d"];
				}
5de62950   Nathanael Jourdane   Improve the VOTab...
373
374
375
376
377
378
379
380
381
				break;
			default:
				$res = NULL;
				$this->addLog("Unknown character: $data_type");
				break;
		}
		$this->c+=$row_size;
		// echo $field_node->getAttribute("ID") . "($data_type $row_size) = " . json_encode($res) . "\n";
		return $res;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
382
383
	}

f534c4a8   Nathanael Jourdane   Make the VOTable ...
384

5de62950   Nathanael Jourdane   Improve the VOTab...
385
386
387
388
	public function getFirstTR()
	{
		 if (!$this->xp)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
389

5de62950   Nathanael Jourdane   Improve the VOTab...
390
		 /*$trs = $this->xp->query($this->queryTR());
f534c4a8   Nathanael Jourdane   Make the VOTable ...
391

5de62950   Nathanael Jourdane   Improve the VOTab...
392
393
		 if ($trs->length < 1)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
394

5de62950   Nathanael Jourdane   Improve the VOTab...
395
		 return $trs->item(0);*/
f534c4a8   Nathanael Jourdane   Make the VOTable ...
396

5de62950   Nathanael Jourdane   Improve the VOTab...
397
398
399
		$tabledatas = $this->xp->query($this->queryTableData());
		 if ($tabledatas->length < 1)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
400

5de62950   Nathanael Jourdane   Improve the VOTab...
401
		 $tabledata = $tabledatas->item(0);
f534c4a8   Nathanael Jourdane   Make the VOTable ...
402

5de62950   Nathanael Jourdane   Improve the VOTab...
403
		 $node = $tabledata->firstChild;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
404

5de62950   Nathanael Jourdane   Improve the VOTab...
405
406
		 while($node && ($node->nodeType != 1) && ($node->nodeName != "TR"))
			$node = $node->nextSibling;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
407

5de62950   Nathanael Jourdane   Improve the VOTab...
408
409
410
411
412
413
414
		return $node;
	}

	public function getNextTR($tr)
	{
		 if (!$this->xp)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
415

5de62950   Nathanael Jourdane   Improve the VOTab...
416
417
		while($tr->nextSibling && ($tr->nextSibling->nodeType != 1) && ($node->nodeName != "TR"))
			$tr = $tr->nextSibling;
16035364   Benjamin Renard   First commit
418
				return $tr->nextSibling;
5de62950   Nathanael Jourdane   Improve the VOTab...
419
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
420

5de62950   Nathanael Jourdane   Improve the VOTab...
421
422
423
424
	public function getTDValueByFieldIndex($tr,$field_index)
	{
		 if (!$this->xp)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
425

5de62950   Nathanael Jourdane   Improve the VOTab...
426
		 $tds = $tr->getElementsByTagName("TD");
f534c4a8   Nathanael Jourdane   Make the VOTable ...
427

5de62950   Nathanael Jourdane   Improve the VOTab...
428
429
		 if (($tds->length < 1) || ($field_index >= $tds->length))
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
430

5de62950   Nathanael Jourdane   Improve the VOTab...
431
432
		 return $tds->item($field_index)->nodeValue;
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
433

5de62950   Nathanael Jourdane   Improve the VOTab...
434
435
436
437
	protected function isTimeField($field)
	{
		if (!$this->xp)
			 return FALSE;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
438

5de62950   Nathanael Jourdane   Improve the VOTab...
439
440
		 return (($field->getAttribute("ucd") == "time.epoch") && ($field->getAttribute("xtype") == "dateTime"));
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
441

5de62950   Nathanael Jourdane   Improve the VOTab...
442
443
444
445
	public function getTimeFieldIndex()
	{
		 if (!$this->xp)
			 return -1;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
446

5de62950   Nathanael Jourdane   Improve the VOTab...
447
		 $fields = $this->xp->query($this->queryFields());
f534c4a8   Nathanael Jourdane   Make the VOTable ...
448

5de62950   Nathanael Jourdane   Improve the VOTab...
449
450
		 if ($fields->length < 1)
			 return -1;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
451

5de62950   Nathanael Jourdane   Improve the VOTab...
452
453
454
		 for ($i = 0; $i < $fields->length; $i++)
			 if ($this->isTimeField($fields->item($i)))
				 return $i;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
455

5de62950   Nathanael Jourdane   Improve the VOTab...
456
457
		 return -1;
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
458

5de62950   Nathanael Jourdane   Improve the VOTab...
459
460
461
462
	protected function getFieldByID($field_id)
	{
		 if (!$this->xp)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
463

5de62950   Nathanael Jourdane   Improve the VOTab...
464
		 $fields = $this->xp->query($this->queryFields());
f534c4a8   Nathanael Jourdane   Make the VOTable ...
465

5de62950   Nathanael Jourdane   Improve the VOTab...
466
467
		 if ($fields->length < 1)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
468

5de62950   Nathanael Jourdane   Improve the VOTab...
469
470
471
		 foreach ($fields as $field)
			 if ($field->getAttribute("ID") == $field_id)
				 return $field;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
472

5de62950   Nathanael Jourdane   Improve the VOTab...
473
474
		 return NULL;
	}
16035364   Benjamin Renard   First commit
475

5de62950   Nathanael Jourdane   Improve the VOTab...
476
477
478
479
		protected function getFieldByName($field_id)
	{
		 if (!$this->xp)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
480

5de62950   Nathanael Jourdane   Improve the VOTab...
481
		 $fields = $this->xp->query($this->queryFieldByName($field_id));
f534c4a8   Nathanael Jourdane   Make the VOTable ...
482

5de62950   Nathanael Jourdane   Improve the VOTab...
483
484
		 if ($fields->length < 1)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
485

5de62950   Nathanael Jourdane   Improve the VOTab...
486
487
488
		 foreach ($fields as $field)
			 if ($field->getAttribute("name") == $field_id)
				 return $field;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
489

5de62950   Nathanael Jourdane   Improve the VOTab...
490
491
		 return NULL;
	}
16035364   Benjamin Renard   First commit
492

5de62950   Nathanael Jourdane   Improve the VOTab...
493
	protected function checkIDAttribute(){
16035364   Benjamin Renard   First commit
494

5de62950   Nathanael Jourdane   Improve the VOTab...
495
496
497
			$fields = $this->xml->getElementsByTagName('FIELD');
			$i = 0;
			foreach ($fields as $field){
16035364   Benjamin Renard   First commit
498
499
	$i++;
	if (!$field->hasAttribute("ID")){
5de62950   Nathanael Jourdane   Improve the VOTab...
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
			$field->setAttribute("ID", "col".$i);
	}
			}
			$this->xml->saveXML();

	}

	public function getFieldIndexByID($field_id)
	{
		 if (!$this->xp)
			 return -1;

		 $fields = $this->xp->query($this->queryFields());

		 if ($fields->length < 1)
			 return -1;

		 for ($i = 0; $i < $fields->length; $i++)
			 if ($fields->item($i)->getAttribute("ID") == $field_id)
				 return $i;

		 return -1;
	}

	public function getStartStop()
	{
		 if (!$this->xp)
			 return '0 0';

		$timeIndex = $this->getTimeFieldIndex();
		if ($timeIndex < 0)
			return '0 0';

		$tr = $this->getFirstTR();

		if (!$tr)
			return '0 0';

		$start = $this->getTDValueByFieldIndex($tr,$timeIndex);

		$stop = $start;
		while ($tr)
		{
			$stop = $this->getTDValueByFieldIndex($tr,$timeIndex);
			$tr = $this->getNextTR($tr);
		}

		if (!$start)
			$start = 0;
		else
			$start = strtotime($start);

		if (!$stop)
			$stop = 0;
		else
			$stop = strtotime($stop);

		return $start." ".$stop;
	}

	public function getFieldInfoByID($field_id)
	{
	 if (!$this->xp)
			 return array("id"		=> $field_id,
										"error" => "No file loaded");

								 $field = $this->getFieldByID($field_id);

		 if (!$field)
			$field = $this->getFieldByName($field_id);

		 if (!$field)
			 return array("id"		=> $field_id,
										"error" => "This field doesn't exist");
		 return $this->getFieldInfo($field);
	}


	public function getFieldInfo($field)
	{
		if (!$this->xp)
			return array("id"		=> $field_id,
			"error" => "No file loaded");
		$description = '';
		$desc = $field->getElementsByTagName("DESCRIPTION");
		if ($desc->length >= 1)
			$description = $desc->item(0)->nodeValue;

		$size = $field->getAttribute("arraysize");
		if ($size == '')
			$size = 1;
		else
			$size = intval($size);

		switch ($field->getAttribute("datatype"))
		{
			 case "short" :
			 	 $type = "SHORT";
			 	 break;
			 case "int" :
			 	 $type = "INTEGER";
			 	 break;
			 case "long"	 :
			 case "double" :
				 $type = "DOUBLE";
				 break;
			 default :
					$type = "FLOAT";
		}
16035364   Benjamin Renard   First commit
609
	if (!$field->getAttribute("ID"))
5de62950   Nathanael Jourdane   Improve the VOTab...
610
		$id = "col".$n;
16035364   Benjamin Renard   First commit
611
	else $id = $field->getAttribute("ID");
f534c4a8   Nathanael Jourdane   Make the VOTable ...
612

5de62950   Nathanael Jourdane   Improve the VOTab...
613
614
615
616
617
618
619
620
621
		 return array("id"		 => $field->getAttribute("ID"),
								 "type"				=> $type,
								 "name"				=> $field->getAttribute("name"),
								 "ucd"				 => $field->getAttribute("ucd"),
								 "unit"				=> $field->getAttribute("unit"),
								 "size"				=> $size,
								 "description" => $description
								);
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
622

5de62950   Nathanael Jourdane   Improve the VOTab...
623
624
625
626
	public function getFieldsInfo()
	{
	 	 if (!$this->xp)
			 return array("error" => "No file loaded");
f534c4a8   Nathanael Jourdane   Make the VOTable ...
627

5de62950   Nathanael Jourdane   Improve the VOTab...
628
		$fields_info = array();
f534c4a8   Nathanael Jourdane   Make the VOTable ...
629

5de62950   Nathanael Jourdane   Improve the VOTab...
630
		 $fields = $this->xp->query($this->queryFields());
f534c4a8   Nathanael Jourdane   Make the VOTable ...
631

5de62950   Nathanael Jourdane   Improve the VOTab...
632
633
		 if ($fields->length < 1)
			 return $fields_info;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
634

5de62950   Nathanael Jourdane   Improve the VOTab...
635
636
637
638
		foreach ($fields as $field)
		{
		 	if ($this->isTimeField($field))
				continue;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
639

5de62950   Nathanael Jourdane   Improve the VOTab...
640
641
			array_push($fields_info,$this->getFieldInfo($field));
		}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
642

5de62950   Nathanael Jourdane   Improve the VOTab...
643
644
		return $fields_info;
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
645

5de62950   Nathanael Jourdane   Improve the VOTab...
646
647
648
649
650
	public function getSamplings()
	{
		 if (!$this->xp)
			 return array("minSampling" => 0,
									 "maxSampling" => 0);
f534c4a8   Nathanael Jourdane   Make the VOTable ...
651

5de62950   Nathanael Jourdane   Improve the VOTab...
652
653
654
655
		 $timeIndex = $this->getTimeFieldIndex();
		if ($timeIndex < 0)
			return array("minSampling" => 0,
									 "maxSampling" => 0);
16035364   Benjamin Renard   First commit
656

5de62950   Nathanael Jourdane   Improve the VOTab...
657
		$tr = $this->getFirstTR();
16035364   Benjamin Renard   First commit
658

5de62950   Nathanael Jourdane   Improve the VOTab...
659
660
661
		if (!$tr)
			return array("minSampling" => 0,
									 "maxSampling" => 0);
f534c4a8   Nathanael Jourdane   Make the VOTable ...
662

5de62950   Nathanael Jourdane   Improve the VOTab...
663
664
665
666
667
668
669
670
671
672
673
674
		$prevTime = 0;
		while ($tr)
		{
			$time = $this->getTDValueByFieldIndex($tr,$timeIndex);

			if ($time)
			{
				$time = strtotime($time);
				if (($prevTime > 0) && ($time-$prevTime > 0))
					$deltaT[$time-$prevTime]++;
				$prevTime = $time;
			}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
675

5de62950   Nathanael Jourdane   Improve the VOTab...
676
677
			$tr = $this->getNextTR($tr);
		}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
678

5de62950   Nathanael Jourdane   Improve the VOTab...
679
680
		$minSampling = +1.e31;
		$maxSampling = 0.0;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
681

5de62950   Nathanael Jourdane   Improve the VOTab...
682
683
		foreach ($deltaT as $key => $value)
		{
f534c4a8   Nathanael Jourdane   Make the VOTable ...
684

5de62950   Nathanael Jourdane   Improve the VOTab...
685
686
		 if ($value/count($deltaT) < 0.10)
				continue;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
687

5de62950   Nathanael Jourdane   Improve the VOTab...
688
689
690
			if ($key < $minSampling) $minSampling = $key;
			if ($key > $maxSampling) $maxSampling = $key;
		}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
691

5de62950   Nathanael Jourdane   Improve the VOTab...
692
693
694
		return array("minSampling" => $minSampling,
								 "maxSampling" => $maxSampling);
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
695

5de62950   Nathanael Jourdane   Improve the VOTab...
696
	public function args2vector($file, $paramID){
16035364   Benjamin Renard   First commit
697

5de62950   Nathanael Jourdane   Improve the VOTab...
698
	$argsArr = explode('_', $paramID);
16035364   Benjamin Renard   First commit
699

5de62950   Nathanael Jourdane   Improve the VOTab...
700
701
702
703
704
705
706
	$dom = new DOMDocument();
	$dom->load($file);
	$fields = $dom->getElementsByTagName('FIELD');
	$table = $dom->getElementsByTagName('TABLE')->item(0);
	$i=0;
	foreach ($fields as $field){
			if ($field->getAttribute('name') == $argsArr[0]){
16035364   Benjamin Renard   First commit
707
	$unit = $field->getAttribute('unit');
5de62950   Nathanael Jourdane   Improve the VOTab...
708
709
	$ucd	= $field->getAttribute('ucd');
	$datatype	= $field->getAttribute('datatype');
16035364   Benjamin Renard   First commit
710
	$firstTD = $i;
5de62950   Nathanael Jourdane   Improve the VOTab...
711
712
713
714
715
716
717
718
719
720
		}
		$i++;
	}
	if ($firstTD > 0){
		$table->removeChild($fields->item($firstTD + 2));
		$table->removeChild($fields->item($firstTD + 1));
		$table->removeChild($fields->item($firstTD));

		$i = 0;
		foreach ($fields as $field){
16035364   Benjamin Renard   First commit
721
	$i++;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
722
	if (strpos($field->getAttribute('ID'),'col') !== FALSE){
5de62950   Nathanael Jourdane   Improve the VOTab...
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
			$field->setAttribute('ID', 'col'.$i);
			$dom->saveXML();
	}
		}

		$group = $dom->createElement('GROUP');
		$group->appendChild(new DOMAttr('ID', 'info_'.$paramID));
		$table->appendChild($group);

		$param = $dom->createElement('PARAM');
		$param->appendChild(new DOMAttr('ID', 'components_'.$paramID));
		$param->appendChild(new DOMAttr('name', 'components_'.$paramID));
		$param->appendChild(new DOMAttr('datatype', 'char'));
		$param->appendChild(new DOMAttr('arraysize', '*'));
		$param->appendChild(new DOMAttr('value', $argsArr[0].' '.$argsArr[1].' '.$argsArr[2] ));
		$group->appendChild($param);

		$new_field = $dom->createElement('FIELD');
		$new_field->appendChild(new DOMAttr('ID', $paramID));
		$new_field->appendChild(new DOMAttr('name', $paramID));
		$new_field->appendChild(new DOMAttr('datatype', $datatype));
		$new_field->appendChild(new DOMAttr('arraysize', '3'));
		$new_field->appendChild(new DOMAttr('unit', $unit));
		$new_field->appendChild(new DOMAttr('ucd', $ucd));
		$new_field->appendChild(new DOMAttr('ref', 'info_'.$paramID));
		$table->appendChild($new_field);

		$trs = $dom->getElementsByTagName('TR');
		foreach($trs as $tr){
			$tds = $tr->getElementsByTagName('TD');
			$value = trim($tds->item($firstTD)->nodeValue).' '.trim($tds->item($firstTD + 1)->nodeValue).' '.trim($tds->item($firstTD + 2)->nodeValue);
			$toRemote	= $tds->item($firstTD);
			$tr->removeChild($toRemote);
			 $toRemote = $tds->item($firstTD);
			$tr->removeChild($toRemote);
			 $toRemote = $tds->item($firstTD);
			$tr->removeChild($toRemote);

			$td = $dom->createElement('TD', $value);
			$tr->appendChild($td);
		}

		$dom->save($file);
		}
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
768

16035364   Benjamin Renard   First commit
769
770
771
772
}



f534c4a8   Nathanael Jourdane   Make the VOTable ...
773
?>