File: select_tm.c

package info (click to toggle)
garlic 1.6-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 4,516 kB
  • sloc: ansic: 52,465; makefile: 2,254
file content (158 lines) | stat: -rw-r--r-- 4,536 bytes parent folder | download | duplicates (5)
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
/* Copyright (C) 2003 Damir Zucic */

/*=============================================================================

				select_tm.c

Purpose:
	Select transmembrane part of the macromolecular complex. 

Input:
	(1) Pointer to MolComplexS structure, with macromol. complexes.
	(2) Number of macromolecular complexes.
	(3) Selection mode index  (0 = overwrite, 1 = restrict, 2 = expand
	    previous selection).

Output:
	(1) The  flag  selectedF  set to one  for selected atoms  in every
	    caught macromolecular complex.
	(2) Return value.

Return value:
	(1) The number of selected atoms (zero or positive value).

Notes:
	(1) Half of the membrane thickness is expanded by two angstroms to
	    include atoms which are outside, but close to the membrane.

========includes:============================================================*/

#include <stdio.h>

#include <math.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>

#include "defines.h"
#include "typedefs.h"

/*======function prototypes:=================================================*/

double		ScalarProduct_ (VectorS *, VectorS *);

/*======select transmembrane part:===========================================*/

long SelectTM_ (MolComplexS *mol_complexSP, int mol_complexesN,
		int selection_modeI)
{
long		selected_atomsN = 0;
int		mol_complexI;
MolComplexS	*curr_mol_complexSP;
size_t		atomsN, atomI;
VectorS		normal_vectorS;
double		membrane_center_x, membrane_center_y, membrane_center_z;
double		half_thickness;
AtomS		*curr_atomSP;
double		x, y, z;
VectorS		curr_vectorS;
int		transmembraneF;
double		projection;
double		absolute_value;

/* Select all atoms above the plane: */
for (mol_complexI = 0; mol_complexI < mol_complexesN; mol_complexI++)
	{
	/* Pointer to the current macromolecular complex: */
	curr_mol_complexSP = mol_complexSP + mol_complexI;

	/* Check is the current macromolecular complex caught: */
	if (curr_mol_complexSP->catchF == 0) continue;

	/* Number of atoms in a macromolecular complex: */
	atomsN = curr_mol_complexSP->atomsN;
	if (atomsN == 0) continue;

	/* Check is membrane defined at all: */
	if (curr_mol_complexSP->membraneS.definedF == 0) continue;

	/* The normal vector: */ 
	normal_vectorS.x = curr_mol_complexSP->membraneS.plane1S.normal_x[0];
	normal_vectorS.y = curr_mol_complexSP->membraneS.plane1S.normal_y;
	normal_vectorS.z = curr_mol_complexSP->membraneS.plane1S.normal_z[0];

	/* Position of the plane center: */
	membrane_center_x = curr_mol_complexSP->membraneS.center_x;
	membrane_center_y = curr_mol_complexSP->membraneS.center_y;
	membrane_center_z = curr_mol_complexSP->membraneS.center_z;

	/* Half of the membrane thickness enlarged by a margin of */
	/* two angstroms.  This margin  allows inclusion  of some */
	/* atoms which are outside the TM area,  but not too far. */
	half_thickness = 0.5 * curr_mol_complexSP->membraneS.thickness + 2.0;

	/* Scan all atoms in the current complex: */
	for (atomI = 0; atomI < atomsN; atomI++)
		{
		/* Pointer to the current atom: */
		curr_atomSP = curr_mol_complexSP->atomSP + atomI;

		/* Copy the coordinates: */
		x = curr_atomSP->raw_atomS.x[0];
		y = curr_atomSP->raw_atomS.y;
		z = curr_atomSP->raw_atomS.z[0];

		/* Position of the atom relative to the membrane center: */
		curr_vectorS.x = x - membrane_center_x;
		curr_vectorS.y = y - membrane_center_y;
		curr_vectorS.z = z - membrane_center_z;

		/* Reset the flag: */
		transmembraneF = 0;

		/* Check the scalar product with the unit direction vector: */
		projection = ScalarProduct_ (&curr_vectorS, &normal_vectorS);

		/* Take the absolute value: */
		absolute_value = fabs (projection);

		/* Compare this value with half of the membrane thickness: */
		if (absolute_value <= half_thickness) transmembraneF = 1;

		/* Set the selection flag for the current atom: */
		switch (selection_modeI)
			{
			/* Overwrite the previous selection: */
			case 0:
				curr_atomSP->selectedF = transmembraneF;
				break;

			/* Restrict the previous selection: */
			case 1:
				curr_atomSP->selectedF &= transmembraneF;
				break;

			/* Expand the previous selection: */
			case 2:
				curr_atomSP->selectedF |= transmembraneF;
				break;

			default:
				;
			}

		/* Check the selection flag; increase */
		/* the count if flag is equal to one: */
		if (curr_atomSP->selectedF) selected_atomsN++;
		}
	}

/* Return the number of selected atoms: */
return selected_atomsN;
}

/*===========================================================================*/