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

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