File: Sanity.pm

package info (click to toggle)
libdemeter-perl 0.9.27%2Bds6-9
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid, trixie
  • size: 74,028 kB
  • sloc: perl: 73,233; python: 2,196; makefile: 1,999; ansic: 1,368; lisp: 454; sh: 74
file content (245 lines) | stat: -rw-r--r-- 6,671 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
package Demeter::Feff::Sanity;

=for Copyright
 .
 Copyright (c) 2006-2019 Bruce Ravel (http://bruceravel.github.io/home).
 All rights reserved.
 .
 This file is free software; you can redistribute it and/or
 modify it under the same terms as Perl itself. See The Perl
 Artistic License.
 .
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

=cut

use autodie qw(open close);

use Moose::Role;

use Carp;
use List::MoreUtils qw(any);
use Demeter::Constants qw($NUMBER);

use Text::Wrap;
$Text::Wrap::columns = 65;


#my $functions = Demeter->regexp('functions');

## verify 1. all ipots are used
##        2. no atoms have undefined ipots
##        3. there is one and only one central atom
##        4. resequence ipots if tests 1 and 2 pass,
##           but ipots are not sequential

##        5. warning about rmax outside cluster
##        6. ipot > 7

sub S_check_ipots {
  my ($self, $r_problems) = @_;
  my ($r_sites, $r_pots) = $self->get(qw(sites potentials));
  my @sites = @$r_sites;
  my @ipot_used    = (0,0,0,0,0,0,0,0); # ipots 0 .. 7
  my @ipot_defined = (0,0,0,0,0,0,0,0);
  foreach my $rs (@sites) {
    my $this_ipot = $rs -> [3];
    if ($this_ipot > 7) {
      $$r_problems{used_ipot_gt_7} = 1;
      push @{$$r_problems{errors}}, "You have defined an atom with potential index greater than 7.";
    } else {
      ++$ipot_used[$this_ipot];
    };
  };
  #my @pots = @$r_pots;
  #foreach my $rp (@pots) {
  foreach my $rp (@{$self->potentials}) {
    my $ipot = $rp->[0];
    if ($ipot > 7) {
      $$r_problems{defined_ipot_gt_7} = 1;
      push @{$$r_problems{errors}}, "You have defined a potential index greater than 7.";
    } else {
      ++$ipot_defined[$ipot];
    };
  };

  if ($ipot_used[0] == 0) {
    $$r_problems{no_absorber} = 1;
    push @{$$r_problems{errors}}, "You have not designated a central atom.  No site in the atoms list is of potential #0."
  };
  if ($ipot_used[0] > 1) {
    $$r_problems{multiple_absorbers} = 1;
    push @{$$r_problems{errors}}, "You have defined more than one central atom by using potential #0 more than once in the atoms list."
  };
  foreach my $i (0 .. $#ipot_used) {
    if ($ipot_used[$i] and not $ipot_defined[$i]) {
      $$r_problems{used_not_defined} = 1;
      push @{$$r_problems{errors}}, "You have used ipot #$i but not defined it as a potential."
    };
    if ($ipot_defined[$i] and not $ipot_used[$i]) {
      $$r_problems{defined_not_used} = 1;
      push @{$$r_problems{errors}}, "You have defined ipot #$i but not used it in the atoms list."
    };
  };

  #use Data::Dumper;
  #print Data::Dumper->Dump([\@ipot_used, \@ipot_defined],
  #		     [qw(*ipot_used *ipot_defined)]);
};

sub S_check_rmax {
  my ($self, $r_problems) = @_;
  return if ($$r_problems{no_absorber} or $$r_problems{multiple_absorbers});
  my ($r_sites, $rmax) = $self->get(qw(sites rmax));
  my @sites = @$r_sites;
  my @center;
  my $rfarthest = 0;
  foreach my $rs (@sites) {
    if ($rs->[3] == 0) {
      @center = ($rs->[0], $rs->[1], $rs->[2]);
      last;
    };
  };
  foreach my $rs (@sites) {
    my @this = @$rs[0..2];
    my $r = $self->distance(@this, @center);
    $rfarthest = $r if ($r > $rfarthest);
  };
  $self->rmax($rfarthest) if $rmax == 0;
  #print join(" ", $rmax,$rfarthest), $/;
  #if ($rmax > $rfarthest) {
  #  $$r_problems{rmax_outside_cluster} = 1;
  #  push @{$$r_problems{warnings}}, "You have specified a value of rmax that is outside the cluster."
  #};
};


sub S_check_cluster_size {
  my ($self, $r_problems) = @_;
  my $nsites = $#{ $self->sites };
  if ($nsites > 500) {
    $$r_problems{cluster_too_big} = 1;
    push @{$$r_problems{errors}}, "Your cluster size if larger than the copiled limit in Feff6L of 500 atoms."
  };
};

1;


=head1 NAME

Demeter::Feff::Sanity - Sanity checks for feff.inp files

=head1 VERSION

This documentation refers to Demeter version 0.9.26.

=head1 SYNOPSIS

    $feff -> Demeter::Feff -> new(file=>"feff.inp");

=head1 DESCRIPTION

This module contains all the sanity checks made on a F<feff.inp> file.
This file forms part of the base of the Demeter::Feff class and serves
no independent function.  That is, using this module directly in a
program does nothing useful -- it is purely a utility module for the
Feff object.

The user should never need to call the methods explicitly since they
are called automatically whenever a F<feff.inp> file is imported.
However they are documented here so that the scope of such checks made
is clearly understood.

=head1 METHODS

The following sanity checks are made on the imported F<feff.inp> file.

=over 4

=item *

Check that all potential indeces are used in the atom list.

=item *

Check that no atoms have undefined potential indeces.

=item *

Check there is one and only one central atom, i.e. an atom with
potential index 0.

=item *

Resequence the potential indeces if other tests pass but the indeces
are not sequential.

=item *

Warn about C<rmax> outside the cluster.

=item *

Warn if a potential index is greater than 7.

=back

=head1 DIAGNOSTICS

I think these are all self-explanatory.

=over 4

=item C<You have defined an atom with potential index greater than 7>

=item C<You have not designated a central atom.  No site in the atoms list is of potential #0.>

=item C<You have defined more than one central atom by using potential #0 more than once in the atoms list.>

=item C<You have used ipot #$i but not defined it as a potential.>

=item C<You have defined ipot #$i but not used it in the atoms list.>

=item C<You have specified a value of rmax that is outside the cluster.>

=back

=head1 CONFIGURATION AND ENVIRONMENT

See L<Demeter::Config> for a description of the configuration system.

=head1 DEPENDENCIES

The dependencies of the Demeter system are in the
F<Build.PL> file.

=head1 BUGS AND LIMITATIONS

There are no known bugs in this module.

Please report problems to the Ifeffit Mailing List
(L<http://cars9.uchicago.edu/mailman/listinfo/ifeffit/>)

Patches are welcome.

=head1 AUTHOR

Bruce Ravel, L<http://bruceravel.github.io/home>

L<http://bruceravel.github.io/demeter/>

=head1 LICENCE AND COPYRIGHT

Copyright (c) 2006-2019 Bruce Ravel (L<http://bruceravel.github.io/home>). All rights reserved.

This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself. See L<perlgpl>.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

=cut