1 'use strict'; 2 3 // 4 // this file contains just the implementation of the 5 // Observation class (I know there are no classes in javascript...) 6 // 7 8 function Observation(obj) 9 { 10 if (typeof(obj)!='object') 11 throw new Error("Observation object can only be constructed using an object."); 12 13 if (!obj.date) 14 throw new Error("Observation object must have a 'date' parameter"); 15 16 var ret = []; 17 18 // FIXME: Check transisiton from summer- and winter-time!! 19 var utc = obj.date.toString().toUpperCase()=="NOW" ? new Date() : new Date(obj.date); 20 if (isNaN(utc.valueOf())) 21 throw new Error('"'+obj.date+'" not a valid Date... try something like "2013-01-08 23:05 UTC".'); 22 ret.start = utc; 23 ret.id = obj.id; 24 25 // If the given data is not an array, make it the first entry of an array 26 // so that we can simply loop over all entries 27 if (obj.measurements.length===undefined) 28 { 29 var cpy = obj.measurements; 30 obj.measurements = []; 31 obj.measurements[0] = cpy; 32 } 33 34 for (var i=0; i<obj.measurements.length; i++) 35 { 36 var obs = obj.measurements[i]; 37 38 ret[i] = { }; 39 ret[i].task = obs.task ? obs.task.toUpperCase() : "DATA"; 40 ret[i].source = obs.source; 41 ret[i].ra = parseFloat(obs.ra); 42 ret[i].dec = parseFloat(obs.dec); 43 ret[i].zd = parseFloat(obs.zd); 44 ret[i].az = parseFloat(obs.az); 45 ret[i].orbit = parseFloat(obs.orbit); 46 ret[i].angle = parseFloat(obs.angle); 47 ret[i].time = parseInt(obs.time); 48 ret[i].threshold = parseInt(obs.threshold); 49 ret[i].lidclosed = obs.lidclosed; 50 ret[i].biason = obs.biason; 51 ret[i].rstype = obs.rstype ? obs.rstype : "default"; 52 ret[i].sub = i; 53 ret[i].start = utc; 54 55 56 ret[i].toString = function() 57 { 58 var rc = this.task; 59 rc += "["+this.sub+"]"; 60 if (this.source) 61 rc += ": " + this.source; 62 //rc += " ["+this.start.toUTCString()+"]"; 63 return rc; 64 } 65 66 switch (ret[i].task) 67 { 68 case 'DATA': 69 if (i!=obj.measurements.length-1) 70 throw new Error("DATA [n="+i+", "+utc.toUTCString()+"] must be the last in the list of measurements [cnt="+obj.measurements.length+"]"); 71 if (ret[i].source == undefined) 72 throw new Error("Observation must have either 'source' or 'task' " + 73 "if 'task' == 'data' it must have also have 'source' "); 74 if (ret[i].lidclosed == true) 75 throw new Error("Observation must not have 'lidclosed'== true " + 76 "if 'task' == 'data' "); 77 break; 78 79 case 'STARTUP': 80 if (ret[i].source != undefined) 81 console.out("warning. Observation with task='startup' also has source defined"); 82 break; 83 84 case 'SHUTDOWN': 85 if (ret[i].source != undefined) 86 console.out("warning. Observation with task='shutdown' also has source defined"); 87 break; 88 89 case 'RATESCAN': 90 if (ret[i].source == undefined && (isNaN(ret[i].ra) || isNaN(ret[i].dec))) 91 throw new Error("Observation must have either 'source' or 'ra' & 'dec' " + 92 "if 'task' == 'ratescan'"); 93 if (ret[i].lidclosed == true) 94 throw new Error("Observation must not have 'lidclosed'== true " + 95 "if 'task' == 'ratescan' "); 96 break; 97 98 case 'RATESCAN2': 99 if ((ret[i].lidclosed != true) && ret[i].source == undefined && (isNaN(ret[i].ra) || isNaN(ret[i].dec))) 100 throw new Error("Observation must have either 'source' or 'ra' & 'dec' " + 101 "if 'task' == 'ratescan2' and lidclosed==false or not given"); 102 if (ret[i].lidclosed == true && (isNaN(ret[i].az) || isNaN(ret[i].az))) 103 throw new Error("Observation must have 'zd' & 'az' " + 104 "if 'task' == 'ratescan2' and option 'lidclosed'=='true'"); 105 break; 106 107 case 'CUSTOM': 108 109 if (isNaN(ret[i].az) || isNaN(ret[i].az) || isNaN(ret[i].time) || isNaN(ret[i].threshold)) 110 throw new Error("Observation must have 'zd' & 'az', 'time' and 'threshold' " + 111 "if 'task' == 'custom' "); 112 break; 113 114 case 'SINGLEPE': 115 case 'OVTEST': 116 case 'DRSCALIB': 117 case 'IDLE': 118 case 'SLEEP': 119 break; 120 121 default: 122 throw new Error("The observation type "+ret[i].task+" is unknown."); 123 } 124 } 125 126 return ret; 127 } 128