Blame view

php/classes/VOTableMgr.php 17.1 KB
16035364   Benjamin Renard   First commit
1
2
3
<?php
/**
 * @class VOTableMgr
ee761f1a   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
ee761f1a   Nathanael Jourdane   Make the VOTable ...
8
define("DEBUG_MODE", TRUE);
16035364   Benjamin Renard   First commit
9
10
11


class VOTableMgr {
f740e66b   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
c333373a   Nathanael Jourdane   Fix VOtable conve...
16
	private $is_little_endian;
f740e66b   Nathanael Jourdane   Improve the VOTab...
17
18
19
20
21
22

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

f740e66b   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

ee761f1a   Nathanael Jourdane   Make the VOTable ...
30
31
	function load($fileName) {
		$this->addLog("File name" . $fileName);
c333373a   Nathanael Jourdane   Fix VOtable conve...
32
		$this->is_little_endian = array_values(unpack('L1L', pack('V', 1)))[0] == 1;
ee761f1a   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();
f740e66b   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;
ee761f1a   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;
	}

f740e66b   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";
	}
ee761f1a   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";
	}


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

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

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

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

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

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

c333373a   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) {
f740e66b   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':
c333373a   Nathanael Jourdane   Fix VOtable conve...
243
				$block_size = 16;
f740e66b   Nathanael Jourdane   Improve the VOTab...
244
245
246
247
			default:
				$block_size = 0;
				break;
		}
f740e66b   Nathanael Jourdane   Improve the VOTab...
248

f740e66b   Nathanael Jourdane   Improve the VOTab...
249
250
251
		if($field_node->getAttribute("arraysize") == NULL) {
			$array_size = $block_size;
		} else if("*" == $field_node->getAttribute("arraysize")) {
f740e66b   Nathanael Jourdane   Improve the VOTab...
252
			$array_size = unpack("Ns", substr($this->stream, $this->c, 4))["s"] * $block_size;
f740e66b   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;
	}
ee761f1a   Nathanael Jourdane   Make the VOTable ...
259
260

	/** Get the VOTable stream content.*/
f740e66b   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);
f740e66b   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);
ee761f1a   Nathanael Jourdane   Make the VOTable ...
287
			}
f740e66b   Nathanael Jourdane   Improve the VOTab...
288
289
			$n_value+=1;
			// echo "Char pos: $this->c\n";
ee761f1a   Nathanael Jourdane   Make the VOTable ...
290
		}
f740e66b   Nathanael Jourdane   Improve the VOTab...
291
292
		return $data;
	}
ee761f1a   Nathanael Jourdane   Make the VOTable ...
293

c333373a   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;
	// }

f740e66b   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);
c333373a   Nathanael Jourdane   Fix VOtable conve...
337
338
		$substr = substr($this->stream, $this->c, $row_size);

f740e66b   Nathanael Jourdane   Improve the VOTab...
339
340
341
		switch ($data_type) {
			case 'boolean':
			case 'unsignedByte':
c333373a   Nathanael Jourdane   Fix VOtable conve...
342
343
				$b = $substr;
				$res = $b == "T" || $b == "t" || $b == "1";
f740e66b   Nathanael Jourdane   Improve the VOTab...
344
345
346
				break;
			case 'char':
			case 'unicodeChar':
c333373a   Nathanael Jourdane   Fix VOtable conve...
347
				$res = $row_size!=0 ? $substr : NULL;
f740e66b   Nathanael Jourdane   Improve the VOTab...
348
349
				break;
			case 'short':
c333373a   Nathanael Jourdane   Fix VOtable conve...
350
				$res = unpack("ss", $substr)["s"];
f740e66b   Nathanael Jourdane   Improve the VOTab...
351
352
				break;
			case 'int':
c333373a   Nathanael Jourdane   Fix VOtable conve...
353
				$res = unpack("Ns", $substr)["s"];
f740e66b   Nathanael Jourdane   Improve the VOTab...
354
355
				break;
			case 'long':
c333373a   Nathanael Jourdane   Fix VOtable conve...
356
				$res = unpack("Js", $substr)["s"];  // /!\ J -> PHP 5.6 only
f740e66b   Nathanael Jourdane   Improve the VOTab...
357
358
				break;
			case 'float':
c333373a   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"];
				}
f740e66b   Nathanael Jourdane   Improve the VOTab...
365
366
				break;
			case 'double':
c333373a   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"];
				}
f740e66b   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;
ee761f1a   Nathanael Jourdane   Make the VOTable ...
382
383
	}

ee761f1a   Nathanael Jourdane   Make the VOTable ...
384

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

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

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

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

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

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

f740e66b   Nathanael Jourdane   Improve the VOTab...
403
		 $node = $tabledata->firstChild;
ee761f1a   Nathanael Jourdane   Make the VOTable ...
404

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

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

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

f740e66b   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;
f740e66b   Nathanael Jourdane   Improve the VOTab...
419
	}
ee761f1a   Nathanael Jourdane   Make the VOTable ...
420

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

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

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

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

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

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

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

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

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

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

f740e66b   Nathanael Jourdane   Improve the VOTab...
456
457
		 return -1;
	}
ee761f1a   Nathanael Jourdane   Make the VOTable ...
458

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

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

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

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

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

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

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

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

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

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

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

f740e66b   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")){
f740e66b   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"))
f740e66b   Nathanael Jourdane   Improve the VOTab...
610
		$id = "col".$n;
16035364   Benjamin Renard   First commit
611
	else $id = $field->getAttribute("ID");
ee761f1a   Nathanael Jourdane   Make the VOTable ...
612

f740e66b   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
								);
	}
ee761f1a   Nathanael Jourdane   Make the VOTable ...
622

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

f740e66b   Nathanael Jourdane   Improve the VOTab...
628
		$fields_info = array();
ee761f1a   Nathanael Jourdane   Make the VOTable ...
629

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

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

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

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

f740e66b   Nathanael Jourdane   Improve the VOTab...
643
644
		return $fields_info;
	}
ee761f1a   Nathanael Jourdane   Make the VOTable ...
645

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

f740e66b   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

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

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

f740e66b   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;
			}
ee761f1a   Nathanael Jourdane   Make the VOTable ...
675

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

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

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

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

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

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

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

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

f740e66b   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');
f740e66b   Nathanael Jourdane   Improve the VOTab...
708
709
	$ucd	= $field->getAttribute('ucd');
	$datatype	= $field->getAttribute('datatype');
16035364   Benjamin Renard   First commit
710
	$firstTD = $i;
f740e66b   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++;
ee761f1a   Nathanael Jourdane   Make the VOTable ...
722
	if (strpos($field->getAttribute('ID'),'col') !== FALSE){
f740e66b   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);
		}
	}
ee761f1a   Nathanael Jourdane   Make the VOTable ...
768

16035364   Benjamin Renard   First commit
769
770
771
772
}



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