iterate a script over TMA cores

315 views
Skip to first unread message

Niki

unread,
Jun 15, 2018, 12:29:56 AM6/15/18
to QuPath users
thanks to your help and kindness, i was able to write a script that does the following job for an image:
1) perform positive cell detection and measurement calculation 
2) export measurements as .csv file 
3) export location of the objects utilizing the script as .png file, as suggested by the following link 

now i'm trying to apply the script over TMA cores. 
step 1) was easily done by running script after tissue detection on TMA cores, but step 2) and 3) do not seem to be straightforward to me. i want to create the output files per each core, named as [corename].csv and [corename].png. to do so, i guess it has to be something like 

for (core in getTMACoreList()) {
  model.setImageData(imageData, imageData.getHierarchy().getObjects(null, PathDetectionObject.class)); <- it has to specify objects belonging to the core 
  for (object in model.getEntries()) {
     create masks and measurements 
     save files 
  }
}

do you think it's possible? thanks in advance! 

micros...@gmail.com

unread,
Jun 15, 2018, 1:02:55 AM6/15/18
to QuPath users
 "Export measurements as a csv file"

What measurements are you looking for?  There is already a function to export the TMA core measurements (positive cells, negative cells, etc) as a CSV file, which I suppose you could then split by line into multiple CSV files if you wanted to.

If you want measurements for each of the cells in the TMA into a separate CSV file that would be a little different, as would a single line CSV file with the same values as a single line from the TMA export.

To generate images per TMA core, you can use: https://github.com/qupath/qupath/issues/97

Niki

unread,
Jun 15, 2018, 1:34:43 AM6/15/18
to QuPath users
the single file generated by the saveMeasurement function was too huge, that's why i want to generate separate files.

in fact, since i wanted to give a unique id to each cell, i've done as follows instead of using the saveMeasurement function (yes i decomposed the function..). so to me, everything would work smoothly if there's a way to specify those objects belonging to a specific TMA core. 

id=1;
for (object in model.getEntries()) {
  sb.append(Integer.toString(id));
  sb.append(',');
for(int col=0; col<nColumns; col++) {
String val = model.getStringValue(object, names.get(col));
if(val != null)
sb.append(val);
if(col < nColumns-1)
sb.append(',');
}
sb.append("\n");
  id+=1; 
}

Pete

unread,
Jun 15, 2018, 2:37:48 AM6/15/18
to QuPath users
For the line in bold, try:

model.setImageData(imageData, imageData.getHierarchy().getDescendantObjects(core, null, PathDetectionObject.class));

Niki

unread,
Jun 17, 2018, 4:55:12 AM6/17/18
to QuPath users
somehow it didn't work, but your suggestion leads to the following trick and it sort of seems to work.

model.setImageData(imageData, imageData.getHierarchy().getObjects(null, PathDetectionObject.class)); 
for (core in getTMACoreList()) {
  ArrayList objList =model.getEntries().findall(it.getParent().getParent().getName()==core.getName())
  for (object in objList) {
     create masks and measurements 
     save files 
  }
}

why sort of? saving measurements works perfectly, but saving masks only works for the first core. for the other cores, only black image is saved.  i'm figuring out why.. 
 

Pete

unread,
Jun 17, 2018, 5:18:07 AM6/17/18
to QuPath users
Ok, I'm not sure how long and complex the script is, but I feel I'm missing some information.  I don't really understand exactly what PNGs and what measurements exactly you want to export (i.e. cell by cell, summary, both...).

If you don't need summary measurements, but rather cell-by-cell measurements, you shouldn't need model at all, and instead you can use something like this
for (detection in getDetectionObjects()) {
   
def value = detection.getMeasurementList().getMeasurement("Some name")
   
// Other things...
}

There are different ways to iterate through all the measurements; I tend to first loop through all the detections and put all the measurement names into a (Tree)set and then request them one-by-one for each detection.  This handles the fact that some detections might have different measurements from others (although generally they don't if they are all created in the same way, e.g. with the Positive Cell Detection command).  If a measurement is missing, it will be NaN.

Also,
it.getParent().getParent().getName()==core.getName()
looks like it could go wrong sometimes.

I think
it.getParent().getParent()==core
should be a bit better (no need to compare names), but it does rely on being 'two levels deeper'.

getDescendantObjects really is designed for this task, and should be faster and more reliable.  Alternatively, check out PathObjectTools.isAncestor(detection, core)https://github.com/qupath/qupath/blob/v0.1.2/qupath-core/src/main/java/qupath/lib/objects/helpers/PathObjectTools.java#L429

Reply all
Reply to author
Forward
0 new messages