forked from Cell-veto/postlhc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpaircorrel.cpp
147 lines (125 loc) · 3.99 KB
/
paircorrel.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// (c) 2015-2016 Sebastian Kapfer <[email protected]>, FAU Erlangen
// compute pair correlators.
#include "storage.hpp"
#include <fstream>
#include <iomanip>
// FIXME implement attributes
template <typename ENCODING>
struct Correlator : AbstractCorrelator
{
typedef Storage <ENCODING> stor_t;
typedef typename stor_t::key_t key_t;
static const unsigned DIM = ENCODING::DIM;
static stor_t *downcast (AbstractStorage *stor_)
{
// convert to reference to force bad_cast exceptions
return &dynamic_cast <stor_t &> (*stor_);
}
virtual void init (AbstractStorage *stor_, double bin_width, double rmax)
{
stor_t *stor = downcast (stor_);
binwid_ = bin_width;
if (rmax == 0.)
{
method_ = "full";
rmax_ = stor->periods ().min (DIM) / 2;
}
else
{
method_ = "window";
assert (rmax > 0.);
rmax_ = rmax;
}
hist_.resize (bin (rmax_) - 1., 0);
ndata_ = 0;
walltime_ = 0;
}
virtual void sample (AbstractStorage *stor_, size_t multiplier)
{
stor_t *stor = downcast (stor_);
// initialized late since stor might be empty at ctor time
rho_ = stor->particle_density ();
ndata_ += multiplier;
walltime_ -= gclock ();
for (size_t n1 = 0; n1 != multiplier; ++n1)
{
key_t k1 = stor->random_particle (&random);
if (method_ == "full")
do_sample (stor, k1, stor->enumerate_all ());
else // window
do_sample (stor, k1, stor->enumerate_box (k1, rmax_));
}
walltime_ += gclock ();
}
virtual void savetxt (std::ostream &os)
{
const double exp_sample_dens = ndata_ * rho_;
hist_[0] = 0;
double rv1 = 0., rv2;
for (unsigned i = 0; i != hist_.size (); ++i)
{
double r = (i+.5) * binwid_;
rv2 = ball_volume (DIM, (i+1) * binwid_);
double expected = exp_sample_dens * (rv2-rv1);
double gofr = hist_[i] / expected;
os << std::setprecision (3) << std::fixed
<< r << ' '
<< std::setprecision (12) << std::scientific
<< gofr << '\n';
rv1 = rv2;
}
os << "# gofr_stat " << ndata_ << " fin\n";
std::cerr << "gofr_stat " << ndata_ << " wrote histo\n";
std::cerr << "gofr_walltime " << walltime_*1e-6 << " seconds\n";
}
private:
template <typename GENERATOR>
void do_sample (stor_t *stor, key_t k1, GENERATOR g)
{
for (; g.not_done (); g.next ())
{
key_t k2 = g.key ();
double r = norm (stor->distance_vector (k1, k2));
unsigned i = bin (r);
if (i < hist_.size ())
++hist_[i];
}
}
size_t bin (double r) const
{
return std::floor (r/binwid_);
}
RandomContext random;
double binwid_, rho_;
string method_;
double rmax_;
std::vector <size_t> hist_;
size_t ndata_;
uint64_t walltime_;
};
AbstractCorrelator::~AbstractCorrelator ()
{
}
void AbstractCorrelator::savetxt (string_ref filename)
{
std::ofstream ofs (filename);
if (!ofs)
rt_error ("cannot open file: " + filename);
savetxt (ofs);
if (!ofs)
rt_error ("error writing data: " + filename);
ofs.close ();
if (!ofs)
rt_error ("error writing data (2): " + filename);
}
AbstractCorrelator *make_correlator (string_ref attribute, AbstractStorage *stor,
double bin_width, double rmax)
{
AbstractCorrelator *ret = Factory <AbstractCorrelator>::make (
attribute + "/" + stor->typecode ());
ret->init (stor, bin_width, rmax);
return ret;
}
static Register <Correlator <Monodisperse2D>> one ("density/mono2d");
static Register <Correlator <Tagged <Monodisperse2D>>> one_tagged ("density/tagged_mono2d");
static Register <Correlator <Monodisperse3D>> two ("density/mono3d");