/usr/include/Gyoto/GyotoAstrobj.h is in libgyoto2-dev 0.2.3-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 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 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 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 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 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 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 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 768 769 770 771 772 773 774 775 776 777 778 779 780 781 | /**
* \file GyotoAstrobj.h
* \brief Astronomical objects (light emitters)
*
* The target of ray-traced Gyoto::Photon
*/
/*
Copyright 2011-2013 Thibaut Paumard, Frederic Vincent
This file is part of Gyoto.
Gyoto is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gyoto is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Gyoto. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GyotoAstrobj_H_
#define __GyotoAstrobj_H_
#include "GyotoConfig.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <GyotoDefs.h>
#include <GyotoSmartPointer.h>
#include <GyotoConverters.h>
namespace Gyoto{
class Photon;
namespace Register { class Entry; }
namespace Metric { class Generic; }
class FactoryMessenger;
namespace Astrobj {
class Generic;
class Properties;
/**
* This is a more specific version of the
* SmartPointee::Subcontractor_t type. An Astrobj::Subcontrator_t
* is called by the Gyoto::Factory to build an instance of the
* kind of astronomical object specified in an XML file (see
* Register()). The Factory and Subcontractor_t function
* communicate through a Gyoto::FactoryMessenger. A template is
* provided so that you may not have to code anything.
*/
typedef SmartPointer<Gyoto::Astrobj::Generic>
Subcontractor_t(Gyoto::FactoryMessenger*);
///< A function to build instances of a specific Astrobj::Generic sub-class
/**
* Instead of reimplementing the wheel, your subcontractor can simply be
* Gyoto::Astrobj::Subcontractor<MyKind>.
*
* If MyKind accepts any XML parameters, it should re-implement
* Astrobj::Generic::setParameter() or, if low-level access to the
* FactoryMessenger is needed, Generic::setParameters().
*
* \tparam T Gyoto::Astrobj::Generic sub-class
*/
template<typename T> SmartPointer<Astrobj::Generic> Subcontractor
(FactoryMessenger* fmp) {
SmartPointer<T> ao = new T();
#ifdef GYOTO_USE_XERCES
ao -> setParameters(fmp);
#endif
return ao;
}
///< A template for Subcontractor_t functions
/**
* Query the Astrobj register to get the Astrobj::Subcontractor_t
* correspondig to a given kind name. This function is normally
* called only from the Factory.
*
* \param name e.g. "Star"
* \param errmode 1 to return NULL in case of failure instead of
* throwing an Error.
* \return pointer to the corresponding subcontractor.
*/
Gyoto::Astrobj::Subcontractor_t* getSubcontractor(std::string name,
int errmode = 0);
///< Query the Astrobj register
/**
* Use the Astrobj::initRegister() once in your program to
* initiliaze it, the Astrobj::Register() function to fill it, and
* the Astrobj::getSubcontractor() function to query it.
*/
extern Gyoto::Register::Entry * Register_;
///< The Astrobj register
/**
* This must be called once.
*/
void initRegister();
///< Empty the Astrobj register
/**
* Register a new Astrobj::Generic sub-class so that the
* Gyoto::Factory knows it.
*
* \param name The kind name which identifies this object type in
* an XML file, as in <Astrobj kind="name">
*
* \param scp A pointer to the subcontractor, which will
* communicate whith the Gyoto::Factory to build an instance of
* the class from its XML description
*/
void Register(std::string name, Gyoto::Astrobj::Subcontractor_t* scp);
///< Make an Astrobj kind known to the Factory
}
}
/**
* \namespace Gyoto::Astrobj
* \brief Access to astronomical objects
*
* Objects which are supposed to be the target of the ray-tracing
* code should inherit from the Gyoto::Astrobj::Generic class.
*
* When implementing a new object, you must:
* - make sure the object can be loaded from XML by providing a
* Subcontractor_t using the Gyoto::Astrobj::Register(std::string
* name, Gyoto::Astrobj::Subcontractor_t* scp) function;
* - make sure this subcontractor is registerred in the initialization
* routine of your plug-in;
* - make sure Generic::Impact() works (see below).
*
* In addition, you should make sure that your object plays nicely in
* the Yorick plug-in, which means:
* - implement the copy constructor and the Generic::clone() method;
* - implement the fillElement method, used for printing and saving to
* XML.
*
* There are basically two ways of making Generic::Impact() work:
* either by making the Astrobj a sub-class of the low-level
* Gyoto::Astrobj::Generic class ans providing your own
* Generic::Impact() function (which, in principle, should rely on
* Generic::processHitQuantities()), or by making the Astrobj a
* sub-class of the higher-level Gyoto::Astrobj::Standard class and
* implementing two lower level, simpler functions which are
* used by the Standard::Impact():
* - Standard::operator()() yields a distance or potential defining
* the interior of the object;
* - Standard::getVelocity() yields the velocity field of the fluid.
*
* Generic::processHitQuantities() itself is an intermediate-level
* function which you may choose to reimplement. It uses three
* low-level, easy to implement functions:
* - Generic::emission();
* - Generic::integrateEmission();
* - Generic::transmission().
* Default implementations of these three functions exist, they have
* little physical relevance but allow quick 0-th order vizualisation
* of your object.
*
* To be usable, a Astrobj::Generic (or Astrobj::Standard) sub-classe
* should register an Astrobj::Subcontractor_t function using the
* Astrobj::Register() function. See also \ref writing_plugins_page
* . If your clas implements setParameter() and/or, if necessary,
* setParameters(), registering it is normally done using the provided
* template:
* \code
* Astrobj::Register("MyKind", &(Astrobj::Subcontractor<Astrobj::MyKind>));
* \endcode
*/
/**
* \class Gyoto::Astrobj::Generic
* \brief Base class for astronomical object
*
* See introduction in the Gyoto::Astrobj namespace.
*/
class Gyoto::Astrobj::Generic : protected Gyoto::SmartPointee {
friend class Gyoto::SmartPointer<Gyoto::Astrobj::Generic>;
// Data :
// -----
protected:
/**
* \brief The Metric in this end of the Universe
*/
SmartPointer<Gyoto::Metric::Generic> gg_;
/**
* Maximum distance from the center of the coordinate system at
* which a photon may hit the object. Child classes may choose to
* update rMax at all time or to use it to cache the value, for
* instance when rMax() is called. External classes (Photons in
* particular) must use rMax() to access this information.
*
* #rmax_set_==1 means that #rmax_ was set using rMax() or the
* constructor. In this case, rMax() must always return this
* value, not recompute it.
*
* #rmax_ is in geometrical units.
*/
double rmax_; ///< Maximum distance to the center of the coordinate system [geometrical units]
/**
* #rmax_set_==1 means that #rmax_ was set using rMax(double r) or the
* constructor. In this case, rMax() must always return this
* value, not recompute it.
*
* Use unsetRmax() to reset rmax_set_ to 0.
*
*/
int rmax_set_; ///< Never recompute rmax: it was externally set
/**
* The kind should match the name of the class, e.g. "Star" for a
* Gyoto::Star.
*/
std::string kind_; ///< Kind of object (e.g. "Star"...)
int flag_radtransf_; ///< 1 if radiative transfer inside Astrobj, else 0
// Constructors - Destructor
// -------------------------
public:
/**
* #kind_ = "Default", #rmax_ = 0., #rmax_set_ = 0.
*/
Generic(); ///< Default constructor.
/**
* #kind_ = "Default", #rmax_ = radmax, #rmax_set_ = 1.
*/
Generic(double radmax); ///< Set rmax in constructor.
/**
* #kind_ = kind, #rmax_ = 0., #rmax_set_ = 0.
*/
Generic(std::string kind); ///< Set kind in constructor.
/**
* Make a deep copy of an Astrobj::Generic instance
*/
Generic(const Generic& ) ; ///< Copy constructor.
/**
* This method must be implemented by the various Astrobj::Generic
* subclasses in order to support cloning:
* \code
* SmartPointer<Astrobj> deep_copy = original->clone();
* \endcode
*
* Cloning is necessary for multi-threading, recommended for
* interaction with the Yorick plug-in etc.
*
* Implementing it is very straightforward, as long as the copy
* constructor Generic(const Generic& ) has been implemented:
* \code
* MyAstrobj* MyAstrobj::clone() const { return new MyAstrobj(*this); }
* \endcode
*/
virtual Generic* clone() const = 0 ; ///< Cloner
virtual ~Generic() ; ///< Destructor: does nothing.
// Accessors
// ---------
public:
/**
* \brief Get the Metric #gg_
*/
virtual SmartPointer<Metric::Generic> metric() const;
/**
* \brief Set the Metric #gg_
*/
virtual void metric(SmartPointer<Metric::Generic>) ;
/**
* Get maximal distance from center of coordinate system at which a
* Photon may hit the object.
*
* Child classes may use the rmax_ member to cache this value.
*
* It can also be set using rmax(). If rmax has been used
* to set rmax_, rMax() must not recompute it.
*
* \return rmax_ in geometrical units
*/
virtual double rMax(); ///< Get maximal distance from center of coordinate system
/**
* Call rMax() and convert result to unit.
*
* \param unit string
* \return double rmax converted to unit
*/
virtual double rMax(std::string unit); ///< Get rmax_ is specified unit
/// Get max step constraint for adaptive integration
/**
* \param[in] coord position
* \return max step to find this object reliably
*/
virtual double deltaMax(double coord[8]);
const std::string kind() const; ///< Get the kind of the Astrobj (e.g. "Star")
/**
* Set maximal distance from center of coordinate system at which a
* Photon may hit the object.
*
* Side effect: set #rmax_set_ to 1.
* \param val new #rmax_ in geometrical units.
*/
virtual void rMax(double val); ///< Set maximal distance from center of coordinate system
/**
* Call Generic::rMax(double val) after converting val from unit
* to geometrical units.
*
* \param val #rmax_ expressed in unit "unit";
* \param unit string...
*/
virtual void rMax(double val, std::string unit); ///< Set maximal distance from center of coordinate system
/**
* rmax() will then be free to recompute rmax_. Astrobjs
* which cache rmax_ may need to update it when unrmax() is
* called.
*/
virtual void unsetRmax() ; ///< Set rmax_set_ to 0.
/**
* Set flag indicating that radiative transfer should be integrated,
* i.e. the object is to be considered optically thin.
* \param flag: 1 if optically thin, 0 if optically thick.
*/
void opticallyThin(int flag);
///< Set whether the object is optically thin.
/**
* See opticallyThin(int flag).
*/
int opticallyThin() const ;
///< Query whether object is optically thin.
/**
* Return a Gyoto::Quantity_t suitable as input to
* Gyoto::Scenery::setRequestedQuantities() to set de default
* quantities to compute for this object. The default of these
* defaults GYOTO_QUANTITY_INTENSITY.
*/
virtual Quantity_t getDefaultQuantities();
///< Which quantities to compute if know was requested
//XML I/O
public:
/**
* \brief Set parameter by name
*
* Assume MyKind is a subclass of Astrobj::Generic which has two
* members (a string StringMember and a double DoubleMember):
* \code
* int MyKind::setParameter(std::string name,
* std::string content,
* std::string unit) {
* if (name=="StringMember") setStringMember(content);
* else if (name=="DoubleMember") setDoubleMember(atof(content.c_str()),
* unit);
* else return Generic::setParameter(name, content, unit);
* return 0;
* }
* \endcode
* If MyKind is not a direct subclass of Generic but is a subclass
* of e.g. Standard, UniformSphere of ThinDisk, it should call the
* corresponding setParameter() implementation instead of
* Generic::setParameter().
*
* \param name XML name of the parameter
* \param content string representation of the value
* \param unit string representation of the unit
* \return 0 if this parameter is known, 1 if it is not.
*/
virtual int setParameter(std::string name,
std::string content,
std::string unit) ;
#ifdef GYOTO_USE_XERCES
/**
* \brief Fill XML section
*
* Astrobj implementations should impement fillElement to save their
* parameters to XML and call the generic implementation to save
* generic parts such as Flag_radtrans: Generic::fillElement(fmp).
*/
virtual void fillElement(FactoryMessenger *fmp) const ;
/**
* \brief Main loop in Subcontractor_t function
*
* The Subcontractor_t function for each Astrobj kind should look
* somewhat like this (templated as
* Gyoto::Astrobj::Subcontractor<MyKind>):
* \code
* SmartPointer<Astrobj::Generic>
* Gyoto::Astrobj::MyKind::Subcontractor(FactoryMessenger* fmp) {
* SmartPointer<MyKind> ao = new MyKind();
* ao -> setParameters(fmp);
* return ao;
* }
* \endcode
*
* Each object kind should implement setParameter(string name,
* string content, string unit) to interpret the individual XML
* elements. setParameters() can be overloaded in case the specific
* Astrobj class needs low level access to the FactoryMessenger. See
* UniformSphere::setParameters().
*/
virtual void setParameters(FactoryMessenger *fmp);
#endif
// Outputs
// -------
public:
/**
* Impact() checks whether a Photon impacts the object between two
* integration steps of the photon's trajectory (those two steps are
* photon->getCoord(index, coord1) and photon->getCoord(index+1,
* coord2)). Impact returns 1 if the photon impacts the object
* between these two steps, else 0. In many cases of geometrically
* thick obects, the implementation Astrobj::Standard::Impact() will
* be fine.
*
* Impact will call Generic::processHitQuantities() (which is
* virtual and may be re-implemented) to compute observable
* properties on demand: if the data pointer is non-NULL, the object
* will look in it for pointers to properties which apply to its
* kind. If a pointer to a property known to this object is present,
* then the property is computed and store at the pointed-to
* adress. For instance, all objects know the "intensity"
* property. If data->intensity != NULL, the instensity is computed
* and stored in *data->intensity.
*
* If data is non-NULL and only in this case, processHitQuantities()
* will also call ph->transmit() to update the transmissions of the
* Photon (see Photon::transmit(size_t, double)). This must not be
* done if data is NULL (see Astrobj::Complex::Impact() for an
* explanation).
*
* \param ph Gyoto::Photon aimed at the object;
* \param index Index of the last photon step;
* \param data Pointer to a structure to hold the observables at impact.
*
* \return 1 if impact, 0 if not.
*/
virtual int Impact(Gyoto::Photon* ph, size_t index,
Astrobj::Properties *data=NULL) = 0 ;
///< Does a photon at these coordinates impact the object?
/**
* \brief Fills Astrobj::Properties
*
* processHitQuantities fills the requested data in Impact. To use
* it, you need to call it in the Impact() method for your object in
* case of hit. It will fill Redshift, Intensity, Spectrum,
* BinSpectrum and update the Photon's transmission by calling
* Photon::transmit(), only if data==NULL.
*
* You can overload it for your Astrobj. The generic implementation
* calls emission(), integrateEmission() and transmission() below.
*/
virtual void processHitQuantities(Photon* ph, double* coord_ph_hit,
double* coord_obj_hit, double dt,
Astrobj::Properties* data) const;
/**
* \brief Specific intensity I<SUB>ν</SUB>
*
* Called by the default implementation for processHitQuantities().
*
* emission() computes the intensity I<SUB>ν</SUB> emitted by the
* small volume of length ds<SUB>em</SUB>, in the emitter's
* frame. It should take self-absorption along ds<SUB>em</SUB> into
* account.
*
* Reminder :
* - intensity = I<SUB>ν</SUB> [J m^-2 s^-1 ster^-1 Hz^-1];
*
* - invariant intensity = I<SUB>ν</SUB>/ν<SUP>3</SUP>, which
* has the same value in any frame;
*
* - emission coefficient = j<SUB>ν</SUB> [J m^-3 s^-1 ster^-1
* Hz^-1] , defined by dI<SUB>ν</SUB> = j<SUB>ν</SUB>*ds,
* where ds is the distance travelled by the photon inside the
* object;
* - invariant emission coef = j<SUB>ν</SUB>/ν<SUP>2</SUP>,
* which has the same value in any frame.
*
* The equation used for radiative transfer (without absorption) is:
*
* d(I<SUB>ν</SUB>/ν<SUP>3</SUP>)/dλ = (j<SUB>ν</SUB>/ν<SUP>2</SUP>) [*]
*
* where λ is the integration parameter along the null geodesic.
*
* NB: Let us consider a particular observer, with ν being the
* frequency measured by this observer, and ds being the proper
* distance (as measured by the observer) that the photon travels
* as it moves from λ to λ+dλ along its
* geodesic. Then it can be shown that:
*
* dλ = ds/ν
*
* This shows that Eq. [*] is homogeneous.
*
* The default implementation returns 1. if optically thick and ds<SUB>em</SUB>
* if optically thin. It allows for a quick implementation of your
* object for visualization purposes.
*
* \param nu_em Frequency at emission [Hz]
* \param dsem length over which to integrate inside the object
* [geometrical units]
* \param coord_ph Photon coordinate
* \param coord_obj Emitter coordinate at current photon position
*/
virtual double emission(double nu_em, double dsem, double coord_ph[8],
double coord_obj[8]=NULL)
const ;
/**
* \brief Specific intensity I<SUB>ν</SUB> for several values of ν<SUB>em</SUB>
*
* Called by the default implementation for processHitQuantities().
*
* emission() computes the intensity I<SUB>ν</SUB> emitted by the small
* volume of length dsem. It should take self-absorption along dsem
* into account.
*
* Same as emission(double nu_em, double dsem, double coord_ph[8],
* double coord_obj[8]=NULL) const
* looping on several values of nu_em.
*
* \param Inu[nbnu] Output (must be set to a previously allocated
* array of doubles)
* \param nu_em[nbnu] Frequencies at emission
* \param nbnu Size of Inu[] and nu_em[]
* \param dsem Length over which to integrate inside the object
* \param coord_ph Photon coordinate
* \param coord_obj Emitter coordinate at current photon position
* \return I<SUB>ν</SUB> or dI<SUB>ν</SUB> [W m-2 sr-2]
*/
virtual void emission(double Inu[], double nu_em[], size_t nbnu,
double dsem, double coord_ph[8],
double coord_obj[8]=NULL) const ;
/**
* Compute the integral of emission() from ν<SUB>1</SUB> to
* ν<SUB>2</SUB>. The default implementation is a numerical
* integrator which works well enough and is reasonably fast if
* emission() is a smooth function (i.e. no emission or absorption
* lines). If possible, it is wise to implement an analytical
* solution. It is used by processHitQuantities to compute the
* "BinSpectrum" quantity which is the most physical: it is the only
* quantity that can be actually measured directly by a real-life
* instrument.
*/
virtual double integrateEmission(double nu1, double nu2, double dsem,
double c_ph[8], double c_obj[8]=NULL) const;
///< ∫<SUB>ν<SUB>1</SUB></SUB><SUP>ν<SUB>2</SUB></SUP> I<SUB>ν</SUB> dν (or j<SUB>ν</SUB>)
/**
* Like double integrateEmission(double nu1, double nu2, double
* dsem, double c_ph[8], double c_obj[8]) const for each
* Spectrometer channel.
*/
virtual void integrateEmission(double * I, double const * boundaries,
size_t const * chaninds, size_t nbnu,
double dsem, double *cph, double *co) const;
///< ∫<SUB>ν<SUB>1</SUB></SUB><SUP>ν<SUB>2</SUB></SUP> I<SUB>ν</SUB> dν (or j<SUB>ν</SUB>)
/**
* transmission() computes the transmission of this fluid element or
* 0 if optically thick. The default implementation returns 1. (no
* attenuation) if optically thin, 0. if optically thick.
*
* \param nuem frequency in the fluid's frame
* \param coord Photon coordinate
* \param dsem geometrical length in geometrical units
*/
virtual double transmission(double nuem, double dsem, double coord[8]) const ;
///< Transmission: exp( α<SUB>ν</SUB> * ds<SUB>em</SUB> )
};
/**
* \class Gyoto::Astrobj::Properties
* \brief Observable properties of an Astronomical object
*
* The sort of properties one wants to measure on a ray-traced
* Gyoto::Photon which hits a Gyoto::Astrobj. Not all Astrobj are
* able to fill all of these properties.
*
* An instance of Properties essentially contains a bunch of pointers
* to memory areas where the observable quantities (see Quantity_t)
* should be stored.
*
* Astrobj::Generic::processHitQuantities() fills the various arrays
* upon request. A quantity is ignored if the corresponding pointer
* is NULL.
*
* Scenery::operator()() increments the Properties between each
* Photon using Properties::operator++().
*
* The main application (gyoto, the yorick plug-in, or your user
* application) is responsible for allocating the various arrays,
* filling the various members of Properties, and doing whatever
* meaninful with the arrays after they have been filled with values
* by the ray-tracing code (e.g. saving them to disk or displaying
* them).
*
* Also see Gyoto::Scenery and Gyoto::Quantity_t.
*/
class Gyoto::Astrobj::Properties : protected Gyoto::SmartPointee {
friend class Gyoto::SmartPointer<Gyoto::Astrobj::Properties>;
public:
double *intensity; ///< GYOTO_QUANTITY_INTENSITY : Intensity
double *time; ///< GYOTO_QUANTITY_EMISSIONTIME: EmissionTime
/**
* Behaves like the square of the closest distance between Photon
* and Astrobj (but not exactly that). Initialize it to DBL_MAX from
* float.h.;
*/
double *distance; ///< GYOTO_QUANTITY_MIN_DISTANCE: MinDistance
/**
* First local minimum in distance from object
*/
double * first_dmin; ///< GYOTO_QUANTITY_FIRST_DMIN : FirstDmin
/**
* Properties::first_dmin will be set to the first local minimum and
* Properties::first_dmin_found will be set to 1 if a local minimum
* in distance is found. Initialize it to 0.
*/
int first_dmin_found; ///< Whether Properties::first_dmin was found
/**
* Redshift factor ν<SUB>obs</SUB>/ν<SUB>em</SUB> (necessary
* for emission lines computation)
*/
double *redshift; ///< GYOTO_QUANTITY_REDSHIFT : RedShift
/**
* I<SUB>ν</SUB> (ν) (observed specific intensity)
*/
double *spectrum; ///< GYOTO_QUANTITY_SPECTRUM : Spectrum
/**
* I<SUB>ν<SUB>1</SUB></SUB><SUP>ν<SUB>2</SUB></SUP>, the
* integral of I<SUB>ν</SUB> over each spectral channel
* (i.e. what a spectrometer would measure)
*/
double *binspectrum; ///< GYOTO_QUANTITY_BINSPECTRUM : BinSpectrum
/**
* Spectra elements are separated by offset doubles in memory. In
* other words, the ith spectral element is spectrum[i*offset].
*/
ptrdiff_t offset; ///< How to jump from one spectral element to the next
/**
* Coordinates of the object and photon at impact
*/
double * impactcoords; ///< GYOTO_QUANTITY_IMPACTCOORDS: ImpactCoords
/**
* \brief GYOTO_QUANTITY_USER1 : User1
* Astrobj-specific quantity
*/
double *user1;
/**
* \brief GYOTO_QUANTITY_USER2 : User2
* Astrobj-specific quantity
*/
double *user2;
/**
* \brief GYOTO_QUANTITY_USER3 : User3
* Astrobj-specific quantity
*/
double *user3;
/**
* \brief GYOTO_QUANTITY_USER4 : User4
* Astrobj-specific quantity
*/
double *user4;
/**
* \brief GYOTO_QUANTITY_USER5 : User5
* Astrobj-specific quantity
*/
double *user5;
# ifdef HAVE_UDUNITS
/**
* \brief Converter between SI (J.m <SUP> -2</SUP>.s<SUP>-1</SUP>.sr<SUP>-1</SUP>.Hz<SUP>-1</SUP>) and requested Intensity unit
*/
Gyoto::SmartPointer<Gyoto::Units::Converter> intensity_converter_ ;
/**
* \brief Converter between SI (J.m <SUP> -2</SUP>.s<SUP>-1</SUP>.sr<SUP>-1</SUP>.Hz<SUP>-1</SUP>) and requested Spectrum unit
*/
Gyoto::SmartPointer<Gyoto::Units::Converter> spectrum_converter_ ;
/**
* \brief Converter between SI (J.m <SUP> -2</SUP>.s<SUP>-1</SUP>.sr<SUP>-1</SUP>) and requested BinSpectrum unit
*/
Gyoto::SmartPointer<Gyoto::Units::Converter> binspectrum_converter_ ;
# endif
public:
Properties(); ///< Default constructor (everything is set to NULL);
Properties (double*, double*); ///<< Set intensity and time pointers.
/**
* \brief Initialize observable quantities
*
* The pointed-to values are initialized as follows (if the
* corresponding pointer is not NULL):
*
* - intensity, firt_dmin_found, redshift, userN: 0
* - time, distance, first_dmin: DBL_MAX
* - for spectrum and binspectrum, nbnuobs values separated by offset in memory are initialized to 0
* - for impactcoords, 16 contiguous values are initialized to DBL_MAX
*/
void init(size_t nbnuobs=0);
/**
* \brief Increment pointers
*
* All valid pointers are incremented by 1 (sizeof(double)), excepted
* impactcoords which is incremented by 16.
*/
Properties operator++();
/**
* \brief Increment pointers by offset
*
* All valid pointers are incremented by offset (sizeof(double)), excepted
* impactcoords which is incremented by 16*offset.
*/
Properties operator+=(ptrdiff_t offset);
# ifdef HAVE_UDUNITS
void intensityConverter(Gyoto::SmartPointer<Gyoto::Units::Converter>);
///< Set Properties::intentity_converter_
void intensityConverter(std::string);
///< Set Properties::intentity_converter_
void spectrumConverter(Gyoto::SmartPointer<Gyoto::Units::Converter>);
///< Set Properties::spectrum_converter_
void spectrumConverter(std::string);
///< Set Properties::spectrum_converter_
void binSpectrumConverter(Gyoto::SmartPointer<Gyoto::Units::Converter>);
///< Set Properties::binspectrum_converter_
void binSpectrumConverter(std::string);
///< Set Properties::binspectrum_converter_
# endif
};
#endif
|