File indexing completed on 2026-04-09 07:49:36
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 #include "NP.hh"
0075 #include "sstr.h"
0076 #include "stra.h"
0077 #include "stran.h"
0078 #include "sphoton.h"
0079
0080 struct sfr
0081 {
0082 static constexpr const char* NAME = "sfr" ;
0083 static constexpr const unsigned NUM_4x4 = 4 ;
0084 static constexpr const unsigned NUM_VALUES = NUM_4x4*4*4 ;
0085 static constexpr const double EPSILON = 1e-5 ;
0086 static constexpr const char* DEFAULT_NAME = "ALL" ;
0087
0088
0089 template<typename T>
0090 static sfr MakeFromCE(const char* ce, char delim=',');
0091 template<typename T>
0092 static sfr MakeFromCE(const T* ce);
0093
0094 template<typename T>
0095 static sfr MakeFromExtent(const char* _extent);
0096 template<typename T>
0097 static sfr MakeFromExtent(T extent);
0098
0099
0100 template<typename T>
0101 static sfr MakeFromTranslateExtent(const char* s_te, char delim);
0102 template<typename T>
0103 static sfr MakeFromTranslateExtent(const T* _te);
0104 template<typename T>
0105 static sfr MakeFromTranslateExtent(T tx, T ty, T tz, T extent );
0106
0107
0108
0109 template<typename T>
0110 static sfr MakeFromAxis(const char* tpde, char delim=',');
0111 template<typename T>
0112 static sfr MakeFromAxis(T theta_deg, T phi_deg, T ax_dist_mm, T extent_mm, T delta_ax_distance_mm );
0113 template<typename T>
0114 static sfr MakeFromAxisQuat(T theta_deg, T phi_deg, T ax_dist_mm, T extent_mm, T delta_ax_distance_mm );
0115
0116
0117
0118 glm::tvec4<double> ce ;
0119 glm::tvec4<int64_t> aux0 ;
0120 glm::tvec4<int64_t> aux1 ;
0121 glm::tvec4<int64_t> aux2 ;
0122
0123 glm::tmat4x4<double> m2w ;
0124 glm::tmat4x4<double> w2m ;
0125
0126 glm::tvec3<double> bbmn ;
0127 glm::tvec3<double> bbmx ;
0128 glm::tvec2<double> padd ;
0129 glm::tvec4<double> ext0 ;
0130 glm::tvec4<double> ext1 ;
0131
0132 std::string name ;
0133 std::string treedir ;
0134
0135
0136
0137
0138 sfr();
0139
0140 void set_propagate_epsilon(double eps);
0141 void set_gridscale(double gsc);
0142
0143 double get_propagate_epsilon() const ;
0144 double get_gridscale() const ;
0145
0146 void set_hostside_simtrace();
0147 bool is_hostside_simtrace() const ;
0148
0149 void set_gasix( int gix) ;
0150 void set_sensorid(int sid) ;
0151 void set_sensorix(int six) ;
0152
0153 int get_gasix() const ;
0154 int get_sensorid() const ;
0155 int get_sensorix() const ;
0156
0157 void set_identity( int inst, int gasix, int sensorid, int sensorix );
0158
0159 void set_lvid(int lvid) ;
0160 void set_lvid_ordinal(int lvid_ordinal ) ;
0161
0162 int get_lvid() const ;
0163 int get_lvid_ordinal() const ;
0164
0165 void set_inst(int idx) ;
0166 void set_nidx(int nidx) ;
0167 void set_prim(int prim) ;
0168 void set_idx(int idx) ;
0169
0170 int get_inst() const ;
0171 int get_nidx() const ;
0172 int get_prim() const ;
0173 int get_idx() const ;
0174
0175
0176
0177 bool is_zero() const ;
0178
0179
0180 double* ce_data() ;
0181 template<typename T> void set_ce( const T* _ce );
0182 template<typename T> void set_extent( T _w );
0183 template<typename T> void set_m2w( const T* _v16, size_t nv=16 );
0184 template<typename T> void set_bb( const T* _bb6 );
0185 template<typename T> int write_bb( T* bb ) const ;
0186
0187
0188 const glm::tmat4x4<double>& get_transform(bool inverse) const ;
0189
0190 void transform_w2m( sphoton& p, bool normalize=true ) const ;
0191 void transform_m2w( sphoton& p, bool normalize=true ) const ;
0192 void transform( sphoton& p, bool normalize, bool inverse ) const ;
0193
0194 Tran<double>* getTransform() const;
0195 NP* transform_photon_m2w( const NP* ph, bool normalize ) const ;
0196 NP* transform_photon_w2m( const NP* ph, bool normalize ) const ;
0197 NP* transform_photon( const NP* ph, bool normalize, bool inverse ) const ;
0198
0199
0200
0201 void set_name( const char* _name );
0202 const std::string& get_name() const ;
0203 const char* get_id() const ;
0204
0205 void set_treedir( const char* _treedir );
0206 const std::string& get_treedir() const ;
0207
0208
0209
0210 std::string get_key() const ;
0211
0212 std::string desc_ce() const ;
0213 std::string desc() const ;
0214 bool is_identity() const ;
0215
0216 NP* serialize() const ;
0217 void save(const char* dir, const char* stem=NAME) const ;
0218
0219 static sfr Import( const NP* a);
0220 static sfr Load( const char* dir, const char* stem=NAME);
0221 static sfr Load_(const char* path );
0222
0223 void load(const char* dir, const char* stem=NAME) ;
0224 void load_(const char* path ) ;
0225 void load(const NP* a) ;
0226
0227 double* data() ;
0228 const double* cdata() const ;
0229 void write( double* dst, unsigned num_values ) const ;
0230 void read( const double* src, unsigned num_values ) ;
0231
0232
0233
0234
0235 };
0236
0237
0238
0239
0240 template<typename T>
0241 inline sfr sfr::MakeFromCE(const char* s_ce, char delim)
0242 {
0243 std::vector<T> elem ;
0244 sstr::split<T>( elem, s_ce, delim );
0245 int num_elem = elem.size();
0246
0247 std::array<T,4> _ce ;
0248
0249 _ce[0] = num_elem > 0 ? elem[0] : 0. ;
0250 _ce[1] = num_elem > 1 ? elem[1] : 0. ;
0251 _ce[2] = num_elem > 2 ? elem[2] : 0. ;
0252 _ce[3] = num_elem > 3 ? elem[3] : 1000. ;
0253
0254 return MakeFromCE<T>(_ce.data());
0255 }
0256
0257 template<typename T>
0258 inline sfr sfr::MakeFromCE(const T* _ce )
0259 {
0260 sfr fr ;
0261 fr.set_ce(_ce);
0262 fr.set_name("MakeFromCE");
0263 return fr ;
0264 }
0265
0266
0267
0268
0269
0270 template<typename T>
0271 inline sfr sfr::MakeFromExtent(const char* _ext)
0272 {
0273 T _extent = sstr::To<T>( _ext ) ;
0274 return MakeFromExtent<T>(_extent);
0275 }
0276
0277 template<typename T>
0278 inline sfr sfr::MakeFromExtent(T extent)
0279 {
0280 sfr fr ;
0281 fr.set_extent(extent);
0282 fr.set_name("MakeFromExtent");
0283 return fr ;
0284 }
0285
0286
0287
0288
0289
0290
0291
0292
0293 template<typename T>
0294 inline sfr sfr::MakeFromTranslateExtent(const char* s_te, char delim)
0295 {
0296 std::vector<T> elem ;
0297 sstr::split<T>( elem, s_te, delim );
0298 int num_elem = elem.size();
0299
0300 std::array<T,4> _te ;
0301
0302 _te[0] = num_elem > 0 ? elem[0] : 0. ;
0303 _te[1] = num_elem > 1 ? elem[1] : 0. ;
0304 _te[2] = num_elem > 2 ? elem[2] : 0. ;
0305 _te[3] = num_elem > 3 ? elem[3] : 1000. ;
0306
0307 return MakeFromTranslateExtent<T>(_te.data());
0308 }
0309
0310 template<typename T>
0311 inline sfr sfr::MakeFromTranslateExtent(const T* _te )
0312 {
0313 return MakeFromTranslateExtent(_te[0], _te[1], _te[2], _te[3]);
0314 }
0315
0316 template<typename T>
0317 inline sfr sfr::MakeFromTranslateExtent(T tx, T ty, T tz, T extent )
0318 {
0319 T sc = 1. ;
0320 glm::tmat4x4<T> model2world = stra<T>::Translate(tx, ty, tz, sc );
0321 sfr fr ;
0322 fr.set_m2w( glm::value_ptr(model2world) );
0323 fr.set_extent(extent);
0324 fr.set_name("MakeFromTranslateExtent");
0325 return fr ;
0326 }
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357 template<typename T>
0358 inline sfr sfr::MakeFromAxis(const char* tpde, char delim)
0359 {
0360 std::vector<T> elem ;
0361 sstr::split<T>( elem, tpde, delim );
0362 int num_elem = elem.size();
0363
0364 T theta_deg = num_elem > 0 ? elem[0] : 0. ;
0365 T phi_deg = num_elem > 1 ? elem[1] : 0. ;
0366 T dist_mm = num_elem > 2 ? elem[2] : 0. ;
0367 T extent_mm = num_elem > 3 ? elem[3] : 1000. ;
0368 T delta_dist_mm = num_elem > 4 ? elem[4] : 0. ;
0369
0370 if(0) std::cout
0371 << "sfr::MakeFromAxis"
0372 << " tpde [" << ( tpde ? tpde : "-" ) << "]"
0373 << " num_elem " << num_elem
0374 << " elem " << sstr::desc<T>(elem)
0375 << "\n"
0376 ;
0377
0378 return MakeFromAxisQuat<T>( theta_deg, phi_deg, dist_mm, extent_mm, delta_dist_mm );
0379 }
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392 template<typename T>
0393 inline sfr sfr::MakeFromAxis(T theta_deg, T phi_deg, T ax_dist_mm, T extent_mm, T delta_ax_dist_mm )
0394 {
0395 std::cout
0396 << "sfr::MakeFromAxis"
0397 << " theta_deg " << theta_deg
0398 << " phi_deg " << phi_deg
0399 << " ax_dist_mm " << ax_dist_mm
0400 << " extent_mm " << extent_mm
0401 << " delta_ax_dist_mm " << delta_ax_dist_mm
0402 << "\n"
0403 ;
0404
0405 T theta = theta_deg * glm::pi<T>() / 180.;
0406 T phi = phi_deg * glm::pi<T>() / 180.;
0407
0408 T st = glm::sin(theta);
0409 T ct = glm::cos(theta);
0410 T sp = glm::sin(phi);
0411 T cp = glm::cos(phi);
0412
0413 glm::tvec3<T> ax = glm::vec3(st * cp, st * sp, ct);
0414 glm::tvec3<T> translation = ax * ( ax_dist_mm + delta_ax_dist_mm ) ;
0415
0416 glm::tvec3<T> world_z = glm::tvec3<T>(0.0f, 0.0f, 1.0f);
0417 glm::tvec3<T> up = world_z - glm::dot(world_z, ax) * ax;
0418 up = glm::normalize(up);
0419
0420 glm::tmat4x4<T> model2world = stra<T>::Model2World(ax, up, translation );
0421
0422 sfr fr ;
0423 fr.set_m2w( glm::value_ptr(model2world) );
0424 fr.set_extent(extent_mm);
0425 fr.set_name("MakeFromAxis");
0426
0427 return fr ;
0428 }
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444 template<typename T>
0445 inline sfr sfr::MakeFromAxisQuat(T theta_deg, T phi_deg, T ax_dist_mm, T extent_mm, T delta_ax_dist_mm )
0446 {
0447 T theta = glm::radians(theta_deg);
0448 T phi = glm::radians(phi_deg);
0449
0450
0451
0452 glm::tquat<T> qPhi = glm::angleAxis(phi, glm::tvec3<T>(0, 0, 1));
0453 glm::tquat<T> qTheta = glm::angleAxis(theta, glm::tvec3<T>(0, 1, 0));
0454
0455
0456 glm::tquat<T> orientation = qPhi * qTheta;
0457
0458
0459
0460 glm::tvec3<T> ax = orientation * glm::tvec3<T>(0, 0, 1);
0461
0462
0463
0464 glm::tvec3<T> up = orientation * glm::tvec3<T>(0, 1, 0);
0465
0466
0467 glm::tvec3<T> translation = ax * (ax_dist_mm + delta_ax_dist_mm);
0468
0469
0470
0471 glm::tmat4x4<T> model2world = stra<T>::Model2World(ax, up, translation);
0472
0473 sfr fr;
0474 fr.set_m2w(glm::value_ptr(model2world));
0475 fr.set_extent(extent_mm);
0476 fr.set_name("MakeFromAxisQuat");
0477
0478 return fr;
0479 }
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493 inline sfr::sfr()
0494 :
0495 ce(0.,0.,0.,100.),
0496 aux0(0),
0497 aux1(0),
0498 aux2(0),
0499 m2w(1.),
0500 w2m(1.),
0501 bbmn(0.,0.,0.),
0502 bbmx(0.,0.,0.),
0503 padd(0.,0.),
0504 ext0(0.,0.,0.,0.),
0505 ext1(0.,0.,0.,0.),
0506 name(DEFAULT_NAME)
0507 {
0508 }
0509
0510
0511
0512 inline void sfr::set_propagate_epsilon(double eps){ ext0.x = eps ; }
0513 inline void sfr::set_gridscale(double gsc){ ext0.y = gsc ; }
0514 inline double sfr::get_propagate_epsilon() const { return ext0.x ; }
0515 inline double sfr::get_gridscale() const { return ext0.y ; }
0516
0517 inline void sfr::set_hostside_simtrace(){ aux1.x = 1 ; }
0518 inline void sfr::set_gasix( int gasix ){ aux1.y = gasix ; }
0519 inline void sfr::set_sensorid( int senid ){ aux1.z = senid ; }
0520 inline void sfr::set_sensorix( int senix ){ aux1.w = senix ; }
0521
0522 inline bool sfr::is_hostside_simtrace() const { return aux1.x == 1 ; }
0523 inline int sfr::get_gasix() const { return aux1.y ; }
0524 inline int sfr::get_sensorid() const { return aux1.z ; }
0525 inline int sfr::get_sensorix() const { return aux1.w ; }
0526
0527 inline void sfr::set_identity( int inst, int gasix, int sensorid, int sensorix )
0528 {
0529 set_inst(inst);
0530 set_gasix(gasix);
0531 set_sensorid( sensorid );
0532 set_sensorix( sensorix );
0533 }
0534
0535
0536 inline void sfr::set_lvid(int lvid){ aux0.x = lvid ; }
0537 inline void sfr::set_lvid_ordinal(int lvid_ordinal){ aux0.y = lvid_ordinal ; }
0538
0539 inline int sfr::get_lvid() const { return aux0.x ; }
0540 inline int sfr::get_lvid_ordinal() const { return aux0.y ; }
0541
0542
0543
0544 inline void sfr::set_inst(int ii){ aux2.x = ii ; }
0545 inline void sfr::set_nidx(int nidx){ aux2.y = nidx ; }
0546 inline void sfr::set_prim(int prim){ aux2.z = prim ; }
0547 inline void sfr::set_idx(int idx) { aux2.w = idx ; }
0548
0549 inline int sfr::get_inst() const { return aux2.x ; }
0550 inline int sfr::get_nidx() const { return aux2.y ; }
0551 inline int sfr::get_prim() const { return aux2.z ; }
0552 inline int sfr::get_idx() const { return aux2.w ; }
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563 inline bool sfr::is_zero() const
0564 {
0565 return ce.x == 0. && ce.y == 0. && ce.z == 0. && ce.w == 0. ;
0566 }
0567
0568
0569
0570
0571
0572
0573 inline double* sfr::ce_data()
0574 {
0575 return glm::value_ptr(ce);
0576 }
0577
0578 template<typename T>
0579 inline void sfr::set_ce( const T* _ce )
0580 {
0581 ce.x = _ce[0];
0582 ce.y = _ce[1];
0583 ce.z = _ce[2];
0584 ce.w = _ce[3];
0585 }
0586
0587
0588
0589 template<typename T>
0590 inline void sfr::set_extent( T _w )
0591 {
0592 ce.w = _w ;
0593 }
0594
0595 template<typename T>
0596 inline void sfr::set_m2w( const T* vv, size_t nv )
0597 {
0598 assert( nv == 16 );
0599 double* _m2w = glm::value_ptr(m2w) ;
0600 for(size_t i=0 ; i < nv ; i++ ) _m2w[i] = T(vv[i]);
0601 w2m = glm::inverse(m2w);
0602 }
0603
0604
0605 template<typename T>
0606 inline void sfr::set_bb( const T* bb )
0607 {
0608 bbmn.x = bb[0] ;
0609 bbmn.y = bb[1] ;
0610 bbmn.z = bb[2] ;
0611 bbmx.x = bb[3] ;
0612 bbmx.y = bb[4] ;
0613 bbmx.z = bb[5] ;
0614 }
0615
0616 template<typename T>
0617 inline int sfr::write_bb( T* bb ) const
0618 {
0619 bb[0] = bbmn.x ;
0620 bb[1] = bbmn.y ;
0621 bb[2] = bbmn.z ;
0622 bb[3] = bbmx.x ;
0623 bb[4] = bbmx.y ;
0624 bb[5] = bbmx.z ;
0625 return 0 ;
0626 }
0627
0628
0629
0630
0631
0632
0633
0634
0635 inline const glm::tmat4x4<double>& sfr::get_transform(bool inverse) const
0636 {
0637 return inverse ? w2m : m2w ;
0638 }
0639 inline void sfr::transform_w2m( sphoton& p, bool normalize ) const
0640 {
0641 transform( p, normalize, true );
0642 }
0643 inline void sfr::transform_m2w( sphoton& p, bool normalize ) const
0644 {
0645 transform( p, normalize, false );
0646 }
0647 inline void sfr::transform( sphoton& p, bool normalize, bool inverse ) const
0648 {
0649 const glm::tmat4x4<double>& tr = get_transform(inverse);
0650 p.transform( tr, normalize );
0651 }
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669 inline Tran<double>* sfr::getTransform() const
0670 {
0671 Tran<double>* geotran = new Tran<double>( m2w, w2m );
0672 return geotran ;
0673 }
0674
0675 inline NP* sfr::transform_photon_m2w( const NP* ph, bool normalize ) const
0676 {
0677 bool inverse = false ;
0678 return transform_photon(ph, normalize, inverse);
0679 }
0680 inline NP* sfr::transform_photon_w2m( const NP* ph, bool normalize ) const
0681 {
0682 bool inverse = true ;
0683 return transform_photon(ph, normalize, inverse);
0684 }
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703 inline NP* sfr::transform_photon( const NP* ph, bool normalize, bool inverse ) const
0704 {
0705 if( ph == nullptr ) return nullptr ;
0706 Tran<double>* tr = getTransform();
0707 assert(tr);
0708 NP* pht = Tran<double>::PhotonTransform(ph, normalize, tr, inverse );
0709 assert( pht->ebyte == 8 );
0710 return pht ;
0711 }
0712
0713
0714
0715 inline const std::string& sfr::get_name() const
0716 {
0717 return name ;
0718 }
0719
0720 inline const char* sfr::get_id() const
0721 {
0722 return name.c_str() ;
0723 }
0724
0725
0726
0727
0728 inline std::string sfr::get_key() const
0729 {
0730 return name.empty() ? "" : sstr::Replace( name.c_str(), ':', '_' ) ;
0731 }
0732
0733 inline void sfr::set_name(const char* _n)
0734 {
0735 if(_n) name = _n ;
0736 }
0737
0738
0739 inline void sfr::set_treedir(const char* _t)
0740 {
0741 if(_t) treedir = _t ;
0742 }
0743 inline const std::string& sfr::get_treedir() const
0744 {
0745 return treedir ;
0746 }
0747
0748
0749
0750 inline std::string sfr::desc_ce() const
0751 {
0752 std::stringstream ss ;
0753 ss << "sfr::desc_ce " << stra<double>::Desc(ce) ;
0754 std::string str = ss.str();
0755 return str ;
0756 }
0757
0758 inline std::string sfr::desc() const
0759 {
0760 std::stringstream ss ;
0761 ss
0762 << "[sfr::desc name [" << name << "]\n"
0763 << "ce\n"
0764 << stra<double>::Desc(ce)
0765 << "\n"
0766 << "aux0\n"
0767 << stra<int64_t>::Desc(aux0)
0768 << "\n"
0769 << "aux1\n"
0770 << stra<int64_t>::Desc(aux1)
0771 << "\n"
0772 << "aux2\n"
0773 << stra<int64_t>::Desc(aux2)
0774 << "\n"
0775 << "m2w\n"
0776 << stra<double>::Desc(m2w)
0777 << "\n"
0778 << "w2m\n"
0779 << stra<double>::Desc(w2m)
0780 << "\n"
0781 << "bbmn\n"
0782 << stra<double>::Desc(bbmn)
0783 << "\n"
0784 << "bbmx\n"
0785 << stra<double>::Desc(bbmx)
0786 << "\n"
0787 << "padd\n"
0788 << stra<double>::Desc(padd)
0789 << "\n"
0790 << "is_identity " << ( is_identity() ? "YES" : "NO " ) << "\n"
0791 << "]sfr::desc\n"
0792 ;
0793
0794 std::string str = ss.str();
0795 return str ;
0796 }
0797
0798 inline bool sfr::is_identity() const
0799 {
0800 bool m2w_identity = stra<double>::IsIdentity(m2w, EPSILON);
0801 bool w2m_identity = stra<double>::IsIdentity(w2m, EPSILON);
0802 return m2w_identity && w2m_identity ;
0803 }
0804
0805
0806
0807
0808
0809 inline NP* sfr::serialize() const
0810 {
0811 NP* a = NP::Make<double>(NUM_4x4, 4, 4) ;
0812 write( a->values<double>(), NUM_4x4*4*4 ) ;
0813 a->set_meta<std::string>("creator", "sfr::serialize");
0814 if(!name.empty()) a->set_meta<std::string>("name", name );
0815 if(!treedir.empty()) a->set_meta<std::string>("treedir", treedir );
0816 return a ;
0817 }
0818
0819 inline void sfr::save(const char* dir, const char* stem_ ) const
0820 {
0821 std::string aname = U::form_name( stem_ , ".npy" ) ;
0822 NP* a = serialize() ;
0823 a->save(dir, aname.c_str());
0824 }
0825
0826
0827
0828
0829
0830
0831
0832 inline sfr sfr::Import( const NP* a)
0833 {
0834 sfr fr ;
0835 fr.load(a);
0836 return fr ;
0837 }
0838
0839 inline sfr sfr::Load(const char* dir, const char* name)
0840 {
0841 sfr fr ;
0842 fr.load(dir, name);
0843 return fr ;
0844 }
0845 inline sfr sfr::Load_(const char* path)
0846 {
0847 sfr fr ;
0848 fr.load_(path);
0849 return fr ;
0850 }
0851
0852
0853 inline void sfr::load(const char* dir, const char* name_ )
0854 {
0855 std::string aname = U::form_name( name_ , ".npy" ) ;
0856 const NP* a = NP::Load(dir, aname.c_str() );
0857 load(a);
0858 }
0859 inline void sfr::load_(const char* path_)
0860 {
0861 const NP* a = NP::Load(path_);
0862 if(!a) std::cerr
0863 << "sfr::load_ ERROR : non-existing"
0864 << " path_ " << path_
0865 << std::endl
0866 ;
0867 assert(a);
0868 load(a);
0869 }
0870 inline void sfr::load(const NP* a)
0871 {
0872 read( a->cvalues<double>() , NUM_VALUES );
0873 std::string _name = a->get_meta<std::string>("name", "");
0874 std::string _treedir = a->get_meta<std::string>("treedir", "");
0875 if(!_name.empty()) name = _name ;
0876 if(!_treedir.empty()) treedir = _treedir ;
0877 }
0878
0879 inline const double* sfr::cdata() const
0880 {
0881 return (const double*)&ce.x ;
0882 }
0883 inline double* sfr::data()
0884 {
0885 return (double*)&ce.x ;
0886 }
0887 inline void sfr::write( double* dst, unsigned num_values ) const
0888 {
0889 assert( num_values == NUM_VALUES );
0890 char* dst_bytes = (char*)dst ;
0891 char* src_bytes = (char*)cdata();
0892 unsigned num_bytes = sizeof(double)*num_values ;
0893 memcpy( dst_bytes, src_bytes, num_bytes );
0894 }
0895
0896 inline void sfr::read( const double* src, unsigned num_values )
0897 {
0898 assert( num_values == NUM_VALUES );
0899 char* src_bytes = (char*)src ;
0900 char* dst_bytes = (char*)data();
0901 unsigned num_bytes = sizeof(double)*num_values ;
0902 memcpy( dst_bytes, src_bytes, num_bytes );
0903 }
0904
0905
0906
0907 inline std::ostream& operator<<(std::ostream& os, const sfr& fr)
0908 {
0909 os << fr.desc() ;
0910 return os;
0911 }
0912
0913