[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastro-commits] master ea1dfa0: Segment can now output only clumps an
From: |
Mohammad Akhlaghi |
Subject: |
[gnuastro-commits] master ea1dfa0: Segment can now output only clumps and avoid objects |
Date: |
Mon, 16 Apr 2018 07:02:35 -0400 (EDT) |
branch: master
commit ea1dfa0304f3b6f8f692a7b1e9d82db8be497787
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>
Segment can now output only clumps and avoid objects
In some contexts, an object image is not necessary so it is a waste of
resources (both CPU, memory and storage space) to force the user to keep an
objects labeled image also. Therefore a new `--onlyclumps' option was added
to Segment that will only output one labeled dataset and all the clumps
will have a unique label.
---
bin/segment/args.h | 13 +++
bin/segment/main.h | 1 +
bin/segment/segment.c | 278 +++++++++++++++++++++++++++++---------------------
bin/segment/ui.h | 1 +
doc/gnuastro.texi | 12 +++
5 files changed, 189 insertions(+), 116 deletions(-)
diff --git a/bin/segment/args.h b/bin/segment/args.h
index 6293575..78a56c8 100644
--- a/bin/segment/args.h
+++ b/bin/segment/args.h
@@ -195,6 +195,19 @@ struct argp_option program_options[] =
GAL_OPTIONS_NOT_SET
},
{
+ "onlyclumps",
+ UI_KEY_ONLYCLUMPS,
+ 0,
+ 0,
+ "Finish after finding true clumps.",
+ GAL_OPTIONS_GROUP_OUTPUT,
+ &p->onlyclumps,
+ GAL_OPTIONS_NO_ARG_TYPE,
+ GAL_OPTIONS_RANGE_0_OR_1,
+ GAL_OPTIONS_NOT_MANDATORY,
+ GAL_OPTIONS_NOT_SET
+ },
+ {
"grownclumps",
UI_KEY_GROWNCLUMPS,
0,
diff --git a/bin/segment/main.h b/bin/segment/main.h
index 083045e..e632ae5 100644
--- a/bin/segment/main.h
+++ b/bin/segment/main.h
@@ -70,6 +70,7 @@ struct segmentparams
float snquant; /* Quantile of clumps in sky for true S/N.*/
uint8_t keepmaxnearriver; /* Keep clumps with a peak near a river. */
float clumpsnthresh; /* Clump S/N threshold. */
+ uint8_t onlyclumps; /* Finish after finding true clumps. */
float gthresh; /* Multiple of STD to stop growing clumps.*/
size_t minriverlength; /* Min, len of good grown clump rivers. */
float objbordersn; /* Minimum S/N for grown clumps to be one.*/
diff --git a/bin/segment/segment.c b/bin/segment/segment.c
index deae6fb..da38458 100644
--- a/bin/segment/segment.c
+++ b/bin/segment/segment.c
@@ -453,8 +453,11 @@ static void
segment_relab_overall(struct clumps_thread_params *cltprm)
{
struct clumps_params *clprm=cltprm->clprm;
- int32_t startinglab, *olabel=clprm->p->olabel->array;
+
+ int32_t startinglab;
+ uint8_t onlyclumps=clprm->p->onlyclumps;
size_t *s=cltprm->indexs->array, *sf=s+cltprm->indexs->size;
+ int32_t *clabel=clprm->p->clabel->array, *olabel=clprm->p->olabel->array;
/* Lock the mutex if we are working on more than one thread. NOTE: it is
very important to keep the number of operations within the mutex to a
@@ -462,18 +465,31 @@ segment_relab_overall(struct clumps_thread_params *cltprm)
if(clprm->p->cp.numthreads>1)
pthread_mutex_lock(&clprm->labmutex);
- /* Save the total number of objects found so far into `startinglab', then
- increment the total number of objects and clumps. */
- startinglab = clprm->totobjects;
- clprm->totobjects += cltprm->numobjects;
+ /* Set the starting label for re-labeling (THIS HAS TO BE BEFORE
+ CORRECTING THE TOTAL NUMBER OF CLUMPS/OBJECTS). */
+ startinglab = onlyclumps ? clprm->totclumps : clprm->totobjects;
+
+ /* Save the total number of clumps and objects. */
clprm->totclumps += cltprm->numtrueclumps;
+ if( !onlyclumps ) clprm->totobjects += cltprm->numobjects;
/* Unlock the mutex (if it was locked). */
if(clprm->p->cp.numthreads>1)
pthread_mutex_unlock(&clprm->labmutex);
/* Increase all the object labels by `startinglab'. */
- do olabel[*s] += startinglab; while(++s<sf);
+ if( onlyclumps )
+ {
+ if(cltprm->numtrueclumps>0)
+ {
+ do
+ if(clabel[*s]>0)
+ clabel[*s] += startinglab;
+ while(++s<sf);
+ }
+ }
+ else
+ do olabel[*s] += startinglab; while(++s<sf);
}
@@ -512,7 +528,7 @@ segment_on_threads(void *in_prm)
int32_t *clabel=p->clabel->array, *olabel=p->olabel->array;
/* Initialize the general parameters for this thread. */
- cltprm.clprm = clprm;
+ cltprm.clprm = clprm;
/* Go over all the detections given to this thread (counting from zero.) */
for(i=0; tprm->indexs[i] != GAL_BLANK_SIZE_T; ++i)
@@ -522,6 +538,7 @@ segment_on_threads(void *in_prm)
the ID given to this thread. */
cltprm.id = tprm->indexs[i]+1;
cltprm.indexs = &clprm->labindexs[ cltprm.id ];
+ cltprm.numinitclumps = cltprm.numtrueclumps = cltprm.numobjects = 0;
/* The `topinds' array is only necessary when the user wants to
@@ -574,102 +591,107 @@ segment_on_threads(void *in_prm)
if(clprm->step==1 || p->checksn)
{ gal_data_free(topinds); continue; }
- /* Only keep true clumps. */
+ /* Only keep true clumps and abort if the user only wants clumps. */
clumps_det_keep_true_relabel(&cltprm);
gal_data_free(topinds);
if(clprm->step==2) continue;
-
- /* Set the internal (with the detection) clump and object
- labels. Segmenting a detection into multiple objects is only
- defined when there is more than one true clump over the
- detection. When there is only one true clump
- (cltprm->numtrueclumps==1) or none (p->numtrueclumps==0), then
- just set the required preliminaries to make the next steps be
- generic for all cases. */
- if(cltprm.numtrueclumps<=1)
+ /* When only clumps are desired ignore the rest of the process. */
+ if(!p->onlyclumps)
{
- /* Set the basics. */
- cltprm.numobjects=1;
- segment_relab_noseg(&cltprm);
-
- /* If the user wanted a check image, this object doesn't
- change. */
- if( clprm->step >= 3 && clprm->step <= 6) continue;
-
- /* If the user has asked for grown clumps in the clumps image
- instead of the raw clumps, then replace the indexs in the
- `clabel' array is well. In this case, there will always be one
- "clump". */
- if(p->grownclumps)
- {
- sf=(s=cltprm.indexs->array)+cltprm.indexs->size;
- do clabel[ *s++ ] = 1; while(s<sf);
- cltprm.numtrueclumps=1;
- }
- }
- else
- {
- /* Grow the true clumps over the detection. */
- clumps_grow_prepare_initial(&cltprm);
- if(cltprm.diffuseindexs->size)
- gal_label_grow_indexs(p->olabel, cltprm.diffuseindexs, 1, 1);
- if(clprm->step==3)
- { gal_data_free(cltprm.diffuseindexs); continue; }
-
- /* If grown clumps are desired instead of the raw clumps, then
- replace all the grown clumps with those in clabel. */
- if(p->grownclumps)
- {
- sf=(s=cltprm.indexs->array)+cltprm.indexs->size;
- do
- if(olabel[*s]>0) clabel[*s]=olabel[*s];
- while(++s<sf);
- }
-
- /* Identify the objects in this detection using the grown clumps
- and correct the grown clump labels into new object labels. */
- segment_relab_to_objects(&cltprm);
- if(clprm->step==4)
+ /* Set the internal (with the detection) clump and object
+ labels. Segmenting a detection into multiple objects is only
+ defined when there is more than one true clump over the
+ detection. When there is only one true clump
+ (cltprm->numtrueclumps==1) or none (p->numtrueclumps==0), then
+ just set the required preliminaries to make the next steps be
+ generic for all cases. */
+ if(cltprm.numtrueclumps<=1)
{
- gal_data_free(cltprm.clumptoobj);
- gal_data_free(cltprm.diffuseindexs);
- continue;
+ /* Set the basics. */
+ cltprm.numobjects=1;
+ segment_relab_noseg(&cltprm);
+
+ /* If the user wanted a check image, this object doesn't
+ change. */
+ if( clprm->step >= 3 && clprm->step <= 6) continue;
+
+ /* If the user has asked for grown clumps in the clumps image
+ instead of the raw clumps, then replace the indexs in the
+ `clabel' array is well. In this case, there will always be
+ one "clump". */
+ if(p->grownclumps)
+ {
+ sf=(s=cltprm.indexs->array)+cltprm.indexs->size;
+ do clabel[ *s++ ] = 1; while(s<sf);
+ cltprm.numtrueclumps=1;
+ }
}
-
- /* Continue the growth and cover the whole area, we don't need
- the diffuse indexs any more, so after filling the detected
- region, free the indexs. */
- if( cltprm.numobjects == 1 )
- segment_relab_noseg(&cltprm);
else
{
- /* Correct the labels so every non-labeled pixel can be
- grown. */
- clumps_grow_prepare_final(&cltprm);
+ /* Grow the true clumps over the detection. */
+ clumps_grow_prepare_initial(&cltprm);
+ if(cltprm.diffuseindexs->size)
+ gal_label_grow_indexs(p->olabel, cltprm.diffuseindexs, 1, 1);
+ if(clprm->step==3)
+ { gal_data_free(cltprm.diffuseindexs); continue; }
- /* Cover the whole area (using maximum connectivity to not
- miss any pixels). */
- gal_label_grow_indexs(p->olabel, cltprm.diffuseindexs, 0,
- p->olabel->ndim);
+ /* If grown clumps are desired instead of the raw clumps,
+ then replace all the grown clumps with those in clabel. */
+ if(p->grownclumps)
+ {
+ sf=(s=cltprm.indexs->array)+cltprm.indexs->size;
+ do
+ if(olabel[*s]>0) clabel[*s]=olabel[*s];
+ while(++s<sf);
+ }
- /* Make sure all diffuse pixels are labeled. */
- if(cltprm.diffuseindexs->size)
- error(EXIT_FAILURE, 0, "a bug! Please contact us at %s to "
- "fix it. %zu pixels of detection %zu have not been "
- "labeled (as an object)", PACKAGE_BUGREPORT,
- cltprm.diffuseindexs->size, cltprm.id);
+ /* Identify the objects in this detection using the grown
+ clumps and correct the grown clump labels into new object
+ labels. */
+ segment_relab_to_objects(&cltprm);
+ if(clprm->step==4)
+ {
+ gal_data_free(cltprm.clumptoobj);
+ gal_data_free(cltprm.diffuseindexs);
+ continue;
+ }
+
+ /* Continue the growth and cover the whole area, we don't
+ need the diffuse indexs any more, so after filling the
+ detected region, free the indexs. */
+ if( cltprm.numobjects == 1 )
+ segment_relab_noseg(&cltprm);
+ else
+ {
+ /* Correct the labels so every non-labeled pixel can be
+ grown. */
+ clumps_grow_prepare_final(&cltprm);
+
+ /* Cover the whole area (using maximum connectivity to
+ not miss any pixels). */
+ gal_label_grow_indexs(p->olabel, cltprm.diffuseindexs, 0,
+ p->olabel->ndim);
+
+ /* Make sure all diffuse pixels are labeled. */
+ if(cltprm.diffuseindexs->size)
+ error(EXIT_FAILURE, 0, "a bug! Please contact us at %s "
+ "to fix it. %zu pixels of detection %zu have not "
+ "been labeled (as an object)", PACKAGE_BUGREPORT,
+ cltprm.diffuseindexs->size, cltprm.id);
+ }
+ gal_data_free(cltprm.diffuseindexs);
+ if(clprm->step==5)
+ { gal_data_free(cltprm.clumptoobj); continue; }
+
+ /* Correct the clump labels. Note that this is only necessary
+ when there is more than object over the detection or when
+ there were multiple clumps over the detection. */
+ if(cltprm.numobjects>1)
+ segment_relab_clumps_in_objects(&cltprm);
+ gal_data_free(cltprm.clumptoobj);
+ if(clprm->step==6) {continue;}
}
- gal_data_free(cltprm.diffuseindexs);
- if(clprm->step==5) { gal_data_free(cltprm.clumptoobj); continue; }
-
- /* Correct the clump labels. Note that this is only necessary
- when there is more than object over the detection or when
- there were multiple clumps over the detection. */
- if(cltprm.numobjects>1)
- segment_relab_clumps_in_objects(&cltprm);
- gal_data_free(cltprm.clumptoobj);
- if(clprm->step==6) {continue;}
}
/* Convert the object labels to their final value */
@@ -772,6 +794,7 @@ static void
segment_detections(struct segmentparams *p)
{
char *msg;
+ int continuecheck=1;
struct clumps_params clprm;
gal_data_t *labindexs, *claborig, *demo=NULL;
@@ -810,7 +833,7 @@ segment_detections(struct segmentparams *p)
/* Do each step. */
- while(clprm.step<8)
+ while(clprm.step<8 && continuecheck)
{
/* Reset the temporary copy of clabel back to its original. */
if(clprm.step>1)
@@ -853,18 +876,28 @@ segment_detections(struct segmentparams *p)
break;
case 3:
- demo=p->olabel;
- demo->name = "DET_CLUMPS_GROWN";
- if(!p->cp.quiet)
+ /* If the user only wanted clumps, there is no point in
+ continuing after this point. We DON'T WANT this at the end
+ of `2', otherwise, the `DET_CLUMPS_TRUE' extension will be
+ different when `--onlyclumps' is called and when it
+ isn't.*/
+ if(p->onlyclumps)
+ continuecheck=0;
+ else
{
- gal_timing_report(NULL, "Identify objects...",
- 1);
- if( asprintf(&msg, "True clumps grown "
- "(HDU: `%s').", demo->name)<0 )
- error(EXIT_FAILURE, 0, "%s: asprintf allocation",
- __func__);
- gal_timing_report(NULL, msg, 2);
- free(msg);
+ demo=p->olabel;
+ demo->name = "DET_CLUMPS_GROWN";
+ if(!p->cp.quiet)
+ {
+ gal_timing_report(NULL, "Identify objects...",
+ 1);
+ if( asprintf(&msg, "True clumps grown "
+ "(HDU: `%s').", demo->name)<0 )
+ error(EXIT_FAILURE, 0, "%s: asprintf allocation",
+ __func__);
+ gal_timing_report(NULL, msg, 2);
+ free(msg);
+ }
}
break;
@@ -935,7 +968,8 @@ segment_detections(struct segmentparams *p)
default values are hard to view, so we'll make a copy of the
demo, set all Sky regions to blank and all clump macro values
to zero. */
- gal_fits_img_write(demo, p->segmentationname, NULL, PROGRAM_NAME);
+ if(continuecheck)
+ gal_fits_img_write(demo, p->segmentationname, NULL, PROGRAM_NAME);
/* If the user wanted to check the clump S/N values, then break
out of the loop, we don't need the rest of the process any
@@ -963,6 +997,7 @@ segment_detections(struct segmentparams *p)
p->numclumps=clprm.totclumps;
p->numobjects=clprm.totobjects;
+
/* If the user wanted to see the S/N table, then make the S/N table. */
if(p->checksn) segment_save_sn_table(&clprm);
@@ -1020,14 +1055,16 @@ segment_output(struct segmentparams *p)
/* The object labels. */
- gal_fits_key_list_add(&keys, GAL_TYPE_SIZE_T, "NUMLABS", 0,
- &p->numobjects, 0, "Total number of objects", 0,
- "counter");
- p->olabel->name="OBJECTS";
- gal_fits_img_write(p->olabel, p->cp.output, keys, PROGRAM_NAME);
- p->olabel->name=NULL;
- keys=NULL;
-
+ if(!p->onlyclumps)
+ {
+ gal_fits_key_list_add(&keys, GAL_TYPE_SIZE_T, "NUMLABS", 0,
+ &p->numobjects, 0, "Total number of objects", 0,
+ "counter");
+ p->olabel->name="OBJECTS";
+ gal_fits_img_write(p->olabel, p->cp.output, keys, PROGRAM_NAME);
+ p->olabel->name=NULL;
+ keys=NULL;
+ }
/* The Standard deviation image (if one was actually given). */
if( !p->rawoutput && p->std->size>1 )
@@ -1154,10 +1191,19 @@ segment(struct segmentparams *p)
/* Report the results and timing to the user. */
if(!p->cp.quiet)
{
- if( asprintf(&msg, "%zu object%s""containing %zu clump%sfound.",
- p->numobjects, p->numobjects==1 ? " " : "s ",
- p->numclumps, p->numclumps ==1 ? " " : "s ")<0 )
- error(EXIT_FAILURE, 0, "%s: asprintf allocation", __func__);
+ if(p->onlyclumps)
+ {
+ if( asprintf(&msg, "%zu clump%sfound.",
+ p->numclumps, p->numclumps ==1 ? " " : "s ")<0 )
+ error(EXIT_FAILURE, 0, "%s: asprintf allocation", __func__);
+ }
+ else
+ {
+ if( asprintf(&msg, "%zu object%s""containing %zu clump%sfound.",
+ p->numobjects, p->numobjects==1 ? " " : "s ",
+ p->numclumps, p->numclumps ==1 ? " " : "s ")<0 )
+ error(EXIT_FAILURE, 0, "%s: asprintf allocation", __func__);
+ }
gal_timing_report(&t1, msg, 1);
free(msg);
}
diff --git a/bin/segment/ui.h b/bin/segment/ui.h
index d591221..a2e9c8f 100644
--- a/bin/segment/ui.h
+++ b/bin/segment/ui.h
@@ -82,6 +82,7 @@ enum option_keys_enum
UI_KEY_MINIMA,
UI_KEY_RAWOUTPUT,
UI_KEY_MINNUMFALSE,
+ UI_KEY_ONLYCLUMPS,
UI_KEY_GROWNCLUMPS,
UI_KEY_CHECKSN,
UI_KEY_CHECKSEGMENTATION,
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 493fb86..65d0999 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -15252,6 +15252,18 @@ Don't abort Segment after producing the check
image(s). The usage of this
option is identical to NoiseChisel's @option{--continueaftercheck} option
(@ref{NoiseChisel input}). Please see the descriptions there for more.
address@hidden --onlyclumps
+Abort Segment after finding true clumps and don't continue with finding
+options. Therefore, no @code{OBJECTS} extension will be present in the
+output. Each true clump in @code{CLUMPS} will get a unique label, but
+diffuse regions will still have a negative value.
+
+To make a catalog of the clumps, the input detection map (where all the
+labels are one) can be fed into @ref{MakeCatalog} along with the input
+detection map to Segment (that only had a value of @code{1} for all
+detected pixels) with @option{--clumpscat}. In this way, MakeCatalog will
+assume all the clumps belong to a single ``object''.
+
@item --grownclumps
In the output @code{CLUMPS} extension, store the grown clumps. If a
detected region contains no clumps or only one clump, then it will be fully
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnuastro-commits] master ea1dfa0: Segment can now output only clumps and avoid objects,
Mohammad Akhlaghi <=