File: Lytle.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 (155 lines) | stat: -rw-r--r-- 4,555 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
package Demeter::Plugins::Lytle;

use Const::Fast;
const my $INIFILE => 'lytle.demeter_conf';

use Moose;
extends 'Demeter::Plugins::FileType';

has '+conffile'     => (default => File::Spec->catfile(Demeter->dot_folder, $INIFILE));

has '+is_binary'   => (default => 0);
has '+description' => (default => "the Lytle database file stored by encoder value");
has '+version'     => (default => 0.2);

use Demeter::Constants qw($R2D $HC);

use File::Basename;
use File::Copy;
use File::Spec;
use Scalar::Util qw(looks_like_number);
use List::MoreUtils qw(all);


Demeter -> co -> read_config(File::Spec->catfile(dirname($INC{'Demeter.pm'}), 'Demeter', 'Plugins', $INIFILE));

sub is {
  my ($self) = @_;
  open D, $self->file or $self->Croak("could not open " . $self->file . " as data (Lytle)\n");
  my $first = <D>;
  close D;
  return 1 if ($first =~ m{\A\s*NPTS\s+NS\s+CUEDGE\s+CUHITE});
  #return 1 if ($first =~ m{\A\s*CUEDGE\s+START\s+STOP\s+BEG\s+FSCTS});
  return 0;
};

sub fix {
  my ($self) = @_;

  my $file = $self->file;
  my $new = File::Spec->catfile($self->stash_folder, $self->filename);
  ($new = File::Spec->catfile($self->stash_folder, "toss")) if (length($new) > 127);
  open D, $file or die "could not open $file as data (fix in Lytle)\n";
  open N, ">".$new or die "could not write to $new (fix in Lytle)\n";

  my ($stpdeg, $dspacing) = (Demeter->co->default('lytle', 'stpdeg'), Demeter->co->default('lytle', 'dspace'));

  while (<D>) {
    chomp;
    next if (m{\A\s*\z});
    $_ =~ s{(E(-|\+)\d+)-}{$1 }g; # fix what appears to be a Fortran formatting overrun
    my @list = split(" ", $_);

    if ($_ =~ m{\A\s*NPTS}) {	# first two lines, snarf mono parameters
      print N "# ", $_, $/;
      my $line = <D>;
      print N "# ", $line;
      my @fields = split(" ", $line);
      ($dspacing, $stpdeg) = @fields[4,5];

    } elsif ($_ =~ m{\A\s*(?:DELTA|DELEND|SEC|OFFSETS?)}) { # various headers
      print N "# ", $_, $/;

    } elsif (all {looks_like_number($_)} @list) {
      #my $line   = <D>;
      #$line      =~ s{(E[-+]\d+)-}{$1 -}gi;
      #my @fields = split(" ", $line);
      my $steps  = shift @list;
      my $energy = $HC / (2 * $dspacing) / sin( $steps / ($R2D * $stpdeg));
      print N join(" ", sprintf("%12.5E", $energy), @list) . $/;

    } else { #($_ =~ m{\d{1,2}-\d{1,2}\-\d{1,2}\s*\z}) { # comment line with date at end
      #print "found it!\n";
      print N "# ", $_, $/;
      print N "# -----------------------", $/;
      print N "# energy  i0  it  if  ir", $/;

    };

  };

  close N;
  close D;
  $self->fixed($new);
  return $new;
};

sub suggest {
  my ($self, $which) = @_;
  $which ||= 'transmission';
  if ($which eq 'transmission') {
    return (energy      => '$1',
	    numerator   => '$2',
	    denominator => '$3',
	    ln          =>  1,);
  } else {
    return (energy      => '$1',
	    numerator   => '$4',
	    denominator => '$2',
	    ln          =>  0,);
  };
};


__PACKAGE__->meta->make_immutable;
1;

=head1 NAME

Demeter::Plugin::Lytle - Import Lytle database files stored by encoder value.

=head1 VERSION

This documentation refers to Demeter version 0.9.26.

=head1 SYNOPSIS

Import Lytle data of the sort that stores encoder value and requires a
transformation to energy.  See question 3 at
L<http://cars9.uchicago.edu/ifeffit/FAQ/Data_Handling>.

=head1 DESCRIPTION

This parses the header to obtain the monochromator d-spacing and the
steps per degree, then uses those values to convert the first column
-- which contains encoder values -- into energy values.  All headers
are simply commented and no attempt is made to write column labels,

The Lytle files that are processed by this plugin have headers that
look like this:

  NPTS  NS CUEDGE  CUHITE   DSPACE  STPDEG  STEPMM  START    STOP     SCALE
   480   4  84294. 200000. 1.92017   4000.   3150.  85290.  74500.    2.000
   DELTA:     50.      8.     16.     32.     46.
  DELEND:  84788.  83804.  81216.  76752.  71076.
     SEC:   2.000   2.000   2.000   2.000   2.000
  OFFSET: 1830. 1937.  366.  851.    4.    6.  137.    4.    6.   18.  641.    3.    2.    5.   61.   20.   93.  232.    0.    0.    0.    0.    0.    0.
 5% CU/CAB IN H2 AT 40C                                            7   9  6-10-83

=head1 BUGS AND LIMITATIONS

=over 4

=item *

Given that the Lytle database stores the files as unix compressed (.Z)
files, directly read compressed files using Archive::Zip

=back

=head1 AUTHOR

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

=cut