c - Zuweisungen fuer 'dx5' und 'gridInFrontOfFoil' vielleicht besser in c 'geo_kammer.input' verlegen! c - Zuweisung fuer 'dx5' fuer Run10 ist noch zu pruefen! (15mm richtig?) c - bei Use_MUTRACK und use_ACCEL pruefen lassen, ob verwendete Geometrien c kompatibel sind (damit naechste Simulation wirklich dort weiterrechnet, c wo die andere aufgehoert hat (gegebenenfalls bei verschiedenen Runs c Bestaetigung einholen) c - bei 'createFoilFile' alle Schleifen die raeumlich nach der Triggerfolie c liegen auf 0,-1e10,1e10 (oder entsprechend) setzen, damit diese c ungenutzten Schleifen nur einmal durchlaufen werden! c - kann Text zwischen 'Marke 1' und 'Marke 2' nicht mit vorherigen Passagen c bzgl. des Triggerdetektors zusammengefasst werden? (Vielleicht nicht!) c------------------------------------------------------------------------------- OPTIONS /EXTEND_SOURCE SUBROUTINE read_inputFile c ========================= IMPLICIT NONE c Diese Subroutine liest das Eingabe-file 'MUTRACK.INPUT' und stellt c die Simulationsparameter fuer das Programm entsprechend ein. Die Parameter c befinden sich alle in einem COMMON-Block und sind so im gesamten Programm c vorhanden. c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c name-lists: c - /acVersion/: namelist /acVersion/ accelVersion c - /muVersion/: namelist /muVersion/ mutrackVersion,accelVersion c - /loop_params/: c diese Variablen sind zwar auch in der nameList /parameter_liste/ enthalten, c werden hier aber noch einmal separat gefuehrt fuer das Einlesen der c Schleifensettings von ACCEL bzw. vom 'foilfile': namelist /loop_params/ + U_Tgt_,U_Gua_,U_G1_,U_L1_,U_Sp_,U_L2_,U_Folie_, B_Helm_,B_TD_, + alfaTgt_,alfaSp_,alfaTD_,Masse_,Ladung_, + E0_,y0_,z0_,theta0_,phi0_,deltaL1_ c nur fuer das Einlesen aelterer foilFile-Versionen: + ,U_KL_ c - /parameter_liste/: c (Die Variablen c randomStarts_prevSim, artList_prevSim, c E0InterFromFile, UseDecay_prevSim, c c sind nicht fuer die Dateneinlesung aus MUTRACK.INPUT sondern werden fuer das c Einlesen der INFO-Files von ACCEL bzw. einer frueheren 'foilFile'-MUTRACK- c Rechnung benoetigt. 'useDecay_AH', 'artList_AH' und 'randomStarts_AH' sind c die Vorgaenger der jetztigen Variablen mit den 'prevSim'-Endungen und c und sind nur noch fuer das Einlesen aelterer Infofiles vorhanden. Sie koennen c in der Zukunft problemlos entfernt werden). namelist /parameter_liste/ + TestRun,Startflaeche,x0_,KammerTeil,alfaTgtVertically, + randomStarts,randomStarts_prevSim, random_energy,lowerE0,upperE0,sigmaE0, + random_position,StartBreite,StartHoehe,StartRadius,sigmaPosition, + random_winkel,StartLambertOrd,SigmaWinkel, + U_Tgt_,U_Gua_,U_G1_,U_L1_,U_Sp_,U_L2_,U_L3_,U_Folie_,U_Vorne_,U_Hinten_, + U_MCP3_,U_MCP2_,alfaTgt_,alfaSp_,alfaTD_, B_Helm_,B_TD_, Masse_,Ladung_, + E0_,y0_,z0_,theta0_,phi0_,thickness_,mean_Eloss_,deltaL1_,deltaL2_, + E0InterFromFile, + artList,artList_prevSim, + TriggerInBeam, n_aufstreu,sigmaAufstreu, + n_E_Verlust,calculate_each,sigmaE,lowerE,upperE,graphitData, + log_neutralize,neutral_fract,TransTDFoil,generate_FE, + GridInFrontOfFoil, + UseDecay, UseDecay_prevSim, TestOnWireHit, + previousSimulation,previousSettings, + fileName_ACCEL,fileName_Mutrack, + createFoilFile,upToTDFoilOnly, + Fo_triggered,xM2_triggered,M2_triggered, + idealMirror, + geo_filename,write_geo,xBlende,radius_Blende, + DEBUG,DEBUG_Anzahl, DEBUG_FE, + GRAPHICS,GRAPHICS_Anzahl, plot_FE, n_postSkript, iMonitor, + color,schnitt_x,schnitt_p,log_marker,vertical, + n_outWhere, + log_out_FE, log_out_pfosten, + SUM_S1xM2,SUM_S1M2,SUM_S1Fo,SUM_FoM2,SUM_S1M3,SUM_M3M2,SUM_t_FE, + SUM_y_Fo,SUM_z_Fo,SUM_r_Fo,SUM_y_M2,SUM_z_M2,SUM_r_M2,SUM_y_xM2, + SUM_z_xM2,SUM_r_xM2, + TAB_S1xM2,TAB_S1M2,TAB_S1Fo,TAB_FoM2,TAB_S1M3,TAB_M3M2,TAB_t_FE, + TAB_y_Fo,TAB_z_Fo,TAB_r_Fo,TAB_y_M2,TAB_z_M2,TAB_r_M2,TAB_y_xM2, + TAB_z_xM2,TAB_r_xM2, + createPhysTab, + PHY_S1xM2,PHY_S1M2,PHY_S1Fo,PHY_FoM2,PHY_S1M3,PHY_M3M2,PHY_t_FE, + PHY_y_Fo,PHY_z_Fo,PHY_r_Fo,PHY_y_M2,PHY_z_M2,PHY_r_M2,PHY_y_xM2, + PHY_z_xM2,PHY_r_xM2, + PHY_mean,PHY_variance,PHY_minimum,PHY_maximum,PHY_percent, + createNTP, + NTP_charge,NTP_S1xM2,NTP_times,NTP_FoM2Only,NTP_lifetime,NTP_start, + NTP_stop,NTP_40mm,NTP_Folie,NTP_steps, smearS1Fo,sigmaS1Fo, + eps_x,eps_v,log_relativ, maxStep, dtsmall,maxBelowDtSmall, d + dl_max_L1,dl_max_Sp,dl_max_L2andFo,dl_max_Fo,dl_max_L3,dl_max_M2, log_confine, + ow_U_Tgt,ow_U_Gua,ow_U_G1,ow_alfaTgt, + ow_masse,ow_ladung,ow_E0,ow_y0,ow_z0,ow_theta0,ow_phi0, + ow_U_L1,ow_U_Sp,ow_U_L2,ow_U_Folie, ow_B_Helm,ow_B_TD, + ow_alfaSp,ow_alfaTD,ow_deltaL1,ow_artList, writeTraj2File, + seed_, + useDecay_AH, artList_AH, randomStarts_AH c fuer Kompatibilitaet mit frueheren Versionen, bei denen statt der Extension c '_prevSim' noch die Extension '_AH' verwendet wurde: logical useDecay_AH /.false./ character artList_AH*50 / ' ' / integer randomStarts_AH / -1E8 / c - /KAMMER_GEO/: namelist /kammer_geo/ + radius_Rohr, + xtarget,dytarget,dztarget, ! Beim Einlesen sind xGrid1 und + xgrid1,dygrid1,dzgrid1, ! xGrid2 relativ zur Targetfolie, + dWires_G1,dist_Wires_G1, ! im Programm relativ zur Kryo- + xgrid2,dygrid2,dzgrid2, ! achse gemessen + dWires_G2,dist_Wires_G2, + rHeShield,dyHeShield,dzHeShield, + rLNShield,dyLNShield,dzLNShield, + xCenterOfLense_L1,MappenName_L1, + xSpiegel,DreharmLaenge,BSpiegel,hSpiegel,DSpiegel,MappenName_Sp, + dWires_Sp,dist_Wires_Sp, + xCenterOfLense_L2,MappenName_L2andFo, + xTD,mappenName_Fo, + xCenterOfLense_L3,MappenName_L3, + xMCP2,radius_MCP2active,MappenName_M2 c------------------------------------------------------------------------------- INCLUDE 'mutrack$SOURCEdirectory:COM_MUTRACK.INC' INCLUDE 'mutrack$sourcedirectory:COM_DIRS.INC' INCLUDE 'mutrack$sourcedirectory:GEO_TRIGGER.INC' INCLUDE 'mutrack$sourcedirectory:COM_KAMMER.INC' character*40 inputName /'MUTRACK.INPUT'/ COMMON /inputName/ inputName integer k ! Zaehlvariable logical flag logical flag_message /.false./ real help integer ihelp character antwort*5 logical log_marker / .false./ ! Marker am Ende der Trajektorien COMMON /marker/ log_marker ! zeichen? integer previousSimulation !/0/ logical ow_U_Tgt /.false./ logical ow_U_Gua /.false./ logical ow_U_G1 /.false./ logical ow_alfaTgt /.false./ logical ow_masse /.false./ logical ow_ladung /.false./ logical ow_E0 /.false./ logical ow_y0 /.false./ logical ow_z0 /.false./ logical ow_theta0 /.false./ logical ow_phi0 /.false./ logical ow_U_L1 /.false./ logical ow_U_Sp /.false./ logical ow_U_L2 /.false./ logical ow_U_Folie /.false./ logical ow_B_Helm /.false./ logical ow_B_TD /.false./ logical ow_alfaSp /.false./ logical ow_alfaTD /.false./ logical ow_deltaL1 /.false./ logical ow_artList /.false./ c lokale Variablen fuer die Gewinnung von VersionIndxAC bzw. VersionIndxMU: integer version1,version2,version3 integer pos1,pos2 c Variablen im Zusammenhang mit den Eingabefile-Listen 'LISTn.INPUT': integer lastOne /0/, fileNr, iostat, length logical testRun_ character datum*9,uhrzeit*8 c die lokalen Variablen zur Festlegung des Startortes und -Gebietes: real x0_ / 0. / ! StartKoordinate integer Kammerteil / 1 / ! Start-Kammerteil c die lokal definierten Groessen zur Festlegung der Zufallsverteilungen der c Startparameter: integer random_energy / 0 / ! welche Verteilung fuer Startenergie? integer random_position / 0 / ! welche Verteilung fuer Startposition? integer random_winkel / 0 / ! welche Verteilung fuer Startwinkel? integer randomStarts / 50/ integer seed_ / 0 / c die lokalen Variablen fuer die Festlegung der Zufallsverteilungen fuer c Energie- und Winkelaufstreuung in der Triggerfolie: integer n_E_Verlust / 0 / ! Art der Beruecksichtigung des Energie- ! verlustes in der Triggerfolie integer n_Aufstreu / 0 / ! Art der Beruecksichtigung der Winkel- ! Aufstreuung in der Triggerfolie c die lokalen Felder der 'Schleifenparameter'. Die Felder werden dann in das c Feld 'par' uebertragen: ! von ! bis ! step ! real U_Tgt_(3) / 0. , +1.e10 , -1.e10 / real U_Gua_(3) / -1.e10 , +1.e10 , -1.e10 / real U_G1_(3) / 0. , +1.e10 , -1.e10 / real U_L1_(3) / 0. , +1.e10 , -1.e10 / real U_Sp_(3) / 0. , +1.e10 , -1.e10 / real U_L2_(3) / 0. , +1.e10 , -1.e10 / real U_L3_(3) / 0. , +1.e10 , -1.e10 / c Fuer das Einlesen aelterer foilFile-Versionen: real U_KL_(3) / -1.e10 , +1.e10 , -1.e10 / real U_Folie_(3) / 0. , +1.e10 , -1.e10 / real U_Vorne_(3) / 0. , +1.e10 , -1.e10 / real U_Hinten_(3) / 0. , +1.e10 , -1.e10 / real U_MCP3_(3) / 0. , +1.e10 , -1.e10 / real U_MCP2_(3) / 0. , +1.e10 , -1.e10 / real B_Helm_(3) / 0. , +1.e10 , -1.e10 / real B_TD_(3) / 0. , +1.e10 , -1.e10 / real alfaTgt_(3) / 0. , +1.e10 , -1.e10 / real alfaSp_(3) / 45. , +1.e10 , -1.e10 / real alfaTD_(3) / 0. , +1.e10 , -1.e10 / real Masse_(3) / 105659. , +1.e10 , -1.e10 / real Ladung_(3) / 1. , +1.e10 , -1.e10 / real E0_(3) / 0. , +1.e10 , -1.e10 / real y0_(3) / 0. , +1.e10 , -1.e10 / real z0_(3) / 0. , +1.e10 , -1.e10 / real theta0_(3) / 0. , +1.e10 , -1.e10 / real phi0_(3) / 0. , +1.e10 , -1.e10 / real thickness_(3) / 0. , +1.e10 , -1.e10 / real mean_Eloss_(3) / 0. , +1.e10 , -1.e10 / real deltaL1_(3) / 0. , +1.e10 , -1.e10 / real deltaL2_(3) / 0. , +1.e10 , -1.e10 / c Defaultwerte fuer Restaurierung: real defVal(3) / 0. , +1.e10 , -1.e10 / c die lokal definierten logicals fuer die Festlegung der im LOG-file auszu- c gebenden Statistiken. Die Logicals werden dann in das Feld 'statInSummary' c uebertragen: logical SUM_S1xM2 / .false. / logical SUM_S1M2 / .false. / logical SUM_S1Fo / .false. / logical SUM_FoM2 / .false. / logical SUM_S1M3 / .false. / logical SUM_M3M2 / .false. / logical SUM_t_FE / .false. / logical SUM_y_Fo / .false. / logical SUM_z_Fo / .false. / logical SUM_r_Fo / .false. / logical SUM_y_M2 / .false. / logical SUM_z_M2 / .false. / logical SUM_r_M2 / .false. / logical SUM_y_xM2 / .false. / logical SUM_z_xM2 / .false. / logical SUM_r_xM2 / .false. / c die lokal definierten logicals fuer die Festlegung der fuer PHYSICA abzu- c speichernden Statistiken. Die Logicals werden dann in das Feld 'statInPHYSICA' c uebertragen: logical PHY_S1xM2 / .false. / logical PHY_S1M2 / .false. / logical PHY_S1Fo / .false. / logical PHY_FoM2 / .false. / logical PHY_S1M3 / .false. / logical PHY_M3M2 / .false. / logical PHY_t_FE / .false. / logical PHY_y_Fo / .false. / logical PHY_z_Fo / .false. / logical PHY_r_Fo / .false. / logical PHY_y_M2 / .false. / logical PHY_z_M2 / .false. / logical PHY_r_M2 / .false. / logical PHY_y_xM2 / .false. / logical PHY_z_xM2 / .false. / logical PHY_r_xM2 / .false. / c die lokal definierten logicals fuer die Festlegung der fuer PHYSICA abzu- c speichernden statistischen Groessen. Die Logicals werden dann in das Feld c 'whatInPHYSICA' uebertragen: logical PHY_mean / .false. / logical PHY_variance / .false. / logical PHY_minimum / .false. / logical PHY_maximum / .false. / logical PHY_percent / .false. / c die lokal definierten logicals fuer die Festlegung der zu erzeugenden c Tabellenfiles. Die Logicals werden dann in das Feld 'createTabelle' ueber- c tragen: logical TAB_S1xM2 / .false. / logical TAB_S1M2 / .false. / logical TAB_S1Fo / .false. / logical TAB_FoM2 / .false. / logical TAB_S1M3 / .false. / logical TAB_M3M2 / .false. / logical TAB_t_FE / .false. / logical TAB_y_Fo / .false. / logical TAB_z_Fo / .false. / logical TAB_r_Fo / .false. / logical TAB_y_M2 / .false. / logical TAB_z_M2 / .false. / logical TAB_r_M2 / .false. / logical TAB_y_xM2 / .false. / logical TAB_z_xM2 / .false. / logical TAB_r_xM2 / .false. / c Defaultwerte fuer dl_max_..: DATA dl_max_L1 / 1.0 / DATA dl_max_Sp / 1.0 / DATA dl_max_L2andFo / 1.0 / DATA dl_max_Fo / 1.0 / DATA dl_max_L3 / 1.0 / DATA dl_max_M2 / 1.0 / c ... character*30 zeile c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - logical writeTraj2File common /writeTraj2File/ writeTraj2File c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Variable fuer den Test, ob 'MUTRACK' als batch job laeuft: c (setzt voraus, dass im Falle eines batch jobs das logical c 'running_in_batchmode' definiert ist). INCLUDE '($SSDEF)/NOLIST' INCLUDE '($LNMDEF)/NOLIST' integer status, sys$trnlnm STRUCTURE /ITMLST/ UNION MAP integer*2 BUFLEN integer*2 CODE integer*4 BUFADR integer*4 RETLENADR END MAP MAP integer*4 END_LIST END MAP END UNION END STRUCTURE RECORD /ITMLST/ LNMLIST(2) character*20 running_in_batchmode c=============================================================================== c Pruefe, ob MUTRACK als batch job laeuft: LNMLIST(1).BufLen = Len(RUNNING_IN_BATCHMODE) LNMLIST(1).Code = LNM$_STRING LNMLIST(1).BufAdr = %Loc(RUNNING_IN_BATCHMODE) LNMLIST(1).RetLenAdr = 0 Status = SYS$trnlnm(lnm$M_case_blind, + 'lnm$file_dev','RUNNING_IN_BATCHMODE',,Lnmlist) if (Status.EQ.SS$_NOLOGNAM) then batch_mode = .false. else write(*,*) write(*,*) ' >>>> *******************************************' write(*,*) ' >>>>> logical ''RUNNING_IN_BATCHMODE'' is defined' write(*,*) ' >>>>> => assume MUTRACK is run in batch mode' write(*,*) ' >>>> *******************************************' write(*,*) batch_mode = .true. c Pruefe, of 'InputListName' definiert ist. Falls ja, verwende die entsprechende c Eingabeliste. Ansonsten bearbeite MUTRACK.INPUT: LNMLIST(1).BufLen = Len(inputListName) LNMLIST(1).Code = LNM$_STRING LNMLIST(1).BufAdr = %Loc(inputListName) LNMLIST(1).RetLenAdr = 0 Status = SYS$trnlnm(lnm$M_case_blind, + 'lnm$file_dev','inputListName',,Lnmlist) if (Status.NE.SS$_NOLOGNAM) then call str$trim(inputListName,inputListName,Length) inputListName = inputListName(1:length) INPUT_LIST = .true. endif c Liess gegebenenfalls zu verwendenden Input-filenamen ein: if (INPUT_LIST) then open(lunRead,file=inputListName//'.INPUT',status='old',iostat=iostat, + defaultfile=readDir) if (iostat.NE.0) then write(*,*) ' Kann '''//inputListName//'.INPUT'' nicht oeffnen' write(*,*) call exit endif ListLength = 0 testRun_ = .false. 10 read(lunRead,'(A)',end=20) inputName read(inputName,*,iostat=iostat) ihelp if (iostat.NE.0) then ListLength = ListLength + 1 goto 10 else if (ihelp.GT.0) then lastOne = ihelp if (lastOne.EQ.1) then write(*,*) 'Es wurden schon alle files aus '''//inputListName//'.INPUT''' write(*,*) 'abgearbeitet!' write(*,*) close(lunRead) call exit endif else gotFileNr = .true. fileNr = -ihelp+1 if (fileNr.EQ.10000) fileNr=9900 endif goto 10 endif 20 if (listLength.EQ.0) then write(*,*) ' no file names found in inputList -> STOP' call exit endif if (lastOne.EQ.0) lastOne=listLength+1 c den Namen des fuer diese Simulation zu verwendenden input-files einlesen: rewind(lunRead) do k = 1, lastOne-2 read(lunRead,*) enddo read(lunRead,'(A)') inputName c die Nummer des jetzt verwendeten input-files sowie (falls schon bekannt) die c (negative) fileNr der Ausgabefile ausgeben: ! bis Listenende weiterblaettern: do k = lastOne, listLength read(lunRead,*) enddo write(lunRead,*) lastOne-1 if (gotFileNr) write(lunRead,*) -fileNr close(lunRead) c gegebenenfalls schon den Namen der Ausgabe-files definieren: if (gotFileNr) then if (fileNr.GE.9900) then TestRun_ = .true. else TestRun_ = .false. endif write(filename(4:7),'(I4)')fileNr if (fileNr.LE.999) write (filename(4:4),'(A1)') '0' if (fileNr.LE. 99) write (filename(5:5),'(A1)') '0' if (fileNr.LE. 9) write (filename(6:6),'(A1)') '0' endif write(*,'(xA,I3,A)')'Verwende',listLength-lastOne+2, + '.letzte INPUT-Datei aus '''//inputListName//'.INPUT'': ' write(*,*) inputName open(lunMessage,file='MU_'//inputListName//'.MESSAGE',defaultfile='SYS$SCRATCH:', + status='UNKNOWN',iostat=iostat) write(lunMessage,'(xx,I2)',iostat=iostat) lastOne-1 else open(lunMessage,file='MUTRACK.MESSAGE',defaultfile='SYS$SCRATCH:', + status='UNKNOWN',iostat=iostat) endif call date(datum) call time(uhrzeit) write(lunMessage,*,iostat=iostat) ' started on '//datum//' at '//uhrzeit write(lunMessage,*,iostat=iostat) inputname close(lunMessage,iostat=iostat) endif c------------------------------------------------------------------------------- c Defaultwerte fuer Kammergeometrie (da diese Variablen in 'COM_KAMMER' gefuehrt c werden anstatt in COM_MUTRACK werden sie hier initialisert): DreharmLaenge = 0. xBlende = -1. c Einlesen der Eingabe-Datei 'MUTRACK.INPUT': open(lunREAD,file=inputName,defaultfile=readDir//':.INPUT', + status='OLD',readonly) read(lunREAD,nml=parameter_liste) close(lunREAD) c Einlesen der 'overwrite_default'-Datei: open(lunREAD,file='overwrite_defaults',defaultfile=readDir//':.INPUT', + status='OLD',readonly,iostat=iostat) if (iostat.EQ.0) then write(*,*) ' ##### READING INPUT FROM FILE >> ''OVERWRITE_DEFAULTS.INPUT'' << #####' read(lunREAD,nml=parameter_liste) close(lunREAD) endif if (previousSimulation.EQ.0) E0InterFromFile = .false. TransTDFoil = TransTDFoil/100. ! Umrechnen von Prozent in absolute Angabe write(*,*) if (seed_.GT.0) then ! -> es wurde Startwert fuer seed vorgegeben seed = seed_ write(*,*) '''seed_'' was specified in MUTRACK.INPUT => not randomly thrown' flag_message = .true. if (seed.LT.1e6) then write(*,*) '''seed'' has to be greater than 1E6' call exit endif if ((seed/2)*2.EQ.seed) then write(*,*) '''seed'' has to be an odd number => seed -> seed + 1' seed = seed+1 endif endif write(*,*) ' seed = ',seed write(*,*) if (previousSimulation.EQ.1) then use_ACCEL = .true. ! default = .false. elseif (previousSimulation.EQ.2) then use_MUTRACK = .true. ! default = .false. NTP_40mm = .false. endif if (NTP_Times) NTP_FoM2Only = .false. if (createFoilFile) then if (.NOT.TriggerInBeam) then TriggerInBeam = .true. write(*,*) '''createFoilFile'' = .true. -> set ''TriggerInBeam'' to ''.true.''' flag_message = .true. endif if (Use_Mutrack) then Use_Mutrack = .false. write(*,*) '''createFoilFile'' = .true. -> set ''Use_Mutrack'' to ''.false.''' flag_message = .true. endif if (Fo_triggered) then Fo_triggered = .false. write(*,*) '''createFoilFile'' = .true. -> set ''Fo_triggered'' to ''.false.''' flag_message = .true. endif upToTDFoilOnly = .true. generate_FE = .false. M2_triggered = .false. xM2_triggered = .false. NTP_s1xM2 = .false. NTP_times = .false. NTP_FoM2Only = .false. NTP_charge = .false. NTP_Folie = .false. elseif (.NOT.TriggerInBeam) then Fo_triggered = .false. upToTDFoilOnly = .false. NTP_FoM2Only = .false. smearS1Fo = .false. endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Aufbereiten von 'geo_filename': call str$upCase(geo_filename,geo_filename) if (geo_filename.EQ.'2') then geo_filename = 'GEO_KAMMER_RUN2' elseif (geo_filename.EQ.'3'.OR.geo_filename.EQ.'4') then geo_filename = 'GEO_KAMMER_RUN3-4' elseif (geo_filename.EQ.'6'.OR.geo_filename.EQ.'7'.OR. + geo_filename.EQ.'8') then geo_filename = 'GEO_KAMMER_RUN6-8' elseif (geo_filename.EQ.'8L' .OR. geo_filename.EQ.'7L') then geo_filename = 'GEO_KAMMER_RUN7_LONG' elseif (geo_filename.EQ.'9') then geo_filename = 'GEO_KAMMER_RUN9' elseif (geo_filename.EQ.'9N') then geo_filename = 'GEO_KAMMER_RUN9_NEW' elseif (geo_filename.EQ.'10') then geo_filename = 'GEO_KAMMER_RUN10' elseif (geo_filename.EQ.'11') then geo_filename = 'GEO_KAMMER_RUN11' endif c gegebenfalls Abstand zwischen hinterem Triggergitter und Massegitter anpassen: if (index(geo_fileName,'_RUN9' ).NE.0 .OR. + index(geo_fileName,'_RUN10').NE.0) then dx5 = 15 ! Default: 8 mm endif c 'GridInFrontOfFoil' gab es bis jetzt nur in Run 9: if (gridInFrontOfFoil .AND. index(geo_fileName,'_RUN9').EQ.0) then write(*,*) write(*,*) 'Ein Gitter vor der Triggerfolie gab es bis jetzt nur in Run9' write(*,*) ' => setze ''gridInFrontOfFoil'' auf .false.!' write(*,*) gridInFrontOfFoil = .false. flag_message = .true. endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Uebertragen der Schleifenparameter in das Feld 'par': do k = 1, 3 par(k,UTgt) = U_Tgt_ (k) par(k,UGua) = U_Gua_ (k) par(k,UG1) = U_G1_ (k) par(k,UL1) = U_L1_ (k) par(k,USp) = U_Sp_ (k) par(k,UL2) = U_L2_ (k) par(k,UL3) = U_L3_ (k) par(k,UFolie) = U_Folie_ (k) par(k,UVorne) = U_Vorne_ (k) par(k,UHinten) = U_Hinten_(k) par(k,UMCP3) = U_MCP3_ (k) par(k,UMCP2) = U_MCP2_ (k) par(k,BHelm) = B_Helm_ (k) par(k,BTD) = B_TD_ (k) par(k,alfTgt) = alfaTgt_ (k) par(k,alfSp) = alfaSp_ (k) par(k,alfTD) = alfaTD_ (k) par(k,mass) = Masse_ (k) par(k,charge) = Ladung_ (k) par(k,ener) = E0_ (k) par(k,yPos) = y0_ (k) par(k,zPos) = z0_ (k) par(k,thetAng) = theta0_ (k) par(k,phiAng) = phi0_ (k) par(k,Thickn) = Thickness_(k) par(k,Eloss) = mean_Eloss_(k) par(k,DeltaL1) = DeltaL1_(k) par(k,DeltaL2) = DeltaL2_(k) enddo c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Einlesen der zu verwendenden Kammergeometrie (falls Use_MUTRACK oder Use_ACCEL c gesetzt ist wird weiter unten ein Teil der Kammergeometrie nochmal ueber- c schrieben): open(lunREAD,file=geo_fileName, + defaultfile=geoDIR//':.INPUT',status='OLD',readonly) read(lunREAD,nml=kammer_geo) rewind (lunREAD) call READ_TRIGGER_GEO ! Drahtdurchmesser und -abstaende einlesen close(lunREAD) if (TriggerInBeam .AND. mappenName_Fo.EQ.' ') then write(*,*) write(*,*) ' Im Geo_file ' write(*,*) write(*,*) ' '//geo_fileName write(*,*) write(*,*) ' ist kein Name fuer die Potentialmappe der Folie angegeben!' write(*,*) ' => bei dieser Kammergeometrie ist offensichtlich kein Triggerdetektor vorgesehen.' write(*,*) ' => ''TriggerInBeam'' auf ''.false.'' gesetzt' TriggerInBeam = .false. if (createFoilFile) then createFoilFile = .false. write(*,*) ' -> set ''createFoilFile'' to ''.false.''' endif flag_message = .true. endif c falls .NOT.use_MUTRACK: c pruefe an dieser Stelle, ob mit die Kammergeometrie die Linse 2 beinhaltet. c Falls ja, lege den Winkel des Triggerdetektors auf Null fest. Ansonsten c setze die Spannung an Linse 2 auf konstant Null: c (im Falle von 'use_MUTRACK' wurden diese Aktionen gegebenenfalls ja schon beim c Erstellen des 'foilFiles' durchgefuehrt) if (.NOT.use_MUTRACK) then if (mappenName_L2andFo.NE.' ') then ! => Linse 2 montiert lense2 = .true. ! => gemeinsame Mappe fuer Linse 2 und TD-Folie ! => TD-Winkel kann nicht variiert werden: if (alfaTD_(1).NE.0 .OR. (alfaTD_(2).NE.0 .AND. alfaTD_(2).NE.+1.e10)) then write(*,*) write(*,*) ' with lense 2 mounted the angle of the trigger detector is not variable' write(*,*) ' -> set alfaTD_ == 0.' write(*,*) par(1,alfTD) = 0. par(2,alfTD) = 0. flag_message = .true. endif else par(1,UL2) = 0. par(2,UL2) = 0. endif endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Einlesen der INFO-Files der Feldmappen (und Setzen einiger Variabler mit c mappenspezifischen Positionsangaben): call read_INFOs if (.NOT.(upToTDFoilOnly .OR. createFoilFile) .AND. + radius_MCP2.LT.radius_MCP2active) then write(*,*) write(*,*) 'radius of MCP2 = ',radius_MCP2 write(*,*) 'radius of the active area of MCP2 = ',radius_MCP2active write(*,*) 'radius_MCP2active has to be .LE. radiusMCP2!!' write(*,*) call exit endif if (lense2) then ! pruefen, ob die Angaben des Geometriefiles mit den Vorgaben ! der 'L2andFo'-Mappe kompatibel ist (Mappenende muss mit Folien- ! ebene zusammenfallen): ! (bei 'use_MUTRACK' ist 'lense2' gegebenenfalls an dieser Stelle ! noch nicht gesetzt!) ! ?: Auch noch pruefen, ob Mappenbeginn mit Spiegelmappe ueberlappt if (xLeaveMap_L2andFo .NE. xTD-d_Folie_Achse) then write(*,*) 'Angaben des Geometriefiles sind nicht kompatibel mit den Vorgaben aus' write(*,*) mappenName_L2andFo write(*,*) ' Mappenende bei ',xLeaveMap_L2andFo write(*,*) ' Ebene der Triggerfolie bei ',xTD-d_Folie_Achse call exit endif endif ! Umrechenen der Blendenposition von 'relativ zum MCP2' in ! absoluten x-Wert: xBlende = xMCP2-xBlende if (xBlende.LT.xEnterMap_M2.OR.xBlende.GT.xMCP2) then if (xBlende.GT.0..AND.xBlende.LE.xMCP2) then write(*,*) 'Beginn der MCP2-Mappe: x = ',xEnterMap_M2 write(*,*) 'Position der Blende: x = ',xBlende write(*,*) '=> Blende liegt vor der Mappe => wird ignoriert!' flag_message = .true. endif xBlende=-1. endif c=============================================================================== c fuer 'fromScratch','Use_ACCEL' und 'Use_MUTRACK' separate Abschnitte: c=============================================================================== if (Use_ACCEL.OR.Use_MUTRACK) fromScratch = .false. if (fromScratch) then ! 1: if ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c Umrechnen der eingelesenen xGrid1- und xGrid2-Werte von Angaben relativ zur c Moderatorfolie in Angaben relativ zur Kryoachse: xGrid1 = xGrid1 + xTarget xGrid2 = xGrid2 + xTarget c Falls die Anzahl zufallsverteilter Starts <= 0 sein sollte, vergiss die c Zufallsstarts: if (randomStarts.LE.0) then random_energy = 0 random_position = 0 random_winkel = 0 endif elseif (Use_ACCEL) then ! 1: elseif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c Spezielle Anweisungen fuer den Fall, dass ACCEL-Simulationen der Trajektorien c im Beschleuniger als Ausgangspunkt fuer die MUTRACK-Simulationen verwendet c werden sollen: c - Oeffnen des INFO-Files: open(lunREAD,file=fileName_ACCEL,defaultfile=ACCEL_Dir//':.INFO', + status='OLD',readonly) c - Festlegen von AccelVersionIndx: read(lunREAD,nml=acVersion,iostat=iostat) rewind(lunREAD) if (iostat.NE.0) then accelVersion = '1.0.?' AccelVersionIndx = 0 else length = len(accelVersion) pos1 = index(accelVersion,'.') pos2 = pos1 + index(accelVersion(pos1+1:length),'.') read(accelVersion( 1:pos1-1),*) Version1 read(accelVersion(pos1+1:pos2-1),*) Version2 read(accelVersion(pos2+1:length),*) Version3 k = 10000*Version1 + 100*Version2 + Version3 if (k.LT.010101) then AccelVersionIndx = 0 elseif (k.LT.10201) then ! Versionen ohne Magnetfelder AccelVersionIndx = 1 else AccelVersionIndx = 2 endif endif if (AccelVersionIndx.EQ.0) then write(*,*) write(*,*) fileName_ACCEL write(*,*) write(*,*) 'Die Simulation wurde mit ACCEL-Version < 1.1.1 erstellt.' write(*,*) 'Diese ACCEL-Versionen mit unformatiertem Ausgabefile' write(*,*) 'anstelle von NTupeln werden seit MUTRACK-Version 1.5.1' write(*,*) 'nicht mehr unterstuetzt!' write(*,*) call exit endif c - Einlesen der Parametereinstellungen waehrend ACCEL: c Um die allgemeinen Parametereinstellungen zu haben, mit denen die ACCEL- c simulationen durchgefuehrt wurden, wird das Namelist /parameter_liste/ c eingelesen. Dieses enthaelt aber bei den .INFO files im Gegensatz zu der c gleichnamigen Namelist der Eingabefiles fuer MUTRACK und ACCEL nicht die c Angaben fuer die 'Schleifenparameter', welche statt dessen in einem eigenen c Namelist 'loop_params' abgelegt sind. Dieses wird hier nur eingelesen, c falls fuer die Schleifenparameter (zumindest teilweise) die Einstellungen c waehrend der ACCEL-Simulation uebernommen werden sollen (-> logical c 'previousSettings'). Ansonsten wird die Information aus /loop_params/ c in der Subroutine 'getPreviousSettings' gelesen und ausgewertet. Entsprechendes c gilt fuer 'artList'. read(lunREAD,nml=parameter_liste) rewind(lunREAD) ! fuer Kompatibilitaet mit frueheren Versionen, bei denen statt ! der Extension '_prevSim' noch die Extension '_AH' verwendet wurde: if (useDecay_AH) useDecay_prevSim = .true. if (artList_AH.NE.' ') artlist_prevSim = artList_AH if (randomStarts_AH.NE.-1E8) randomStarts_prevSim = randomStarts_AH if (previousSettings) then c -- Resetten der Parameterliste: do k = 1, 3 U_Tgt_(k) = defVal(k) U_Gua_(k) = defVal(k) U_G1_(k) = defVal(k) B_Helm_(k) = defVal(k) B_TD_(k) = defVal(k) Masse_(k) = defVal(k) Ladung_(k) = defVal(k) E0_(k) = defVal(k) y0_(k) = defVal(k) z0_(k) = defVal(k) theta0_(k) = defVal(k) phi0_(k) = defVal(k) enddo U_Gua_(1) = -1.e10 Masse_(1) = 105659. Ladung_(1) = 1. c -- Einlesen der Schleifensettings waehrend ACCEL: read(lunREAD,nml=loop_params) rewind (lunREAD) c -- Uebernehmen der geforderten Parameter: if (artList_prevSim.NE.' ') then ow_masse = ow_artList ow_Ladung = ow_artList else ow_artList = .false. endif if (.NOT.ow_artList) artList = artList_prevSim do k = 1, 3 if (.NOT.ow_U_Tgt) par(k,UTgt) = U_Tgt_ (k) if (.NOT.ow_U_Gua) par(k,UGua) = U_Gua_ (k) if (.NOT.ow_U_G1) par(k,UG1) = U_G1_ (k) if (.NOT.ow_B_Helm) par(k,BHelm) = B_Helm_ (k) if (.NOT.ow_B_TD) par(k,BTD) = B_TD_ (k) if (.NOT.ow_Masse) par(k,mass) = Masse_ (k) if (.NOT.ow_Ladung) par(k,charge) = Ladung_ (k) if (.NOT.ow_E0) par(k,ener) = E0_ (k) if (.NOT.ow_y0) par(k,yPos) = y0_ (k) if (.NOT.ow_z0) par(k,zPos) = z0_ (k) if (.NOT.ow_theta0) par(k,thetAng) = theta0_ (k) if (.NOT.ow_phi0) par(k,phiAng) = phi0_ (k) enddo endif c -- Auswerten der Vorgabe: call examine_artList call getPreviousSettings rewind (lunREAD) c - Einlesen der Targetgeometrie aus dem INFO-file: call read_ACCEL_geometry rLNShield = rLNShield*scaleFactor c - gegebenenfalls E0-Intervalle einlesen: if (E0InterFromFile) then rewind (lunREAD) zeile = ' ' do while (index(zeile,'BOUNDARIES OF E0-INTERVALLS').EQ.0) read (lunREAD,'(A)') zeile call str$upcase(zeile,zeile) enddo do k = 1, nint(E0_(2))+1 read (lunREAD,*) E0Low(k) enddo do k = 1, nint(E0_(2)) write(*,'(x,A,I4,A,F6.3,A,F6.3,A)') 'E0-intervall',k,': [',E0Low(k),',',E0Low(k+1),']' enddo endif close(lunREAD) c - Anzahl der Zufallsstarts setzen: if (randomStarts.LT.0 .OR. randomStarts.GT.randomStarts_prevSim) then randomStarts = randomStarts_prevSim endif else ! => Use_MUTRACK ! 1: else ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c Spezielle Anweisungen fuer den Fall, dass fruehere MUTRACK-Simulationen bis c zur Triggerfolie als Ausgangspunkt fuer weitere Simulationen eingelesen werden c sollen: c (wurde die fruehere MUTRACK-Simulation mit 'Use_ACCEL' erstellt, so wird auch c jetzt beim Einlesen des INFO-files 'Use_ACCEL' wieder auf '.true.' gesetzt. c Dies geschieht, um beim Erstellen des LOG-files die entsprechenden Informa- c tionen zur Verfuegung zu haben. Nach dem Erstellen des LOG-Files wird c 'Use_ACCEL' dann wieder negiert). c - Oeffnen des INFO-Files: open(lunREAD,file=fileName_MUTRACK,defaultfile=outDir//':.INFO', + status='OLD',readonly) c - Festlegen von MutrackVersionIndx: read(lunREAD,nml=muVersion) rewind(lunREAD) length = len(mutrackVersion) pos1 = index(mutrackVersion,'.') pos2 = pos1 + index(mutrackVersion(pos1+1:length),'.') read(MutrackVersion( 1:pos1-1),*) Version1 read(MutrackVersion(pos1+1:pos2-1),*) Version2 read(MutrackVersion(pos2+1:length),*) Version3 k = 10000*Version1 + 100*Version2 + Version3 if (k.LT.010501) then ! Versionen ohne Linse 2 und ohne Magnetfelder MutrackVersionIndx = 1 else MutrackVersionIndx = 2 endif c - Einlesen der zugehoerigen Kammer-Geometrie aus dem INFO-file: mappenName_L2andFo = ' ' read(lunRead,nml=kammer_geo) rewind (lunREAD) if (mappenName_L2andFo.NE.' ') then ! => Linse 2 montiert lense2 = .true. ! => gemeinsame Mappe fuer Linse 2 und TD-Folie ! => TD-Winkel kann nicht variiert werden: if (ow_alfaTD .AND. + (alfaTD_(1).NE.0 .OR. (alfaTD_(2).NE.0 .AND. alfaTD_(2).NE.+1.e10))) then write(*,*) write(*,*) ' with lense 2 mounted the angle of the trigger detector is not variable' write(*,*) ' -> set alfaTD_ == 0.' write(*,*) par(alfTD,1) = 0. par(alfTD,2) = 0. flag_message = .true. endif ! Geometriedaten aus INFO-file der Mappe einlesen, um sie ! gegebenenfalls fuer Ausgabe parat zu haben: if (write_geo) CALL READ_INFO_L2andFo else par(1,UL2) = 0. par(2,UL2) = 0. endif c - Einlesen der Parametereinstellungen waehrend Erstellung des 'foilFiles' c (bis auf die Schleifenparameter. Siehe Bemerkung zu entsprechendem Abschnitt c bei Use_ACCEL): read(lunREAD,nml=parameter_liste) rewind(lunREAD) ! fuer Kompatibilitaet mit frueheren Versionen, bei denen statt ! der Extension '_prevSim' noch die Extension '_AH' verwendet wurde: if (useDecay_AH) useDecay_prevSim = .true. if (artList_AH.NE.' ') artlist_prevSim = artList_AH if (randomStarts_AH.NE.-1E8) randomStarts_prevSim = randomStarts_AH if (previousSettings) then c -- Resetten der Parameterliste: do k = 1, 3 U_Tgt_(k) = defVal(k) U_Gua_(k) = defVal(k) U_G1_(k) = defVal(k) U_L1_(k) = defVal(k) U_Sp_(k) = defVal(k) U_L2_(k) = defVal(k) U_Folie_(k) = defVal(k) B_Helm_(k) = defVal(k) B_TD_(k) = defVal(k) alfaTgt_(k) = defVal(k) alfaSp_(k) = defVal(k) alfaTD_(k) = defVal(k) Masse_(k) = defVal(k) Ladung_(k) = defVal(k) E0_(k) = defVal(k) y0_(k) = defVal(k) z0_(k) = defVal(k) theta0_(k) = defVal(k) phi0_(k) = defVal(k) deltaL1_(k) = defVal(k) enddo U_Gua_(1) = -1.e10 alfaSp_(1) = 45. Masse_(1) = 105659. Ladung_(1) = 1. c -- Einlesen der Schleifensettings waehrend der Erstellung des 'foilFiles': read(lunREAD,nml=loop_params) rewind (lunREAD) ! fuer Kompatibilitaet mit aelteren foilFile-Versionen: if (U_KL_(1).NE.-1.e10) then do k = 1, 3 U_L1_(k) = U_KL_(k) enddo endif c -- Uebernehmen der geforderten Parameter: if (artList_prevSim.NE.' ') then ow_masse = ow_artList ow_Ladung = ow_artList else ow_artList = .false. endif if (.NOT.ow_artList) artList = artList_prevSim do k = 1, 3 if (.NOT.ow_U_Tgt) par(k,UTgt) = U_Tgt_ (k) if (.NOT.ow_U_Gua) par(k,UGua) = U_Gua_ (k) if (.NOT.ow_U_G1) par(k,UG1) = U_G1_ (k) if (.NOT.ow_U_L1) par(k,UL1) = U_L1_ (k) if (.NOT.ow_U_Sp) par(k,USp) = U_Sp_ (k) if (.NOT.ow_U_L2) par(k,UL2) = U_L2_ (k) if (.NOT.ow_U_Folie) par(k,UFolie) = U_Folie_ (k) if (.NOT.ow_B_Helm) par(k,BHelm) = B_Helm_ (k) if (.NOT.ow_B_TD) par(k,BTD) = B_TD_ (k) if (.NOT.ow_alfaTgt) par(k,alfTgt) = alfaTgt_ (k) if (.NOT.ow_alfaSp ) par(k,alfSp) = alfaSp_ (k) if (.NOT.ow_alfaTD ) par(k,alfTD) = alfaTD_ (k) if (.NOT.ow_Masse) par(k,mass) = Masse_ (k) if (.NOT.ow_Ladung) par(k,charge) = Ladung_ (k) if (.NOT.ow_E0) par(k,ener) = E0_ (k) if (.NOT.ow_y0) par(k,yPos) = y0_ (k) if (.NOT.ow_z0) par(k,zPos) = z0_ (k) if (.NOT.ow_theta0) par(k,thetAng) = theta0_ (k) if (.NOT.ow_phi0) par(k,phiAng) = phi0_ (k) if (.NOT.ow_deltaL1) par(k,deltaL1) = deltaL1_ (k) enddo endif c -- Auswerten der Vorgabe: call examine_artList call getPreviousSettings ! liesst auch noch von 'lunREAD' c - gegebenenfalls E0-Intervalle einlesen: if (E0InterFromFile) then rewind (lunREAD) zeile = ' ' do while (index(zeile,'BOUNDARIES OF E0-INTERVALLS').EQ.0) read (lunREAD,'(A)') zeile call str$upcase(zeile,zeile) enddo do k = 1, nint(E0_(2))+1 read (lunREAD,*) E0Low(k) enddo do k = 1, nint(E0_(2)) write(*,'(x,A,I4,A,F6.3,A,F6.3,A)') 'E0-intervall',k,': [',E0Low(k),',',E0Low(k+1),']' enddo endif close(lunREAD) c - damit, falls das 'Foilfile' selbst auf einer ACCEL-Simulation beruht, c die zugehoerige Targetgeometrie aus dem ACCEL-INFO-File gelesen wird c (use_ACCEL wird im Hauptprogramm dann wieder resettet): if (previousSimulation.EQ.1) Use_ACCEL=.true. c - Anzahl der Zufallsstarts setzen: if (randomStarts.LT.0 .OR. randomStarts.GT.randomStarts_prevSim) then randomStarts = randomStarts_prevSim endif endif ! 1: endif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c=============================================================================== c Ab hier wieder fuer 'fromScratch', 'Use_ACCEL' und 'Use_MUTRACK' gemeinsam c=============================================================================== c Startgebiet und -Koordinate festlegen: if (StartFlaeche.EQ.-1) then if (Kammerteil.LE.1) then if (x0_.LE.0) then x0_ = 0. Startflaeche = 0 Gebiet0 = target elseif (x0_.LE.xGrid1) then Gebiet0 = upToGrid1 if (x0_.EQ.xGrid1) Startflaeche = 1 elseif (x0_.LE.xGrid2) then Gebiet0 = upToGrid2 elseif (x0_.LE.rHeShield) then Gebiet0 = upToHeShield elseif (x0_.LE.rLNShield) then Gebiet0 = upToLNShield elseif (x0_.LE.xEnterMap_L1) then Gebiet0 = upToL1Map elseif (x0_.LE.xLeaveMap_L1) then Gebiet0 = upToExL1 else Gebiet0 = upToEnSp endif else if (x0_.LE.xEnterMap_L3) then if (lense2) then if (x0_.LE.xEnterMap_L2andFo) then Gebiet0 = upToL2andFoMap elseif (x0_.LE.xEndLense_L2) then Gebiet0 = upToExL2 elseif (x0_.LE.xLeaveMap_L2andFo) then Gebiet0 = upToEnTD endif elseif (TriggerInBeam) then Gebiet0 = upToEnTD else Gebiet0 = upToL3Map endif elseif (x0_.LE.xEnterMap_L3) then Gebiet0 = upToL3Map elseif (x0_.LE.xLeaveMap_L3) then Gebiet0 = upToExL3 elseif (x0_.LE.xEnterMap_M2) then Gebiet0 = upToM2Map else Gebiet0 = upToMCP2 endif endif x0(1) = x0_ elseif (StartFlaeche.EQ.1) then Gebiet0 = upToGrid2 x0(1) = xGrid1 elseif (StartFlaeche.EQ.2) then TriggerInBeam = .true. Gebiet0 = upToExTD log_alpha0_KS = .true. x0(1) = 0. elseif (StartFlaeche.EQ.3) then TriggerInBeam = .true. Gebiet0 = upToExTD x0(1) = 0. else Startflaeche = 0 Gebiet0 = target x0(1) = xtarget endif if (Gebiet0.GT.upToExTD) then if (createFoilFile.OR.generate_FE.OR.upToTDFoilOnly) then write(*,*)' ''Gebiet0.GT.upToExTD''' if (createFoilFile) then createFoilFile = .false. write(*,*) ' -> set ''createFoilFile'' to ''.false.''' endif if (generate_FE) then generate_FE = .false. write(*,*) ' -> set ''generate_FE'' to ''.false.''' endif if (upToTDFoilOnly) then upToTDFoilOnly = .false. write(*,*) ' -> set ''upToTDFoilOnly'' to ''.false.''' endif flag_message = .true. endif endif if (Gebiet0.GT.upToLnShield) NTP_40mm = .false. c Zufallsverteilung fuer Startenergie? if (random_energy.GE.1 .AND. random_energy.LE.2) then random_E0 = .true. if (random_energy.EQ.1 .AND..NOT.(lowerE0.EQ.0..AND.upperE0.EQ.0.)) then if (lowerE0.GT.upperE0) then help = lowerE0 lowerE0 = upperE0 upperE0 = help endif random_E0_equal = .true. elseif (random_energy.EQ.2 .AND..NOT.(sigmaE0.EQ.0.)) then random_E0_gauss = .true. else random_E0 = .false. endif elseif (random_energy.NE.0) then write(*,*) write(*,*) 'random_energy = ',random_energy,' is not defined' write(*,*) call exit endif if (.NOT.random_E0 .AND. par(1,ener).EQ.0. .AND. par(2,ener).EQ.0.) then do k = 1, 3 par(k,phiAng) = 0. par(k,ThetAng) = 0. enddo endif c Zufallsverteilung fuer Startpositionen? if (random_position.GE.1 .AND. random_position. LE.4) then random_pos = .true. ! setze gegebenenfalls Defaultwerte ein: if (startBreite.LT.0.) startBreite = dyTarget if (startHoehe .LT.0.) startHoehe = dzTarget if (startRadius.LT.0.) startRadius = 20. sigmaPosition = abs(sigmaPosition) if (random_position.EQ.1 .AND. + .NOT.(StartBreite.EQ.0 .AND. StartHoehe.EQ.0)) then random_y0z0_equal = .true. elseif (random_position.EQ.2 .AND. .NOT.StartRadius.EQ.0) then random_r0_equal = .true. elseif (random_position.EQ.3 .AND. .NOT.sigmaPosition.EQ.0. + .AND. .NOT.(StartBreite.EQ.0 .AND. StartHoehe.EQ.0)) then random_y0z0_Gauss = .true. elseif (random_position.EQ.4 .AND. .NOT.StartRadius.EQ.0. + .AND. .NOT.sigmaPosition.EQ.0.) then random_r0_Gauss = .true. else random_pos = .false. endif elseif (random_position.NE.0) then write(*,*) write(*,*) 'random_position = ',random_position,' is not defined' write(*,*) call exit endif c Zufallsverteilung fuer Startwinkel? if (random_winkel.GE.1 .AND. random_winkel.LE.2) then random_angle = .true. if (random_winkel.EQ.1) then random_lambert = .true. elseif (random_winkel.EQ.2 .AND. .NOT.sigmaWinkel.EQ.0.) then random_gauss = .true. else random_angle = .false. endif elseif (random_winkel.NE.0) then write(*,*) write(*,*) 'random_winkel = ',random_winkel,' is not defined' write(*,*) call exit endif c Durchlaufzahl fuer die 'Zufallsschleife' setzen: if (random_E0.OR.random_pos.OR.random_angle) then par(2,0) = randomStarts ! (Default = 1) endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Falls der Trigger nicht im Strahlweg haengt sollen die Triggerschleifen c nicht unnoetig durchlaufen werden. Ausserdem fallen dann auch Energieverlust c und Aufstreuung in der Folie weg. Auch muessen keine Folienelektronen c generiert werden: if (.NOT.TriggerInBeam) then do k = 1, 3 par(k,UFolie) = 0. par(k,UVorne) = 0. par(k,UHinten)= 0. par(k,UMCP3) = 0. par(k,alfTD) = 0. par(k,Eloss) = 0. par(k,Thickn) = 0. enddo n_E_Verlust = 0 n_aufstreu = 0 log_neutralize = .false. ntp_folie = .false. Fo_triggered = .false. upToTDFoilOnly = .false. generate_FE = .false. endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c wurde die Variable 'artList' nicht gesetzt, setze 'UseDecay' und c 'log_neutralize' auf .false. (steht wegen 'log_neutralize' an dieser Stelle) if (fromScratch) call examine_artList if (.NOT.artList_defined) then if (UseDecay) then UseDecay = .false. write(*,1000) 'Myonen-Zerfall nur bei Verwendung von '// + '''ArtList''','UseDecay = .false. gesetzt' flag_message = .true. endif if (log_neutralize) then log_neutralize = .false. write(*,1000) 'Neutralisierung nur bei Verwendung von '// + '''ArtList''','log_neutralize = .false. gesetzt' flag_message = .true. endif endif if (.NOT.UseDecay) NTP_lifeTime = .false. c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c falls nur bis zur Triggerfolie gerechnet werden soll: Streiche Erstellung c aller Tabellen, Statistiken und NTupel-Eintraege die bis dahin nicht c gefuellt werden. Setze Spannung an L3 und MCP2 auf 0. Negiere alle Aktionen, c die erst danach stattfaenden. ('upToTDFoilOnly' ist auch gesetzt bei c 'createFoilFile'): if (upToTDFoilOnly) then n_E_Verlust = 0 n_Aufstreu = 0 log_neutralize = .false. xM2_triggered = .false. M2_triggered = .false. do k = 1, 3 par(k,UL3) = 0. par(k,UMCP2) = 0. par(k,deltaL2) = 0. par(k,Thickn) = 0. par(k,Eloss) = 0. enddo if (.NOT.generate_FE) then do k = 1, 3 par(k,UVorne) = 0. par(k,UHinten) = 0. par(k,UMCP3) = 0. enddo endif NTP_S1xM2 = .false. NTP_FoM2Only = .false. NTP_Folie = .false. NTP_charge= .false. SUM_S1xM2 = .false. SUM_S1M2 = .false. SUM_FoM2 = .false. SUM_M3M2 = .false. SUM_y_M2 = .false. SUM_z_M2 = .false. SUM_r_M2 = .false. SUM_y_xM2 = .false. SUM_z_xM2 = .false. SUM_r_xM2 = .false. PHY_S1xM2 = .false. PHY_S1M2 = .false. PHY_FoM2 = .false. PHY_M3M2 = .false. PHY_y_M2 = .false. PHY_z_M2 = .false. PHY_r_M2 = .false. PHY_y_xM2 = .false. PHY_z_xM2 = .false. PHY_r_xM2 = .false. TAB_S1xM2 = .false. TAB_S1M2 = .false. TAB_FoM2 = .false. TAB_M3M2 = .false. TAB_y_M2 = .false. TAB_z_M2 = .false. TAB_r_M2 = .false. TAB_y_xM2 = .false. TAB_z_xM2 = .false. TAB_r_xM2 = .false. endif c falls der Triggerdetektor im Strahl haengt: nimm entsprechende Einstellungen c fuer Energieverlust, Aufstreuung und Neutralisierung vor. Andernfalls: c streiche alle Statistiken und Tabellen, die auf ihm beruhen. if (TriggerInBeam) then !c Energie-Verlust in der Triggerfolie beruecksichtigen? if (abs(n_E_Verlust).GE.1 .AND. abs(n_E_Verlust).LE.5) then log_E_Verlust = .true. if (n_E_Verlust.LT.0) then log_E_Verlust_defined = .true. if (par(1,Eloss).LT.0) then write(*,*) write(*,*)'mittlerer E-Verlust muss positiv sein' write(*,*) call exit endif else log_E_Verlust_ICRU = .true. do k = 1, 3 par(k,Eloss) = 0. enddo endif n_E_verlust = ABS(n_E_verlust) if (n_E_verlust.EQ.1) then ! scharfer Energieverlust, also keine Aufstreuung elseif (n_E_verlust.EQ.2 .AND. sigmaE.NE.0.) then log_E_Straggling_sigma = .true. sigmaE = abs(sigmaE) elseif (n_E_verlust.EQ.3 .AND. .NOT.(lowerE.EQ.0.AND.upperE.EQ.0)) then log_E_Straggling_equal = .true. if (lowerE.GT.upperE) then help = lowerE lowerE = upperE upperE = help endif elseif (n_E_verlust.EQ.4) then log_E_Straggling_Lindhard = .true. elseif (n_E_verlust.EQ.5) then log_E_Straggling_Yang = .true. endif elseif (n_E_Verlust.NE.0) then write(*,*) write(*,*) 'n_E_Verlust = ',n_E_Verlust,' is not defined' write(*,*) call exit else ! -> n_E_Verlust = 0 do k = 1, 3 par(k,Eloss) = 0. enddo endif ! Falls Berechnung des mittleren Energieverlustes aus ICRU-Tabelle: ! Falls die Teilchen nicht vom Moderator oder vom 1. Gitter starten, ! berchne den mittleren Energieverlust fuer jedes Teilchen neu. ! Sonst: Wenn der mittlere Energieverlust nicht aus ICRU Tabelle ! berechnet werden soll oder alle Teilchen (einer Schleife) die ! exakt gleiche Startenergie haben, streiche 'calculate_each': if (log_E_Verlust_ICRU.AND.random_E0 .AND. + (Startflaeche.NE.0 .AND. Startflaeche.NE.1)) then calculate_each = .true. elseif (.NOT.(log_E_Verlust_ICRU.AND.random_E0)) then calculate_each = .false. endif ! Aufstreuung in der Folie beruecksichtigen? if (n_aufstreu.GE.1 .AND. n_aufstreu.LE.3) then log_aufstreu = .true. if (n_aufstreu.EQ.1) then log_aufstreu_fixed = .true. if (sigmaAufstreu.EQ.0.) then log_aufstreu = .false. elseif (sigmaAufstreu.LT.0) then write(*,1000) '''sigmaAufstreu.LT.0''','verwende Absolutbetrag' flag_message = .true. sigmaAufstreu = abs(sigmaAufstreu) endif elseif (n_Aufstreu.EQ.2) then log_Meyer_Gauss = .true. elseif (n_Aufstreu.EQ.3) then log_Meyer_F_Function = .true. endif elseif (n_Aufstreu.NE.0) then write(*,*) write(*,*) 'n_Aufstreu = ',n_Aufstreu,' is not defined' write(*,*) call exit endif ! Neutralisierung in der Folie beruecksichtigen? if (log_neutralize) then do k = 1, artenMax if ((neutral_fract(k).LT.0. .OR. neutral_fract(k).GT.100.) + .AND. neutral_fract(k).NE.-1) then write(*,*) write(*,*)'die neutralen Anteile '// + 'muessen zwischen 0 und 100 Prozent liegen!' write(*,*)'(''-1'' wird als Code fuer automatische '// + 'Berechnung gemaess M.Gonin akzeptiert)' write(*,*) call exit endif enddo endif endif if (.NOT.log_neutralize) ntp_charge = .false. c Soll nun abgesehen von der Neutralisierung eine im Zusammenhang mit der c Wechselwirkung der Teilchen mit der Triggerfolie auftretenden Groessen c zufallsverteilt gewuerfelt werden, so uebernehme die Anzahl der je Schleife c durchzufuehrender Starts, auch wenn die Startparameter selbst nicht gewuerfelt c werden: if (log_E_Straggling_sigma .OR. log_E_Straggling_equal .OR. + log_E_Straggling_Lindhard .OR. log_E_Straggling_Yang .OR. + log_aufstreu) then par(2,0) = randomStarts endif c Pruefe, ob die Foliendicke falls noetig tatsaechlich groesser Null ist. c Geht die Foliendicke nicht in die Berechnungen ein, setze sie auf Null. if (log_E_Verlust_ICRU .OR. log_Meyer_Gauss .OR. log_Meyer_F_Function + .OR. log_E_Straggling_Lindhard .OR. log_E_Straggling_Yang) then if (par(1,Thickn).LE.0 .OR. par(2,Thickn).LE.0) then write(*,*) if (log_E_Verlust_ICRU) then write(*,*)'Energieverlust in Triggerfolie soll aus ICRU-Tabelle berechnet werden.' endif if (log_Meyer_Gauss .OR. log_Meyer_F_Function) then write(*,*)'Winkelaufstreuung in Triggerfolie soll nach Meyer-Formel berechnet werden.' endif if (log_E_Straggling_Lindhard) then write(*,*)'Energieverluststreuung in C-folie soll nach Lindhard/Scharff berechnet werden.' endif if (log_E_Straggling_Yang) then write(*,*)'Energieverluststreuung in C-folie soll nach Yang berechnet werden.' endif write(*,*)'=> Foliendicke muss positiv sein!' write(*,*) call exit endif else do k = 1, 3 par(k,Thickn) = 0. enddo endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c die Parameter fuer die Schleifen setzen und die Gesamtzahl startender c Projektile berechnen: call adjustLoops if (n_par(0).EQ.1) OneStartPerLoop = .true. SchleifenZahl = GesamtZahl/n_par(0) if (SchleifenZahl.EQ.1) OneLoop = .true. c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Bereiche der Winkeleinstellungen checken: if (abs(par(1,alfTgt)).GT.15 .OR. + abs(par(2,alfTgt)).GT.15) then write(*,*) write(*,*) 'Der Bereich moeglicher Targetwinkel ist auf '// + '[-15,15] eingeschraenkt!' write(*,*) call exit endif if (par(1,alfSP).LT.30 .OR. par(1,alfSP).GT.60 .OR. + par(2,alfSP).LT.30 .OR. par(2,alfSP).GT.60) then write(*,*) write(*,*) 'Der Bereich moeglicher Spiegelwinkel ist auf '// + '[30,60] eingeschraenkt!' write(*,*) call exit endif if (abs(par(1,alfTD)).GT.30 .OR. + abs(par(2,alfTD)).GT.30) then write(*,*) write(*,*) 'Der Bereich moeglicher Triggerwinkel ist auf '// + '[-30,30] eingeschraenkt!' write(*,*) call exit endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Falls der Verdrehungswinkel des TDs Null ist und auch nicht geaendert werden c soll sind alpha gemessen im Kammersystem und alpha gemessen im Triggersystem c gleich. Deswegen: bleib dann gleich im Triggersystem: if (log_alpha0_KS) then if (par(1,alfTD).EQ.0. .AND. n_par(alfTD).LE.1) then log_alpha0_KS = .false. else write(par_text(thetAng)(7:10),'(A4)')'(KS)' write(par_text(phiAng)(7:10),'(A4)')'(KS)' endif endif c if (startFlaeche.NE.0) then alfaTgtVertically = .false. elseif (alfaTgtVertically) then write(par_text(alfTgt)(10:10),'(A1)') 'V' endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c falls kein NTupel erzeugt werden soll brauchen die Daten gar nicht erst fuer c die Ntupelausgabe gespeichert zu werden. Falls umgekehrt das NTupel eh nicht c gefuellt wird, erzeuge es erst gar nicht: if (.NOT.createNTP) then NTP_S1xM2 = .false. NTP_times = .false. NTP_FoM2Only = .false. NTP_charge = .false. NTP_lifeTime = .false. NTP_start = .false. NTP_stop = .false. NTP_40mm = .false. NTP_Folie = .false. NTP_steps = .false. xM2_triggered= .false. M2_triggered = .false. Fo_triggered = .false. elseif (.NOT. (NTP_S1xM2.OR.NTP_times.OR.NTP_FoM2Only.OR. + NTP_charge.OR.NTP_lifeTime.OR.NTP_start.OR. + NTP_stop.OR.NTP_40mm.OR.NTP_Folie.OR.NTP_steps)) then createNTP = .false. endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c setze Triggerbedingungen, die bereits durch andere Triggerbedingungen c abgedeckt sind, auf .false.: if (Fo_triggered) then xM2_triggered = .false. M2_triggered = .false. elseif (xM2_triggered) then M2_triggered = .false. endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Bei Debug grundsaetzlich die RunNummern von 9900 bis 9999 verwenden (TestRun). c Bei Debug soll volles Logfile erstellt werden. Falls jedoch keine Projektil- c DEBUG-Informationen verlangt sind, unterlasse auch die Ausgabe von FE- c DEBUG-Informationen: if (DEBUG) then if (debug_Anzahl.EQ.0) then write(*,1000) 'debug_Anzahl = 0','es werden keine'// + 'DEBUG-Informationen ausgegeben' flag_message = .true. debug = .false. else debug_Anzahl = min(debug_Anzahl,n_par(0)) TestRun = .true. if (abs(n_outWhere.LT.1)) then n_outWhere = 1 elseif (abs(n_outWhere).GT.2) then n_outWhere = 2 endif endif else DEBUG_FE = .false. endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Marke 1 ====================================================================== if (.NOT.TriggerInBeam) then GridInFrontOfFoil = .false. generate_FE = .false. ! dadurch fallen bereits einige SUM_.., ! PHY_.. und TAB_.. weg SUM_S1Fo = .false. SUM_FoM2 = .false. SUM_y_Fo = .false. SUM_z_Fo = .false. SUM_r_Fo = .false. PHY_S1Fo = .false. PHY_FoM2 = .false. PHY_y_Fo = .false. PHY_z_Fo = .false. PHY_r_Fo = .false. TAB_S1Fo = .false. TAB_FoM2 = .false. TAB_y_Fo = .false. TAB_z_Fo = .false. TAB_r_Fo = .false. endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Falls keine Folienelektronen generiert werden sollen, setze alle Aktionen, c die auf ihnen beruhen auf .false.. Falls umgekehrt weder FE-Trajektorien c gezeichnet noch FE-Informationen verarbeitet werden sollen, generiere erst c gar keine FE: if (.NOT.generate_FE) then log_out_FE = .false. plot_FE = .false. debug_FE = .false. SUM_S1M3 = .false. SUM_M3M2 = .false. SUM_t_FE = .false. PHY_S1M3 = .false. PHY_M3M2 = .false. PHY_t_FE = .false. TAB_S1M3 = .false. TAB_M3M2 = .false. TAB_t_FE = .false. elseif (.NOT.(log_out_FE .OR. plot_FE .OR. + SUM_S1M3 .OR. SUM_M3M2 .OR. SUM_t_FE .OR. + PHY_S1M3 .OR. PHY_M3M2 .OR. PHY_t_FE .OR. + TAB_S1M3 .OR. TAB_M3M2 .OR. TAB_t_FE ) ) then generate_FE = .false. endif c Marke 2 ====================================================================== c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c welche Ausgabekanaele sollen fuer das Summary durchlaufen werden? if (n_outWhere.NE.0) then if (abs(n_outWhere).GT.3) then write(*,*) write(*,*) 'Der Bereich von n_outWhere ist auf '// + '[-3,3] eingeschraenkt!' write(*,*) call exit elseif (n_outWhere.LT.0) then smallLogFile = .true. n_outWhere = abs(n_outWhere) elseif (n_outWhere.LE.2) then LogFile = .true. ! volles Summary-File endif indx1 = int((n_outWhere+1)/2) ! = 1,1,2 fuer n_outWhere=1,2,3 indx2 = int((n_outWhere+2)/2) ! = 1,2,2 fuer n_outWhere=1,2,3 endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Uebertragen der logicals fuer die zu erzeugenden Tabellen: c Falls irgendwelche Tabellenfiles erzeugt werden sollen, setze 'createTabellen' c auf .true.: createTabelle(Nr_S1xM2)= TAB_S1xM2 createTabelle(Nr_S1M2) = TAB_S1M2 createTabelle(Nr_S1Fo) = TAB_S1Fo createTabelle(Nr_FoM2) = TAB_FoM2 createTabelle(Nr_S1M3) = TAB_S1M3 createTabelle(Nr_M3M2) = TAB_M3M2 createTabelle(Nr_t_FE) = TAB_t_FE createTabelle(Nr_y_Fo) = TAB_y_Fo createTabelle(Nr_z_Fo) = TAB_z_Fo createTabelle(Nr_r_Fo) = TAB_r_Fo createTabelle(Nr_y_M2) = TAB_y_M2 createTabelle(Nr_z_M2) = TAB_z_M2 createTabelle(Nr_r_M2) = TAB_r_M2 createTabelle(Nr_y_xM2) = TAB_y_xM2 createTabelle(Nr_z_xM2) = TAB_z_xM2 createTabelle(Nr_r_xM2) = TAB_r_xM2 do k = 1, Stat_Anzahl if (createTabelle(k)) createTabellen = .true. enddo c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Uebertragen der logicals fuer die im Logfile auszugebenden Statistiken. c Falls im Summary irgendwelche Statistiken ausgegeben werden sollen, setze c 'statsInSummary' auf .true.: statInSummary(Nr_S1xM2)= SUM_S1xM2 statInSummary(Nr_S1M2) = SUM_S1M2 statInSummary(Nr_S1Fo) = SUM_S1Fo statInSummary(Nr_FoM2) = SUM_FoM2 statInSummary(Nr_S1M3) = SUM_S1M3 statInSummary(Nr_M3M2) = SUM_M3M2 statInSummary(Nr_t_FE) = SUM_t_FE statInSummary(Nr_y_Fo) = SUM_y_Fo statInSummary(Nr_z_Fo) = SUM_z_Fo statInSummary(Nr_r_Fo) = SUM_r_Fo statInSummary(Nr_y_M2) = SUM_y_M2 statInSummary(Nr_z_M2) = SUM_z_M2 statInSummary(Nr_r_M2) = SUM_r_M2 statInSummary(Nr_y_xM2)= SUM_y_xM2 statInSummary(Nr_z_xM2)= SUM_z_xM2 statInSummary(Nr_r_xM2)= SUM_r_xM2 do k = 1, stat_Anzahl if (statInSummary(k)) statsInSummary = .true. enddo c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Uebertragen der logicals fuer die im .PHYSICA file auszugebenden Statistiken c und die statistischen Groessen: if (createPhysTab) then statInPHYSICA(Nr_S1xM2)= PHY_S1xM2 statInPHYSICA(Nr_S1M2) = PHY_S1M2 statInPHYSICA(Nr_S1Fo) = PHY_S1Fo statInPHYSICA(Nr_FoM2) = PHY_FoM2 statInPHYSICA(Nr_S1M3) = PHY_S1M3 statInPHYSICA(Nr_M3M2) = PHY_M3M2 statInPHYSICA(Nr_t_FE) = PHY_t_FE statInPHYSICA(Nr_y_Fo) = PHY_y_Fo statInPHYSICA(Nr_z_Fo) = PHY_z_Fo statInPHYSICA(Nr_r_Fo) = PHY_r_Fo statInPHYSICA(Nr_y_M2) = PHY_y_M2 statInPHYSICA(Nr_z_M2) = PHY_z_M2 statInPHYSICA(Nr_r_M2) = PHY_r_M2 statInPHYSICA(Nr_y_xM2)= PHY_y_xM2 statInPHYSICA(Nr_z_xM2)= PHY_z_xM2 statInPHYSICA(Nr_r_xM2)= PHY_r_xM2 whatInPHYSICA(1) = PHY_mean whatInPHYSICA(2) = PHY_variance whatInPHYSICA(3) = PHY_minimum whatInPHYSICA(4) = PHY_maximum whatInPHYSICA(5) = PHY_percent endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Sollte pro Schleife nur ein Teilchenstart erfolgen oder umgekehrt ausser c der 'Zufalls-Schleife' keine anderen Schleife durchlaufen werden, setze c 'createPhysTab' auf .false. und unterlasse die Ausgabe von Tabellenfiles: if ((OneStartPerLoop.OR.OneLoop) .AND. (createPhysTab.OR.createTabellen)) then write(*,*) ' nur eine Schleife bzw. nur ein Start pro Schleife' if (createPhysTab) then createPhysTab = .false. write(*,*) ' -> set ''createPhysTab'' to ''.false.''' flag_message = .true. endif if (createTabellen) then createTabellen = .false. do k = 1, Stat_Anzahl createTabelle(k) = .false. enddo write(*,*) ' -> set ''createTabellen'' to ''.false.''' endif flag_message = .true. endif c falls im .PHYSICA file keine Statistiken oder keine statistischen Groessen c ausgegeben werden sollen, setze 'createPhysTab' auf .false. if (createPhysTab) then flag = .false. do k = 1, stat_Anzahl if (statInPHYSICA(k)) flag = .true. enddo if (.NOT.flag) then createPhysTab = .false. write(*,*) ' no statistics specified for PHYSICA -> set ''createPhysTab'' to ''.false.''' flag_message = .true. else flag = .false. do k = 1, what_Anzahl if (whatInPHYSICA(k)) flag = .true. enddo if (.NOT.flag) then createPhysTab = .false. write(*,*) ' no statistical entities specified -> set ''createPhysTab'' to ''.false.''' flag_message = .true. endif endif endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c wenn keine Ausgabe des LOG-files vorgesehen ist, aber das PHYSICA-file, das c NTP-file oder ein 'foilFile' erzeugt werden soll, dann ist zumindest die c Minimalversion des LOG-files zu erstellen: if (.NOT.LogFile .AND. (createPhysTab.OR.createNTP.OR.createFoilFile)) then smallLogFile = .true. ! Minimalversion erzeugen endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Falls weder grosses noch kleines Summary ausgegeben werden soll, und auch die c Bildschirmausgabe unterbleibt, setze alle statInSummary auf .false.: if (statsInSummary .AND. .NOT.(LogFile .OR. smallLogFile) .AND. n_outWhere.LT.2) then statsInSummary = .false. do k = 1, stat_Anzahl statInSummary(k) = .false. enddo endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c pruefe, fuer welche Groessen Statistiken gefuehrt werden muessen, und setze c das jeweilige 'statNeeded' auf .true.: do k = 1, Stat_Anzahl if (createTabelle(k).OR.statInSummary(k).OR.statInPHYSICA(k)) then statNeeded(k) = .true. endif enddo c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Bei batch jobs: entweder alle oder keine Postskripts erzeugen: if (batch_mode .AND. graphics) then if (n_postSkript.GE.1) then n_postSkript = 2 graphics_Anzahl = min(graphics_Anzahl,50) else write(*,*) write(*,*)'Ausgabe von Postskripts bei batch jobs nur, wenn ''GRAPHICS''=.true.' write(*,*)'und ''n_Postskript''>0.' write(*,*)'-> es werden keine .PS-files erstellt!' write(*,*) graphics = .false. endif endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1000 format(x,A,T36,'->',T40,A) c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c falls keinerlei output erzeugt werden soll, breche Programm ab: if (.NOT.(createTabellen.OR.graphics.OR.LogFile.OR.smallLogFile.OR + .n_outWhere.GT.1)) then write(*,*) write(*,*)' -> according to input file no output would be produced' write(*,*) call exit endif c Hole Zustimmung fuer abgeaenderte Parameter ein: if (flag_message .AND. .NOT.BATCH_MODE) then write(*,1010) 1010 format(' ok? ( = ABBRUCH)',T36'-> ',$) read(*,'(A)') antwort call str$upCase(antwort,antwort) k = 0 1 k = k+1 if (antwort(k:k).eq.' ' .AND. k.LE.4) goto 1 if (antwort(k:k).eq.'N' .OR. antwort(k:k).eq.'A' .OR. + antwort(k:k).eq.'C' ) then write(*,*) call exit endif endif c bei Verwendung von 'input_list' korrigiere noetigenfalls den Wert von c 'testRun' (dort kann auch Ausgabefilenummer .ge. 9900 angegeben werden c ohne dass der Run im INPUT-file als solcher markiert wurde) if (input_list.AND.gotFileNr) testRun = testRun_ c falls kein Summary-File erstellt wird, braucht auch die 'T E S T - R U N' - c Meldung nicht auf dem Bildschirm erscheinen: if (.NOT.(logFile.OR.smallLogFile)) testRun = .false. c Bedingungen fuer die Ausgabe der Prozentzahl schon gerechneter Teilchen c pruefen: if (.NOT.BATCH_MODE .AND. n_par(0).GE.50 .AND. n_outWhere.GE.2) then log_percent = .true. endif c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c n_par der unbenutzten Schleifen auf 0 setzen (dies hat 1. zur Folge, dass c die Ausgabe dieser unbenutzten Parameter im Logfile unterbleibt, und dass c sie 2. auch nicht an PHYSICA weitergegeben werden): c (der Spiegelwinkel wird dann unterdrueckt, wenn er konstant 45 degree hat, c da hier dies die Normaleinstellung ist). if (random_E0) then if (par(1,ener).EQ.0. .AND. par(2,ener).EQ.0.) then n_par(ener) = 0 ener_offset = .false. ! default = .true. endif else if (par(1,ener).EQ.0. .AND. par(2,ener).EQ.0.) then n_par(phiAng) = 0 endif endif if (random_pos .AND. + par(1,yPos).EQ.0. .AND .par(2,yPos).EQ.0. .AND. + par(1,zPos).EQ.0. .AND .par(2,zPos).EQ.0. ) then n_par(yPos) = 0 n_par(zPos) = 0 pos_offset = .false. ! default = .true. endif if (random_angle .AND. + par(1,thetAng).EQ.0. .AND .par(2,thetAng).EQ.0. .AND. + par(1,phiAng).EQ.0. .AND .par(2,phiAng).EQ.0. ) then n_par(thetAng) = 0 n_par(phiAng) = 0 angle_offset = .false. ! default = .true. endif if (.NOT.random_angle .AND. + par(1,thetAng).EQ.0. .AND .par(2,thetAng).EQ.0. ) then n_par(phiAng) = 0 endif if (.NOT.TriggerInBeam) then n_par(UFolie) = 0 n_par(UVorne) = 0 n_par(UHinten) = 0 n_par(UMCP3) = 0 n_par(alfTD) = 0 n_par(Eloss) = 0 endif if (upToTDFoilOnly) then n_par(UL3) = 0 n_par(UMCP2) = 0 if (.NOT.generate_FE) then n_par(UVorne) = 0 n_par(UHinten) = 0 n_par(UMCP3) = 0 endif endif if (.NOT.guard) n_par(UGua) = 0 if (artlist_defined) n_par(mass) = 0 if (par(1,alfTgt) .EQ.0. .AND. par(2,alfTgt) .EQ.0.) n_par(alfTgt) = 0 if (par(1,alfSp) .EQ.45. .AND. par(2,alfSp ).EQ.45.) n_par(alfSp) = 0 if (par(1,ThetAng).EQ.0. .AND. par(2,ThetAng).EQ.0.) n_par(ThetAng) = 0 if (par(1,PhiAng) .EQ.0. .AND. par(2,PhiAng) .EQ.0.) n_par(PhiAng) = 0 if (par(1,alfTD) .EQ.0. .AND. par(2,alfTD) .EQ.0.) n_par(alfTD) = 0 if (par(1,Eloss) .EQ.0. .AND. par(2,Eloss) .EQ.0.) n_par(Eloss) = 0 if (par(1,Thickn) .EQ.0. .AND. par(2,Thickn) .EQ.0.) n_par(Thickn) = 0 if (par(1,BHelm) .EQ.0. .AND. par(2,BHelm) .EQ.0.) n_par(BHelm) = 0 if (par(1,BTD) .EQ.0. .AND. par(2,BTD) .EQ.0.) n_par(BTD) = 0 if (par(1,deltaL1).EQ.0. .AND. par(2,deltaL1).EQ.0.) n_par(deltaL1) = 0 if (par(1,deltaL2).EQ.0. .AND. par(2,deltaL2).EQ.0.) n_par(deltaL2) = 0 if (mappenName_L2andFo.EQ.' ') n_par(UL2) = 0. c noch ein paar Einstellungen fuer die Graphikausgabe ueberpruefen: if (.NOT.graphics) then writeTraj2File = .false. elseif (schnitt_x.LT.0) then GRAPHICS_Anzahl = min(GRAPHICS_Anzahl,n_par(0)) ! fuer 'schnitt_x' kein Wert vorgegeben => setze Defaultwert ein: schnitt_x = xMCP2 endif END c=============================================================================== OPTIONS /EXTEND_SOURCE SUBROUTINE adjustLoops c ====================== IMPLICIT NONE INCLUDE 'mutrack$sourcedirectory:COM_MUTRACK.INC' integer k,nn real help, factor, step GesamtZahl=1 do k = 0 , par_Anzahl ! k=0: 'Zufalls-Schleife' if (par(2,k).NE.1.E10) then ! wurde maxWert vorgegeben? if (par(2,k).EQ.par(1,k).OR.par(3,k).EQ.0.) then par(2,k) = par(1,k) par(3,k) = 1. ! step = 0 vermeiden else ! wurde step vorgegeben? if (par(3,k).EQ.-1.E10) par(3,k)=par(2,k)-par(1,k) endif else if (k.EQ.UGua .AND. (par(1,UGua).EQ.-1.E10 .OR. + fromScratch ) ) then guard = .false. ! default = .true. par(1,UGua) = 0 endif par(2,k) = par(1,k) par(3,k) = 1. endif ! es kam vor, dass wegen der endlichen Genauigkeit numerischer Zahlen ! die letzte Schleife nicht durchlaufen wurde. Deshalb wurden folgende ! Befehlszeilen eingebaut: factor = 1 step = par(3,k) 1 do help = par(1,k), par(2,k), step ! just count the loop index enddo ! falls jetzt 'help' gerade geringfuegig 'hinter' par(2,k) liegt, ! also aufgrund von Rundungsfehlern die letzte Schleife, die ! eigentlich durchlaufen werden sollte nicht durchlaufen werden ! wuerde, so reduziere schrittweise 'step', bis letzte Schleife ! wieder akzeptiert wird: ! (nachdem die Schleife fuer erledigt erklaert wurde ist ! ((help-par(2,k))/step auf jeden Fall groesser Null!) if ((help-par(2,k))/step.LT.1.E-3) then factor = factor - 0.00000003 ! (smallest number that should ! work) step = par(3,k) * factor C WRITE(*,*) 'HELP, FACTOR, STEP = ',HELP,FACTOR, STEP goto 1 endif par(3,k) = step C WRITE(*,*) 'FINAL: HELP, FACTOR, STEP = ',HELP,FACTOR, STEP n_par(k) = int((par(2,k)-par(1,k)+par(3,k))/par(3,k) +.5) ! so werden laut if (n_par(k).LE.0) n_par(k)=1 ! library die Anzahlen der Durchlaeufe berechnet c da es hier immer noch Schwierigkeiten gab (oder vielleicht noch gibt?) hier c noch eine zusaetzliche Kontrolle: Bestimme mittels Probedurchlauf die Anzahl c der wirklich durchlaufenen Schleifen und vergleiche mit erwartetem Wert. c Falls hier immer noch Abweichungen bestehen, breche mit Fehlermeldung ab: nn = 0 do help = par(1,k), par(2,k), par(3,k) ! just count the loops nn = nn + 1 enddo if (n_par(k).NE.nn) then write(*,*) 'SUBROUTINE ''adjustLoops'' in ''SUB_INPUT.FOR'':' write(*,*) 'A L A R M: n_par(k).NE.nn' write(*,*) ' n_par(k) = ',n_par(k) write(*,*) ' nn = ',nn write(*,*) par_Text(k) call exit endif 99 GesamtZahl = GesamtZahl * n_par(k) c setze Parameter, deren Variation sinnlos waere auf Null: if (k.EQ.ener .AND. .NOT.random_E0 .AND. + n_par(ener).LE.1 .AND. par(1,ener).EQ.0. ) then par(1,thetang) = 0. par(2,thetang) = 0. par(1,phiAng) = 0. par(2,phiAng) = 0. random_angle = .false. random_lambert = .false. random_gauss = .false. elseif (k.EQ.thetAng .AND. + n_par(thetAng).LE.1 .AND. par(1,thetAng).EQ.0. ) then par(1,phiAng) = 0. par(2,phiAng) = 0. endif if (par(1,k).EQ.-1.e10) then par(1,k) = 0. par(2,k) = 0. par(3,k) = 1. n_par(k) = 0 endif enddo END c=============================================================================== OPTIONS /EXTEND_SOURCE SUBROUTINE READ_ACCEL_GEOMETRY c ============================== IMPLICIT NONE c Diese Subroutine liesst bei Verwendung von ACCEL-Simulationen des realen c Beschleunigers die den Daten zugrundeliegende Beschleunigergeometrie ein. c Dieser Quelltext steht in einer einenen Subroutine, um Verwirrungen um c die Speicherbezeichnungen bei MUTRACK und ACCEL im Vorfeld zu vermeiden. INCLUDE 'mutrack$sourcedirectory:COM_KAMMER.INC' INCLUDE 'mutrack$sourcedirectory:COM_MUTRACK.INC' INCLUDE 'mutrack$sourcedirectory:COM_DIRS.INC' c------------------------------------------------------------------------------- namelist /geometry/ + scaleFactor, + xFoil, + xEnd_TgtHolder,Dy_Foil,Dz_Foil,Dy_TgtHolder,Dz_TgtHolder, + outerDy_TgtHolder,outerDz_TgtHolder, + innerDy1_TgtHolder,innerDz1_TgtHolder,innerDy2_TgtHolder,innerDz2_TgtHolder, + xStart_Guardring,xEnd_Guardring,innerDy_Guardring,outerDy_Guardring, + innerDz_Guardring,outerDz_Guardring, + xPosition_Grid1,distance_wires1,dWires1,y_Pos_lastWire1, + xStart_Balken,xEnd_Balken,Dy_Balken, + innerDz_Balken,outerDz_Balken, + xStart_Gridframe1,xEnd_Gridframe1,innerDy_Gridframe1,outerDy_Gridframe1, + innerDz_Gridframe1,outerDz_Gridframe1, + xPosition_Grid2,distance_wires2,dWires2,y_Pos_lastWire2, + xStart_Gridframe2,xEnd_Gridframe2,innerDy_Gridframe2,outerDy_Gridframe2, + innerDz_Gridframe2,outerDz_Gridframe2, + rHeShield c Die Groessen, die in der /geometry/-namelist von 'ACCEL' verwendet werden: c - moderator: real xFoil,Dy_Foil,Dz_Foil,xEnd_TgtHolder real innerDy1_TgtHolder,innerDz1_TgtHolder real innerDy2_TgtHolder,innerDz2_TgtHolder real outerDy_TgtHolder,outerDz_TgtHolder c nur um Infofiles von ACCEL-Versionen vor 1.2.1 einlesen zu koennen c (wurden ab Version 1.2.1 ersetzt durch outerDy_TgtHolder, outerDz_TgtHolder): real Dy_TgtHolder, Dz_TgtHolder c - guardring: real xStart_Guardring,xEnd_Guardring,innerDy_Guardring,outerDy_Guardring, + innerDz_Guardring,outerDz_Guardring c - first grid: real xPosition_Grid1,distance_Wires1,dWires1,y_Pos_lastWire1, + xStart_Gridframe1,xEnd_Gridframe1,innerDy_Gridframe1, + outerDy_Gridframe1,innerDz_Gridframe1,outerDz_Gridframe1,xStart_Balken, + xEnd_Balken,Dy_Balken,innerDz_Balken,outerDz_Balken c - second grid: real xPosition_Grid2,distance_Wires2,dWires2,y_Pos_lastWire2, + xStart_Gridframe2,xEnd_Gridframe2,innerDy_Gridframe2, + outerDy_Gridframe2,innerDz_Gridframe2,outerDz_Gridframe2 c - He-shield: ! real rHeShield ! schon in COM_KAMMER.INC enthalten c------------------------------------------------------------------------------- c Einlesen der Target-Geometrie aus dem ACCEL-INFO-file: read(lunREAD,nml=geometry) rewind(lunREAD) if (outerDy_TgtHolder.EQ.-1.E10) outerDy_TgtHolder = Dy_TgtHolder if (outerDz_TgtHolder.EQ.-1.E10) outerDz_TgtHolder = Dz_TgtHolder if (innerDy1_TgtHolder.EQ.-1.E10) innerDy1_TgtHolder = Dy_Foil if (innerDz1_TgtHolder.EQ.-1.E10) innerDz1_TgtHolder = Dz_Foil if (innerDy2_TgtHolder.EQ.-1.E10) innerDy2_TgtHolder = Dy_Foil if (innerDz2_TgtHolder.EQ.-1.E10) innerDz2_TgtHolder = Dz_Foil c gegebenenfalls Beschleunigergeometrie skalieren: c (eigentlich nicht fuer alle noetig, da nicht alle von Mutrack verwendet werden. c Aber besser fuer zu viele als fuer zu wenige...) if (scaleFactor.NE.1) then xFoil = scaleFactor * xFoil xEnd_TgtHolder = scaleFactor * xEnd_TgtHolder Dy_Foil = scaleFactor * Dy_Foil innerDy1_TgtHolder = scaleFactor * innerDy1_TgtHolder innerDz1_TgtHolder = scaleFactor * innerDz1_TgtHolder innerDy2_TgtHolder = scaleFactor * innerDy2_TgtHolder innerDz2_TgtHolder = scaleFactor * innerDz2_TgtHolder outerDy_TgtHolder = scaleFactor * outerDy_TgtHolder outerDz_TgtHolder = scaleFactor * outerDz_TgtHolder Dz_Foil = scaleFactor * Dz_Foil xStart_Guardring = scaleFactor * xStart_Guardring xEnd_Guardring = scaleFactor * xEnd_Guardring innerDy_Guardring = scaleFactor * innerDy_Guardring outerDy_Guardring = scaleFactor * outerDy_Guardring innerDz_Guardring = scaleFactor * innerDz_Guardring outerDz_Guardring = scaleFactor * outerDz_Guardring xPosition_Grid1 = scaleFactor * xPosition_Grid1 distance_wires1 = scaleFactor * distance_wires1 dWires1 = scaleFactor * dWires1 y_Pos_lastWire1 = scaleFactor * y_Pos_lastWire1 xStart_Balken = scaleFactor * xStart_Balken xEnd_Balken = scaleFactor * xEnd_Balken Dy_Balken = scaleFactor * Dy_Balken innerDz_Balken = scaleFactor * innerDz_Balken outerDz_Balken = scaleFactor * outerDz_Balken xStart_Gridframe1 = scaleFactor * xStart_Gridframe1 xEnd_Gridframe1 = scaleFactor * xEnd_Gridframe1 innerDy_Gridframe1 = scaleFactor * innerDy_Gridframe1 outerDy_Gridframe1 = scaleFactor * outerDy_Gridframe1 innerDz_Gridframe1 = scaleFactor * innerDz_Gridframe1 outerDz_Gridframe1 = scaleFactor * outerDz_Gridframe1 xPosition_Grid2 = scaleFactor * xPosition_Grid2 distance_wires2 = scaleFactor * distance_wires2 dWires2 = scaleFactor * dWires2 y_Pos_lastWire2 = scaleFactor * y_Pos_lastWire2 xStart_Gridframe2 = scaleFactor * xStart_Gridframe2 xEnd_Gridframe2 = scaleFactor * xEnd_Gridframe2 innerDy_Gridframe2 = scaleFactor * innerDy_Gridframe2 outerDy_Gridframe2 = scaleFactor * outerDy_Gridframe2 innerDz_Gridframe2 = scaleFactor * innerDz_Gridframe2 outerDz_Gridframe2 = scaleFactor * outerDz_Gridframe2 rHeShield = scaleFactor * rHeShield endif c Uebertragen der Geometriegroessen in die von 'MUTRACK' verwendeten Speicher: c (x-Positionen sind bei 'ACCEL'-Outputs bereits relativ zur Kryoachse; c dy- und dz-Ausdehnungen sind bei 'ACCEL' in 50% des totalen Wertes angegeben) xTarget = xFoil dyTarget = 2 * Dy_Foil dzTarget = 2 * Dz_Foil xGrid1 = xPosition_Grid1 dyGrid1 = 2 * innerDy_Gridframe1 dzGrid1 = 2 * innerDz_Gridframe1 dWires_G1 = dWires1 dist_Wires_G1 = distance_Wires1 xGrid2 = xPosition_Grid2 dyGrid2 = 2 * innerDy_Gridframe2 dzGrid2 = 2 * innerDz_Gridframe2 dWires_G2 = dWires2 dist_Wires_G2 = distance_Wires2 ! Der Radius des He-Schildes ist sowohl bei 'ACCEL' als auch bei ! 'MUTRACK' mit 'rHeShield' bezeichnet, muss also nicht explizit ! uebertragen werden. END c=============================================================================== OPTIONS /EXTEND_SOURCE SUBROUTINE getPreviousSettings c ============================== c Diese Subroutine liest die 'Schleifenparameter', mit denen gegebenenfalls c das 'ACCEL-file' bzw. das 'FoilFile' erstellt worden ist, in ein separates c Feld 'par_prevSim' ein. Dies wird benoetigt, um fuer die jeweiligen Settings c der 'Schleifenparameter' im aktuellen MUTRACK-Run die Nummer derjenigen c Schleife des ACCEL-files bzw. des 'FoilFiles' mit den gleichen Settings c berechnen zu koennen. Es wird geprueft, ob die Werte, die die einzelnen c Parameter jetzt annehmen sollen, auch bei der frueheren Simulation gerechnet c worden sind. c In dieser Routine wird auch ueberprueft, ob jedes der jetzt abzuarbeitenden c Teilchen in der frueheren Simulation gerechnet worden ist, sowie an welcher c Stelle in 'artList' das jeweilige Teilchen bei der frueheren Simlation stand. IMPLICIT NONE INCLUDE 'mutrack$sourcedirectory:COM_MUTRACK.INC' INCLUDE 'mutrack$sourcedirectory:COM_DIRS.INC' namelist /loop_params/ + U_Tgt_,U_Gua_,U_G1_,U_L1_,U_Sp_,U_L2_,U_Folie_, B_Helm_,B_TD_, + alfaTgt_,alfaSp_,alfaTD_,Masse_,Ladung_, + E0_,y0_,z0_,theta0_,phi0_,deltaL1_,U_KL_ ! (U_KL_ nur fuer das Einlesen aelterer foilFile-Versionen) nameList /additionals/ par_Anzahl_prevSim,reihenFolge_prevSim,artenZahl_prevSim, + par_Anzahl_AH ,reihenFolge_AH ,artenZahl_AH, + mappenNameACCEL c 'artListIndx_prevSim(i)' enthaelt die Nummer, die das Teilchen, das jetzt bei c Mutrack an Stelle 'i' in 'artList' steht, waehrend ACCEL bzw. waehrend c 'FoilFile' innehatte. integer par_Anzahl_prevSim,reihenFolge_prevSim(par_Anzahl) real par_prevSim(3,par_Anzahl),n_par_prevSim(par_Anzahl) integer artListIndx_prevSim(arten_zahl),artenZahl_prevSim COMMON /prevSim/ par_Anzahl_prevSim,reihenFolge_prevSim,par_prevSim,n_par_prevSim COMMON /prevSim/ artListIndx_prevSim c Misc.: integer i, par_ real help, factor integer firstIndx_,lastIndx_ integer pos1,pos2 character*4 art,art_prevSim integer artIndx_prevSim real von,bis,step,von_prevSim,bis_prevSim,step_prevSim integer iHelp,errorNr c integer j c fuer Kompatibilitaet mit frueheren Versionen, bei denen statt der Extension c '_prevSim' noch die Extension '_AH' verwendet wurde: integer par_Anzahl_AH /-1.E8/ integer reihenFolge_AH(par_Anzahl) /par_anzahl*-1.E8/ integer artenZahl_AH /-1.E8/ c die lokalen Variablen fuer das Einlesen der Schleifenparameter der freuheren c Simulation, die dann in das Feld 'par_prevSim' uebertragen werden: ! von ! bis ! step ! real U_Tgt_(3) / 0. , +1.e10 , -1.e10 / real U_Gua_(3) / -1.e10 , +1.e10 , -1.e10 / real U_G1_(3) / 0. , +1.e10 , -1.e10 / real U_L1_(3) / 0. , +1.e10 , -1.e10 / real U_Sp_(3) / 0. , +1.e10 , -1.e10 / real U_L2_(3) / 0. , +1.e10 , -1.e10 / c Fuer das Einlesen aelterer foilFile-Versionen: real U_KL_(3) / -1.e10 , +1.e10 , -1.e10 / real U_Folie_(3) / 0. , +1.e10 , -1.e10 / real B_Helm_(3) / 0. , +1.e10 , -1.e10 / real B_TD_(3) / 0. , +1.e10 , -1.e10 / real alfaTgt_(3) / 0. , +1.e10 , -1.e10 / real alfaSp_(3) / 45. , +1.e10 , -1.e10 / real alfaTD_(3) / 0. , +1.e10 , -1.e10 / real Masse_(3) / 105659. , +1.e10 , -1.e10 / real Ladung_(3) / 1. , +1.e10 , -1.e10 / real E0_(3) / 0. , +1.e10 , -1.e10 / real y0_(3) / 0. , +1.e10 , -1.e10 / real z0_(3) / 0. , +1.e10 , -1.e10 / real theta0_(3) / 0. , +1.e10 , -1.e10 / real phi0_(3) / 0. , +1.e10 , -1.e10 / real deltaL1_(3) / 0. , +1.e10 , -1.e10 / c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c in ParAC2ParMu(i,j) steht, welche CodeZahl die jetztige MUTRACK-Version c fuer denjenigen Parameter verwendet, der von ACCEL (waehrend der vom c VersionIndx 'j' abgedeckten Versionen) unter der CodeNummer 'i' c gefuehrt wurde: c ParAC2ParMu = ParAC2ParMu(parAC,VersionIndx) c (bei der Zuordnung unbelegte Nummern sind auf Null zu setzen) integer ParAC2ParMu(12,2) DATA ParAC2ParMu / c AccelVersionIndx = 1: noch ohne Magnetfelder c Nummer waehrend ACCEL: c 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12 c Nummer bei aktueller MUTRACK-Version: + 1, 2, 3,18,19,20,21,22,23,24, 0, 0, ! AccelVersionIndx = 1 + 1, 2, 3,13,14,18,19,20,21,22,23,24/ ! AccelVersionIndx = 2 c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c in ParMU2ParMu(i,j) steht, welche CodeZahl die jetztige MUTRACK-Version c fuer denjenigen Parameter verwendet, der waehrend 'foilFile' (waehrend der c vom VersionIndx 'j' abgedeckten Versionen) unter der CodeNummer 'i' gefuehrt c wurde: c ParMu2ParMu = ParMu2ParMu(parMU,VersionIndx) c (bei der Zuordnung unbelegte Nummern sind auf Null zu setzen) c (Die vorliegende Mutrack-Version gehoert mit zum hoechsten MutrackVersionIndx. c Daher gibt es fuer das hoechste 'MutrackVersionIndx' eine eins zu eins Ent- c sprechung der CodeZahlen, weshalb in der letzten Initialisierungszeile c fuer 'ParMU2ParMu' einfach die ganzen Zahlen von 1 bis par_Anzahl durchge- c zaehlt sind. integer ParMU2ParMu(par_Anzahl,2) DATA ParMU2ParMu / c Nummer waehrend frueherer Version: c 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15|16|17|18|19|20| c 21|22|23|24|25|26|27|28 c Nummer jetzt: + 1, 2, 3, 4, 5, 7, 8, 9,10,11,12,15,16,17,18,19,20,21,22,23, ! indx = 1 + 24,25,26,27,28, 0, 0, 0, ! indx = 1 + 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20, ! indx = 2 + 21,22,23,24,25,26,27,28/ ! indx = 2 c------------------------------------------------------------------------------- c Lies die Einstellungen der Schleifenparameter waehrend der Simulation mit c ACCEL bzw. waehrend 'createFoilFile': read(lunREAD,nml=loop_params) rewind(lunREAD) read(lunREAD,nml=additionals) rewind(lunREAD) ! fuer Kompatibilitaet mit aelteren foilFile-Versionen: if (U_KL_(1).NE.-1.e10) then do i = 1, 3 U_L1_(i) = U_KL_(i) enddo endif c fuer Kompatibilitaet mit frueheren Versionen, bei denen statt der Extension c '_prevSim' noch die Extension '_AH' verwendet wurde: if (par_Anzahl_AH.NE.-1.E8) par_Anzahl_prevSim = par_Anzahl_AH if (reihenFolge_AH(1).NE.-1.E8) then do i = 1, par_Anzahl_prevSim reihenFolge_prevSim(i) = reihenFolge_AH(i) enddo endif if (artenZahl_AH.NE.-1.E8) artenZahl_prevSim = artenZahl_AH c Ersetze die von Accel bzw. von FoilFile verwendeten Parameter-Codenummern c durch die von der aktuellen MUTRACK-Version verwendeten Codenummern: c write(*,*) 'mutrackVersionIndx = ',mutrackVersionIndx do i = 1 , par_Anzahl_prevSim par_ = reihenFolge_prevSim(i) if (use_accel) then reihenFolge_prevSim(i) = parAC2parMU(par_,accelVersionIndx) else ! => use_MUTRACK reihenFolge_prevSim(i) = parMU2parMU(par_,mutrackVersionIndx) c write(*,*) par_,' wird zu ',reihenFolge_prevSim(i) endif enddo c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Vergleich von 'artList' und 'artList_prevSim': if ((artList_prevSim.NE.' ' .AND. .NOT.artList_defined) .OR. + (artList_prevSim.EQ.' ' .AND. artList_defined) ) then write(*,*) 'missmatch 111' call exit endif c Entfernen der embedded blanks aus 'artList_prevSim': pos 2 = 0 do pos1 = 1, len(artList_prevSim) if(artList_prevSim(pos1:pos1).NE.' ') then pos2 = pos2 + 1 artList_prevSim(pos2:pos2) = artList_prevSim(pos1:pos1) endif enddo do pos1 = pos2+1, len(artList_prevSim) artList_prevSim(pos1:pos1) = ' ' enddo if (artList_defined) then ! Pruefe fuer jeden Eintrag in 'artlist', ob er auch in 'artList_prevSim' ! vorhanden ist. Lege die Nummer des entsprechenden Teilchens ! in 'artList_prevSim' in 'artListIndx_prevSim' ab: do i = 1, par(2,charge) ! fuer jede Art aus 'artlist' art = art_Name(art_Nr(i)) pos1 = 0 pos2 = 0 artIndx_prevSim = 0 do while (pos2.LE.50) pos2 = Index(artList_prevSim(pos1+1:50),',') if (pos2.EQ.0) pos2=51 art_prevSim = artList_prevSim(pos1+1:pos2-1) artIndx_prevSim = artIndx_prevSim + 1 if (art.EQ.art_prevSim) then artListIndx_prevSim(i) = artIndx_prevSim c write(*,'(x,A,I2)') ' das Teilchen '//art//' hat in ''artList_prevSim'' die Position ',artIndx_prevSim goto 1 endif pos1 = pos2 enddo write(*,*) ' Teilchen '//art//' ist nicht im ACCEL-file bzw. ''Foilfile'' enthalten!' write(*,*) ' ''artList_prevSim'' = ',artList_prevSim call exit 1 enddo endif c write(*,*) 'artListIndx_prevSim = ',artListIndx_prevSim c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c Uebertragen der Schleifenparameter in das Feld 'par_prevSim': do i = 1, 3 par_prevSim(i,UTgt) = U_Tgt_ (i) par_prevSim(i,UGua) = U_Gua_ (i) par_prevSim(i,UG1) = U_G1_ (i) par_prevSim(i,UL1) = U_L1_ (i) par_prevSim(i,USp) = U_Sp_ (i) par_prevSim(i,UL2) = U_L2_ (i) par_prevSim(i,UFolie) = U_Folie_ (i) par_prevSim(i,BHelm) = B_Helm_ (i) par_prevSim(i,BTD) = B_TD_ (i) par_prevSim(i,alfTgt) = alfaTgt_ (i) par_prevSim(i,alfSp) = alfaSp_ (i) par_prevSim(i,alfTD) = alfaTD_ (i) par_prevSim(i,mass) = Masse_ (i) par_prevSim(i,charge) = Ladung_ (i) par_prevSim(i,ener) = E0_ (i) par_prevSim(i,yPos) = y0_ (i) par_prevSim(i,zPos) = z0_ (i) par_prevSim(i,thetAng) = theta0_ (i) par_prevSim(i,phiAng) = phi0_ (i) par_prevSim(i,DeltaL1) = DeltaL1_ (i) enddo c Bestimme 'par_prevSim' und 'n_par_prevSim' sowie 'par' und 'n_par' (Fuer c Kommentare zur Vorgehensweise siehe Subroutine 'adjustLoops'): if (artList_defined) then par_prevSim(1,mass) = 1. par_prevSim(2,mass) = 1. par_prevSim(1,charge) = 1. par_prevSim(2,charge) = artenZahl_prevSim endif do i = 1 , par_Anzahl_prevSim par_ = reihenFolge_prevSim(i) c - PREVIOUS SIMULATION: if (par_prevSim(2,par_).NE.1.E10) then ! wurde maxWert vorgegeben? if (par_prevSim(2,par_).EQ.par_prevSim(1,par_) .OR. par_prevSim(3,par_).EQ.0.) then par_prevSim(2,par_) = par_prevSim(1,par_) par_prevSim(3,par_) = 1. else ! wurde step vorgegeben? if (par_prevSim(3,par_).EQ.-1.E10) then par_prevSim(3,par_) = par_prevSim(2,par_) - par_prevSim(1,par_) endif endif else if (par_.EQ.UGua .AND. par_prevSim(1,UGua).EQ.-1.E10) then guard = .false. ! default = .true. par(1,UGua) = 0. par(2,UGua) = 0. par_prevSim(1,UGua) = 0. endif par_prevSim(2,par_) = par_prevSim(1,par_) par_prevSim(3,par_) = 1. endif factor = 1 step = par_prevSim(3,par_) 2 do help = par_prevSim(1,par_), par_prevSim(2,par_), step ! just count the loop index enddo if ((help-par_prevSim(2,par_))/step.LT.1.E-4) then factor = factor - 0.00000003 ! (smallest number that works) step = par_prevSim(3,par_) * factor goto 2 endif par_prevSim(3,par_) = step n_par_prevSim(par_) = int((par_prevSim(2,par_)-par_prevSim(1,par_)+par_prevSim(3,par_))/par_prevSim(3,par_) +.5) if (n_par_prevSim(par_).LE.0) n_par_prevSim(par_)=1 c - MUTRACK: if (par(2,par_).NE.1.E10) then ! wurde maxWert vorgegeben? if (par(2,par_).EQ.par(1,par_) .OR. par(3,par_).EQ.0.) then par(2,par_) = par(1,par_) par(3,par_) = 1. else ! wurde step vorgegeben? if (par(3,par_).EQ.-1.E10) then par(3,par_) = par(2,par_) - par(1,par_) endif endif else par(2,par_) = par(1,par_) par(3,par_) = 1. endif factor = 1 step = par(3,par_) 3 do help = par(1,par_), par(2,par_), step ! just count the loop index enddo if ((help-par(2,par_))/step.LT.1.E-4) then factor = factor - 0.00000003 ! (smallest number that works) step = par(3,par_) * factor goto 3 endif par(3,par_) = step n_par(par_) = int((par(2,par_)-par(1,par_)+par(3,par_))/par(3,par_) +.5) if (n_par(par_).LE.0) n_par(par_)=1 enddo c Pruefe, ob die von MUTRACK zu verwendenden Werte eine Teilmenge derjenigen c Werte darstellen, die von ACCEL bzw. waehrend 'createFoilFile' verwendet c wurden: do i = 1, par_Anzahl_prevSim par_ = reihenFolge_prevSim(i) if (par_.EQ.charge.AND.artList_defined) goto 10 if (n_par(par_).GT.n_par_prevSim(par_)) then errorNr = 1 goto 9999 endif von = par(1,par_) bis = par(2,par_) step = par(3,par_) von_prevSim = par_prevSim(1,par_) bis_prevSim = par_prevSim(2,par_) step_prevSim = par_prevSim(3,par_) c die folgenden Zeilen nochmals ueberpruefen: if (n_par(par_).EQ.1) then if (n_par_prevSim(par_).EQ.1) then if (von_prevSim.EQ.0) then if (abs(von.GT.1.E-4)) then errorNr = 2 goto 9999 endif elseif (abs((von_prevSim-von)/von_prevSim).GT.1.E-4) then errorNr = 3 goto 9999 endif else firstIndx_ = int((von-von_prevSim)/step_prevSim + 0.5) + 1 if ( (firstIndx_.LT.1 .OR. firstIndx_.GT.n_par_prevSim(par_)) .OR. + (abs((von_prevSim+(firstIndx_-1)*step_prevSim-von)/step_prevSim).GT.1.E-4)) then errorNr = 4 goto 9999 endif endif else firstIndx_ = int((von-von_prevSim)/step_prevSim + 0.5) + 1 if ( (firstIndx_.LT.1 .OR. firstIndx_.GT.n_par_prevSim(par_)) .OR. + (abs((von_prevSim+(firstIndx_-1)*step_prevSim-von)/step_prevSim).GT.1.E-4)) then errorNr = 5 goto 9999 endif lastIndx_ = int((bis-von_prevSim)/step_prevSim + 0.5) + 1 if ( (lastIndx_.LT.1 .OR. lastIndx_.GT.n_par_prevSim(par_)) .OR. + (abs((von_prevSim+(lastIndx_-1)*step_prevSim-bis)/step_prevSim).GT.1.E-4)) then if (lastIndx_.LT.1) then write(*,*) 'I: lastIndx_ = ',lastIndx_ endif if (lastIndx_.GT.n_par_prevSim(par_)) then write(*,*) 'II : lastIndx_ = ',lastIndx_ write(*,*) 'II : n_par_prevSim(par_) = ',n_par_prevSim(par_) endif if ((abs((von_prevSim+(lastIndx_-1)*step_prevSim-bis)/step_prevSim).GT.1.E-4)) then write(*,*) 'III: lastIndx_-1 = ',lastIndx_-1 write(*,*) 'III: von_prevSim+(lastIndx_-1)*step_prevSim-bis = ',von_prevSim+(lastIndx_-1)*step_prevSim-bis write(*,*) 'III: ((von_prevSim+(lastIndx_-1)*step_prevSim-bis)/step_prevSim = ', + (von_prevSim+(lastIndx_-1)*step_prevSim-bis)/step_prevSim endif errorNr = 6 goto 9999 endif iHelp = int(step/step_prevSim + 0.5) if (abs((iHelp*step_prevSim-step)/step_prevSim).GT.1.E-4) goto 9999 endif 10 enddo c -> falls wir hier ankommen, sind die beiden Parametersaetze kompatibel! RETURN c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 9999 continue ! -> Fehlermeldung write(*,*) write(*,*) ' =================================================================' write(*,*) ' | Mutrack-Vorgabe ist nicht kompatibel mit frueherer Simulation |' write(*,*) ' | errorCode = ',errorNr,' |' write(*,*) ' =================================================================' write(*,*) write(*,*) write(*,*) 'par_ = ',par_ write(*,*) write(*,*) ' Werte bei frueherer Simulation:' if (n_par_prevSim(par_).LE.1) then write (*,*) ' ',par_text(par_)(1:10),' = ',von_prevSim elseif (n_par_prevSim(par_).EQ.2) then write (*,*) ' ',par_text(par_)(1:10),' = ',von_prevSim,bis_prevSim else write (*,*) ' ',par_text(par_)(1:10),' = ',von_prevSim,bis_prevSim,step_prevSim endif write(*,*) ' jetztige Wertevorgabe:' if (n_par(par_).LE.1) then write (*,*) ' ',par_text(par_)(1:10),' = ',von elseif (n_par(par_).EQ.2) then write (*,*) ' ',par_text(par_)(1:10),' = ',von,bis else write (*,*) ' ',par_text(par_)(1:10),' = ',von,bis,step endif write(*,*) ' =======================================================' write(*,*) call exit END c=============================================================================== OPTIONS /EXTEND_SOURCE integer*4 function firstEventNr() c ================================= IMPLICIT NONE INCLUDE 'mutrack$sourcedirectory:COM_MUTRACK.INC' INCLUDE 'mutrack$sourcedirectory:COM_DIRS.INC' real par_prevSim(3,par_Anzahl),n_par_prevSim(par_Anzahl) integer par_Anzahl_prevSim,reihenFolge_prevSim(par_Anzahl) integer artListIndx_prevSim(arten_zahl) COMMON /prevSim/ par_Anzahl_prevSim,reihenFolge_prevSim,par_prevSim,n_par_prevSim COMMON /prevSim/ artListIndx_prevSim integer qIndxMu common /qIndxMu/ qIndxMu integer loopNr_prevSim,parIndx_prevSim,i,par_ c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - loopNr_prevSim = 1 do i = 1, par_Anzahl_prevSim par_ = reihenFolge_prevSim(i) if (n_par_prevSim(par_).GT.1) then if (par_.EQ.charge .AND. artList_defined) then parIndx_prevSim = artListIndx_prevSim(qIndxMu) write(*,*) write(*,*) 'parIndx_prevSim = ',parIndx_prevSim write(*,*) else parIndx_prevSim = int( (parWert(par_)-par_prevSim(1,par_))/par_prevSim(3,par_) + 0.5) + 1 endif loopNr_prevSim = (loopNr_prevSim-1)*n_par_prevSim(par_) + parIndx_prevSim endif enddo firstEventNr = (loopNr_prevSim-1)*randomStarts_prevSim END c===============================================================================