// // XSPEC12 November 2003 // // #include #include #include #include #include #include #include #include #include int XSGlobal::xsDelcomp(ClientData cdata,Tcl_Interp* tclInterp,int objc, Tcl_Obj* CONST objv[]) { using XSContainer::models; static RangePair prevRange(1,1); string cmd = string(static_cast(cdata)); if ( objc == 1 ) { XSGlobal::printDocs(static_cast(cdata),"?"); return globalData->autoSave(TCL_OK); } else { const string arg(Tcl_GetString(objv[1])); if ( arg[0] == '?') { XSGlobal::printDocs(static_cast(cdata),"?"); return globalData->autoSave(TCL_OK); } else { string modelName; string rangeStr; // This command is set up to handle only one range, so anything beyond // the first arg (or first comma in first arg) is ignored. string::size_type colPos = arg.find(':'); if (colPos != string::npos) { modelName = arg.substr(0,colPos); rangeStr = arg.substr(colPos+1); } else rangeStr = arg; string::size_type commaPos = rangeStr.find(','); if (commaPos != string::npos) rangeStr = rangeStr.substr(0, commaPos); try { // only 1 range arg in this case StringArray inputArgs(1,rangeStr); std::vector modelsToBeEdited (models->lookupModelGroup(modelName)); const size_t N = modelsToBeEdited.size(); if (!N) { string msg; if ( modelName.length()) { msg = string("Model not defined: "); msg += modelName; } else msg = string("Unnamed model not defined"); throw YellowAlert (msg); } if (!modelName.length()) modelName = Model::DEFAULT(); const size_t numComponents = modelsToBeEdited[0]->numberOfComponents(); const RangePair limits(1,numComponents); // this can throw IntegerArray components = XSparse::getRanges(inputArgs,prevRange,limits); const size_t numComponentsToDelete = components.size(); if (numComponentsToDelete) { if(numComponentsToDelete >= numComponents) throw YellowAlert("Cannot remove all model components model. Use 'model clear' instead."); // Since only 1 range went into getRanges, components array must // be sequentially numbered, no gaps. Therefore we can keep // calling delete on the same componentNumber. const size_t componentNumber = components[0]; for (size_t i=0; ideleteComponent(componentNumber); } // force computation of the models just edited. XSContainer::models->setCompute(modelName); if (!modelsToBeEdited[0]->isActive()) { // For inactive models, need to initialize calculation // here since it won't be done through Fit::Update. std::vector remainingComps; modelsToBeEdited[0]->bundleComponents(remainingComps); for (size_t i=0; iinitializeForFit(); } modelsToBeEdited[0]->calculate(); } XSContainer::models->Notify(); for (size_t j = 0; j < N ; ++j) { tcout << *modelsToBeEdited[j] << std::endl; } } return globalData->autoSave(TCL_OK); } catch (YellowAlert&) { // deleteComponent will throw if the seek on componentNumber // fails, in which case the model will be unchanged. // will throw InvalidModelEdit if the model after deletion // of the component fails the context checks. return globalData->autoSave(TCL_ERROR); } } } }