Hey guys,
I'm a newbie here and also to Perl.I have a similar but difficult question than a previous question here.
http://www.daniweb.com/forums/thread245502.html#

I have a output file containing atoms like this:

#F A 1 1 1 3 3 2
#C number type mass x y z vx vy vz Epot eam_rho
#E
1390 0 63.546300 1.366122 3.274510 3.959495 -0.014555 0.021480 0.011286 -3.336130 0.983624
2075 0 63.546300 0.197795 4.925601 2.678359 0.015554 0.035225 0.028217 -3.354595 0.977031
3833 0 63.546300 4.796687 5.563218 3.726159 0.010010 -0.001101 0.048472 -3.379659 0.898155
232 0 63.546300 1.785678 0.692921 3.458947 -0.010475 -0.028170 -0.039203 -3.255102 0.907376
2417 0 63.546300 1.431713 3.511336 1.161916 -0.047983
....n lines

From line4, the first column is atom ID, the 4,5,6 column is atom's coordinate x,y,z.

1.I need save it in array format.
2.Then, for atom i, calculate the distance to all other atoms by d=sqrt[ (xi-xj)^2+(yi-yj)^2+(zi-zj)^2].
3.Sort these distance in ascending order.
4.Pickup the first 12 atoms closet to atom i.
5.Pick the closet distance as d1, then search other 11 atoms find one can minimize Dj=|d1+dj|^2. Let D1=Dj.
6. Throw d1 and j atom out from 12 atoms. In remaining atoms, pick up one closet to atom i, and repeat step5 until 12 atoms are empty.
7. calculate parameter c=(D1+...+D6)/(2*(d1^2+....d12^2))
8. calculate c for atom i+1
9. at last, output all atoms with c in this format in a new file:
atom id, x, y,z, c


I ready some post but still haven't any idea. Please help me....Thanks a tonne in adv....

Recommended Answers

All 2 Replies

Which part of the program do you need help with?

One way to accomplish the first three tasks:

#!/usr/bin/perl
use strict;
use warnings;
use Math::Complex;

my @atoms;
#For testing, I like to read from the __DATA__ section at the end of the program.
#If you prefer, you can do the following instead
#open FH, '<', 'somefile.txt' or die $!;
#and read from <FH> instead of <DATA>
while (<DATA>) {
	next if m/^#/; #Skip line if it is a comment
	push @atoms, [split /\s+/, $_];
}

my ($stat, $size);
$size = @atoms;
foreach (0..$size-1) {
	print "\nPrinting array of atoms by ascending order of distance from atom_id $atoms[$_]->[0]\n";
	my @arr = sort_atoms_by_distance(\@atoms, $_);
	# @arr contains a sorted list of distances of all atoms relative to one atom.
	foreach my $a (@arr) {
		print $a, "\n";
	}
}

sub sort_atoms_by_distance {
	my ($aref, $i) = @_;
	my @a = @{$aref};
	my $href = {};
	my $distance;
	foreach (0..$size-1) {
		$distance = calcdist($a[$i], $a[$_]);
		$href->{$a[$_]->[0]} = $distance;
	}
	my @sortedkeys = sort { ${$href}{$a} <=> ${$href}{$b} } keys %{$href};
	my @sorted;
	foreach my $j (@sortedkeys) {
		push @sorted, "Distance between atom_id $a[$i]->[0] and atom_id $j is ${$href}{$j}";
	}
	return @sorted;
}

sub calcdist {
	my ($ref1, $ref2) = @_;
	my ($atom_id1, $x1, $y1, $z1) = ($ref1->[0], $ref1->[3], $ref1->[4], $ref1->[5]);
	my ($atom_id2, $x2, $y2, $z2) = ($ref2->[0], $ref2->[3], $ref2->[4], $ref2->[5]);
	my $dist = sqrt(($x1 - $x2)**2 + ($y1 - $y2)**2 + ($z1 - $z2)**2);
	return $dist;
}

__DATA__
#F A 1 1 1 3 3 2
#C number type mass x y z vx vy vz Epot eam_rho
#E
1390 0 63.546300 1.366122 3.274510 3.959495 -0.014555 0.021480 0.011286 -3.336130 0.983624
2075 0 63.546300 0.197795 4.925601 2.678359 0.015554 0.035225 0.028217 -3.354595 0.977031
3833 0 63.546300 4.796687 5.563218 3.726159 0.010010 -0.001101 0.048472 -3.379659 0.898155
232 0 63.546300 1.785678 0.692921 3.458947 -0.010475 -0.028170 -0.039203 -3.255102 0.907376
2417 0 63.546300 1.431713 3.511336 1.161916 -0.047983

This gives the following output:

Printing array of atoms by ascending order of distance from atom_id 1390
Distance between atom_id 1390 and atom_id 1390 is 0
Distance between atom_id 1390 and atom_id 2075 is 2.39424286982461
Distance between atom_id 1390 and atom_id 232 is 2.66292645455352
Distance between atom_id 1390 and atom_id 2417 is 2.80835129476317
Distance between atom_id 1390 and atom_id 3833 is 4.13054551087202

Printing array of atoms by ascending order of distance from atom_id 2075
Distance between atom_id 2075 and atom_id 2075 is 0
Distance between atom_id 2075 and atom_id 1390 is 2.39424286982461
Distance between atom_id 2075 and atom_id 2417 is 2.41294394738005
Distance between atom_id 2075 and atom_id 232 is 4.58762139129124
Distance between atom_id 2075 and atom_id 3833 is 4.75964787629852

Printing array of atoms by ascending order of distance from atom_id 3833
Distance between atom_id 3833 and atom_id 3833 is 0
Distance between atom_id 3833 and atom_id 1390 is 4.13054551087202
Distance between atom_id 3833 and atom_id 2417 is 4.70197957520543
Distance between atom_id 3833 and atom_id 2075 is 4.75964787629852
Distance between atom_id 3833 and atom_id 232 is 5.73213488320312

Printing array of atoms by ascending order of distance from atom_id 232
Distance between atom_id 232 and atom_id 232 is 0
Distance between atom_id 232 and atom_id 1390 is 2.66292645455352
Distance between atom_id 232 and atom_id 2417 is 3.65309536535949
Distance between atom_id 232 and atom_id 2075 is 4.58762139129124
Distance between atom_id 232 and atom_id 3833 is 5.73213488320312

Printing array of atoms by ascending order of distance from atom_id 2417
Distance between atom_id 2417 and atom_id 2417 is 0
Distance between atom_id 2417 and atom_id 2075 is 2.41294394738005
Distance between atom_id 2417 and atom_id 1390 is 2.80835129476317
Distance between atom_id 2417 and atom_id 232 is 3.65309536535949
Distance between atom_id 2417 and atom_id 3833 is 4.70197957520543
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.