Writing two variable in a root file in RootFramework - c++

I am new in root framework. I want to draw a graph for example; x vs. y graph. These values are related each other in a for loop.I get x values and y values for each x value. However, I could not save these variables in the same root file to draw a x vs. y graph, I could not find how can I do, because when I use TBrowser and use Draw option I get only a vs. bin graph.
Besides, I try to Fill option but it is needed a histogram, I guess I do not want to get histogram. I search Root Support, but I could not find a result for that there, also here.
Is there any suggestion to plot a graph with these two variables? Also, how can I save these variables in the same file?
Thank you!

Have you tried using TGraph class?
If you store x and y in some sort of array you can easily do something like this:
TGraph* graph=new TGraph(n,x,y); //where n is size of x and y arrays
TCanvas *c1 = new TCanvas("c1","",0,0,600,600);
graph->Draw("AP");
c1->Print("Graph.pdf"); //you can use different file format in output
That should create a pdf file with your graph. For saving your data you could use TNtuple or TTree. They have separate branches for each variable and the variable values are passed by giving the adress of variable in your program to the branch. Or you can just save it in the text file
TGraph
TCanvas

Related

Pymol: How to use a list index as input for a pymol function (align)?

I want to get the RMSD for each pair of poses generated by an autodock docking via the align function:
align pose1, pose2, cycles=0, transform=0
Instead of using the names of the poses as input, I want to access a list that contains all poses.
This list is successfully obtained via:
allobjects = cmd.get_object_list('all')
and
print(allobjects[x])
successfully prints the pose at position x in this list.
However, the following method did not work:
align allobjects[1], allobjects[2], cycles=0, transform=0
yields error: Invalid selection name "allobjects[1]"
What would be the correct way to feed the align function with the list indices?
Thank you in advance!
As far as I know, you can not pass values from python variables to the built-in functions of PyMOL. But there is almost always an equivalent python function that does the same and can receive regular pythonic arguments. In the case of align it would be cmd.align().
The result of cmd.align() is not printed as nice as the align function, but instead a list of 7 elements is returned, being the first element the calculated RMSD. The meaning of the rest of the values can be found in the source code of the function.
I also assume that you intent to calculate the RMSD for every possible pair of docked structures. For that purpose you have to use all the unique combinations of all structures and manually do a python loop over them. Be aware that the calculation time will increase exponentially with the number of structures you have.
allobjects = cmd.get_object_list('all')
from itertools import combinations
for pair in combinations(allobjects, 2): print(pair[0], pair[1], cmd.align(pair[0], pair[1], cycles=0, transform=0)[0])

How to get y axis range in Stata

Suppose I am using some twoway graph command in Stata. Without any action on my part Stata will choose some reasonable values for the ranges of both y and x axes, based both upon the minimum and maximum y and x values in my data, but also upon some algorithm that decides when it would be prettier for the range to extend instead to a number like '0' instead of '0.0139'. Wonderful! Great.
Now suppose that after (or while) I draw my graph, I want to slap some very important text onto it, and I want to be choosy about precisely where the text appears. Having the minimum and maximum values of the displayed axes would be useful: how can I get these min and max numbers? (Either before or while calling the graph command.)
NB: I am not asking how to set the y or x axis ranges.
Since this issue has been a bit of a headache for me for quite some time and I believe there is no good solution out there yet I wanted to write up two ways in which I was able to solve a similar problem to the one described in the post. Specifically, I was able to solve the issue of gray shading for part of the graph using these.
Define a global macro in the code generating the axis labels This is the less elegant way to do it but it works well. Locate the tickset_g.class file in your ado path. The graph twoway command uses this to draw the axes of any graph. There, I defined a global macro in the draw program that takes the value of the omin and omax locals after they have been set to the minimum between the axis range and data range (the command that does this is local omin = min(.scale.min,omin) and analogously for the max), since the latter sometimes exceeds the former. You could also define the global further up in that code block to only get the axis extent. You can then access the axis range using the globals after the graph command (and use something like addplot to add to the previously drawn graph). Two caveats for this approach: using global macros is, as far as I understand, bad practice and can be dangerous. I used names I was sure wouldn't be included in any program with the prefix userwritten. Also, you may not have administrator privileges that allow you to alter this file based on your organization's decisions. However, it is the simpler way. If you prefer a more elegant approach along the lines of what Nick Cox suggested, then you can:
Use the undocumented gdi natscale command to define your own axis labels The gdi commands are the internal commands that are used to generate what you see as graph output (cf. https://www.stata.com/meeting/dcconf09/dc09_radyakin.pdf). The tickset_g.class uses the gdi natscale command to generate the nice numbers of the axes. Basic documentation is available with help _natscale, basically you enter the minimum and maximum, e.g. from a summarize return, and a suggested number of steps and the command returns a min, max, and delta to be used in the x|ylabel option (several possible ways, all rather straightforward once you have those numbers so I won't spell them out for brevity). You'd have to adjust this approach in case you use some scale transformation.
Hope this helps!
I like Nick's suggestion, but if you're really determined, it seems that you can find these values by inspecting the output after you set trace on. Here's some inefficient code that seems to do exactly what you want. Three notes:
when I import the log file I get this message:
Note: Unmatched quote while processing row XXXX; this can be due to a formatting problem in the file or because a quoted data element spans multiple lines. You should carefully inspect your data after importing. Consider using option bindquote(strict) if quoted data spans multiple lines or option bindquote(nobind) if quotes are not used for binding data.
Sometimes the data fall outside of the min and max range values that are chosen for the graph's axis labels (but you can easily test for this).
The log linesize is actually important to my code below because the key values must fall on the same line as the strings that I use to identify the helpful rows.
* start a log (critical step for my solution)
cap log close _all
set linesize 255
log using "log", replace text
* make up some data:
clear
set obs 3
gen xvar = rnormal(0,10)
gen yvar = rnormal(0,.01)
* turn trace on, run the -twoway- call, and then turn trace off
set trace on
twoway scatter yvar xvar
set trace off
cap log close _all
* now read the log file in and find the desired info
import delimited "log.log", clear
egen my_string = concat(v*)
keep if regexm(my_string,"forvalues yf") | regexm(my_string,"forvalues xf")
drop if regexm(my_string,"delta")
split my_string, parse("=") gen(new)
gen axis = "vertical" if regexm(my_string,"yf")
replace axis = "horizontal" if regexm(my_string,"xf")
keep axis new*
duplicates drop
loc my_regex = "(.*[0-9]+)\((.*[0-9]+)\)(.*[0-9]+)"
gen min = regexs(1) if regexm(new3,"`my_regex'")
gen delta = regexs(2) if regexm(new3,"`my_regex'")
gen max_temp= regexs(3) if regexm(new3,"`my_regex'")
destring min max delta , replace
gen max = min + delta* int((max_temp-min)/delta)
*here is the info you want:
list axis min delta max

Abaqus Python 'Getclosest' command

I'm using the getclosest command to find a vertex.
ForceVertex1 = hatInstance.vertices.getClosest(coordinates=((x,y,z,))
This is a dictionary object with Key 0 and two values (hatInstance.vertices[1] and the coordinates of the vertex) The specific output:
{0: (mdb.models['EXP-100'].rootAssembly.instances['hatInstance-100'].vertices[1], (62.5242172081597, 101.192447407436, 325.0))}
Whenever I try to create a set, the vertex isn't accepted
mainAssembly.Set(vertices=ForceVertex1[0][0],name='LoadSet1')
I also tried a different way:
tolerance = 1.0e-3
vertex = []
for vertex in hatInstance.vertices:
x = vertex.pointOn[0][0]
print x
y = vertex.pointOn[0][1]
print y
z = vertex.pointOn[0][2]
print z
break
if (abs(x-xTarget)) < tolerance and abs(y-yTarget) < tolerance and abs(z-zTarget) < tolerance):
vertex.append(hatInstance.vertices[vertex.index:vertex.index+1])
xTarget etc being my coordinates, despite this I still don't get a vertex object
For those struggeling with this, I solved it.
Don't use the getClosest command as it returns a dictionary object despite the manual recommending this. I couldn't convert this dictionary object, specifically a key and a value within to a standalone object (vertex)
Instead use Instance.vertices.getByBoundingSphere(center=,radius=)
The center is basically a tuple of the coordinates and the radius is the tolerance. This returns an array of vertices
If you want the geometrical object you just have to access the dictionary.
One way to do it is:
ForceVertex1 = hatInstance.vertices.getClosest(coordinates=((x,y,z,))[0][0]
This will return the vertices object only, which you can assign to a set or whatever.
Edit: Found a solution to actually address the original question:
part=mdb.models[modelName].parts[partName]
v=part.vertices.getClosest(coordinates=(((x,y,z)),))
Note the formatting requirement for coordinates ((( )),), three sets of parenthesis with a comma. This will find the vertex closest to the specified point. In order to use this to create a set, I found you need to massage the Abaqus Python interface to return the vertex in a format that uses their "getSequenceFromMask" method. In order to create a set, the edges, faces, and/or vertices need to be of type "Sequence", which is internal to Abaqus. To do this, I then use the following code:
v2=part.verticies.findAt((((v[0][1])),))
part.Set(name='setName', vertices=v2)
Note, v[0][1] will give you the point at which the vertex lies on. Note again the format of the specified point using the findAt method (((point)),) with three sets of parenthesis and a comma. This will return a vertex that uses the getSequenceFromMask method in Abaqus (you can check by typing v2 then enter in the python box at the bottom of CAE, works with Abaqus 2020). This is type "Sequence" (you can check by typing type(V2)) and this can be used to create a set. If you do not format the point in findAt correctly (e.g., findAt(v[0][1]), without the parenthesis and comma), it will return an identical vertex as you get by accessing the dictionary returned using getClosest (e.g., v[0][0]). This is type 'Vertex' and cannot be used to create a set, even though it asks for a vertex. If you know the exact point where the vertex is, then you do not need the first step. You can simply use the findAt method with the correct formatting. However, the tolerance for findAt is very small (1e-6) and will return an empty sequence if nothing is found within the tolerance. If you only have a ballpark idea of where the vertex is located, then you need to use the getClosest method first. This indeed gets the closest vertex to the specified point, which may or may not be the one you are interested in.
Original post:
None of these answers work for a similar problem I am having while trying to create a set of faces within some range near a point. If I use getClosest as follows
f=mdb.models['Model-1'].parts['Part-1'].faces.getClosest(coordinates=((0,0,0),), searchTolerance=1)
mdb.models['Model-1'].parts['Part-1'].Set(faces=f, name='faceSet')
I get an error "TypeError: Keyword error on faces".
If I access the dictionary via face=f[0], I get error "Feature Creation Failed". If I access the tuple within the dictionary via f[0][0], I get the error "TypeError: keyword error on faces" again.
The option to use .getByBoundingSphere doesn't work either, because the faces in my model are massive, and the faces have to be completely contained within the sphere for Abaqus to "get" them, basically requiring me to create a sphere that encompasses the entire model.
My solution was to create my own script as follows:
import numpy as np
model=mdb.models['Model-1']
part=model.parts['Part-1']
faceSave=[]
faceSave2=[]
x=np.arange(-1,1,0.1)
y=np.arange(-1,1,0.1)
z=np.arange(-1,1,0.1)
for x1 in x:
for y1 in y:
for z1 in z:
f=part.faces.findAt(((x1,y1,z1),))
if len(f)>0:
if f[0] in faceSave2:
None
else:
faceSave.append(f)
faceSave2.append(f[0])
part.Set(faces=faceSave,name='faceSet')
This works, but it's extraordinarily slow, in part because "findAt" will throw a warning to the console whenever it doesn't find a face, and it usually doesn't find a face with this approach. The code above basically looks within a small cube for any faces, and puts them in the list "faceSave". faceSave2 is setup to ensure that duplicate faces aren't added to the list. Accessing the tuple (e.g, f[0] in the code above) contains the unique information about the face, whereas 'f' is just a pointer to the 'findAt' command. Strangely, you can use the pointer 'f' to create a Set, but you cannot use the actual face object 'f[0]' to create a set. The problem with this approach for general use is, the tolerance for "findAt" is super small, so, you either have to be confident where things are located in your model, or have the step size be 1e-6 in np.arange() to ensure you don't miss a face that's in the cube. With a tiny step size, expect the code to take forever.
At any rate, I can use a tuple (or a list of tuples) obtained via "findAt" to create a Set in Abaqus. However, I cannot use the tuple obtained via "getClosest" to make a set, even though I see no difference between the two objects. It's unfortunate, because getClosest gives me the exact info I need effectively immediately without my jumbled mess of for-loops.
#anarchoNobody:
Thank you so much for your edited answer!
This workaround works great, also with faces. I spent a lot of hours trying to figure out why .getClosest does not provide a working result for creating a set, but with the workaround and the number of brackets it works.
If applied with several faces, the code has to be slightly modified:
faces=((mdb.models['Model-1'].rootAssembly.instances['TT-1'].faces.getClosest(
coordinates=(((10.0, 10.0, 10.0)),), searchTolerance=2)),
(mdb.models['Model-1'].rootAssembly.instances['TT-1'].faces.getClosest(
coordinates=((-10.0, 10.0, 10.0),), searchTolerance=2)),)
faces1=(mdb.models['Model-1'].rootAssembly.instances['Tube-1'].faces.findAt((((
faces[0][0][1])),)),
mdb.models['Model-1'].rootAssembly.instances['Tube-1'].faces.findAt((((
faces[1][0][1])),)),)
mdb.models['Model-1'].rootAssembly.Surface(name='TT-inner-surf', side1Faces=faces1)
```

NetLogo: how to use data from txt file

I started using Netlogo a few weeks ago and I still have to learn a lot.
I'm writing a model and I need to access 3 values from my excel file to set initial placement of turtles on the world. Values are an x variable, y variable and a type(1,2,3,4).
I know that I have to convert the file in a txt file but I dont't understand how to organize the values in a list and open it to take them.
I would like to ask each turtle access 'x' and 'y', and populate the screen using this positions, than color turtles according to the type.
I really appreciate any help and suggestions on this matter.
L.

Random dependent variables using QtConcurrent

I ran into a problem of design. Prepare, as there will be a lot to come, and perhaps it is a too complex problem for SO.
For people familiar with R this might help:
I created a package in R for creating correlations between variables (for the purpose of simulations). I created a multiple threads version to allow parallelism. While R makes it seem embarrassingly parallel, I almost reconsider this statement in C++.
Sample a 100000 by 2 random data matrix.
Split it into a list of (100,000 / 200) = 500 splits of 200 rows by 2 columns data matrices.
Using a multi-core list apply function (mclapply, which can handle matrices as "item" in a list), I was able to send these smaller data matrices with 2 dimensions to the same function, though in different threads.
The function randomly rearranged the first column conditionally on the second column to produce a certain correlation. It then returned the rearranged matrix. I am not asking for this part, I am just mentioning this to outrule solutions that skip steps by independently creating x and y.
The list apply function automatically glues together these 500 splits of 200 rows by 2 columns into one big matrix (100,000 by 2).
listdata:
[[1]]
[1] [2]
... ...
... ...
[[2]]
[1] [2]
... ...
... ...
Applying:
mclapply(listdata, myFunction, cores=4)
Result:
[1] [2]
... ...
... ...
... ...
... ...
Randomness
I want to have a thread-safe, statistically random (results unrelated to the pseudo randomness) function yielding aggregated dependent x and y vectors.
Randomness is difficult since there usually is a global state for a random generator, which is not possible to share in a parallel situation.
Some of my solutions showed that the threads all used similar values, which does not happen using R.
Qt
I am using Qt, and I am trying to use QtConcurrent for creating the right (convenient for user) amount of threads, given a variable amount of splits.
I'll first say that I did not find a way to be able to pass multiple arguments to a function in a QtConcurrent. They all seem to be focused on mapping, without allowing extra arguments.
One attempt was the following:
QList< QVector<double> > list_of_one_split;
QList< QList< QVector<double> > list_containing_all_splits;
QVector<double> vector_of_doubles(10);
qFill(vector_of_doubles.begin(), vector_of_doubles.end(), 1); // not random
list_of_a_split.append(vector_of_doubles); // x variable split
list_of_a_split.append(vector_of_doubles); // y variable split
list_containing_all_splits.append(list_of_a_split) // first split
list_containing_all_splits.append(list_of_a_split) // second split
QtFuture<void> res = `QtConcurrent::map(list_containing_all_splits.begin(),
list_containing_all_splits.end(),
mapFunction)`
QList< QVector<double> > mapFunction(QList< QVector<double> > &list_of_a_split)
{
// random arranging one column on other
return list_of_a_split;
}
For some reason this return did not seem to affect the original list.
Another way I tried was to generate the y within the mapper function, giving it X as input, and returning y into a new variable using QtConcurrent:mappedReduced(), mapping over x in split form, producing y, return y split, and using reduce to merge it together into QVector<double> y. This has serious random issues, as I am not able to send a generator as extra argument.
I am just showing my efforts here, but feel free to approach the problem from any way (though same results) you like.
The goal in the end:
// Whether or not packed in a QList< >:
QVector<double> x = {..., ..., ..., ...};
QVector<double> y = {..., ..., ..., ...}; // dependent on x