source: trunk/MagicSoft/Mars/mastro/MAstro.cc@ 3392

Last change on this file since 3392 was 3371, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 8.6 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz, 11/2003 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MAstro
28// ------
29//
30////////////////////////////////////////////////////////////////////////////
31#include "MAstro.h"
32
33#include <TVector3.h> // TVector3
34
35#include "MTime.h" // MTime::GetGmst
36
37ClassImp(MAstro);
38
39Double_t MAstro::Trunc(Double_t val)
40{
41 /* dint(A) - truncate to nearest whole number towards zero (double) */
42 return val<0 ? TMath::Ceil(val) : TMath::Floor(val);
43}
44
45Double_t MAstro::Round(Double_t val)
46{
47 /* dnint(A) - round to nearest whole number (double) */
48 return val<0 ? TMath::Ceil(val-0.5) : TMath::Floor(val+0.5);
49}
50
51Double_t MAstro::Hms2Sec(Int_t deg, UInt_t min, Double_t sec, Char_t sgn)
52{
53 const Double_t rc = TMath::Sign((60.0 * (60.0 * (Double_t)TMath::Abs(deg) + (Double_t)min) + sec), (Double_t)deg);
54 return sgn=='-' ? -rc : rc;
55}
56
57Double_t MAstro::Dms2Rad(Int_t deg, UInt_t min, Double_t sec, Char_t sgn)
58{
59 /* pi/(180*3600): arcseconds to radians */
60 //#define DAS2R 4.8481368110953599358991410235794797595635330237270e-6
61 return Hms2Sec(deg, min, sec, sgn)*TMath::Pi()/(180*3600)/**DAS2R*/;
62}
63
64Double_t MAstro::Hms2Rad(Int_t hor, UInt_t min, Double_t sec, Char_t sgn)
65{
66 /* pi/(12*3600): seconds of time to radians */
67//#define DS2R 7.2722052166430399038487115353692196393452995355905e-5
68 return Hms2Sec(hor, min, sec, sgn)*TMath::Pi()/(12*3600)/**DS2R*/;
69}
70
71Double_t MAstro::Dms2Deg(Int_t deg, UInt_t min, Double_t sec, Char_t sgn)
72{
73 return Hms2Sec(deg, min, sec, sgn)/3600.;
74}
75
76Double_t MAstro::Hms2Deg(Int_t hor, UInt_t min, Double_t sec, Char_t sgn)
77{
78 return Hms2Sec(hor, min, sec, sgn)/240.;
79}
80
81Double_t MAstro::Dms2Hor(Int_t deg, UInt_t min, Double_t sec, Char_t sgn)
82{
83 return Hms2Sec(deg, min, sec, sgn)/15.;
84}
85
86Double_t MAstro::Hms2Hor(Int_t hor, UInt_t min, Double_t sec, Char_t sgn)
87{
88 return Hms2Sec(hor, min, sec, sgn)/3600.;
89}
90
91void MAstro::Day2Hms(Double_t day, Char_t &sgn, UShort_t &hor, UShort_t &min, UShort_t &sec)
92{
93 /* Handle sign */
94 sgn = day<0?'-':'+';
95
96 /* Round interval and express in smallest units required */
97 Double_t a = Round(86400. * TMath::Abs(day)); // Days to seconds
98
99 /* Separate into fields */
100 const Double_t ah = Trunc(a/3600.);
101 a -= ah * 3600.;
102 const Double_t am = Trunc(a/60.);
103 a -= am * 60.;
104 const Double_t as = Trunc(a);
105
106 /* Return results */
107 hor = (UShort_t)ah;
108 min = (UShort_t)am;
109 sec = (UShort_t)as;
110}
111
112void MAstro::Rad2Hms(Double_t rad, Char_t &sgn, UShort_t &deg, UShort_t &min, UShort_t &sec)
113{
114 Day2Hms(rad/(TMath::Pi()*2), sgn, deg, min, sec);
115}
116
117void MAstro::Rad2Dms(Double_t rad, Char_t &sgn, UShort_t &deg, UShort_t &min, UShort_t &sec)
118{
119 Rad2Hms(rad*15, sgn, deg, min, sec);
120}
121
122void MAstro::Deg2Dms(Double_t d, Char_t &sgn, UShort_t &deg, UShort_t &min, UShort_t &sec)
123{
124 Day2Hms(d/24, sgn, deg, min, sec);
125}
126
127void MAstro::Deg2Hms(Double_t d, Char_t &sgn, UShort_t &deg, UShort_t &min, UShort_t &sec)
128{
129 Rad2Hms(d/360, sgn, deg, min, sec);
130}
131
132void MAstro::Hor2Dms(Double_t h, Char_t &sgn, UShort_t &deg, UShort_t &min, UShort_t &sec)
133{
134 Day2Hms(h*15/24, sgn, deg, min, sec);
135}
136
137void MAstro::Hor2Hms(Double_t h, Char_t &sgn, UShort_t &deg, UShort_t &min, UShort_t &sec)
138{
139 Day2Hms(h/24, sgn, deg, min, sec);
140}
141
142void MAstro::Day2Hm(Double_t day, Char_t &sgn, UShort_t &hor, Double_t &min)
143{
144 /* Handle sign */
145 sgn = day<0?'-':'+';
146
147 /* Round interval and express in smallest units required */
148 Double_t a = Round(86400. * TMath::Abs(day)); // Days to seconds
149
150 /* Separate into fields */
151 const Double_t ah = Trunc(a/3600.);
152 a -= ah * 3600.;
153
154 /* Return results */
155 hor = (UShort_t)ah;
156 min = a/60.;
157}
158
159void MAstro::Rad2Hm(Double_t rad, Char_t &sgn, UShort_t &deg, Double_t &min)
160{
161 Day2Hm(rad/(TMath::Pi()*2), sgn, deg, min);
162}
163
164void MAstro::Rad2Dm(Double_t rad, Char_t &sgn, UShort_t &deg, Double_t &min)
165{
166 Rad2Hm(rad*15, sgn, deg, min);
167}
168
169void MAstro::Deg2Dm(Double_t d, Char_t &sgn, UShort_t &deg, Double_t &min)
170{
171 Day2Hm(d/24, sgn, deg, min);
172}
173
174void MAstro::Deg2Hm(Double_t d, Char_t &sgn, UShort_t &deg, Double_t &min)
175{
176 Rad2Hm(d/360, sgn, deg, min);
177}
178
179void MAstro::Hor2Dm(Double_t h, Char_t &sgn, UShort_t &deg, Double_t &min)
180{
181 Day2Hm(h*15/24, sgn, deg, min);
182}
183
184void MAstro::Hor2Hm(Double_t h, Char_t &sgn, UShort_t &deg, Double_t &min)
185{
186 Day2Hm(h/24, sgn, deg, min);
187}
188
189// --------------------------------------------------------------------------
190//
191// Interpretes a string ' - 12 30 00.0' or '+ 12 30 00.0'
192// as floating point value -12.5 or 12.5. If interpretation is
193// successfull kTRUE is returned, otherwise kFALSE. ret is not
194// touched if interpretation was not successfull. The successfull
195// interpreted part is removed from the TString.
196//
197Bool_t MAstro::String2Angle(TString &str, Double_t &ret)
198{
199 Char_t sgn;
200 Int_t d, len;
201 UInt_t m;
202 Float_t s;
203
204 // Skip whitespaces before %c and after %f
205 int n=sscanf(str.Data(), " %c %d %d %f %n", &sgn, &d, &m, &s, &len);
206
207 if (n!=4 || (sgn!='+' && sgn!='-'))
208 return kFALSE;
209
210 str.Remove(0, len);
211
212 ret = Dms2Deg(d, m, s, sgn);
213 return kTRUE;
214}
215
216// --------------------------------------------------------------------------
217//
218// Interpretes a string '-12:30:00.0', '12:30:00.0' or '+12:30:00.0'
219// as floating point value -12.5, 12.5 or 12.5. If interpretation is
220// successfull kTRUE is returned, otherwise kFALSE. ret is not
221// touched if interpretation was not successfull.
222//
223Bool_t MAstro::Coordinate2Angle(const TString &str, Double_t &ret)
224{
225 Char_t sgn = str[0]=='-' ? '-' : '+';
226 Int_t d;
227 UInt_t m;
228 Float_t s;
229
230 const int n=sscanf(str[0]=='+'||str[0]=='-' ? str.Data()+1 : str.Data(), "%d:%d:%f", &d, &m, &s);
231
232 if (n!=3)
233 return kFALSE;
234
235 ret = Dms2Deg(d, m, s, sgn);
236 return kTRUE;
237}
238
239// --------------------------------------------------------------------------
240//
241// Return year y, month m and day d corresponding to Mjd.
242//
243void MAstro::Mjd2Ymd(UInt_t mjd, UShort_t &y, Byte_t &m, Byte_t &d)
244{
245 // Express day in Gregorian calendar
246 const ULong_t jd = mjd + 2400001;
247 const ULong_t n4 = 4*(jd+((6*((4*jd-17918)/146097))/4+1)/2-37);
248 const ULong_t nd10 = 10*(((n4-237)%1461)/4)+5;
249
250 y = n4/1461L-4712;
251 m = ((nd10/306+2)%12)+1;
252 d = (nd10%306)/10+1;
253}
254
255// --------------------------------------------------------------------------
256//
257// Return Mjd corresponding to year y, month m and day d.
258//
259Int_t MAstro::Ymd2Mjd(UShort_t y, Byte_t m, Byte_t d)
260{
261 // Month lengths in days
262 static int months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
263
264 // Validate month
265 if (m<1 || m>12)
266 return -1;
267
268 // Allow for leap year
269 months[1] = (y%4==0 && (y%100!=0 || y%400==0)) ? 29 : 28;
270
271 // Validate day
272 if (d<1 || d>months[m-1])
273 return -1;
274
275 // Precalculate some values
276 const Byte_t lm = 12-m;
277 const ULong_t lm10 = 4712 + y - lm/10;
278
279 // Perform the conversion
280 return 1461L*lm10/4 + (306*((m+9)%12)+5)/10 - (3*((lm10+188)/100))/4 + d - 2399904;
281}
282
283// --------------------------------------------------------------------------
284//
285// theta0, phi0 [rad]: polar angle/zenith distance, azimuth of 1st object
286// theta1, phi1 [rad]: polar angle/zenith distance, azimuth of 2nd object
287// AngularDistance [rad]: Angular distance between two objects
288//
289Double_t MAstro::AngularDistance(Double_t theta0, Double_t phi0, Double_t theta1, Double_t phi1)
290{
291 TVector3 v0(1);
292 v0.Rotate(phi0, theta0);
293
294 TVector3 v1(1);
295 v1.Rotate(phi1, theta1);
296
297 return v0.Angle(v1);
298}
299
300// --------------------------------------------------------------------------
301//
302// Calls MTime::GetGmst() Better use MTime::GetGmst() directly
303//
304Double_t MAstro::UT2GMST(Double_t ut1)
305{
306 return MTime(ut1).GetGmst();
307}
Note: See TracBrowser for help on using the repository browser.