GLAMERDOC++
Gravitational Lensing Code Library
utilities_slsim.h
1 #ifndef _UTILITIES_H
2 #define _UTILITIES_H
3 
4 #include "standard.h"
5 #include <typeinfo>
6 #include <vector>
7 #include <map>
8 #include <string>
9 #include <stdexcept>
10 #include <algorithm>
11 #include <utility>
12 #include <iterator>
13 #include <cstdlib>
14 #include <random>
15 //#if __cplusplus >= 201103L
16 #include <typeindex>
17 #include <dirent.h>
18 #include <unistd.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <boost/variant.hpp>
22 #include <set>
23 #include <iomanip>
24 #include <thread>
25 #include <cmath>
26 #include <cstdint>
27 #include <limits>
28 #include <stdexcept>
29 #include <fstream>
30 #include <sstream>
31 
32 namespace Utilities
33 {
35 template<class T>
36 T to_numeric(const std::string &str) {
37  return std::stoi(str);
38 };
39 template<>
40 inline long to_numeric<long>(const std::string &str) {
41  try{
42  return std::stol(str);
43  }catch(...){
44  return -500;
45  }
46 };
47 template<>
48 inline int to_numeric<int>(const std::string &str) {
49  return std::stoi(str);
50  try{
51  return std::stoi(str);
52  }catch(...){
53  return -500;
54  }
55 };
56 template<>
57 inline float to_numeric<float>(const std::string &str) {
58  return std::stof(str);
59  try{
60  return std::stof(str);
61  }catch(...){
62  return -500;
63  }
64 };
65 template<>
66 inline double to_numeric<double>(const std::string &str) {
67  try{
68  return std::stod(str);
69  }catch(...){
70  return -500;
71  }
72 };
73 //********************************************************
74 
75 template <typename T>
76 bool AlwaysTrue(T t){return true;}
77 
78 template <typename T>
79 bool AlwaysFalse(T t){return false;}
80 
81 template <typename T>
82 T vec_sum(const std::vector<T> &v){
83  double sum=0.0;
84  for(const T &a : v) sum += a;
85  return sum;
86 }
87 
88 // this is not for the user
89 namespace detail
90 {
91 //#if __cplusplus < 201103L
92 //class type_index
93 //{
94 //public:
95 // type_index(const std::type_info& type) : t(type) {}
96 // inline bool operator<(const type_index& rhs) const { return t.before(rhs.t); }
97 //
98 //private:
99 // const std::type_info& t;
100 //};
101 //#else
102 using std::type_index;
103 //#endif
104 }
105 
106 template <class T>
107 void Matrix(T **matrix, long rows, long cols){
108  matrix = new T*[rows];
109  matrix[0] = new T[rows*cols];
110  for (long i = 1; i < rows; ++i)
111  matrix[i] = matrix[0] + i * cols;
112 }
113 
114 template <class T>
115 void free_Matrix(T **matrix, long rows, long){
116  if (rows) delete[] matrix[0];
117  delete []matrix;
118 }
119 
120 PosType **PosTypeMatrix(size_t rows, size_t cols);
121 void free_PosTypeMatrix(PosType **matrix, size_t rows, size_t cols);
122 PosType **PosTypeMatrix(long rows1,long rows2, long cols1, long cols2);
123 void free_PosTypeMatrix(PosType **matrix, long rows1,long rows2, long cols1, long cols2);
124 
126 template<typename T>
127 class D3Matrix{
128 public:
129  D3Matrix(size_t xsize,size_t ysize,size_t zsize)
130  :xn(xsize),yn(ysize),zn(zsize){
131  array = new T[xn*yn*zn];
132  }
133  ~D3Matrix(){
134  delete[] array;
135  }
136 
137  T& operator()(size_t i,size_t j,size_t k){
138  return array[i + j*xn + k*xn*yn];
139  }
140 
141  T& operator()(size_t m){
142  return array[m];
143  }
144 
145  size_t xindex(size_t m){
146  return m % (xn);
147  }
148  size_t yindex(size_t m){
149  return (m % (xn*yn) ) / xn;
150  }
151 
152  size_t zindex(size_t m){
153  return m / (xn*yn);
154  }
155 
156 private:
157  size_t xn;
158  size_t yn;
159  size_t zn;
160  T *array;
161 };
162 
163 
165 template<typename T>
166 class D2Matrix{
167 
168 public:
169  D2Matrix(size_t xsize,size_t ysize)
170  :xn(xsize),yn(ysize){
171  array = new T[xn*yn];
172  }
173  ~D2Matrix(){
174  delete[] array;
175  }
176 
177  T& operator()(size_t i,size_t j){
178  return array[i + j*xn];
179  }
180 
181  T& operator()(size_t m){
182  return array[m];
183  }
184 
185  size_t xindex(size_t m){
186  return m % xn;
187  }
188  size_t yindex(size_t m){
189  return m / xn;
190  }
191 
192 
193 private:
194  size_t xn;
195  size_t yn;
196  T *array;
197 };
198 
204 template <typename T>
206  std::vector<T> v;
207  int n;
208  int m;
209 public:
210  SymmetricMatrix(int n):n(n){
211  v.resize(n*(n+1)/2);
212  m = 2*n-1;
213  }
214  T& operator()(int i,int j){
215  //long k = j + (2*n-1-i)*i/2 ;
216  //size_t k = (i <= j ) ? j + (2*n-1-i)*i/2 : i + (2*n-1-j)*j/2;
217  size_t k = (i <= j ) ? j + (m-i)*i/2 : i + (m-j)*j/2;
218  //assert(k>=0);
219  //assert(k < v.size());
220  return v[ k ];
221  }
222  T& operator[](size_t k){
223  return v[ k ];
224  }
225  const T &operator[](size_t k) const {
226  return v[k];
227  }
228 
229  int size(){return n;}
230 
232  size_t oned_index(int i,int j){
233  return (i <= j ) ? j + (m-i)*i/2 : i + (m-j)*j/2;
234  }
235 };
236 
237 
279 template<typename BaseT>
281 {
282 public: /* iterators */
283  template<typename ValueT = BaseT> // TODO: needs to check subclass type
284  class iterator
285  {
286  private:
287  typedef typename std::vector<BaseT*>::iterator base_iterator;
288  base_iterator it;
289 
290  public:
291  typedef ValueT value_type;
292  typedef ValueT* pointer;
293  typedef const ValueT* const_pointer;
294  typedef ValueT& reference;
295  typedef const ValueT& const_reference;
296  typedef typename base_iterator::difference_type difference_type;
297  typedef typename base_iterator::iterator_category iterator_category;
298 
299  iterator() {}
300  iterator(base_iterator i) : it(i) {}
301  iterator(const iterator& other) : it(other.it) {}
302 
303  iterator& operator=(const iterator& rhs) { it = rhs.it; return *this; }
304 
305  reference operator*() { return (reference)(**it); }
306 
307  //const reference operator*() const { return (const reference)(**it); }
308 
309  pointer operator->() { return (pointer)(*it); }
310  const_pointer operator->() const { return (const_pointer)(*it); }
311 
312  iterator& operator++() { ++it; return *this; }
313  iterator operator++(int) { iterator tmp(*this); ++it; return tmp; }
314  iterator& operator--() { --it; return *this; }
315  iterator operator--(int) { iterator tmp(*this); --it; return tmp; }
316 
317  bool operator==(const iterator& rhs) const { return (it == rhs.it); }
318  bool operator!=(const iterator& rhs) const { return (it != rhs.it); }
319 
320  iterator& operator+=(difference_type n) { it += n; return *this; }
321  iterator& operator-=(difference_type n) { it -= n; return *this; }
322 
323  reference operator[](difference_type n) { return (reference)*it[n]; }
324 
325  //const reference operator[](difference_type n) const { return (const reference)*it[n]; }
326 
327  friend iterator operator+(const iterator& i, difference_type n) { return iterator(i.it + n); }
328  friend iterator operator+(difference_type n, const iterator& i) { return iterator(i.it + n); }
329  friend iterator operator-(const iterator& i, difference_type n) { return iterator(i.it - n); }
330  friend iterator operator-(difference_type n, const iterator& i) { return iterator(i.it - n); }
331 
332  friend difference_type operator-(const iterator& b, const iterator& a) { return (b.it - a.it); }
333 
334  friend bool operator<(const iterator&a, const iterator& b) { return (a.it < b.it); }
335  friend bool operator>(const iterator&a, const iterator& b) { return (a.it > b.it); }
336  friend bool operator<=(const iterator&a, const iterator& b) { return (a.it <= b.it); }
337  friend bool operator>=(const iterator&a, const iterator& b) { return (a.it >= b.it); }
338  };
339 
340 public:
343  {
344  }
345 
348  {
349  clear();
350  }
351 
354  {
355  using std::swap;
356 
357  swap(a.items, b.items);
358  swap(a.tmap, b.tmap);
359  }
360 
363  {
364  // copy-and-swap idiom
365  swap(*this, rhs);
366  return *this;
367  }
368 
370  template<typename SubclassT>
371  void copy_back(const SubclassT& obj)
372  {
373  // make sure this is a subclass of BaseT
374  check_subclass(obj);
375 
376  // copy the object
377  SubclassT* copy = new SubclassT(obj);
378 
379  // add the copy of the object to the list of items
380  items.push_back(copy);
381 
382  // add the copy to type map
383  tmap[typeid(SubclassT)].push_back(copy);
384  }
385 
386 
388  void pop_back()
389  {
390  // get very last element
391  BaseT* back = items.back();
392 
393  // remove from the vector in the type map
394  tmap[back->type()].pop_back();
395 
396  // remove from items
397  items.pop_back();
398 
399  // delete from memory
400  delete back;
401  }
402 
404  template<typename SubclassT>
405  void pop_back()
406  {
407  // search for vector belonging to SubclassT
408  typename tmap_t::iterator found = tmap.find(typeid(SubclassT));
409  if(found == tmap.end())
410  return;
411 
412  // pop from vector for type
413  found->second.pop_back();
414 
415  // go through list of all items from back, until item of correct type is found
416  for(typename base_container::reverse_iterator it = items.rbegin(); it != items.rend(); ++it)
417  {
418  if((*it)->type() == typeid(SubclassT))
419  {
420  // remove the item
421  delete (*it);
422  items.erase(it);
423  return;
424  }
425  }
426  }
427 
429  void clear()
430  {
431  for(std::size_t i = 0, n = items.size(); i < n; ++i)
432  delete items[i];
433  items.clear();
434  tmap.clear();
435  }
436 
438  template<typename SubclassT>
439  void clear()
440  {
441  // search for vector belonging to SubclassT
442  typename tmap_t::iterator found = tmap.find(typeid(SubclassT));
443  if(found == tmap.end())
444  return;
445 
446  base_container& titems = found.second;
447 
448  // delete items from vector for subclass
449  for(std::size_t i = 0, n = titems.size(); i < n; ++i)
450  delete titems[i];
451 
452  // remove items for subclass
453  tmap.erase(found);
454 
455  // erase items matching type
456  items.erase(std::remove_if(items.begin(), items.end(), is_type<SubclassT>), items.end());
457  }
458 
460  BaseT* data()
461  {
462  return items.data();
463  }
464 
466  const BaseT* data() const
467  {
468  return items.data();
469  }
470 
472  template<typename SubclassT>
473  bool type(std::size_t i)
474  {
475  return is_type<SubclassT>(items[i]);
476  }
477 
479  BaseT& operator[](std::size_t i)
480  {
481  return *items[i];
482  }
483 
485  const BaseT& operator[](std::size_t i) const
486  {
487  return *items[i];
488  }
489 
491  BaseT& get(std::size_t i)
492  {
493  return *items[i];
494  }
495 
497  const BaseT& get(std::size_t i) const
498  {
499  return *items[i];
500  }
501 
503  template<typename SubclassT>
504  SubclassT& get(std::size_t i)
505  {
506  typename tmap_t::iterator found = tmap.find(typeid(SubclassT));
507  if(found == tmap.end())
508  throw std::out_of_range(std::string() + "type " + typeid(SubclassT).name() + " not in vector");
509  return (SubclassT&)*found->second[i];
510  }
511 
513  template<typename SubclassT>
514  const SubclassT& get(std::size_t i) const
515  {
516  typename tmap_t::const_iterator found = tmap.find(typeid(SubclassT));
517  if(found == tmap.end())
518  throw std::out_of_range(std::string() + "type " + typeid(SubclassT).name() + " not in vector");
519  return (const SubclassT&)*found->second[i];
520  }
521 
523  BaseT& at(std::size_t i)
524  {
525  return *items.at(i);
526  }
527 
529  const BaseT& at(std::size_t i) const
530  {
531  return *items.at(i);
532  }
533 
538  template<typename SubclassT>
539  SubclassT& at(std::size_t i)
540  {
541  typename tmap_t::iterator found = tmap.find(typeid(SubclassT));
542  if(found == tmap.end())
543  throw std::out_of_range(std::string() + "type " + typeid(SubclassT).name() + " not in vector");
544  return (SubclassT&)*found->second.at(i);
545  }
546 
548  template<typename SubclassT>
549  const SubclassT& at(std::size_t i) const
550  {
551  typename tmap_t::const_iterator found = tmap.find(typeid(SubclassT));
552  if(found == tmap.end())
553  throw std::out_of_range(std::string() + "type " + typeid(SubclassT).name() + " not in vector");
554  return (const SubclassT&)*found->second.at(i);
555  }
556 
558  std::size_t size() const
559  {
560  return items.size();
561  }
562 
564  template<typename SubclassT>
565  std::size_t size() const
566  {
567  typename tmap_t::const_iterator found = tmap.find(typeid(SubclassT));
568  if(found == tmap.end())
569  return 0;
570  return found->second.size();
571  }
572 
574  bool empty() const
575  {
576  return items.empty();
577  }
578 
580  template<typename SubclassT>
581  bool empty() const
582  {
583  typename tmap_t::const_iterator found = tmap.find(typeid(SubclassT));
584  if(found == tmap.end())
585  return true;
586 
587  return found->second.empty();
588  }
589 
591  iterator<> begin()
592  {
593  return iterator<>(items.begin());
594  }
595 
597  iterator<> end()
598  {
599  return iterator<>(items.end());
600  }
601 
603  template<typename SubclassT>
604  iterator<SubclassT> begin()
605  {
606  typename tmap_t::iterator found = tmap.find(typeid(SubclassT));
607  if(found == tmap.end())
608  return iterator<SubclassT>(items.end());
609  return iterator<SubclassT>(found->second.begin());
610  }
611 
613  template<typename SubclassT>
614  iterator<SubclassT> end()
615  {
616  typename tmap_t::iterator found = tmap.find(typeid(SubclassT));
617  if(found == tmap.end())
618  return iterator<SubclassT>(items.end());
619  return iterator<SubclassT>(found->second.end());
620  }
621 
622 private:
624  MixedVector(const MixedVector<BaseT>& other);
625 
626  typedef std::vector<BaseT*> base_container;
627 
628  inline static void check_subclass(const BaseT&) {}
629 
630  template<typename SubclassT>
631  inline static bool is_type(const BaseT* obj) { return (typeid(*obj) == typeid(SubclassT)); }
632 
633  base_container items;
634 
635  typedef std::map<detail::type_index, base_container> tmap_t;
636  tmap_t tmap;
637 };
638 
640 template<typename BaseT>
641 class MixedVector<BaseT*>
642 {
643 public: /* iterators */
644  template<typename ValueT = BaseT*> // TODO: needs to check subclass pointer type
645  class iterator
646  {
647  private:
648  typedef typename std::vector<BaseT*>::iterator base_iterator;
649  base_iterator it;
650 
651  public:
652  typedef typename std::vector<ValueT>::iterator::value_type value_type;
653  typedef typename std::vector<ValueT>::iterator::pointer pointer;
654  typedef typename std::vector<ValueT>::iterator::reference reference;
655  typedef typename base_iterator::difference_type difference_type;
656  typedef typename base_iterator::iterator_category iterator_category;
657 
658  iterator() {}
659  iterator(base_iterator i) : it(i) {}
660  iterator(const iterator& other) : it(other.it) {}
661 
662  iterator& operator=(const iterator& rhs) { it = rhs.it; return *this; }
663 
664  reference operator*() { return (reference)*it; }
665  const reference operator*() const { return (const reference)*it; }
666 
667  iterator& operator++() { ++it; return *this; }
668  iterator operator++(int) { iterator tmp(*this); ++it; return tmp; }
669  iterator& operator--() { --it; return *this; }
670  iterator operator--(int) { iterator tmp(*this); --it; return tmp; }
671 
672  bool operator==(const iterator& rhs) const { return (it == rhs.it); }
673  bool operator!=(const iterator& rhs) const { return (it != rhs.it); }
674 
675  iterator& operator+=(difference_type n) { it += n; return *this; }
676  iterator& operator-=(difference_type n) { it -= n; return *this; }
677 
678  pointer operator[](difference_type n) { return (pointer)it[n]; }
679  const pointer operator[](difference_type n) const { return (const pointer)it[n]; }
680 
681  friend iterator operator+(const iterator& i, difference_type n) { return iterator(i.it + n); }
682  friend iterator operator+(difference_type n, const iterator& i) { return iterator(i.it + n); }
683  friend iterator operator-(const iterator& i, difference_type n) { return iterator(i.it - n); }
684  friend iterator operator-(difference_type n, const iterator& i) { return iterator(i.it - n); }
685 
686  friend difference_type operator-(const iterator& b, const iterator& a) { return (b.it - a.it); }
687 
688  friend bool operator<(const iterator&a, const iterator& b) { return (a.it < b.it); }
689  friend bool operator>(const iterator&a, const iterator& b) { return (a.it > b.it); }
690  friend bool operator<=(const iterator&a, const iterator& b) { return (a.it <= b.it); }
691  friend bool operator>=(const iterator&a, const iterator& b) { return (a.it >= b.it); }
692  };
693 
694 public:
697  {
698  }
699 
702  : items(other.items), tmap(other.tmap)
703  {
704  }
705 
708  {
709  clear();
710  }
711 
714  {
715  using std::swap;
716 
717  swap(a.items, b.items);
718  swap(a.tmap, b.tmap);
719  }
720 
723  {
724  // copy-and-swap idiom
725  swap(*this, rhs);
726  return *this;
727  }
728 
730  BaseT& back()
731  {
732  return items.back();
733  }
734 
736  const BaseT& back() const
737  {
738  return items.back();
739  }
740 
742  void push_back(BaseT* obj)
743  {
744  // make sure this is a subclass of BaseT
745  check_subclass(obj);
746 
747  // add the copy of the object pointer to the list of items
748  items.push_back(obj);
749 
750  // add the copy to type map
751  tmap[typeid(*obj)].push_back(obj);
752  }
753 
755  void pop_back()
756  {
757  // get very last element
758  BaseT* back = items.back();
759 
760  // remove from the vector in the type map
761  tmap[typeid(*back)].pop_back();
762 
763  // remove from items
764  items.pop_back();
765 
766  delete back; // delete object
767  }
768 
770  template<typename SubclassT>
771  void pop_back()
772  {
773  // search for vector belonging to SubclassT
774  typename tmap_t::iterator found = tmap.find(typeid(SubclassT));
775  if(found == tmap.end())
776  return;
777 
778  // pop from vector for type
779  found->second.pop_back();
780 
781  // go through list of all items from back, until item of correct type is found
782  for(typename std::vector<BaseT*>::reverse_iterator it = items.rbegin(); it != items.rend(); ++it)
783  {
784  if(typeid(**it) == typeid(SubclassT))
785  {
786  // remove the item
787  delete(*it);
788  items.erase(it);
789  return;
790  }
791  }
792  }
793 
795  void clear()
796  {
797  while(!empty()) pop_back();
798  }
799 
801  template<typename SubclassT>
802  void clear()
803  {
804  // remove vector for subclass
805  tmap.erase(typeid(SubclassT));
806 
807  // erase items matching type
808  items.erase(std::remove_if(items.begin(), items.end(), is_type<SubclassT>), items.end());
809  }
810 
812  BaseT** data()
813  {
814  return items.data();
815  }
816 
818  const BaseT** data() const
819  {
820  return items.data();
821  }
822 
824  template<typename SubclassT>
825  bool type(std::size_t i)
826  {
827  return is_type<SubclassT>(items[i]);
828  }
829 
831  BaseT* operator[](std::size_t i) const
832  {
833  return items[i];
834  }
835 
837  BaseT* get(std::size_t i)
838  {
839  return items[i];
840  }
841 
843  const BaseT* get(std::size_t i) const
844  {
845  return items[i];
846  }
847 
849  template<typename SubclassT>
850  SubclassT* get(std::size_t i)
851  {
852  typename tmap_t::iterator found = tmap.find(typeid(SubclassT));
853  if(found == tmap.end())
854  throw std::out_of_range(std::string() + "type " + typeid(SubclassT).name() + " not in vector");
855  return (SubclassT*)found->second[i];
856  }
857 
859  template<typename SubclassT>
860  const SubclassT* get(std::size_t i) const
861  {
862  typename tmap_t::const_iterator found = tmap.find(typeid(SubclassT));
863  if(found == tmap.end())
864  throw std::out_of_range(std::string() + "type " + typeid(SubclassT).name() + " not in vector");
865  return (const SubclassT*)found->second[i];
866  }
867 
869  BaseT* at(std::size_t i)
870  {
871  return items.at(i);
872  }
873 
875  const BaseT* at(std::size_t i) const
876  {
877  return items.at(i);
878  }
879 
884  template<typename SubclassT>
885  SubclassT* at(std::size_t i)
886  {
887  typename tmap_t::iterator found = tmap.find(typeid(SubclassT));
888  if(found == tmap.end())
889  throw std::out_of_range(std::string() + "type " + typeid(SubclassT).name() + " not in vector");
890  return (SubclassT*)found->second.at(i);
891  }
892 
894  template<typename SubclassT>
895  const SubclassT* at(std::size_t i) const
896  {
897  typename tmap_t::const_iterator found = tmap.find(typeid(SubclassT));
898  if(found == tmap.end())
899  throw std::out_of_range(std::string() + "type " + typeid(SubclassT).name() + " not in vector");
900  return (const SubclassT*)found->second.at(i);
901  }
902 
904  std::size_t size() const
905  {
906  return items.size();
907  }
908 
910  template<typename SubclassT>
911  std::size_t size() const
912  {
913  typename tmap_t::const_iterator found = tmap.find(typeid(SubclassT));
914  if(found == tmap.end())
915  return 0;
916  return found->second.size();
917  }
918 
920  bool empty() const
921  {
922  return items.empty();
923  }
924 
926  template<typename SubclassT>
927  bool empty() const
928  {
929  typename tmap_t::const_iterator found = tmap.find(typeid(SubclassT));
930  if(found == tmap.end())
931  return true;
932 
933  return found->second.empty();
934  }
935 
937  iterator<> begin()
938  {
939  return iterator<>(items.begin());
940  }
941 
943  iterator<> end()
944  {
945  return iterator<>(items.end());
946  }
947 
949  template<typename SubclassT>
950  iterator<SubclassT> begin()
951  {
952  typename tmap_t::iterator found = tmap.find(typeid(SubclassT));
953  if(found == tmap.end())
954  return iterator<SubclassT>(items.end());
955  return iterator<SubclassT>(found->second.begin());
956  }
957 
959  template<typename SubclassT>
960  iterator<SubclassT> end()
961  {
962  typename tmap_t::iterator found = tmap.find(typeid(SubclassT));
963  if(found == tmap.end())
964  return iterator<SubclassT>(items.end());
965  return iterator<SubclassT>(found->second.end());
966  }
967 
968 private:
969  inline void check_subclass(const BaseT*) {}
970 
971  template<typename SubclassT>
972  inline static bool is_type(const BaseT* obj) { return (typeid(*obj) == typeid(SubclassT)); }
973 
974  typedef std::vector<BaseT*> base_container;
975 
976  base_container items;
977 
978  typedef std::map<detail::type_index, base_container> tmap_t;
979  tmap_t tmap;
980 };
981 
982 template<class BaseT>
983 std::size_t lower_bound(std::vector<BaseT*>& items, PosType target){
984  std::size_t ju,jm,jl;
985 
986  if(items.size() == 0) return 0;
987 
988  jl=0;
989  ju=items.size()-1;
990  while (ju-jl > 1) {
991  jm=(ju+jl) >> 1;
992  if(items[jm]->compareZ(target))
993  jl=jm;
994  else
995  ju=jm;
996  }
997  return jl;
998 }
999 
1001 template<typename Container>
1002 void delete_container(Container& c) { while(!c.empty()) delete c.back(), c.pop_back(); }
1003 
1013 public:
1015  PosType x_min
1016  ,PosType y_min
1017  ,PosType my_range
1018  ,PosType smallsize
1019  ):
1020  range(my_range)
1021  {
1022  xo[0] = x_min;
1023  xo[1] = y_min;
1024  n = (int)(range/smallsize+1);
1025  }
1026 
1027  int xy2d (int x, int y);
1028  int xy2d (PosType x, PosType y);
1029  void d2xy(int d, int *x, int *y);
1030  void d2xy(int d, PosType *x, PosType *y);
1031 
1032 private:
1033  int n;
1034  PosType xo[2],range;
1035  void rot(int s,int *x, int *y, int rx, int ry);
1036 };
1037 
1038 template<typename T>
1039 T between(const T& x, const T& l, const T& u)
1040 {
1041  return std::max(l, std::min(u, x));
1042 }
1043 
1044 #ifdef ENABLE_CLANG
1045 class RandomNumbers{
1047 public:
1048 
1049  RandomNumbers(unsigned int seed);
1050  ~RandomNumbers(void);
1051 
1052  PosType operator()(void);
1054  PosType gauss(){return norm_dist(rand_gen);}
1055 private:
1056 
1057  std::normal_distribution<> norm_dist;
1058  std::mt19937 rand_gen;
1059 };
1060 #endif
1061 
1069 public:
1070 
1071  RandomNumbers_NR(long seed);
1072  // sets seed from clock
1073  RandomNumbers_NR();
1074 
1075  PosType operator()(void);
1077  PosType gauss(){
1078  ++calls;
1079  if(count){
1080  do{
1081  u = 2*ran2() - 1;
1082  v = 2*ran2() - 1;
1083  s = u*u +v*v;
1084  }while( s > 1.0 || s == 0.0);
1085 
1086  s = sqrt(-2*log(s)/s);
1087  count = false;
1088  return s*u;
1089  }else{
1090  count = true;
1091  return s*v;
1092  }
1093  };
1094 
1095  int poisson(double lam){
1096  if(lam > 200){
1097  return std::max<long>(std::lround( gauss()*sqrt(lam) + lam ) ,0);
1098  }
1099  double L = exp(-lam),p=1;
1100  int k = 0;
1101  do{
1102  ++k;
1103  p *= operator()();
1104  }while(p>L);
1105 
1106  return k-1;
1107  }
1108 
1109 // int poisson(double lam){
1110 //
1111 // int step = 500;
1112 // double Lam = lam,p=1;
1113 // int k = 0;
1114 // do{
1115 // ++k;
1116 // p *= operator()();
1117 // while(p<1 && Lam>0){
1118 // if(Lam > step){
1119 // p *= exp(step);
1120 // Lam -= step;
1121 // }else{
1122 // p *= exp(Lam);
1123 // Lam=0;
1124 // }
1125 // }
1126 // }while(p>1);
1127 //
1128 // return k-1;
1129 // }
1130 
1131  size_t calls = 0;
1132 
1133  long getseed(){return firstseed;}
1134 private:
1135  long idum;
1136  PosType ran2(void);
1137 
1138  int IM1;
1139  int IM2;
1140  PosType AM;
1141  //int IMM1 = (IM1-1);
1142  int IA1;
1143  int IA2;
1144  int IQ1;
1145  int IQ2;
1146  int IR1;
1147  int IR2;
1148  int NDIV;
1149  PosType EPS;
1150  PosType RNMX;
1151 
1152  long idum2;
1153  long iy;
1154  long iv[32];
1155  bool count;
1156  PosType u,v,s;
1157  long firstseed;
1158 
1159 };
1160 
1161 class BetaDistribution {
1162 public:
1163  using result_type = double;
1164 
1165  BetaDistribution(double alpha, double beta)
1166  : alpha_(alpha),
1167  beta_(beta),
1168  gamma_alpha_(alpha, 1.0),
1169  gamma_beta_(beta, 1.0)
1170  {
1171  if (!(alpha > 0.0) || !(beta > 0.0)) {
1172  throw std::invalid_argument(
1173  "Beta distribution parameters must be positive");
1174  }
1175  }
1176 
1177  double operator()(){
1178  // The loop protects against the extremely unlikely case that both
1179  // Gamma samples underflow to zero.
1180  for (;;) {
1181  const double x = gamma_alpha_(engine);
1182  const double y = gamma_beta_(engine);
1183  const double sum = x + y;
1184 
1185  if (sum > 0.0 && std::isfinite(sum)) {
1186  return x / sum;
1187  }
1188  }
1189  }
1190 
1191  double alpha() const noexcept { return alpha_; }
1192  double beta() const noexcept { return beta_; }
1193 
1194  static constexpr double min() noexcept { return 0.0; }
1195  static constexpr double max() noexcept { return 1.0; }
1196 
1197 private:
1198 
1199  std::mt19937_64 engine{std::random_device{}()};
1200  double alpha_;
1201  double beta_;
1202  std::gamma_distribution<double> gamma_alpha_;
1203  std::gamma_distribution<double> gamma_beta_;
1204 };
1205 
1206 
1207 
1209 template <typename T, typename R>
1210 void shuffle(
1211  std::vector<T> &vec
1212  ,R &ran
1213 ){
1214 
1215  size_t ran_t;
1216  if(vec.size() < 2) return;
1217  for (size_t i = vec.size()-1; i>0; --i) {
1218  ran_t = (size_t)(ran()*(i+1));
1219  //swap(tmp,vec[ran_t]);
1220  std::swap(vec[ran_t],vec[i]);
1221  //swap(vec[i],tmp);
1222  }
1223 }
1224 
1226 template <typename T>
1227 void sort_indexes(const std::vector<T> &v
1228  ,std::vector<size_t> &index
1229 ) {
1230 
1231  // initialise original index locations
1232  index.resize(v.size());
1233  for (size_t i = 0; i != index.size(); ++i) index[i] = i;
1234 
1235  // sort indexes based on comparing values in v
1236  std::sort(index.begin(), index.end(),[&v](size_t i1, size_t i2) {return v[i1] < v[i2];});
1237 }
1238 
1239 template <typename T>
1240 void sort_indexes(const T *v
1241  ,std::vector<size_t> &index
1242  ,size_t N) {
1243 
1244  // initialise original index locations
1245  index.resize(N);
1246 
1247  for (size_t i = 0; i != index.size(); ++i) index[i] = i;
1248 
1249  // sort indexes based on comparing values in v
1250  std::sort(index.begin(), index.end(),
1251  [v](size_t i1, size_t i2) {return v[i1] < v[i2];});
1252 }
1253 
1255 template <typename T>
1256 void sort_indexes_decending(const std::vector<T> &v
1257  ,std::vector<size_t> &index
1258 ) {
1259 
1260  // initialise original index locations
1261  index.resize(v.size());
1262  for (size_t i = 0; i != index.size(); ++i) index[i] = i;
1263 
1264  // sort indexes based on comparing values in v
1265  std::sort(index.begin(), index.end(),
1266  [&v](size_t i1, size_t i2) {return v[i1] > v[i2];});
1267 }
1268 
1274 template <typename R>
1276 public:
1277  ShuffledIndex(size_t N,R &ran){
1278  if(N == 0) throw std::invalid_argument("N=0");
1279 
1280  for(size_t i=0 ; i<N ; ++i) index[i] = i;
1281  index.resize(N);
1282  Utilities::shuffle(index,ran);
1283  index_internal = 0;
1284  }
1285 
1287  size_t operator*(){return index[index_internal];}
1289  size_t operator++(int){
1290  size_t tmp = index[index_internal];
1291  if(index_internal == index.size()){
1292  index_internal = 0;
1293  }else{
1294  ++index_internal;
1295  }
1296  return tmp;
1297  }
1299  size_t operator++(){
1300  if(index_internal == index.size()){
1301  index_internal = 0;
1302  }else{
1303  ++index_internal;
1304  }
1305  return index[index_internal];
1306  }
1307 
1309  void reshuffle(R &ran){
1310  Utilities::shuffle(index,ran);
1311  index_internal = 0;
1312  }
1313 
1314 private:
1315  std::vector<size_t> index;
1316  size_t index_internal;
1317 };
1318 
1319 
1320 // reorders vec according to index p
1321 template <typename T>
1322 void apply_permutation(
1323  T *vec,
1324  const std::vector<std::size_t>& p)
1325 {
1326  std::vector<T> copy(p.size());
1327 
1328  for(std::size_t i = 0; i < p.size(); ++i){
1329  copy[i] = vec[i];
1330  }
1331 
1332  for(std::size_t i = 0; i < p.size(); ++i){
1333  vec[i] = copy[p[i]];
1334  }
1335 }
1336 
1337 template <typename T>
1338 void apply_permutation(
1339  std::vector<T>& vec,
1340  const std::vector<std::size_t>& p)
1341 {
1342  apply_permutation(vec.data(),p);
1343 }
1344 
1345 
1350 void powerspectrum2d(
1351  std::valarray<double> const &aa
1352  ,std::valarray<double> const &bb
1353  ,long nx
1354  ,long ny
1355  ,double boxlx
1356  ,double boxly
1357  ,std::vector<double> &ll
1358  ,std::vector<double> &Pl
1359  ,double zeropaddingfactor
1360  );
1361 
1362 void powerspectrum2d(
1363  std::valarray<double> &aa
1364  ,long nx
1365  ,long ny
1366  ,double boxlx
1367  ,double boxly
1368  ,std::vector<double> &ll
1369  ,std::vector<double> &Pl
1370 );
1371 
1373  std::valarray<double> &aa
1374  ,long nx
1375  ,long ny
1376  ,double boxlx
1377  ,double boxly
1378  ,const std::vector<double> &ll
1379  ,std::vector<double> &Pl
1380  ,std::vector<double> &llave
1381 );
1382 
1383 void powerspectrum2d(
1384  std::valarray<float> const &aa
1385  ,std::valarray<float> const &bb
1386  ,long nx
1387  ,long ny
1388  ,double boxlx
1389  ,double boxly
1390  ,std::vector<double> &ll
1391  ,std::vector<double> &Pl
1392  ,double zeropaddingfactor
1393  );
1394 
1395 void powerspectrum2d(
1396  std::valarray<float> &aa
1397  ,long nx
1398  ,long ny
1399  ,double boxlx
1400  ,double boxly
1401  ,std::vector<double> &ll
1402  ,std::vector<double> &Pl
1403 );
1404 
1406  std::valarray<float> &aa
1407  ,int nx
1408  ,int ny
1409  ,double boxlx
1410  ,double boxly
1411  ,const std::vector<double> &ll
1412  ,std::vector<double> &Pl
1413  ,std::vector<double> &llave
1414 );
1415 
1417 int GetNThreads();
1418 
1420 namespace IO{
1421 
1422 inline bool file_exists (const std::string& name) {
1423  struct stat buffer;
1424  return (stat (name.c_str(), &buffer) == 0);
1425 }
1426 
1427  template <class T>
1429  std::string filename
1430  ,std::vector<T> &x
1431  ,int skiplines = 0
1432  ,bool verbose = false
1433  ){
1434 
1435  x.clear();
1436 
1437  std::ifstream file_in(filename.c_str());
1438  std::string myline;
1439  std::string space = " ";
1440  T myt1;
1441 
1442  std::string strg;
1443  std::stringstream buffer;
1444 
1445  if(!file_in){
1446  std::cout << "Can't open file " << filename << std::endl;
1447  ERROR_MESSAGE();
1448  throw std::runtime_error(" Cannot open file.");
1449  }
1450 
1451  std::cout << "Reading from " << filename << std::endl;
1452  size_t i=0;
1453  while(i < skiplines){
1454  getline(file_in,myline);
1455  ++i;
1456  }
1457  while(file_in.peek() == '#'){
1458  file_in.ignore(10000,'\n');
1459  ++i;
1460  }
1461  std::cout << "skipped "<< i << " comment lines in " << filename << std::endl;
1462 
1463  size_t pos;
1464  // read in data
1465  while(getline(file_in,myline)){
1466 
1467  if(myline[0] == '#'){
1468  std::cout << "skipped line " << i << std::endl;
1469  continue;
1470  }
1471 
1472  pos= myline.find_first_not_of(space);
1473  myline.erase(0,pos);
1474 
1475  buffer << myline;
1476  buffer >> myt1;
1477  if(verbose) std::cout << myt1 << " ";
1478  x.push_back(myt1);
1479 
1480  strg.clear();
1481  buffer.clear();
1482  myline.clear();
1483 
1484  }
1485  std::cout << "Read " << x.size() << " lines from " << filename << std::endl;
1486  }
1487 
1490 template <class T1,class T2>
1492  std::string filename
1493  ,std::vector<T1> &x
1494  ,std::vector<T2> &y
1495  ,std::string delineator = " "
1496  ,int skiplines = 0
1497  ,bool verbose = false
1498 
1499  ){
1500 
1501  x.clear();
1502  y.clear();
1503 
1504  std::ifstream file_in(filename.c_str());
1505  std::string myline;
1506  std::string space = " ";
1507  T1 myt1;
1508  T2 myt2;
1509 
1510  std::string strg;
1511  std::stringstream buffer;
1512 
1513  if(!file_in){
1514  std::cout << "Can't open file " << filename << std::endl;
1515  ERROR_MESSAGE();
1516  throw std::runtime_error(" Cannot open file.");
1517  }
1518 
1519  std::cout << "Reading caustic information from " << filename << std::endl;
1520  size_t i=0;
1521  while(i < skiplines){
1522  getline(file_in,myline);
1523  ++i;
1524  }
1525  while(file_in.peek() == '#'){
1526  file_in.ignore(10000,'\n');
1527  ++i;
1528  }
1529  std::cout << "skipped "<< i << " comment lines in " << filename << std::endl;
1530 
1531  size_t pos;
1532  // read in data
1533  while(getline(file_in,myline)){
1534 
1535  if(myline[0] == '#'){
1536  std::cout << "skipped line " << i << std::endl;
1537  continue;
1538  }
1539 
1540  pos= myline.find_first_not_of(space);
1541  myline.erase(0,pos);
1542 
1543 
1544  pos = myline.find(delineator);
1545  strg.assign(myline,0,pos);
1546  buffer << strg;
1547  buffer >> myt1;
1548  if(verbose) std::cout << myt1 << " ";
1549  x.push_back(myt1);
1550 
1551  myline.erase(0,pos+1);
1552  pos= myline.find_first_not_of(space);
1553  myline.erase(0,pos);
1554 
1555  strg.clear();
1556  buffer.clear();
1557 
1558  pos = myline.find(space);
1559  strg.assign(myline,0,pos);
1560  buffer << strg;
1561  buffer >> myt2;
1562  if(verbose) std::cout << myt2 << std::endl;
1563  y.push_back(myt2);
1564 
1565  strg.clear();
1566  buffer.clear();
1567  myline.clear();
1568 
1569  }
1570  std::cout << "Read " << x.size() << " lines from " << filename << std::endl;
1571 }
1574 template <class T1,class T2,class T3>
1576  std::string filename
1577  ,std::vector<T1> &x
1578  ,std::vector<T2> &y
1579  ,std::vector<T3> &z
1580  ,std::string delineator = " "
1581  ,bool verbose = false
1582 
1583  ){
1584 
1585 
1586  assert(0); // Untested!!!!
1587  x.clear();
1588  y.clear();
1589  z.clear();
1590 
1591  std::ifstream file_in(filename.c_str());
1592  std::string myline;
1593  std::string space = " ";
1594  T1 myt1;
1595  T2 myt2;
1596  T3 myt3;
1597 
1598  std::string strg;
1599  std::stringstream buffer;
1600 
1601  if(!file_in){
1602  std::cout << "Can't open file " << filename << std::endl;
1603  ERROR_MESSAGE();
1604  throw std::runtime_error(" Cannot open file.");
1605  }
1606 
1607  std::cout << "Reading caustic information from " << filename << std::endl;
1608  size_t i=0;
1609  while(file_in.peek() == '#'){
1610  file_in.ignore(10000,'\n');
1611  ++i;
1612  }
1613  std::cout << "skipped "<< i << " comment lines in " << filename << std::endl;
1614 
1615  size_t pos;
1616  // read in data
1617  while(getline(file_in,myline)){
1618 
1619  if(myline[0] == '#'){
1620  std::cout << "skipped line " << i << std::endl;
1621  continue;
1622  }
1623 
1624  pos= myline.find_first_not_of(space);
1625  myline.erase(0,pos);
1626 
1627 
1628  pos = myline.find(delineator);
1629  strg.assign(myline,0,pos);
1630  buffer << strg;
1631  buffer >> myt1;
1632  if(verbose) std::cout << myt1 << " ";
1633  x.push_back(myt1);
1634 
1635  myline.erase(0,pos+1);
1636  pos= myline.find_first_not_of(space);
1637  myline.erase(0,pos);
1638 
1639  strg.clear();
1640  buffer.clear();
1641 
1642  // ******************
1643 
1644 
1645  pos = myline.find(space);
1646  strg.assign(myline,0,pos);
1647  buffer << strg;
1648  buffer >> myt2;
1649  if(verbose) std::cout << myt2 << std::endl;
1650  y.push_back(myt2);
1651 
1652  myline.erase(0,pos+1);
1653  pos= myline.find_first_not_of(space);
1654  myline.erase(0,pos);
1655 
1656  strg.clear();
1657  buffer.clear();
1658 
1659  // ******************
1660  pos = myline.find(space);
1661  strg.assign(myline,0,pos);
1662  buffer << strg;
1663  buffer >> myt3;
1664  if(verbose) std::cout << myt3 << std::endl;
1665  y.push_back(myt3);
1666 
1667  strg.clear();
1668  buffer.clear();
1669  myline.clear();
1670 
1671  }
1672  std::cout << "Read " << x.size() << " lines from " << filename << std::endl;
1673 }
1674 
1675 int NumberOfEntries(const std::string &string,char deliniator);
1676 
1678 int CountColumns(std::string filename
1679  ,char comment_char = '#'
1680  ,char deliniator = ' '
1681 );
1682 
1686 void ReadFileNames(
1687  std::string dir
1688  ,const std::string filespec
1689  ,std::vector<std::string> & filenames
1690  ,bool verbose);
1691 
1693 bool check_directory(std::string dir);
1695 bool make_directories(const std::string &root_dir);
1696 
1697 
1707 template <typename T>
1708 void ReadASCII(std::vector<T> &data
1709  ,std::string filename
1710  ,int &columns
1711  ,int &rows
1712  ,char comment_char = '#'
1713  ,int skiplines = 0
1714  ,size_t MaxNrows = std::numeric_limits<size_t>::max()
1715  ,bool verbose = true){
1716 
1717  std::ifstream file(filename);
1718  // find number of particles
1719  if (!file.is_open()){
1720  std::cerr << "file " << filename << " cann't be opened." << std::endl;
1721  throw std::runtime_error("no file");
1722  }
1723 
1724 
1725  data.empty();
1726 
1727  std::string line;
1728  columns = 0;
1729  rows = 0;
1730  size_t first_data_line;
1731 
1732  // skip over first lines
1733  int i=0;
1734  while(i < skiplines){
1735  std::getline(file,line);
1736  if(!file) break; // probably EOF
1737  ++i;
1738  }
1739 
1740  // read comment lines and first data line
1741  do{
1742  first_data_line = file.tellg();
1743  std::getline(file,line);
1744  if(!file) break; // probably EOF
1745  }while(line[0] == comment_char);
1746 
1747  columns = NumberOfEntries(line,' ');
1748 
1749  file.seekg(first_data_line); // move back to first data line
1750 
1751  std::copy(std::istream_iterator<T>(file),
1752  std::istream_iterator<T>(),
1753  std::back_inserter(data));
1754 
1755  rows = data.size()/columns;
1756  if(verbose){
1757  std::cout << "Read " << rows << " rows of " << columns << " columns from file " << filename << std::endl;
1758  }
1759 }
1760 
1778 template <typename T>
1779 int ReadCSVnumerical1(std::string filename
1780  ,std::vector<std::vector<T> > &data
1781  ,std::vector<std::string> &column_names
1782  ,size_t MaxNumber = 100000000
1783  ,char comment_char = '#'
1784  ,char deliniator = ','
1785  ,std::string replace = "\\N"
1786  ,std::function<bool(std::vector<T> &)> accept = [](std::vector<T> &v){return true;}
1787  ){
1788 
1789  bool verbose = false;
1790 
1791  std::ifstream file(filename);
1792  // find number of particles
1793  if (!file.is_open()){
1794  std::cerr << "file " << filename << " cann't be opened." << std::endl;
1795  throw std::runtime_error("no file");
1796  }
1797 
1798  int count_preamble=0;
1799  std::string line;
1800  // read comment lines and first data line
1801  do{
1802  std::getline(file,line);
1803  ++count_preamble;
1804  if(!file) break; // probably EOF
1805  }while(line[0] == comment_char);
1806 
1807  // read the names
1808  std::stringstream lineStream(line);
1809  std::string cell;
1810  column_names.empty();
1811  while(std::getline(lineStream,cell, deliniator))
1812  {
1813  column_names.push_back(cell);
1814  }
1815  // This checks for a trailing comma with no data after it.
1816  if (!lineStream && cell.empty())
1817  {
1818  column_names.push_back("");
1819  }
1820 
1821  if(verbose){ // print column names
1822  int i = 0;
1823  for(auto st : column_names){
1824  std::cout << i++ << " " << st << std::endl;
1825  }
1826  }
1827 
1828  int ncolumns = NumberOfEntries(line,deliniator);
1829 
1830  // check if any of the columns are strings
1831  std::getline(file,line);
1832  {
1833  size_t n=0,m = 0,i=0;
1834  do{
1835  m = line.find(",",n);
1836  cell = line.substr(n,m-n);
1838  cell.erase(remove_if(cell.begin(),cell.end(), isspace), cell.end());
1839  n = m+1;
1840  ++i;
1841  }while(m != std::string::npos);
1842  }
1843 
1844  // count number of data line
1845  size_t number_of_data_lines = 1;
1846  while(std::getline(file, line) && number_of_data_lines < MaxNumber ) ++number_of_data_lines;
1847 
1848  //std::vector<std::vector<T> > tmp_data(columns,std::vector<T>(number_of_data_lines));
1849  std::vector<std::vector<T> > tmp_data(ncolumns,std::vector<T>(0));
1850  swap(data,tmp_data);
1851  std::vector<T> tmp_row(ncolumns);
1852 
1854  //file.seekg(std::ios::beg);
1855  file.clear();
1856  file.close();
1857  file.open(filename);
1858  for(int i=0; i < count_preamble; ++i){
1859  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
1860  }
1861 
1862  size_t rows = 0;
1863  while(std::getline(file,line) && rows < MaxNumber){
1864  // read the names
1865  std::stringstream lineStream(line);
1866  std::string cell;
1867 
1868  int i=0;
1869  while(std::getline(lineStream,cell,deliniator))
1870  {
1871  if(cell==replace) cell='0';
1872 
1874  cell.erase(remove_if(cell.begin(),cell.end(), isspace), cell.end());
1875  //data[i].push_back(to_numeric<T>(cell));
1876  //data[i][rows] = to_numeric<T>(cell);
1877  tmp_row[i] = to_numeric<T>(cell);
1878  i = (i+1)%ncolumns;
1879  }
1880  if(accept(tmp_row)){
1881  ++rows;
1882  for(int i=0 ; i < ncolumns ; ++i) data[i].push_back(tmp_row[i]);
1883  }
1884  }
1885  return 1;
1886 }
1887 
1892 template <typename T>
1893 size_t ReadCSVrange(std::string filename
1894  ,std::vector<std::vector<T> > &ranges
1895  ,std::vector<std::string> &column_names
1896  ,size_t MaxNumber = 100000000
1897  ,char comment_char = '#'
1898  ,char deliniator = ','
1899  ,std::string replace = "\\N"
1900  ,std::function<bool(std::vector<T> &)> accept = [](std::vector<T> &v){return true;}
1901 ){
1902 
1903  bool verbose = false;
1904 
1905  std::ifstream file(filename);
1906  // find number of particles
1907  if (!file.is_open()){
1908  std::cerr << "file " << filename << " cann't be opened." << std::endl;
1909  throw std::runtime_error("no file");
1910  }
1911 
1912  int count_preamble=0;
1913  std::string line;
1914  // read comment lines and first data line
1915  do{
1916  std::getline(file,line);
1917  ++count_preamble;
1918  if(!file) break; // probably EOF
1919  }while(line[0] == comment_char);
1920 
1921  // read the names
1922  std::stringstream lineStream(line);
1923  std::string cell;
1924  column_names.empty();
1925  while(std::getline(lineStream,cell, ','))
1926  {
1927  column_names.push_back(cell);
1928  }
1929  // This checks for a trailing comma with no data after it.
1930  if (!lineStream && cell.empty())
1931  {
1932  column_names.push_back("");
1933  }
1934 
1935  if(verbose){ // print colum names
1936  int i = 0;
1937  for(auto st : column_names){
1938  std::cout << i++ << " " << st << std::endl;
1939  }
1940  }
1941 
1942  int columns = NumberOfEntries(line,deliniator);
1943 
1944  std::vector<std::vector<T> > tmp_ranges(columns,std::vector<T>(2));
1945  swap(ranges,tmp_ranges);
1946  std::vector<T> tmp_row(columns);
1947 
1949  //file.seekg(std::ios::beg);
1950  file.clear();
1951  file.close();
1952  file.open(filename);
1953  for(int i=0; i < count_preamble; ++i){
1954  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
1955  }
1956  //std::getline(file,line);
1957 
1958  size_t rows = 0;
1959  while(std::getline(file,line) && rows < MaxNumber){
1960  // read the names
1961  std::stringstream lineStream(line);
1962  std::string cell;
1963 
1964  int i=0;
1965  while(std::getline(lineStream,cell,deliniator))
1966  {
1967  if(cell==replace) cell='0';
1968 
1970  cell.erase(remove_if(cell.begin(),cell.end(), isspace), cell.end());
1971  tmp_row[i] = to_numeric<T>(cell);
1972  i = (i+1)%columns;
1973  }
1974  if(accept(tmp_row)){
1975  if(rows==0){
1976  for(int j=0 ; j < columns ; ++j){
1977  ranges[j][0] = tmp_row[j];
1978  ranges[j][1] = tmp_row[j];
1979 
1980  }
1981  }else{
1982  for(int j=0 ; j < columns ; ++j){
1983  if(ranges[j][0] > tmp_row[j]) ranges[j][0] = tmp_row[j];
1984  if(ranges[j][1] < tmp_row[j]) ranges[j][1] = tmp_row[j];
1985  }
1986  }
1987  ++rows;
1988  }
1989  }
1990  return rows;
1991 }
1992 
2008 template <typename T>
2009 int ReadCSVnumerical2(std::string filename
2010  ,std::vector<std::vector<T> > &data
2011  ,std::vector<std::string> &column_names
2012  ,size_t Nmax = 1000000
2013  ,char comment_char = '#'
2014  ,char deliniator = ','
2015  ,bool header = true
2016  ,std::string reject = ""
2017 ){
2018 
2019 
2020  std::ifstream file(filename);
2021 
2022  if (!file.is_open()){
2023  std::cerr << "file " << filename << " cann't be opened." << std::endl;
2024  throw std::runtime_error("no file");
2025  }
2026  std::string line;
2027  // read comment lines and first data line
2028  do{
2029  std::getline(file,line);
2030  if(!file) break; // probably EOF
2031  }while(line[0] == comment_char);
2032 
2033  // read the names
2034  std::stringstream lineStream(line);
2035  std::string cell;
2036  column_names.empty();
2037  long ii = 0;
2038 
2039  if(header){
2040  while(std::getline(lineStream,cell,deliniator))
2041  {
2042  column_names.push_back(cell);
2043  }
2044 
2045  // This checks for a trailing comma with no data after it.
2046  if (!lineStream && cell.empty())
2047  {
2048  column_names.push_back("");
2049  }
2050  }else{
2051 
2052  while(std::getline(lineStream,cell,deliniator))
2053  {
2054  column_names.push_back(cell);
2055  }
2056 
2057  data.emplace_back(column_names.size());
2058  int i=0;
2059  for(auto a : column_names){
2061  cell.erase(remove_if(cell.begin(),cell.end(), isspace), cell.end());
2062  data.back()[i++] = to_numeric<T>(a);
2063  }
2064  ++ii;
2065  }
2066 
2067  int columns = NumberOfEntries(line,deliniator);
2068 
2069  for(auto &v : data ) v.empty();
2070 
2071  while(std::getline(file,line) && ii < Nmax){
2072 
2073  data.emplace_back(columns);
2074 
2075  // read the numbers
2076  std::stringstream lineStream(line);
2077  std::string cell;
2078 
2079  int i=0;
2080  while(std::getline(lineStream,cell, deliniator))
2081  {
2082  assert(i < columns);
2083  cell.erase(remove_if(cell.begin(),cell.end(), isspace), cell.end());
2084  if(cell == reject){
2085  data.pop_back();
2086  --ii;
2087  break;
2088  }else{
2089  data.back()[i] = to_numeric<T>(cell);
2090  ++i;
2091  }
2092  }
2093  ++ii;
2094  }
2095 
2096  return 1;
2097 }
2098 
2117 template<typename T>
2118 void writeCSV(const std::string filename
2119  ,const std::vector<std::string> header
2120  ,std::vector<T *> &data
2121 ){
2122 
2123  std::ofstream s(filename + ".csv");
2124 
2125  long ncol = header.size();
2126  assert(ncol == data.size() );
2127  for(int i = 0 ; i < header.size()-1 ; ++i){
2128  s << header[i] << ",";
2129  }
2130  s << header.back() << std::endl;
2131 
2132  size_t nrow = data[0]->size();
2133  for(auto v : data) assert(nrow == v->size() );
2134 
2135  for(size_t j = 0 ; j < nrow ; ++j){
2136  for(int i = 0 ; i < ncol-1 ; ++i){
2137  s << data[i]->operator[](j) << ",";
2138  }
2139  s << data.back()->operator[](j) << "\n";
2140  }
2141 }
2142 
2143 /*** \brief A class for reading and then looking up objects from a CSV catalog.
2144 
2145  The constructor will read in the whole catalog and sort it into Nxbins X-bins. Each
2146  X-bin is then sorted by Y.
2147 
2148  The find(x,y) function will set the current value to a galaxy with a x within the
2149  x-bin of x and a y close to y. The other information in the row of the csv file for
2150  this entry can then be read.
2151 
2152  */
2153 class XYcsvLookUp{
2154 public:
2155  XYcsvLookUp(std::string datafile
2156  ,std::string Xlabel
2157  ,std::string Ylabel
2158  ,int Nxbins
2159  ,size_t MaxNumber = 1000000
2160  ,bool verbose = false);
2161  XYcsvLookUp(
2162  std::string datafile
2163  ,std::string Xlabel
2164  ,std::string Ylabel
2165  ,std::vector<double> Xbins
2166  ,size_t MaxNumber = 1000000
2167  ,bool verbose = false);
2168 
2170  std::vector<double> find(double x,double y);
2171 
2173  double operator[](std::string label) const;
2174 
2176  double operator[](int i) const{
2177  return (*current)[i];
2178  }
2180  double getX() const {
2181  return (*current)[Xindex];
2182  }
2184  double getY() const {
2185  return (*current)[Yindex];
2186  }
2188  std::vector<double> record() const{
2189  return *current;
2190  }
2192  std::vector<double> operator*() const {
2193  return *current;
2194  }
2195 
2196  void operator++(){
2197  if(current != data.end() ) ++current;
2198  }
2199  void operator--(){
2200  if(current != data.begin() ) --current;
2201  }
2203  std::vector<std::string> labels() const{
2204  return column_names;
2205  }
2206 
2207  double Xmin() const {return xmin;}
2208  double Xmax() const {return xmax;}
2210  double Ymin(double x) const;
2212  double Ymax(double x) const;
2213 
2214  void printcurrent(){
2215  int i = 0;
2216  for(auto label : column_names){
2217  std::cout << label << " : " << (*current)[i++] << std::endl;
2218  }
2219  }
2220 
2221 private:
2222  int Xindex;
2223  int Yindex;
2224  double xmax;
2225  double xmin;
2226  std::vector<std::vector<double> >::iterator current;
2227  std::vector<std::vector<std::vector<double> >::iterator> borders;
2228  std::vector<std::vector<double> > data;
2229  std::vector<std::string> column_names;
2230  std::vector<double> Xborders;
2231  size_t NinXbins;
2232  std::string filename;
2233 };
2234 } // Utilities::IO
2235 
2237 void splitstring(std::string &line,std::vector<std::string> &vec,const std::string &delimiter);
2238 
2247 template< typename T>
2249 public:
2250  DataFrame(std::string datafile
2251  ,size_t MaxNumber = 1000000
2252  ,char comment_char = '#'
2253  ,char deliniator = ','
2254  ,std::string replace = "\\N"
2255  ,std::function<bool(std::vector<T> &)> accept = [](std::vector<T> &v){return true;}
2256  ):filename(datafile){
2257  input(datafile,MaxNumber,comment_char,deliniator,replace,accept);
2258  };
2259 
2260  DataFrame(){};
2261 
2262  void input(std::string datafile
2263  ,size_t MaxNumber = 1000000
2264  ,char comment_char = '#'
2265  ,char deliniator = ','
2266  ,std::string replace = "\\N"
2267  ,std::function<bool(std::vector<T> &)> accept = [](std::vector<T> &v){return true;}
2268  ){
2269  filename = datafile;
2270  Utilities::IO::ReadCSVnumerical1(datafile,data,column_names,MaxNumber,'#',',',replace,accept);
2271  for(int i=0 ; i<column_names.size() ; ++i) datamap[column_names[i]] = i;
2272  };
2273 
2275  void pop(std::string colname){
2276 
2277  int i=datamap[colname];
2278 
2279  swap(column_names[i],column_names.back());
2280  column_names.pop_back();
2281  swap(data[i],data.back());
2282  data.pop_back();
2283 
2284  datamap.empty();
2285  for(int i=0 ; i<column_names.size() ; ++i) datamap[column_names[i]] = i;
2286  }
2287 
2289  std::vector<T>& operator[](const std::string &label){
2290  if(datamap.find(label) == datamap.end()){
2291  std::cerr << "No label - " << label << " - in " << filename <<std::endl;
2292  throw std::invalid_argument("no label");
2293  }
2294  return data[datamap[label]];
2295  //for(auto c : column_names ) std::cout << c << " ";
2296  //std::cout << std::endl;
2297  //throw std::invalid_argument(label + " was not one of the columns of the galaxy data file :" + filename);
2298  };
2299  const std::vector<T>& operator[](const std::string &label) const{
2300  if(datamap.find(label) == datamap.end()){
2301  std::cerr << "No label - " << label << " - in " << filename <<std::endl;
2302  throw std::invalid_argument("no label");
2303  }
2304  return data[datamap[label]];
2305  };
2306 
2308  void add_column(const std::string &name,const std::vector<T> &vec){
2309  if(vec.size() != data[0].size()){
2310  std::cerr << "Added column to DataFrame needs to have the same size." << std::endl;
2311  throw std::invalid_argument("wrong size");
2312  }
2313  column_names.push_back(name);
2314  data.push_back(vec);
2315  data[name] = data.size()-1;
2316  };
2317 
2319  std::vector<T>& operator[](int i){
2320  return data[i];
2321  };
2322  const std::vector<T>& operator[](int i) const{
2323  return data[i];
2324  };
2325 
2327  std::vector<std::string> labels() const{
2328  return column_names;
2329  };
2330 
2331  // sort by one of the columns
2332  void sortby(std::string name){
2333  std::vector<size_t> index(data[0].size());
2334  size_t N = index.size();
2335  for(size_t i=0 ; i<N ; ++i) index[i] = i;
2336 
2337  sort_indexes(data[datamap[name]],index);
2338  std::vector<T> tmp_v(N);
2339 
2340  for(size_t j=0 ; j<data.size() ; ++j){
2341  for(size_t i=0 ; i<N ; ++i){
2342  tmp_v[i] = data[j][index[i]];
2343  }
2344  swap(data[j],tmp_v);
2345  }
2346  }
2347 
2348  // shuffle order of rows
2349  void shuffle(Utilities::RandomNumbers_NR &ran){
2350  std::vector<size_t> index(data[0].size());
2351  size_t N = index.size();
2352  for(size_t i=0 ; i<N ; ++i) index[i] = i;
2353  Utilities::shuffle(index, ran);
2354 
2355  std::vector<T> tmp_v(N);
2356 
2357  for(size_t j=0 ; j<data.size() ; ++j){
2358  for(size_t i=0 ; i<N ; ++i){
2359  tmp_v[i] = data[j][index[i]];
2360  }
2361  swap(data[j],tmp_v);
2362  }
2363  }
2364 
2365  size_t number_of_rows(){return data[0].size();}
2366  size_t number_of_columns(){return data.size();}
2367 
2368  std::vector<std::vector<T> > data;
2369 private:
2370  std::map<std::string,int> datamap;
2371  std::vector<std::string> column_names;
2372  std::string filename;
2373 };
2374 
2375 // this is a summation algorithm that maintains percision for large sequences of numbers
2376 template <typename T>
2377 double KleinSum(std::vector<T> &input){
2378  double s = 0.0,cs = 0.0,ccs = 0.0,c,cc;
2379  size_t n = input.size();
2380  for(size_t i = 0 ; i<n ; ++i){
2381  double t = s + input[i];
2382  if( abs(s) >= abs(input[i]) ){
2383  c = (s - t) + input[i];
2384  }else{
2385  c = (input[i] - t) + s;
2386  }
2387  s = t;
2388  t = cs + c;
2389  if( abs(cs) >= abs(c) ){
2390  cc = (cs - t) + c;
2391  }else{
2392  cc = (c - t) + cs;
2393  }
2394  cs = t;
2395  ccs = ccs + cc;
2396  }
2397  return s + cs + ccs;
2398 }
2399 
2400 
2401 template <typename T,typename F>
2402 double PairWiseSum(T *begin,T *end,F value){
2403  double sum = 0;
2404  size_t n = end - begin;
2405  if(n <= 10){
2406  for(T* p=begin ; p != end ; ++p){
2407  sum += value(p);
2408  }
2409  }else{
2410  sum = PairWiseSum<T,F>(begin,begin + n/2,value) + PairWiseSum<T,F>(begin + n/2,end,value);
2411  }
2412  return sum;
2413 }
2414 
2416 template <typename T>
2417 double PairWiseSum(T *begin,T *end){
2418  double sum = 0;
2419  size_t n = end - begin;
2420  if(n <= 10){
2421  for(T* p=begin ; p != end ; ++p){
2422  sum += *p;
2423  }
2424  }else{
2425  sum = PairWiseSum(begin,begin + n/2) + PairWiseSum(begin + n/2,end);
2426  }
2427  return sum;
2428 }
2429 
2431 template <typename T>
2432 double PairWiseSum(std::vector<T> &v){
2433  return PairWiseSum(v.data(),v.data() + v.size());
2434 }
2435 
2437 template <typename T,typename F>
2438 double PairWiseSum(std::vector<T> &v,F value){
2439  return PairWiseSum(v.data(),v.data() + v.size(),value);
2440 }
2441 
2443 template <typename T>
2444 class SUMMER{
2445 
2446 public:
2447 
2448  SUMMER():batch(1000),n(0),ntotal(0),current(0.0){};
2449  SUMMER(size_t batchsize)
2450  :batch(batchsize),n(0),current(0.0),ntotal(0){};
2451 
2453  void operator+=(T x){
2454  ++n;
2455  current += x;
2456  ++ntotal;
2457  if(n % batch == 0){
2458  v.push_back(current);
2459  n=0;
2460  current = 0;
2461  }
2462  }
2463 
2466  if(v.size() ==0 ) return 0;
2467  v.push_back(current);
2468  return Utilities::PairWiseSum(v);
2469  }
2470 
2472  void reset(){
2473  std::vector<T> dump;
2474  std::swap(v,dump);
2475  n = ntotal = 0;
2476  current = 0;
2477  }
2478 
2480  size_t total_number(){
2481  return ntotal;
2482  }
2483 
2484 private:
2485  size_t batch;
2486  size_t n;
2487  size_t ntotal;
2488  T current;
2489  std::vector<T> v;
2490 };
2491 
2492 /*
2493 This is 1F2(a,b,c:x)
2494 
2495  Note convergence restrictions: abs(x) < 1 and c not a negative integer or zero
2496 */
2497 template <typename T = double>
2498 double hypergeometric( T a, T b, T c, T x )
2499 {
2500 
2501  if(abs(x) > 1 ){
2502  throw std::invalid_argument("out of bounds");
2503  }
2504  const double TOLERANCE = 1.0e-10;
2505  double term = a * b * x / c;
2506  double value = 1.0 + term;
2507  int n = 1;
2508 
2509  while ( abs( term ) > TOLERANCE )
2510  {
2511  a++, b++, c++, n++;
2512  term *= a * b * x / c / n;
2513  value += term;
2514  }
2515 
2516  return value;
2517 }
2518 
2519 class LOGPARAMS{
2520 
2521 public:
2522  typedef boost::variant<int,size_t,long,float,double,std::string,bool> MULTITYPE;
2523  typedef std::map<std::string,MULTITYPE> LINE;
2524  typedef std::map<std::string,std::vector<double> > VLINE;
2525  typedef std::map<std::string,std::vector<bool> > BLINE;
2526 
2527 private:
2528  time_t to;
2529 
2530  LINE lines;
2531  VLINE vlines;
2532  BLINE blines;
2533  std::map<std::string,std::string> input_lines;
2534  std::string filename;
2535  std::string blanck_val;
2536 public:
2537 
2538  LOGPARAMS(std::string file,std::string blanck_value = "0"):filename(file),blanck_val(blanck_value){
2539  time(&to);
2540  };
2541 
2542  ~LOGPARAMS(){
2543  print_file(filename);
2544  }
2545 
2546  void operator()(std::string label,MULTITYPE v){lines[label] = v;}
2547  void operator()(std::string label,const std::vector<double> &v){vlines[label] = v;}
2548  void operator()(std::string label,const std::vector<bool> &v){blines[label] = v;}
2549  void operator()(std::string label){lines[label] = "-----";}
2550 
2551 
2552  MULTITYPE operator[](std::string label){return lines[label];}
2553  void setlogfile(std::string name){filename = name;}
2554 
2560  void setinput(const std::string &input_filename){
2561  std::ifstream input_file(input_filename);
2562  if(!input_file){
2563  throw std::runtime_error("Unable to open parameter file: " + input_filename);
2564  }
2565 
2566  input_lines.clear();
2567  std::string line;
2568  const std::string whitespace = " \t\r\n";
2569  while(std::getline(input_file,line)){
2570  const std::string::size_type value_end = line.find_last_not_of(whitespace);
2571  if(value_end == std::string::npos) continue;
2572 
2573  const std::string::size_type value_begin = line.find_last_of(whitespace,value_end);
2574  if(value_begin == std::string::npos) continue;
2575 
2576  const std::string::size_type label_end = line.find_last_not_of(whitespace,value_begin);
2577  if(label_end == std::string::npos) continue;
2578 
2579  const std::string label = line.substr(0,label_end+1);
2580  const std::string value = line.substr(value_begin+1,value_end-value_begin);
2581  input_lines[label] = value;
2582  }
2583  }
2584 
2586  bool get(const std::string &label) {
2587  const std::map<std::string,std::string>::const_iterator entry = input_lines.find(label);
2588  if(entry == input_lines.end()) return false;
2589 
2590  // The text log does not retain the original variant type, so preserve the
2591  // value exactly as it appeared in the input file.
2592  lines[label] = entry->second;
2593  return true;
2594  }
2595 
2600  template<typename T>
2601  bool get(const std::string &label,T &value) {
2602  const std::map<std::string,std::string>::const_iterator entry = input_lines.find(label);
2603  if(entry == input_lines.end()){
2604  lines[label] = value;
2605  return false;
2606  }
2607 
2608  std::istringstream stream(entry->second);
2609  T parsed;
2610  stream >> parsed;
2611  if(stream.fail()){
2612  throw std::runtime_error("Invalid value for input parameter '" + label + "'");
2613  }
2614  value = parsed;
2615  lines[label] = value;
2616  return true;
2617  }
2618 
2619  void print(){
2620  for(auto a : lines){
2621  std::cout << std::left << std::setw(25) << a.first << " " << a.second << std::endl;
2622  }
2623  for(auto a : vlines){
2624  std::cout << std::left << std::setw(25) << a.first << " : ";
2625  for(double x : a.second ) std::cout << x << " ";
2626  std::cout << std::endl;
2627  }
2628  for(auto a : blines){
2629  std::cout << std::left << a.first << " : ";
2630  for(double x : a.second ) std::cout << x << " ";
2631  std::cout << std::endl;
2632  }
2633  time_t now = time(0);
2634  std::cout << "log has existed for " << difftime(now,to)/60 << " min" << std::endl;
2635  }
2636 
2637  void print_to_file(){
2638  print_file(filename);
2639  }
2640 
2641  void print_file(std::string filename){
2642  //printrow(std::cout, it->first, it->second, comment->second);
2643 
2644  std::ofstream logfile(filename);
2645  time_t now = time(0);
2646  struct tm date = *localtime(&now);
2647  logfile << date.tm_hour << ":" << date.tm_min << " " << date.tm_mday << "/" << date.tm_mon << "/" << date.tm_year + 1900 << std::endl;
2648  logfile << "log has existed for " << difftime(now,to)/60 << " min" << std::endl;
2649  for(auto a : lines){
2650  logfile << std::left << std::setw(23) << a.first << " " << a.second << std::endl;
2651  }
2652  for(auto a : vlines){
2653  logfile << std::left << std::setw(23) << a.first << " : ";
2654  for(double x : a.second ) logfile << x << " ";
2655  logfile << std::endl;
2656  }
2657  for(auto a : blines){
2658  logfile << std::left << a.first << " : ";
2659  for(double x : a.second ) logfile << x << " ";
2660  logfile << std::endl;
2661  }
2662  }
2663 
2664 };
2665 
2666 
2667 class LOGDATA{
2668 
2669 public:
2670  typedef boost::variant<int,long,size_t,float,double,std::string,bool> MULTITYPE;
2671  typedef std::map<std::string,MULTITYPE> LINE;
2672 
2673 private:
2674  std::vector<LINE> lines;
2675  std::string filename;
2676  std::string blank_val;
2677  std::vector<std::string> header;
2678  long nbatch;
2679  int precision;
2680  long last_line_printed;
2681  long nlabels;
2682  std::set<std::string> labels;
2683 
2684  std::map<std::string,std::string> label_comments;
2685 
2686  long nprints;
2687 
2688  void append_file(){
2689 
2690  const long default_precision = std::cout.precision();
2691  std::ofstream logfile;
2692  logfile.open(filename,std::ios_base::app);
2693 
2694  size_t n=labels.size();
2695  if(n == nlabels && last_line_printed > 0){
2696  std::cout << std::setprecision(precision);
2697  for(size_t j=last_line_printed ; j<lines.size() ; ++j ){
2698  int i=0;
2699  for(auto &label : labels){
2700  try{
2701  if(label == "ID" || label == "id"
2702  || label == "galaxy_halo_id" ){
2703  logfile << std::setprecision(17) << lines[j].at(label);
2704  std::cout << std::setprecision(precision);
2705  }else if(label == "RA" || label == "DEC" ){
2706  logfile << std::setprecision(8) << lines[j].at(label) ;
2707  std::cout << std::setprecision(precision);
2708  }else{
2709  logfile << std::setprecision(precision) << lines[j].at(label) ;
2710  }
2711  if(i<n-1) logfile << ",";
2712  }catch(std::exception& e){
2713  logfile << std::setprecision(precision) << blank_val ;
2714  if(i<n-1) logfile << ",";
2715  }
2716  ++i;
2717  }
2718  logfile << std::endl;
2719  }
2720  std::cout << std::setprecision(default_precision);
2721 
2722  last_line_printed = lines.size();
2723  }else{
2724  // number of labels has changed print from the beginning
2725  print_to_file();
2726  }
2727  }
2728 
2729 public:
2730 
2731  LOGDATA(std::string file
2732  ,std::string blanck_value = "0"
2733  ,long Nbatch=1000
2734  ):filename(file),blank_val(blanck_value)
2735  ,nbatch(Nbatch),precision(std::cout.precision())
2736  ,last_line_printed(0),nlabels(0),nprints(0){
2737  print_to_file();
2738  };
2739 
2740  ~LOGDATA(){print_to_file();}
2741 
2742  std::string output_file(){return filename;}
2743 
2744  void set_precision(int p){
2745  precision = p;
2746  }
2747 
2748  // current number of columns
2749  size_t ncol(){return labels.size();}
2750  // names of columns
2751  std::set<std::string> names = labels;
2752 
2753  void print_to_file(){
2754 
2755  const int default_precision = std::cout.precision();
2756  //std::cout << std::setprecision(12);
2757 
2758  if(lines.size() == 0 ) return;
2759 
2760  std::ofstream logfile(filename);
2761 
2762  time_t now = time(0);
2763  struct tm date = *localtime(&now);
2764  logfile << "# " << date.tm_hour << ":" << date.tm_min << " " << date.tm_mday << "/" << date.tm_mon << "/" << date.tm_year + 1900 << std::endl;
2765  for(std::string &s : header){
2766  logfile << "# " << s << std::endl;
2767  }
2768 
2769  // print comments on labels
2770  {
2771  int i=1;
2772  for(auto &label : labels){
2773  auto it = label_comments.find(label);
2774  if(it == label_comments.end() ){
2775  logfile << "# " << i << " " << label << " : no comment" << std::endl;
2776  }else{
2777  logfile << "# " << i << " " << it->first << " : " << it->second << std::endl;
2778  }
2779  ++i;
2780  }
2781  }
2782  size_t i=0;
2783  nlabels = labels.size();
2784  for(auto &label : labels){
2785  logfile << label;
2786  if(i<nlabels-1) logfile << ",";
2787  ++i;
2788  }
2789  logfile << std::endl;
2790 
2791  std::cout << std::setprecision(precision);
2792  for(LINE &line : lines){
2793  i=0;
2794  for(auto &label : labels){
2795  try{
2796  if(label == "ID"){
2797  logfile << std::setprecision(17) << line.at(label) ;
2798  std::cout << std::setprecision(precision);
2799  }else if(label == "RA" || label == "DEC" ){
2800  logfile << std::setprecision(8) << line.at(label) ;
2801  std::cout << std::setprecision(precision);
2802  }else{
2803  logfile << std::setprecision(precision) << line.at(label);
2804  }
2805  if(i<nlabels-1) logfile << ",";
2806  }catch(std::exception& e){
2807  logfile << std::setprecision(precision) << blank_val;
2808  if(i<nlabels-1) logfile << ",";
2809  }
2810  ++i;
2811  }
2812  logfile << std::endl;
2813  }
2814  std::cout << std::setprecision(default_precision);
2815 
2816  last_line_printed = lines.size();
2817  ++nprints;
2818  }
2819 
2821  void add(const LINE &line){
2822  for (auto itr = line.begin(); itr != line.end(); ++itr) labels.insert(itr->first);
2823  lines.push_back(line);
2824  if(lines.size() % nbatch == 0) append_file();
2825  }
2826 
2828  void replace(const LINE &line){
2829  for (auto itr = line.begin(); itr != line.end(); ++itr) labels.insert(itr->first);
2830  lines.back() = line;
2831  }
2832 
2834  void header_comment(const std::string &s){
2835  header.push_back(s);
2836  }
2837 
2839  void label_description(const std::string &name
2840  ,const std::string &description
2841  ){
2842  label_comments[name] = description;
2843  }
2844 };
2845 
2846 // /// alternative to std::thread that counts threads
2847 // template<class Function, class ... Args >
2848 // class MyThread
2849 // {
2850 // private:
2851 // std::thread thread_;
2852 //
2853 // static long count;
2854 // static long unjoined;
2855 //
2856 // public:
2857 // MyThread(Function&& f,Args&&... args)
2858 // {
2859 // if(count > 20) throw std::runtime_error("too many threads");
2860 // thread_ = std::thread(std::forward<Function>(f),std::forward<Args>(args)...);
2861 // ++count;
2862 // ++unjoined;
2863 // }
2864 //
2865 // ~MyThread(){
2866 // --count;
2867 // }
2868 //
2869 // void join(){
2870 // thread_.join();
2871 // --unjoined;
2872 // }
2873 //
2874 //
2875 // };
2876 
2877 
2883 template <typename T>
2884 std::valarray<T> AdaptiveSmooth(const std::valarray<T> &map_in,size_t Nx,size_t Ny,T value){
2885 
2886  std::valarray<T> map_out(map_in.size());
2887  long r,area;
2888  T val;
2889  for(long i=0;i<Nx;++i){
2890  for(long j=0;j<Ny;++j){
2891  r = 0;
2892  val = map_in[i+j*Nx];
2893  while(val < value && r < std::min(Nx, Ny) ){
2894 
2895  area = 0;
2896  val = 0;
2897  long imin,imax,jmin,jmax;
2898 
2899  imin = (i-r < 0) ? 0 : i-r;
2900  imax = (i+r > Nx-1) ? Nx-1 : i+r;
2901 
2902  jmin = (j-r < 0) ? 0 : j-r;
2903  jmax = (j+r > Ny-1) ? Ny-1 : j+r;
2904 
2905 
2906  for(long ii=imin;ii<=imax;++ii){
2907  for(long jj=jmin;jj<=jmax;++jj){
2908  if( (ii-i)*(ii-i) + (jj-j)*(jj-j) < r){
2909  val += map_in[ii+jj*Nx];
2910  ++area;
2911  }
2912  }
2913  }
2914  ++r;
2915  }
2916 
2917  map_out[i+j*Nx] = val/area;
2918  }
2919  }
2920 
2921  return map_out;
2922  }
2923 } // Utilities
2924 
2925 //#endif
2926 
2927 
2928 #endif
Utilities::MixedVector::at
BaseT & at(std::size_t i)
indexed access with bounds checking
Definition: utilities_slsim.h:523
Utilities::MixedVector::empty
bool empty() const
check if vector of items of type SubclassT is empty
Definition: utilities_slsim.h:581
Utilities::splitstring
void splitstring(std::string &line, std::vector< std::string > &vec, const std::string &delimiter)
split string into vector of seporate strings that were seporated by
Definition: utilities.cpp:828
Utilities::MixedVector< BaseT * >::MixedVector
MixedVector(const MixedVector< BaseT * > &other)
copy constructor
Definition: utilities_slsim.h:701
Utilities::to_numeric
T to_numeric(const std::string &str)
convert a string to a numerical value of various types
Definition: utilities_slsim.h:36
Utilities::ShuffledIndex
Gives a randomized sequence of numbers from 0 to N-1.
Definition: utilities_slsim.h:1275
Utilities::MixedVector::size
std::size_t size() const
number of elements of a specific type
Definition: utilities_slsim.h:565
Utilities::MixedVector< BaseT * >::pop_back
void pop_back()
erase the last element of a specific type
Definition: utilities_slsim.h:771
Utilities::MixedVector< BaseT * >::pop_back
void pop_back()
pop element from back of vector
Definition: utilities_slsim.h:755
Utilities::MixedVector::empty
bool empty() const
check if vector of items is empty
Definition: utilities_slsim.h:574
Utilities::MixedVector< BaseT * >::at
const BaseT * at(std::size_t i) const
indexed access with bounds checking (const)
Definition: utilities_slsim.h:875
Utilities::D2Matrix
2 dimensional matrix
Definition: utilities_slsim.h:166
Utilities::MixedVector< BaseT * >::operator[]
BaseT * operator[](std::size_t i) const
Indexing operator for all elements in form of a reference to the base class.
Definition: utilities_slsim.h:831
Utilities::RandomNumbers_NR::operator()
PosType operator()(void)
return a uniform random number between 0 and 1
Definition: utilities.cpp:429
Utilities::MixedVector< BaseT * >::push_back
void push_back(BaseT *obj)
add an object of type SubclassT to the vector, this does not copy the object but will delete is when ...
Definition: utilities_slsim.h:742
Utilities::MixedVector< BaseT * >::type
bool type(std::size_t i)
Checks if element i is of the derived type SubclassT.
Definition: utilities_slsim.h:825
Utilities::MixedVector< BaseT * >::begin
iterator begin()
get iterator to first of all items
Definition: utilities_slsim.h:937
Utilities::ShuffledIndex::operator*
size_t operator*()
return the index number
Definition: utilities_slsim.h:1287
Utilities::MixedVector< BaseT * >::data
const BaseT ** data() const
direct access to underlying array (const)
Definition: utilities_slsim.h:818
Utilities::D3Matrix
3 dimensional matrix, fixed size
Definition: utilities_slsim.h:127
Utilities::MixedVector::at
const SubclassT & at(std::size_t i) const
Templated indexing operator for elements of a specific derived class (const).
Definition: utilities_slsim.h:549
Utilities::MixedVector::pop_back
void pop_back()
pop element from back of vector
Definition: utilities_slsim.h:388
Utilities::MixedVector< BaseT * >::get
BaseT * get(std::size_t i)
indexed access
Definition: utilities_slsim.h:837
Utilities::DataFrame::pop
void pop(std::string colname)
remove a column
Definition: utilities_slsim.h:2275
Utilities::MixedVector::clear
void clear()
clear all elements of a given type
Definition: utilities_slsim.h:439
Utilities::MixedVector::operator[]
BaseT & operator[](std::size_t i)
Indexing operator for all elements.
Definition: utilities_slsim.h:479
Utilities::SUMMER::operator*
T operator*()
returns the current total
Definition: utilities_slsim.h:2465
Utilities::DataFrame::DataFrame
DataFrame(std::string datafile, size_t MaxNumber=1000000, char comment_char='#', char deliniator=',', std::string replace="\\N", std::function< bool(std::vector< T > &)> accept=[](std::vector< T > &v){return true;})
Definition: utilities_slsim.h:2250
Utilities::DataFrame::operator[]
std::vector< T > & operator[](int i)
returns column by number
Definition: utilities_slsim.h:2319
Utilities::MixedVector::get
const BaseT & get(std::size_t i) const
indexed access (const)
Definition: utilities_slsim.h:497
Utilities::IO::ReadCSVnumerical1
int ReadCSVnumerical1(std::string filename, std::vector< std::vector< T > > &data, std::vector< std::string > &column_names, size_t MaxNumber=100000000, char comment_char='#', char deliniator=',', std::string replace="\\N", std::function< bool(std::vector< T > &)> accept=[](std::vector< T > &v){return true;})
Read numerical data from a csv file with a header.
Definition: utilities_slsim.h:1779
Utilities::MixedVector::operator=
MixedVector< BaseT > & operator=(MixedVector< BaseT > rhs)
assign one MixedVector to another
Definition: utilities_slsim.h:362
Utilities::MixedVector::begin
iterator begin()
get iterator to first of all items
Definition: utilities_slsim.h:591
Utilities::MixedVector< BaseT * >::at
const SubclassT * at(std::size_t i) const
Templated indexing operator for elements of a specific derived class (const).
Definition: utilities_slsim.h:895
Utilities::RandomNumbers_NR
This is a class for generating random numbers. It simplifies and fool proofs initialization and allow...
Definition: utilities_slsim.h:1068
Utilities::MixedVector< BaseT * >::back
const BaseT & back() const
back of list
Definition: utilities_slsim.h:736
Utilities::ShuffledIndex::operator++
size_t operator++()
goto the next number
Definition: utilities_slsim.h:1299
Utilities::MixedVector< BaseT * >::MixedVector
MixedVector()
default constructor
Definition: utilities_slsim.h:696
Utilities::MixedVector< BaseT * >::back
BaseT & back()
back of list
Definition: utilities_slsim.h:730
Utilities::MixedVector< BaseT * >::get
const BaseT * get(std::size_t i) const
indexed access (const)
Definition: utilities_slsim.h:843
Utilities::HilbertCurve
Class for calculating the Hilbert curve distance in two dimensions.
Definition: utilities_slsim.h:1012
Utilities::shuffle
void shuffle(std::vector< T > &vec, R &ran)
Shuffles a vector into a random order.
Definition: utilities_slsim.h:1210
Utilities::MixedVector< BaseT * >::at
BaseT * at(std::size_t i)
indexed access with bounds checking
Definition: utilities_slsim.h:869
Utilities::DataFrame
class for impoting data from a csv file and allowing label string lookup like a data frame.
Definition: utilities_slsim.h:2248
Utilities::DataFrame::labels
std::vector< std::string > labels() const
returns labels of the columns from the data file
Definition: utilities_slsim.h:2327
Utilities::MixedVector< BaseT * >::size
std::size_t size() const
number of all elements
Definition: utilities_slsim.h:904
Utilities::SymmetricMatrix::oned_index
size_t oned_index(int i, int j)
convertion from 2d to 1d index
Definition: utilities_slsim.h:232
Utilities::MixedVector< BaseT * >
A MixedVector for pointers.
Definition: utilities_slsim.h:642
Utilities::sort_indexes_decending
void sort_indexes_decending(const std::vector< T > &v, std::vector< size_t > &index)
Find the indexes that sort a vector in descending order.
Definition: utilities_slsim.h:1256
Utilities::IO::read3columnfile
void read3columnfile(std::string filename, std::vector< T1 > &x, std::vector< T2 > &y, std::vector< T3 > &z, std::string delineator=" ", bool verbose=false)
Read in data from an ASCII file with three columns.
Definition: utilities_slsim.h:1575
Utilities::IO::read2columnfile
void read2columnfile(std::string filename, std::vector< T1 > &x, std::vector< T2 > &y, std::string delineator=" ", int skiplines=0, bool verbose=false)
Read in data from an ASCII file with two columns.
Definition: utilities_slsim.h:1491
Utilities::MixedVector< BaseT * >::end
iterator< SubclassT > end()
get iterator to last of items of type SubclassT
Definition: utilities_slsim.h:960
Utilities::MixedVector::data
const BaseT * data() const
direct access to underlying array (const)
Definition: utilities_slsim.h:466
Utilities::MixedVector< BaseT * >::clear
void clear()
clear all elements
Definition: utilities_slsim.h:795
Utilities::powerspectrum2d
void powerspectrum2d(std::valarray< double > const &aa, std::valarray< double > const &bb, long nx, long ny, double boxlx, double boxly, std::vector< double > &ll, std::vector< double > &Pl, double zeropaddingfactor)
Calculates power spectrum from a 2d map or the cross-power spectrum between two 2d maps.
Definition: utilities.cpp:839
Utilities::PairWiseSum
double PairWiseSum(std::vector< T > &v, F value)
This version allows you to specify a function( value(T * p) ), that returns the value of a pointer to...
Definition: utilities_slsim.h:2438
Utilities::MixedVector
A container that can hold mixed objects all derived from a base class and retains the ability to acce...
Definition: utilities_slsim.h:281
Utilities::MixedVector::end
iterator end()
get iterator to last of all items
Definition: utilities_slsim.h:597
Utilities::MixedVector::at
SubclassT & at(std::size_t i)
Templated indexing operator for elements of a specific derived class. The index runs 0 ....
Definition: utilities_slsim.h:539
Utilities::MixedVector::~MixedVector
~MixedVector()
destroy the vector and all contained items
Definition: utilities_slsim.h:347
Utilities::MixedVector< BaseT * >::end
iterator end()
get iterator to last of all items
Definition: utilities_slsim.h:943
standard.h
Utilities::MixedVector< BaseT * >::size
std::size_t size() const
number of elements of a specific type
Definition: utilities_slsim.h:911
Utilities::MixedVector::size
std::size_t size() const
number of all elements
Definition: utilities_slsim.h:558
Utilities::MixedVector< BaseT * >::get
SubclassT * get(std::size_t i)
indexed access for type SubclassT
Definition: utilities_slsim.h:850
Utilities::MixedVector::get
BaseT & get(std::size_t i)
indexed access
Definition: utilities_slsim.h:491
Utilities::HilbertCurve::d2xy
void d2xy(int d, int *x, int *y)
convert d to (x,y)
Definition: utilities.cpp:303
Utilities::MixedVector< BaseT * >::empty
bool empty() const
check if vector of items is empty
Definition: utilities_slsim.h:920
Utilities::MixedVector::swap
friend void swap(MixedVector< BaseT > &a, MixedVector< BaseT > &b)
swap two MixedVectors
Definition: utilities_slsim.h:353
Utilities::IO::ReadCSVrange
size_t ReadCSVrange(std::string filename, std::vector< std::vector< T > > &ranges, std::vector< std::string > &column_names, size_t MaxNumber=100000000, char comment_char='#', char deliniator=',', std::string replace="\\N", std::function< bool(std::vector< T > &)> accept=[](std::vector< T > &v){return true;})
Definition: utilities_slsim.h:1893
Utilities::sort_indexes
void sort_indexes(const std::vector< T > &v, std::vector< size_t > &index)
Find the indexes that sort a vector in asending order.
Definition: utilities_slsim.h:1227
Utilities::MixedVector::type
bool type(std::size_t i)
Checks if element i is of the derived type SubclassT.
Definition: utilities_slsim.h:473
Utilities::RandomNumbers_NR::gauss
PosType gauss()
generates a Gaussian distributed number with unit variance by polar Box-Muller transform
Definition: utilities_slsim.h:1077
Utilities::MixedVector::begin
iterator< SubclassT > begin()
get iterator to first of items of type SubclassT
Definition: utilities_slsim.h:604
Utilities::ShuffledIndex::operator++
size_t operator++(int)
goto the next number
Definition: utilities_slsim.h:1289
Utilities::IO::make_directories
bool make_directories(const std::string &root_dir)
make a directory if it doesn't exist
Definition: utilities.cpp:564
Utilities::MixedVector::at
const BaseT & at(std::size_t i) const
indexed access with bounds checking (const)
Definition: utilities_slsim.h:529
Utilities::IO::read1columnfile
void read1columnfile(std::string filename, std::vector< T > &x, int skiplines=0, bool verbose=false)
Definition: utilities_slsim.h:1428
Utilities::MixedVector< BaseT * >::empty
bool empty() const
check if vector of items of type SubclassT is empty
Definition: utilities_slsim.h:927
Utilities::RandomNumbers_NR::getseed
long getseed()
total number of calls
Definition: utilities_slsim.h:1133
Utilities::SUMMER::operator+=
void operator+=(T x)
add another number
Definition: utilities_slsim.h:2453
Utilities::DataFrame::add_column
void add_column(const std::string &name, const std::vector< T > &vec)
add a column to the data frame. This does a copy.
Definition: utilities_slsim.h:2308
Utilities::DataFrame::operator[]
std::vector< T > & operator[](const std::string &label)
returns column by name
Definition: utilities_slsim.h:2289
Utilities::DataFrame::input
void input(std::string datafile, size_t MaxNumber=1000000, char comment_char='#', char deliniator=',', std::string replace="\\N", std::function< bool(std::vector< T > &)> accept=[](std::vector< T > &v){return true;})
Definition: utilities_slsim.h:2262
Utilities::MixedVector::operator[]
const BaseT & operator[](std::size_t i) const
Indexing operator for all elements (const).
Definition: utilities_slsim.h:485
Utilities::IO::CountColumns
int CountColumns(std::string filename, char comment_char='#', char deliniator=' ')
Count the number of columns in a ASCII data file.
Definition: utilities.cpp:614
Utilities::SymmetricMatrix
Symetric matrix.
Definition: utilities_slsim.h:205
Utilities::IO::writeCSV
void writeCSV(const std::string filename, const std::vector< std::string > header, std::vector< T * > &data)
write a CSV data file for some data vectors
Definition: utilities_slsim.h:2118
Utilities::ShuffledIndex::reshuffle
void reshuffle(R &ran)
get a new random order
Definition: utilities_slsim.h:1309
Utilities::AdaptiveSmooth
std::valarray< T > AdaptiveSmooth(const std::valarray< T > &map_in, size_t Nx, size_t Ny, T value)
Smooth a 2 dimensional map stored in a valarray with a density dependent kernel.
Definition: utilities_slsim.h:2884
Utilities::IO::check_directory
bool check_directory(std::string dir)
returns true if director exists and false if it doesn't
Definition: utilities.cpp:556
Utilities::SUMMER::total_number
size_t total_number()
returns the number of numbers that have been added
Definition: utilities_slsim.h:2480
Utilities::IO::ReadFileNames
void ReadFileNames(std::string dir, const std::string filespec, std::vector< std::string > &filenames, bool verbose)
Reads the file names in a directory that contain a specific sub string.
Definition: utilities.cpp:574
Utilities::HilbertCurve::HilbertCurve
HilbertCurve(PosType x_min, PosType y_min, PosType my_range, PosType smallsize)
Definition: utilities_slsim.h:1014
Utilities::MixedVector::get
SubclassT & get(std::size_t i)
indexed access for type SubclassT
Definition: utilities_slsim.h:504
Utilities::MixedVector::clear
void clear()
clear all elements
Definition: utilities_slsim.h:429
Utilities::powerspectrum2dprebin
void powerspectrum2dprebin(std::valarray< double > &aa, long nx, long ny, double boxlx, double boxly, const std::vector< double > &ll, std::vector< double > &Pl, std::vector< double > &llave)
Definition: utilities.cpp:454
Utilities::IO::ReadCSVnumerical2
int ReadCSVnumerical2(std::string filename, std::vector< std::vector< T > > &data, std::vector< std::string > &column_names, size_t Nmax=1000000, char comment_char='#', char deliniator=',', bool header=true, std::string reject="")
Read numerical data from a csv file with a header.
Definition: utilities_slsim.h:2009
Utilities::MixedVector< BaseT * >::at
SubclassT * at(std::size_t i)
Templated indexing operator for elements of a specific derived class. The index runs 0 ....
Definition: utilities_slsim.h:885
Utilities::MixedVector::MixedVector
MixedVector()
default constructor
Definition: utilities_slsim.h:342
Utilities::MixedVector::copy_back
void copy_back(const SubclassT &obj)
add a copy of an object of type SubclassT to the vector, in contrast push_back() deos not copy and wi...
Definition: utilities_slsim.h:371
Utilities::MixedVector::data
BaseT * data()
direct access to underlying array
Definition: utilities_slsim.h:460
Utilities::MixedVector< BaseT * >::swap
friend void swap(MixedVector< BaseT * > &a, MixedVector< BaseT * > &b)
swap two MixedVectors
Definition: utilities_slsim.h:713
Utilities::MixedVector< BaseT * >::operator=
MixedVector< BaseT * > & operator=(MixedVector< BaseT * > rhs)
assign one MixedVector to another
Definition: utilities_slsim.h:722
Utilities::HilbertCurve::xy2d
int xy2d(int x, int y)
convert (x,y) to d
Definition: utilities.cpp:291
Utilities::MixedVector< BaseT * >::data
BaseT ** data()
direct access to underlying array
Definition: utilities_slsim.h:812
Utilities::MixedVector< BaseT * >::get
const SubclassT * get(std::size_t i) const
indexed access for type SubclassT (const)
Definition: utilities_slsim.h:860
Utilities::MixedVector::get
const SubclassT & get(std::size_t i) const
indexed access for type SubclassT (const)
Definition: utilities_slsim.h:514
Utilities::SUMMER
class for adding large amounts of numbers with less error than the simple sum
Definition: utilities_slsim.h:2444
Utilities::MixedVector::end
iterator< SubclassT > end()
get iterator to last of items of type SubclassT
Definition: utilities_slsim.h:614
Utilities::delete_container
void delete_container(Container &c)
delete the objects that are pointed to in a container of pointers
Definition: utilities_slsim.h:1002
Utilities::GetNThreads
int GetNThreads()
returns the compiler variable N_THREADS that is maximum number of threads to be used.
Definition: utilities.cpp:553
Utilities::MixedVector::pop_back
void pop_back()
erase the last element of a specific type
Definition: utilities_slsim.h:405
Utilities::MixedVector< BaseT * >::begin
iterator< SubclassT > begin()
get iterator to first of items of type SubclassT
Definition: utilities_slsim.h:950
Utilities::MixedVector< BaseT * >::~MixedVector
~MixedVector()
destroy the vector and all contained items
Definition: utilities_slsim.h:707
Utilities::IO::ReadASCII
void ReadASCII(std::vector< T > &data, std::string filename, int &columns, int &rows, char comment_char='#', int skiplines=0, size_t MaxNrows=std::numeric_limits< size_t >::max(), bool verbose=true)
This function will read in all the numbers from a multi-column ,space seporated ASCII data file.
Definition: utilities_slsim.h:1708
Utilities
Definition: utilities.h:48
Utilities::SUMMER::reset
void reset()
reset to start over, frees memory
Definition: utilities_slsim.h:2472
Utilities::MixedVector< BaseT * >::clear
void clear()
clear all elements of a given type
Definition: utilities_slsim.h:802