41 std::vector<const tools::Property*> view;
42 for (
const auto& child : regions_def) {
43 view.push_back(&child);
45 std::sort(view.begin(), view.end(),
47 return (A->get(
"id").as<Index>()) < (B->get(
"id").as<Index>());
54 std::vector<std::string> modified_options;
55 for (
auto& child : opt) {
56 if (child.as<std::string>() ==
"jobfile") {
57 if (job_opt.
exists(child.name())) {
59 modified_options.push_back(child.path() +
"." + child.name());
62 for (
const auto& job_childchild : job_opt_child) {
63 child.add(job_childchild);
66 child.value() = job_opt_child.
value();
69 throw std::runtime_error(
"Requested to replace:" + child.path() +
"." +
71 " but no option in jobfile found");
73 }
else if (job_opt.
exists(child.name())) {
74 std::vector<std::string> child_modified_options =
76 job_opt.
get(child.name()));
77 modified_options.insert(modified_options.end(),
78 child_modified_options.begin(),
79 child_modified_options.end());
82 return modified_options;
88 std::vector<const tools::Property*> regions_def_job =
89 prop.
Select(
"regions.*region");
91 for (
const auto& job_region : regions_def_job) {
93 Index job_region_id = job_region->get(
"id").as<
Index>();
96 std::find_if(regions_def.
begin(), regions_def.
end(),
98 return p.get(
"id").as<Index>() == job_region_id;
100 if (found_prop == regions_def.
end()) {
101 throw std::runtime_error(
102 "Your jobfile options want to modify a region with id " +
103 std::to_string(job_region_id) +
104 " it does not exist in your region specifications.");
108 if (region.
name() != job_region->name()) {
109 throw std::runtime_error(
"Types of region with id" +
110 std::to_string(job_region_id) +
111 " do not agree jobfile:" + job_region->name() +
112 " options:" + region.
name());
115 std::vector<std::string> changed_options =
118 if (!changed_options.empty()) {
120 <<
" is modified by jobfile" << std::flush;
122 <<
" Replacing the following paths with jobfile entries"
124 for (
const std::string& path : changed_options) {
132 const Topology& top, std::pair<std::string, tools::Property> options) {
137 std::vector<std::vector<SegId>> region_seg_ids =
143 for (
const auto& region :
regions_) {
154 Eigen::Vector3d r = mol.getPos() - center;
155 Eigen::Vector3d shift = r_pbc - r;
156 if (shift.norm() > 1
e-9) {
157 mol.Translate(shift);
162 const std::pair<std::string, tools::Property>& options,
const Topology& top,
163 const std::vector<std::vector<SegId>>& region_seg_ids) {
164 std::string mapfile = options.first;
166 Eigen::Vector3d center = top.
getSegment(region_seg_ids[0][0].Id()).
getPos();
170 const std::vector<SegId>& seg_ids = region_seg_ids[id];
171 std::string type = region_def.
name();
172 std::unique_ptr<Region> region;
177 std::unique_ptr<QMRegion> qmregion =
181 for (
const SegId& seg_index : seg_ids) {
184 mol.
setType(
"qm" + std::to_string(
id));
186 qmregion->push_back(mol);
188 region = std::move(qmregion);
189 }
else if (type == Polardummy.
identify()) {
190 std::unique_ptr<PolarRegion> polarregion =
191 std::make_unique<PolarRegion>(
id,
log_);
194 for (
const SegId& seg_index : seg_ids) {
200 mol.
setType(
"mm" + std::to_string(
id));
201 polarregion->push_back(mol);
203 region = std::move(polarregion);
204 }
else if (type == Staticdummy.
identify()) {
205 std::unique_ptr<StaticRegion> staticregion =
206 std::make_unique<StaticRegion>(
id,
log_);
209 for (
const SegId& seg_index : seg_ids) {
212 mol.
setType(
"mm" + std::to_string(
id));
214 staticregion->push_back(mol);
216 region = std::move(staticregion);
219 throw std::runtime_error(
"Region type not known!");
221 region->Initialize(region_def);
222 regions_.push_back(std::move(region));
229 writer.
Open(filename,
false);
231 for (
const std::unique_ptr<Region>& reg :
regions_) {
232 reg->WritePDB(writer);
240 std::vector<const tools::Property*> sorted_regions =
243 std::vector<Index> explicitly_named_segs_per_region;
244 std::vector<std::vector<SegId>> segids_per_region;
245 std::vector<bool> processed_segments =
246 std::vector<bool>(top.
Segments().size(),
false);
249 if (!region_def->exists(
"segments") && !region_def->exists(
"cutoff")) {
250 throw std::runtime_error(
251 "Region definition needs either segments or a cutoff to find "
254 std::vector<SegId> seg_ids;
255 if (region_def->exists(
"segments")) {
256 seg_ids = region_def->get(
"segments").as<std::vector<SegId>>();
257 for (
const SegId& seg_id : seg_ids) {
259 throw std::runtime_error(
"Segment id is not in topology");
261 processed_segments[seg_id.Id()] =
true;
264 explicitly_named_segs_per_region.push_back(
Index(seg_ids.size()));
266 if (region_def->exists(
"cutoff")) {
270 std::string seg_geometry =
271 region_def->get(
"cutoff.geometry").as<std::string>();
272 double min = top.
getBox().diagonal().minCoeff();
273 if (cutoff > 0.5 * min) {
274 throw std::runtime_error(
275 (boost::format(
"Cutoff is larger than half the box size. Maximum "
276 "allowed cutoff is %1$1.1f") %
280 std::vector<SegId> center = seg_ids;
282 Index id = region_def->get(
"cutoff.region").as<
Index>();
283 bool only_explicit = region_def->get(
"cutoff.explicit_segs").as<
bool>();
284 if (
id <
Index(segids_per_region.size())) {
285 center = segids_per_region[id];
287 Index no_of_segs = explicitly_named_segs_per_region[id];
288 if (no_of_segs == 0) {
289 throw std::runtime_error(
290 "Region with id '" + std::to_string(
id) +
291 "' does not have explicitly named segments");
293 center.resize(no_of_segs,
SegId(0,
"n"));
298 }
else if (
id != region_def->get(
"id").as<
Index>()) {
299 throw std::runtime_error(
"Region with id '" + std::to_string(
id) +
300 "' used for cutoff does not exist");
303 if (center.empty()) {
304 throw std::runtime_error(
305 "Region needs either a segment or another region to which to "
309 for (
const SegId& segid : center) {
312 if (center_seg.
getId() == otherseg.getId() ||
313 processed_segments[otherseg.getId()]) {
318 seg_ids.push_back(
SegId(otherseg.getId(), seg_geometry));
319 processed_segments[otherseg.getId()] =
true;
324 segids_per_region.push_back(seg_ids);
326 return segids_per_region;
331 std::vector<Index> reg_ids;
333 reg_ids.push_back(region_def.get(
"id").as<
Index>());
336 std::vector<Index> v(reg_ids.size());
337 std::iota(v.begin(), v.end(), 0);
338 if (!std::is_permutation(reg_ids.begin(), reg_ids.end(), v.begin())) {
339 throw std::runtime_error(
340 "Region id definitions are not clear. You must start at id 0 and "
342 "ascending order. i.e. 0 1 2 3.");
352 for (
const auto& region :
regions_) {
354 cpf.
getWriter(
"region_" + std::to_string(region->getId()));
355 region->WriteToCpt(w);
365 throw std::runtime_error(
366 "Jobid from checkpoint file does not agree with jobid" +
367 std::to_string(
id) +
":" + std::to_string(
job_.
getId()));
377 for (
Index i = 0; i < no_regions; i++) {
382 std::unique_ptr<Region> region =
nullptr;
385 }
else if (type == Polardummy.
identify()) {
386 region = std::make_unique<PolarRegion>(i,
log_);
387 }
else if (type == Staticdummy.
identify()) {
388 region = std::make_unique<StaticRegion>(i,
log_);
390 throw std::runtime_error(
"Region type:" + type +
" not known!");
392 region->ReadFromCpt(r);
393 if (
id != region->getId()) {
394 throw std::runtime_error(
"read in the wrong region, ids are mismatched.");
396 regions_.push_back(std::move(region));
void WriteHeader(std::string header)
void Open(std::string file, bool bAppend=false) override
void setType(std::string type)
const Eigen::Vector3d & getPos() const
CheckpointReader getReader()
CheckpointWriter getWriter()
Index getNumDataSets() const
std::vector< std::unique_ptr< Region > > regions_
void ShiftPBC(const Topology &top, const Eigen::Vector3d ¢er, T &mol) const
std::vector< const tools::Property * > SortRegionsDefbyId(const tools::Property ®ions_def) const
void ReadFromHdf5(std::string filename)
static constexpr int jobtopology_version()
void CreateRegions(const std::pair< std::string, tools::Property > &options, const Topology &top, const std::vector< std::vector< SegId > > ®ion_seg_ids)
std::vector< std::vector< SegId > > PartitionRegions(const tools::Property ®ions_def, const Topology &top) const
void WriteToPdb(std::string filename) const
void CheckEnumerationOfRegions(const tools::Property ®ions_def) const
void BuildRegions(const Topology &top, std::pair< std::string, tools::Property > options)
void WriteToHdf5(std::string filename) const
void ModifyOptionsByJobFile(tools::Property ®ions_def) const
tools::Property & getInput()
std::string identify() const override
std::string identify() const override
void LoadMappingFile(const std::string &mapfile)
AtomContainer map(const Segment &seg, const SegId &segid) const
std::string identify() const override
Container for segments and box and atoms.
Eigen::Vector3d PbShortestConnect(const Eigen::Vector3d &r1, const Eigen::Vector3d &r2) const
std::vector< Segment > & Segments()
const Eigen::Matrix3d & getBox() const
Segment & getSegment(Index id)
#define XTP_LOG(level, log)
std::vector< std::string > ModifyRegionOptionsFromJobFileRegion(tools::Property &opt, const tools::Property &job_opt)
base class for all analysis tools