void Output_Clusters(Segmentation *segs, Overlaps *ovl, Clusters *clust) { Array *stack, *proj; int i, j, k; #ifdef PROGRESS printf("\nGenerating %d color cluster stacks\n",clust->inum); fflush(stdout); #endif stack = Make_Array(RGB_KIND,UINT16_TYPE,3,Images[0]->dims); proj = Make_Array(RGB_KIND,UINT16_TYPE,2,Images[0]->dims); for (i = 0; i < clust->inum; i++) { Array_Op_Scalar(stack,SET_OP,UVAL,VALU(0)); for (j = clust->ilist[i]; j < clust->ilist[i+1]; j++) { Array_Bundle plane; int item = clust->item[j]; int chan = ovl->chans[item]; int seg = item - segs[chan].base; for (k = 0; k < NumChans; k++) { plane = *stack; Draw_Region_Image(Get_Array_Plane(&plane,k%3), Images[k],segs[chan].segs[seg]); } } if (!Is_Arg_Matched("-pj")) { sprintf(NameBuf,"%s/%s.clust%d.tif",RezFolder,CoreName,i); Write_Image(NameBuf,stack,LZW_PRESS); } #ifdef PROGRESS printf("*"); fflush(stdout); #endif Z_Projection(stack,proj); sprintf(NameBuf,"%s/%s.PR.clust%d.tif",RezFolder,CoreName,i); Write_Image(NameBuf,proj,LZW_PRESS); } Free_Array(proj); Free_Array(stack); #ifdef PROGRESS printf("\n"); fflush(stdout); #endif }
void Output_False_Color_Stack(int nsegs, Region **regs, char *name, int which) { Array *stack; int i; Color_Bundle color; #ifdef PROGRESS printf(" Generating faux color stack of %s.%s%d.tif\n",CoreName,name,which); fflush(stdout); fflush(stdout); #endif stack = Make_Array(RGB_KIND,UINT16_TYPE,3,Images[0]->dims); Array_Op_Scalar(stack,SET_OP,UVAL,VALU(0)); color.op = SET_PIX; for (i = 0; i < nsegs; i++) { color.red = VALU(rand()%256); color.green = VALU(rand()%256); color.blue = VALU(rand()%256); Draw_Region(stack,&color,regs[i]); } sprintf(NameBuf,"%s/%s.%s%d.tif",RezFolder,CoreName,name,which); Write_Image(NameBuf,stack,LZW_PRESS); Free_Array(stack); }
*/ static REBFLG Get_Struct_Var(REBSTU *stu, REBVAL *word, REBVAL *val) /* ***********************************************************************/ { struct Struct_Field *field = NULL; REBCNT i = 0; field = (struct Struct_Field *)SERIES_DATA(stu->fields); for (i = 0; i < SERIES_TAIL(stu->fields); i ++, field ++) { if (VAL_WORD_CANON(word) == VAL_SYM_CANON(BLK_SKIP(PG_Word_Table.series, field->sym))) { if (field->array) { REBSER *ser = Make_Array(field->dimension); REBCNT n = 0; for (n = 0; n < field->dimension; n ++) { REBVAL elem; get_scalar(stu, field, n, &elem); Append_Value(ser, &elem); } Val_Init_Block(val, ser); } else { get_scalar(stu, field, 0, val); } return TRUE; } } return FALSE; }
// // Map_To_Block: C // // mapser = series of the map // what: -1 - words, +1 - values, 0 -both // REBSER *Map_To_Block(REBSER *mapser, REBINT what) { REBVAL *val; REBCNT cnt = 0; REBSER *blk; REBVAL *out; // Count number of set entries: for (val = BLK_HEAD(mapser); NOT_END(val) && NOT_END(val+1); val += 2) { if (!IS_NONE(val+1)) cnt++; // must have non-none value } // Copy entries to new block: blk = Make_Array(cnt * ((what == 0) ? 2 : 1)); out = BLK_HEAD(blk); for (val = BLK_HEAD(mapser); NOT_END(val) && NOT_END(val+1); val += 2) { if (!IS_NONE(val+1)) { if (what <= 0) *out++ = val[0]; if (what >= 0) *out++ = val[1]; } } SET_END(out); blk->tail = out - BLK_HEAD(blk); return blk; }
*/ void Init_Frame(void) /* ***********************************************************************/ { // Temporary block used while scanning for frame words: Set_Root_Series(TASK_BUF_WORDS, Make_Array(100), "word cache"); // just holds words, no GC }
void Output_Neurons(int numneur, Region **neurons, int do_brighten) { Array *stack, *proj; int i, k; #ifdef PROGRESS printf("\nGenerating %d individual neuron stacks\n",numneur); fflush(stdout); #endif stack = Make_Array(RGB_KIND,UINT16_TYPE,3,Images[0]->dims); proj = Make_Array(RGB_KIND,UINT16_TYPE,2,Images[0]->dims); for (i = 0; i < numneur; i++) { Array_Op_Scalar(stack,SET_OP,UVAL,VALU(0)); for (k = 0; k < NumChans; k++) { Array_Bundle plane = *stack; Draw_Region_Image(Get_Array_Plane(&plane,k%3),Images[k],neurons[i]); } if (do_brighten) Scale_Array_To_Range(stack,VALU(0),VALU(4095)); if (!Is_Arg_Matched("-pj")) { sprintf(NameBuf,"%s/%s.neuron%d.tif",RezFolder,CoreName,i); Write_Image(NameBuf,stack,LZW_PRESS); } #ifdef PROGRESS printf("*"); fflush(stdout); #endif Z_Projection(stack,proj); sprintf(NameBuf,"%s/%s.PR.neuron%d.tif",RezFolder,CoreName,i); Write_Image(NameBuf,proj,LZW_PRESS); } // Kill_Array(proj); these are causing a glib.c memory error in Linux // Kill_Array(stack); #ifdef PROGRESS printf("\n"); fflush(stdout); #endif }
// // Make_Map: C // // Makes a MAP block (that holds both keys and values). // Size is the number of key-value pairs. // If size >= MIN_DICT, then a hash series is also created. // static REBSER *Make_Map(REBINT size) { REBSER *blk = Make_Array(size * 2); REBSER *ser = 0; if (size >= MIN_DICT) ser = Make_Hash_Sequence(size); blk->extra.series = ser; return blk; }
void Work(void) { long t; Read(C); t = n = strlen(C); for (long i = 0; i < n; i++) C[i + n] = C[i]; n <<= 1; Make_Array(C); for (long i = 0, l = 0; l < t; i++) if (S[i] < t) putchar(C[ (S[i] + t - 1) % n ]), l++; }
// // Split_Lines: C // // Given a string series, split lines on CR-LF. Give back array of strings. // // Note: The definition of "line" in POSIX is a sequence of characters that // end with a newline. Hence, the last line of a file should have a newline // marker, or it's not a "line") // // https://stackoverflow.com/a/729795 // // This routine does not require it. // // !!! CR support is likely to be removed...and CR will be handled as a normal // character, with special code needed to process it. // REBARR *Split_Lines(const REBVAL *str) { REBDSP dsp_orig = DSP; REBCNT len = VAL_LEN_AT(str); REBCNT i = VAL_INDEX(str); if (i == len) return Make_Array(0); DECLARE_MOLD (mo); Push_Mold(mo); REBCHR(const*) cp = VAL_STRING_AT(str); REBUNI c; cp = NEXT_CHR(&c, cp); for (; i < len; ++i, cp = NEXT_CHR(&c, cp)) { if (c != LF && c != CR) { Append_Codepoint(mo->series, c); continue; } Init_Text(DS_PUSH(), Pop_Molded_String(mo)); SET_CELL_FLAG(DS_TOP, NEWLINE_BEFORE); Push_Mold(mo); if (c == CR) { REBCHR(const*) tp = NEXT_CHR(&c, cp); if (c == LF) { ++i; cp = tp; // treat CR LF as LF, lone CR as LF } } } // If there's any remainder we pushed in the buffer, consider the end of // string to be an implicit line-break if (STR_SIZE(mo->series) == mo->offset) Drop_Mold(mo); else { Init_Text(DS_PUSH(), Pop_Molded_String(mo)); SET_CELL_FLAG(DS_TOP, NEWLINE_BEFORE); } return Pop_Stack_Values_Core(dsp_orig, ARRAY_FLAG_NEWLINE_AT_TAIL); }
*/ REBSER *Make_Frame(REBINT len, REBOOL has_self) /* ** Create a frame of a given size, allocating space for both ** words and values. Normally used for global frames. ** ***********************************************************************/ { REBSER *frame; REBSER *words; REBVAL *value; words = Make_Array(len + 1); // size + room for SELF frame = Make_Array(len + 1); // Note: cannot use Append_Frame for first word. value = Alloc_Tail_Array(frame); SET_FRAME(value, 0, words); value = Alloc_Tail_Array(words); Val_Init_Word_Typed( value, REB_WORD, has_self ? SYM_SELF : SYM_NOT_USED, ALL_64 ); return frame; }
x*/ void RXI_To_Block(RXIFRM *frm, REBVAL *out) { /* ***********************************************************************/ REBCNT n; REBSER *blk; REBVAL *val; REBCNT len; blk = Make_Array(len = RXA_COUNT(frm)); for (n = 1; n <= len; n++) { val = Alloc_Tail_Array(blk); RXI_To_Value(val, frm->args[n], RXA_TYPE(frm, n)); } Val_Init_Block(out, blk); }
*/ static REBSER *Make_Map(REBINT size) /* ** Makes a MAP block (that holds both keys and values). ** Size is the number of key-value pairs. ** If size >= MIN_DICT, then a hash series is also created. ** ***********************************************************************/ { REBSER *blk = Make_Array(size * 2); REBSER *ser = 0; if (size >= MIN_DICT) ser = Make_Hash_Sequence(size); blk->extra.series = ser; return blk; }
Array *Build_Line_Detectors( Range off, Range wid, Range ang, float length, int supportsize ) { Array *bank; int noff = compute_number_steps( &off ), nwid = compute_number_steps( &wid ), nang = compute_number_steps( &ang ); int shape[5] = { supportsize, supportsize, noff, nwid, nang}; bank = Make_Array( shape, 5, sizeof(float) ); memset( bank->data, 0, bank->strides_bytes[0] ); { int o,a,w; for( o = 0; o < noff; o++ ) { //point anchor = {supportsize/2.0, o*off.step + off.min + supportsize/2.0}; point anchor = {supportsize/2.0, supportsize/2.0}; for( a = 0; a < nang; a++ ) for( w = 0; w < nwid; w++ ) // Render_Curved_Line_Detector( // o*off.step + off.min, //offset (before rotation) // length, //length, // a*ang.step + ang.min, //angle, // w*wid.step + wid.min, //width, // 3*length, //radius of curvature // anchor, //anchor, // Get_Line_Detector( bank, o,w,a), //image // bank->strides_px + 3); //strides Render_Line_Detector( o*off.step + off.min, //offset (before rotation) length, //length, a*ang.step + ang.min, //angle, w*wid.step + wid.min, //width, anchor, //anchor, Get_Line_Detector( bank, o,w,a), //image bank->strides_px + 3); //strides } } return bank; }
*/ REBSER *Make_Object_Block(REBSER *frame, REBINT mode) /* ** Return a block containing words, values, or set-word: value ** pairs for the given object. Note: words are bound to original ** object. ** ** Modes: ** 1 for word ** 2 for value ** 3 for words and values ** ***********************************************************************/ { REBVAL *words = FRM_WORDS(frame); REBVAL *values = FRM_VALUES(frame); REBSER *block; REBVAL *value; REBCNT n; n = (mode & 4) ? 0 : 1; block = Make_Array(SERIES_TAIL(frame) * (n + 1)); for (; n < SERIES_TAIL(frame); n++) { if (!VAL_GET_EXT(words + n, EXT_WORD_HIDE)) { if (mode & 1) { value = Alloc_Tail_Array(block); if (mode & 2) { VAL_SET(value, REB_SET_WORD); VAL_SET_OPT(value, OPT_VALUE_LINE); } else VAL_SET(value, REB_WORD); //VAL_TYPE(words+n)); VAL_WORD_SYM(value) = VAL_BIND_SYM(words+n); VAL_WORD_INDEX(value) = n; VAL_WORD_FRAME(value) = frame; } if (mode & 2) { Append_Value(block, values+n); } } } return block; }
// // Init_Typesets: C // // Create typeset variables that are defined above. // For example: NUMBER is both integer and decimal. // Add the new variables to the system context. // void Init_Typesets(void) { REBVAL *value; REBINT n; Set_Root_Series(ROOT_TYPESETS, ARR_SERIES(Make_Array(40))); for (n = 0; Typesets[n].sym != SYM_0; n++) { value = Alloc_Tail_Array(VAL_ARRAY(ROOT_TYPESETS)); // Note: the symbol in the typeset is not the symbol of a word holding // the typesets, rather an extra data field used when the typeset is // in a context key slot to identify that field's name // Val_Init_Typeset(value, Typesets[n].bits, SYM_0); *Append_Context(Lib_Context, NULL, Typesets[n].sym) = *value; } }
*/ REBSER *Create_Frame(REBSER *words, REBSER *spec) /* ** Create a new frame from a word list. ** The values of the frame are initialized to NONE. ** ***********************************************************************/ { REBINT len = SERIES_TAIL(words); REBSER *frame = Make_Array(len); REBVAL *value = BLK_HEAD(frame); SET_FRAME(value, spec, words); SERIES_TAIL(frame) = len; for (value++, len--; len > 0; len--, value++) SET_NONE(value); // skip first value (self) SET_END(value); return frame; }
// // RL_Extend: C // // Appends embedded extension to system/catalog/boot-exts. // // Returns: // A pointer to the REBOL library (see reb-lib.h). // Arguments: // source - A pointer to a UTF-8 (or ASCII) string that provides // extension module header, function definitions, and other // related functions and data. // call - A pointer to the extension's command dispatcher. // Notes: // This function simply adds the embedded extension to the // boot-exts list. All other processing and initialization // happens later during startup. Each embedded extension is // queried and init using LOAD-EXTENSION system native. // See c:extensions-embedded // RL_API void *RL_Extend(const REBYTE *source, RXICAL call) { REBVAL *value; REBARR *array; value = CTX_VAR(Sys_Context, SYS_CTX_BOOT_EXTS); if (IS_BLOCK(value)) array = VAL_ARRAY(value); else { array = Make_Array(2); Val_Init_Block(value, array); } value = Alloc_Tail_Array(array); Val_Init_Binary(value, Copy_Bytes(source, -1)); // UTF-8 value = Alloc_Tail_Array(array); SET_HANDLE_CODE(value, cast(CFUNC*, call)); return Extension_Lib(); }
// // Collect_Set_Words: C // // Scan a block, collecting all of its SET words as a block. // REBARR *Collect_Set_Words(REBVAL *val) { REBCNT count = 0; REBVAL *val2 = val; REBARR *array; for (; NOT_END(val); val++) if (IS_SET_WORD(val)) count++; val = val2; array = Make_Array(count); val2 = ARR_HEAD(array); for (; NOT_END(val); val++) { if (IS_SET_WORD(val)) Val_Init_Word(val2++, REB_WORD, VAL_WORD_SYM(val)); } SET_END(val2); SET_ARRAY_LEN(array, count); return array; }
// // Destroy_External_Storage: C // // Destroy the external storage pointed by `->data` by calling the routine // `free_func` if it's not NULL // // out Result // ser The series // free_func A routine to free the storage, if it's NULL, only mark the // external storage non-accessible // REB_R Destroy_External_Storage(REBVAL *out, REBSER *ser, REBVAL *free_func) { SET_VOID(out); if (!GET_SER_FLAG(ser, SERIES_FLAG_EXTERNAL)) { fail (Error(RE_NO_EXTERNAL_STORAGE)); } if (!GET_SER_FLAG(ser, SERIES_FLAG_ACCESSIBLE)) { REBVAL i; SET_INTEGER(&i, cast(REBUPT, SER_DATA_RAW(ser))); fail (Error(RE_ALREADY_DESTROYED, &i)); } CLEAR_SER_FLAG(ser, SERIES_FLAG_ACCESSIBLE); if (free_func) { REBVAL safe; REBARR *array; REBVAL *elem; REBOOL threw; array = Make_Array(2); MANAGE_ARRAY(array); PUSH_GUARD_ARRAY(array); elem = Alloc_Tail_Array(array); *elem = *free_func; elem = Alloc_Tail_Array(array); SET_INTEGER(elem, cast(REBUPT, SER_DATA_RAW(ser))); threw = Do_At_Throws(&safe, array, 0, SPECIFIED); // 2 non-relative val DROP_GUARD_ARRAY(array); if (threw) return R_OUT_IS_THROWN; } return R_OUT; }
// // Typeset_To_Array: C // // Converts typeset value to a block of datatypes. // No order is specified. // REBARR *Typeset_To_Array(REBVAL *tset) { REBARR *block; REBVAL *value; REBINT n; REBINT size = 0; for (n = 0; n < REB_MAX_0; n++) { if (TYPE_CHECK(tset, KIND_FROM_0(n))) size++; } block = Make_Array(size); // Convert bits to types: for (n = 0; n < REB_MAX_0; n++) { if (TYPE_CHECK(tset, KIND_FROM_0(n))) { value = Alloc_Tail_Array(block); Val_Init_Datatype(value, KIND_FROM_0(n)); } } return block; }
*/ RL_API void *RL_Make_Block(u32 size) /* ** Allocate a series suitable for storing Rebol values. This series ** can be used as a backing store for a BLOCK!, but also for any ** other Rebol Array type (PAREN!, PATH!, GET-PATH!, SET-PATH!, or ** LIT-PATH!). ** ** Returns: ** A pointer to a block series. ** Arguments: ** size - the length of the block. The system will add one extra ** for the end-of-block marker. ** Notes: ** Blocks are allocated with REBOL's internal memory manager. ** Internal structures may change, so NO assumptions should be made! ** Blocks are automatically garbage collected if there are ** no references to them from REBOL code (C code does nothing.) ** However, you can lock blocks to prevent deallocation. (?? default) ** ***********************************************************************/ { return Make_Array(size); }
// // Vector_To_Array: C // // Convert a vector to a block. // REBARR *Vector_To_Array(const REBVAL *vect) { REBCNT len = VAL_LEN_AT(vect); REBYTE *data = SER_DATA_RAW(VAL_SERIES(vect)); REBCNT type = VECT_TYPE(VAL_SERIES(vect)); REBARR *array = NULL; REBCNT n; RELVAL *val; if (len <= 0) fail (Error_Invalid_Arg(vect)); array = Make_Array(len); val = ARR_HEAD(array); for (n = VAL_INDEX(vect); n < VAL_LEN_HEAD(vect); n++, val++) { VAL_RESET_HEADER(val, (type >= VTSF08) ? REB_DECIMAL : REB_INTEGER); VAL_INT64(val) = get_vect(type, data, n); // can be int or decimal } TERM_ARRAY_LEN(array, len); assert(IS_END(val)); return array; }
*/ RL_API void *RL_Extend(const REBYTE *source, RXICAL call) /* ** Appends embedded extension to system/catalog/boot-exts. ** ** Returns: ** A pointer to the REBOL library (see reb-lib.h). ** Arguments: ** source - A pointer to a UTF-8 (or ASCII) string that provides ** extension module header, function definitions, and other ** related functions and data. ** call - A pointer to the extension's command dispatcher. ** Notes: ** This function simply adds the embedded extension to the ** boot-exts list. All other processing and initialization ** happens later during startup. Each embedded extension is ** queried and init using LOAD-EXTENSION system native. ** See c:extensions-embedded ** ***********************************************************************/ { REBVAL *value; REBSER *ser; value = BLK_SKIP(Sys_Context, SYS_CTX_BOOT_EXTS); if (IS_BLOCK(value)) ser = VAL_SERIES(value); else { ser = Make_Array(2); Val_Init_Block(value, ser); } value = Alloc_Tail_Array(ser); Val_Init_Binary(value, Copy_Bytes(source, -1)); // UTF-8 value = Alloc_Tail_Array(ser); SET_HANDLE_CODE(value, cast(CFUNC*, call)); return Extension_Lib(); }
ZArray::ZArray(ZArray::Value_Type type, int ndims, mylib::Dimn_Type *dims) { m_data = Make_Array(mylib::PLAIN_KIND, type, ndims, dims); }
// // Make_Where_For_Frame: C // // Each call frame maintains the array it is executing in, the current index // in that array, and the index of where the current expression started. // This can be deduced into a segment of code to display in the debug views // to indicate roughly "what's running" at that stack level. // // Unfortunately, Rebol doesn't formalize this very well. There is no lock // on segments of blocks during their evaluation, and it's possible for // self-modifying code to scramble the blocks being executed. The DO // evaluator is robust in terms of not *crashing*, but the semantics may well // suprise users. // // !!! Should blocks on the stack be locked from modification, at least by // default unless a special setting for self-modifying code unlocks it? // // So long as WHERE information is unreliable, this has to check that // `expr_index` (where the evaluation started) and `index` (where the // evaluation thinks it currently is) aren't out of bounds here. We could // be giving back positions now unrelated to the call...but it won't crash! // REBARR *Make_Where_For_Frame(struct Reb_Frame *frame) { REBCNT start; REBCNT end; REBARR *where; REBOOL pending; if (FRM_IS_VALIST(frame)) { const REBOOL truncated = TRUE; Reify_Va_To_Array_In_Frame(frame, truncated); } // WARNING: MIN is a C macro and repeats its arguments. // start = MIN(ARR_LEN(FRM_ARRAY(frame)), cast(REBCNT, frame->expr_index)); end = MIN(ARR_LEN(FRM_ARRAY(frame)), FRM_INDEX(frame)); assert(end >= start); assert(frame->mode != CALL_MODE_GUARD_ARRAY_ONLY); pending = NOT(frame->mode == CALL_MODE_FUNCTION); // Do a shallow copy so that the WHERE information only includes // the range of the array being executed up to the point of // currently relevant evaluation, not all the way to the tail // of the block (where future potential evaluation would be) { REBCNT n = 0; REBCNT len = 1 // fake function word (compensates for prefetch) + (end - start) // data from expr_index to the current index + (pending ? 1 : 0); // if it's pending we put "..." to show that where = Make_Array(len); // !!! Due to "prefetch" the expr_index will be *past* the invocation // of the function. So this is a lie, as a placeholder for what a // real debug mode would need to actually save the data to show. // If the execution were a path or anything other than a word, this // will lose it. // Val_Init_Word(ARR_AT(where, n), REB_WORD, FRM_LABEL(frame)); ++n; for (n = 1; n < len; ++n) *ARR_AT(where, n) = *ARR_AT(FRM_ARRAY(frame), start + n - 1); SET_ARRAY_LEN(where, len); TERM_ARRAY(where); } // Making a shallow copy offers another advantage, that it's // possible to get rid of the newline marker on the first element, // that would visually disrupt the backtrace for no reason. // if (end - start > 0) CLEAR_VAL_FLAG(ARR_HEAD(where), VALUE_FLAG_LINE); // We add an ellipsis to a pending frame to make it a little bit // clearer what is going on. If someone sees a where that looks // like just `* [print]` the asterisk alone doesn't quite send // home the message that print is not running and it is // argument fulfillment that is why it's not "on the stack" // yet, so `* [print ...]` is an attempt to say that better. // // !!! This is in-band, which can be mixed up with literal usage // of ellipsis. Could there be a better "out-of-band" conveyance? // Might the system use colorization in a value option bit. // if (pending) Val_Init_Word(Alloc_Tail_Array(where), REB_WORD, SYM_ELLIPSIS); return where; }
int main(int argc, char *argv[]) { FILE *output; Process_Arguments(argc,argv,Spec,0); #ifdef PROGRESS printf("\nParameters: c=%g e=%g s=%d\n", Get_Double_Arg("-c"),Get_Double_Arg("-e"),Get_Int_Arg("-s")); printf("SubFolder: %s\n",Get_String_Arg("folder")); printf("CoreName: %s\n",Get_String_Arg("core")); fflush(stdout); #endif RezFolder = strdup(Get_String_Arg("folder")); if (RezFolder[strlen(RezFolder)-1] == '/') RezFolder[strlen(RezFolder)-1] = '\0'; if (mkdir(RezFolder,S_IRWXU|S_IRWXG|S_IRWXO)) { if (errno != EEXIST) { fprintf(stderr,"Error trying to create directory %s: %s\n",RezFolder,strerror(errno)); exit (1); } } CoreName = strdup(Get_String_Arg("core")); sprintf(NameBuf,"%s.neu",CoreName); output = fopen(NameBuf,"w"); fprintf(output,"NEUSEP: Version 0.9\n"); { Histogram *hist; int curchan; int maxchans; int i, n; n = Get_Repeat_Count("inputs"); fwrite(&n,sizeof(int),1,output); hist = Make_Histogram(UVAL,0x10000,VALU(1),VALU(0)); maxchans = 0; for (i = 0; i < n; i++) { curchan = NumChans; maxchans = Read_All_Channels(Get_String_Arg("inputs",i),maxchans); int channelsInCurrentFile=NumChans-curchan; { Size_Type sum, max; Indx_Type p; int j, wch; uint16 *val; max = -1; for (j = curchan; j < NumChans; j++) { val = AUINT16(Images[j]); sum = 0; for (p = 0; p < Images[j]->size; p++) sum += val[p]; if (sum > max) { max = sum; wch = j; } } fprintf(output,"%s\n",Get_String_Arg("inputs",i)); j = wch-curchan; fwrite(&j,sizeof(int),1,output); #ifdef PROGRESS printf("\n Eliminating channel %d from %s\n",j+1,Get_String_Arg("inputs",i)); fflush(stdout); #endif { // Section to write out the reference channel printf("\n Considering reference channel output, channelsInCurrentFile=%d\n", channelsInCurrentFile); fflush(stdout); if (channelsInCurrentFile>2) { // should work with both lsm pair with channels=3, or raw file with channels=4 sprintf(NameBuf,"%s/Reference.tif",RezFolder,CoreName,i); Write_Image(NameBuf,Images[wch],LZW_PRESS); } } Free_Array(Images[wch]); NumChans -= 1; for (j = wch; j < NumChans; j++) Images[j] = Images[j+1]; } { int j, ceil; Indx_Type p; uint16 *val; for (j = curchan; j < NumChans; j++) { Histagain_Array(hist,Images[j],0); ceil = Percentile2Bin(hist,1e-5); if (ceil==0) { fprintf(stderr, "Channel must have non-zero values for this program to function\n"); exit(1); } #ifdef PROGRESS printf(" Clipping channel %d at ceil = %d\n",j,ceil); fflush(stdout); fflush(stdout); #endif val = AUINT16(Images[j]); for (p = 0; p < Images[j]->size; p++) { if (val[p] > ceil) val[p] = ceil; val[p] = (val[p]*4095)/ceil; } // Convert_Array_Inplace(Images[j],PLAIN_KIND,UINT8_TYPE,8,0); } } } Free_Histogram(hist); printf("Starting ConsolidatedSignal.tif section\n"); fflush(stdout); // NA addition: write tif with re-scaled intensities to serve as basis for mask file { Array *signalStack; signalStack = Make_Array(RGB_KIND,UINT8_TYPE,3,Images[0]->dims); uint8 *sp=AUINT8(signalStack); int m; Indx_Type signalIndex; signalIndex=0; for (m=0;m<NumChans;m++) { sprintf(NameBuf, "%s/Signal_%d.tif", RezFolder, m); printf("Writing 16-bit channel file %s...", NameBuf); Write_Image(NameBuf, Images[m], LZW_PRESS); printf("done\n"); uint16 *ip=AUINT16(Images[m]); Indx_Type channelIndex; for (channelIndex=0;channelIndex<Images[m]->size;channelIndex++) { int value=ip[channelIndex]/16; if (value>255) { value=255; } sp[signalIndex++]=value; // convert 12-bit to 8-bit } } sprintf(NameBuf,"%s/ConsolidatedSignal.tif", RezFolder); printf("Writing 8-bit consolidated signal file %s...", NameBuf); Write_Image(NameBuf,signalStack,LZW_PRESS); printf("done"); //Free_Array(signalStack); - this is causing a bug } printf("Finished ConsolidatedSignal.tif section\n"); fflush(stdout); } { int i; Segmentation *segs; Overlaps *ovl; Clusters *clust; int numneur; Region **neurons; segs = (Segmentation *) Guarded_Malloc(sizeof(Segmentation)*NumChans,Program_Name()); for (i = 0; i < NumChans; i++) { Segment_Channel(Images[i],segs+i); if (i == 0) segs[i].base = 0; else segs[i].base = segs[i-1].base + segs[i-1].nsegs; printf("channel=%d segmentBase=%d\n", i, segs[i].base); } ovl = Find_Overlaps(segs); clust = Merge_Segments(segs,ovl); neurons = Segment_Clusters(segs,ovl,clust,&numneur); if (Is_Arg_Matched("-gp")) Output_Clusters(segs,ovl,clust); if (Is_Arg_Matched("-nr")) Output_Neurons(numneur,neurons,1); // Added for NA Output_Consolidated_Mask(numneur,neurons,1); fwrite(&numneur,sizeof(int),1,output); for (i = 0; i < numneur; i++) Write_Region(neurons[i],output); #ifdef PROGRESS printf("\nProduced %d neurons/fragments in %s.neu\n",numneur,CoreName); fflush(stdout); #endif printf("DEBUG: starting cleanup\n"); fflush(stdout); for (i = 0; i < numneur; i++) { printf("DEBUG: calling Kill_Region on neuron=%d\n", i); fflush(stdout); Kill_Region(neurons[i]); } printf("DEBUG: calling Kill_Clusters\n"); fflush(stdout); Kill_Clusters(clust); printf("DEBUG: calling Kill_Overlaps\n"); fflush(stdout); //Kill_Overlaps(ovl); - causing a bug printf("DEBUG: starting Kill_Segmentation loop\n"); fflush(stdout); for (i = 0; i < NumChans; i++) { printf("DEBUG: Kill_Segmentation on index=%d\n", i); fflush(stdout); Kill_Segmentation(segs+i); } printf("DEBUG: calling free() on segs\n"); fflush(stdout); free(segs); } printf("DEBUG: starting filestream cleanup\n"); fflush(stdout); { int i; fclose(output); free(CoreName); free(RezFolder); for (i = 0; i < NumChans; i++) Kill_Array(Images[i]); free(Images); } #ifdef VERBOSE printf("\nDid I free all arrays?:\n"); Print_Inuse_List(stdout,4); #endif exit (0); }
*/ REBSER *Struct_To_Block(const REBSTU *stu) /* ** Used by MOLD to create a block. ** ***********************************************************************/ { REBSER *ser = Make_Array(10); struct Struct_Field *field = (struct Struct_Field*) SERIES_DATA(stu->fields); REBCNT i; // We are building a recursive structure. So if we did not hand each // sub-series over to the GC then a single Free_Series() would not know // how to free them all. There would have to be a specialized walk to // free the resulting structure. Hence, don't invoke the GC until the // root series being returned is done being used or is safe from GC! MANAGE_SERIES(ser); for(i = 0; i < SERIES_TAIL(stu->fields); i ++, field ++) { REBVAL *val = NULL; REBVAL *type_blk = NULL; /* required field name */ val = Alloc_Tail_Array(ser); Val_Init_Word_Unbound(val, REB_SET_WORD, field->sym); /* required type */ type_blk = Alloc_Tail_Array(ser); Val_Init_Block(type_blk, Make_Array(1)); val = Alloc_Tail_Array(VAL_SERIES(type_blk)); if (field->type == STRUCT_TYPE_STRUCT) { REBVAL *nested = NULL; DS_PUSH_NONE; nested = DS_TOP; Val_Init_Word_Unbound(val, REB_WORD, SYM_STRUCT_TYPE); get_scalar(stu, field, 0, nested); val = Alloc_Tail_Array(VAL_SERIES(type_blk)); Val_Init_Block(val, Struct_To_Block(&VAL_STRUCT(nested))); DS_DROP; } else Val_Init_Word_Unbound(val, REB_WORD, type_to_sym[field->type]); /* optional dimension */ if (field->dimension > 1) { REBSER *dim = Make_Array(1); REBVAL *dv = NULL; val = Alloc_Tail_Array(VAL_SERIES(type_blk)); Val_Init_Block(val, dim); dv = Alloc_Tail_Array(dim); SET_INTEGER(dv, field->dimension); } /* optional initialization */ if (field->dimension > 1) { REBSER *dim = Make_Array(1); REBCNT n = 0; val = Alloc_Tail_Array(ser); Val_Init_Block(val, dim); for (n = 0; n < field->dimension; n ++) { REBVAL *dv = Alloc_Tail_Array(dim); get_scalar(stu, field, n, dv); } } else { val = Alloc_Tail_Array(ser); get_scalar(stu, field, 0, val); } } return ser; }
// // RL_Make_Block: C // // Allocate a series suitable for storing Rebol values. This series // can be used as a backing store for a BLOCK!, but also for any // other Rebol Array type (GROUP!, PATH!, GET-PATH!, SET-PATH!, or // LIT-PATH!). // // Returns: // A pointer to a block series. // Arguments: // size - the length of the block. The system will add one extra // for the end-of-block marker. // Notes: // Blocks are allocated with REBOL's internal memory manager. // Internal structures may change, so NO assumptions should be made! // Blocks are automatically garbage collected if there are // no references to them from REBOL code (C code does nothing.) // However, you can lock blocks to prevent deallocation. (?? default) // RL_API REBSER *RL_Make_Block(u32 size) { REBARR * array = Make_Array(size); MANAGE_ARRAY(array); return ARR_SERIES(array); }
void Segment_Channel(Array *input, Segmentation *seg) { double mean, sdev; int threshc, threshe, sizemin; Array *labels; Histogram *hist = Histogram_Array(input,0x100,VALU(1),VALU(0)); mean = Histogram_Mean(hist); sdev = Histogram_Sigma(hist); threshc = mean + Get_Double_Arg("-c")*sdev; threshe = mean + Get_Double_Arg("-e")*sdev; sizemin = Get_Int_Arg("-s"); #ifdef PROGRESS printf("\nChannel Segmentation:\n"); printf(" Mean = %.2f Std.Dev = %.2f\n",mean,sdev); printf(" Thresh-c = %d Thresh-e = %d Size-s = %d\n",threshc,threshe,sizemin); #ifdef DEBUG Print_Histogram(hist,stdout,4,BIN_COUNT|CUMULATIVE_COUNT|CLIP_HGRAM,0); #endif fflush(stdout); #endif Free_Histogram(hist); labels = Make_Array(PLAIN_KIND,UINT8_TYPE,3,input->dims); Array_Op_Scalar(labels,SET_OP,UVAL,VALU(0)); SEG_threshc = threshc; SEG_threshe = threshe; SEG_sizemin = sizemin; SEG_values = AUINT16(input); SEG_labels = AUINT8(labels); SEG_count = 0; SEG_coretouch = 0; SEG_id = 0; // Mark connected-components of pixels >= threshc that have not less than sizemin pixels Flood_All(input,0,ISCON2N,NULL,InCore,NULL,CountCore,NULL,GoodCore,NULL,MarkAsIn); // Mark all connected components of pixels >= threshe that contain a good core as above Flood_All(input,0,ISCON2N,NULL,InExtend,NULL,TouchCore,NULL,GoodExtend,NULL,SetLabel); // Capture each labeled region in "labels" with a Region { int i, nsegs; Indx_Type p; uint8 *val; Region **segs; seg->label = labels; seg->nsegs = nsegs = SEG_id; seg->segs = segs = (Region **) Guarded_Malloc(sizeof(Region *)*nsegs,Program_Name()); seg->mean = mean; seg->ethresh = threshe; seg->cthresh = threshc; for (i = 0; i < nsegs; i++) segs[i] = NULL; val = AUINT8(labels); for (p = 0; p < labels->size; p++) { i = val[p]; if (i > 0 && segs[i-1] == NULL) segs[i-1] = Record_Basic(labels,0,ISCON2N,p,1,EQ_COMP,VALU(i)); } } }
void Output_Consolidated_Mask(int numneur, Region **neurons, int do_brighten) { printf("Starting Output_Consolidated_Mask\n"); fflush(stdout); Array *mask,*stack; int i, k; Indx_Type mp,sp; uint8 *m; uint16 *s; mask = Make_Array(PLAIN_KIND,UINT8_TYPE,3,Images[0]->dims); stack = Make_Array(RGB_KIND,UINT16_TYPE,3,Images[0]->dims); m=AUINT8(mask); s=AUINT16(stack); printf("ConsolidatedMask mask size=%d\n", mask->size); printf("ConsolidatedMask stack size=%d\n", stack->size); fflush(stdout); for (i = 0; i < numneur; i++) { if (i<256) { for (k = 0; k < NumChans; k++) { Array_Bundle plane = *stack; Draw_Region_Image(Get_Array_Plane(&plane,k%3),Images[k],neurons[i]); } int count=0; for (mp=0;mp<mask->size;mp++) { if (s[mp]>0 || s[mp+mask->size]>0 || s[mp+(mask->size * 2)]>0) { count++; m[mp]=i+1; } } printf("For neuron %d, added %d label points\n", i, count); fflush(stdout); // Clear stack for (sp=0;sp<stack->size;sp++) { s[sp]=0; } } else { printf("Can only handle 256 neurons with 8-bit label - skipping neuron %d\n", i); fflush(stdout); } } sprintf(NameBuf,"%s/ConsolidatedLabel.tif", RezFolder); Write_Image(NameBuf,mask,LZW_PRESS); Kill_Array(mask); Kill_Array(stack); printf("Finished Output_Consolidated_Mask\n"); fflush(stdout); }