Hi Jared,

May I reopen the ticket?

I got the `get_volume_field` idea. It returns the grid. My grid was trimmed
or was justified to have only the observations and because of this my
shapes seemed incoherent.

I jumped in the code yesterday to add the `quiet` flag on `dump`. This is
code is like the `get_volume_field` but return points instead of the grid
itself. Seems that there is no way on the PyMOL API to handle a grid
dislocated from origin (except dump level by level until fill a volume and
then parse each file). Some notes: (1) my build has no numpy and no idea
why; (2) and I'm not sure if I got the offset alright; (3) didn't handled
other typeofs, only float.

Can you review this code for me?


void ObjectMapDump(ObjectMap* om, const char* fname, int state, int quiet)
{
  auto file = fopen(fname, "wb");
  if (!file) {
    ErrMessage(om->G, "ObjectMapDump", "can't open file for writing");
  }

  ObjectMapState* oms = om->State + 0;

  int zd = oms->Field->dimensions[2];
  int yd = oms->Field->dimensions[1];
  int xd = oms->Field->dimensions[0];

  float zs = (oms->ExtentMax[2] - oms->ExtentMin[2]) /
(oms->Field->dimensions[2]);
  float ys = (oms->ExtentMax[1] - oms->ExtentMin[1]) /
(oms->Field->dimensions[1]);
  float xs = (oms->ExtentMax[0] - oms->ExtentMin[0]) /
(oms->Field->dimensions[0]);

  int offset = 0;
  for (int zi = 0; zi < oms->Field->dimensions[2]; zi++) {
    for (int yi = 0; yi < oms->Field->dimensions[1]; yi++) {
      for (int xi = 0; xi < oms->Field->dimensions[0]; xi++) {

        float z = oms->ExtentMin[2] + zs * zi;
        float y = oms->ExtentMin[1] + ys * yi;
        float x = oms->ExtentMin[0] + xs * xi;

        float* data = (float*) oms->Field->data->data;
        float value = data[offset];
        offset += 1;

        fprintf(file, "%10.4f%10.4f%10.4f%10.4f\n", x, y, z, value);
      }
    }
  }
  fclose(file);
  if (!quiet) {
    PRINTFB(om->G, FB_ObjectMap, FB_Actions)
      " ObjectMapDump: %s written to %s\n", om->Name, fname ENDFB(om->G);
  }
}

Em qui., 7 de nov. de 2019 às 11:41, Jared Sampson <
jared.samp...@columbia.edu> escreveu:

> Hi Pedro - Glad you have something working for your use case.
>
> Best,
> Jared
>
>
> On November 5, 2019 at 9:32:51 AM, Pedro Lacerda (pslace...@gmail.com)
> wrote:
>
> Update:
>
> worked the same for me, but may have impact in other cases:
>
> MIN_LEVEL = 0
> MAX_LEVEL = 20
> LEVEL_RANGE = np.arange(MIN_LEVEL, MAX_LEVEL+0.5, 0.5)
>
> def _get_map(map_name):
>     dump_fhandle, dump_fname = tempfile.mkstemp()
>     open(dump_fhandle).close()
>
>     try:
>         levels = {}
>         for level in LEVEL_RANGE:
>             # dump level
>             cmd.isodot('_i', map_name, level)
>             cmd.dump(dump_fname, '_i')
>             cmd.delete('_i')
>
>             # load level
>             with warnings.catch_warnings():
>                 xyz = np.loadtxt(dump_fname)
>                 warnings.simplefilter("ignore")
>
>             # handle empty maps
>             if len(xyz) == 0:
>                 xyz = np.ndarray((0, 3))
>
>             xyz = xyz[:, :3]
>             levels[level] = xyz
>
>         return levels
>     finally:
>         os.unlink(dump_fname)
>
> Em ter., 5 de nov. de 2019 às 11:13, Pedro Lacerda <pslace...@gmail.com>
> escreveu:
>
>> For the sake of completeness here is some working code.
>>
>> `dump` exports the surface of map representations. They are all surfaces.
>>
>> So I had to dump the map at each level (0.5 by 0.5 increment) in order to
>> get a filled volume. If you concatenate all xyz arrays you get the filled
>> volume of the level 20 surface.
>>
>> Thank you for the support.
>>
>>
>> MIN_LEVEL = 0
>> MAX_LEVEL = 20
>> LEVEL_RANGE = np.arange(MIN_LEVEL, MAX_LEVEL+0.5, 0.5)
>>
>>
>> def _get_map(map_name):
>>     dump_fhandle, dump_fname = tempfile.mkstemp()
>>     open(dump_fhandle).close()
>>
>>     try:
>>         levels = {}
>>         skip = False
>>         for level in LEVEL_RANGE:
>>             if not skip:
>>                 # dump level
>>                 cmd.isodot('_i', map_name, level)
>>                 cmd.dump(dump_fname, '_i')
>>                 cmd.delete('_i')
>>
>>                 # load level
>>                 with warnings.catch_warnings():
>>                     xyz = np.loadtxt(dump_fname)
>>                     warnings.simplefilter("ignore")
>>
>>             # handle empty maps
>>             if skip or len(xyz) == 0:
>>                 xyz = np.ndarray((0, 3))
>>                 skip = True
>>
>>             xyz = xyz[:, :3]
>>             levels[level] = xyz
>>
>>         return levels
>>     finally:
>>         os.unlink(dump_fname)
>>
>> Em seg., 4 de nov. de 2019 às 01:38, Pedro Lacerda <pslace...@gmail.com>
>> escreveu:
>>
>>> Hi Jared,
>>>
>>> So COLLADA exports some kind of already rendered 3D image.
>>>
>>> Took me some time to figure out if dump exports the map points or
>>> something specific to the surface representation. In fact, it is yet to be
>>> figured out.
>>>
>>> Dump can export at least map and surface objects.
>>>
>>> When I export two different overlapping surfaces of the same map there
>>> is points of the outer surface that aren't in the inner. I expected all
>>> points of the inner to be present in both dumps.
>>>
>>> So I guess that when I dump surface objects it exports newly created
>>> points of the enclosed volume of that surface. Is it correct?
>>>
>>> To export the map directly would preserve the original points? (Which I
>>> hope to be the original grid count of the server's method)
>>>
>>> Is overlap is defined for map objects?
>>>
>>>
>>> Sorry maybe I'm not saying very clear.
>>>
>>> And about the get_volume_field(), if I remember correctly it returned on
>>> a call an ndarray of shape (28, 26, 15) and on other call an ndarray of
>>> shape (28, 28, 16). Something like that.
>>>
>>>
>>> Cheers,
>>>
>>>
>>> Em sex, 1 de nov de 2019 10:33, Jared Sampson <
>>> jared.samp...@columbia.edu> escreveu:
>>>
>>>> Hi Pedro -
>>>>
>>>> The COLLADA option exports unlabeled mesh objects so I couldn't figure
>>>> out which one is acceptor or donor.
>>>>
>>>> Yes, you're correct about that.  This is due to the fact that COLLADA
>>>> export uses geometry after it is prepared for ray tracing, which doesn't
>>>> know about object names (see the primary function call
>>>> <https://github.com/schrodinger/pymol-open-source/blob/master/layer1/COLLADA.cpp#L667>).
>>>> It might be interesting/useful to export things in a more granular way
>>>> using pre-ray-tracing information as it is stored in the PyMOL session, but
>>>> that would involve substantial effort, and wasn't included when we planned
>>>> this export feature.
>>>>
>>>> If you wanted to know which mesh is which, you could export objects
>>>> one-at-a-time by disabling all the others, although to me, the dump command
>>>> output looks more helpful as it can be more easily parsed.
>>>>
>>>> Just one more question, what are these normal values?
>>>>
>>>>
>>>> The normal values Thomas refers to are the 3 components of the vector
>>>> indicating the direction toward the "outside" of the object, which is
>>>> normal to the surface the triangle mesh attempts to approximate.  This is
>>>> used in shading.
>>>>
>>>> https://en.wikipedia.org/wiki/Vertex_normal
>>>>
>>>> The cmd.get_volume_field() returns a sparse ndarray with unknow layout
>>>> and all dimensions variables depending of the object. How to interpret such
>>>> array?
>>>> On PyMOL 1.x it returned -1 but in 2.x returned the array.
>>>>
>>>> The dump command worked (almost) like a charm.
>>>> I expect to extract the "dump" array from get_volume_field() so don't
>>>> need to write the file just to be read and deleted afterwards. Is it
>>>> possible?
>>>>
>>>>
>>>> I'm not familiar with `cmd.get_volume_field()`, so I'll defer to others
>>>> on those questions.
>>>>
>>>> Hope that helps.
>>>>
>>>> Cheers,
>>>> Jared
>>>>
>>>
>>
>> --
>> Pedro Sousa Lacerda
>>
>>
>> *Laboratório de Bioinformática e Modelagem Molecular*
>> *Faculdade de Farmácia / UFBA*
>>
>> *@pslacerda*
>>
>> *+55 71 9 9981-1856*
>>
>
>
> --
> Pedro Sousa Lacerda
>
>
> *Laboratório de Bioinformática e Modelagem Molecular*
> *Faculdade de Farmácia / UFBA*
>
> *@pslacerda*
>
> *+55 71 9 9981-1856*
>
>

-- 
Pedro Sousa Lacerda


*Laboratório de Bioinformática e Modelagem Molecular*
*Faculdade de Farmácia / UFBA*

*@pslacerda*

*+55 71 9 9981-1856*
_______________________________________________
PyMOL-users mailing list
Archives: http://www.mail-archive.com/pymol-users@lists.sourceforge.net
Unsubscribe: 
https://sourceforge.net/projects/pymol/lists/pymol-users/unsubscribe

Reply via email to