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