int IEVChannelSumGadget::process(GadgetContainerMessage< ISMRMRD::ImageHeader>* m1) { GadgetContainerMessage<hoNDArray< float > > *unfiltered_unwrapped_msg_ptr = AsContainerMessage<hoNDArray<float>>(m1->cont()); GadgetContainerMessage<hoNDArray< float > > *filtered_unwrapped_msg_ptr = AsContainerMessage<hoNDArray<float>>(unfiltered_unwrapped_msg_ptr->cont()); GadgetContainerMessage<ISMRMRD::MetaContainer> *meta; static int c=0; int e; int echo = m1->getObjectPtr()->contrast; float inv_echo_time; int echo_offset=yres*xres*num_ch*echo; if(!filtered_unwrapped_msg_ptr || !unfiltered_unwrapped_msg_ptr) { GERROR("Wrong types received in IEVChannelSumGadget. Filtered and unfiltered phase expected.\n"); return GADGET_FAIL; } meta = AsContainerMessage<ISMRMRD::MetaContainer>(filtered_unwrapped_msg_ptr->cont()); //float* filtered_phase_ptr= filtered_unwrapped_msg_ptr->getObjectPtr()->get_data_ptr(); m1->getObjectPtr()->channels=1; //yes? inv_echo_time=1/echoTimes[echo];//to avoid millions of divisions per slice memcpy(filtered_phase_ptr+echo_offset, filtered_unwrapped_msg_ptr->getObjectPtr()->get_data_ptr(), xres*yres*num_ch*sizeof(float)); for (int i = 0; i < xres*yres*num_ch; i++) freq_ptr[echo_offset+i] = filtered_phase_ptr[echo_offset+i]*inv_echo_time; hdr_ptr[echo]=*(m1->getObjectPtr()); if(meta) { meta->getObjectPtr()->append("StudyInstanceUID", studyInstanceUID.c_str());//may be in xml header, may not be, in that case put it in xml so it can get to dicom char TE[10]; sprintf(TE, "%f", echoTimes[echo]*1000); meta->getObjectPtr()->append("TE", TE); attributes[echo]=*(meta->getObjectPtr()); } unfiltered_unwrapped_msg_ptr->release();//all data have been copied if(echo==(numEchos-1)) { float* weights= new float[xres*yres*num_ch]; float** channel_weights= new float* [num_ch]; float* to_normalize = new float[xres*yres]; int ch; if(iev.value()==int(IEV::YES))//just to allow this to work without IEV/make it very easy to compare { #pragma omp parallel //expanded parallel --- to allow sample to be allocated once { float* sample = new float[numEchos]; int start = omp_get_thread_num()/omp_get_num_threads()*xres*yres*num_ch; int end = (omp_get_thread_num()+1)/omp_get_num_threads()*xres*yres*num_ch; for(int i =start; i <end; i++) { ///////// for(int j = 0; j < numEchos; j++) sample[j]=freq_ptr[i+j*xres*yres*num_ch]; //assuming all(6-10 at at time) pages can be held in memory, this isn't terrible weights[i]=stdev(sample, numEchos); //find standard deviation between echoes ///// } delete[] sample; } #pragma omp parallel for private(ch) for(ch = 0; ch < num_ch; ch++) { float* temp_array; channel_weights[ch]=&weights[ch*xres*yres]; medianFilter(channel_weights[ch], xres, yres); for (int i = 0; i < xres*yres; i++) { channel_weights[ch][i]=1/(channel_weights[ch][i]+FLT_MIN); //weight as inverse, } } for (int i = 0; i < xres*yres; i++) to_normalize[i] = 0; for(int ch=0; ch< num_ch; ch++) for (int i = 0; i < xres*yres; i++) { to_normalize[i]+=channel_weights[ch][i]; } for(int ch=0; ch< num_ch; ch++) for (int i = 0; i < xres*yres; i++) { channel_weights[ch][i]/=to_normalize[i]; //normalize weights } } else { #pragma omp parallel for private(ch) for(int ch=0; ch< num_ch; ch++) { channel_weights[ch]=&weights[ch*xres*yres]; for (int i = 0; i < xres*yres; i++) { channel_weights[ch][i]=1; } } } for(e=0; e<numEchos; e++) { hdr_ptr[e].channels=1; hdr_ptr[e].contrast=e; hdr_ptr[e].data_type = ISMRMRD::ISMRMRD_FLOAT;//GADGET_IMAGE_REAL_FLOAT; hdr_ptr[e].image_type = ISMRMRD::ISMRMRD_IMTYPE_PHASE;//There is no frequency image type hdr_ptr[e].slice= (hdr_ptr[e].image_index) % num_slices;//was hdr_ptr[e].image_index___-1_____) % num_slices before decrementor was added upstream if(output_phase.value()) { // GadgetContainerMessage<ISMRMRD::ImageHeader>* phase_hdr = new GadgetContainerMessage<ISMRMRD::ImageHeader>(hdr_ptr[e]); //*(phase_hdr->getObjectPtr()) =*(hdr_ptr[e]->getObjectPtr()); GadgetContainerMessage<hoNDArray< float > > *comb_phase_msg = new GadgetContainerMessage<hoNDArray< float > >(); phase_hdr->getObjectPtr()->image_series_index=series_id_offset+1; try{comb_phase_msg->getObjectPtr()->create(xres,yres);} catch (std::runtime_error &err){ GEXCEPTION(err,"Unable to create output image\n"); return GADGET_FAIL; } float* output_ptr=comb_phase_msg->getObjectPtr()->get_data_ptr(); phase_hdr->cont(comb_phase_msg); // for (int i = 0; i < xres*yres; i++) { output_ptr[i]=filtered_phase_ptr[e*xres*yres*num_ch+i]*channel_weights[0][i]; //instead of setting to 0 and adding first channel } for(int ch=1; ch< num_ch; ch++) for (int i = 0; i < xres*yres; i++) { output_ptr[i]+=filtered_phase_ptr[e*xres*yres*num_ch+xres*yres*ch+i]*channel_weights[ch][i];; //instead of setting to 0 and adding first channel } // if(meta) { GadgetContainerMessage<ISMRMRD::MetaContainer>* meta = new GadgetContainerMessage<ISMRMRD::MetaContainer>(attributes[e]); comb_phase_msg->cont(meta); } // if (this->next()->putq(phase_hdr) == -1) { m1->release(); GERROR("Unable to put collapsed images on next gadget's queue\n"); return GADGET_FAIL; } } if(output_LFS.value()) { // GadgetContainerMessage<ISMRMRD::ImageHeader>* freq_hdr=new GadgetContainerMessage<ISMRMRD::ImageHeader>(hdr_ptr[e]); //*(freq_hdr->getObjectPtr()) =*(hdr_ptr[e]->getObjectPtr()); GadgetContainerMessage<hoNDArray< float > > *comb_freq_msg = new GadgetContainerMessage<hoNDArray< float > >(); freq_hdr->getObjectPtr()->image_series_index=series_id_offset+output_phase.value()+1; try{comb_freq_msg->getObjectPtr()->create(xres,yres);} catch (std::runtime_error &err){ GEXCEPTION(err,"Unable to create output image\n"); return GADGET_FAIL; } float* output_ptr=comb_freq_msg->getObjectPtr()->get_data_ptr(); freq_hdr->cont(comb_freq_msg); freq_hdr->getObjectPtr()->image_type = 6; // for (int i = 0; i < xres*yres; i++) output_ptr[i]=freq_ptr[e*xres*yres*num_ch+i]*channel_weights[0][i]; //instead of setting to 0 and adding first channel for(int ch=1; ch< num_ch; ch++) for (int i = 0; i < xres*yres; i++) { output_ptr[i]+=freq_ptr[e*xres*yres*num_ch+xres*yres*ch+i]*channel_weights[ch][i]; } // if(meta) { GadgetContainerMessage<ISMRMRD::MetaContainer>* meta = new GadgetContainerMessage<ISMRMRD::MetaContainer>(attributes[e]); meta->getObjectPtr()->set(GADGETRON_DATA_ROLE, GADGETRON_IMAGE_FREQMAP); //*(meta->getObjectPtr())=*(attributes[e]->getObjectPtr()); comb_freq_msg->cont(meta); } // if (this->next()->putq(freq_hdr) == -1) { //m1->release(); GERROR("Unable to put collapsed images on next gadget's queue\n"); return GADGET_FAIL; } } } delete[] to_normalize; delete[] weights; delete[] channel_weights; //if(output.value()==int(OUTPUT::PHASE)) // delete[] unfiltered_phase_ptr; } return GADGET_OK; }