// process a single acquisition int RtRoiDifference::process(ACE_Message_Block *mb) { ACE_TRACE(("RtRoiDifference::process")); RtStreamMessage *msg = (RtStreamMessage*) mb->rd_ptr(); cout << "PROCESSING " << endl; // find the data with the right data IDs RtActivation *posact = (RtActivation*) msg->getData(posRoiModuleID, posRoiDataName, posRoiRoiID); RtActivation *negact = (RtActivation*) msg->getData(negRoiModuleID, negRoiDataName, negRoiRoiID); double p = 0; if(posact != NULL) { p = posact->getPixel(0); } double n = 0; if(negact != NULL) { n = negact->getPixel(0); } // create a one element activation image RtActivation *diff = new RtActivation(1); // setup the data id diff->getDataID().setFromInputData(*posact,*this); diff->getDataID().setDataName(NAME_ROIDIFF); diff->getDataID().setRoiID(posRoiRoiID + "-" + negRoiRoiID); // compute the difference diff->setPixel(0, p - n); setResult(msg, diff); return 0; }
// process a single acquisition int RtCurrentActivation::process(ACE_Message_Block *mb) { ACE_TRACE(("RtCurrentActivation::process")); timer tim; if(printTiming) { tim.start(); } // get pointer to message RtStreamMessage *msg = (RtStreamMessage*) mb->rd_ptr(); // get the current image to operate on RtMRIImage *dat = (RtMRIImage*) msg->getCurrentData(); // check for validity of data if (dat == NULL) { cerr << "RtCurrentActivation::process: data passed is NULL" << endl; if(logOutput) { stringstream logs(""); logs << "RtCurrentActivation::process: data passed is NULL" << endl; log(logs); } return 0; } // get mask from msg RtMaskImage *mask = getMaskFromMessage(*msg); // check validity of mask if (mask == NULL) { cerr << "RtCurrentActivation::process: mask is NULL" << endl; if(logOutput) { stringstream logs(""); logs << "RtCurrentActivation::process: mask is NULL at tr " << dat->getDataID().getTimePoint() << endl; log(logs); } return 0; } // initialize the computation if necessary if (needsInit) { initEstimation(*dat, mask); } // get design // TODO this may not work if there are more than one design matrix RtDataID tempDataID; tempDataID.setDataName(NAME_DESIGN); // debug // getDataStore().getAvailableData(); RtDesignMatrix *design = static_cast<RtDesignMatrix*>( getDataStore().getData(tempDataID)); if(design == NULL) { cerr << "error: could not find design matrix in datastore!" << endl; cerr << "searched for design matrix id: " << tempDataID << endl; return 0; } // allocate a new data image for the stats RtActivation *currentActivation = new RtActivation(*dat); // setup the data id currentActivation->getDataID().setFromInputData(*dat, *this); currentActivation->getDataID().setDataName(NAME_ACTIVATION); currentActivation->getDataID().setRoiID(modelFitRoiID); currentActivation->initToNans(); // get the residual and the beta images for discounting nuissance // signals // find the betas RtActivation **betas = new RtActivation*[design->getNumColumns()]; for(unsigned int j = 0; j < design->getNumColumns(); j++) { betas[j] = (RtActivation*) msg->getData(modelFitModuleID, string(NAME_BETA) + "_" + design->getColumnName(j), modelFitRoiID); // check for found if (betas[j] == NULL) { cerr << "RtCurrentActivation:process: beta " << j << " is null" << endl; if(logOutput) { stringstream logs(""); logs << "RtCurrentActivation::process: beta " << j << " is NULL at tr " << dat->getDataID().getTimePoint() << endl; log(logs); } return 0; } } // get residual from message if timepoint is less than // numDataPointsForErrEst otherwise use the steady state // residual value RtActivation *residual; if (dat->getDataID().getTimePoint() < numDataPointsForErrEst) { // get residual off of msg residual = (RtActivation *) msg->getData(modelFitModuleID, NAME_RESIDUAL_MSE, modelFitRoiID); // save off residual steadyStateResidual = residual; } else { // post-numDataPointsForErrEst, use saved residual residual = steadyStateResidual; } // check that residual is not null if (residual == NULL) { cerr << "RtCurrentActivation:process: residual is null" << endl; if(logOutput) { stringstream logs(""); logs << "RtCurrentActivation::process: residual is NULL at tr " << dat->getDataID().getTimePoint() << endl; log(logs); } return 0; } // get this design matrix row vnl_vector<double> Xrow = design->getRow(dat->getDataID().getTimePoint()-1); // include this timepoint for each voxel RtElementAccess datAc(dat, mask); RtElementAccess resAc(residual, mask); vector<unsigned int> inds = datAc.getElementIndices(); for(vector<unsigned int>::iterator it = inds.begin(); it != inds.end(); it++) { // get voxel intensity double y = datAc.getDoubleElement(*it); double *betavals = new double[Xrow.size()]; // compute error double err = y; for (unsigned int j = 0; j < Xrow.size(); j++) { if (!design->isColumnOfInterest(j)) { double beta = betas[j]->getPixel(*it); err -= beta * Xrow[j]; betavals[j] = beta; } else { // for debug output betavals[j] = betas[j]->getPixel(*it); } } // compute the dev and current activation (magic happens here) double dev = sqrt(resAc.getDoubleElement(*it) / (residual->getDataID().getTimePoint())); currentActivation->setPixel(*it, err / dev); if (dumpAlgoVars && dat->getDataID().getTimePoint() > 2) { dumpFile << dat->getDataID().getTimePoint() << " " << *it << " " << y << " " << err << " " << Xrow[0] << " " << residual->getPixel(*it) << " " << dev << " " << currentActivation->getPixel(*it) << " "; for (unsigned int b = 0; b < design->getNumColumns(); b++) { dumpFile << betavals[b] << " "; } dumpFile << endl; } delete [] betavals; } setResult(msg, currentActivation); setResult(msg, residual); delete [] betas; if(printTiming) { tim.stop(); cout << "RtCurrentActivation process at tr " << dat->getDataID().getTimePoint() << " elapsed time: " << tim.elapsed_time()*1000 << "ms" << endl; } if(print) { cout << "RtCurrentActivation: done at tr " << dat->getDataID().getTimePoint() << endl; } if(logOutput) { stringstream logs(""); logs << "RtCurrentActivation: done at tr " << dat->getDataID().getTimePoint() << endl; log(logs); } if(saveResult) { string fn = getExperimentConfig().getVolFilename( dat->getDataID().getSeriesNum(), dat->getDataID().getTimePoint()); string stem = getExperimentConfig().get("study:volumeFileStem").str(); currentActivation->setFilename(fn.replace(fn.rfind(stem), stem.size(), "curact")); currentActivation->save(); } return 0; }
// process a single acquisition int RtSingleImageCor::process(ACE_Message_Block *mb) { ACE_TRACE(("RtSingleImageCor::process")); RtStreamMessage *msg = (RtStreamMessage*) mb->rd_ptr(); // get the current image to operate on RtMRIImage *dat = (RtMRIImage*) msg->getCurrentData(); if (dat == NULL) { cout << "RtSingleImageCor::process: data passed is NULL" << endl; ACE_DEBUG((LM_INFO, "RtSingleImageCor:process: data passed is NULL\n")); return 0; } RtMaskImage *mask = getMaskFromMessage(*msg); numTimepoints++; // initialize the computation if necessary if (needsInit) { initEstimation(*dat, mask); } // allocate a new data images for the stats RtActivation *stat = new RtActivation(*dat); // setup the data id stat->getDataID().setFromInputData(*dat, *this); stat->getDataID().setDataName(NAME_ACTIVATION); stat->getDataID().setRoiID(mask->getDataID().getRoiID()); stat->initToZeros(); // residual sum of squares map RtActivation *res = new RtActivation(*dat); // setup the data id res->getDataID().setFromInputData(*dat, *this); res->getDataID().setDataName(NAME_RESIDUAL_MSE); res->getDataID().setRoiID(mask->getDataID().getRoiID()); res->initToZeros(); //// element independent setup /// build a design matrix row vnl_vector<double> Xrow = design.getRow(dat->getDataID().getTimePoint()); bool anyOverZero = false; for (unsigned int i = 0; i < design.getNumColumns(); i++) { // check for on condition for any stimulus if (design.isColumnOfInterest(i) && Xrow[i] > std::numeric_limits<double>::epsilon()) { anyOverZero = true; break; } } if (DEBUG_LEVEL & MODERATE) { cout << " xrow " << numTimepoints << ":"; for (unsigned int i = 0; i < Xrow.size(); i++) { cout << Xrow[i] << " "; } cout << endl; } // check if we should include this timepoint in variance computation bool includeInErr; if ((numTimepoints > numDataPointsForErrEst) || (onlyEstErrInBaseline && anyOverZero)) { includeInErr = false; } else { includeInErr = true; numDataPointsCount++; } //// compute t map for each element RtElementAccess elAc(dat, mask); vector<unsigned int> indices = elAc.getElementIndices(); unsigned int curSolver = 0; for (vector<unsigned int>::iterator i = indices.begin(); i != indices.end(); i++, curSolver++) { if (!mask->getPixel(*i)) { stat->setPixel(*i, numeric_limits<double>::quiet_NaN()); // assign nan res->setPixel(*i, numeric_limits<double>::quiet_NaN()); // assign nan continue; } // include this timepoint in the solver for this voxel double y = dat->getElement(*i); solvers[curSolver]->include(&y, Xrow.data_block(), 1.0); // get stats and residual double *beta = solvers[curSolver]->regress(0); // note that residual is always the standard L2 version, despite which // norm we are using for the stat scaling res->setPixel(*i, sqrt(solvers[curSolver]->getTotalSquaredError(0) / (numTimepoints - 1))); // compute stat double err = y; double meanCondActivity = 0; for (unsigned int j = 0; j < Xrow.size(); j++) { if (!design.isColumnOfInterest(j)) { err -= beta[j] * Xrow[j]; } else { meanCondActivity += beta[j] * Xrow[j]; } } if (DEBUG_LEVEL & ADVANCED) { static double lastErr = 0; cerr << *i << ": err is " << err << " ?= " << sqrt(solvers[curSolver]->getTotalSquaredError(0)) - lastErr << endl; lastErr = sqrt(solvers[curSolver]->getTotalSquaredError(0)); } // update the error in the estimate for the voxel // get estimation error and compute the standard deviation based on // the error sum and current error norm and include the error in the // estimate if desired double dev; switch (errorNorm) { case L1: if (includeInErr) { estErrSum->setPixel(*i, estErrSum->getPixel(*i) + fabs(err)); } dev = estErrSum->getPixel(*i) / (numDataPointsCount - 1); break; case L2: default: if (includeInErr) { estErrSum->setPixel(*i, estErrSum->getPixel(*i) + err * err); } dev = sqrt(estErrSum->getPixel(*i) / (numDataPointsCount - 1)); break; case LINF: if (includeInErr) { estErrSum->setPixel(*i, std::max(estErrSum->getPixel(*i), fabs(err))); } dev = estErrSum->getPixel(*i); break; } if (DEBUG_LEVEL & ADVANCED) { cerr << dev << " ?= " << sqrt(solvers[curSolver]->getTotalSquaredError(0) / (numTimepoints - 1)) << endl; } // compute the sds away from the mean (magic kinda happens here) if (includeConditionMean) { stat->setPixel(*i, (meanCondActivity + err) / dev); } else { stat->setPixel(*i, (meanCondActivity) + (err / dev)); } if (DEBUG_LEVEL & ADVANCED) { cerr << numTimepoints << " " << *i << " " << y << " " << err + meanCondActivity << " " << err << " " << dev << " " << stat->getPixel(*i) << " " << endl; } if (DEBUG_LEVEL & MODERATE) { cerr << err << "/" << dev << "=" << stat->getPixel(*i) << endl; } if (numTimepoints > 2) { dumpFile << numTimepoints << " " << *i << " " << y << " " << err + meanCondActivity << " " << Xrow[0] << " " << err << " " << dev << " " << stat->getPixel(*i) << " "; for (unsigned int b = 0; b < design.getNumColumns(); b++) { dumpFile << beta[b] << " "; } dumpFile << endl; } delete beta; } if (DEBUG_LEVEL & BASIC) { cout << "done processing single image correlation at "; printNow(cout); cout << endl; } // set the results setResult(msg, stat); setResult(msg, res); return 0; }