Using MDAnalysis to extract coordinates in an array from pdb - pdb

I have a pdb file that is a subset of a much larger system. This pdb is special because I have some vectors based on this file's coordinate system. I want to draw these vectors and the basis vector of that system onto the pdb. Eventually I would like to visualize the vector and basis vectors as it moves through some MD simulation where I an update the vector position based on the trajectory over time.
To start, I would like to read a pdb that has coordinates that define the basis vectors that further define the other vectors I want to visualize. Right now I'm using this class in MDAnalysis:
https://docs.mdanalysis.org/1.0.0/_modules/MDAnalysis/coordinates/PDB.html#PDBReader
molecule=mda.coordinates.PDB.PDBReader('molecule.pdb')
This works and it reads the pdb just fine, but returns with this variable type
coordinates.PDB.Reader
I suppose this isn't a surprise, but I want to be able to print this variable and get some array of coordinate positions and atom types. I'd love to see the bonds as well but that's not necessary. Now when I print I get
<PDBReader molecule.pdb with 1 frames of 60 atoms>
I want something that would look like
[atomtype1,x1,y1,z1]...[atomtypen,xn,yn,zn]
Thank you,

Loading data: Universe
To get the coordinates in MDAnalysis you first load a Universe (you don't normally use the coordinate readers directly):
import MDAnalysis as mda
u = mda.Universe('molecule.pdb')
The Universe contains "topology" (atom types, bonds if available, etc) and the "trajectory" (i.e., coordinates).
Accessing per-atom data: Universe.atoms
All the atoms are stored in u.atoms (they form an AtomGroup). All information about the atoms is available from an AtomGroup. For example, all positions are available as a numpy array with
u.atoms.positions
The names are
u.atoms.names
and there are many more attributes. (The same works for residues: u.residues or u.atoms.residues gives the residues. You can also slice/index an AtomGroup to get a new AtomGroup. For example, the residues that belong to the first 20 atoms are u.atoms[:20].residues... AtomGroups are the key to working with MDAnalysis.)
Extracting atom names and positions
To build the list that you asked for:
names_positions = [[at] + list(pos) for at, pos in zip(u.atoms.names, u.atoms.positions)]
For example, with the test file PDB that is included with the MDAnalysisTests package:
import MDAnalysis as mda
from MDAnalysisTests.datafiles import PDB
u = mda.Universe(PDB)
names_positions = [[at] + list(pos) for at, pos in zip(u.atoms.names, u.atoms.positions)]
# show the first three entries
print(names_positions[:3])
gives
[['N', 52.017, 43.56, 31.555], ['H1', 51.188, 44.112, 31.722], ['H2', 51.551, 42.828, 31.039]]
Learning more...
For a rapid introduction to MDAnalysis have a look at the Quickstart Guide, which explains most of these things in more detail. It also tells you how to select specific atoms and form new AtomGroups.
Then you can have a look at the rest of the User Guide.
Bonds are a bit more tricky (you can get them with u.atoms.bonds but if you want to use them you have to learn more about how MDAnalysis represents topologies — I'd suggest you start by asking on user mailing list, see participating in MDAnalysis because this is where MDAnalysis developers primarily answer questions.)

Related

How to access net displacements in pyiron

Using pyiron, I want to calculate the mean square displacement of the ions in my system. How do I see the total displacement (i.e. not folded back by periodic boundary conditions) without dumping very frequently and checking when an atom passes over the boundary and gets wrapped?
Try to compare job['output/generic/unwrapped_positions'][-1] and job.structure.positions+job.output.total_displacements[-1]. If they deliver the same values, it's definitely fine both ways. If not, you can post the relevant lines in your notebook here.
I'd like to add a few comments to Jan's answer:
While job['output/generic/unwrapped_positions'] returns the unwrapped positions parsed from the output files, job.output.total_displacements returns the displacement of atoms calculated from each pair of consecutive snapshots. So if an atom moves more than half the box length in any direction, job.output.total_displacements will give wrong coordinates. Therefore, job['output/generic/unwrapped_positions'] is generally more trustworthy, but it is not available in all the codes (since some codes simply do not provide an output for unwrapped positions).
Moreover, if an interactive job is used, it is possible that job.structure.positions does not return the initial positions, i.e. job.structure.positions+job.output.total_displacements won't be initial positions + displacements.
So, in short, my answer to your question would be rather "Use job['output/generic/unwrapped_positions'] and if it's not available, use job.structure.positions+job.output.total_displacements but be aware of potential problems you might be running into."

Using collections to create random buildings with Blender

I had the idea of creating a fantasy city, and to avoid having the same house over and over, but not have to manually create hundreds of houses I was thinking on creating collections like "windows", "doors", "roofs", etc, and then create objects with vertex's assigned to specific groups with the same names ("windows" vertex groups, "doors" vertex groups, etc), and then have blender pick for each instance of a house a random window for each of the vertex in the group, same for doors, roofs, etc.
Is there a way of doing this? (couldn't find anything online), or do I need to create a custom addon? If so, any good reference or starting point where something close to this is done?
I've thought of particle systems, or child objects, but couldn't find a way to attach to the vertex a random part of the collection. Also thought of booleans, but it doesn't have an option to attach to specific vertex, nor to use collections. So I'm out of ideas of how to approach this.
What I have in mind:
Create basic shape, and assign vertex to the "windows" vertex group:
https://i.imgur.com/DAkgDR3.png
And then have random objects within the "Windows" collection attached to those vertex, as either a particle or modifier:
https://i.imgur.com/rl5BDQL.png
Thanks for any help :)
Ok, I've found a way of doing this.
I'm using 3 particle systems (doors, roofs and windows), each using vertex as emitters, and using vector groups to define where to display one of each the different options.
To avoid the particle emitter to put more than one object per vertex, I created a small script that counts the number of vertex of each vertex group and updates each of the particle system Emission number accordingly.
import bpy
o = bpy.data.objects["buildings"]
groups = ["windows", "doors", "roofs"]
for group in groups:
vid = o.vertex_groups.find(group)
vectors = [ v for v in o.data.vertices if vid in [ vg.group for vg in v.groups ] ]
bpy.data.particles[group].count = len(vectors)
I've used someone's code from stack overflow for counting the number of vectors in a vector group, but can't find again the link to the specific question, so if you see your code here, please do comment and I'll update my answer with the proper credit.

GIS data files converting each address to lat/lon in dbf shape data

I need Lat/LON from GIS data
I have data files from
http://www.mngeo.state.mn.us/chouse/land_own_property.html
given in the format of
.dbf, .prj, .sbn, .sbx, .shp, and .shx
in the .dbf I see
PIN, Shape_area, Shape_len
PARC_CODE Parcel Polygon to Parcel Point numeric 2
and PIN Relationship Code
and in the .prj
PROJCS["NAD_1983_UTM_Zone_15N",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-93.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
I also know the polygon points for each county
polygons points
Anoka 129139 129138
Carver 38134 38133
Dakota 135925 150294
Hennepin 422976 446623
Ramsey 149169 168233
Scott 55191 55191
Washington 98915 103915
and I know the bounding coordinates
-94.012
-92.732
45.415
44.471
there seems to be tons of software applications for GIS
http://en.wikipedia.org/wiki/List_of_geographic_information_systems_software
but what do I need to do?
I want the lat, lon of every house
Is there a library that will do this for me?
What is the data I need?
I think you need to install one GIS software. You can try open-source Qgis.
Because, firstly your data is not in long/lat (geographic) coordinates. Your .prj part of the shapefile (yes, all .dbf, .prj, .sbn, .sbx, .shp, and .shx files with the same name are one shapefile for GIS) says that the data are in the projected coordinate system NAD 1983 UTM Zone 15N. So, you need to transform your data to geographic system. This you easy can do in GIS, or programmatically by proj.4 library. (In Qgis add the shapefile to the project, then select it in the table of contents, right mouse button and choose "save as...". It will ask you for the target coordinate system.) Note, that you need to decide which geographic coordinates you wish, because your data are in the North American Datum (NAD 1983), but the most common worldwide now is WGS 1984.
Secondly, in GIS you will see your data, are they really points, or maybe polygons. (In case your houses are polygons you will need to get centroids of them, in Qgis menu Vector - Geometry Tools - Polygon Centroids).
Finally, when you really have your houses as points in geographic coordinates, you can get their coordinates, for example using advices from these questions Get list of coordinates for points in a layer and How do I calculate the latitude and longitude of points using QGIS.
Besides, there is a good library to work with GIS vector data, OGR, which can be used by many programming languages.
The file extensions above show, that the files are in ESRI Shape File format. In Java you could use GeoTools libraries, to read that.
The example below shows the first lines, search Internet for a more complete example.
// init shapefile
File shpFile = new File(fileName);
if (!shpFile.exists()) {
LOGGER.fatal(fileName + " does not exist");
}
Map<String, URL> connect = new HashMap<String, URL>();
FeatureCollection collection = null;
FeatureIterator iterator = null;
try {
connect.put("url", shpFile.toURI().toURL());
DataStore dataStore = DataStoreFinder.getDataStore(connect);
String typeName = dataStore.getTypeNames()[0];
"I want the lat, lon of every house" suggests that what you want to do is the process called geocoding. There are services you can use for that, some free (for limited uses) some not. You could start by looking at the List of geocoding systems to get an idea of where to start. I don't think you want to start by learning GIS or shapefiles, other than to extract the addresses you are trying to geocode.
You could estimate the lat/lon of each house by computing the centroid of each parcel. You could more roughly estimate the lat/lon of each house by calculating the centroid of the bounding rectangle of each parcel. Either of those would require extracting the parcel coordinates. If you are doing that for every house in Minnesota you will processing lots of data. A geocoding service would be cheaper. The Census Geocoder might help.

Tesselation/CGR Details from CATPart_CATIA_API

I need to read the tessellation/cgr/visualisation details from a CATIA V5R18 Part file using CATIA V5R18 API.
Visualisation details such as:
Number of Vertices
Number of Triangles
Number of Strips
Number of Fans
Number of Normal
Bounding Sphere Centre and Radius
These details I have read from .cgr files using CAT3DRep/CATRep/CATSurfacicRep, but I am not able to read the same for .CATPart files.
From .CATPart with the help of CATIVisu I got CAT3DBagRep type, when I queried from PartFeatures. But to get Visualisation details I need CATSurfacicRep.
What interface should I query and from where should I query?
I am not sure about R18 but for R22 and R23 if you have the CAA documentation there is an example located at: C:\Program Files\Dassault Systemes\B23\CAADoc\CAATessellation.edu.
This example code has everything you need to get the tessellation data except normals and bounding spheres. I used this example code when I was teaching myself how to make a tessellated nurbs surface and it was quite useful for testing.

CATIA-CAA CATIVisu

Hi i need the flow to read the visualisation details from a CATIA V5R18 Part file.
Visualisation details lik,
1.No of Vertices
2.No of Triangles
3.No of Strips
4.No of Fans
5.No of Normal
6.Bouding Sphere Centre and Radius
These details i have red from .cgr files using CAT3DRep/CATRep/CATSurfacicRep...
But i am not able to read the same for .CATPart files.
From .CATPart with the help of CATIVisu i got CAT3DBagRep type When i queried from PartFeatures But to get Visualisation details i need CATSurfacicRep.
Can anyone help?
Wat Interface i should query and from where i should query?
Well, information about the mesh (triangle, strips, fans, etc) is only carried by leaf Reps, like CAT3DSurfacicRep.
For complex files like CATPart or CATProduct, where you have a hierarchy of geometries, there's also a hierarchy of Reps. CAT3DBagRep is the class that allows building this hierarchy, as it has children Reps (which can of course be also CAT3DBagReps).
One solution may be to recursively explore this Rep hierarchy from the root CAT3DBagRep you get. The method to get the children Reps of a CAT3DBagRep is:
list<CATRep> *GetChildren();
You can go down the Rep tree until you get Reps of the expected type, like CATSurfacicRep. You may find many of them depending on your model.
When retrieving the mesh coordinates, normals and bounding element, please take into account that they are given in local Rep coordinates. A CAT3DBagRep carries positioning and orientation information (used when you position CATProducts, for example). This is returned by the following CAT3DBagRep method:
const CAT4x4Matrix * GetMatrix() const;
Depending on your scenario/model, you may need to take this positioning information into account.