Commit 76c80845 authored by Simone Liuzzo's avatar Simone Liuzzo

qempanel updated

parent 441f606a
function cor=qemcorrdt(qemres,kn,cor0)
function [cor,qemres]=qemcorrdt(qemres,kn,cor0)
%QEMCORRDT computes quad correction (rdt method)
% COR=QEMCORRDT(QEMRES,QERRORS,COR0)
% Q: quadrupole strengths
......@@ -7,25 +7,63 @@ function cor=qemcorrdt(qemres,kn,cor0)
% see also: QEMCOR, QEMCORFIT, QEMCORGRID
mach=qemres.at(:);
alpha_c = mcf(mach);
%RDT
disp('RDT derivative');
[respx,respz]=qemrdtresp(mach,qemres.bpmidx,[qemres.qpidx qemres.qcoridx]);
dkn=kn-atgetfieldvalues(mach(qemres.qpidx),'PolynomB',{2});
strength=[qemres.ql.*dkn;cor0];
fx=respx*strength;
fz=respz*strength;
warning('The quad disp deriv matrix should be copied where posible from the fit one, and recomputed only if cnecessary.')
if isfield(qemres,'quadhdispresponse')
rx=qemres.quadhdispresponse;
else
[rx,~]=qemdispderiv(mach,qemres.ct,@setk,1.e-3,...
[qemres.qcoridx],qemres.bpmidx); % h dispersion derivative resepct to quadrupoles
qemres.quadhdispresponse = rx;
end
function elem=setk(elem,dk)
k=elem.PolynomB(2)+dk;
elem.K=k;
elem.PolynomB(2)=k;
end
% dispersion
disp('h dispersion derivative');
frh = qemres.frespx;
[frh0,frv0]=qemfresp(mach,qemres.ct,qemres.bpmidx,[],[],[]); %#ok<ASGLU>
dfrh = alpha_c * (qemres.bhscale*frh-frh0);
a1 = qemres.hdispRDTcorWeight;
if a1 > 1 | a1<0
error('hor. dispersion weigth should be between 0 and 1');
end
disp('start correction');
if isfield(qemres,'qcorkeep')
qpmask=qemres.qcorkeep;
else
qpmask=true(size(qemres.qcoridx));
end
sk=[false(size(qemres.qpidx)) qpmask];
rsp=[...
real(respx(:,sk));imag(respx(:,sk));...
real(respz(:,sk));imag(respz(:,sk))];
(1-a1)*real(respx(:,sk));imag(respx(:,sk));...
(1-a1)*real(respz(:,sk));imag(respz(:,sk));...
a1*rx(:,qpmask)]; % dispersion
b=[...
real(fx);imag(fx);...
real(fz);imag(fz)];
(1-a1)*real(fx);imag(fx);...
(1-a1)*real(fz);imag(fz);...
a1*dfrh];
cor=cor0;
% cor(qpmask)=cor(qpmask)-rsp\b;
......
......@@ -18,7 +18,7 @@ function [dresp,drespskew,dDx_db,dDy_ds]=qemderivAnalytic(mach,dpp,elemfunc,dv,v
%RESP0: Response matrix of the unperturbed mchine on 1 column:
% [HRESPONSE(:);VRESPONSE(:);DFFRESPONSE;TUNES]
global NUMDIFPARAMS
global NUMDIFPARAMS qemres
dpsave=isfield(NUMDIFPARAMS,'DPStep');
if dpsave, dpsp=NUMDIFPARAMS.DPStep; end
......@@ -53,19 +53,7 @@ bndidx=sort(bndidx([1:4:end,4:4:end]));% only long part
dispfunc(1,3);
disp('ANALYTIC QEMPANEL Response AT2.0/errors_corrections')
% % get anlytical RM response
% [...
% dX_dq, dY_dq, ...
% dDx_dq, dDx_db, Dx, ...
% dXY_ds, dYX_ds, ...
% dDx_ds, dDy_ds...
% ]=CalcRespXXRespMat_thick_V2(...
% mach',dpp,...
% bpmidx',... % bpm
% hsidxlat,... % correctors
% varidx,... % quadrupoles
% bndidx',...% dipoles
% varidx); % quadrupoles
[...
dX_dq, dY_dq, ...
dDx_dq, ~, ~, ...
......@@ -80,6 +68,26 @@ disp('ANALYTIC QEMPANEL Response AT2.0/errors_corrections')
bndidx',... % no dipoles, later
varidx);
if isfield(qemres,'quadhdispresponse')
% do not recomput if already available
dDx_dq=qemres.quadhdispresponse;
dDy_ds=qemres.skewvdispresponse;
else
disp('FIRST and only h.disp derivative with respect to quadrupoles');
disp('computation starts on lattice without errors/correctors');
[dDx_dq,dDy_ds]=qemdispderiv(qemres(1).at,qemres.ct,@setk,1.e-3,...
[varidx],qemres.bpmidx,dispfunc); % h dispersion derivative resepct to quadrupoles
qemres.quadhdispresponse = dDx_dq;
qemres.skewvdispresponse = dDy_ds;
disp('finished. stored in qemres.quadhdispresponse')
end
function elem=setk(elem,dk)
k=elem.PolynomB(2)+dk;
elem.K=k;
elem.PolynomB(2)=k;
end
qind=find(atgetcells(mach,'Class','Quadrupole'))'; % response matrix computed always at all quadrupoles
quadforresponse=find(ismember(qind,varidx)); % quadrupoles to use for fit amoung all
......@@ -89,11 +97,11 @@ for iq=1:nq
ib = quadforresponse(iq); % use only selected quadrupoles
rha=dX_dq(:,:,ib);
rva=dY_dq(:,:,ib);
dxdqa=[-dDx_dq(:,ib);0;0]/dval(iq);% analytic, no tune dispersion derivative very different from
dxdqa=[dDx_dq(:,ib);0;0]/dval(iq);% analytic, no tune dispersion derivative very different from
dresp(:,iq)=[rha(:);rva(:);dxdqa];
rhsa=dXY_ds(:,:,ib);
rvsa=dYX_ds(:,:,ib);
dxdqsa=[-dDy_ds(:,ib)]/dval(iq);% analytic, no tune dispersion derivative very different from
dxdqsa=[dDy_ds(:,ib)]/dval(iq);% analytic, no tune dispersion derivative very different from
drespskew(:,iq)=[rhsa(:);rvsa(:);dxdqsa];
......
......@@ -16,7 +16,8 @@ if isempty(okfit), okfit=true(size(qemres.dipidx)); end
dfrh=qemres.bhscale*frh-frh0;
[dipresponse,~]=qemdispderivAnalytic(mach,qemres.dipidx,qemres.bpmidx);
bok=isfinite(dfrh)&okbpm;
% [dipresponseN,~]=qemdispderiv(mach,qemres.ct,@setbendangle,1.e-3,...
% qemres.dipidx,qemres.bpmidx);
dipdelta = qemsvd(dipresponse(bok,okfit),dfrh(bok),qemres.neigDipFit);
......
No preview for this file type
......@@ -22,7 +22,7 @@ function varargout = qempanel2(varargin)
% Edit the above text to modify the response to help qempanel2
% Last Modified by GUIDE v2.5 30-Jan-2019 15:19:12
% Last Modified by GUIDE v2.5 31-Jan-2019 12:33:12
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
......@@ -132,6 +132,8 @@ set(handles.PartialRMcheckbox,'Enable','off')
qemres.neigDipFit=str2double(handles.neigDipFit.String);
qemres.neigQuadFit=str2double(handles.neigQuadFit.String);
qemres.neigQuadRDTcor=str2double(handles.neigQuadRDTcor.String);
qemres.hdispRDTcorWeight = str2double(handles.hdispRDTcorWeight.String);
qemres.hdispWeigth = str2double(handles.hdispWeigth.String);
wrongbpms=qemres.wrongbpms; % find(bpmm.All_Status.read~=0)
[semres.resph,semres.respv]=semloadresp(qemres,semres,wrongbpms);
......@@ -207,7 +209,7 @@ function pushbutton7_Callback(hObject, eventdata, handles)
% handles structure with handles and user data (see GUIDATA)
global qemb qemres semres MACHFS
tnow=now();
measpath=fullfile(MACHFS,'MDT',datestr(tnow,'yyyy'),datestr(tnow,'mm_dd'));
measpath=fullfile(MACHFS,'MDT',datestr(tnow,'yyyy'),datestr(tnow,'yyyy_mm_dd'));
list=dir(fullfile(measpath,'resp*'));
namelist={list.name};
......@@ -457,11 +459,15 @@ if ~ok
if ischar(fname), corfile=fullfile(fpath,fname); ok=true; end
end
if ok
% qemwritecor(corfile,-qemb(2).cor(:,end));
% save_correction(corfile,qemres.qpcode,qemb(2).cor(:,end),qemres.opticsdir);
warning('quadrupole name list not generically working (does not inlcude DQ!)');
ebs.save_correction( corfile, ... filename
ebs.qpname(1:length(qemres.qcoridx)),... device names
qemb(2).cor(:,end)); % correction values
set(handles.pushbutton18,'Enable','On');
end
set(handles.statustext,'String','correction saved');
set(handles.statustext,'String',['correction saved in ' corfile]);
% --- Executes on button press in pushbutton17: Correction Load
function pushbutton17_Callback(hObject, eventdata, handles)
......@@ -507,9 +513,28 @@ function pushbutton18_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton18 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global qemres
warning('Correction Apply Disabled')
warning('add here quad strengths setting and resonances init, or similar to set them to zero.')
global qemres qemb
r = qemres(1).at; %atreduce(qemres(1).at);
all_quad_ind = find(atgetcells(r,'Class','Quadrupole') | atgetcells(r,'FamName','DQ\w*') )';
warning('will probably not work for correction using DQ! (splitted DQ in the model)')
all_quad_ind(diff(all_quad_ind)==2)=[]; % remove sliced magenets from list.
qind = ismember(all_quad_ind,qemres.qcoridx);
qcor = zeros(size(all_quad_ind)); % 610x1
qcor(qind) = qemb(2).cor(:,end);
qdev = tango.Device('srmag/m-q/all');
try
qdev.CorrectionStrengths = qcor;
set(handles.statustext,'String','correction applied');
catch err
disp(err);
set(handles.statustext,'String','correction NOT applied, probably too strong correctors.');
end
% bindir=[getenv('MACH_HOME') '/bin/' getenv('MACHARCH') '/'];
% corfile=fullfile(qemres.datadir, 'cornew.dat');
......@@ -714,7 +739,7 @@ function neigQuadRDTcor_Callback(hObject, eventdata, handles)
global qemres
qemres.neigQuadRDTcor = str2double(get(hObject,'String'));
if ~isempty(handles)
set(handles.statustext,'String',[ num2str(qemres.neigQuadFit) ' correction eigenvectors ']);
set(handles.statustext,'String',[ num2str(qemres.neigQuadRDTcor) ' correction eigenvectors ']);
end
......@@ -783,3 +808,58 @@ function neigDipFit_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function hdispRDTcorWeight_Callback(hObject, eventdata, handles)
% hObject handle to hdispRDTcorWeight (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of hdispRDTcorWeight as text
% str2double(get(hObject,'String')) returns contents of hdispRDTcorWeight as a double
global qemres
qemres.hdispRDTcorWeight = str2double(get(hObject,'String'));
if ~isempty(handles)
set(handles.statustext,'String',[ num2str(qemres.hdispRDTcorWeight) ' hdisp Weigth for correction ']);
end
% --- Executes during object creation, after setting all properties.
function hdispRDTcorWeight_CreateFcn(hObject, eventdata, handles)
% hObject handle to hdispRDTcorWeight (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function hdispWeigth_Callback(hObject, eventdata, handles)
% hObject handle to hdispWeigth (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of hdispWeigth as text
% str2double(get(hObject,'String')) returns contents of hdispWeigth as a double
global qemres
qemres.hdispWeigth = str2double(get(hObject,'String'));
if ~isempty(handles)
set(handles.statustext,'String',[ num2str(qemres.hdispWeigth) ' hdisp Weigth for fit ']);
end
% --- Executes during object creation, after setting all properties.
function hdispWeigth_CreateFcn(hObject, eventdata, handles)
% hObject handle to hdispWeigth (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
......@@ -32,39 +32,44 @@ mess={...
[' 2*NuX = 153 :' num2str(stpb.h153*1e3,'%2.2f')];...
[' 2*NuZ = 55 :' num2str(stpb.v55*1e3,'%2.2f')]};
if all(isfield(handles,{'axes2','axes3'})) % displays beta modulation
sbpm=cat(1,qemb.lindata.SPos);
qemmodulplot(handles.axes2, sbpm, modulh, '');hold on;
qemmodulplot(handles.axes2, sbpm, modulv, '');hold off;
legend('\beta_x','\beta_z')
% qemd(handles.axes2, sbpm, modulv, '\eta_x');
end
% if all(isfield(handles,{'axes2','axes3'})) % displays beta modulation
% sbpm=cat(1,qemb.lindata.SPos);
% qemmodulplot(handles.axes2, sbpm, modulh, '');hold on;
% qemmodulplot(handles.axes2, sbpm, modulv, '');hold off;
% legend('\beta_x','\beta_z')
%
% % qemd(handles.axes2, sbpm, modulv, '\eta_x');
% end
disp('qemstopbands msg');toc;
%%
if isfield(handles,'axes3') % displays horizontal dispersion
if isfield(qemres,'frespx')
plot(handles.axes3,sbpm,-qemb.pm.alpha*[qemb.frespx-qemb0.frespx...
qemres.bhscale*qemres.frespx-qemb0.frespx...
(qemb.frespx-qemb0.frespx)-(qemres.bhscale*qemres.frespx-qemb0.frespx)]);
else
plot(handles.axes3,sbpm,-qemb.pm.alpha*(qemb.frespx-qemb0.frespx));
end
title(handles.axes3,'Horizontal dispersion');
ax=axis(handles.axes3);
ym=max(abs(ax([3 4])));
axis(handles.axes3,[0 844.39 -ym ym]);
ylabel(handles.axes3,'\eta_x [m]');
grid(handles.axes3,'on');
legend(handles.axes3,'measured','fit','difference')
if all(isfield(handles,{'axes2','axes3'})) % displays beta modulation
sbpm=cat(1,qemb.lindata.SPos);
qemmodulplot(handles.axes2, sbpm, modulh, '\beta_x');
qemmodulplot(handles.axes3, sbpm, modulv, '\beta_z');
end
% if isfield(handles,'axes3') % displays horizontal dispersion
% if isfield(qemres,'frespx')
% plot(handles.axes3,sbpm,-qemb.pm.alpha*[qemb.frespx-qemb0.frespx...
% qemres.bhscale*qemres.frespx-qemb0.frespx...
% (qemb.frespx-qemb0.frespx)-(qemres.bhscale*qemres.frespx-qemb0.frespx)]);
% else
% plot(handles.axes3,sbpm,-qemb.pm.alpha*(qemb.frespx-qemb0.frespx));
%
% end
% title(handles.axes3,'Horizontal dispersion');
% ax=axis(handles.axes3);
% ym=max(abs(ax([3 4])));
% axis(handles.axes3,[0 844.39 -ym ym]);
% ylabel(handles.axes3,'\eta_x [m]');
% grid(handles.axes3,'on');
% legend(handles.axes3,'measured','fit','difference')
%
% end
% %% compare to simulator
% a=load('/operation/appdata/EbsSimulator/s28dseed1order12.mat','s28dseed1order12');
% rs=a.s28dseed1order12;
......
......@@ -55,6 +55,7 @@ dpp=o0(5);
%dresp=qemderivAnalyticDebuggingVersion(qemb.at,dpp,@setk,0.0001,qemres.qpidx(okfit),qemres.bpmidx,shidx,svidx,disparg{:});
dresp=qemderivAnalytic(qemb.at,dpp,@setk,0.0001,qemres.qpidx(okfit),qemres.bpmidx,shidx,svidx,disparg{:});
% % % lines for tests
%drespA=qemderivAnalytic(qemb.at,dpp,@setk,0.0001,qemres.qpidx(okfit),qemres.bpmidx,shidx,svidx,disparg{:});
%drespN= qemderiv(qemb.at,dpp,@setk,0.0001,qemres.qpidx(okfit),qemres.bpmidx,shidx,svidx,disparg{:});
......@@ -80,6 +81,7 @@ if ~isfield(mode,'vnorm')
% mode.vnorm=vv(okfit)';
end
mode.neigs=qemres.neigQuadFit;
mode.dispweight=qemres.hdispWeigth;
newkn=qemb.kn;
newkn(okfit)=qemb.kn(okfit)+qemerrfit(nhst,nvst,resp-resp0,dresp,mode,okbpm);
......
......@@ -25,8 +25,11 @@ qemres.datadir=dirname;
qemres.opticsdir=fullfile(dirname,'optics','');
[~,theodir]=system(['readlink ' fullfile(dirname,'optics','')]);
qemres.opticsname = theodir;
a=load(fullfile(qemres.opticsdir,'betamodel.mat'),'betamodel');
atmod=ebs.model(a.betamodel);
a=load(fullfile(qemres.opticsdir,'betamodel.mat'),'betamodel');
ring= a.betamodel;
%atmod=ebs.model(ring,'reduce',true); % removing splitted magnets not allowed, due to pinhole data!
atmod=ebs.model(ring);
warning('HARD CODED NUMBERS! NOT GOOD! 288 h steerers instead of 384!')
if full_partial
......@@ -100,7 +103,8 @@ qemres.dpp=syncorb(5,1);
[~,tunes]=atlinopt(qemres.at,qemres.dpp);
qemres.fractunes=periods*tunes-fix(periods*tunes);
qemres.dipidx=find(atgetcells(atmod.ring,'FamName','[DJ]L[12][AE]_3','DQ1[B]','DQ2C_1'))';%,'DQ1[BD]' atmod.get(0,'di');
% qemres.dipidx=find(atgetcells(atmod.ring,'FamName','[DJ]L[12][AE]_3','DQ1[B]','DQ2C_1'))';%,'DQ1[BD]' atmod.get(0,'di');
qemres.dipidx=find(atgetcells(atmod.ring,'FamName','[DJ]L[12][AE]_[15]','ml_\w*'))';%,'DQ1[BD]' atmod.get(0,'di');
bang=atmod.getfieldvalue(qemres.dipidx,'BendingAngle');
qemres.dipidx=qemres.dipidx(bang>0.001);
%qemres.dipidx=qemres.dipidx(1);
......
......@@ -43,10 +43,10 @@ familyfilename=fullfile(dirname,'familymag.dat');
if exist(familyfilename,'file') == 0 % Select magnet file
% % generate, copy, erase setting
% famsave.GenerateSettingsFile({['FILE:' globalfilename ''],'AUTHOR: qempanel','COMMENTS: '});
% copyfile(fullfile(famsave.SettingsPath.read,[globalfilename '.ts']),quadfilename);
% copyfile(fullfile(famsave.SettingsPath.read,[globalfilename '.ts']),familyfilename);
% famsave.DeleteFile([globalfilename '.ts']);
% % save latest applied file
% save latest applied file
copyfile(fullfile(famsave.SettingsPath.read,[famsave.LastAppliedFile.read '.ts']),familyfilename);
end
......@@ -55,27 +55,27 @@ end
% save correction strenghts
quadfilename=fullfile(dirname,'quadcor.dat');
if exist(quadfilename,'file') == 0 % Select magnet file
% quasave.GenerateSettingsFile({['FILE:' globalfilename ''],'AUTHOR: qempanel','COMMENTS: '});
% copyfile(fullfile(quasave.SettingsPath.read,[globalfilename '.ts']),quadfilename);
% quasave.DeleteFile([globalfilename '.ts']);
copyfile(fullfile(quasave.SettingsPath.read,[quasave.LastAppliedFile.read '.ts']),quadfilename);
quasave.GenerateSettingsFile({['FILE:' globalfilename ''],'AUTHOR: qempanel','COMMENTS: '});
copyfile(fullfile(quasave.SettingsPath.read,[globalfilename '.ts']),quadfilename);
quasave.DeleteFile([globalfilename '.ts']);
% copyfile(fullfile(quasave.SettingsPath.read,[quasave.LastAppliedFile.read '.ts']),quadfilename);
end
skewfilename=fullfile(dirname,'skewcor.dat');
if exist(skewfilename,'file') == 0 % Select magnet file
% skwsave.GenerateSettingsFile({['FILE:' globalfilename ''],'AUTHOR: qempanel','COMMENTS: '});
% copyfile(fullfile(skwsave.SettingsPath.read,[globalfilename '.ts']),skewfilename);
% skwsave.DeleteFile([globalfilename '.ts']);
copyfile(fullfile(skwsave.SettingsPath.read,[skwsave.LastAppliedFile.read '.ts']),skewfilename);
skwsave.GenerateSettingsFile({['FILE:' globalfilename ''],'AUTHOR: qempanel','COMMENTS: '});
copyfile(fullfile(skwsave.SettingsPath.read,[globalfilename '.ts']),skewfilename);
skwsave.DeleteFile([globalfilename '.ts']);
% copyfile(fullfile(skwsave.SettingsPath.read,[skwsave.LastAppliedFile.read '.ts']),skewfilename);
end
sextfilename=fullfile(dirname,'sextcor.dat');
if exist(sextfilename,'file') == 0 % Select magnet file
% sxtsave.GenerateSettingsFile({['FILE:' globalfilename ''],'AUTHOR: qempanel','COMMENTS: '});
% copyfile(fullfile(sxtsave.SettingsPath.read,[globalfilename '.ts']),sextfilename);
% sxtsave.DeleteFile([globalfilename '.ts']);
copyfile(fullfile(sxtsave.SettingsPath.read,[sxtsave.LastAppliedFile.read '.ts']),sextfilename);
sxtsave.GenerateSettingsFile({['FILE:' globalfilename ''],'AUTHOR: qempanel','COMMENTS: '});
copyfile(fullfile(sxtsave.SettingsPath.read,[globalfilename '.ts']),sextfilename);
sxtsave.DeleteFile([globalfilename '.ts']);
% copyfile(fullfile(sxtsave.SettingsPath.read,[sxtsave.LastAppliedFile.read '.ts']),sextfilename);
end
octfilename=fullfile(dirname,'octcor.dat');
......@@ -90,11 +90,11 @@ end
steerfilename=fullfile(dirname,'steerers.dat');
if exist(steerfilename,'file') == 0 % Select magnet file
% strsave.GenerateSettingsFile({['FILE:' globalfilename ''],'AUTHOR: qempanel','COMMENTS: '});
% copyfile(fullfile(strsave.SettingsPath.read,[globalfilename '.ts']),steerfilename);
% strsave.DeleteFile([globalfilename '.ts']);
strsave.GenerateSettingsFile({['FILE:' globalfilename ''],'AUTHOR: qempanel','COMMENTS: '});
copyfile(fullfile(strsave.SettingsPath.read,[globalfilename '.ts']),steerfilename);
strsave.DeleteFile([globalfilename '.ts']);
copyfile(fullfile(strsave.SettingsPath.read,[strsave.LastAppliedFile.read '.ts']),steerfilename);
% copyfile(fullfile(strsave.SettingsPath.read,[strsave.LastAppliedFile.read '.ts']),steerfilename);
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment